From ce183f6e3e3c532b0fb1343914e5369cee7f7920 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Tue, 21 Nov 2023 11:08:18 +0100 Subject: [PATCH 001/481] Add experimental.windowHistorySupport to Turbopack supported options (#58717) ## What? Enables `experimental.windowHistorySupport` support for Turbopack. ## How? Turbopack has a guard for unknown options (allow-list). Added the option to the list of supported configurations. No additional changes are needed as Turbopack already uses the define-env config. --- packages/next/src/lib/turbopack-warning.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/next/src/lib/turbopack-warning.ts b/packages/next/src/lib/turbopack-warning.ts index fdd407165bb0a..aff0d1d2ce7f5 100644 --- a/packages/next/src/lib/turbopack-warning.ts +++ b/packages/next/src/lib/turbopack-warning.ts @@ -67,6 +67,7 @@ const supportedTurbopackNextConfigOptions = [ 'experimental.useDeploymentIdServerActions', 'experimental.deploymentId', 'experimental.useLightningcss', + 'experimental.windowHistorySupport', // Experimental options that don't affect compilation 'experimental.ppr', From 9471fb854f65126590091b397e390978032d2297 Mon Sep 17 00:00:00 2001 From: Shu Ding Date: Tue, 21 Nov 2023 21:35:10 +0800 Subject: [PATCH 002/481] Improve Server Actions compiler (#58391) Currently to make inline-defined Server Actions work, the compiler hoists the actual `"use server"` function to the module level and convert the inlined function to a parentheses expression that creates a noop wrapper function and wraps it with the proxy. This works fine however expressions are still different from declarations (#57392). So there're some details that can't be aligned well. With this change, we're going to make the compilation for the two types of inline-defined Server Actions more robust and more lightweight: #### 1. Expressions ```jsx const action = async () => { "use server" ... } const action = async function () { "use server" ... } const action = async function named () { "use server" ... } foo={async function () { "use server" ... }} ... ``` These expressions can directly be replaced with a new expression `createActionProxy("id", hoisted_action)`. A `.bind(...)` member call can be followed if it needs to bind any variables from the closure level. #### 2. Declarations ```js async function named () { "use server" ... } ``` In this case, we replace all the same `named` idents to be the expression `createActionProxy("id", hoisted_action)`, and removed that function declaration. With these changes, these will be fewer structural changes to the AST and the code is more performant. The PR also changes it to use React's `registerServerReference` method directly instead of our in-house implementation inside `createActionProxy`. Another small change is to stabilize the comment header to use `BTreeMap` inside the SWC transform. Otherwise the test snapshots will randomly mismatch. Closes #57392. --- .../crates/core/src/server_actions.rs | 519 +++++++----------- .../server-actions/client-graph/1/output.js | 8 +- .../server-actions/server-graph/1/output.js | 2 +- .../server-actions/server-graph/2/output.js | 2 +- .../server-actions/server-graph/3/output.js | 2 +- .../server-actions/server-graph/7/output.js | 5 +- .../server-actions/server-graph/8/output.js | 7 +- .../fixture/server-actions/client/1/output.js | 3 +- .../fixture/server-actions/client/2/output.js | 3 +- .../fixture/server-actions/client/3/output.js | 3 +- .../fixture/server-actions/client/4/output.js | 3 +- .../fixture/server-actions/server/1/output.js | 30 +- .../server-actions/server/10/output.js | 2 +- .../server-actions/server/11/output.js | 2 +- .../server-actions/server/12/output.js | 2 +- .../server-actions/server/13/output.js | 4 +- .../server-actions/server/14/output.js | 2 +- .../server-actions/server/15/output.js | 2 +- .../server-actions/server/16/output.js | 39 +- .../server-actions/server/17/output.js | 4 +- .../server-actions/server/18/output.js | 28 +- .../server-actions/server/19/output.js | 13 +- .../fixture/server-actions/server/2/output.js | 12 +- .../server-actions/server/20/output.js | 2 +- .../server-actions/server/21/output.js | 23 +- .../server-actions/server/22/output.js | 4 +- .../server-actions/server/23/output.js | 26 +- .../server-actions/server/24/output.js | 9 +- .../fixture/server-actions/server/25/input.js | 34 ++ .../server-actions/server/25/output.js | 41 ++ .../fixture/server-actions/server/26/input.js | 6 + .../server-actions/server/26/output.js | 7 + .../fixture/server-actions/server/3/output.js | 2 +- .../fixture/server-actions/server/4/output.js | 6 +- .../fixture/server-actions/server/5/output.js | 19 +- .../fixture/server-actions/server/6/output.js | 23 +- .../fixture/server-actions/server/7/input.js | 45 +- .../fixture/server-actions/server/7/output.js | 72 ++- .../fixture/server-actions/server/8/output.js | 7 +- .../fixture/server-actions/server/9/output.js | 8 +- .../next-flight-loader/action-proxy.ts | 51 +- 41 files changed, 511 insertions(+), 571 deletions(-) create mode 100644 packages/next-swc/crates/core/tests/fixture/server-actions/server/25/input.js create mode 100644 packages/next-swc/crates/core/tests/fixture/server-actions/server/25/output.js create mode 100644 packages/next-swc/crates/core/tests/fixture/server-actions/server/26/input.js create mode 100644 packages/next-swc/crates/core/tests/fixture/server-actions/server/26/output.js diff --git a/packages/next-swc/crates/core/src/server_actions.rs b/packages/next-swc/crates/core/src/server_actions.rs index 7013520ec7e79..702cb852c4569 100644 --- a/packages/next-swc/crates/core/src/server_actions.rs +++ b/packages/next-swc/crates/core/src/server_actions.rs @@ -1,5 +1,5 @@ use std::{ - collections::HashMap, + collections::BTreeMap, convert::{TryFrom, TryInto}, }; @@ -29,7 +29,8 @@ pub struct Config { } /// A mapping of hashed action id to the action's exported function name. -pub type ActionsMap = HashMap; +// Using BTreeMap to ensure the order of the actions is deterministic. +pub type ActionsMap = BTreeMap; pub fn server_actions( file_name: &FileName, @@ -58,6 +59,7 @@ pub fn server_actions( annotations: Default::default(), extra_items: Default::default(), export_actions: Default::default(), + replaced_action_proxies: Default::default(), }) } @@ -113,6 +115,7 @@ struct ServerActions { // (ident, export name) exported_idents: Vec<(Id, String)>, + replaced_action_proxies: Vec<(Ident, Box)>, annotations: Vec, extra_items: Vec, @@ -157,13 +160,12 @@ impl ServerActions { is_action_fn } - fn add_action_annotations_and_maybe_hoist( + fn maybe_hoist_and_create_proxy( &mut self, ident: &Ident, function: Option<&mut Box>, arrow: Option<&mut ArrowExpr>, - return_paren: bool, - ) -> (Option>, Option>) { + ) -> Option> { let action_name: JsWord = gen_ident(&mut self.ident_cnt); let action_ident = private_ident!(action_name.clone()); @@ -197,56 +199,9 @@ impl ServerActions { } }); - let args_arg = private_ident!("args"); - - let call = CallExpr { - span: DUMMY_SP, - callee: action_ident - .clone() - .make_member(quote_ident!("apply")) - .as_callee(), - args: vec![ - ExprOrSpread { - spread: None, - expr: Lit::Null(Null { span: DUMMY_SP }).into(), - }, - ExprOrSpread { - spread: None, - expr: Box::new(Expr::Call(CallExpr { - span: DUMMY_SP, - callee: Callee::Expr(Box::new(Expr::Member(MemberExpr { - span: DUMMY_SP, - obj: Box::new(Expr::Bin(BinExpr { - span: DUMMY_SP, - op: op!("||"), - left: Box::new(ident.clone().make_member(quote_ident!("$$bound"))), - right: Box::new( - ArrayLit { - span: DUMMY_SP, - elems: vec![], - } - .into(), - ), - })), - prop: MemberProp::Ident(Ident { - sym: "concat".into(), - span: DUMMY_SP, - optional: false, - }), - }))), - args: vec![args_arg.clone().as_arg()], - type_args: Default::default(), - })), - }, - ], - type_args: Default::default(), - }; - if let Some(a) = arrow { - let mut arrow_annotations = Vec::new(); - annotate_ident_as_action( - &mut arrow_annotations, - ident.clone(), + let register_action_expr = annotate_ident_as_action( + action_ident.clone(), ids_from_closure .iter() .cloned() @@ -254,42 +209,28 @@ impl ServerActions { .collect(), &self.file_name, export_name.to_string(), - Some(action_ident.clone()), ); if let BlockStmtOrExpr::BlockStmt(block) = &mut *a.body { block.visit_mut_with(&mut ClosureReplacer { used_ids: &ids_from_closure, }); - } - let new_arrow = ArrowExpr { - span: DUMMY_SP, - params: vec![ - // ...args - Pat::Rest(RestPat { - span: DUMMY_SP, - dot3_token: DUMMY_SP, - arg: Box::new(Pat::Ident(args_arg.into())), - type_ann: Default::default(), - }), - ], - body: Box::new(BlockStmtOrExpr::Expr(Box::new(Expr::Call(call)))), - is_async: true, - is_generator: false, - type_params: Default::default(), - return_type: Default::default(), - }; + self.replaced_action_proxies + .push((ident.clone(), Box::new(register_action_expr))); + } // export const $ACTION_myAction = async () => {} - let mut new_params: Vec = vec![]; + let mut new_params: Vec = vec![]; let mut new_body: BlockStmtOrExpr = *a.body.clone(); if !ids_from_closure.is_empty() { // First argument is the encrypted closure variables - new_params.push(Pat::Ident( - Ident::new("$$ACTION_CLOSURE_BOUND".into(), DUMMY_SP).into(), - )); + new_params.push(Param { + span: DUMMY_SP, + decorators: vec![], + pat: Pat::Ident(Ident::new("$$ACTION_CLOSURE_BOUND".into(), DUMMY_SP).into()), + }); // Also prepend the decryption decl into the body. // var [arg1, arg2, arg3] = await decryptActionBoundArgs(actionId, @@ -348,66 +289,47 @@ impl ServerActions { } for p in a.params.iter() { - new_params.push(p.clone()); + new_params.push(Param { + span: DUMMY_SP, + decorators: vec![], + pat: p.clone(), + }); } - // Create the action export decl + // Create the action export decl from the arrow function self.extra_items .push(ModuleItem::ModuleDecl(ModuleDecl::ExportDecl(ExportDecl { span: DUMMY_SP, - decl: Decl::Var(Box::new(VarDecl { - span: DUMMY_SP, - kind: VarDeclKind::Var, - declare: Default::default(), - decls: vec![VarDeclarator { + decl: FnDecl { + ident: action_ident.clone(), + function: Box::new(Function { + params: new_params, + body: match new_body { + BlockStmtOrExpr::BlockStmt(body) => Some(body), + BlockStmtOrExpr::Expr(expr) => Some(BlockStmt { + span: DUMMY_SP, + stmts: vec![Stmt::Return(ReturnStmt { + span: DUMMY_SP, + arg: Some(expr), + })], + }), + }, + decorators: vec![], span: DUMMY_SP, - name: action_ident.clone().into(), - init: Some(Box::new(Expr::Arrow(ArrowExpr { - params: new_params, - body: Box::new(new_body), - ..a.clone() - }))), - definite: Default::default(), - }], - })), + is_generator: false, + is_async: true, + type_params: None, + return_type: None, + }), + declare: Default::default(), + } + .into(), }))); - // Create a paren expr to wrap all annotations: - // ($ACTION = async () => {}, $ACTION.$$id = "..", .., - // $ACTION) - let mut exprs = vec![Box::new(Expr::Assign(AssignExpr { - span: DUMMY_SP, - left: PatOrExpr::Pat(Box::new(Pat::Ident(ident.clone().into()))), - op: op!("="), - right: Box::new(Expr::Arrow(new_arrow)), - }))]; - exprs.extend(arrow_annotations.into_iter().map(|a| { - if let Stmt::Expr(ExprStmt { expr, .. }) = a { - expr - } else { - unreachable!() - } - })); - exprs.push(Box::new(Expr::Ident(ident.clone()))); - - let new_paren = ParenExpr { - span: DUMMY_SP, - expr: Box::new(Expr::Seq(SeqExpr { - span: DUMMY_SP, - exprs, - })), - }; - - return (Some(Box::new(new_paren)), None); + return Some(Box::new(Expr::Ident(ident.clone()))); } else if let Some(f) = function { - let mut fn_annotations = Vec::new(); - annotate_ident_as_action( - if return_paren { - &mut fn_annotations - } else { - &mut self.annotations - }, - ident.clone(), + let register_action_expr = annotate_ident_as_action( + action_ident.clone(), ids_from_closure .iter() .cloned() @@ -415,41 +337,14 @@ impl ServerActions { .collect(), &self.file_name, export_name.to_string(), - Some(action_ident.clone()), ); f.body.visit_mut_with(&mut ClosureReplacer { used_ids: &ids_from_closure, }); - let new_fn = Function { - params: vec![ - // ...args - Param { - span: DUMMY_SP, - decorators: vec![], - pat: Pat::Rest(RestPat { - span: DUMMY_SP, - dot3_token: DUMMY_SP, - arg: Box::new(Pat::Ident(args_arg.into())), - type_ann: Default::default(), - }), - }, - ], - decorators: vec![], - span: f.span, - body: Some(BlockStmt { - span: DUMMY_SP, - stmts: vec![Stmt::Return(ReturnStmt { - span: DUMMY_SP, - arg: Some(call.into()), - })], - }), - is_generator: false, - is_async: true, - type_params: Default::default(), - return_type: Default::default(), - }; + self.replaced_action_proxies + .push((ident.clone(), Box::new(register_action_expr))); // export async function $ACTION_myAction () {} let mut new_params: Vec = vec![]; @@ -530,41 +425,10 @@ impl ServerActions { .into(), }))); - if return_paren { - // Create a paren expr to wrap all annotations: - // ($ACTION = async function () {}, $ACTION.$$id = "..", .., - // $ACTION) - let mut exprs = vec![Box::new(Expr::Assign(AssignExpr { - span: DUMMY_SP, - left: PatOrExpr::Pat(Box::new(Pat::Ident(ident.clone().into()))), - op: op!("="), - right: Box::new(Expr::Fn(FnExpr { - ident: None, - function: Box::new(new_fn), - })), - }))]; - fn_annotations.into_iter().for_each(|a| { - if let Stmt::Expr(ExprStmt { expr, .. }) = a { - exprs.push(expr); - } - }); - exprs.push(Box::new(Expr::Ident(ident.clone()))); - - let new_paren = ParenExpr { - span: DUMMY_SP, - expr: Box::new(Expr::Seq(SeqExpr { - span: DUMMY_SP, - exprs, - })), - }; - - return (Some(Box::new(new_paren)), None); - } - - return (None, Some(Box::new(new_fn))); + return Some(Box::new(Expr::Ident(ident.clone()))); } - (None, None) + None } } @@ -670,16 +534,22 @@ impl VisitMut for ServerActions { .emit(); }); } else if !self.in_action_file { - let (_, maybe_new_fn) = self.add_action_annotations_and_maybe_hoist( - &f.ident, - Some(&mut f.function), - None, - false, - ); + self.maybe_hoist_and_create_proxy(&f.ident, Some(&mut f.function), None); - if let Some(new_fn) = maybe_new_fn { - f.function = new_fn; - } + // Make the original function declaration empty, as we have hoisted it already. + f.function = Box::new(Function { + params: vec![], + decorators: vec![], + span: DUMMY_SP, + body: Some(BlockStmt { + span: DUMMY_SP, + stmts: vec![], + }), + is_generator: false, + is_async: false, + type_params: None, + return_type: None, + }); } } @@ -814,18 +684,13 @@ impl VisitMut for ServerActions { let action_name = gen_ident(&mut self.ident_cnt); let ident = private_ident!(action_name); - let (maybe_new_paren, _) = - self.add_action_annotations_and_maybe_hoist(&ident, None, Some(a), true); + let maybe_new_expr = self.maybe_hoist_and_create_proxy(&ident, None, Some(a)); - *n = attach_name_to_expr( - ident, - if let Some(new_paren) = maybe_new_paren { - Expr::Paren(*new_paren) - } else { - Expr::Arrow(a.clone()) - }, - &mut self.extra_items, - ); + *n = if let Some(new_expr) = maybe_new_expr { + *new_expr + } else { + Expr::Arrow(a.clone()) + }; } Expr::Fn(f) => { let is_action_fn = self.get_action_info(f.function.body.as_mut(), true); @@ -842,19 +707,11 @@ impl VisitMut for ServerActions { Some(i) => i, }; - let (maybe_new_paren, _) = self.add_action_annotations_and_maybe_hoist( - ident, - Some(&mut f.function), - None, - true, - ); + let maybe_new_expr = + self.maybe_hoist_and_create_proxy(ident, Some(&mut f.function), None); - if let Some(new_paren) = maybe_new_paren { - *n = attach_name_to_expr( - ident.clone(), - Expr::Paren(*new_paren), - &mut self.extra_items, - ); + if let Some(new_expr) = maybe_new_expr { + *n = *new_expr; } } _ => {} @@ -1112,14 +969,15 @@ impl VisitMut for ServerActions { new.push(export_expr); } } else { - annotate_ident_as_action( - &mut self.annotations, - ident.clone(), - Vec::new(), - &self.file_name, - export_name.to_string(), - None, - ); + self.annotations.push(Stmt::Expr(ExprStmt { + span: DUMMY_SP, + expr: Box::new(annotate_ident_as_action( + ident.clone(), + Vec::new(), + &self.file_name, + export_name.to_string(), + )), + })); } } @@ -1199,27 +1057,28 @@ impl VisitMut for ServerActions { }, ); - // import { createActionProxy } from 'private-next-rsc-action-proxy' - // createActionProxy("action_id") - new.push(ModuleItem::ModuleDecl(ModuleDecl::Import(ImportDecl { - span: DUMMY_SP, - specifiers: vec![ImportSpecifier::Named(ImportNamedSpecifier { - span: DUMMY_SP, - local: quote_ident!("createActionProxy"), - imported: None, - is_type_only: false, - })], - src: Box::new(Str { + if self.config.is_react_server_layer { + // Inlined actions are only allowed on the server layer. + // import { createActionProxy } from 'private-next-rsc-action-proxy' + // createActionProxy("action_id") + new.push(ModuleItem::ModuleDecl(ModuleDecl::Import(ImportDecl { span: DUMMY_SP, - value: "private-next-rsc-action-proxy".into(), - raw: None, - }), - type_only: false, - with: None, - }))); + specifiers: vec![ImportSpecifier::Named(ImportNamedSpecifier { + span: DUMMY_SP, + local: quote_ident!("createActionProxy"), + imported: None, + is_type_only: false, + })], + src: Box::new(Str { + span: DUMMY_SP, + value: "private-next-rsc-action-proxy".into(), + raw: None, + }), + type_only: false, + with: None, + }))); - // Encryption and decryption only happens on the server layer. - if self.config.is_react_server_layer { + // Encryption and decryption only happens on the server layer. // import { encryptActionBoundArgs, decryptActionBoundArgs } from // 'private-next-rsc-action-encryption' new.push(ModuleItem::ModuleDecl(ModuleDecl::Import(ImportDecl { @@ -1257,6 +1116,10 @@ impl VisitMut for ServerActions { *stmts = new; + stmts.visit_mut_with(&mut ClosureActionReplacer { + replaced_action_proxies: &self.replaced_action_proxies, + }); + self.annotations = old_annotations; } @@ -1348,79 +1211,74 @@ fn generate_action_id(file_name: &str, export_name: &str) -> String { } fn annotate_ident_as_action( - annotations: &mut Vec, ident: Ident, bound: Vec>, file_name: &str, export_name: String, - maybe_orig_action_ident: Option, -) { +) -> Expr { // Add the proxy wrapper call `createActionProxy($$id, $$bound, myAction, // maybe_orig_action)`. let action_id = generate_action_id(file_name, &export_name); - let mut args = vec![ - // $$id - ExprOrSpread { - spread: None, - expr: Box::new(action_id.clone().into()), - }, - // myAction.$$bound = [encryptActionBoundArgs(actionId, [arg1, arg2, arg3])]; - // or myAction.$$bound = null; if there are no bound values. - ExprOrSpread { - spread: None, - expr: Box::new(if bound.is_empty() { - Lit::Null(Null { span: DUMMY_SP }).into() - } else { - ArrayLit { - span: DUMMY_SP, - elems: vec![Some(ExprOrSpread { - spread: None, - expr: Box::new(Expr::Call(CallExpr { - span: DUMMY_SP, - callee: quote_ident!("encryptActionBoundArgs").as_callee(), - args: vec![ - ExprOrSpread { - spread: None, - expr: Box::new(action_id.into()), - }, - ExprOrSpread { - spread: None, - expr: Box::new(Expr::Array(ArrayLit { - span: DUMMY_SP, - elems: bound, - })), - }, - ], - type_args: None, - })), - })], - } - .into() - }), - }, - ExprOrSpread { - spread: None, - expr: Box::new(Expr::Ident(ident)), - }, - ]; - - annotations.push(Stmt::Expr(ExprStmt { + + let proxy_expr = Expr::Call(CallExpr { span: DUMMY_SP, - expr: Box::new(Expr::Call(CallExpr { + callee: quote_ident!("createActionProxy").as_callee(), + args: vec![ + // $$id + ExprOrSpread { + spread: None, + expr: Box::new(action_id.clone().into()), + }, + ExprOrSpread { + spread: None, + expr: Box::new(Expr::Ident(ident)), + }, + ], + type_args: Default::default(), + }); + + if bound.is_empty() { + proxy_expr + } else { + // proxy_expr.bind(null, [encryptActionBoundArgs("id", [arg1, ...])]) + Expr::Call(CallExpr { span: DUMMY_SP, - callee: quote_ident!("createActionProxy").as_callee(), - args: if let Some(orig_action_ident) = maybe_orig_action_ident { - args.push(ExprOrSpread { + callee: Expr::Member(MemberExpr { + span: DUMMY_SP, + obj: Box::new(proxy_expr), + prop: MemberProp::Ident(quote_ident!("bind")), + }) + .as_callee(), + args: vec![ + ExprOrSpread { spread: None, - expr: Box::new(Expr::Ident(orig_action_ident)), - }); - args - } else { - args - }, + expr: Box::new(Expr::Lit(Lit::Null(Null { span: DUMMY_SP }))), + }, + ExprOrSpread { + spread: None, + expr: Box::new(Expr::Call(CallExpr { + span: DUMMY_SP, + callee: quote_ident!("encryptActionBoundArgs").as_callee(), + args: vec![ + ExprOrSpread { + spread: None, + expr: Box::new(action_id.into()), + }, + ExprOrSpread { + spread: None, + expr: Box::new(Expr::Array(ArrayLit { + span: DUMMY_SP, + elems: bound, + })), + }, + ], + type_args: None, + })), + }, + ], type_args: Default::default(), - })), - })); + }) + } } const DIRECTIVE_TYPOS: &[&str] = &[ @@ -1692,6 +1550,45 @@ fn collect_idents_in_stmt(stmt: &Stmt) -> Vec { ids } +pub(crate) struct ClosureActionReplacer<'a> { + replaced_action_proxies: &'a Vec<(Ident, Box)>, +} + +impl ClosureActionReplacer<'_> { + fn index(&self, i: &Ident) -> Option { + self.replaced_action_proxies + .iter() + .position(|(ident, _)| ident.sym == i.sym && ident.span.ctxt == i.span.ctxt) + } +} + +impl VisitMut for ClosureActionReplacer<'_> { + fn visit_mut_expr(&mut self, e: &mut Expr) { + e.visit_mut_children_with(self); + + if let Expr::Ident(i) = e { + if let Some(index) = self.index(i) { + *e = *self.replaced_action_proxies[index].1.clone(); + } + } + } + + fn visit_mut_prop_or_spread(&mut self, n: &mut PropOrSpread) { + n.visit_mut_children_with(self); + + if let PropOrSpread::Prop(box Prop::Shorthand(i)) = n { + if let Some(index) = self.index(i) { + *n = PropOrSpread::Prop(Box::new(Prop::KeyValue(KeyValueProp { + key: PropName::Ident(i.clone()), + value: Box::new(*self.replaced_action_proxies[index].1.clone()), + }))); + } + } + } + + noop_visit_mut_type!(); +} + pub(crate) struct ClosureReplacer<'a> { used_ids: &'a [Name], } diff --git a/packages/next-swc/crates/core/tests/errors/server-actions/client-graph/1/output.js b/packages/next-swc/crates/core/tests/errors/server-actions/client-graph/1/output.js index 4f6910bb0b0e7..544296c840873 100644 --- a/packages/next-swc/crates/core/tests/errors/server-actions/client-graph/1/output.js +++ b/packages/next-swc/crates/core/tests/errors/server-actions/client-graph/1/output.js @@ -1,9 +1,5 @@ -/* __next_internal_client_entry_do_not_use__ default auto */ /* __next_internal_action_entry_do_not_use__ {"6d53ce510b2e36499b8f56038817b9bad86cabb4":"$$ACTION_0"} */ import { createActionProxy } from "private-next-rsc-action-proxy"; +/* __next_internal_client_entry_do_not_use__ default auto */ /* __next_internal_action_entry_do_not_use__ {"6d53ce510b2e36499b8f56038817b9bad86cabb4":"$$ACTION_0"} */ export async function $$ACTION_0() {} export default function App() { - async function fn(...args) { - return $$ACTION_0.apply(null, (fn.$$bound || []).concat(args)); - } - createActionProxy("6d53ce510b2e36499b8f56038817b9bad86cabb4", null, fn, $$ACTION_0); + function fn() {} return
App
; } -export async function $$ACTION_0() {} diff --git a/packages/next-swc/crates/core/tests/errors/server-actions/server-graph/1/output.js b/packages/next-swc/crates/core/tests/errors/server-actions/server-graph/1/output.js index 7a8fe41229e26..9e261dd7b291e 100644 --- a/packages/next-swc/crates/core/tests/errors/server-actions/server-graph/1/output.js +++ b/packages/next-swc/crates/core/tests/errors/server-actions/server-graph/1/output.js @@ -5,4 +5,4 @@ import { ensureServerEntryExports } from "private-next-rsc-action-validate"; ensureServerEntryExports([ foo ]); -createActionProxy("ab21efdafbe611287bc25c0462b1e0510d13e48b", null, foo); +createActionProxy("ab21efdafbe611287bc25c0462b1e0510d13e48b", foo); diff --git a/packages/next-swc/crates/core/tests/errors/server-actions/server-graph/2/output.js b/packages/next-swc/crates/core/tests/errors/server-actions/server-graph/2/output.js index 72edc1481ec50..97d918daabba0 100644 --- a/packages/next-swc/crates/core/tests/errors/server-actions/server-graph/2/output.js +++ b/packages/next-swc/crates/core/tests/errors/server-actions/server-graph/2/output.js @@ -6,4 +6,4 @@ import { ensureServerEntryExports } from "private-next-rsc-action-validate"; ensureServerEntryExports([ bar ]); -createActionProxy("ac840dcaf5e8197cb02b7f3a43c119b7a770b272", null, bar); +createActionProxy("ac840dcaf5e8197cb02b7f3a43c119b7a770b272", bar); diff --git a/packages/next-swc/crates/core/tests/errors/server-actions/server-graph/3/output.js b/packages/next-swc/crates/core/tests/errors/server-actions/server-graph/3/output.js index e3619a247013b..c6a9e115ec00f 100644 --- a/packages/next-swc/crates/core/tests/errors/server-actions/server-graph/3/output.js +++ b/packages/next-swc/crates/core/tests/errors/server-actions/server-graph/3/output.js @@ -5,4 +5,4 @@ import { ensureServerEntryExports } from "private-next-rsc-action-validate"; ensureServerEntryExports([ x ]); -createActionProxy("b78c261f135a7a852508c2920bd7228020ff4bd7", null, x); +createActionProxy("b78c261f135a7a852508c2920bd7228020ff4bd7", x); diff --git a/packages/next-swc/crates/core/tests/errors/server-actions/server-graph/7/output.js b/packages/next-swc/crates/core/tests/errors/server-actions/server-graph/7/output.js index fafe434c1e7f2..a20e6da44a5b2 100644 --- a/packages/next-swc/crates/core/tests/errors/server-actions/server-graph/7/output.js +++ b/packages/next-swc/crates/core/tests/errors/server-actions/server-graph/7/output.js @@ -1,5 +1,4 @@ /* __next_internal_action_entry_do_not_use__ {"188d5d945750dc32e2c842b93c75a65763d4a922":"$$ACTION_1"} */ import { createActionProxy } from "private-next-rsc-action-proxy"; import { encryptActionBoundArgs, decryptActionBoundArgs } from "private-next-rsc-action-encryption"; -const foo = ($$ACTION_0 = async (...args)=>$$ACTION_1.apply(null, ($$ACTION_0.$$bound || []).concat(args)), createActionProxy("188d5d945750dc32e2c842b93c75a65763d4a922", null, $$ACTION_0, $$ACTION_1), $$ACTION_0); -export var $$ACTION_1 = ()=>{}; -var $$ACTION_0; +const foo = createActionProxy("188d5d945750dc32e2c842b93c75a65763d4a922", $$ACTION_1); +export async function $$ACTION_1() {} diff --git a/packages/next-swc/crates/core/tests/errors/server-actions/server-graph/8/output.js b/packages/next-swc/crates/core/tests/errors/server-actions/server-graph/8/output.js index aeb9d47f6df11..257ea035bb64a 100644 --- a/packages/next-swc/crates/core/tests/errors/server-actions/server-graph/8/output.js +++ b/packages/next-swc/crates/core/tests/errors/server-actions/server-graph/8/output.js @@ -1,10 +1,9 @@ /* __next_internal_action_entry_do_not_use__ {"188d5d945750dc32e2c842b93c75a65763d4a922":"$$ACTION_1"} */ import { createActionProxy } from "private-next-rsc-action-proxy"; import { encryptActionBoundArgs, decryptActionBoundArgs } from "private-next-rsc-action-encryption"; -const foo = ($$ACTION_0 = async (...args)=>$$ACTION_1.apply(null, ($$ACTION_0.$$bound || []).concat(args)), createActionProxy("188d5d945750dc32e2c842b93c75a65763d4a922", null, $$ACTION_0, $$ACTION_1), $$ACTION_0); -export var $$ACTION_1 = async ()=>{ +const foo = createActionProxy("188d5d945750dc32e2c842b93c75a65763d4a922", $$ACTION_1); +export async function $$ACTION_1() { 'use strict'; -}; -var $$ACTION_0; +} const bar = async ()=>{ const x = 1; // prettier-ignore diff --git a/packages/next-swc/crates/core/tests/fixture/server-actions/client/1/output.js b/packages/next-swc/crates/core/tests/fixture/server-actions/client/1/output.js index eee92f539097c..d560cc5559c7d 100644 --- a/packages/next-swc/crates/core/tests/fixture/server-actions/client/1/output.js +++ b/packages/next-swc/crates/core/tests/fixture/server-actions/client/1/output.js @@ -1,5 +1,4 @@ // app/send.ts -/* __next_internal_action_entry_do_not_use__ {"c18c215a6b7cdc64bf709f3a714ffdef1bf9651d":"default","e10665baac148856374b2789aceb970f66fec33e":"myAction"} */ import { createActionProxy } from "private-next-rsc-action-proxy"; +/* __next_internal_action_entry_do_not_use__ {"c18c215a6b7cdc64bf709f3a714ffdef1bf9651d":"default","e10665baac148856374b2789aceb970f66fec33e":"myAction"} */ export default createServerReference("c18c215a6b7cdc64bf709f3a714ffdef1bf9651d"); import { createServerReference } from "private-next-rsc-action-client-wrapper"; export var myAction = createServerReference("e10665baac148856374b2789aceb970f66fec33e"); -export default createServerReference("c18c215a6b7cdc64bf709f3a714ffdef1bf9651d"); diff --git a/packages/next-swc/crates/core/tests/fixture/server-actions/client/2/output.js b/packages/next-swc/crates/core/tests/fixture/server-actions/client/2/output.js index e21c169ecfe1a..73612880801a2 100644 --- a/packages/next-swc/crates/core/tests/fixture/server-actions/client/2/output.js +++ b/packages/next-swc/crates/core/tests/fixture/server-actions/client/2/output.js @@ -1,4 +1,3 @@ // app/send.ts -/* __next_internal_action_entry_do_not_use__ {"ab21efdafbe611287bc25c0462b1e0510d13e48b":"foo"} */ import { createActionProxy } from "private-next-rsc-action-proxy"; +/* __next_internal_action_entry_do_not_use__ {"ab21efdafbe611287bc25c0462b1e0510d13e48b":"foo"} */ export var foo = createServerReference("ab21efdafbe611287bc25c0462b1e0510d13e48b"); import { createServerReference } from "private-next-rsc-action-client-wrapper"; -export var foo = createServerReference("ab21efdafbe611287bc25c0462b1e0510d13e48b"); diff --git a/packages/next-swc/crates/core/tests/fixture/server-actions/client/3/output.js b/packages/next-swc/crates/core/tests/fixture/server-actions/client/3/output.js index b03370598668b..9cd3edfa39a3f 100644 --- a/packages/next-swc/crates/core/tests/fixture/server-actions/client/3/output.js +++ b/packages/next-swc/crates/core/tests/fixture/server-actions/client/3/output.js @@ -1,6 +1,5 @@ -/* __next_internal_action_entry_do_not_use__ {"bd336abe00c3c59da66acb696fc8e151d8e54ea4":"sampleFunction","a0c73dd6f5af839e3335c6b19262ecb86cca6af4":"sampleFunction2","f03b256ee88a51700367acee3082894e25e6e7d9":"sampleFunction4","d4f2e95bc745b6500b439c0847003511748c8ece":"sampleFunction3"} */ import { createActionProxy } from "private-next-rsc-action-proxy"; +/* __next_internal_action_entry_do_not_use__ {"a0c73dd6f5af839e3335c6b19262ecb86cca6af4":"sampleFunction2","bd336abe00c3c59da66acb696fc8e151d8e54ea4":"sampleFunction","d4f2e95bc745b6500b439c0847003511748c8ece":"sampleFunction3","f03b256ee88a51700367acee3082894e25e6e7d9":"sampleFunction4"} */ export var sampleFunction4 = createServerReference("f03b256ee88a51700367acee3082894e25e6e7d9"); import { createServerReference } from "private-next-rsc-action-client-wrapper"; export var sampleFunction = createServerReference("bd336abe00c3c59da66acb696fc8e151d8e54ea4"); export var sampleFunction2 = createServerReference("a0c73dd6f5af839e3335c6b19262ecb86cca6af4"); export var sampleFunction3 = createServerReference("d4f2e95bc745b6500b439c0847003511748c8ece"); -export var sampleFunction4 = createServerReference("f03b256ee88a51700367acee3082894e25e6e7d9"); diff --git a/packages/next-swc/crates/core/tests/fixture/server-actions/client/4/output.js b/packages/next-swc/crates/core/tests/fixture/server-actions/client/4/output.js index 41fa6e3beec61..9caa9de514b2a 100644 --- a/packages/next-swc/crates/core/tests/fixture/server-actions/client/4/output.js +++ b/packages/next-swc/crates/core/tests/fixture/server-actions/client/4/output.js @@ -1,3 +1,2 @@ -/* __next_internal_action_entry_do_not_use__ {"ac840dcaf5e8197cb02b7f3a43c119b7a770b272":"bar"} */ import { createActionProxy } from "private-next-rsc-action-proxy"; +/* __next_internal_action_entry_do_not_use__ {"ac840dcaf5e8197cb02b7f3a43c119b7a770b272":"bar"} */ export var bar = createServerReference("ac840dcaf5e8197cb02b7f3a43c119b7a770b272"); import { createServerReference } from "private-next-rsc-action-client-wrapper"; -export var bar = createServerReference("ac840dcaf5e8197cb02b7f3a43c119b7a770b272"); diff --git a/packages/next-swc/crates/core/tests/fixture/server-actions/server/1/output.js b/packages/next-swc/crates/core/tests/fixture/server-actions/server/1/output.js index a90bc4edad633..ceb6571d200f7 100644 --- a/packages/next-swc/crates/core/tests/fixture/server-actions/server/1/output.js +++ b/packages/next-swc/crates/core/tests/fixture/server-actions/server/1/output.js @@ -2,16 +2,11 @@ import { encryptActionBoundArgs, decryptActionBoundArgs } from "private-next-rsc-action-encryption"; import deleteFromDb from 'db'; export function Item({ id1, id2 }) { - async function deleteItem(...args) { - return $$ACTION_0.apply(null, (deleteItem.$$bound || []).concat(args)); - } - createActionProxy("6d53ce510b2e36499b8f56038817b9bad86cabb4", [ - encryptActionBoundArgs("6d53ce510b2e36499b8f56038817b9bad86cabb4", [ - id1, - id2 - ]) - ], deleteItem, $$ACTION_0); - return ; + function deleteItem() {} + return ; } export async function $$ACTION_0($$ACTION_CLOSURE_BOUND) { var [$$ACTION_ARG_0, $$ACTION_ARG_1] = await decryptActionBoundArgs("6d53ce510b2e36499b8f56038817b9bad86cabb4", $$ACTION_CLOSURE_BOUND); @@ -23,17 +18,14 @@ export default function Home() { name: 'John', test: 'test' }; - const action = ($$ACTION_1 = async (...args)=>$$ACTION_2.apply(null, ($$ACTION_1.$$bound || []).concat(args)), createActionProxy("9878bfa39811ca7650992850a8751f9591b6a557", [ - encryptActionBoundArgs("9878bfa39811ca7650992850a8751f9591b6a557", [ - info.name, - info.test - ]) - ], $$ACTION_1, $$ACTION_2), $$ACTION_1); + const action = createActionProxy("9878bfa39811ca7650992850a8751f9591b6a557", $$ACTION_2).bind(null, encryptActionBoundArgs("9878bfa39811ca7650992850a8751f9591b6a557", [ + info.name, + info.test + ])); return null; } -export var $$ACTION_2 = async ($$ACTION_CLOSURE_BOUND)=>{ +export async function $$ACTION_2($$ACTION_CLOSURE_BOUND) { var [$$ACTION_ARG_0, $$ACTION_ARG_1] = await decryptActionBoundArgs("9878bfa39811ca7650992850a8751f9591b6a557", $$ACTION_CLOSURE_BOUND); console.log($$ACTION_ARG_0); console.log($$ACTION_ARG_1); -}; -var $$ACTION_1; +} diff --git a/packages/next-swc/crates/core/tests/fixture/server-actions/server/10/output.js b/packages/next-swc/crates/core/tests/fixture/server-actions/server/10/output.js index 3e8436d9c95a1..8666bb1f6e985 100644 --- a/packages/next-swc/crates/core/tests/fixture/server-actions/server/10/output.js +++ b/packages/next-swc/crates/core/tests/fixture/server-actions/server/10/output.js @@ -5,4 +5,4 @@ import { ensureServerEntryExports } from "private-next-rsc-action-validate"; ensureServerEntryExports([ foo ]); -createActionProxy("c18c215a6b7cdc64bf709f3a714ffdef1bf9651d", null, foo); +createActionProxy("c18c215a6b7cdc64bf709f3a714ffdef1bf9651d", foo); diff --git a/packages/next-swc/crates/core/tests/fixture/server-actions/server/11/output.js b/packages/next-swc/crates/core/tests/fixture/server-actions/server/11/output.js index cea76b8da3fa0..dab935ba484f6 100644 --- a/packages/next-swc/crates/core/tests/fixture/server-actions/server/11/output.js +++ b/packages/next-swc/crates/core/tests/fixture/server-actions/server/11/output.js @@ -5,4 +5,4 @@ import { ensureServerEntryExports } from "private-next-rsc-action-validate"; ensureServerEntryExports([ $$ACTION_0 ]); -createActionProxy("c18c215a6b7cdc64bf709f3a714ffdef1bf9651d", null, $$ACTION_0); +createActionProxy("c18c215a6b7cdc64bf709f3a714ffdef1bf9651d", $$ACTION_0); diff --git a/packages/next-swc/crates/core/tests/fixture/server-actions/server/12/output.js b/packages/next-swc/crates/core/tests/fixture/server-actions/server/12/output.js index 5ee8474d6a6f2..373f388b78dcb 100644 --- a/packages/next-swc/crates/core/tests/fixture/server-actions/server/12/output.js +++ b/packages/next-swc/crates/core/tests/fixture/server-actions/server/12/output.js @@ -6,4 +6,4 @@ import { ensureServerEntryExports } from "private-next-rsc-action-validate"; ensureServerEntryExports([ foo ]); -createActionProxy("c18c215a6b7cdc64bf709f3a714ffdef1bf9651d", null, foo); +createActionProxy("c18c215a6b7cdc64bf709f3a714ffdef1bf9651d", foo); diff --git a/packages/next-swc/crates/core/tests/fixture/server-actions/server/13/output.js b/packages/next-swc/crates/core/tests/fixture/server-actions/server/13/output.js index 37475e9ead4af..c4db2124ab3cb 100644 --- a/packages/next-swc/crates/core/tests/fixture/server-actions/server/13/output.js +++ b/packages/next-swc/crates/core/tests/fixture/server-actions/server/13/output.js @@ -9,5 +9,5 @@ ensureServerEntryExports([ foo, bar ]); -createActionProxy("c18c215a6b7cdc64bf709f3a714ffdef1bf9651d", null, foo); -createActionProxy("ac840dcaf5e8197cb02b7f3a43c119b7a770b272", null, bar); +createActionProxy("c18c215a6b7cdc64bf709f3a714ffdef1bf9651d", foo); +createActionProxy("ac840dcaf5e8197cb02b7f3a43c119b7a770b272", bar); diff --git a/packages/next-swc/crates/core/tests/fixture/server-actions/server/14/output.js b/packages/next-swc/crates/core/tests/fixture/server-actions/server/14/output.js index fd8bf705474bd..1b1dbde5af657 100644 --- a/packages/next-swc/crates/core/tests/fixture/server-actions/server/14/output.js +++ b/packages/next-swc/crates/core/tests/fixture/server-actions/server/14/output.js @@ -7,4 +7,4 @@ import { ensureServerEntryExports } from "private-next-rsc-action-validate"; ensureServerEntryExports([ foo ]); -createActionProxy("ab21efdafbe611287bc25c0462b1e0510d13e48b", null, foo); +createActionProxy("ab21efdafbe611287bc25c0462b1e0510d13e48b", foo); diff --git a/packages/next-swc/crates/core/tests/fixture/server-actions/server/15/output.js b/packages/next-swc/crates/core/tests/fixture/server-actions/server/15/output.js index 867cd841293fe..8aeb838a9c956 100644 --- a/packages/next-swc/crates/core/tests/fixture/server-actions/server/15/output.js +++ b/packages/next-swc/crates/core/tests/fixture/server-actions/server/15/output.js @@ -8,4 +8,4 @@ import { ensureServerEntryExports } from "private-next-rsc-action-validate"; ensureServerEntryExports([ $$ACTION_0 ]); -createActionProxy("c18c215a6b7cdc64bf709f3a714ffdef1bf9651d", null, $$ACTION_0); +createActionProxy("c18c215a6b7cdc64bf709f3a714ffdef1bf9651d", $$ACTION_0); diff --git a/packages/next-swc/crates/core/tests/fixture/server-actions/server/16/output.js b/packages/next-swc/crates/core/tests/fixture/server-actions/server/16/output.js index 48aff3d82ad8b..a33ad000d1f3c 100644 --- a/packages/next-swc/crates/core/tests/fixture/server-actions/server/16/output.js +++ b/packages/next-swc/crates/core/tests/fixture/server-actions/server/16/output.js @@ -1,47 +1,34 @@ -/* __next_internal_action_entry_do_not_use__ {"9c0dd1f7c2b3f41d32e10f5c437de3d67ad32c6c":"$$ACTION_4","9878bfa39811ca7650992850a8751f9591b6a557":"$$ACTION_2","188d5d945750dc32e2c842b93c75a65763d4a922":"$$ACTION_1"} */ import { createActionProxy } from "private-next-rsc-action-proxy"; +/* __next_internal_action_entry_do_not_use__ {"188d5d945750dc32e2c842b93c75a65763d4a922":"$$ACTION_1","9878bfa39811ca7650992850a8751f9591b6a557":"$$ACTION_2","9c0dd1f7c2b3f41d32e10f5c437de3d67ad32c6c":"$$ACTION_4"} */ import { createActionProxy } from "private-next-rsc-action-proxy"; import { encryptActionBoundArgs, decryptActionBoundArgs } from "private-next-rsc-action-encryption"; import deleteFromDb from 'db'; const v1 = 'v1'; export function Item({ id1, id2 }) { const v2 = id2; - const deleteItem = ($$ACTION_0 = async (...args)=>$$ACTION_1.apply(null, ($$ACTION_0.$$bound || []).concat(args)), createActionProxy("188d5d945750dc32e2c842b93c75a65763d4a922", [ - encryptActionBoundArgs("188d5d945750dc32e2c842b93c75a65763d4a922", [ - id1, - v2 - ]) - ], $$ACTION_0, $$ACTION_1), $$ACTION_0); + const deleteItem = createActionProxy("188d5d945750dc32e2c842b93c75a65763d4a922", $$ACTION_1).bind(null, encryptActionBoundArgs("188d5d945750dc32e2c842b93c75a65763d4a922", [ + id1, + v2 + ])); return ; } -export var $$ACTION_1 = async ($$ACTION_CLOSURE_BOUND)=>{ +export async function $$ACTION_1($$ACTION_CLOSURE_BOUND) { var [$$ACTION_ARG_0, $$ACTION_ARG_1] = await decryptActionBoundArgs("188d5d945750dc32e2c842b93c75a65763d4a922", $$ACTION_CLOSURE_BOUND); await deleteFromDb($$ACTION_ARG_0); await deleteFromDb(v1); await deleteFromDb($$ACTION_ARG_1); -}; -var $$ACTION_0; +} const f = (x)=>{ - async function g(...args) { - return $$ACTION_2.apply(null, (g.$$bound || []).concat(args)); - } - createActionProxy("9878bfa39811ca7650992850a8751f9591b6a557", [ - encryptActionBoundArgs("9878bfa39811ca7650992850a8751f9591b6a557", [ - x - ]) - ], g, $$ACTION_2); + function g() {} }; export async function $$ACTION_2($$ACTION_CLOSURE_BOUND, y, ...z) { var [$$ACTION_ARG_0] = await decryptActionBoundArgs("9878bfa39811ca7650992850a8751f9591b6a557", $$ACTION_CLOSURE_BOUND); return $$ACTION_ARG_0 + y + z[0]; } const g = (x)=>{ - f = ($$ACTION_3 = async (...args)=>$$ACTION_4.apply(null, ($$ACTION_3.$$bound || []).concat(args)), createActionProxy("9c0dd1f7c2b3f41d32e10f5c437de3d67ad32c6c", [ - encryptActionBoundArgs("9c0dd1f7c2b3f41d32e10f5c437de3d67ad32c6c", [ - x - ]) - ], $$ACTION_3, $$ACTION_4), $$ACTION_3); + f = createActionProxy("9c0dd1f7c2b3f41d32e10f5c437de3d67ad32c6c", $$ACTION_4).bind(null, encryptActionBoundArgs("9c0dd1f7c2b3f41d32e10f5c437de3d67ad32c6c", [ + x + ])); }; -export var $$ACTION_4 = async ($$ACTION_CLOSURE_BOUND, y, ...z)=>{ +export async function $$ACTION_4($$ACTION_CLOSURE_BOUND, y, ...z) { var [$$ACTION_ARG_0] = await decryptActionBoundArgs("9c0dd1f7c2b3f41d32e10f5c437de3d67ad32c6c", $$ACTION_CLOSURE_BOUND); return $$ACTION_ARG_0 + y + z[0]; -}; -var $$ACTION_3; +} diff --git a/packages/next-swc/crates/core/tests/fixture/server-actions/server/17/output.js b/packages/next-swc/crates/core/tests/fixture/server-actions/server/17/output.js index 2768102d45678..655766407d050 100644 --- a/packages/next-swc/crates/core/tests/fixture/server-actions/server/17/output.js +++ b/packages/next-swc/crates/core/tests/fixture/server-actions/server/17/output.js @@ -8,5 +8,5 @@ ensureServerEntryExports([ foo, bar ]); -createActionProxy("ab21efdafbe611287bc25c0462b1e0510d13e48b", null, foo); -createActionProxy("ac840dcaf5e8197cb02b7f3a43c119b7a770b272", null, bar); +createActionProxy("ab21efdafbe611287bc25c0462b1e0510d13e48b", foo); +createActionProxy("ac840dcaf5e8197cb02b7f3a43c119b7a770b272", bar); diff --git a/packages/next-swc/crates/core/tests/fixture/server-actions/server/18/output.js b/packages/next-swc/crates/core/tests/fixture/server-actions/server/18/output.js index 1591ca40a433d..b4628bf98efd3 100644 --- a/packages/next-swc/crates/core/tests/fixture/server-actions/server/18/output.js +++ b/packages/next-swc/crates/core/tests/fixture/server-actions/server/18/output.js @@ -6,25 +6,19 @@ export function Item({ id1, id2 }) { const v2 = id2; return <> - - ; + return ; } -export const action = withValidate(($$ACTION_1 = async (...args)=>$$ACTION_2.apply(null, ($$ACTION_1.$$bound || []).concat(args)), createActionProxy("9878bfa39811ca7650992850a8751f9591b6a557", null, $$ACTION_1, $$ACTION_2), $$ACTION_1)); -export var $$ACTION_2 = async ()=>{}; -var $$ACTION_1; +export const action = withValidate(createActionProxy("9878bfa39811ca7650992850a8751f9591b6a557", $$ACTION_2)); +export async function $$ACTION_2() {} diff --git a/packages/next-swc/crates/core/tests/fixture/server-actions/server/20/output.js b/packages/next-swc/crates/core/tests/fixture/server-actions/server/20/output.js index 1a97f734b5b0b..bd3457e7b41a5 100644 --- a/packages/next-swc/crates/core/tests/fixture/server-actions/server/20/output.js +++ b/packages/next-swc/crates/core/tests/fixture/server-actions/server/20/output.js @@ -8,4 +8,4 @@ import { ensureServerEntryExports } from "private-next-rsc-action-validate"; ensureServerEntryExports([ foo ]); -createActionProxy("c18c215a6b7cdc64bf709f3a714ffdef1bf9651d", null, foo); +createActionProxy("c18c215a6b7cdc64bf709f3a714ffdef1bf9651d", foo); diff --git a/packages/next-swc/crates/core/tests/fixture/server-actions/server/21/output.js b/packages/next-swc/crates/core/tests/fixture/server-actions/server/21/output.js index bdb8662bb91c8..9962a9e0f8bfd 100644 --- a/packages/next-swc/crates/core/tests/fixture/server-actions/server/21/output.js +++ b/packages/next-swc/crates/core/tests/fixture/server-actions/server/21/output.js @@ -1,25 +1,18 @@ -/* __next_internal_action_entry_do_not_use__ {"1383664d1dc2d9cfe33b88df3fa0eaffef8b99bc":"$$ACTION_5","56a859f462d35a297c46a1bbd1e6a9058c104ab8":"$$ACTION_3","188d5d945750dc32e2c842b93c75a65763d4a922":"$$ACTION_1"} */ import { createActionProxy } from "private-next-rsc-action-proxy"; +/* __next_internal_action_entry_do_not_use__ {"1383664d1dc2d9cfe33b88df3fa0eaffef8b99bc":"$$ACTION_5","188d5d945750dc32e2c842b93c75a65763d4a922":"$$ACTION_1","56a859f462d35a297c46a1bbd1e6a9058c104ab8":"$$ACTION_3"} */ import { createActionProxy } from "private-next-rsc-action-proxy"; import { encryptActionBoundArgs, decryptActionBoundArgs } from "private-next-rsc-action-encryption"; import { validator, another } from 'auth'; const x = 1; export default function Page() { const y = 1; - return ; + return ; } export async function $$ACTION_1($$ACTION_CLOSURE_BOUND, z) { var [$$ACTION_ARG_0] = await decryptActionBoundArgs("188d5d945750dc32e2c842b93c75a65763d4a922", $$ACTION_CLOSURE_BOUND); return x + $$ACTION_ARG_0 + z; } -var $$ACTION_0; -validator(($$ACTION_2 = async (...args)=>$$ACTION_3.apply(null, ($$ACTION_2.$$bound || []).concat(args)), createActionProxy("56a859f462d35a297c46a1bbd1e6a9058c104ab8", null, $$ACTION_2, $$ACTION_3), $$ACTION_2)); -export var $$ACTION_3 = async ()=>{}; -var $$ACTION_2; -another(validator(($$ACTION_4 = async (...args)=>$$ACTION_5.apply(null, ($$ACTION_4.$$bound || []).concat(args)), createActionProxy("1383664d1dc2d9cfe33b88df3fa0eaffef8b99bc", null, $$ACTION_4, $$ACTION_5), $$ACTION_4))); -export var $$ACTION_5 = async ()=>{}; -var $$ACTION_4; +validator(createActionProxy("56a859f462d35a297c46a1bbd1e6a9058c104ab8", $$ACTION_3)); +export async function $$ACTION_3() {} +another(validator(createActionProxy("1383664d1dc2d9cfe33b88df3fa0eaffef8b99bc", $$ACTION_5))); +export async function $$ACTION_5() {} diff --git a/packages/next-swc/crates/core/tests/fixture/server-actions/server/22/output.js b/packages/next-swc/crates/core/tests/fixture/server-actions/server/22/output.js index fa43b6820eb81..94f01484799aa 100644 --- a/packages/next-swc/crates/core/tests/fixture/server-actions/server/22/output.js +++ b/packages/next-swc/crates/core/tests/fixture/server-actions/server/22/output.js @@ -9,5 +9,5 @@ ensureServerEntryExports([ action, $$ACTION_0 ]); -createActionProxy("f14702b5a021dd117f7ec7a3c838f397c2046d3b", null, action); -createActionProxy("c18c215a6b7cdc64bf709f3a714ffdef1bf9651d", null, $$ACTION_0); +createActionProxy("f14702b5a021dd117f7ec7a3c838f397c2046d3b", action); +createActionProxy("c18c215a6b7cdc64bf709f3a714ffdef1bf9651d", $$ACTION_0); diff --git a/packages/next-swc/crates/core/tests/fixture/server-actions/server/23/output.js b/packages/next-swc/crates/core/tests/fixture/server-actions/server/23/output.js index d5d8b578ddfcc..19a553d7580aa 100644 --- a/packages/next-swc/crates/core/tests/fixture/server-actions/server/23/output.js +++ b/packages/next-swc/crates/core/tests/fixture/server-actions/server/23/output.js @@ -1,28 +1,20 @@ /* __next_internal_action_entry_do_not_use__ {"6d53ce510b2e36499b8f56038817b9bad86cabb4":"$$ACTION_0","9878bfa39811ca7650992850a8751f9591b6a557":"$$ACTION_2"} */ import { createActionProxy } from "private-next-rsc-action-proxy"; import { encryptActionBoundArgs, decryptActionBoundArgs } from "private-next-rsc-action-encryption"; export default function Page({ foo, x, y }) { - async function action(...args) { - return $$ACTION_0.apply(null, (action.$$bound || []).concat(args)); - } - createActionProxy("6d53ce510b2e36499b8f56038817b9bad86cabb4", [ - encryptActionBoundArgs("6d53ce510b2e36499b8f56038817b9bad86cabb4", [ - x - ]) - ], action, $$ACTION_0); - action.bind(null, foo[0], foo[1], foo.x, foo[y]); - const action2 = ($$ACTION_1 = async (...args)=>$$ACTION_2.apply(null, ($$ACTION_1.$$bound || []).concat(args)), createActionProxy("9878bfa39811ca7650992850a8751f9591b6a557", [ - encryptActionBoundArgs("9878bfa39811ca7650992850a8751f9591b6a557", [ - x - ]) - ], $$ACTION_1, $$ACTION_2), $$ACTION_1); + function action() {} + createActionProxy("6d53ce510b2e36499b8f56038817b9bad86cabb4", $$ACTION_0).bind(null, encryptActionBoundArgs("6d53ce510b2e36499b8f56038817b9bad86cabb4", [ + x + ])).bind(null, foo[0], foo[1], foo.x, foo[y]); + const action2 = createActionProxy("9878bfa39811ca7650992850a8751f9591b6a557", $$ACTION_2).bind(null, encryptActionBoundArgs("9878bfa39811ca7650992850a8751f9591b6a557", [ + x + ])); action2.bind(null, foo[0], foo[1], foo.x, foo[y]); } export async function $$ACTION_0($$ACTION_CLOSURE_BOUND, a, b, c, d) { var [$$ACTION_ARG_0] = await decryptActionBoundArgs("6d53ce510b2e36499b8f56038817b9bad86cabb4", $$ACTION_CLOSURE_BOUND); console.log(a, b, $$ACTION_ARG_0, c, d); } -export var $$ACTION_2 = async ($$ACTION_CLOSURE_BOUND, a, b, c, d)=>{ +export async function $$ACTION_2($$ACTION_CLOSURE_BOUND, a, b, c, d) { var [$$ACTION_ARG_0] = await decryptActionBoundArgs("9878bfa39811ca7650992850a8751f9591b6a557", $$ACTION_CLOSURE_BOUND); console.log(a, b, $$ACTION_ARG_0, c, d); -}; -var $$ACTION_1; +} diff --git a/packages/next-swc/crates/core/tests/fixture/server-actions/server/24/output.js b/packages/next-swc/crates/core/tests/fixture/server-actions/server/24/output.js index adc929dd6d772..98b899925ae01 100644 --- a/packages/next-swc/crates/core/tests/fixture/server-actions/server/24/output.js +++ b/packages/next-swc/crates/core/tests/fixture/server-actions/server/24/output.js @@ -1,14 +1,7 @@ /* __next_internal_action_entry_do_not_use__ {"6d53ce510b2e36499b8f56038817b9bad86cabb4":"$$ACTION_0"} */ import { createActionProxy } from "private-next-rsc-action-proxy"; import { encryptActionBoundArgs, decryptActionBoundArgs } from "private-next-rsc-action-encryption"; export default function Page({ foo, x, y }) { - async function action(...args) { - return $$ACTION_0.apply(null, (action.$$bound || []).concat(args)); - } - createActionProxy("6d53ce510b2e36499b8f56038817b9bad86cabb4", [ - encryptActionBoundArgs("6d53ce510b2e36499b8f56038817b9bad86cabb4", [ - foo - ]) - ], action, $$ACTION_0); + function action() {} } export async function $$ACTION_0($$ACTION_CLOSURE_BOUND, a, b, c, { d }) { var [$$ACTION_ARG_0] = await decryptActionBoundArgs("6d53ce510b2e36499b8f56038817b9bad86cabb4", $$ACTION_CLOSURE_BOUND); diff --git a/packages/next-swc/crates/core/tests/fixture/server-actions/server/25/input.js b/packages/next-swc/crates/core/tests/fixture/server-actions/server/25/input.js new file mode 100644 index 0000000000000..d6995dc0a6842 --- /dev/null +++ b/packages/next-swc/crates/core/tests/fixture/server-actions/server/25/input.js @@ -0,0 +1,34 @@ +import deleteFromDb from 'db' + +export function Item({ id1, id2 }) { + id1++ + return (() => { + id1++ + return + })() + + async function deleteItem() { + 'use server' + await deleteFromDb(id1) + await deleteFromDb(id2) + } +} + +// In this example, if Button immediately executes the action, different ids should +// be passed. +export function Item2({ id1, id2 }) { + id1++ + const temp = [] + temp.push() + + id1++ + temp.push() + + return temp + + async function deleteItem() { + 'use server' + await deleteFromDb(id1) + await deleteFromDb(id2) + } +} diff --git a/packages/next-swc/crates/core/tests/fixture/server-actions/server/25/output.js b/packages/next-swc/crates/core/tests/fixture/server-actions/server/25/output.js new file mode 100644 index 0000000000000..07ea05c5b4be2 --- /dev/null +++ b/packages/next-swc/crates/core/tests/fixture/server-actions/server/25/output.js @@ -0,0 +1,41 @@ +/* __next_internal_action_entry_do_not_use__ {"188d5d945750dc32e2c842b93c75a65763d4a922":"$$ACTION_1","6d53ce510b2e36499b8f56038817b9bad86cabb4":"$$ACTION_0"} */ import { createActionProxy } from "private-next-rsc-action-proxy"; +import { encryptActionBoundArgs, decryptActionBoundArgs } from "private-next-rsc-action-encryption"; +import deleteFromDb from 'db'; +export function Item({ id1, id2 }) { + id1++; + return (()=>{ + id1++; + return ; + })(); + function deleteItem() {} +} +export async function $$ACTION_0($$ACTION_CLOSURE_BOUND) { + var [$$ACTION_ARG_0, $$ACTION_ARG_1] = await decryptActionBoundArgs("6d53ce510b2e36499b8f56038817b9bad86cabb4", $$ACTION_CLOSURE_BOUND); + await deleteFromDb($$ACTION_ARG_0); + await deleteFromDb($$ACTION_ARG_1); +} +// In this example, if Button immediately executes the action, different ids should +// be passed. +export function Item2({ id1, id2 }) { + id1++; + const temp = []; + temp.push(); + id1++; + temp.push(); + return temp; + function deleteItem() {} +} +export async function $$ACTION_1($$ACTION_CLOSURE_BOUND) { + var [$$ACTION_ARG_0, $$ACTION_ARG_1] = await decryptActionBoundArgs("188d5d945750dc32e2c842b93c75a65763d4a922", $$ACTION_CLOSURE_BOUND); + await deleteFromDb($$ACTION_ARG_0); + await deleteFromDb($$ACTION_ARG_1); +} diff --git a/packages/next-swc/crates/core/tests/fixture/server-actions/server/26/input.js b/packages/next-swc/crates/core/tests/fixture/server-actions/server/26/input.js new file mode 100644 index 0000000000000..771f2f8bd5e02 --- /dev/null +++ b/packages/next-swc/crates/core/tests/fixture/server-actions/server/26/input.js @@ -0,0 +1,6 @@ +const noop = (action) => action + +export const log = noop(async (data) => { + 'use server' + console.log(data) +}) diff --git a/packages/next-swc/crates/core/tests/fixture/server-actions/server/26/output.js b/packages/next-swc/crates/core/tests/fixture/server-actions/server/26/output.js new file mode 100644 index 0000000000000..7b59b9896387e --- /dev/null +++ b/packages/next-swc/crates/core/tests/fixture/server-actions/server/26/output.js @@ -0,0 +1,7 @@ +/* __next_internal_action_entry_do_not_use__ {"188d5d945750dc32e2c842b93c75a65763d4a922":"$$ACTION_1"} */ import { createActionProxy } from "private-next-rsc-action-proxy"; +import { encryptActionBoundArgs, decryptActionBoundArgs } from "private-next-rsc-action-encryption"; +const noop = (action)=>action; +export const log = noop(createActionProxy("188d5d945750dc32e2c842b93c75a65763d4a922", $$ACTION_1)); +export async function $$ACTION_1(data) { + console.log(data); +} diff --git a/packages/next-swc/crates/core/tests/fixture/server-actions/server/3/output.js b/packages/next-swc/crates/core/tests/fixture/server-actions/server/3/output.js index 26b543c50a0ce..7bde2d0604efd 100644 --- a/packages/next-swc/crates/core/tests/fixture/server-actions/server/3/output.js +++ b/packages/next-swc/crates/core/tests/fixture/server-actions/server/3/output.js @@ -8,4 +8,4 @@ import { ensureServerEntryExports } from "private-next-rsc-action-validate"; ensureServerEntryExports([ myAction ]); -createActionProxy("e10665baac148856374b2789aceb970f66fec33e", null, myAction); +createActionProxy("e10665baac148856374b2789aceb970f66fec33e", myAction); diff --git a/packages/next-swc/crates/core/tests/fixture/server-actions/server/4/output.js b/packages/next-swc/crates/core/tests/fixture/server-actions/server/4/output.js index 0aaa4cc657a06..06a5bfa7ac9a6 100644 --- a/packages/next-swc/crates/core/tests/fixture/server-actions/server/4/output.js +++ b/packages/next-swc/crates/core/tests/fixture/server-actions/server/4/output.js @@ -13,6 +13,6 @@ ensureServerEntryExports([ b, c ]); -createActionProxy("6e7bc104e4d6e7fda190c4a51be969cfd0be6d6d", null, a); -createActionProxy("d1f7eb64271d7c601dfef7d4d7053de1c2ca4338", null, b); -createActionProxy("1ab723c80dcca470e0410b4b2a2fc2bf21f41476", null, c); +createActionProxy("6e7bc104e4d6e7fda190c4a51be969cfd0be6d6d", a); +createActionProxy("d1f7eb64271d7c601dfef7d4d7053de1c2ca4338", b); +createActionProxy("1ab723c80dcca470e0410b4b2a2fc2bf21f41476", c); diff --git a/packages/next-swc/crates/core/tests/fixture/server-actions/server/5/output.js b/packages/next-swc/crates/core/tests/fixture/server-actions/server/5/output.js index 2ffa42c88e809..607ec4b203741 100644 --- a/packages/next-swc/crates/core/tests/fixture/server-actions/server/5/output.js +++ b/packages/next-swc/crates/core/tests/fixture/server-actions/server/5/output.js @@ -4,18 +4,13 @@ import deleteFromDb from 'db'; const v1 = 'v1'; export function Item({ id1, id2, id3, id4 }) { const v2 = id2; - async function deleteItem(...args) { - return $$ACTION_0.apply(null, (deleteItem.$$bound || []).concat(args)); - } - createActionProxy("6d53ce510b2e36499b8f56038817b9bad86cabb4", [ - encryptActionBoundArgs("6d53ce510b2e36499b8f56038817b9bad86cabb4", [ - id1, - v2, - id3, - id4.x - ]) - ], deleteItem, $$ACTION_0); - return ; + function deleteItem() {} + return ; } export async function $$ACTION_0($$ACTION_CLOSURE_BOUND) { var [$$ACTION_ARG_0, $$ACTION_ARG_1, $$ACTION_ARG_2, $$ACTION_ARG_3] = await decryptActionBoundArgs("6d53ce510b2e36499b8f56038817b9bad86cabb4", $$ACTION_CLOSURE_BOUND); diff --git a/packages/next-swc/crates/core/tests/fixture/server-actions/server/6/output.js b/packages/next-swc/crates/core/tests/fixture/server-actions/server/6/output.js index 50ea347905162..c9c87a090ebb6 100644 --- a/packages/next-swc/crates/core/tests/fixture/server-actions/server/6/output.js +++ b/packages/next-swc/crates/core/tests/fixture/server-actions/server/6/output.js @@ -19,20 +19,15 @@ export function y(p, [p1, { p2 }], ...p3) { if (true) { const f8 = 1; } - async function action(...args) { - return $$ACTION_0.apply(null, (action.$$bound || []).concat(args)); - } - createActionProxy("6d53ce510b2e36499b8f56038817b9bad86cabb4", [ - encryptActionBoundArgs("6d53ce510b2e36499b8f56038817b9bad86cabb4", [ - f2, - f11, - p, - p1, - p2, - p3 - ]) - ], action, $$ACTION_0); - return ; + function action() {} + return ; } export async function $$ACTION_0($$ACTION_CLOSURE_BOUND) { var [$$ACTION_ARG_0, $$ACTION_ARG_1, $$ACTION_ARG_2, $$ACTION_ARG_3, $$ACTION_ARG_4, $$ACTION_ARG_5] = await decryptActionBoundArgs("6d53ce510b2e36499b8f56038817b9bad86cabb4", $$ACTION_CLOSURE_BOUND); diff --git a/packages/next-swc/crates/core/tests/fixture/server-actions/server/7/input.js b/packages/next-swc/crates/core/tests/fixture/server-actions/server/7/input.js index ce85dc4194495..4185109b0e194 100644 --- a/packages/next-swc/crates/core/tests/fixture/server-actions/server/7/input.js +++ b/packages/next-swc/crates/core/tests/fixture/server-actions/server/7/input.js @@ -1,7 +1,7 @@ import deleteFromDb from 'db' -export function Item(product, foo, bar) { - async function deleteItem() { +export function Item1(product, foo, bar) { + const a = async function deleteItem1() { 'use server' await deleteFromDb( product.id, @@ -10,5 +10,44 @@ export function Item(product, foo, bar) { product[(foo, bar)] ) } - return + return +} + +export function Item2(product, foo, bar) { + async function deleteItem2() { + 'use server' + await deleteFromDb( + product.id, + product?.foo, + product.bar.baz, + product[(foo, bar)] + ) + } + return +} + +export function Item3(product, foo, bar) { + const deleteItem3 = async function () { + 'use server' + await deleteFromDb( + product.id, + product?.foo, + product.bar.baz, + product[(foo, bar)] + ) + } + return +} + +export function Item4(product, foo, bar) { + const deleteItem4 = async () => { + 'use server' + await deleteFromDb( + product.id, + product?.foo, + product.bar.baz, + product[(foo, bar)] + ) + } + return } diff --git a/packages/next-swc/crates/core/tests/fixture/server-actions/server/7/output.js b/packages/next-swc/crates/core/tests/fixture/server-actions/server/7/output.js index 8b539ce494620..b83a85c6f8fa1 100644 --- a/packages/next-swc/crates/core/tests/fixture/server-actions/server/7/output.js +++ b/packages/next-swc/crates/core/tests/fixture/server-actions/server/7/output.js @@ -1,23 +1,63 @@ -/* __next_internal_action_entry_do_not_use__ {"6d53ce510b2e36499b8f56038817b9bad86cabb4":"$$ACTION_0"} */ import { createActionProxy } from "private-next-rsc-action-proxy"; +/* __next_internal_action_entry_do_not_use__ {"1383664d1dc2d9cfe33b88df3fa0eaffef8b99bc":"$$ACTION_5","188d5d945750dc32e2c842b93c75a65763d4a922":"$$ACTION_1","56a859f462d35a297c46a1bbd1e6a9058c104ab8":"$$ACTION_3","6d53ce510b2e36499b8f56038817b9bad86cabb4":"$$ACTION_0"} */ import { createActionProxy } from "private-next-rsc-action-proxy"; import { encryptActionBoundArgs, decryptActionBoundArgs } from "private-next-rsc-action-encryption"; import deleteFromDb from 'db'; -export function Item(product, foo, bar) { - async function deleteItem(...args) { - return $$ACTION_0.apply(null, (deleteItem.$$bound || []).concat(args)); - } - createActionProxy("6d53ce510b2e36499b8f56038817b9bad86cabb4", [ - encryptActionBoundArgs("6d53ce510b2e36499b8f56038817b9bad86cabb4", [ - product.id, - product?.foo, - product.bar.baz, - product, - foo, - bar - ]) - ], deleteItem, $$ACTION_0); - return ; +export function Item1(product, foo, bar) { + const a = createActionProxy("6d53ce510b2e36499b8f56038817b9bad86cabb4", $$ACTION_0).bind(null, encryptActionBoundArgs("6d53ce510b2e36499b8f56038817b9bad86cabb4", [ + product.id, + product?.foo, + product.bar.baz, + product, + foo, + bar + ])); + return ; } export async function $$ACTION_0($$ACTION_CLOSURE_BOUND) { var [$$ACTION_ARG_0, $$ACTION_ARG_1, $$ACTION_ARG_2, $$ACTION_ARG_3, $$ACTION_ARG_4, $$ACTION_ARG_5] = await decryptActionBoundArgs("6d53ce510b2e36499b8f56038817b9bad86cabb4", $$ACTION_CLOSURE_BOUND); await deleteFromDb($$ACTION_ARG_3.id, $$ACTION_ARG_3?.foo, $$ACTION_ARG_3.bar.baz, $$ACTION_ARG_3[$$ACTION_ARG_4, $$ACTION_ARG_5]); } +export function Item2(product, foo, bar) { + function deleteItem2() {} + return ; +} +export async function $$ACTION_1($$ACTION_CLOSURE_BOUND) { + var [$$ACTION_ARG_0, $$ACTION_ARG_1, $$ACTION_ARG_2, $$ACTION_ARG_3, $$ACTION_ARG_4, $$ACTION_ARG_5] = await decryptActionBoundArgs("188d5d945750dc32e2c842b93c75a65763d4a922", $$ACTION_CLOSURE_BOUND); + await deleteFromDb($$ACTION_ARG_3.id, $$ACTION_ARG_3?.foo, $$ACTION_ARG_3.bar.baz, $$ACTION_ARG_3[$$ACTION_ARG_4, $$ACTION_ARG_5]); +} +export function Item3(product, foo, bar) { + const deleteItem3 = createActionProxy("56a859f462d35a297c46a1bbd1e6a9058c104ab8", $$ACTION_3).bind(null, encryptActionBoundArgs("56a859f462d35a297c46a1bbd1e6a9058c104ab8", [ + product.id, + product?.foo, + product.bar.baz, + product, + foo, + bar + ])); + return ; +} +export async function $$ACTION_3($$ACTION_CLOSURE_BOUND) { + var [$$ACTION_ARG_0, $$ACTION_ARG_1, $$ACTION_ARG_2, $$ACTION_ARG_3, $$ACTION_ARG_4, $$ACTION_ARG_5] = await decryptActionBoundArgs("56a859f462d35a297c46a1bbd1e6a9058c104ab8", $$ACTION_CLOSURE_BOUND); + await deleteFromDb($$ACTION_ARG_3.id, $$ACTION_ARG_3?.foo, $$ACTION_ARG_3.bar.baz, $$ACTION_ARG_3[$$ACTION_ARG_4, $$ACTION_ARG_5]); +} +export function Item4(product, foo, bar) { + const deleteItem4 = createActionProxy("1383664d1dc2d9cfe33b88df3fa0eaffef8b99bc", $$ACTION_5).bind(null, encryptActionBoundArgs("1383664d1dc2d9cfe33b88df3fa0eaffef8b99bc", [ + product.id, + product?.foo, + product.bar.baz, + product, + foo, + bar + ])); + return ; +} +export async function $$ACTION_5($$ACTION_CLOSURE_BOUND) { + var [$$ACTION_ARG_0, $$ACTION_ARG_1, $$ACTION_ARG_2, $$ACTION_ARG_3, $$ACTION_ARG_4, $$ACTION_ARG_5] = await decryptActionBoundArgs("1383664d1dc2d9cfe33b88df3fa0eaffef8b99bc", $$ACTION_CLOSURE_BOUND); + await deleteFromDb($$ACTION_ARG_3.id, $$ACTION_ARG_3?.foo, $$ACTION_ARG_3.bar.baz, $$ACTION_ARG_3[$$ACTION_ARG_4, $$ACTION_ARG_5]); +} diff --git a/packages/next-swc/crates/core/tests/fixture/server-actions/server/8/output.js b/packages/next-swc/crates/core/tests/fixture/server-actions/server/8/output.js index 93358366e844f..2ba116bc7de3c 100644 --- a/packages/next-swc/crates/core/tests/fixture/server-actions/server/8/output.js +++ b/packages/next-swc/crates/core/tests/fixture/server-actions/server/8/output.js @@ -1,14 +1,11 @@ /* __next_internal_action_entry_do_not_use__ {"6d53ce510b2e36499b8f56038817b9bad86cabb4":"$$ACTION_0"} */ import { createActionProxy } from "private-next-rsc-action-proxy"; import { encryptActionBoundArgs, decryptActionBoundArgs } from "private-next-rsc-action-encryption"; -async function myAction(...args) { - return $$ACTION_0.apply(null, (myAction.$$bound || []).concat(args)); -} -createActionProxy("6d53ce510b2e36499b8f56038817b9bad86cabb4", null, myAction, $$ACTION_0); +function myAction() {} export async function $$ACTION_0(a, b, c) { // comment 'use strict'; console.log('a'); } export default function Page() { - return ; + return ; } diff --git a/packages/next-swc/crates/core/tests/fixture/server-actions/server/9/output.js b/packages/next-swc/crates/core/tests/fixture/server-actions/server/9/output.js index 38682c5fd5672..9d61cc907880f 100644 --- a/packages/next-swc/crates/core/tests/fixture/server-actions/server/9/output.js +++ b/packages/next-swc/crates/core/tests/fixture/server-actions/server/9/output.js @@ -1,5 +1,5 @@ // app/send.ts -/* __next_internal_action_entry_do_not_use__ {"c18c215a6b7cdc64bf709f3a714ffdef1bf9651d":"default","ab21efdafbe611287bc25c0462b1e0510d13e48b":"foo","050e3854b72b19e3c7e3966a67535543a90bf7e0":"baz"} */ import { createActionProxy } from "private-next-rsc-action-proxy"; +/* __next_internal_action_entry_do_not_use__ {"050e3854b72b19e3c7e3966a67535543a90bf7e0":"baz","ab21efdafbe611287bc25c0462b1e0510d13e48b":"foo","c18c215a6b7cdc64bf709f3a714ffdef1bf9651d":"default"} */ import { createActionProxy } from "private-next-rsc-action-proxy"; import { encryptActionBoundArgs, decryptActionBoundArgs } from "private-next-rsc-action-encryption"; async function foo() {} export { foo }; @@ -13,6 +13,6 @@ ensureServerEntryExports([ bar, qux ]); -createActionProxy("ab21efdafbe611287bc25c0462b1e0510d13e48b", null, foo); -createActionProxy("050e3854b72b19e3c7e3966a67535543a90bf7e0", null, bar); -createActionProxy("c18c215a6b7cdc64bf709f3a714ffdef1bf9651d", null, qux); +createActionProxy("ab21efdafbe611287bc25c0462b1e0510d13e48b", foo); +createActionProxy("050e3854b72b19e3c7e3966a67535543a90bf7e0", bar); +createActionProxy("c18c215a6b7cdc64bf709f3a714ffdef1bf9651d", qux); diff --git a/packages/next/src/build/webpack/loaders/next-flight-loader/action-proxy.ts b/packages/next/src/build/webpack/loaders/next-flight-loader/action-proxy.ts index 0fe5ef99f21fb..0975e2fcc7080 100644 --- a/packages/next/src/build/webpack/loaders/next-flight-loader/action-proxy.ts +++ b/packages/next/src/build/webpack/loaders/next-flight-loader/action-proxy.ts @@ -1,49 +1,6 @@ -const SERVER_REFERENCE_TAG = Symbol.for('react.server.reference') +/* eslint-disable import/no-extraneous-dependencies */ +import { registerServerReference } from 'react-server-dom-webpack/server.edge' -export function createActionProxy( - id: string, - boundArgsFromClosure: null | any[], - action: any, - originalAction?: any -) { - function bindImpl(this: any, _: any, ...boundArgs: any[]) { - const currentAction = this - - const newAction = async function (...args: any[]) { - if (originalAction) { - return originalAction(newAction.$$bound.concat(args)) - } else { - // In this case we're calling the user-defined action directly. - return currentAction(...newAction.$$bound, ...args) - } - } - - for (const key of ['$$typeof', '$$id', '$$FORM_ACTION']) { - // @ts-ignore - newAction[key] = currentAction[key] - } - - // Rebind args - newAction.$$bound = (currentAction.$$bound || []).concat(boundArgs) - - // Assign bind method - newAction.bind = bindImpl.bind(newAction) - - return newAction - } - - Object.defineProperties(action, { - $$typeof: { - value: SERVER_REFERENCE_TAG, - }, - $$id: { - value: id, - }, - $$bound: { - value: boundArgsFromClosure, - }, - bind: { - value: bindImpl, - }, - }) +export function createActionProxy(id: string, action: any) { + return registerServerReference(action, id, null) } From 642ad12c29c8a98c55cd86e026bdfff0b84f6c7a Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Tue, 21 Nov 2023 12:28:34 -0500 Subject: [PATCH 003/481] Seed CacheNodes immediately after receiving response (#58669) ## Based on #58666 *I submitted this stack as separate PRs so I could run CI but I want to land them as a single unit. So I've left all but this last one in draft mode. You can review them commit-by-commit.* We render nested layouts in parallel on the server. This means we should be able to create a CacheNode entry for every layout in the tree as soon as the Flight response is received by the client, even before the nested layouts have streamed in. Currently, we wait until the nested layouts start rendering before we write them into the cache, which prevents us from performing certain optimizations. That's because the CacheNodes are sent as a prop to LayoutRouter; the only way to unwrap the CacheNode is to wait for LayoutRouter to render. In previous PRs, I updated the server to create a top-level data structure that contains all the CacheNodes for the entire tree. This PR updates the client side to receive the nodes and write them into the cache. --------- Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../next/src/client/components/app-router.tsx | 6 +- .../src/client/components/layout-router.tsx | 46 -------- .../router-reducer/apply-flight-data.ts | 9 +- .../apply-router-state-patch-to-tree.test.tsx | 7 +- .../create-initial-router-state.test.tsx | 4 +- .../create-initial-router-state.ts | 21 +++- .../fill-cache-with-new-subtree-data.test.tsx | 2 +- .../fill-cache-with-new-subtree-data.ts | 12 +- ...ll-lazy-items-till-leaf-with-head.test.tsx | 14 ++- .../fill-lazy-items-till-leaf-with-head.ts | 92 +++++++++++---- ...te-cache-below-flight-segmentpath.test.tsx | 5 +- .../reducers/fast-refresh-reducer.ts | 2 +- .../reducers/navigate-reducer.test.tsx | 46 ++++---- .../reducers/navigate-reducer.ts | 4 +- .../reducers/prefetch-reducer.test.tsx | 9 +- .../reducers/refresh-reducer.test.tsx | 31 ++--- .../reducers/refresh-reducer.ts | 10 +- .../reducers/restore-reducer.test.tsx | 6 +- .../reducers/server-action-reducer.ts | 7 +- .../reducers/server-patch-reducer.test.tsx | 14 +-- .../reducers/server-patch-reducer.ts | 6 +- .../should-hard-navigate.test.tsx | 15 +-- .../next/src/server/app-render/app-render.tsx | 30 +++-- .../app-render/create-component-tree.tsx | 54 +++------ packages/next/src/server/app-render/types.ts | 5 +- .../walk-tree-with-flight-router-state.tsx | 108 ++++++++---------- 26 files changed, 277 insertions(+), 288 deletions(-) diff --git a/packages/next/src/client/components/app-router.tsx b/packages/next/src/client/components/app-router.tsx index 574d16a43dc2c..0cd0c44abb209 100644 --- a/packages/next/src/client/components/app-router.tsx +++ b/packages/next/src/client/components/app-router.tsx @@ -255,14 +255,14 @@ function Router({ initialHead, initialTree, initialCanonicalUrl, - children, + initialSeedData, assetPrefix, }: AppRouterProps) { const initialState = useMemo( () => createInitialRouterState({ buildId, - children, + initialSeedData, initialCanonicalUrl, initialTree, initialParallelRoutes, @@ -270,7 +270,7 @@ function Router({ location: !isServer ? window.location : null, initialHead, }), - [buildId, children, initialCanonicalUrl, initialTree, initialHead] + [buildId, initialSeedData, initialCanonicalUrl, initialTree, initialHead] ) const [reducerState, dispatch, sync] = useReducerWithReduxDevtools(initialState) diff --git a/packages/next/src/client/components/layout-router.tsx b/packages/next/src/client/components/layout-router.tsx index 41e067aeb38f6..9401adab52a50 100644 --- a/packages/next/src/client/components/layout-router.tsx +++ b/packages/next/src/client/components/layout-router.tsx @@ -314,7 +314,6 @@ function InnerLayoutRouter({ parallelRouterKey, url, childNodes, - initialChildNode, segmentPath, tree, // TODO-APP: implement `` when available. @@ -324,7 +323,6 @@ function InnerLayoutRouter({ parallelRouterKey: string url: string childNodes: ChildSegmentMap - initialChildNode: React.ReactNode | null segmentPath: FlightSegmentPath tree: FlightRouterState isActive: boolean @@ -340,39 +338,6 @@ function InnerLayoutRouter({ // Read segment path from the parallel router cache node. let childNode = childNodes.get(cacheKey) - // If initialChildNode is available this means it's the Flight / SSR case. - // TODO: `null` is a valid React Node, so technically we should use some other - // value besides `null` to indicate that the tree is partial. However, we're - // about to remove all the cases that lead to a partial tree, so this soon - // won't be an issue. - if (initialChildNode !== null) { - if (!childNode) { - // Add the segment's subTreeData to the cache. - // This writes to the cache when there is no item in the cache yet. It never *overwrites* existing cache items which is why it's safe in concurrent mode. - - // TODO: We should seed all the CacheNodes as soon as the Flight payload - // is received. We already collect them eagerly on the server, so we - // shouldn't need to wait until the render phase to write them into - // the cache. Requires refactoring the Flight response type. Then we can - // delete this code. - childNode = { - status: CacheStates.READY, - data: null, - subTreeData: initialChildNode, - parallelRoutes: new Map(), - } - - childNodes.set(cacheKey, childNode) - } else { - if (childNode.status === CacheStates.LAZY_INITIALIZED) { - // @ts-expect-error we're changing it's type! - childNode.status = CacheStates.READY - // @ts-expect-error - childNode.subTreeData = initialChildNode - } - } - } - // When childNode is not available during rendering client-side we need to fetch it from the server. if (!childNode || childNode.status === CacheStates.LAZY_INITIALIZED) { /** @@ -503,8 +468,6 @@ function LoadingBoundary({ export default function OuterLayoutRouter({ parallelRouterKey, segmentPath, - initialChildNode, - childPropSegment, error, errorStyles, errorScripts, @@ -521,8 +484,6 @@ export default function OuterLayoutRouter({ }: { parallelRouterKey: string segmentPath: FlightSegmentPath - initialChildNode: React.ReactNode | null - childPropSegment: Segment error: ErrorComponent errorStyles: React.ReactNode | undefined errorScripts: React.ReactNode | undefined @@ -570,10 +531,6 @@ export default function OuterLayoutRouter({ <> {styles} {preservedSegments.map((preservedSegment) => { - const isChildPropSegment = matchSegment( - preservedSegment, - childPropSegment - ) const preservedSegmentValue = getSegmentValue(preservedSegment) const cacheKey = createRouterCacheKey(preservedSegment) @@ -612,9 +569,6 @@ export default function OuterLayoutRouter({ url={url} tree={tree} childNodes={childNodesForParallelRouter!} - initialChildNode={ - isChildPropSegment ? initialChildNode : null - } segmentPath={segmentPath} cacheKey={cacheKey} isActive={ diff --git a/packages/next/src/client/components/router-reducer/apply-flight-data.ts b/packages/next/src/client/components/router-reducer/apply-flight-data.ts index 3eb8ea1b04a20..accdcd89aefa9 100644 --- a/packages/next/src/client/components/router-reducer/apply-flight-data.ts +++ b/packages/next/src/client/components/router-reducer/apply-flight-data.ts @@ -11,21 +11,22 @@ export function applyFlightData( wasPrefetched: boolean = false ): boolean { // The one before last item is the router state tree patch - const [treePatch, subTreeData, head /* , cacheNodeSeedData */] = - flightDataPath.slice(-4) + const [treePatch, cacheNodeSeedData, head] = flightDataPath.slice(-3) // Handles case where prefetch only returns the router tree patch without rendered components. - if (subTreeData === null) { + if (cacheNodeSeedData === null) { return false } - if (flightDataPath.length === 4) { + if (flightDataPath.length === 3) { + const subTreeData = cacheNodeSeedData[2] cache.status = CacheStates.READY cache.subTreeData = subTreeData fillLazyItemsTillLeafWithHead( cache, existingCache, treePatch, + cacheNodeSeedData, head, wasPrefetched ) diff --git a/packages/next/src/client/components/router-reducer/apply-router-state-patch-to-tree.test.tsx b/packages/next/src/client/components/router-reducer/apply-router-state-patch-to-tree.test.tsx index 511ec02a8b8b5..2b6892eb93ce8 100644 --- a/packages/next/src/client/components/router-reducer/apply-router-state-patch-to-tree.test.tsx +++ b/packages/next/src/client/components/router-reducer/apply-router-state-patch-to-tree.test.tsx @@ -33,11 +33,10 @@ const getFlightData = (): FlightData => { children: ['', {}], }, ], -

About Page!

, + ['about', null,

About Page!

], <> About page! , - null, ], ] } @@ -53,8 +52,8 @@ describe('applyRouterStatePatchToTree', () => { // Mirrors the way router-reducer values are passed in. const flightDataPath = flightData[0] - const [treePatch /*, subTreeData, head*/] = flightDataPath.slice(-4) - const flightSegmentPath = flightDataPath.slice(0, -5) + const [treePatch /*, cacheNodeSeedData, head*/] = flightDataPath.slice(-3) + const flightSegmentPath = flightDataPath.slice(0, -4) const newRouterStateTree = applyRouterStatePatchToTree( ['', ...flightSegmentPath], diff --git a/packages/next/src/client/components/router-reducer/create-initial-router-state.test.tsx b/packages/next/src/client/components/router-reducer/create-initial-router-state.test.tsx index c605eb281802c..274b9b7f7af5f 100644 --- a/packages/next/src/client/components/router-reducer/create-initial-router-state.test.tsx +++ b/packages/next/src/client/components/router-reducer/create-initial-router-state.test.tsx @@ -37,7 +37,7 @@ describe('createInitialRouterState', () => { buildId, initialTree, initialCanonicalUrl, - children, + initialSeedData: ['', null, children], initialParallelRoutes, isServer: false, location: new URL('/linking', 'https://localhost') as any, @@ -48,7 +48,7 @@ describe('createInitialRouterState', () => { buildId, initialTree, initialCanonicalUrl, - children, + initialSeedData: ['', null, children], initialParallelRoutes, isServer: false, location: new URL('/linking', 'https://localhost') as any, diff --git a/packages/next/src/client/components/router-reducer/create-initial-router-state.ts b/packages/next/src/client/components/router-reducer/create-initial-router-state.ts index c112997f72ae6..8e2c6402a1548 100644 --- a/packages/next/src/client/components/router-reducer/create-initial-router-state.ts +++ b/packages/next/src/client/components/router-reducer/create-initial-router-state.ts @@ -1,6 +1,9 @@ import type { ReactNode } from 'react' import type { CacheNode } from '../../../shared/lib/app-router-context.shared-runtime' -import type { FlightRouterState } from '../../../server/app-render/types' +import type { + FlightRouterState, + CacheNodeSeedData, +} from '../../../server/app-render/types' import { CacheStates } from '../../../shared/lib/app-router-context.shared-runtime' import { createHrefFromUrl } from './create-href-from-url' @@ -11,7 +14,7 @@ export interface InitialRouterStateParameters { buildId: string initialTree: FlightRouterState initialCanonicalUrl: string - children: ReactNode + initialSeedData: CacheNodeSeedData initialParallelRoutes: CacheNode['parallelRoutes'] isServer: boolean location: Location | null @@ -21,24 +24,32 @@ export interface InitialRouterStateParameters { export function createInitialRouterState({ buildId, initialTree, - children, + initialSeedData, initialCanonicalUrl, initialParallelRoutes, isServer, location, initialHead, }: InitialRouterStateParameters) { + const subTreeData = initialSeedData[2] + const cache: CacheNode = { status: CacheStates.READY, data: null, - subTreeData: children, + subTreeData: subTreeData, // The cache gets seeded during the first render. `initialParallelRoutes` ensures the cache from the first render is there during the second render. parallelRoutes: isServer ? new Map() : initialParallelRoutes, } // When the cache hasn't been seeded yet we fill the cache with the head. if (initialParallelRoutes === null || initialParallelRoutes.size === 0) { - fillLazyItemsTillLeafWithHead(cache, undefined, initialTree, initialHead) + fillLazyItemsTillLeafWithHead( + cache, + undefined, + initialTree, + initialSeedData, + initialHead + ) } return { diff --git a/packages/next/src/client/components/router-reducer/fill-cache-with-new-subtree-data.test.tsx b/packages/next/src/client/components/router-reducer/fill-cache-with-new-subtree-data.test.tsx index d81ee63e12817..cd6d5e561cba4 100644 --- a/packages/next/src/client/components/router-reducer/fill-cache-with-new-subtree-data.test.tsx +++ b/packages/next/src/client/components/router-reducer/fill-cache-with-new-subtree-data.test.tsx @@ -17,7 +17,7 @@ const getFlightData = (): FlightData => { children: ['', {}], }, ], -

SubTreeData Injected!

, + ['about', null,

SubTreeData Injected!

], <> Head Injected! , diff --git a/packages/next/src/client/components/router-reducer/fill-cache-with-new-subtree-data.ts b/packages/next/src/client/components/router-reducer/fill-cache-with-new-subtree-data.ts index 028dd91f81034..4668dfd8f48ac 100644 --- a/packages/next/src/client/components/router-reducer/fill-cache-with-new-subtree-data.ts +++ b/packages/next/src/client/components/router-reducer/fill-cache-with-new-subtree-data.ts @@ -1,6 +1,9 @@ import { CacheStates } from '../../../shared/lib/app-router-context.shared-runtime' import type { CacheNode } from '../../../shared/lib/app-router-context.shared-runtime' -import type { FlightDataPath } from '../../../server/app-render/types' +import type { + FlightDataPath, + CacheNodeSeedData, +} from '../../../server/app-render/types' import { invalidateCacheByRouterState } from './invalidate-cache-by-router-state' import { fillLazyItemsTillLeafWithHead } from './fill-lazy-items-till-leaf-with-head' import { createRouterCacheKey } from './create-router-cache-key' @@ -14,7 +17,7 @@ export function fillCacheWithNewSubTreeData( flightDataPath: FlightDataPath, wasPrefetched?: boolean ): void { - const isLastEntry = flightDataPath.length <= 6 + const isLastEntry = flightDataPath.length <= 5 const [parallelRouteKey, segment] = flightDataPath const cacheKey = createRouterCacheKey(segment) @@ -43,10 +46,12 @@ export function fillCacheWithNewSubTreeData( !childCacheNode.data || childCacheNode === existingChildCacheNode ) { + const seedData: CacheNodeSeedData = flightDataPath[3] + const subTreeData = seedData[2] childCacheNode = { status: CacheStates.READY, data: null, - subTreeData: flightDataPath[3], + subTreeData, // Ensure segments other than the one we got data for are preserved. parallelRoutes: existingChildCacheNode ? new Map(existingChildCacheNode.parallelRoutes) @@ -65,6 +70,7 @@ export function fillCacheWithNewSubTreeData( childCacheNode, existingChildCacheNode, flightDataPath[2], + seedData, flightDataPath[4], wasPrefetched ) diff --git a/packages/next/src/client/components/router-reducer/fill-lazy-items-till-leaf-with-head.test.tsx b/packages/next/src/client/components/router-reducer/fill-lazy-items-till-leaf-with-head.test.tsx index 2adfd8a055b82..824c58c31090b 100644 --- a/packages/next/src/client/components/router-reducer/fill-lazy-items-till-leaf-with-head.test.tsx +++ b/packages/next/src/client/components/router-reducer/fill-lazy-items-till-leaf-with-head.test.tsx @@ -26,11 +26,10 @@ const getFlightData = (): FlightData => { null, true, ], -

About Page!

, + ['', null,

About Page!

], <> About page! , - null, ], ] } @@ -88,9 +87,14 @@ describe('fillLazyItemsTillLeafWithHead', () => { // Mirrors the way router-reducer values are passed in. const flightDataPath = flightData[0] - // eslint-disable-next-line @typescript-eslint/no-unused-vars - const [treePatch, _subTreeData, head] = flightDataPath.slice(-4) - fillLazyItemsTillLeafWithHead(cache, existingCache, treePatch, head) + const [treePatch, cacheNodeSeedData, head] = flightDataPath.slice(-3) + fillLazyItemsTillLeafWithHead( + cache, + existingCache, + treePatch, + cacheNodeSeedData, + head + ) const expectedCache: CacheNode = { data: null, diff --git a/packages/next/src/client/components/router-reducer/fill-lazy-items-till-leaf-with-head.ts b/packages/next/src/client/components/router-reducer/fill-lazy-items-till-leaf-with-head.ts index 4292b7f4607a0..12f4a712ae114 100644 --- a/packages/next/src/client/components/router-reducer/fill-lazy-items-till-leaf-with-head.ts +++ b/packages/next/src/client/components/router-reducer/fill-lazy-items-till-leaf-with-head.ts @@ -1,12 +1,16 @@ import { CacheStates } from '../../../shared/lib/app-router-context.shared-runtime' import type { CacheNode } from '../../../shared/lib/app-router-context.shared-runtime' -import type { FlightRouterState } from '../../../server/app-render/types' +import type { + FlightRouterState, + CacheNodeSeedData, +} from '../../../server/app-render/types' import { createRouterCacheKey } from './create-router-cache-key' export function fillLazyItemsTillLeafWithHead( newCache: CacheNode, existingCache: CacheNode | undefined, routerState: FlightRouterState, + cacheNodeSeedData: CacheNodeSeedData | null, head: React.ReactNode, wasPrefetched?: boolean ): void { @@ -21,26 +25,58 @@ export function fillLazyItemsTillLeafWithHead( const segmentForParallelRoute = parallelRouteState[0] const cacheKey = createRouterCacheKey(segmentForParallelRoute) + // TODO: We should traverse the cacheNodeSeedData tree instead of the router + // state tree. Ideally, they would always be the same shape, but because of + // the loading.js pattern, cacheNodeSeedData sometimes only represents a + // partial tree. That's why this node is sometimes null. Once PPR lands, + // loading.js will no longer have special behavior and we can traverse the + // data tree instead. + // + // We should also consider merging the router state tree and the data tree + // in the response format, so that we don't have to send the keys twice. + // Then the client can convert them into separate representations. + const parallelSeedData = + cacheNodeSeedData !== null && + cacheNodeSeedData[1] !== null && + cacheNodeSeedData[1][key] !== undefined + ? cacheNodeSeedData[1][key] + : null if (existingCache) { const existingParallelRoutesCacheNode = existingCache.parallelRoutes.get(key) if (existingParallelRoutesCacheNode) { let parallelRouteCacheNode = new Map(existingParallelRoutesCacheNode) const existingCacheNode = parallelRouteCacheNode.get(cacheKey) - const newCacheNode: CacheNode = - wasPrefetched && existingCacheNode - ? ({ - status: existingCacheNode.status, - data: existingCacheNode.data, - subTreeData: existingCacheNode.subTreeData, - parallelRoutes: new Map(existingCacheNode.parallelRoutes), - } as CacheNode) - : { - status: CacheStates.LAZY_INITIALIZED, - data: null, - subTreeData: null, - parallelRoutes: new Map(existingCacheNode?.parallelRoutes), - } + let newCacheNode: CacheNode + if (parallelSeedData !== null) { + // New data was sent from the server. + const seedNode = parallelSeedData[2] + newCacheNode = { + status: CacheStates.READY, + data: null, + subTreeData: seedNode, + parallelRoutes: new Map(existingCacheNode?.parallelRoutes), + } + } else if (wasPrefetched && existingCacheNode) { + // No new data was sent from the server, but the existing cache node + // was prefetched, so we should reuse that. + newCacheNode = { + status: existingCacheNode.status, + data: existingCacheNode.data, + subTreeData: existingCacheNode.subTreeData, + parallelRoutes: new Map(existingCacheNode.parallelRoutes), + } as CacheNode + } else { + // No data available for this node. This will trigger a lazy fetch + // during render. + newCacheNode = { + status: CacheStates.LAZY_INITIALIZED, + data: null, + subTreeData: null, + parallelRoutes: new Map(existingCacheNode?.parallelRoutes), + } + } + // Overrides the cache key with the new cache node. parallelRouteCacheNode.set(cacheKey, newCacheNode) // Traverse deeper to apply the head / fill lazy items till the head. @@ -48,6 +84,7 @@ export function fillLazyItemsTillLeafWithHead( newCacheNode, existingCacheNode, parallelRouteState, + parallelSeedData ? parallelSeedData : null, head, wasPrefetched ) @@ -57,11 +94,25 @@ export function fillLazyItemsTillLeafWithHead( } } - const newCacheNode: CacheNode = { - status: CacheStates.LAZY_INITIALIZED, - data: null, - subTreeData: null, - parallelRoutes: new Map(), + let newCacheNode: CacheNode + if (parallelSeedData !== null) { + // New data was sent from the server. + const seedNode = parallelSeedData[2] + newCacheNode = { + status: CacheStates.READY, + data: null, + subTreeData: seedNode, + parallelRoutes: new Map(), + } + } else { + // No data available for this node. This will trigger a lazy fetch + // during render. + newCacheNode = { + status: CacheStates.LAZY_INITIALIZED, + data: null, + subTreeData: null, + parallelRoutes: new Map(), + } } const existingParallelRoutes = newCache.parallelRoutes.get(key) @@ -75,6 +126,7 @@ export function fillLazyItemsTillLeafWithHead( newCacheNode, undefined, parallelRouteState, + parallelSeedData, head, wasPrefetched ) diff --git a/packages/next/src/client/components/router-reducer/invalidate-cache-below-flight-segmentpath.test.tsx b/packages/next/src/client/components/router-reducer/invalidate-cache-below-flight-segmentpath.test.tsx index 4c548663c4a6c..08bdcd2c4ad78 100644 --- a/packages/next/src/client/components/router-reducer/invalidate-cache-below-flight-segmentpath.test.tsx +++ b/packages/next/src/client/components/router-reducer/invalidate-cache-below-flight-segmentpath.test.tsx @@ -18,11 +18,10 @@ const getFlightData = (): FlightData => { children: ['', {}], }, ], -

About Page!

, + ['about', null,

About Page!

], <> About page! , - null, ], ] } @@ -80,7 +79,7 @@ describe('invalidateCacheBelowFlightSegmentPath', () => { // Mirrors the way router-reducer values are passed in. const flightDataPath = flightData[0] - const flightSegmentPath = flightDataPath.slice(0, -4) + const flightSegmentPath = flightDataPath.slice(0, -3) // @ts-expect-error TODO-APP: investigate why this is not a TS error in router-reducer. cache.status = CacheStates.READY diff --git a/packages/next/src/client/components/router-reducer/reducers/fast-refresh-reducer.ts b/packages/next/src/client/components/router-reducer/reducers/fast-refresh-reducer.ts index f5bbc54baac44..e02151925823d 100644 --- a/packages/next/src/client/components/router-reducer/reducers/fast-refresh-reducer.ts +++ b/packages/next/src/client/components/router-reducer/reducers/fast-refresh-reducer.ts @@ -59,7 +59,7 @@ function fastRefreshReducerImpl( for (const flightDataPath of flightData) { // FlightDataPath with more than two items means unexpected Flight data was returned - if (flightDataPath.length !== 4) { + if (flightDataPath.length !== 3) { // TODO-APP: handle this case better console.log('REFRESH FAILED') return state diff --git a/packages/next/src/client/components/router-reducer/reducers/navigate-reducer.test.tsx b/packages/next/src/client/components/router-reducer/reducers/navigate-reducer.test.tsx index c07c560d8173f..95dbaa10243ce 100644 --- a/packages/next/src/client/components/router-reducer/reducers/navigate-reducer.test.tsx +++ b/packages/next/src/client/components/router-reducer/reducers/navigate-reducer.test.tsx @@ -28,11 +28,10 @@ const flightData: FlightData = [ children: ['__PAGE__', {}], }, ], -

About Page!

, + ['about', null,

About Page!

], <> About page! , - null, ], ] @@ -57,14 +56,17 @@ const demographicsFlightData: FlightData = [ null, true, ], - - - Root layout from response - , + [ + '', + null, + + + Root layout from response + , + ], <> Demographics Head , - null, ], ] @@ -173,7 +175,7 @@ describe('navigateReducer', () => { initialTree, initialHead: null, initialCanonicalUrl, - children, + initialSeedData: ['', null, children], initialParallelRoutes, isServer: false, location: new URL('/linking', 'https://localhost') as any, @@ -375,7 +377,7 @@ describe('navigateReducer', () => { initialTree, initialHead: null, initialCanonicalUrl, - children, + initialSeedData: ['', null, children], initialParallelRoutes, isServer: false, location: new URL('/linking', 'https://localhost') as any, @@ -386,7 +388,7 @@ describe('navigateReducer', () => { initialTree, initialHead: null, initialCanonicalUrl, - children, + initialSeedData: ['', null, children], initialParallelRoutes, isServer: false, location: new URL('/linking', 'https://localhost') as any, @@ -567,7 +569,7 @@ describe('navigateReducer', () => { initialTree, initialHead: null, initialCanonicalUrl, - children, + initialSeedData: ['', null, children], initialParallelRoutes, isServer: false, location: new URL('/linking', 'https://localhost') as any, @@ -578,7 +580,7 @@ describe('navigateReducer', () => { initialTree, initialHead: null, initialCanonicalUrl, - children, + initialSeedData: ['', null, children], initialParallelRoutes, isServer: false, location: new URL('/linking', 'https://localhost') as any, @@ -726,7 +728,7 @@ describe('navigateReducer', () => { initialTree, initialHead: null, initialCanonicalUrl, - children, + initialSeedData: ['', null, children], initialParallelRoutes, isServer: false, location: new URL('/linking', 'https://localhost') as any, @@ -737,7 +739,7 @@ describe('navigateReducer', () => { initialTree, initialHead: null, initialCanonicalUrl, - children, + initialSeedData: ['', null, children], initialParallelRoutes, isServer: false, location: new URL('/linking', 'https://localhost') as any, @@ -885,7 +887,7 @@ describe('navigateReducer', () => { initialTree, initialHead: null, initialCanonicalUrl, - children, + initialSeedData: ['', null, children], initialParallelRoutes, isServer: false, location: new URL('/linking', 'https://localhost') as any, @@ -896,7 +898,7 @@ describe('navigateReducer', () => { initialTree, initialHead: null, initialCanonicalUrl, - children, + initialSeedData: ['', null, children], initialParallelRoutes, isServer: false, location: new URL('/linking#hash', 'https://localhost') as any, @@ -1048,7 +1050,7 @@ describe('navigateReducer', () => { initialTree, initialHead: null, initialCanonicalUrl, - children, + initialSeedData: ['', null, children], initialParallelRoutes, isServer: false, location: new URL('/linking', 'https://localhost') as any, @@ -1063,7 +1065,7 @@ describe('navigateReducer', () => { initialTree, initialHead: null, initialCanonicalUrl, - children, + initialSeedData: ['', null, children], initialParallelRoutes, isServer: false, location: new URL('/linking', 'https://localhost') as any, @@ -1338,7 +1340,7 @@ describe('navigateReducer', () => { initialTree, initialHead: null, initialCanonicalUrl, - children, + initialSeedData: ['', null, children], initialParallelRoutes, isServer: false, location: new URL('/parallel-tab-bar', 'https://localhost') as any, @@ -1349,7 +1351,7 @@ describe('navigateReducer', () => { initialTree, initialHead: null, initialCanonicalUrl, - children, + initialSeedData: ['', null, children], initialParallelRoutes, isServer: false, location: new URL('/parallel-tab-bar', 'https://localhost') as any, @@ -1554,7 +1556,7 @@ describe('navigateReducer', () => { initialTree, initialHead: null, initialCanonicalUrl, - children, + initialSeedData: ['', null, children], initialParallelRoutes, isServer: false, location: new URL('/linking#hash', 'https://localhost') as any, @@ -1704,7 +1706,7 @@ describe('navigateReducer', () => { initialTree, initialHead: null, initialCanonicalUrl, - children, + initialSeedData: ['', null, children], initialParallelRoutes, isServer: false, location: new URL('/linking', 'https://localhost') as any, diff --git a/packages/next/src/client/components/router-reducer/reducers/navigate-reducer.ts b/packages/next/src/client/components/router-reducer/reducers/navigate-reducer.ts index 1dcd6a15ca23b..c27d480865e26 100644 --- a/packages/next/src/client/components/router-reducer/reducers/navigate-reducer.ts +++ b/packages/next/src/client/components/router-reducer/reducers/navigate-reducer.ts @@ -175,10 +175,10 @@ export function navigateReducer( for (const flightDataPath of flightData) { const flightSegmentPath = flightDataPath.slice( 0, - -5 + -4 ) as unknown as FlightSegmentPath // The one before last item is the router state tree patch - const treePatch = flightDataPath.slice(-4)[0] as FlightRouterState + const treePatch = flightDataPath.slice(-3)[0] as FlightRouterState // TODO-APP: remove '' const flightSegmentPathWithLeadingEmpty = ['', ...flightSegmentPath] diff --git a/packages/next/src/client/components/router-reducer/reducers/prefetch-reducer.test.tsx b/packages/next/src/client/components/router-reducer/reducers/prefetch-reducer.test.tsx index 71e7cc30c7f6e..a30b46e811183 100644 --- a/packages/next/src/client/components/router-reducer/reducers/prefetch-reducer.test.tsx +++ b/packages/next/src/client/components/router-reducer/reducers/prefetch-reducer.test.tsx @@ -23,11 +23,10 @@ jest.mock('../fetch-server-response', () => { children: ['', {}], }, ], -

About Page!

, + ['about', null,

About Page!

], <> About page! , - null, ], ] return { @@ -118,7 +117,7 @@ describe('prefetchReducer', () => { initialTree, initialHead: null, initialCanonicalUrl, - children, + initialSeedData: ['', null, children], initialParallelRoutes, isServer: false, location: new URL('/linking', 'https://localhost') as any, @@ -260,7 +259,7 @@ describe('prefetchReducer', () => { initialTree, initialHead: null, initialCanonicalUrl, - children, + initialSeedData: ['', null, children], initialParallelRoutes, isServer: false, location: new URL('/linking', 'https://localhost') as any, @@ -271,7 +270,7 @@ describe('prefetchReducer', () => { initialTree, initialHead: null, initialCanonicalUrl, - children, + initialSeedData: ['', null, children], initialParallelRoutes, isServer: false, location: new URL('/linking', 'https://localhost') as any, diff --git a/packages/next/src/client/components/router-reducer/reducers/refresh-reducer.test.tsx b/packages/next/src/client/components/router-reducer/reducers/refresh-reducer.test.tsx index 9692c88a12bd6..934cbf9b9dfa0 100644 --- a/packages/next/src/client/components/router-reducer/reducers/refresh-reducer.test.tsx +++ b/packages/next/src/client/components/router-reducer/reducers/refresh-reducer.test.tsx @@ -27,16 +27,19 @@ jest.mock('../fetch-server-response', () => { null, true, ], - - - -

Linking Page!

- - , + [ + '', + null, + + + +

Linking Page!

+ + , + ], <> Linking page! , - null, ], ] return { @@ -125,7 +128,7 @@ describe('refreshReducer', () => { initialTree, initialHead: null, initialCanonicalUrl, - children, + initialSeedData: ['', null, children], initialParallelRoutes, isServer: false, location: new URL('/linking', 'https://localhost') as any, @@ -275,7 +278,7 @@ describe('refreshReducer', () => { initialTree, initialHead: null, initialCanonicalUrl, - children, + initialSeedData: ['', null, children], initialParallelRoutes, isServer: false, location: new URL('/linking', 'https://localhost') as any, @@ -286,7 +289,7 @@ describe('refreshReducer', () => { initialTree, initialHead: null, initialCanonicalUrl, - children, + initialSeedData: ['', null, children], initialParallelRoutes, isServer: false, location: new URL('/linking', 'https://localhost') as any, @@ -463,7 +466,7 @@ describe('refreshReducer', () => { initialTree, initialHead: null, initialCanonicalUrl, - children, + initialSeedData: ['', null, children], initialParallelRoutes, isServer: false, location: new URL('/linking', 'https://localhost') as any, @@ -474,7 +477,7 @@ describe('refreshReducer', () => { initialTree, initialHead: null, initialCanonicalUrl, - children, + initialSeedData: ['', null, children], initialParallelRoutes, isServer: false, location: new URL('/linking', 'https://localhost') as any, @@ -697,7 +700,7 @@ describe('refreshReducer', () => { initialTree, initialHead: null, initialCanonicalUrl, - children, + initialSeedData: ['', null, children], initialParallelRoutes, isServer: false, location: new URL('/linking', 'https://localhost') as any, @@ -710,7 +713,7 @@ describe('refreshReducer', () => { initialTree, initialHead: null, initialCanonicalUrl, - children, + initialSeedData: ['', null, children], initialParallelRoutes, isServer: false, location: new URL('/linking', 'https://localhost') as any, diff --git a/packages/next/src/client/components/router-reducer/reducers/refresh-reducer.ts b/packages/next/src/client/components/router-reducer/reducers/refresh-reducer.ts index 12ddc6921407c..bf9571e6a11d8 100644 --- a/packages/next/src/client/components/router-reducer/reducers/refresh-reducer.ts +++ b/packages/next/src/client/components/router-reducer/reducers/refresh-reducer.ts @@ -57,8 +57,8 @@ export function refreshReducer( cache.data = null for (const flightDataPath of flightData) { - // FlightDataPath with more than four items means unexpected Flight data was returned - if (flightDataPath.length !== 4) { + // FlightDataPath with more than two items means unexpected Flight data was returned + if (flightDataPath.length !== 3) { // TODO-APP: handle this case better console.log('REFRESH FAILED') return state @@ -95,10 +95,11 @@ export function refreshReducer( } // The one before last item is the router state tree patch - const [subTreeData, head] = flightDataPath.slice(-3) + const [cacheNodeSeedData, head] = flightDataPath.slice(-2) // Handles case where prefetch only returns the router tree patch without rendered components. - if (subTreeData !== null) { + if (cacheNodeSeedData !== null) { + const subTreeData = cacheNodeSeedData[2] cache.status = CacheStates.READY cache.subTreeData = subTreeData fillLazyItemsTillLeafWithHead( @@ -106,6 +107,7 @@ export function refreshReducer( // Existing cache is not passed in as `router.refresh()` has to invalidate the entire cache. undefined, treePatch, + cacheNodeSeedData, head ) mutable.cache = cache diff --git a/packages/next/src/client/components/router-reducer/reducers/restore-reducer.test.tsx b/packages/next/src/client/components/router-reducer/reducers/restore-reducer.test.tsx index 3a890266ba962..50b1d2be335e9 100644 --- a/packages/next/src/client/components/router-reducer/reducers/restore-reducer.test.tsx +++ b/packages/next/src/client/components/router-reducer/reducers/restore-reducer.test.tsx @@ -84,7 +84,7 @@ describe('serverPatchReducer', () => { initialTree, initialHead: null, initialCanonicalUrl, - children, + initialSeedData: ['', null, children], initialParallelRoutes, isServer: false, location: new URL('/linking', 'https://localhost') as any, @@ -239,7 +239,7 @@ describe('serverPatchReducer', () => { initialTree, initialHead: null, initialCanonicalUrl, - children, + initialSeedData: ['', null, children], initialParallelRoutes, isServer: false, location: new URL('/linking', 'https://localhost') as any, @@ -249,7 +249,7 @@ describe('serverPatchReducer', () => { initialTree, initialHead: null, initialCanonicalUrl, - children, + initialSeedData: ['', null, children], initialParallelRoutes, isServer: false, location: new URL('/linking', 'https://localhost') as any, diff --git a/packages/next/src/client/components/router-reducer/reducers/server-action-reducer.ts b/packages/next/src/client/components/router-reducer/reducers/server-action-reducer.ts index f6f2f8f728f4b..05f4b1d370cdf 100644 --- a/packages/next/src/client/components/router-reducer/reducers/server-action-reducer.ts +++ b/packages/next/src/client/components/router-reducer/reducers/server-action-reducer.ts @@ -206,7 +206,7 @@ export function serverActionReducer( for (const flightDataPath of flightData) { // FlightDataPath with more than two items means unexpected Flight data was returned - if (flightDataPath.length !== 4) { + if (flightDataPath.length !== 3) { // TODO-APP: handle this case better console.log('SERVER ACTION APPLY FAILED') return state @@ -235,7 +235,9 @@ export function serverActionReducer( } // The one before last item is the router state tree patch - const [subTreeData, head] = flightDataPath.slice(-3) + const [cacheNodeSeedData, head] = flightDataPath.slice(-2) + const subTreeData = + cacheNodeSeedData !== null ? cacheNodeSeedData[2] : null // Handles case where prefetch only returns the router tree patch without rendered components. if (subTreeData !== null) { @@ -246,6 +248,7 @@ export function serverActionReducer( // Existing cache is not passed in as `router.refresh()` has to invalidate the entire cache. undefined, treePatch, + cacheNodeSeedData, head ) mutable.cache = cache diff --git a/packages/next/src/client/components/router-reducer/reducers/server-patch-reducer.test.tsx b/packages/next/src/client/components/router-reducer/reducers/server-patch-reducer.test.tsx index 65738a74218c7..f357caa2f3a59 100644 --- a/packages/next/src/client/components/router-reducer/reducers/server-patch-reducer.test.tsx +++ b/packages/next/src/client/components/router-reducer/reducers/server-patch-reducer.test.tsx @@ -26,11 +26,10 @@ jest.mock('../fetch-server-response', () => { children: ['', {}], }, ], -

About Page!

, + ['about', null,

About Page!

], <> About page! , - null, ], ] return { @@ -58,11 +57,10 @@ const flightDataForPatch: FlightData = [ children: ['', {}], }, ], -

Somewhere Page!

, + ['somewhere-else', null,

Somewhere Page!

], <> Somewhere page! , - null, ], ] @@ -150,7 +148,7 @@ describe('serverPatchReducer', () => { initialTree, initialHead: null, initialCanonicalUrl, - children, + initialSeedData: ['', null, children], initialParallelRoutes, isServer: false, location: new URL('/linking/about', 'https://localhost') as any, @@ -330,7 +328,7 @@ describe('serverPatchReducer', () => { initialTree, initialHead: null, initialCanonicalUrl, - children, + initialSeedData: ['', null, children], initialParallelRoutes, isServer: false, location: new URL('/linking/about', 'https://localhost') as any, @@ -341,7 +339,7 @@ describe('serverPatchReducer', () => { initialTree, initialHead: null, initialCanonicalUrl, - children, + initialSeedData: ['', null, children], initialParallelRoutes, isServer: false, location: new URL('/linking/about', 'https://localhost') as any, @@ -518,7 +516,7 @@ describe('serverPatchReducer', () => { initialTree, initialHead: null, initialCanonicalUrl, - children, + initialSeedData: ['', null, children], initialParallelRoutes, isServer: false, location: new URL(initialCanonicalUrl, 'https://localhost') as any, diff --git a/packages/next/src/client/components/router-reducer/reducers/server-patch-reducer.ts b/packages/next/src/client/components/router-reducer/reducers/server-patch-reducer.ts index fbc2e67d5ec2e..2c9200793b601 100644 --- a/packages/next/src/client/components/router-reducer/reducers/server-patch-reducer.ts +++ b/packages/next/src/client/components/router-reducer/reducers/server-patch-reducer.ts @@ -49,10 +49,10 @@ export function serverPatchReducer( let currentCache = state.cache for (const flightDataPath of flightData) { - // Slices off the last segment (which is at -5) as it doesn't exist in the tree yet - const flightSegmentPath = flightDataPath.slice(0, -5) + // Slices off the last segment (which is at -4) as it doesn't exist in the tree yet + const flightSegmentPath = flightDataPath.slice(0, -4) - const [treePatch] = flightDataPath.slice(-4, -3) + const [treePatch] = flightDataPath.slice(-3, -2) const newTree = applyRouterStatePatchToTree( // TODO-APP: remove '' ['', ...flightSegmentPath], diff --git a/packages/next/src/client/components/router-reducer/should-hard-navigate.test.tsx b/packages/next/src/client/components/router-reducer/should-hard-navigate.test.tsx index 766160907ee16..5a9b52593f858 100644 --- a/packages/next/src/client/components/router-reducer/should-hard-navigate.test.tsx +++ b/packages/next/src/client/components/router-reducer/should-hard-navigate.test.tsx @@ -35,11 +35,10 @@ describe('shouldHardNavigate', () => { children: ['', {}], }, ], -

About Page!

, + ['about', null,

About Page!

], <> About page! , - null, ], ] } @@ -51,7 +50,7 @@ describe('shouldHardNavigate', () => { // Mirrors the way router-reducer values are passed in. const flightDataPath = flightData[0] - const flightSegmentPath = flightDataPath.slice(0, -4) + const flightSegmentPath = flightDataPath.slice(0, -3) const result = shouldHardNavigate( ['', ...flightSegmentPath], @@ -95,8 +94,7 @@ describe('shouldHardNavigate', () => { children: ['', {}], }, ], - null, - null, + [['id', '123', 'd'], null, null], null, ], ] @@ -109,7 +107,7 @@ describe('shouldHardNavigate', () => { // Mirrors the way router-reducer values are passed in. const flightDataPath = flightData[0] - const flightSegmentPath = flightDataPath.slice(0, -4) + const flightSegmentPath = flightDataPath.slice(0, -3) const result = shouldHardNavigate( ['', ...flightSegmentPath], @@ -153,8 +151,7 @@ describe('shouldHardNavigate', () => { children: ['', {}], }, ], - null, - null, + [['id', '123', 'd'], null, null], null, ], ] @@ -167,7 +164,7 @@ describe('shouldHardNavigate', () => { // Mirrors the way router-reducer values are passed in. const flightDataPath = flightData[0] - const flightSegmentPath = flightDataPath.slice(0, -4) + const flightSegmentPath = flightDataPath.slice(0, -3) const result = shouldHardNavigate( ['', ...flightSegmentPath], diff --git a/packages/next/src/server/app-render/app-render.tsx b/packages/next/src/server/app-render/app-render.tsx index bfad64d2e6cb7..840d873002822 100644 --- a/packages/next/src/server/app-render/app-render.tsx +++ b/packages/next/src/server/app-render/app-render.tsx @@ -7,6 +7,7 @@ import type { FlightSegmentPath, RenderOpts, Segment, + CacheNodeSeedData, } from './types' import type { StaticGenerationStore } from '../../client/components/static-generation-async-storage.external' import type { RequestStore } from '../../client/components/request-async-storage.external' @@ -359,7 +360,7 @@ function createServerComponentsRenderer( asNotFound: props.asNotFound, metadataOutlet: , }) - const componentTree = seedData[2] + return ( <> {styles} @@ -370,12 +371,7 @@ function createServerComponentsRenderer( // This is the router state tree. initialTree={initialTree} // This is the tree of React nodes that are seeded into the cache - // TODO: This will be passed as a prop in a later PR. Then we will use - // this prop to populate the cache nodes as soon as the app router - // receives the response. This will replace the `initialChildNode` - // that's currently passed to Layout Router. - // - // cacheNodeSeedData={seedData} + initialSeedData={seedData} initialHead={ <> {ctx.res.statusCode > 400 && ( @@ -386,9 +382,7 @@ function createServerComponentsRenderer( } globalErrorComponent={GlobalError} - > - {componentTree} - + /> ) }, options) @@ -923,6 +917,14 @@ async function renderToHTMLOrFlightImpl( // For metadata notFound error there's no global not found boundary on top // so we create a not found page with AppRouter + const initialSeedData: CacheNodeSeedData = [ + initialTree[0], + null, + + + + , + ] return ( - - - - - + initialSeedData={initialSeedData} + /> ) }, { diff --git a/packages/next/src/server/app-render/create-component-tree.tsx b/packages/next/src/server/app-render/create-component-tree.tsx index ee8c451768849..9da1f4e8a148c 100644 --- a/packages/next/src/server/app-render/create-component-tree.tsx +++ b/packages/next/src/server/app-render/create-component-tree.tsx @@ -4,8 +4,6 @@ import { isClientReference } from '../../lib/client-reference' import { getLayoutOrPageModule } from '../lib/app-dir-module' import type { LoaderTree } from '../lib/app-dir-module' import { interopDefault } from './interop-default' -import { preloadComponent } from './preload-component' -import { addSearchParamsIfPageSegment } from './create-flight-router-state-from-loader-tree' import { parseLoaderTree } from './parse-loader-tree' import type { CreateSegmentPath, AppRenderContext } from './app-render' import { createComponentStylesAndScripts } from './create-component-styles-and-scripts' @@ -57,7 +55,6 @@ export async function createComponentTree({ }, pagePath, getDynamicParamFromSegment, - query, isPrefetch, searchParamsProps, } = ctx @@ -285,13 +282,9 @@ export async function createComponentTree({ // Resolve the segment param const actualSegment = segmentParam ? segmentParam.treeSegment : segment - // This happens outside of rendering in order to eagerly kick off data fetching for layouts / the page further down - // TODO: Once we're done refactoring the Flight response type so that all the - // tree nodes are passed at the root of the response, we'll no longer need to - // do anything extra to preload the nested layouts; all of the child nodes will - // automatically be rendered in parallel by React. Then, to simplify the code, - // we should combine this `map` traversal with the loop below that turns - // the array into an object. + // + // TODO: Combine this `map` traversal with the loop below that turns the array + // into an object. const parallelRouteMap = await Promise.all( Object.keys(parallelRoutes).map( async ( @@ -304,8 +297,6 @@ export async function createComponentTree({ const parallelRoute = parallelRoutes[parallelRouteKey] - const childSegment = parallelRoute[0] - const childSegmentParam = getDynamicParamFromSegment(childSegment) const notFoundComponent = NotFound && isChildrenRouteKey ? : undefined @@ -313,12 +304,7 @@ export async function createComponentTree({ // otherwise we keep rendering for the prefetch. // We also want to bail out if there's no Loading component in the tree. let currentStyles = undefined - let initialChildNode = null - let childCacheNodeSeedData = null - const childPropSegment = addSearchParamsIfPageSegment( - childSegmentParam ? childSegmentParam.treeSegment : childSegment, - query - ) + let childCacheNodeSeedData: CacheNodeSeedData | null = null if ( !( isPrefetch && @@ -343,7 +329,6 @@ export async function createComponentTree({ }) currentStyles = childComponentStyles - initialChildNode = seedData[2] childCacheNodeSeedData = seedData } @@ -370,11 +355,6 @@ export async function createComponentTree({ templateScripts={templateScripts} notFound={notFoundComponent} notFoundStyles={notFoundStyles} - // TODO: This prop will soon by removed and instead we'll return all - // the child nodes in the entire tree at the top level of the - // Flight response. - initialChildNode={initialChildNode} - childPropSegment={childPropSegment} styles={currentStyles} />, childCacheNodeSeedData, @@ -397,12 +377,16 @@ export async function createComponentTree({ // When the segment does not have a layout or page we still have to add the layout router to ensure the path holds the loading component if (!Component) { return { - // TODO: I don't think the extra fragment is necessary. React treats top - // level fragments as transparent, i.e. the runtime behavior should be - // identical even without it. But maybe there's some findDOMNode-related - // reason that I'm not aware of, so I'm leaving it as-is out of extreme - // caution, for now. - seedData: [actualSegment, null, <>{parallelRouteProps.children}], + seedData: [ + actualSegment, + parallelRouteCacheNodeSeedData, + // TODO: I don't think the extra fragment is necessary. React treats top + // level fragments as transparent, i.e. the runtime behavior should be + // identical even without it. But maybe there's some findDOMNode-related + // reason that I'm not aware of, so I'm leaving it as-is out of extreme + // caution, for now. + <>{parallelRouteProps.children}, + ], styles: layerAssets, } } @@ -452,16 +436,6 @@ export async function createComponentTree({ })(), } - // Eagerly execute layout/page component to trigger fetches early. - // TODO: We can delete this once we start passing the nested layouts at the - // top-level of the Flight response, because React will render them in - // parallel automatically. - if (!isClientComponent) { - Component = await Promise.resolve().then(() => - preloadComponent(Component, props) - ) - } - return { seedData: [ actualSegment, diff --git a/packages/next/src/server/app-render/types.ts b/packages/next/src/server/app-render/types.ts index 0a46a5c1865d5..9bc8a570b929d 100644 --- a/packages/next/src/server/app-render/types.ts +++ b/packages/next/src/server/app-render/types.ts @@ -86,9 +86,8 @@ export type FlightDataPath = ...FlightSegmentPath[], /* segment of the rendered slice: */ Segment, /* treePatch */ FlightRouterState, - /* subTreeData: */ React.ReactNode | null, // Can be null during prefetch if there's no loading component - /* head */ React.ReactNode | null, - /* cacheNodeSeedData */ null + /* cacheNodeSeedData */ CacheNodeSeedData, // Can be null during prefetch if there's no loading component + /* head */ React.ReactNode | null ] /** diff --git a/packages/next/src/server/app-render/walk-tree-with-flight-router-state.tsx b/packages/next/src/server/app-render/walk-tree-with-flight-router-state.tsx index ecbd72b05f05d..4bc0b0596ef12 100644 --- a/packages/next/src/server/app-render/walk-tree-with-flight-router-state.tsx +++ b/packages/next/src/server/app-render/walk-tree-with-flight-router-state.tsx @@ -122,68 +122,56 @@ export async function walkTreeWithFlightRouterState({ flightRouterState && canSegmentBeOverridden(actualSegment, flightRouterState[0]) ? flightRouterState[0] - : null + : actualSegment - return [ - [ - overriddenSegment ?? actualSegment, - createFlightRouterStateFromLoaderTree( - // Create router state using the slice of the loaderTree - loaderTreeToFilter, - getDynamicParamFromSegment, - query - ), - shouldSkipComponentTree - ? null - : // Create component tree using the slice of the loaderTree - // TODO: Not sure why this ts error started happening, after a - // seemingly innocuous change. But I'm also not sure why this extra - // wrapper element exists. We should just remove it. - // @ts-expect-error: Type is referenced directly or indirectly in the fulfillment callback of its own 'then' method. - React.createElement(async () => { - const { seedData } = await createComponentTree( - // This ensures flightRouterPath is valid and filters down the tree - { - ctx, - createSegmentPath, - loaderTree: loaderTreeToFilter, - parentParams: currentParams, - firstItem: isFirst, - injectedCSS, - injectedJS, - injectedFontPreloadTags, - // This is intentionally not "rootLayoutIncludedAtThisLevelOrAbove" as createComponentTree starts at the current level and does a check for "rootLayoutAtThisLevel" too. - rootLayoutIncluded, - asNotFound, - metadataOutlet, - } - ) - const componentNode = seedData[2] - return componentNode - }), - shouldSkipComponentTree - ? null - : (() => { - const { layoutOrPagePath } = parseLoaderTree(loaderTreeToFilter) - - const layerAssets = getLayerAssets({ - ctx, - layoutOrPagePath, - injectedCSS: new Set(injectedCSS), - injectedJS: new Set(injectedJS), - injectedFontPreloadTags: new Set(injectedFontPreloadTags), - }) + const routerState = createFlightRouterStateFromLoaderTree( + // Create router state using the slice of the loaderTree + loaderTreeToFilter, + getDynamicParamFromSegment, + query + ) - return ( - <> - {layerAssets} - {rscPayloadHead} - - ) - })(), - null, - ], - ] + if (shouldSkipComponentTree) { + // Send only the router state + return [[overriddenSegment, routerState, null, null]] + } else { + // Create component tree using the slice of the loaderTree + const { seedData } = await createComponentTree( + // This ensures flightRouterPath is valid and filters down the tree + { + ctx, + createSegmentPath, + loaderTree: loaderTreeToFilter, + parentParams: currentParams, + firstItem: isFirst, + injectedCSS, + injectedJS, + injectedFontPreloadTags, + // This is intentionally not "rootLayoutIncludedAtThisLevelOrAbove" as createComponentTree starts at the current level and does a check for "rootLayoutAtThisLevel" too. + rootLayoutIncluded, + asNotFound, + metadataOutlet, + } + ) + + // Create head + const { layoutOrPagePath } = parseLoaderTree(loaderTreeToFilter) + const layerAssets = getLayerAssets({ + ctx, + layoutOrPagePath, + injectedCSS: new Set(injectedCSS), + injectedJS: new Set(injectedJS), + injectedFontPreloadTags: new Set(injectedFontPreloadTags), + }) + const head = ( + <> + {layerAssets} + {rscPayloadHead} + + ) + + return [[overriddenSegment, routerState, seedData, head]] + } } // If we are not rendering on this level we need to check if the current From 5ab289caaeca2f842e618d60b2f52e6b31114962 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Tue, 21 Nov 2023 19:57:41 +0100 Subject: [PATCH 004/481] Turbopack: improve error display (#58734) ### What? * include path and title in errors * don't block the page for errors in node_modules ### Why? ### How? --------- Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../next/src/server/lib/router-utils/setup-dev-bundler.ts | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts b/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts index 423e72545b2d4..1155a2c6eede3 100644 --- a/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts +++ b/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts @@ -305,10 +305,12 @@ async function startWatcher(opts: SetupOpts) { const { start } = source.range message = `${issue.severity} - ${formattedFilePath}:${ start.line + 1 - }:${start.column}` + }:${start.column} ${formattedTitle}` } else { message = `${issue.severity} - ${formattedFilePath} ${formattedTitle}` } + } else if (formattedFilePath) { + message = `${formattedFilePath} ${formattedTitle}` } else { message = `${formattedTitle}` } @@ -368,6 +370,9 @@ async function startWatcher(opts: SetupOpts) { console.error(` ⚠ ${displayName} ${formatted}\n\n`) } newSet.set(key, issue) + + // We show errors in node_modules to the console, but don't throw for them + if (/(^|\/)node_modules(\/|$)/.test(issue.filePath)) continue relevantIssues.add(formatted) } From 8b11264ea95c9ed2f7dfd1e8d66a36b57ebc0da1 Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Tue, 21 Nov 2023 19:04:07 +0000 Subject: [PATCH 005/481] v14.0.4-canary.7 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 16 ++++++++-------- 18 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lerna.json b/lerna.json index e534830de3c15..cb4956646b156 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.6" + "version": "14.0.4-canary.7" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 2bfaf63642d7f..959d121cccc2d 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.6", + "version": "14.0.4-canary.7", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 59c5ffb0770c8..a256f43baa9a0 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.6", + "version": "14.0.4-canary.7", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.6", + "@next/eslint-plugin-next": "14.0.4-canary.7", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 0b794d9e84c58..16e3d35f929fe 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.6", + "version": "14.0.4-canary.7", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index a09aaadeb77bb..12bd1a7f37fcd 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.6", + "version": "14.0.4-canary.7", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index bd4f446f65b74..418754e51924d 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.6", + "version": "14.0.4-canary.7", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 96259f9497d8e..4490b29fb1173 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.6", + "version": "14.0.4-canary.7", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 8994386d7737c..50e6dba891ea3 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.6", + "version": "14.0.4-canary.7", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 07f0bd396c506..e86bc81ac9239 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.6", + "version": "14.0.4-canary.7", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 1521cb393f8fe..4a9daf0f0cfdd 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.6", + "version": "14.0.4-canary.7", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index 1863e7eac869e..85c4c7fe90276 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.6", + "version": "14.0.4-canary.7", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index d6b38f8eb604a..3d4c9d7caa135 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.6", + "version": "14.0.4-canary.7", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index 748fc93835c9d..d2323539aa46a 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.6", + "version": "14.0.4-canary.7", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index f29228f738911..33c3ca6b7f617 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.6", + "version": "14.0.4-canary.7", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.6", + "@next/env": "14.0.4-canary.7", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -146,11 +146,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.6", - "@next/polyfill-nomodule": "14.0.4-canary.6", - "@next/react-dev-overlay": "14.0.4-canary.6", - "@next/react-refresh-utils": "14.0.4-canary.6", - "@next/swc": "14.0.4-canary.6", + "@next/polyfill-module": "14.0.4-canary.7", + "@next/polyfill-nomodule": "14.0.4-canary.7", + "@next/react-dev-overlay": "14.0.4-canary.7", + "@next/react-refresh-utils": "14.0.4-canary.7", + "@next/swc": "14.0.4-canary.7", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index e613c798f9e93..7f2af217f8885 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.6", + "version": "14.0.4-canary.7", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index 5c29b795e08b3..e09ee9b6cbfba 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.6", + "version": "14.0.4-canary.7", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index 1409cdd77c07e..daa87bdc4456c 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.6", + "version": "14.0.4-canary.7", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -23,7 +23,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.6", + "next": "14.0.4-canary.7", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0367ff79e72ed..59afe738def47 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -735,7 +735,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.6 + specifier: 14.0.4-canary.7 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -800,7 +800,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.6 + specifier: 14.0.4-canary.7 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -924,19 +924,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.6 + specifier: 14.0.4-canary.7 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.6 + specifier: 14.0.4-canary.7 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.6 + specifier: 14.0.4-canary.7 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.6 + specifier: 14.0.4-canary.7 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.6 + specifier: 14.0.4-canary.7 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1587,7 +1587,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.6 + specifier: 14.0.4-canary.7 version: link:../next outdent: specifier: 0.8.0 From 346711679467d1ce97d8b234ae65f7c2084d536d Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Tue, 21 Nov 2023 23:58:14 +0100 Subject: [PATCH 006/481] fix node externals resolving (#58129) ### What? Various fixes in handling of externals in node.js * add extensions to builtin externals to allow node.js ESM to work * improve the auto-externals logic to detect more edge cases * prepare for `esmExternals` support, but that's blocked by client manifest missing the async flag * currently only `esmExternals: false` is supported ### Why? ### Turbopack Changes * https://github.com/vercel/turbo/pull/6531 * https://github.com/vercel/turbo/pull/6530 --------- Co-authored-by: Leah Co-authored-by: Zack Tanner --- Cargo.lock | 66 +++--- Cargo.toml | 6 +- .../next-swc/crates/next-core/src/babel.rs | 2 + .../crates/next-core/src/next_config.rs | 4 + .../crates/next-core/src/next_import_map.rs | 17 +- .../next-core/src/next_server/context.rs | 4 + .../next-core/src/next_server/resolve.rs | 197 ++++++++++++------ .../next-core/src/next_shared/resolve.rs | 6 + .../transforms/swc_ecma_transform_plugins.rs | 12 +- packages/next/package.json | 2 +- .../src/server/app-render/action-handler.ts | 5 +- packages/next/src/server/require-hook.ts | 1 + pnpm-lock.yaml | 10 +- 13 files changed, 219 insertions(+), 113 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 316c7a4e7a115..d585caac1f7c1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -322,7 +322,7 @@ dependencies = [ [[package]] name = "auto-hash-map" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231120.2#5de1380b33ec564de8b32b430c155163bcbc9cfb" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" dependencies = [ "serde", "smallvec", @@ -3549,7 +3549,7 @@ dependencies = [ [[package]] name = "node-file-trace" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231120.2#5de1380b33ec564de8b32b430c155163bcbc9cfb" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" dependencies = [ "anyhow", "serde", @@ -7695,7 +7695,7 @@ dependencies = [ [[package]] name = "turbo-tasks" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231120.2#5de1380b33ec564de8b32b430c155163bcbc9cfb" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" dependencies = [ "anyhow", "async-trait", @@ -7727,7 +7727,7 @@ dependencies = [ [[package]] name = "turbo-tasks-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231120.2#5de1380b33ec564de8b32b430c155163bcbc9cfb" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" dependencies = [ "anyhow", "cargo-lock", @@ -7739,7 +7739,7 @@ dependencies = [ [[package]] name = "turbo-tasks-bytes" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231120.2#5de1380b33ec564de8b32b430c155163bcbc9cfb" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" dependencies = [ "anyhow", "bytes", @@ -7754,7 +7754,7 @@ dependencies = [ [[package]] name = "turbo-tasks-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231120.2#5de1380b33ec564de8b32b430c155163bcbc9cfb" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" dependencies = [ "anyhow", "dotenvs", @@ -7768,7 +7768,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fetch" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231120.2#5de1380b33ec564de8b32b430c155163bcbc9cfb" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7785,7 +7785,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fs" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231120.2#5de1380b33ec564de8b32b430c155163bcbc9cfb" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" dependencies = [ "anyhow", "auto-hash-map", @@ -7815,7 +7815,7 @@ dependencies = [ [[package]] name = "turbo-tasks-hash" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231120.2#5de1380b33ec564de8b32b430c155163bcbc9cfb" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" dependencies = [ "base16", "hex", @@ -7827,7 +7827,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231120.2#5de1380b33ec564de8b32b430c155163bcbc9cfb" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" dependencies = [ "anyhow", "convert_case 0.6.0", @@ -7841,7 +7841,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros-shared" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231120.2#5de1380b33ec564de8b32b430c155163bcbc9cfb" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" dependencies = [ "proc-macro2", "quote", @@ -7851,7 +7851,7 @@ dependencies = [ [[package]] name = "turbo-tasks-malloc" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231120.2#5de1380b33ec564de8b32b430c155163bcbc9cfb" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" dependencies = [ "mimalloc", ] @@ -7859,7 +7859,7 @@ dependencies = [ [[package]] name = "turbo-tasks-memory" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231120.2#5de1380b33ec564de8b32b430c155163bcbc9cfb" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" dependencies = [ "anyhow", "auto-hash-map", @@ -7884,7 +7884,7 @@ dependencies = [ [[package]] name = "turbopack" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231120.2#5de1380b33ec564de8b32b430c155163bcbc9cfb" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" dependencies = [ "anyhow", "async-recursion", @@ -7915,7 +7915,7 @@ dependencies = [ [[package]] name = "turbopack-binding" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231120.2#5de1380b33ec564de8b32b430c155163bcbc9cfb" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" dependencies = [ "auto-hash-map", "mdxjs", @@ -7955,7 +7955,7 @@ dependencies = [ [[package]] name = "turbopack-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231120.2#5de1380b33ec564de8b32b430c155163bcbc9cfb" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7978,7 +7978,7 @@ dependencies = [ [[package]] name = "turbopack-cli-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231120.2#5de1380b33ec564de8b32b430c155163bcbc9cfb" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" dependencies = [ "anyhow", "clap 4.4.2", @@ -8002,7 +8002,7 @@ dependencies = [ [[package]] name = "turbopack-core" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231120.2#5de1380b33ec564de8b32b430c155163bcbc9cfb" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" dependencies = [ "anyhow", "async-recursion", @@ -8032,7 +8032,7 @@ dependencies = [ [[package]] name = "turbopack-css" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231120.2#5de1380b33ec564de8b32b430c155163bcbc9cfb" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" dependencies = [ "anyhow", "async-trait", @@ -8058,7 +8058,7 @@ dependencies = [ [[package]] name = "turbopack-dev" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231120.2#5de1380b33ec564de8b32b430c155163bcbc9cfb" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -8082,7 +8082,7 @@ dependencies = [ [[package]] name = "turbopack-dev-server" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231120.2#5de1380b33ec564de8b32b430c155163bcbc9cfb" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" dependencies = [ "anyhow", "async-compression", @@ -8119,7 +8119,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231120.2#5de1380b33ec564de8b32b430c155163bcbc9cfb" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" dependencies = [ "anyhow", "async-trait", @@ -8153,7 +8153,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-hmr-protocol" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231120.2#5de1380b33ec564de8b32b430c155163bcbc9cfb" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" dependencies = [ "serde", "serde_json", @@ -8164,7 +8164,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-plugins" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231120.2#5de1380b33ec564de8b32b430c155163bcbc9cfb" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" dependencies = [ "anyhow", "async-trait", @@ -8187,7 +8187,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-runtime" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231120.2#5de1380b33ec564de8b32b430c155163bcbc9cfb" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" dependencies = [ "anyhow", "indoc", @@ -8204,7 +8204,7 @@ dependencies = [ [[package]] name = "turbopack-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231120.2#5de1380b33ec564de8b32b430c155163bcbc9cfb" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -8220,7 +8220,7 @@ dependencies = [ [[package]] name = "turbopack-image" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231120.2#5de1380b33ec564de8b32b430c155163bcbc9cfb" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" dependencies = [ "anyhow", "base64 0.21.4", @@ -8240,7 +8240,7 @@ dependencies = [ [[package]] name = "turbopack-json" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231120.2#5de1380b33ec564de8b32b430c155163bcbc9cfb" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" dependencies = [ "anyhow", "serde", @@ -8255,7 +8255,7 @@ dependencies = [ [[package]] name = "turbopack-mdx" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231120.2#5de1380b33ec564de8b32b430c155163bcbc9cfb" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" dependencies = [ "anyhow", "mdxjs", @@ -8270,7 +8270,7 @@ dependencies = [ [[package]] name = "turbopack-node" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231120.2#5de1380b33ec564de8b32b430c155163bcbc9cfb" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" dependencies = [ "anyhow", "async-stream", @@ -8305,7 +8305,7 @@ dependencies = [ [[package]] name = "turbopack-static" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231120.2#5de1380b33ec564de8b32b430c155163bcbc9cfb" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" dependencies = [ "anyhow", "serde", @@ -8321,7 +8321,7 @@ dependencies = [ [[package]] name = "turbopack-swc-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231120.2#5de1380b33ec564de8b32b430c155163bcbc9cfb" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" dependencies = [ "swc_core", "turbo-tasks", @@ -8332,7 +8332,7 @@ dependencies = [ [[package]] name = "turbopack-wasm" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231120.2#5de1380b33ec564de8b32b430c155163bcbc9cfb" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" dependencies = [ "anyhow", "indexmap 1.9.3", diff --git a/Cargo.toml b/Cargo.toml index d1dc9ccc6256a..3e760d38c0d11 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,11 +43,11 @@ next-transform-strip-page-exports = { path = "packages/next-swc/crates/next-tran testing = { version = "0.35.10" } # Turbo crates -turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231120.2" } +turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231121.2" } # [TODO]: need to refactor embed_directory! macro usages, as well as resolving turbo_tasks::function, macros.. -turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231120.2" } +turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231121.2" } # [TODO]: need to refactor embed_directory! macro usage in next-core -turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231120.2" } +turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231121.2" } # General Deps diff --git a/packages/next-swc/crates/next-core/src/babel.rs b/packages/next-swc/crates/next-core/src/babel.rs index a3bc8dbb0279c..c2cf946391e00 100644 --- a/packages/next-swc/crates/next-core/src/babel.rs +++ b/packages/next-swc/crates/next-core/src/babel.rs @@ -5,6 +5,7 @@ use turbopack_binding::{ turbopack::{ core::{ issue::{Issue, IssueExt, IssueSeverity, StyledString}, + reference_type::{CommonJsReferenceSubType, ReferenceType}, resolve::{parse::Request, pattern::Pattern, resolve}, }, node::transforms::webpack::WebpackLoaderItem, @@ -122,6 +123,7 @@ pub async fn maybe_add_babel_loader( pub async fn is_babel_loader_available(project_path: Vc) -> Result> { let result = resolve( project_path, + Value::new(ReferenceType::CommonJs(CommonJsReferenceSubType::Undefined)), Request::parse(Value::new(Pattern::Constant( "babel-loader/package.json".to_string(), ))), diff --git a/packages/next-swc/crates/next-core/src/next_config.rs b/packages/next-swc/crates/next-core/src/next_config.rs index ec0dd24da52d1..c156ce10660de 100644 --- a/packages/next-swc/crates/next-core/src/next_config.rs +++ b/packages/next-swc/crates/next-core/src/next_config.rs @@ -832,6 +832,10 @@ async fn load_next_config_and_custom_routes_internal( import_map.insert_exact_alias("next", ImportMapping::External(None).into()); import_map.insert_wildcard_alias("next/", ImportMapping::External(None).into()); import_map.insert_exact_alias("styled-jsx", ImportMapping::External(None).into()); + import_map.insert_exact_alias( + "styled-jsx/style", + ImportMapping::External(Some("styled-jsx/style.js".to_string())).cell(), + ); import_map.insert_wildcard_alias("styled-jsx/", ImportMapping::External(None).into()); let context = node_evaluate_asset_context( diff --git a/packages/next-swc/crates/next-core/src/next_import_map.rs b/packages/next-swc/crates/next-core/src/next_import_map.rs index 8f4ed68844c1f..de639c9fffd71 100644 --- a/packages/next-swc/crates/next-core/src/next_import_map.rs +++ b/packages/next-swc/crates/next-core/src/next_import_map.rs @@ -7,6 +7,7 @@ use turbopack_binding::{ turbo::tasks_fs::{glob::Glob, FileSystem, FileSystemPath}, turbopack::{ core::{ + reference_type::{CommonJsReferenceSubType, ReferenceType}, resolve::{ options::{ConditionValue, ImportMap, ImportMapping, ResolveOptions, ResolvedMap}, parse::Request, @@ -219,6 +220,10 @@ pub fn get_next_build_import_map() -> Vc { import_map.insert_exact_alias("next", external); import_map.insert_wildcard_alias("next/", external); import_map.insert_exact_alias("styled-jsx", external); + import_map.insert_exact_alias( + "styled-jsx/style", + ImportMapping::External(Some("styled-jsx/style.js".to_string())).cell(), + ); import_map.insert_wildcard_alias("styled-jsx/", external); import_map.cell() @@ -293,6 +298,10 @@ pub async fn get_next_server_import_map( import_map.insert_exact_alias("react-dom", external); import_map.insert_wildcard_alias("react-dom/", external); import_map.insert_exact_alias("styled-jsx", external); + import_map.insert_exact_alias( + "styled-jsx/style", + ImportMapping::External(Some("styled-jsx/style.js".to_string())).cell(), + ); import_map.insert_wildcard_alias("styled-jsx/", external); // TODO: we should not bundle next/dist/build/utils in the pages renderer at all import_map.insert_wildcard_alias("next/dist/build/utils", external); @@ -508,7 +517,7 @@ async fn insert_next_server_special_aliases( "@opentelemetry/api", // TODO(WEB-625) this actually need to prefer the local version of // @opentelemetry/api - external_if_node(pages_dir, "next/dist/compiled/@opentelemetry/api"), + external_if_node(pages_dir, "next/dist/compiled/@opentelemetry/api/index.js"), ); insert_alias_to_alternatives( import_map, @@ -544,7 +553,10 @@ async fn insert_next_server_special_aliases( "@opentelemetry/api", // TODO(WEB-625) this actually need to prefer the local version of // @opentelemetry/api - request_to_import_mapping(app_dir, "next/dist/compiled/@opentelemetry/api"), + request_to_import_mapping( + app_dir, + "next/dist/compiled/@opentelemetry/api/index.js", + ), ); import_map.insert_exact_alias( "styled-jsx", @@ -880,6 +892,7 @@ async fn package_lookup_resolve_options( pub async fn get_next_package(context_directory: Vc) -> Result> { let result = resolve( context_directory, + Value::new(ReferenceType::CommonJs(CommonJsReferenceSubType::Undefined)), Request::parse(Value::new(Pattern::Constant( "next/package.json".to_string(), ))), diff --git a/packages/next-swc/crates/next-core/src/next_server/context.rs b/packages/next-swc/crates/next-core/src/next_server/context.rs index 65db03c036a67..7641cd6b868df 100644 --- a/packages/next-swc/crates/next-core/src/next_server/context.rs +++ b/packages/next-swc/crates/next-core/src/next_server/context.rs @@ -126,6 +126,8 @@ pub async fn get_server_resolve_options_context( project_path, project_path.root(), ExternalPredicate::Only(Vc::cell(external_packages)).cell(), + // TODO(sokra) esmExternals support + false, ); let ty = ty.into_value(); @@ -144,6 +146,8 @@ pub async fn get_server_resolve_options_context( project_path, project_path.root(), ExternalPredicate::AllExcept(next_config.transpile_packages()).cell(), + // TODO(sokra) esmExternals support + false, ); let next_external_plugin = NextExternalResolvePlugin::new(project_path); diff --git a/packages/next-swc/crates/next-core/src/next_server/resolve.rs b/packages/next-swc/crates/next-core/src/next_server/resolve.rs index d75bbad51ffaa..43c1138f72668 100644 --- a/packages/next-swc/crates/next-core/src/next_server/resolve.rs +++ b/packages/next-swc/crates/next-core/src/next_server/resolve.rs @@ -3,6 +3,9 @@ use turbo_tasks::{Value, Vc}; use turbopack_binding::{ turbo::tasks_fs::{glob::Glob, FileJsonContent, FileSystemPath}, turbopack::core::{ + reference_type::{ + CommonJsReferenceSubType, EcmaScriptModulesReferenceSubType, ReferenceType, + }, resolve::{ find_context_file, node::{node_cjs_resolve_options, node_esm_resolve_options}, @@ -35,6 +38,7 @@ pub(crate) struct ExternalCjsModulesResolvePlugin { project_path: Vc, root: Vc, predicate: Vc, + import_externals: bool, } #[turbo_tasks::value_impl] @@ -44,11 +48,13 @@ impl ExternalCjsModulesResolvePlugin { project_path: Vc, root: Vc, predicate: Vc, + import_externals: bool, ) -> Vc { ExternalCjsModulesResolvePlugin { project_path, root, predicate, + import_externals, } .cell() } @@ -61,15 +67,23 @@ async fn is_node_resolveable( expected: Vc, is_esm: bool, ) -> Result> { - let node_resolve_result = resolve( - context, - request, - if is_esm { - node_esm_resolve_options(context.root()) - } else { - node_cjs_resolve_options(context.root()) - }, - ); + let node_resolve_result = if is_esm { + resolve( + context, + Value::new(ReferenceType::EcmaScriptModules( + EcmaScriptModulesReferenceSubType::Undefined, + )), + request, + node_esm_resolve_options(context.root()), + ) + } else { + resolve( + context, + Value::new(ReferenceType::CommonJs(CommonJsReferenceSubType::Undefined)), + request, + node_cjs_resolve_options(context.root()), + ) + }; let primary_node_assets = node_resolve_result.primary_sources().await?; let Some(&node_asset) = primary_node_assets.first() else { // can't resolve request with node.js options @@ -101,6 +115,7 @@ impl ResolvePlugin for ExternalCjsModulesResolvePlugin { &self, fs_path: Vc, context: Vc, + reference_type: Value, request: Vc, ) -> Result> { if *condition(self.root).matches(context).await? { @@ -136,73 +151,127 @@ impl ResolvePlugin for ExternalCjsModulesResolvePlugin { } } - // node.js only supports these file extensions - // mjs is an esm module and we can't bundle that yet - if !matches!( - raw_fs_path.extension_ref(), - Some("cjs" | "js" | "node" | "json") - ) { - return Ok(ResolveResultOption::none()); + let is_esm = ReferenceType::EcmaScriptModules(EcmaScriptModulesReferenceSubType::Undefined) + .includes(&reference_type); + + enum FileType { + CommonJs, + EcmaScriptModule, + Unsupported, } - let FindContextFileResult::Found(package_json, _) = - *find_context_file(fs_path.parent(), package_json()).await? - else { - // can't find package.json - return Ok(ResolveResultOption::none()); - }; - let FileJsonContent::Content(package) = &*package_json.read_json().await? else { - // can't parse package.json - return Ok(ResolveResultOption::none()); - }; + async fn get_file_type( + fs_path: Vc, + raw_fs_path: &FileSystemPath, + ) -> Result { + // node.js only supports these file extensions + // mjs is an esm module and we can't bundle that yet + let ext = raw_fs_path.extension_ref(); + if matches!(ext, Some("cjs" | "node" | "json")) { + return Ok(FileType::CommonJs); + } + if matches!(ext, Some("mjs")) { + return Ok(FileType::EcmaScriptModule); + } + if matches!(ext, Some("js")) { + // for .js extension in cjs context, we need to check the actual module type via + // package.json + let FindContextFileResult::Found(package_json, _) = + *find_context_file(fs_path.parent(), package_json()).await? + else { + // can't find package.json + return Ok(FileType::CommonJs); + }; + let FileJsonContent::Content(package) = &*package_json.read_json().await? else { + // can't parse package.json + return Ok(FileType::Unsupported); + }; - // always bundle esm modules - if let Some("module") = package["type"].as_str() { - return Ok(ResolveResultOption::none()); - } + if let Some("module") = package["type"].as_str() { + return Ok(FileType::EcmaScriptModule); + } - // We don't know if this is a ESM reference, so also check if it is resolveable - // as ESM. - let is_esm_resolveable = - *is_node_resolveable(self.project_path, request, fs_path, true).await?; - let is_cjs_resolveable = - *is_node_resolveable(self.project_path, request, fs_path, false).await?; + return Ok(FileType::CommonJs); + } - if !is_cjs_resolveable && !is_esm_resolveable { - // can't resolve request with node.js options - return Ok(ResolveResultOption::none()); + Ok(FileType::Unsupported) } - // check if we can resolve the package from the project dir with node.js resolve - // options (might be hidden by pnpm) - if is_cjs_resolveable { - // mark as external - return Ok(ResolveResultOption::some( - ResolveResult::primary(ResolveResultItem::OriginalReferenceExternal).cell(), - )); - } + let file_type = get_file_type(fs_path, raw_fs_path).await?; + + let (expected, is_esm) = match (file_type, is_esm) { + (FileType::Unsupported, _) => { + // unsupported file type, bundle it + return Ok(ResolveResultOption::none()); + } + (FileType::CommonJs, false) => (fs_path, false), + (FileType::CommonJs, true) => (fs_path, self.import_externals), + (FileType::EcmaScriptModule, false) => (fs_path, false), + (FileType::EcmaScriptModule, true) => { + if self.import_externals { + (fs_path, true) + } else { + // We verify with the CommonJS alternative + let cjs_resolved = resolve( + context, + reference_type.clone(), + request, + node_cjs_resolve_options(context.root()), + ); + let Some(result) = *cjs_resolved.first_source().await? else { + // this can't resolve with commonjs, so bundle it + return Ok(ResolveResultOption::none()); + }; + let path = result.ident().path(); + let file_type = get_file_type(path, &*path.await?).await?; + if !matches!(file_type, FileType::CommonJs) { + // even with require() this resolves to a ESM, which would break node.js + // bundle it + // This happens for invalid packages like `textlinestream` + return Ok(ResolveResultOption::none()); + } - // When it's not resolveable as ESM, there is maybe an extension missing, try - // .js - if let Some(mut request_str) = request.await?.request() { - if !request_str.ends_with(".js") { - request_str += ".js"; - let request = Request::parse(Value::new(Pattern::Constant(request_str.clone()))); - if *is_node_resolveable(self.project_path, request, fs_path, false).await? - && *is_node_resolveable(self.project_path, request, fs_path, true).await? - { - // mark as external, but with .js extension - return Ok(ResolveResultOption::some( - ResolveResult::primary(ResolveResultItem::OriginalReferenceTypeExternal( - request_str, - )) - .cell(), - )); + (path, false) } } + }; + + let is_resolveable = + *is_node_resolveable(self.project_path, request, expected, is_esm).await?; + + if !is_resolveable { + if is_esm { + // When it's not resolveable as ESM, there is maybe an extension missing, + // try to add .js + if let Some(mut request_str) = request.await?.request() { + if !request_str.ends_with(".js") { + request_str += ".js"; + let new_request = + Request::parse(Value::new(Pattern::Constant(request_str.clone()))); + let is_resolveable = + *is_node_resolveable(self.project_path, new_request, expected, is_esm) + .await?; + if is_resolveable { + // mark as external, but with .js extension + return Ok(ResolveResultOption::some( + ResolveResult::primary( + ResolveResultItem::OriginalReferenceTypeExternal(request_str), + ) + .cell(), + )); + } + } + } + } + + // this can't resolve with node.js, so bundle it + return Ok(ResolveResultOption::none()); } - Ok(ResolveResultOption::none()) + // mark as external + Ok(ResolveResultOption::some( + ResolveResult::primary(ResolveResultItem::OriginalReferenceExternal).cell(), + )) } } diff --git a/packages/next-swc/crates/next-core/src/next_shared/resolve.rs b/packages/next-swc/crates/next-core/src/next_shared/resolve.rs index d27e9f4997e50..c9caa53485d3e 100644 --- a/packages/next-swc/crates/next-core/src/next_shared/resolve.rs +++ b/packages/next-swc/crates/next-core/src/next_shared/resolve.rs @@ -10,6 +10,7 @@ use turbopack_binding::{ diagnostics::DiagnosticExt, file_source::FileSource, issue::{unsupported_module::UnsupportedModuleIssue, IssueExt}, + reference_type::ReferenceType, resolve::{ parse::Request, pattern::Pattern, @@ -67,6 +68,7 @@ impl ResolvePlugin for UnsupportedModulesResolvePlugin { &self, _fs_path: Vc, file_path: Vc, + _reference_type: Value, request: Vc, ) -> Result> { if let Request::Module { @@ -131,6 +133,7 @@ impl ResolvePlugin for NextExternalResolvePlugin { &self, fs_path: Vc, _context: Vc, + _reference_type: Value, _request: Vc, ) -> Result> { let raw_fs_path = &*fs_path.await?; @@ -179,6 +182,7 @@ impl ResolvePlugin for NextNodeSharedRuntimeResolvePlugin { &self, fs_path: Vc, _context: Vc, + _reference_type: Value, _request: Vc, ) -> Result> { let stem = fs_path.file_stem().await?; @@ -240,6 +244,7 @@ impl ResolvePlugin for ModuleFeatureReportResolvePlugin { &self, _fs_path: Vc, _context: Vc, + _reference_type: Value, request: Vc, ) -> Result> { if let Request::Module { @@ -294,6 +299,7 @@ impl ResolvePlugin for NextSharedRuntimeResolvePlugin { &self, fs_path: Vc, _context: Vc, + _reference_type: Value, _request: Vc, ) -> Result> { let raw_fs_path = &*fs_path.await?; diff --git a/packages/next-swc/crates/next-core/src/next_shared/transforms/swc_ecma_transform_plugins.rs b/packages/next-swc/crates/next-core/src/next_shared/transforms/swc_ecma_transform_plugins.rs index ca72ffd5a7e86..8346d11d01147 100644 --- a/packages/next-swc/crates/next-core/src/next_shared/transforms/swc_ecma_transform_plugins.rs +++ b/packages/next-swc/crates/next-core/src/next_shared/transforms/swc_ecma_transform_plugins.rs @@ -40,7 +40,7 @@ pub async fn get_swc_ecma_transform_plugin_impl( core::{ asset::Asset, issue::IssueSeverity, - reference_type::ReferenceType, + reference_type::{CommonJsReferenceSubType, ReferenceType}, resolve::{handle_resolve_error, parse::Request, pattern::Pattern, resolve}, }, ecmascript_plugin::transform::swc_ecma_transform_plugins::{ @@ -68,8 +68,14 @@ pub async fn get_swc_ecma_transform_plugin_impl( ); let plugin_wasm_module_resolve_result = handle_resolve_error( - resolve(project_path, request, resolve_options).as_raw_module_result(), - Value::new(ReferenceType::Undefined), + resolve( + project_path, + Value::new(ReferenceType::CommonJs(CommonJsReferenceSubType::Undefined)), + request, + resolve_options, + ) + .as_raw_module_result(), + Value::new(ReferenceType::CommonJs(CommonJsReferenceSubType::Undefined)), project_path, request, resolve_options, diff --git a/packages/next/package.json b/packages/next/package.json index 33c3ca6b7f617..f9ed1b983492e 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -193,7 +193,7 @@ "@types/ws": "8.2.0", "@vercel/ncc": "0.34.0", "@vercel/nft": "0.22.6", - "@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231120.2", + "@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231121.2", "acorn": "8.5.0", "amphtml-validator": "1.0.35", "anser": "1.4.9", diff --git a/packages/next/src/server/app-render/action-handler.ts b/packages/next/src/server/app-render/action-handler.ts index da31800203c3e..a1e3057817468 100644 --- a/packages/next/src/server/app-render/action-handler.ts +++ b/packages/next/src/server/app-render/action-handler.ts @@ -540,8 +540,9 @@ To configure the body size limit for Server Actions, see: https://nextjs.org/doc } } - const actionHandler = - ComponentMod.__next_app__.require(actionModId)[actionId] + const actionHandler = ( + await ComponentMod.__next_app__.require(actionModId) + )[actionId] const returnVal = await actionHandler.apply(null, bound) diff --git a/packages/next/src/server/require-hook.ts b/packages/next/src/server/require-hook.ts index c5bfccc3a3ecd..1b4b9ba1c4b26 100644 --- a/packages/next/src/server/require-hook.ts +++ b/packages/next/src/server/require-hook.ts @@ -18,6 +18,7 @@ export const hookPropertyMap = new Map() export const defaultOverrides = { 'styled-jsx': path.dirname(resolve('styled-jsx/package.json')), 'styled-jsx/style': resolve('styled-jsx/style'), + 'styled-jsx/style.js': resolve('styled-jsx/style'), } const toResolveMap = (map: Record): [string, string][] => diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 59afe738def47..3960f63de1b43 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1065,8 +1065,8 @@ importers: specifier: 0.22.6 version: 0.22.6 '@vercel/turbopack-ecmascript-runtime': - specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231120.2 - version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231120.2(react-refresh@0.12.0)(webpack@5.86.0)' + specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231121.2 + version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231121.2(react-refresh@0.12.0)(webpack@5.86.0)' acorn: specifier: 8.5.0 version: 8.5.0 @@ -24646,9 +24646,9 @@ packages: /zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} - '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231120.2(react-refresh@0.12.0)(webpack@5.86.0)': - resolution: {registry: https://registry.npmjs.org/, tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231120.2} - id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231120.2' + '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231121.2(react-refresh@0.12.0)(webpack@5.86.0)': + resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231121.2} + id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231121.2' name: '@vercel/turbopack-ecmascript-runtime' version: 0.0.0 dependencies: From f6b50ae32b5b9a41deff0172bcd9b34c74f509ef Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Tue, 21 Nov 2023 23:22:46 +0000 Subject: [PATCH 007/481] v14.0.4-canary.8 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 18 +++++++++--------- 18 files changed, 34 insertions(+), 34 deletions(-) diff --git a/lerna.json b/lerna.json index cb4956646b156..b4141e2e62708 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.7" + "version": "14.0.4-canary.8" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 959d121cccc2d..5636720cea43e 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.7", + "version": "14.0.4-canary.8", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index a256f43baa9a0..3e06ec317b092 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.7", + "version": "14.0.4-canary.8", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.7", + "@next/eslint-plugin-next": "14.0.4-canary.8", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 16e3d35f929fe..17111cbe16ba8 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.7", + "version": "14.0.4-canary.8", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index 12bd1a7f37fcd..fee9637620b79 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.7", + "version": "14.0.4-canary.8", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 418754e51924d..259d70150e8ff 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.7", + "version": "14.0.4-canary.8", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 4490b29fb1173..5d3a170f05082 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.7", + "version": "14.0.4-canary.8", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 50e6dba891ea3..b91c0422060fc 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.7", + "version": "14.0.4-canary.8", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index e86bc81ac9239..118e201457158 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.7", + "version": "14.0.4-canary.8", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 4a9daf0f0cfdd..152ae1d9f70ee 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.7", + "version": "14.0.4-canary.8", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index 85c4c7fe90276..0a2332ddcf248 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.7", + "version": "14.0.4-canary.8", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index 3d4c9d7caa135..1740c247ed709 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.7", + "version": "14.0.4-canary.8", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index d2323539aa46a..8a7ba189391e5 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.7", + "version": "14.0.4-canary.8", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index f9ed1b983492e..a0f0d1ea19d8c 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.7", + "version": "14.0.4-canary.8", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.7", + "@next/env": "14.0.4-canary.8", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -146,11 +146,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.7", - "@next/polyfill-nomodule": "14.0.4-canary.7", - "@next/react-dev-overlay": "14.0.4-canary.7", - "@next/react-refresh-utils": "14.0.4-canary.7", - "@next/swc": "14.0.4-canary.7", + "@next/polyfill-module": "14.0.4-canary.8", + "@next/polyfill-nomodule": "14.0.4-canary.8", + "@next/react-dev-overlay": "14.0.4-canary.8", + "@next/react-refresh-utils": "14.0.4-canary.8", + "@next/swc": "14.0.4-canary.8", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index 7f2af217f8885..cee8342d82878 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.7", + "version": "14.0.4-canary.8", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index e09ee9b6cbfba..32605fe54bb40 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.7", + "version": "14.0.4-canary.8", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index daa87bdc4456c..31acfd2428eb1 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.7", + "version": "14.0.4-canary.8", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -23,7 +23,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.7", + "next": "14.0.4-canary.8", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 3960f63de1b43..ee43314cc9d50 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -735,7 +735,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.7 + specifier: 14.0.4-canary.8 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -800,7 +800,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.7 + specifier: 14.0.4-canary.8 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -924,19 +924,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.7 + specifier: 14.0.4-canary.8 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.7 + specifier: 14.0.4-canary.8 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.7 + specifier: 14.0.4-canary.8 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.7 + specifier: 14.0.4-canary.8 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.7 + specifier: 14.0.4-canary.8 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1587,7 +1587,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.7 + specifier: 14.0.4-canary.8 version: link:../next outdent: specifier: 0.8.0 @@ -24647,7 +24647,7 @@ packages: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231121.2(react-refresh@0.12.0)(webpack@5.86.0)': - resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231121.2} + resolution: {registry: https://registry.npmjs.org/, tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231121.2} id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231121.2' name: '@vercel/turbopack-ecmascript-runtime' version: 0.0.0 From 3043feef448bc0685c996a9946381fcfdb51048d Mon Sep 17 00:00:00 2001 From: Zack Tanner Date: Tue, 21 Nov 2023 16:55:44 -0800 Subject: [PATCH 008/481] disable static prefetching behavior for dynamic segments (#58609) ### What? When a layout segment forces dynamic rendering (such as with `force-dynamic` or `revalidate: 0`), navigating to sub-pages of that layout will attempt to re-render the layout, also resulting in side effects re-running. This means if your layout relies on a data fetch and you render the result of that data in the layout, it will unexpectedly change when navigating between sub-paths, as described in #57326. As a separate issue (but caused by the same underlying mechanism), when using `searchParams` on a dynamic page, changes to those search params will be erroneously ignored when navigating, as described in #57075 ### Why? As a performance optimization we generate static prefetch files for dynamic segments ([original PR](https://github.com/vercel/next.js/pull/54403)). This makes it so that when prefetching is turned on, the prefetch can be served quickly from the edge without needing to invoke unnecessarily. We're able to eagerly serve things that can be safely prefetched. This is nice for cases where a path has a `loading.js` that we can eagerly render while waiting for the dynamic data to be loaded. This causes a problem with layouts that opt into dynamic rendering: when the page loads and a prefetch is kicked off for the sub-page, it'll load the static prefetch, which won't be generated with the same router state as the dynamically rendered page. This causes a mismatch between the two trees, and when navigating within the same segment, a refetch will be added to the router because it thinks that it's navigating to a new layout. This also causes issues for dynamic pages that use `searchParams`. The static prefetch will be generated without any knowledge of search params, and when the prefetch occurs, we still match to the prefetch generated without search params. This will make the router think that no change occurs, and the UI will not update to reflect the change. ### How? There's ongoing work by @acdlite to refactor the client router. Hopefully it will be easier to re-land this once that work is finished. For now, I've reverted the behavior as it doesn't seem to be worth the bugs it currently causes. I've also added tests so that when we do re-land this behavior, we can catch these subtleties. Fixes #57326 Fixes #57075 Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- packages/next/src/export/routes/app-page.ts | 19 +++- packages/next/src/server/base-server.ts | 46 +++++----- .../app-prefetch/app/force-dynamic/layout.js | 19 ++++ .../app/force-dynamic/search-params/page.js | 11 +++ .../app/force-dynamic/test-page/page.js | 10 +++ .../force-dynamic/test-page/sub-page/page.js | 10 +++ .../app-prefetch/app/revalidate-0/layout.js | 19 ++++ .../app/revalidate-0/search-params/page.js | 11 +++ .../app/revalidate-0/test-page/page.js | 10 +++ .../revalidate-0/test-page/sub-page/page.js | 10 +++ .../app-dir/app-prefetch/prefetching.test.ts | 87 +++++++++++++++---- .../e2e/app-dir/app-static/app-static.test.ts | 36 ++++---- test/e2e/app-dir/app/index.test.ts | 3 +- 13 files changed, 229 insertions(+), 62 deletions(-) create mode 100644 test/e2e/app-dir/app-prefetch/app/force-dynamic/layout.js create mode 100644 test/e2e/app-dir/app-prefetch/app/force-dynamic/search-params/page.js create mode 100644 test/e2e/app-dir/app-prefetch/app/force-dynamic/test-page/page.js create mode 100644 test/e2e/app-dir/app-prefetch/app/force-dynamic/test-page/sub-page/page.js create mode 100644 test/e2e/app-dir/app-prefetch/app/revalidate-0/layout.js create mode 100644 test/e2e/app-dir/app-prefetch/app/revalidate-0/search-params/page.js create mode 100644 test/e2e/app-dir/app-prefetch/app/revalidate-0/test-page/page.js create mode 100644 test/e2e/app-dir/app-prefetch/app/revalidate-0/test-page/sub-page/page.js diff --git a/packages/next/src/export/routes/app-page.ts b/packages/next/src/export/routes/app-page.ts index e0ccd312c0d9e..775b95382823a 100644 --- a/packages/next/src/export/routes/app-page.ts +++ b/packages/next/src/export/routes/app-page.ts @@ -37,7 +37,14 @@ async function generatePrefetchRsc( htmlFilepath: string, renderOpts: RenderOpts, fileWriter: FileWriter -) { +): Promise { + // TODO: Re-enable once this is better supported client-side + // It's currently not reliable to generate these prefetches because the client router + // depends on the RSC payload being generated with FlightRouterState. When we generate these prefetches + // without router state, it causes mismatches on client-side nav, resulting in subtle navigation bugs + // like unnecessarily re-rendering layouts. + return false + // When we're in PPR, the RSC payload is emitted as the prefetch payload, so // attempting to generate a prefetch RSC is an error. if (renderOpts.experimental.ppr) { @@ -64,13 +71,15 @@ async function generatePrefetchRsc( const prefetchRscData = await prefetchRenderResult.toUnchunkedString(true) - if ((renderOpts as any).store.staticPrefetchBailout) return + if ((renderOpts as any).store.staticPrefetchBailout) return false await fileWriter( ExportedAppPageFiles.FLIGHT, htmlFilepath.replace(/\.html$/, RSC_PREFETCH_SUFFIX), prefetchRscData ) + + return true } export async function exportAppPage( @@ -94,7 +103,7 @@ export async function exportAppPage( try { if (isAppPrefetch) { - await generatePrefetchRsc( + const generated = await generatePrefetchRsc( req, path, res, @@ -104,7 +113,9 @@ export async function exportAppPage( fileWriter ) - return { revalidate: 0 } + if (generated) { + return { revalidate: 0 } + } } const result = await lazyRenderAppPage( diff --git a/packages/next/src/server/base-server.ts b/packages/next/src/server/base-server.ts index f1e885a390663..f8813e0e3af5b 100644 --- a/packages/next/src/server/base-server.ts +++ b/packages/next/src/server/base-server.ts @@ -84,7 +84,6 @@ import { NEXT_RSC_UNION_QUERY, ACTION, NEXT_ROUTER_PREFETCH_HEADER, - RSC_CONTENT_TYPE_HEADER, } from '../client/components/app-router-headers' import type { MatchOptions, @@ -2315,28 +2314,29 @@ export default abstract class Server { { page: pathname, params: opts.params, query, renderOpts } ) } else if (isAppPageRouteModule(routeModule)) { - if ( - !opts.experimental.ppr && - isPrefetchRSCRequest && - process.env.NODE_ENV === 'production' && - !this.minimalMode - ) { - try { - const prefetchRsc = await this.getPrefetchRsc(resolvedUrlPathname) - if (prefetchRsc) { - res.setHeader( - 'cache-control', - 'private, no-cache, no-store, max-age=0, must-revalidate' - ) - res.setHeader('content-type', RSC_CONTENT_TYPE_HEADER) - res.body(prefetchRsc).send() - return null - } - } catch { - // We fallback to invoking the function if prefetch data is not - // available. - } - } + // TODO: Re-enable once static prefetches re-land + // if ( + // !opts.experimental.ppr && + // isPrefetchRSCRequest && + // process.env.NODE_ENV === 'production' && + // !this.minimalMode + // ) { + // try { + // const prefetchRsc = await this.getPrefetchRsc(resolvedUrlPathname) + // if (prefetchRsc) { + // res.setHeader( + // 'cache-control', + // 'private, no-cache, no-store, max-age=0, must-revalidate' + // ) + // res.setHeader('content-type', RSC_CONTENT_TYPE_HEADER) + // res.body(prefetchRsc).send() + // return null + // } + // } catch { + // // We fallback to invoking the function if prefetch data is not + // // available. + // } + // } const module = components.routeModule as AppPageRouteModule diff --git a/test/e2e/app-dir/app-prefetch/app/force-dynamic/layout.js b/test/e2e/app-dir/app-prefetch/app/force-dynamic/layout.js new file mode 100644 index 0000000000000..d48c1a709a6c3 --- /dev/null +++ b/test/e2e/app-dir/app-prefetch/app/force-dynamic/layout.js @@ -0,0 +1,19 @@ +import React from 'react' + +export const dynamic = 'force-dynamic' + +export default async function Layout({ children }) { + console.log('re-fetching in layout') + const data = await fetch( + 'https://next-data-api-endpoint.vercel.app/api/random' + ) + const randomNumber = await data.text() + + return ( +
+

{randomNumber}

+ + {children} +
+ ) +} diff --git a/test/e2e/app-dir/app-prefetch/app/force-dynamic/search-params/page.js b/test/e2e/app-dir/app-prefetch/app/force-dynamic/search-params/page.js new file mode 100644 index 0000000000000..be0b02addb54d --- /dev/null +++ b/test/e2e/app-dir/app-prefetch/app/force-dynamic/search-params/page.js @@ -0,0 +1,11 @@ +import Link from 'next/link' + +export default function Home({ searchParams }) { + return ( + <> +
{JSON.stringify(searchParams)}
+ Add search params + Clear Params + + ) +} diff --git a/test/e2e/app-dir/app-prefetch/app/force-dynamic/test-page/page.js b/test/e2e/app-dir/app-prefetch/app/force-dynamic/test-page/page.js new file mode 100644 index 0000000000000..6eafc9a17990e --- /dev/null +++ b/test/e2e/app-dir/app-prefetch/app/force-dynamic/test-page/page.js @@ -0,0 +1,10 @@ +import Link from 'next/link' + +export default function Page() { + return ( +
+ Hello from /force-dynamic/test-page{' '} + To Sub Page +
+ ) +} diff --git a/test/e2e/app-dir/app-prefetch/app/force-dynamic/test-page/sub-page/page.js b/test/e2e/app-dir/app-prefetch/app/force-dynamic/test-page/sub-page/page.js new file mode 100644 index 0000000000000..de9cb036b49a4 --- /dev/null +++ b/test/e2e/app-dir/app-prefetch/app/force-dynamic/test-page/sub-page/page.js @@ -0,0 +1,10 @@ +import Link from 'next/link' + +export default function Page() { + return ( +
+ Hello from /force-dynamic/test-page/sub-page{' '} + Back to Test Page +
+ ) +} diff --git a/test/e2e/app-dir/app-prefetch/app/revalidate-0/layout.js b/test/e2e/app-dir/app-prefetch/app/revalidate-0/layout.js new file mode 100644 index 0000000000000..95d001d2c77e5 --- /dev/null +++ b/test/e2e/app-dir/app-prefetch/app/revalidate-0/layout.js @@ -0,0 +1,19 @@ +import React from 'react' + +export const revalidate = 0 + +export default async function Layout({ children }) { + console.log('re-fetching in layout') + const data = await fetch( + 'https://next-data-api-endpoint.vercel.app/api/random' + ) + const randomNumber = await data.text() + + return ( +
+

{randomNumber}

+ + {children} +
+ ) +} diff --git a/test/e2e/app-dir/app-prefetch/app/revalidate-0/search-params/page.js b/test/e2e/app-dir/app-prefetch/app/revalidate-0/search-params/page.js new file mode 100644 index 0000000000000..6faaf156f4fdc --- /dev/null +++ b/test/e2e/app-dir/app-prefetch/app/revalidate-0/search-params/page.js @@ -0,0 +1,11 @@ +import Link from 'next/link' + +export default function Home({ searchParams }) { + return ( + <> +
{JSON.stringify(searchParams)}
+ Add search params + Clear Params + + ) +} diff --git a/test/e2e/app-dir/app-prefetch/app/revalidate-0/test-page/page.js b/test/e2e/app-dir/app-prefetch/app/revalidate-0/test-page/page.js new file mode 100644 index 0000000000000..a3eb60248ef2e --- /dev/null +++ b/test/e2e/app-dir/app-prefetch/app/revalidate-0/test-page/page.js @@ -0,0 +1,10 @@ +import Link from 'next/link' + +export default function Page() { + return ( +
+ Hello from /revalidate-0/test-page{' '} + To Sub Page +
+ ) +} diff --git a/test/e2e/app-dir/app-prefetch/app/revalidate-0/test-page/sub-page/page.js b/test/e2e/app-dir/app-prefetch/app/revalidate-0/test-page/sub-page/page.js new file mode 100644 index 0000000000000..d672b3beac96d --- /dev/null +++ b/test/e2e/app-dir/app-prefetch/app/revalidate-0/test-page/sub-page/page.js @@ -0,0 +1,10 @@ +import Link from 'next/link' + +export default function Page() { + return ( +
+ Hello from /revalidate-0/test-page/sub-page{' '} + Back to Test Page +
+ ) +} diff --git a/test/e2e/app-dir/app-prefetch/prefetching.test.ts b/test/e2e/app-dir/app-prefetch/prefetching.test.ts index 9f8426392ee55..63fb9d55cdd81 100644 --- a/test/e2e/app-dir/app-prefetch/prefetching.test.ts +++ b/test/e2e/app-dir/app-prefetch/prefetching.test.ts @@ -301,24 +301,79 @@ createNextDescribe( expect(prefetchResponse).toContain('Loading Prefetch Auto') }) - it('should not generate static prefetches for layouts that opt into dynamic rendering', async () => { - await next.stop() - const rootLoading = await next.readFile('./app/loading.js') - await next.deleteFile('./app/loading.js') - await next.start() - expect( - await next - .readFile('.next/server/app/prefetch-dynamic-usage/foo.prefetch.rsc') - .catch(() => false) - ).toBeFalsy() + describe('dynamic rendering', () => { + async function hasStaticPrefetch(filePath: string): Promise { + try { + await next.readFile(`.next/server/app${filePath}`) + return true + } catch { + return false + } + } + it('should not generate a static prefetch for layouts that use cookies/headers', async () => { + expect( + await hasStaticPrefetch('/prefetch-dynamic-usage/foo.prefetch.rsc') + ).toBe(false) - expect( - await next - .readFile('.next/server/app/prefetch-dynamic-usage/foo.prefetch.rsc') - .catch(() => false) - ).toBeFalsy() + expect( + await hasStaticPrefetch('/prefetch-dynamic-usage/bar.prefetch.rsc') + ).toBe(false) + }) - await next.patchFile('./app/loading', rootLoading) + describe.each(['/force-dynamic', '/revalidate-0'])('%s', (basePath) => { + it('should not re-render layout when navigating between sub-pages', async () => { + const logStartIndex = next.cliOutput.length + + const browser = await next.browser(`${basePath}/test-page`) + let initialRandomNumber = await browser + .elementById('random-number') + .text() + await browser + .elementByCss(`[href="${basePath}/test-page/sub-page"]`) + .click() + + await check(() => browser.hasElementByCssSelector('#sub-page'), true) + + const newRandomNumber = await browser + .elementById('random-number') + .text() + + expect(initialRandomNumber).toBe(newRandomNumber) + + await check(() => { + const logOccurrences = + next.cliOutput.slice(logStartIndex).split('re-fetching in layout') + .length - 1 + + return logOccurrences + }, 1) + }) + + it('should update search params following a link click', async () => { + const browser = await next.browser(`${basePath}/search-params`) + await check( + () => browser.elementById('search-params-data').text(), + /{}/ + ) + await browser.elementByCss('[href="?foo=true"]').click() + await check( + () => browser.elementById('search-params-data').text(), + /{"foo":"true"}/ + ) + await browser + .elementByCss(`[href="${basePath}/search-params"]`) + .click() + await check( + () => browser.elementById('search-params-data').text(), + /{}/ + ) + await browser.elementByCss('[href="?foo=true"]').click() + await check( + () => browser.elementById('search-params-data').text(), + /{"foo":"true"}/ + ) + }) + }) }) } ) diff --git a/test/e2e/app-dir/app-static/app-static.test.ts b/test/e2e/app-dir/app-static/app-static.test.ts index 868c3a7cae165..68b8ce979ab4c 100644 --- a/test/e2e/app-dir/app-static/app-static.test.ts +++ b/test/e2e/app-dir/app-static/app-static.test.ts @@ -507,7 +507,7 @@ createNextDescribe( 'ssg-draft-mode.rsc', 'ssr-forced/page.js', 'articles/works.rsc', - 'custom.prefetch.rsc', + // 'custom.prefetch.rsc', 'force-cache/page.js', 'ssg-draft-mode.html', 'articles/works.html', @@ -526,7 +526,7 @@ createNextDescribe( 'force-static/first.html', 'force-static/second.rsc', 'ssg-draft-mode/test.rsc', - 'ssr-forced.prefetch.rsc', + // 'ssr-forced.prefetch.rsc', 'isr-error-handling.html', 'articles/[slug]/page.js', 'no-store/static/page.js', @@ -537,15 +537,15 @@ createNextDescribe( 'no-store/dynamic/page.js', 'blog/seb/second-post.html', 'ssg-draft-mode/test-2.rsc', - 'response-url.prefetch.rsc', + // 'response-url.prefetch.rsc', 'blog/styfle/first-post.rsc', - 'default-cache.prefetch.rsc', + // 'default-cache.prefetch.rsc', 'dynamic-error/[id]/page.js', 'ssg-draft-mode/test-2.html', 'blog/styfle/first-post.html', 'blog/styfle/second-post.rsc', - 'fetch-no-cache.prefetch.rsc', - 'force-no-store.prefetch.rsc', + // 'fetch-no-cache.prefetch.rsc', + // 'force-no-store.prefetch.rsc', 'force-static/[slug]/page.js', 'hooks/use-pathname/slug.rsc', 'hooks/use-search-params.rsc', @@ -571,12 +571,12 @@ createNextDescribe( 'react-fetch-deduping-node/page.js', 'variable-revalidate/encoding.html', 'variable-revalidate/cookie/page.js', - 'gen-params-dynamic/one.prefetch.rsc', + // 'gen-params-dynamic/one.prefetch.rsc', 'ssg-draft-mode/[[...route]]/page.js', 'variable-revalidate/post-method.rsc', 'stale-cache-serving/app-page/page.js', 'dynamic-no-gen-params/[slug]/page.js', - 'ssr-auto/cache-no-store.prefetch.rsc', + // 'ssr-auto/cache-no-store.prefetch.rsc', 'static-to-dynamic-error/[id]/page.js', 'variable-revalidate/encoding/page.js', 'variable-revalidate/no-store/page.js', @@ -590,7 +590,7 @@ createNextDescribe( 'variable-revalidate/revalidate-3.html', 'force-dynamic-prerender/[slug]/page.js', 'gen-params-dynamic-revalidate/one.html', - 'react-fetch-deduping-node.prefetch.rsc', + // 'react-fetch-deduping-node.prefetch.rsc', 'ssr-auto/fetch-revalidate-zero/page.js', 'variable-revalidate/authorization.html', '_not-found_client-reference-manifest.js', @@ -604,8 +604,8 @@ createNextDescribe( 'variable-revalidate/headers-instance.rsc', 'variable-revalidate/revalidate-3/page.js', 'stale-cache-serving-edge/app-page/page.js', - 'stale-cache-serving/app-page.prefetch.rsc', - 'force-dynamic-catch-all/slug.prefetch.rsc', + // 'stale-cache-serving/app-page.prefetch.rsc', + // 'force-dynamic-catch-all/slug.prefetch.rsc', 'hooks/use-search-params/force-static.html', 'hooks/use-search-params/with-suspense.rsc', 'route-handler/revalidate-360-isr/route.js', @@ -613,13 +613,13 @@ createNextDescribe( 'variable-revalidate-edge/no-store/page.js', 'variable-revalidate/authorization/page.js', 'variable-revalidate/headers-instance.html', - 'variable-revalidate/no-store.prefetch.rsc', + // 'variable-revalidate/no-store.prefetch.rsc', 'stale-cache-serving/route-handler/route.js', 'hooks/use-search-params/with-suspense.html', 'route-handler-edge/revalidate-360/route.js', 'variable-revalidate/revalidate-360-isr.rsc', 'variable-revalidate/revalidate-360/page.js', - 'ssr-auto/fetch-revalidate-zero.prefetch.rsc', + // 'ssr-auto/fetch-revalidate-zero.prefetch.rsc', 'static-to-dynamic-error-forced/[id]/page.js', 'variable-config-revalidate/revalidate-3.rsc', 'variable-revalidate/revalidate-360-isr.html', @@ -630,9 +630,9 @@ createNextDescribe( 'variable-config-revalidate/revalidate-3.html', 'variable-revalidate-edge/post-method/page.js', 'variable-revalidate/headers-instance/page.js', - 'variable-revalidate/status-code.prefetch.rsc', + // 'variable-revalidate/status-code.prefetch.rsc', 'force-cache/page_client-reference-manifest.js', - 'force-dynamic-no-with-revalidate.prefetch.rsc', + // 'force-dynamic-no-with-revalidate.prefetch.rsc', 'hooks/use-search-params/with-suspense/page.js', 'variable-revalidate-edge/revalidate-3/page.js', '(new)/custom/page_client-reference-manifest.js', @@ -642,10 +642,10 @@ createNextDescribe( 'stale-cache-serving-edge/route-handler/route.js', 'blog/[author]/page_client-reference-manifest.js', 'default-cache/page_client-reference-manifest.js', - 'force-dynamic-prerender/frameworks.prefetch.rsc', + // 'force-dynamic-prerender/frameworks.prefetch.rsc', 'variable-config-revalidate/revalidate-3/page.js', 'variable-revalidate/post-method-request/page.js', - 'variable-revalidate/revalidate-360.prefetch.rsc', + // 'variable-revalidate/revalidate-360.prefetch.rsc', 'fetch-no-cache/page_client-reference-manifest.js', 'force-dynamic-catch-all/[slug]/[[...id]]/page.js', 'force-no-store/page_client-reference-manifest.js', @@ -677,7 +677,7 @@ createNextDescribe( 'partial-gen-params-no-additional-lang/fr/second.html', 'partial-gen-params-no-additional-slug/en/second.html', 'partial-gen-params-no-additional-slug/fr/second.html', - 'variable-revalidate/post-method-request.prefetch.rsc', + // 'variable-revalidate/post-method-request.prefetch.rsc', 'variable-revalidate-edge/post-method-request/page.js', 'force-static/[slug]/page_client-reference-manifest.js', 'blog/[author]/[slug]/page_client-reference-manifest.js', diff --git a/test/e2e/app-dir/app/index.test.ts b/test/e2e/app-dir/app/index.test.ts index 6811a37c142f8..5c5f5b230b48a 100644 --- a/test/e2e/app-dir/app/index.test.ts +++ b/test/e2e/app-dir/app/index.test.ts @@ -37,7 +37,8 @@ createNextDescribe( ) }) - it('should use RSC prefetch data from build', async () => { + // TODO: Re-enable once static prefetches re-land + it.skip('should use RSC prefetch data from build', async () => { expect( await next.readFile('.next/server/app/linking.prefetch.rsc') ).toBeTruthy() From 7a0fdb33dae7a21a5a0dbde2f8340b52d56f53d1 Mon Sep 17 00:00:00 2001 From: Zack Tanner Date: Tue, 21 Nov 2023 18:01:53 -0800 Subject: [PATCH 009/481] fix: ensure DynamicUsageErrors caught during render bubble up (#58747) After the changes in #58669, it's now possible for these `DynamicUsageErrors` to be caught in the streaming renderer. We didn't have any logic to handle this happening inside the existing catch block, so this adds a check for that specific error and re-throws it so that it properly bubbles to `exportPage`. `exportPage` checks the error to see if it's a `DynamicUsageError` and if so, marks the page as dynamic. (This resolves an issue with particular scenarios hanging the build, caught by a few of our tests: [example](https://github.com/vercel/next.js/actions/runs/6949079695/job/18907597751?pr=58744), [example](https://github.com/vercel/next.js/actions/runs/6948412805/job/18904387924)) --- packages/next/src/export/routes/app-page.ts | 47 ++++++++++++++----- .../next/src/server/app-render/app-render.tsx | 7 +++ 2 files changed, 43 insertions(+), 11 deletions(-) diff --git a/packages/next/src/export/routes/app-page.ts b/packages/next/src/export/routes/app-page.ts index 775b95382823a..64b62dfc9405d 100644 --- a/packages/next/src/export/routes/app-page.ts +++ b/packages/next/src/export/routes/app-page.ts @@ -160,17 +160,11 @@ export async function exportAppPage( const { staticBailoutInfo = {} } = metadata if (revalidate === 0 && debugOutput && staticBailoutInfo?.description) { - const err = new Error( - `Static generation failed due to dynamic usage on ${path}, reason: ${staticBailoutInfo.description}` - ) - - // Update the stack if it was provided via the bailout info. - const { stack } = staticBailoutInfo - if (stack) { - err.stack = err.message + stack.substring(stack.indexOf('\n')) - } - - console.warn(err) + logDynamicUsageWarning({ + path, + description: staticBailoutInfo.description, + stack: staticBailoutInfo.stack, + }) } return { revalidate: 0 } @@ -234,6 +228,37 @@ export async function exportAppPage( throw err } + if (debugOutput) { + const { dynamicUsageDescription, dynamicUsageStack } = (renderOpts as any) + .store + + logDynamicUsageWarning({ + path, + description: dynamicUsageDescription, + stack: dynamicUsageStack, + }) + } + return { revalidate: 0 } } } + +function logDynamicUsageWarning({ + path, + description, + stack, +}: { + path: string + description: string + stack?: string +}) { + const errMessage = new Error( + `Static generation failed due to dynamic usage on ${path}, reason: ${description}` + ) + + if (stack) { + errMessage.stack = errMessage.message + stack.substring(stack.indexOf('\n')) + } + + console.warn(errMessage) +} diff --git a/packages/next/src/server/app-render/app-render.tsx b/packages/next/src/server/app-render/app-render.tsx index 840d873002822..d8a6e2662b871 100644 --- a/packages/next/src/server/app-render/app-render.tsx +++ b/packages/next/src/server/app-render/app-render.tsx @@ -75,6 +75,7 @@ import { setReferenceManifestsSingleton } from './action-encryption-utils' import { createStaticRenderer } from './static/static-renderer' import { MissingPostponeDataError } from './is-missing-postpone-error' import { DetachedPromise } from '../../lib/detached-promise' +import { DYNAMIC_ERROR_CODE } from '../../client/components/hooks-server-context' export type GetDynamicParamFromSegment = ( // [slug] / [[slug]] / [...slug] @@ -819,6 +820,12 @@ async function renderToHTMLOrFlightImpl( throw err } + if (isStaticGeneration && err.digest === DYNAMIC_ERROR_CODE) { + // ensure that DynamicUsageErrors bubble up during static generation + // as this will indicate that the page needs to be dynamically rendered + throw err + } + if (err.digest === NEXT_DYNAMIC_NO_SSR_CODE) { warn( `Entire page ${pagePath} deopted into client-side rendering. https://nextjs.org/docs/messages/deopted-into-client-rendering`, From c0bafcb3541252e7ca915d2d6b16b535338459ea Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Wed, 22 Nov 2023 02:11:25 +0000 Subject: [PATCH 010/481] v14.0.4-canary.9 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 16 ++++++++-------- 18 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lerna.json b/lerna.json index b4141e2e62708..b326078caf02d 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.8" + "version": "14.0.4-canary.9" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 5636720cea43e..57f6aac0ae385 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.8", + "version": "14.0.4-canary.9", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 3e06ec317b092..1e08f097e36c1 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.8", + "version": "14.0.4-canary.9", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.8", + "@next/eslint-plugin-next": "14.0.4-canary.9", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 17111cbe16ba8..be3f1ecb2e0c6 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.8", + "version": "14.0.4-canary.9", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index fee9637620b79..f9e4702cd825c 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.8", + "version": "14.0.4-canary.9", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 259d70150e8ff..5b2084ed8d265 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.8", + "version": "14.0.4-canary.9", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 5d3a170f05082..7819967b8a624 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.8", + "version": "14.0.4-canary.9", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index b91c0422060fc..2679d6ba9c20f 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.8", + "version": "14.0.4-canary.9", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 118e201457158..f0cd8c4e0814f 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.8", + "version": "14.0.4-canary.9", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 152ae1d9f70ee..78f7492f033d0 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.8", + "version": "14.0.4-canary.9", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index 0a2332ddcf248..398f065d8791b 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.8", + "version": "14.0.4-canary.9", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index 1740c247ed709..4e068e3d7c4d4 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.8", + "version": "14.0.4-canary.9", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index 8a7ba189391e5..36c3663fbaf59 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.8", + "version": "14.0.4-canary.9", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index a0f0d1ea19d8c..c1876e2481066 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.8", + "version": "14.0.4-canary.9", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.8", + "@next/env": "14.0.4-canary.9", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -146,11 +146,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.8", - "@next/polyfill-nomodule": "14.0.4-canary.8", - "@next/react-dev-overlay": "14.0.4-canary.8", - "@next/react-refresh-utils": "14.0.4-canary.8", - "@next/swc": "14.0.4-canary.8", + "@next/polyfill-module": "14.0.4-canary.9", + "@next/polyfill-nomodule": "14.0.4-canary.9", + "@next/react-dev-overlay": "14.0.4-canary.9", + "@next/react-refresh-utils": "14.0.4-canary.9", + "@next/swc": "14.0.4-canary.9", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index cee8342d82878..cd6781ce6a80f 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.8", + "version": "14.0.4-canary.9", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index 32605fe54bb40..a3c6fc50b1870 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.8", + "version": "14.0.4-canary.9", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index 31acfd2428eb1..ece8e0937dc1d 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.8", + "version": "14.0.4-canary.9", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -23,7 +23,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.8", + "next": "14.0.4-canary.9", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ee43314cc9d50..93bac11312c32 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -735,7 +735,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.8 + specifier: 14.0.4-canary.9 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -800,7 +800,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.8 + specifier: 14.0.4-canary.9 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -924,19 +924,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.8 + specifier: 14.0.4-canary.9 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.8 + specifier: 14.0.4-canary.9 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.8 + specifier: 14.0.4-canary.9 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.8 + specifier: 14.0.4-canary.9 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.8 + specifier: 14.0.4-canary.9 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1587,7 +1587,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.8 + specifier: 14.0.4-canary.9 version: link:../next outdent: specifier: 0.8.0 From a2b781fafe54011d9f006a9423cfbd0d14d551c4 Mon Sep 17 00:00:00 2001 From: Zack Tanner Date: Tue, 21 Nov 2023 18:20:59 -0800 Subject: [PATCH 011/481] fix image.domains deprecation warning (#58656) ### What? In #57062, a deprecation warning was added for usage of `nextConfig.images.domains`. This warning was erroneously showing up for users that had an `assetPrefix` configured. ### Why? When an `assetPrefix` specified, during assignment for `nextConfig` default values, we push to `nextConfig.images.domains` so that the user doesn't receive errors about hostnames not being configured ([Original PR](https://github.com/vercel/next.js/pull/29307)). This means people are indirectly being opted into a deprecated config, and receiving a warning because of it. ### How? We no longer push any defaults to the deprecated config option. Additionally, this applies the same defaults handling to `remotePatterns,` as otherwise people using this new config will run into the same issue as this block was originally intended to fix. Fixes #58074 --- packages/next/src/server/config.test.ts | 64 +++++++++++++++++++ packages/next/src/server/config.ts | 35 ++++++++-- .../image-optimizer/test/index.test.ts | 51 +++++++++++++++ .../asset-prefix/test/index.test.js | 40 +++++++++++- 4 files changed, 184 insertions(+), 6 deletions(-) create mode 100644 packages/next/src/server/config.test.ts diff --git a/packages/next/src/server/config.test.ts b/packages/next/src/server/config.test.ts new file mode 100644 index 0000000000000..7b04cbe5fefdb --- /dev/null +++ b/packages/next/src/server/config.test.ts @@ -0,0 +1,64 @@ +import loadConfig from './config' + +describe('loadConfig', () => { + describe('nextConfig.images defaults', () => { + it('should assign a `images.remotePatterns` when using assetPrefix', async () => { + const result = await loadConfig('', __dirname, { + customConfig: { + assetPrefix: 'https://cdn.example.com', + images: { + formats: ['image/webp'], + }, + }, + }) + + expect(result.images.remotePatterns).toMatchInlineSnapshot(` + [ + { + "hostname": "cdn.example.com", + "port": "", + "protocol": "https", + }, + ] + `) + }) + + it('should not assign a duplicate `images.remotePatterns` value when using assetPrefix', async () => { + let result = await loadConfig('', __dirname, { + customConfig: { + assetPrefix: 'https://cdn.example.com', + images: { + formats: ['image/webp'], + remotePatterns: [ + { + hostname: 'cdn.example.com', + port: '', + protocol: 'https', + }, + ], + }, + }, + }) + + expect(result.images.remotePatterns.length).toBe(1) + + result = await loadConfig('', __dirname, { + customConfig: { + assetPrefix: 'https://cdn.example.com/foobar', + images: { + formats: ['image/webp'], + remotePatterns: [ + { + hostname: 'cdn.example.com', + port: '', + protocol: 'https', + }, + ], + }, + }, + }) + + expect(result.images.remotePatterns.length).toBe(1) + }) + }) +}) diff --git a/packages/next/src/server/config.ts b/packages/next/src/server/config.ts index 0fa4663b8dc6b..b0cba57e061da 100644 --- a/packages/next/src/server/config.ts +++ b/packages/next/src/server/config.ts @@ -20,6 +20,7 @@ import { flushAndExit } from '../telemetry/flush-and-exit' import { findRootDir } from '../lib/find-root' import { setHttpClientAndAgentOptions } from './setup-http-agent-env' import { pathHasPrefix } from '../shared/lib/router/utils/path-has-prefix' +import { matchRemotePattern } from '../shared/lib/match-remote-pattern' import { ZodParsedType, util as ZodUtil } from 'next/dist/compiled/zod' import type { ZodError, ZodIssue } from 'next/dist/compiled/zod' @@ -358,10 +359,10 @@ function assignDefaults( ) } - if (images.domains) { - if (!Array.isArray(images.domains)) { + if (images.remotePatterns) { + if (!Array.isArray(images.remotePatterns)) { throw new Error( - `Specified images.domains should be an Array received ${typeof images.domains}.\nSee more info here: https://nextjs.org/docs/messages/invalid-images-config` + `Specified images.remotePatterns should be an Array received ${typeof images.remotePatterns}.\nSee more info here: https://nextjs.org/docs/messages/invalid-images-config` ) } @@ -369,7 +370,33 @@ function assignDefaults( // so we need to ensure _next/image allows downloading from // this resource if (config.assetPrefix?.startsWith('http')) { - images.domains.push(new URL(config.assetPrefix).hostname) + try { + const url = new URL(config.assetPrefix) + const hasMatchForAssetPrefix = images.remotePatterns.some((pattern) => + matchRemotePattern(pattern, url) + ) + + // avoid double-pushing the same remote if it already can be matched + if (!hasMatchForAssetPrefix) { + images.remotePatterns?.push({ + hostname: url.hostname, + protocol: url.protocol.replace(/:$/, '') as 'http' | 'https', + port: url.port, + }) + } + } catch (error) { + throw new Error( + `Invalid assetPrefix provided. Original error: ${error}` + ) + } + } + } + + if (images.domains) { + if (!Array.isArray(images.domains)) { + throw new Error( + `Specified images.domains should be an Array received ${typeof images.domains}.\nSee more info here: https://nextjs.org/docs/messages/invalid-images-config` + ) } } diff --git a/test/integration/image-optimizer/test/index.test.ts b/test/integration/image-optimizer/test/index.test.ts index 519247edcf750..64dd66039d744 100644 --- a/test/integration/image-optimizer/test/index.test.ts +++ b/test/integration/image-optimizer/test/index.test.ts @@ -380,6 +380,57 @@ describe('Image Optimizer', () => { ) }) + it('should error when assetPrefix is provided but is invalid', async () => { + await nextConfig.replace( + '{ /* replaceme */ }', + JSON.stringify({ + assetPrefix: 'httpbad', + images: { + formats: ['image/webp'], + }, + }) + ) + let stderr = '' + + app = await launchApp(appDir, await findPort(), { + onStderr(msg) { + stderr += msg || '' + }, + }) + await waitFor(1000) + await killApp(app).catch(() => {}) + await nextConfig.restore() + + expect(stderr).toContain( + `Invalid assetPrefix provided. Original error: TypeError [ERR_INVALID_URL]: Invalid URL` + ) + }) + + it('should error when images.remotePatterns is invalid', async () => { + await nextConfig.replace( + '{ /* replaceme */ }', + JSON.stringify({ + images: { + remotePatterns: 'testing', + }, + }) + ) + let stderr = '' + + app = await launchApp(appDir, await findPort(), { + onStderr(msg) { + stderr += msg || '' + }, + }) + await waitFor(1000) + await killApp(app).catch(() => {}) + await nextConfig.restore() + + expect(stderr).toContain( + `Expected array, received string at "images.remotePatterns"` + ) + }) + it('should error when images.contentDispositionType is not valid', async () => { await nextConfig.replace( '{ /* replaceme */ }', diff --git a/test/integration/next-image-new/asset-prefix/test/index.test.js b/test/integration/next-image-new/asset-prefix/test/index.test.js index ef65c497f8cd7..578e2227e2a07 100644 --- a/test/integration/next-image-new/asset-prefix/test/index.test.js +++ b/test/integration/next-image-new/asset-prefix/test/index.test.js @@ -17,9 +17,18 @@ let app describe('Image Component assetPrefix Tests', () => { describe('dev mode', () => { + let stdout = '' + let stderr = '' beforeAll(async () => { appPort = await findPort() - app = await launchApp(appDir, appPort) + app = await launchApp(appDir, appPort, { + onStdout(msg) { + stdout += msg + }, + onStderr(msg) { + stderr += msg + }, + }) }) afterAll(() => killApp(app)) @@ -33,12 +42,30 @@ describe('Image Component assetPrefix Tests', () => { /\/_next\/image\?url=https%3A%2F%2Fexample\.vercel\.sh%2Fpre%2F_next%2Fstatic%2Fmedia%2Ftest(.+).jpg&w=8&q=70/ ) }) + + it('should not log a deprecation warning about using `images.domains`', async () => { + await webdriver(appPort, '/') + const warningMessage = + 'The "images.domains" configuration is deprecated. Please use "images.remotePatterns" configuration instead.' + + expect(stderr).not.toContain(warningMessage) + expect(stdout).not.toContain(warningMessage) + }) }) ;(process.env.TURBOPACK ? describe.skip : describe)('production mode', () => { + let stdout = '' + let stderr = '' beforeAll(async () => { await nextBuild(appDir) appPort = await findPort() - app = await nextStart(appDir, appPort) + app = await nextStart(appDir, appPort, { + onStdout(msg) { + stdout += msg + }, + onStderr(msg) { + stderr += msg + }, + }) }) afterAll(() => killApp(app)) @@ -50,5 +77,14 @@ describe('Image Component assetPrefix Tests', () => { ) expect(bgImage).toMatch('data:image/jpeg;base64') }) + + it('should not log a deprecation warning about using `images.domains`', async () => { + await webdriver(appPort, '/') + const warningMessage = + 'The "images.domains" configuration is deprecated. Please use "images.remotePatterns" configuration instead.' + + expect(stderr).not.toContain(warningMessage) + expect(stdout).not.toContain(warningMessage) + }) }) }) From 48a566bc4fcfc48d8489f096a87e792912c4989f Mon Sep 17 00:00:00 2001 From: Zack Tanner Date: Tue, 21 Nov 2023 18:37:35 -0800 Subject: [PATCH 012/481] fix waitUntil handling in pipeToNodeResponse (#58744) ### What? Calls to `revalidateTag` when using the data cache would sometimes be ignored. This would result in stale data being displayed even after manually triggering a revalidation. ### Why? Revalidation calls are pushed onto a `pendingRevalidates` array and, in the case of a route handler, are awaited [here](https://github.com/vercel/next.js/blob/8b11264ea95c9ed2f7dfd1e8d66a36b57ebc0da1/packages/next/src/server/send-response.ts#L53-L55). Previously this took place as part of the former `pipeReadable` implementation ([ref](https://github.com/vercel/next.js/blob/57bb52d37dd43fd669c5c07296daba19b6a12917/packages/next/src/server/send-response.ts#L49)) which awaited the promise before calling res.end ([ref](https://github.com/vercel/next.js/blob/57bb52d37dd43fd669c5c07296daba19b6a12917/packages/next/src/server/pipe-readable.ts#L99-L105)). There was a subtle change in behavior here in a recent refactor that seems to cause a race between awaiting the promise and ending the response, which results in this unpredictable behavior. ### How? This applies similar logic that used to be in the `pipeReadable` function to the new `pipeToNodeResponse` function. Namely, we plumb `waitUntil` into the writeable stream close handler and await it before calling `res.end()`. This is a very difficult edge case to test, and as such resorted to rigorous manual testing when deployed to an environment that uses the data cache. Fixes #52962 Fixes #57632 --- packages/next/src/server/pipe-readable.ts | 16 ++++++++++++---- packages/next/src/server/render-result.ts | 8 +------- packages/next/src/server/send-response.ts | 10 ++-------- 3 files changed, 15 insertions(+), 19 deletions(-) diff --git a/packages/next/src/server/pipe-readable.ts b/packages/next/src/server/pipe-readable.ts index 037ae2edcc349..89fe9f8c5afee 100644 --- a/packages/next/src/server/pipe-readable.ts +++ b/packages/next/src/server/pipe-readable.ts @@ -11,7 +11,8 @@ export function isAbortError(e: any): e is Error & { name: 'AbortError' } { } function createWriterFromResponse( - res: ServerResponse + res: ServerResponse, + waitUntilForEnd?: Promise ): WritableStream { let started = false @@ -75,7 +76,13 @@ function createWriterFromResponse( res.destroy(err) }, - close: () => { + close: async () => { + // if a waitUntil promise was passed, wait for it to resolve before + // ending the response. + if (waitUntilForEnd) { + await waitUntilForEnd + } + if (res.writableFinished) return res.end() @@ -86,7 +93,8 @@ function createWriterFromResponse( export async function pipeToNodeResponse( readable: ReadableStream, - res: ServerResponse + res: ServerResponse, + waitUntilForEnd?: Promise ) { try { // If the response has already errored, then just return now. @@ -97,7 +105,7 @@ export async function pipeToNodeResponse( // client disconnects. const controller = createAbortController(res) - const writer = createWriterFromResponse(res) + const writer = createWriterFromResponse(res, waitUntilForEnd) await readable.pipeTo(writer, { signal: controller.signal }) } catch (err: any) { diff --git a/packages/next/src/server/render-result.ts b/packages/next/src/server/render-result.ts index 217df3decf8af..8a498e6fb0bd1 100644 --- a/packages/next/src/server/render-result.ts +++ b/packages/next/src/server/render-result.ts @@ -216,12 +216,6 @@ export default class RenderResult { * @param res */ public async pipeToNodeResponse(res: ServerResponse) { - try { - await pipeToNodeResponse(this.readable, res) - } finally { - if (this.waitUntil) { - await this.waitUntil - } - } + await pipeToNodeResponse(this.readable, res, this.waitUntil) } } diff --git a/packages/next/src/server/send-response.ts b/packages/next/src/server/send-response.ts index 256ffb411b371..20dd088b788bb 100644 --- a/packages/next/src/server/send-response.ts +++ b/packages/next/src/server/send-response.ts @@ -15,7 +15,7 @@ export async function sendResponse( req: BaseNextRequest, res: BaseNextResponse, response: Response, - waitUntil?: Promise + waitUntil?: Promise ): Promise { // Don't use in edge runtime if (process.env.NEXT_RUNTIME !== 'edge') { @@ -47,13 +47,7 @@ export async function sendResponse( // A response body must not be sent for HEAD requests. See https://httpwg.org/specs/rfc9110.html#HEAD if (response.body && req.method !== 'HEAD') { - try { - await pipeToNodeResponse(response.body, originalResponse) - } finally { - if (waitUntil) { - await waitUntil - } - } + await pipeToNodeResponse(response.body, originalResponse, waitUntil) } else { originalResponse.end() } From b6f56444b4d0210b1cf603b6f9a2c2f95e238c90 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Wed, 22 Nov 2023 13:38:53 +0100 Subject: [PATCH 013/481] Use consistent resolve extensions alias for compiler (#58725) ## What? Changes the default resolve extensions to be consistent between server/client compilation. Currently browser prefers `.mjs` then `.js` and the server compiler prefers `.js` then `.mjs`. I added that behavior back in 2018 before mjs/cjs extensions were fully baked and many npm libraries had incorrect usage of it (PR: #5898). In the new setup with ESM resolving in Node.js writing out the full extension is required for `.mjs` files, meaning this "magic resolving" of a file to `.mjs` is no longer correct. In the future we'll likely want to remove `.mjs` from the default list of resolve extensions to align with the Node.js ESM resolver a bit more. For now we have to keep it in order to not break existing applications that rely on that behavior, an example of that seems to be contentlayer. ## How? Removed the condition and aligned it on a single list instead of separate lists. Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- packages/next/src/build/webpack-config.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/next/src/build/webpack-config.ts b/packages/next/src/build/webpack-config.ts index 221b3a0120d8a..72f7c6f4813da 100644 --- a/packages/next/src/build/webpack-config.ts +++ b/packages/next/src/build/webpack-config.ts @@ -587,9 +587,7 @@ export default async function getBaseWebpackConfig( const resolveConfig: webpack.Configuration['resolve'] = { // Disable .mjs for node_modules bundling - extensions: isNodeServer - ? ['.js', '.mjs', '.tsx', '.ts', '.jsx', '.json', '.wasm'] - : ['.mjs', '.js', '.tsx', '.ts', '.jsx', '.json', '.wasm'], + extensions: ['.js', '.mjs', '.tsx', '.ts', '.jsx', '.json', '.wasm'], extensionAlias: config.experimental.extensionAlias, modules: [ 'node_modules', From 154268a144dfac40a24f09c6ffc8a2fb48aa50be Mon Sep 17 00:00:00 2001 From: Will Binns-Smith Date: Wed, 22 Nov 2023 04:39:24 -0800 Subject: [PATCH 014/481] Turbopack: Use styled issue titles and details (#58743) This uses styled issue titles and details introduced in vercel/turbo#6535, which also moves "Module not found" messaging to the title field for those issues. Closes PACK-2013 --------- Co-authored-by: Tobias Koppers Co-authored-by: Leah Co-authored-by: Zack Tanner --- Cargo.lock | 66 +++++++++---------- Cargo.toml | 6 +- .../crates/napi/src/next_api/utils.rs | 61 +++++++++-------- .../next-core/src/app_segment_config.rs | 33 ++++++---- .../crates/next-core/src/app_structure.rs | 15 +++-- .../next-swc/crates/next-core/src/babel.rs | 15 +++-- .../crates/next-core/src/next_config.rs | 23 ++++--- .../src/next_font/google/font_fallback.rs | 5 +- .../crates/next-core/src/next_font/issue.rs | 10 +-- .../next-swc/crates/next-core/src/util.rs | 45 +++++++------ packages/next/package.json | 2 +- packages/next/src/build/swc/index.ts | 6 +- .../lib/router-utils/setup-dev-bundler.ts | 29 ++++---- pnpm-lock.yaml | 10 +-- test/development/basic/next-rs-api.test.ts | 21 +++++- 15 files changed, 197 insertions(+), 150 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d585caac1f7c1..da772eab006c2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -322,7 +322,7 @@ dependencies = [ [[package]] name = "auto-hash-map" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" dependencies = [ "serde", "smallvec", @@ -3549,7 +3549,7 @@ dependencies = [ [[package]] name = "node-file-trace" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" dependencies = [ "anyhow", "serde", @@ -7695,7 +7695,7 @@ dependencies = [ [[package]] name = "turbo-tasks" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" dependencies = [ "anyhow", "async-trait", @@ -7727,7 +7727,7 @@ dependencies = [ [[package]] name = "turbo-tasks-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" dependencies = [ "anyhow", "cargo-lock", @@ -7739,7 +7739,7 @@ dependencies = [ [[package]] name = "turbo-tasks-bytes" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" dependencies = [ "anyhow", "bytes", @@ -7754,7 +7754,7 @@ dependencies = [ [[package]] name = "turbo-tasks-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" dependencies = [ "anyhow", "dotenvs", @@ -7768,7 +7768,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fetch" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7785,7 +7785,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fs" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" dependencies = [ "anyhow", "auto-hash-map", @@ -7815,7 +7815,7 @@ dependencies = [ [[package]] name = "turbo-tasks-hash" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" dependencies = [ "base16", "hex", @@ -7827,7 +7827,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" dependencies = [ "anyhow", "convert_case 0.6.0", @@ -7841,7 +7841,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros-shared" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" dependencies = [ "proc-macro2", "quote", @@ -7851,7 +7851,7 @@ dependencies = [ [[package]] name = "turbo-tasks-malloc" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" dependencies = [ "mimalloc", ] @@ -7859,7 +7859,7 @@ dependencies = [ [[package]] name = "turbo-tasks-memory" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" dependencies = [ "anyhow", "auto-hash-map", @@ -7884,7 +7884,7 @@ dependencies = [ [[package]] name = "turbopack" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" dependencies = [ "anyhow", "async-recursion", @@ -7915,7 +7915,7 @@ dependencies = [ [[package]] name = "turbopack-binding" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" dependencies = [ "auto-hash-map", "mdxjs", @@ -7955,7 +7955,7 @@ dependencies = [ [[package]] name = "turbopack-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7978,7 +7978,7 @@ dependencies = [ [[package]] name = "turbopack-cli-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" dependencies = [ "anyhow", "clap 4.4.2", @@ -8002,7 +8002,7 @@ dependencies = [ [[package]] name = "turbopack-core" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" dependencies = [ "anyhow", "async-recursion", @@ -8032,7 +8032,7 @@ dependencies = [ [[package]] name = "turbopack-css" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" dependencies = [ "anyhow", "async-trait", @@ -8058,7 +8058,7 @@ dependencies = [ [[package]] name = "turbopack-dev" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -8082,7 +8082,7 @@ dependencies = [ [[package]] name = "turbopack-dev-server" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" dependencies = [ "anyhow", "async-compression", @@ -8119,7 +8119,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" dependencies = [ "anyhow", "async-trait", @@ -8153,7 +8153,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-hmr-protocol" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" dependencies = [ "serde", "serde_json", @@ -8164,7 +8164,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-plugins" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" dependencies = [ "anyhow", "async-trait", @@ -8187,7 +8187,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-runtime" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" dependencies = [ "anyhow", "indoc", @@ -8204,7 +8204,7 @@ dependencies = [ [[package]] name = "turbopack-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -8220,7 +8220,7 @@ dependencies = [ [[package]] name = "turbopack-image" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" dependencies = [ "anyhow", "base64 0.21.4", @@ -8240,7 +8240,7 @@ dependencies = [ [[package]] name = "turbopack-json" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" dependencies = [ "anyhow", "serde", @@ -8255,7 +8255,7 @@ dependencies = [ [[package]] name = "turbopack-mdx" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" dependencies = [ "anyhow", "mdxjs", @@ -8270,7 +8270,7 @@ dependencies = [ [[package]] name = "turbopack-node" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" dependencies = [ "anyhow", "async-stream", @@ -8305,7 +8305,7 @@ dependencies = [ [[package]] name = "turbopack-static" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" dependencies = [ "anyhow", "serde", @@ -8321,7 +8321,7 @@ dependencies = [ [[package]] name = "turbopack-swc-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" dependencies = [ "swc_core", "turbo-tasks", @@ -8332,7 +8332,7 @@ dependencies = [ [[package]] name = "turbopack-wasm" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231121.2#46a3854518d697f98747cc70f9a6395547549a2c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" dependencies = [ "anyhow", "indexmap 1.9.3", diff --git a/Cargo.toml b/Cargo.toml index 3e760d38c0d11..cf33d5921fd23 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,11 +43,11 @@ next-transform-strip-page-exports = { path = "packages/next-swc/crates/next-tran testing = { version = "0.35.10" } # Turbo crates -turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231121.2" } +turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231122.2" } # [TODO]: need to refactor embed_directory! macro usages, as well as resolving turbo_tasks::function, macros.. -turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231121.2" } +turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231122.2" } # [TODO]: need to refactor embed_directory! macro usage in next-core -turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231121.2" } +turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231122.2" } # General Deps diff --git a/packages/next-swc/crates/napi/src/next_api/utils.rs b/packages/next-swc/crates/napi/src/next_api/utils.rs index 3c09a28a4b97f..13ab019977fb7 100644 --- a/packages/next-swc/crates/napi/src/next_api/utils.rs +++ b/packages/next-swc/crates/napi/src/next_api/utils.rs @@ -100,9 +100,9 @@ pub struct NapiIssue { pub severity: String, pub category: String, pub file_path: String, - pub title: String, - pub description: serde_json::Value, - pub detail: String, + pub title: serde_json::Value, + pub description: Option, + pub detail: Option, pub source: Option, pub documentation_link: String, pub sub_issues: Vec, @@ -111,15 +111,20 @@ pub struct NapiIssue { impl From<&PlainIssue> for NapiIssue { fn from(issue: &PlainIssue) -> Self { Self { - description: serde_json::to_value(Into::::into(&issue.description)) - .unwrap(), + description: issue + .description + .as_ref() + .map(|styled| serde_json::to_value(StyledStringSerialize::from(styled)).unwrap()), category: issue.category.clone(), file_path: issue.file_path.clone(), - detail: issue.detail.clone(), + detail: issue + .detail + .as_ref() + .map(|styled| serde_json::to_value(StyledStringSerialize::from(styled)).unwrap()), documentation_link: issue.documentation_link.clone(), severity: issue.severity.as_str().to_string(), source: issue.source.as_deref().map(|source| source.into()), - title: issue.title.clone(), + title: serde_json::to_value(StyledStringSerialize::from(&issue.title)).unwrap(), sub_issues: issue .sub_issues .iter() @@ -131,32 +136,36 @@ impl From<&PlainIssue> for NapiIssue { #[derive(Serialize)] #[serde(tag = "type", rename_all = "camelCase")] -pub enum NapiStyledString { - Line { value: Vec }, - Stack { value: Vec }, - Text { value: String }, - Code { value: String }, - Strong { value: String }, +pub enum StyledStringSerialize<'a> { + Line { + value: Vec>, + }, + Stack { + value: Vec>, + }, + Text { + value: &'a str, + }, + Code { + value: &'a str, + }, + Strong { + value: &'a str, + }, } -impl From<&StyledString> for NapiStyledString { - fn from(value: &StyledString) -> Self { +impl<'a> From<&'a StyledString> for StyledStringSerialize<'a> { + fn from(value: &'a StyledString) -> Self { match value { - StyledString::Line(parts) => NapiStyledString::Line { + StyledString::Line(parts) => StyledStringSerialize::Line { value: parts.iter().map(|p| p.into()).collect(), }, - StyledString::Stack(parts) => NapiStyledString::Stack { + StyledString::Stack(parts) => StyledStringSerialize::Stack { value: parts.iter().map(|p| p.into()).collect(), }, - StyledString::Text(string) => NapiStyledString::Text { - value: string.clone(), - }, - StyledString::Code(string) => NapiStyledString::Code { - value: string.clone(), - }, - StyledString::Strong(string) => NapiStyledString::Strong { - value: string.clone(), - }, + StyledString::Text(string) => StyledStringSerialize::Text { value: string }, + StyledString::Code(string) => StyledStringSerialize::Code { value: string }, + StyledString::Strong(string) => StyledStringSerialize::Strong { value: string }, } } } diff --git a/packages/next-swc/crates/next-core/src/app_segment_config.rs b/packages/next-swc/crates/next-core/src/app_segment_config.rs index 6804322075400..335f724eba630 100644 --- a/packages/next-swc/crates/next-core/src/app_segment_config.rs +++ b/packages/next-swc/crates/next-core/src/app_segment_config.rs @@ -13,7 +13,10 @@ use turbopack_binding::turbopack::{ core::{ file_source::FileSource, ident::AssetIdent, - issue::{Issue, IssueExt, IssueSeverity, IssueSource, OptionIssueSource, StyledString}, + issue::{ + Issue, IssueExt, IssueSeverity, IssueSource, OptionIssueSource, OptionStyledString, + StyledString, + }, source::Source, }, ecmascript::{ @@ -151,7 +154,7 @@ impl NextSegmentConfig { #[turbo_tasks::value(shared)] pub struct NextSegmentConfigParsingIssue { ident: Vc, - detail: Vc, + detail: Vc, source: Vc, } @@ -163,8 +166,8 @@ impl Issue for NextSegmentConfigParsingIssue { } #[turbo_tasks::function] - fn title(&self) -> Vc { - Vc::cell("Unable to parse config export in source file".to_string()) + fn title(&self) -> Vc { + StyledString::Text("Unable to parse config export in source file".to_string()).cell() } #[turbo_tasks::function] @@ -178,18 +181,20 @@ impl Issue for NextSegmentConfigParsingIssue { } #[turbo_tasks::function] - fn description(&self) -> Vc { - StyledString::Text( - "The exported configuration object in a source file need to have a very specific \ - format from which some properties can be statically parsed at compiled-time." - .to_string(), - ) - .cell() + fn description(&self) -> Vc { + Vc::cell(Some( + StyledString::Text( + "The exported configuration object in a source file need to have a very specific \ + format from which some properties can be statically parsed at compiled-time." + .to_string(), + ) + .cell(), + )) } #[turbo_tasks::function] - fn detail(&self) -> Vc { - self.detail + fn detail(&self) -> Vc { + Vc::cell(Some(self.detail)) } #[turbo_tasks::function] @@ -285,7 +290,7 @@ fn parse_config_value( let (explainer, hints) = value.explain(2, 0); NextSegmentConfigParsingIssue { ident: source.ident(), - detail: Vc::cell(format!("{detail} Got {explainer}.{hints}")), + detail: StyledString::Text(format!("{detail} Got {explainer}.{hints}")).cell(), source: issue_source(source, span), } .cell() diff --git a/packages/next-swc/crates/next-core/src/app_structure.rs b/packages/next-swc/crates/next-core/src/app_structure.rs index 14dca4fe8dc59..3ff195b687a9a 100644 --- a/packages/next-swc/crates/next-core/src/app_structure.rs +++ b/packages/next-swc/crates/next-core/src/app_structure.rs @@ -13,7 +13,7 @@ use turbo_tasks::{ }; use turbopack_binding::{ turbo::tasks_fs::{DirectoryContent, DirectoryEntry, FileSystemEntryType, FileSystemPath}, - turbopack::core::issue::{Issue, IssueExt, IssueSeverity, StyledString}, + turbopack::core::issue::{Issue, IssueExt, IssueSeverity, OptionStyledString, StyledString}, }; use crate::{ @@ -1140,10 +1140,11 @@ impl Issue for DirectoryTreeIssue { } #[turbo_tasks::function] - async fn title(&self) -> Result> { - Ok(Vc::cell( - "An issue occurred while preparing your Next.js app".to_string(), - )) + async fn title(&self) -> Result> { + Ok( + StyledString::Text("An issue occurred while preparing your Next.js app".to_string()) + .cell(), + ) } #[turbo_tasks::function] @@ -1157,7 +1158,7 @@ impl Issue for DirectoryTreeIssue { } #[turbo_tasks::function] - fn description(&self) -> Vc { - self.message + fn description(&self) -> Vc { + Vc::cell(Some(self.message)) } } diff --git a/packages/next-swc/crates/next-core/src/babel.rs b/packages/next-swc/crates/next-core/src/babel.rs index c2cf946391e00..849bde5cd2593 100644 --- a/packages/next-swc/crates/next-core/src/babel.rs +++ b/packages/next-swc/crates/next-core/src/babel.rs @@ -4,7 +4,7 @@ use turbopack_binding::{ turbo::tasks_fs::{FileSystemEntryType, FileSystemPath}, turbopack::{ core::{ - issue::{Issue, IssueExt, IssueSeverity, StyledString}, + issue::{Issue, IssueExt, IssueSeverity, OptionStyledString, StyledString}, reference_type::{CommonJsReferenceSubType, ReferenceType}, resolve::{parse::Request, pattern::Pattern, resolve}, }, @@ -74,10 +74,11 @@ pub async fn maybe_add_babel_loader( { BabelIssue { path: project_root, - title: Vc::cell( + title: StyledString::Text( "Unable to resolve babel-loader, but a babel config is present" .to_owned(), - ), + ) + .cell(), description: StyledString::Text( "Make sure babel-loader is installed via your package manager." .to_owned(), @@ -145,7 +146,7 @@ pub async fn is_babel_loader_available(project_path: Vc) -> Resu #[turbo_tasks::value] struct BabelIssue { path: Vc, - title: Vc, + title: Vc, description: Vc, severity: Vc, } @@ -168,12 +169,12 @@ impl Issue for BabelIssue { } #[turbo_tasks::function] - fn title(&self) -> Vc { + fn title(&self) -> Vc { self.title } #[turbo_tasks::function] - fn description(&self) -> Vc { - self.description + fn description(&self) -> Vc { + Vc::cell(Some(self.description)) } } diff --git a/packages/next-swc/crates/next-core/src/next_config.rs b/packages/next-swc/crates/next-core/src/next_config.rs index c156ce10660de..9c012d17bb6ef 100644 --- a/packages/next-swc/crates/next-core/src/next_config.rs +++ b/packages/next-swc/crates/next-core/src/next_config.rs @@ -12,7 +12,10 @@ use turbopack_binding::{ context::AssetContext, file_source::FileSource, ident::AssetIdent, - issue::{Issue, IssueDescriptionExt, IssueExt, IssueSeverity, StyledString}, + issue::{ + Issue, IssueDescriptionExt, IssueExt, IssueSeverity, OptionStyledString, + StyledString, + }, reference_type::{EntryReferenceSubType, InnerAssets, ReferenceType}, resolve::{ find_context_file, @@ -983,15 +986,19 @@ impl Issue for OutdatedConfigIssue { } #[turbo_tasks::function] - fn title(&self) -> Vc { - Vc::cell(format!( - "\"{}\" has been replaced by \"{}\"", - self.old_name, self.new_name - )) + fn title(&self) -> Vc { + StyledString::Line(vec![ + StyledString::Code(self.old_name.clone()), + StyledString::Text(" has been replaced by ".to_string()), + StyledString::Code(self.new_name.clone()), + ]) + .cell() } #[turbo_tasks::function] - fn description(&self) -> Vc { - StyledString::Text(self.description.to_string()).cell() + fn description(&self) -> Vc { + Vc::cell(Some( + StyledString::Text(self.description.to_string()).cell(), + )) } } diff --git a/packages/next-swc/crates/next-core/src/next_font/google/font_fallback.rs b/packages/next-swc/crates/next-core/src/next_font/google/font_fallback.rs index 171c353b724fa..b45790cce78ab 100644 --- a/packages/next-swc/crates/next-core/src/next_font/google/font_fallback.rs +++ b/packages/next-swc/crates/next-core/src/next_font/google/font_fallback.rs @@ -82,10 +82,11 @@ pub(super) async fn get_font_fallback( Err(_) => { NextFontIssue { path: context, - title: Vc::cell(format!( + title: StyledString::Text(format!( "Failed to find font override values for font `{}`", &options.font_family, - )), + )) + .cell(), description: StyledString::Text( "Skipping generating a fallback font.".to_owned(), ) diff --git a/packages/next-swc/crates/next-core/src/next_font/issue.rs b/packages/next-swc/crates/next-core/src/next_font/issue.rs index 44c021b4c2632..7f0fd762ef208 100644 --- a/packages/next-swc/crates/next-core/src/next_font/issue.rs +++ b/packages/next-swc/crates/next-core/src/next_font/issue.rs @@ -1,13 +1,13 @@ use turbo_tasks::Vc; use turbopack_binding::{ turbo::tasks_fs::FileSystemPath, - turbopack::core::issue::{Issue, IssueSeverity, StyledString}, + turbopack::core::issue::{Issue, IssueSeverity, OptionStyledString, StyledString}, }; #[turbo_tasks::value(shared)] pub(crate) struct NextFontIssue { pub(crate) path: Vc, - pub(crate) title: Vc, + pub(crate) title: Vc, pub(crate) description: Vc, pub(crate) severity: Vc, } @@ -30,12 +30,12 @@ impl Issue for NextFontIssue { } #[turbo_tasks::function] - fn title(&self) -> Vc { + fn title(&self) -> Vc { self.title } #[turbo_tasks::function] - fn description(&self) -> Vc { - self.description + fn description(&self) -> Vc { + Vc::cell(Some(self.description)) } } diff --git a/packages/next-swc/crates/next-core/src/util.rs b/packages/next-swc/crates/next-core/src/util.rs index 381f78a1ce718..d20658aaf80f8 100644 --- a/packages/next-swc/crates/next-core/src/util.rs +++ b/packages/next-swc/crates/next-core/src/util.rs @@ -12,7 +12,7 @@ use turbopack_binding::{ asset::AssetContent, environment::{ServerAddr, ServerInfo}, ident::AssetIdent, - issue::{Issue, IssueExt, IssueSeverity, StyledString}, + issue::{Issue, IssueExt, IssueSeverity, OptionStyledString, StyledString}, module::Module, source::Source, virtual_source::VirtualSource, @@ -165,7 +165,7 @@ impl ValueDefault for NextSourceConfig { #[turbo_tasks::value(shared)] pub struct NextSourceConfigParsingIssue { ident: Vc, - detail: Vc, + detail: Vc, } #[turbo_tasks::value_impl] @@ -176,8 +176,8 @@ impl Issue for NextSourceConfigParsingIssue { } #[turbo_tasks::function] - fn title(&self) -> Vc { - Vc::cell("Unable to parse config export in source file".to_string()) + fn title(&self) -> Vc { + StyledString::Text("Unable to parse config export in source file".to_string()).cell() } #[turbo_tasks::function] @@ -191,18 +191,20 @@ impl Issue for NextSourceConfigParsingIssue { } #[turbo_tasks::function] - fn description(&self) -> Vc { - StyledString::Text( - "The exported configuration object in a source file need to have a very specific \ - format from which some properties can be statically parsed at compiled-time." - .to_string(), - ) - .cell() + fn description(&self) -> Vc { + Vc::cell(Some( + StyledString::Text( + "The exported configuration object in a source file need to have a very specific \ + format from which some properties can be statically parsed at compiled-time." + .to_string(), + ) + .cell(), + )) } #[turbo_tasks::function] - fn detail(&self) -> Vc { - self.detail + fn detail(&self) -> Vc { + Vc::cell(Some(self.detail)) } } @@ -238,11 +240,12 @@ pub async fn parse_config_from_source(module: Vc>) -> Result>) -> Result>) -> Result>, value: &JsValue) -> N let (explainer, hints) = value.explain(2, 0); NextSourceConfigParsingIssue { ident: module.ident(), - detail: Vc::cell(format!("{detail} Got {explainer}.{hints}")), + detail: StyledString::Text(format!("{detail} Got {explainer}.{hints}")).cell(), } .cell() .emit() diff --git a/packages/next/package.json b/packages/next/package.json index c1876e2481066..518b85a4c064d 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -193,7 +193,7 @@ "@types/ws": "8.2.0", "@vercel/ncc": "0.34.0", "@vercel/nft": "0.22.6", - "@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231121.2", + "@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231122.2", "acorn": "8.5.0", "amphtml-validator": "1.0.35", "anser": "1.4.9", diff --git a/packages/next/src/build/swc/index.ts b/packages/next/src/build/swc/index.ts index ec11391b36490..225a0e9a4107c 100644 --- a/packages/next/src/build/swc/index.ts +++ b/packages/next/src/build/swc/index.ts @@ -499,9 +499,9 @@ export interface Issue { severity: string category: string filePath: string - title: string - description: StyledString - detail: string + title: StyledString + description?: StyledString + detail?: StyledString source?: { source: { ident: string diff --git a/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts b/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts index 1155a2c6eede3..d2a5176230518 100644 --- a/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts +++ b/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts @@ -291,7 +291,10 @@ async function startWatcher(opts: SetupOpts) { function formatIssue(issue: Issue) { const { filePath, title, description, source, detail } = issue - let formattedTitle = title.replace(/\n/g, '\n ') + let formattedTitle = renderStyledStringToErrorAnsi(title).replace( + /\n/g, + '\n ' + ) let formattedFilePath = filePath .replace('[project]/', '') @@ -341,7 +344,10 @@ async function startWatcher(opts: SetupOpts) { } if (detail) { - message += `\n${detail.replace(/\n/g, '\n ')}` + message += `\n${renderStyledStringToErrorAnsi(detail).replace( + /\n/g, + '\n ' + )}` } return message @@ -502,7 +508,9 @@ async function startWatcher(opts: SetupOpts) { errors.set(key, { message, - details: issue.detail, + details: issue.detail + ? renderStyledStringToErrorAnsi(issue.detail) + : undefined, }) } } @@ -2518,19 +2526,10 @@ function renderStyledStringToErrorAnsi(string: StyledString): string { return bold(red(string.value)) case 'code': return green(string.value) - case 'line': { - let line = '' - for (const styled of string.value) { - line += renderStyledStringToErrorAnsi(styled) - } - return line + '\n' - } + case 'line': + return string.value.map(renderStyledStringToErrorAnsi).join('') case 'stack': - let stack = '' - for (const styled of string.value) { - stack += renderStyledStringToErrorAnsi(styled) + '\n' - } - return stack + '\n' + return string.value.map(renderStyledStringToErrorAnsi).join('\n') default: throw new Error('Unknown StyledString type', string) } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 93bac11312c32..6433a3c6a1e64 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1065,8 +1065,8 @@ importers: specifier: 0.22.6 version: 0.22.6 '@vercel/turbopack-ecmascript-runtime': - specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231121.2 - version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231121.2(react-refresh@0.12.0)(webpack@5.86.0)' + specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231122.2 + version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231122.2(react-refresh@0.12.0)(webpack@5.86.0)' acorn: specifier: 8.5.0 version: 8.5.0 @@ -24646,9 +24646,9 @@ packages: /zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} - '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231121.2(react-refresh@0.12.0)(webpack@5.86.0)': - resolution: {registry: https://registry.npmjs.org/, tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231121.2} - id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231121.2' + '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231122.2(react-refresh@0.12.0)(webpack@5.86.0)': + resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231122.2} + id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231122.2' name: '@vercel/turbopack-ecmascript-runtime' version: 0.0.0 dependencies: diff --git a/test/development/basic/next-rs-api.test.ts b/test/development/basic/next-rs-api.test.ts index b5648106c6afb..c24ab30b122ce 100644 --- a/test/development/basic/next-rs-api.test.ts +++ b/test/development/basic/next-rs-api.test.ts @@ -8,6 +8,7 @@ import { Issue, loadBindings, Project, + StyledString, TurbopackResult, UpdateInfo, } from 'next/src/build/swc' @@ -23,11 +24,29 @@ function normalizePath(path: string) { ) } +function styledStringToMarkdown(styled: StyledString): string { + switch (styled.type) { + case 'text': + return styled.value + case 'strong': + return '**' + styled.value + '**' + case 'code': + return '`' + styled.value + '`' + case 'line': + return styled.value.map(styledStringToMarkdown).join('') + case 'stack': + return styled.value.map(styledStringToMarkdown).join('\n') + default: + throw new Error('Unknown StyledString type', styled) + } +} + function normalizeIssues(issues: Issue[]) { return issues .map((issue) => ({ ...issue, - detail: issue.detail && normalizePath(issue.detail), + detail: + issue.detail && normalizePath(styledStringToMarkdown(issue.detail)), filePath: issue.filePath && normalizePath(issue.filePath), source: issue.source && { ...issue.source, From 8f9e494cb502de9b77da78f17994baf7ec278ad3 Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Wed, 22 Nov 2023 12:48:53 +0000 Subject: [PATCH 015/481] v14.0.4-canary.10 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 18 +++++++++--------- 18 files changed, 34 insertions(+), 34 deletions(-) diff --git a/lerna.json b/lerna.json index b326078caf02d..13fbd5596520c 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.9" + "version": "14.0.4-canary.10" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 57f6aac0ae385..9fb002b56326c 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.9", + "version": "14.0.4-canary.10", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 1e08f097e36c1..4c9271347baa2 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.9", + "version": "14.0.4-canary.10", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.9", + "@next/eslint-plugin-next": "14.0.4-canary.10", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index be3f1ecb2e0c6..85364fb81f66e 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.9", + "version": "14.0.4-canary.10", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index f9e4702cd825c..96adb981f1b31 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.9", + "version": "14.0.4-canary.10", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 5b2084ed8d265..14c53e7988f5c 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.9", + "version": "14.0.4-canary.10", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 7819967b8a624..8f36226e87946 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.9", + "version": "14.0.4-canary.10", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 2679d6ba9c20f..73ec7b1d64de8 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.9", + "version": "14.0.4-canary.10", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index f0cd8c4e0814f..36a0da3351b06 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.9", + "version": "14.0.4-canary.10", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 78f7492f033d0..02ccab17c4377 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.9", + "version": "14.0.4-canary.10", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index 398f065d8791b..a9d2e17c50bcd 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.9", + "version": "14.0.4-canary.10", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index 4e068e3d7c4d4..371be1d840051 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.9", + "version": "14.0.4-canary.10", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index 36c3663fbaf59..5db5fd3dd4f52 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.9", + "version": "14.0.4-canary.10", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index 518b85a4c064d..6fcee8ec1bad6 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.9", + "version": "14.0.4-canary.10", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.9", + "@next/env": "14.0.4-canary.10", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -146,11 +146,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.9", - "@next/polyfill-nomodule": "14.0.4-canary.9", - "@next/react-dev-overlay": "14.0.4-canary.9", - "@next/react-refresh-utils": "14.0.4-canary.9", - "@next/swc": "14.0.4-canary.9", + "@next/polyfill-module": "14.0.4-canary.10", + "@next/polyfill-nomodule": "14.0.4-canary.10", + "@next/react-dev-overlay": "14.0.4-canary.10", + "@next/react-refresh-utils": "14.0.4-canary.10", + "@next/swc": "14.0.4-canary.10", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index cd6781ce6a80f..585a658b54667 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.9", + "version": "14.0.4-canary.10", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index a3c6fc50b1870..5c4c494f370f8 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.9", + "version": "14.0.4-canary.10", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index ece8e0937dc1d..efeff028925ee 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.9", + "version": "14.0.4-canary.10", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -23,7 +23,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.9", + "next": "14.0.4-canary.10", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6433a3c6a1e64..95aa246bb4ef3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -735,7 +735,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.9 + specifier: 14.0.4-canary.10 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -800,7 +800,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.9 + specifier: 14.0.4-canary.10 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -924,19 +924,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.9 + specifier: 14.0.4-canary.10 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.9 + specifier: 14.0.4-canary.10 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.9 + specifier: 14.0.4-canary.10 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.9 + specifier: 14.0.4-canary.10 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.9 + specifier: 14.0.4-canary.10 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1587,7 +1587,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.9 + specifier: 14.0.4-canary.10 version: link:../next outdent: specifier: 0.8.0 @@ -24647,7 +24647,7 @@ packages: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231122.2(react-refresh@0.12.0)(webpack@5.86.0)': - resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231122.2} + resolution: {registry: https://registry.npmjs.org/, tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231122.2} id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231122.2' name: '@vercel/turbopack-ecmascript-runtime' version: 0.0.0 From 8baf2e0b79fcac8cd07c616b3308f2af77fa59ab Mon Sep 17 00:00:00 2001 From: Jimmy Lai Date: Wed, 22 Nov 2023 15:29:01 +0100 Subject: [PATCH 016/481] route handlers: make req.cookies opt you into dynamic (#58769) This PR fixes an issue where users would try to access `req.cookies` from a route handler and be unable to read from it. This issue was caused by `req.cookies` not opting you into dynamic behaviour, unlike `cookies()` from `next/headers`. This fixes it. --- .../app-route/helpers/proxy-request.ts | 1 + .../app-dir/app-routes/app-custom-routes.test.ts | 13 +++++++++++++ .../app-routes/app/hooks/cookies/req/route.ts | 12 ++++++++++++ 3 files changed, 26 insertions(+) create mode 100644 test/e2e/app-dir/app-routes/app/hooks/cookies/req/route.ts diff --git a/packages/next/src/server/future/route-modules/app-route/helpers/proxy-request.ts b/packages/next/src/server/future/route-modules/app-route/helpers/proxy-request.ts index 695b14e5a6cb3..cd58e253a6a98 100644 --- a/packages/next/src/server/future/route-modules/app-route/helpers/proxy-request.ts +++ b/packages/next/src/server/future/route-modules/app-route/helpers/proxy-request.ts @@ -107,6 +107,7 @@ export function proxyRequest( // request.nextUrl we bail since it includes query // values that can be relied on dynamically case 'url': + case 'cookies': case 'body': case 'blob': case 'json': diff --git a/test/e2e/app-dir/app-routes/app-custom-routes.test.ts b/test/e2e/app-dir/app-routes/app-custom-routes.test.ts index f624d635fbbf2..04867a9e4ad7f 100644 --- a/test/e2e/app-dir/app-routes/app-custom-routes.test.ts +++ b/test/e2e/app-dir/app-routes/app-custom-routes.test.ts @@ -423,6 +423,19 @@ createNextDescribe( }) }) + describe('req.cookies', () => { + it('gets the correct values', async () => { + const res = await next.fetch(basePath + '/hooks/cookies/req', { + headers: cookieWithRequestMeta({ ping: 'pong' }), + }) + + expect(res.status).toEqual(200) + + const meta = getRequestMeta(res.headers) + expect(meta.ping).toEqual('pong') + }) + }) + describe('cookies().has()', () => { it('gets the correct values', async () => { const res = await next.fetch(basePath + '/hooks/cookies/has') diff --git a/test/e2e/app-dir/app-routes/app/hooks/cookies/req/route.ts b/test/e2e/app-dir/app-routes/app/hooks/cookies/req/route.ts new file mode 100644 index 0000000000000..0399af342552c --- /dev/null +++ b/test/e2e/app-dir/app-routes/app/hooks/cookies/req/route.ts @@ -0,0 +1,12 @@ +import { getRequestMeta, withRequestMeta } from '../../../../helpers' +import { NextRequest } from 'next/server' + +export async function GET(req: NextRequest) { + // Put the request meta in the response directly as meta again. + const meta = getRequestMeta(req.cookies) + + return new Response(null, { + status: 200, + headers: withRequestMeta(meta), + }) +} From 98f7994ce8d7688f7b588329a8e377cd9b56ae30 Mon Sep 17 00:00:00 2001 From: Dima Voytenko Date: Wed, 22 Nov 2023 09:52:15 -0800 Subject: [PATCH 017/481] OpenTelemetry: a more reliable way to establish a root context (#58662) It's too easy to change the root context and thus the `context.active() === ROOT_CONTEXT` it's not a reliable way to check whether the current context is a root. A much more predictable option is to see if there's actually an active tracing span already defined. Co-authored-by: Tim Neutkens Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- packages/next/src/server/lib/trace/tracer.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/next/src/server/lib/trace/tracer.ts b/packages/next/src/server/lib/trace/tracer.ts index 5307aa93ecdbc..150db18b86602 100644 --- a/packages/next/src/server/lib/trace/tracer.ts +++ b/packages/next/src/server/lib/trace/tracer.ts @@ -174,10 +174,12 @@ class NextTracerImpl implements NextTracer { } public withPropagatedContext(req: BaseNextRequest, fn: () => T): T { - if (context.active() !== ROOT_CONTEXT) { + const activeContext = context.active() + if (trace.getSpanContext(activeContext)) { + // Active span is already set, too late to propagate. return fn() } - const remoteContext = propagation.extract(ROOT_CONTEXT, req.headers) + const remoteContext = propagation.extract(activeContext, req.headers) return context.with(remoteContext, fn) } From bb3d5cf4c3f3ecf575f2a6dbab3bb3665e8ac4a8 Mon Sep 17 00:00:00 2001 From: Leah Date: Wed, 22 Nov 2023 19:30:26 +0100 Subject: [PATCH 018/481] fix(turbopack): `e2e/404-page-router` test (#58146) --- test/e2e/404-page-router/app/next.config.js | 5 +---- test/e2e/404-page-router/index.test.ts | 25 ++++++++++++--------- test/turbopack-tests-manifest.json | 4 ++-- 3 files changed, 18 insertions(+), 16 deletions(-) diff --git a/test/e2e/404-page-router/app/next.config.js b/test/e2e/404-page-router/app/next.config.js index 7e80bb10470c7..4ba52ba2c8df6 100644 --- a/test/e2e/404-page-router/app/next.config.js +++ b/test/e2e/404-page-router/app/next.config.js @@ -1,4 +1 @@ -module.exports = { - _basePath: '/docs', - _i18n: { defaultLocale: 'en-ca', locales: ['en-ca', 'en-fr'] }, -} +module.exports = {} diff --git a/test/e2e/404-page-router/index.test.ts b/test/e2e/404-page-router/index.test.ts index bcffd89f3de70..b94bd1e26035a 100644 --- a/test/e2e/404-page-router/index.test.ts +++ b/test/e2e/404-page-router/index.test.ts @@ -29,6 +29,13 @@ const table = [ ]), ] +const baseNextConfig = ` +module.exports = { + BASE_PATH + I18N +} +` + describe('404-page-router', () => { let next: NextInstance @@ -64,18 +71,16 @@ describe('404-page-router', () => { ) ) } - let curNextConfig = await fs.readFile( - path.join(__dirname, 'app', 'next.config.js'), - 'utf8' - ) - if (options.basePath) { - curNextConfig = curNextConfig.replace('_basePath', 'basePath') - } + let curNextConfig = baseNextConfig + .replace('BASE_PATH', options.basePath ? "basePath: '/docs'," : '') + .replace( + 'I18N', + options.i18n + ? "i18n: { defaultLocale: 'en-ca', locales: ['en-ca', 'en-fr'] }," + : '' + ) - if (options.i18n) { - curNextConfig = curNextConfig.replace('_i18n', 'i18n') - } await next.patchFile('next.config.js', curNextConfig) await next.start() }) diff --git a/test/turbopack-tests-manifest.json b/test/turbopack-tests-manifest.json index 8dc5baa3cd9ea..352c2623a12e2 100644 --- a/test/turbopack-tests-manifest.json +++ b/test/turbopack-tests-manifest.json @@ -2113,8 +2113,7 @@ "runtimeError": false }, "test/e2e/404-page-router/index.test.ts": { - "passed": [], - "failed": [ + "passed": [ "404-page-router 404-page-router with basePath of false and i18n of false and middleware false for /not/a/real/page should have the correct router parameters after it is ready", "404-page-router 404-page-router with basePath of false and i18n of false and middleware false for /not/a/real/page?with=query should have the correct router parameters after it is ready", "404-page-router 404-page-router with basePath of false and i18n of false and middleware false should not throw any errors when re-fetching the route info", @@ -2128,6 +2127,7 @@ "404-page-router 404-page-router with basePath of true and i18n of true and middleware false for /not/a/real/page?with=query should have the correct router parameters after it is ready", "404-page-router 404-page-router with basePath of true and i18n of true and middleware false should not throw any errors when re-fetching the route info" ], + "failed": [], "pending": [], "flakey": [], "runtimeError": true From d9531c13c4d1864b873df4ae911fb54c00fccccb Mon Sep 17 00:00:00 2001 From: Zack Tanner Date: Wed, 22 Nov 2023 10:49:20 -0800 Subject: [PATCH 019/481] Revert "fix: fetch() behavior when "dynamic" is "force-dynamic" (#58735) Reverts vercel/next.js#58484 The correct way to address this is to use the `fetchCache` segment: https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#fetchcache There are valid use-cases to want to force a dynamic response but still need fetch caching. Additionally, this PR updates the docs, since they're incorrect about behavior. [slack x-ref](https://vercel.slack.com/archives/C042LHPJ1NX/p1691623048477119?thread_ts=1691613915.257239&cid=C042LHPJ1NX) --- .../route-segment-config.mdx | 6 +----- packages/next/src/server/lib/patch-fetch.ts | 3 +-- .../e2e/app-dir/app-static/app-static.test.ts | 21 ------------------- .../force-dynamic-no-with-revalidate/page.tsx | 21 ------------------- .../app/stale-cache-serving/app-page/page.tsx | 2 +- .../route-handler/route.ts | 2 +- 6 files changed, 4 insertions(+), 51 deletions(-) delete mode 100644 test/e2e/app-dir/app-static/app/force-dynamic-no-with-revalidate/page.tsx diff --git a/docs/02-app/02-api-reference/02-file-conventions/route-segment-config.mdx b/docs/02-app/02-api-reference/02-file-conventions/route-segment-config.mdx index caffddbf4d3fc..18a546c5c104b 100644 --- a/docs/02-app/02-api-reference/02-file-conventions/route-segment-config.mdx +++ b/docs/02-app/02-api-reference/02-file-conventions/route-segment-config.mdx @@ -62,11 +62,7 @@ export const dynamic = 'auto' > **Good to know**: The new model in the `app` directory favors granular caching control at the `fetch` request level over the binary all-or-nothing model of `getServerSideProps` and `getStaticProps` at the page-level in the `pages` directory. The `dynamic` option is a way to opt back in to the previous model as a convenience and provides a simpler migration path. - **`'auto'`** (default): The default option to cache as much as possible without preventing any components from opting into dynamic behavior. -- **`'force-dynamic'`**: Force dynamic rendering and uncached data fetching of a layout or page by disabling all caching of `fetch` requests and always revalidating. This option is equivalent to: - - - `getServerSideProps()` in the `pages` directory. - - Setting the option of every `fetch()` request in a layout or page to `{ cache: 'no-store', next: { revalidate: 0 } }`. - - Setting the segment config to `export const fetchCache = 'force-no-store'` +- **`'force-dynamic'`**: Force [dynamic rendering](/docs/app/building-your-application/rendering/server-components#dynamic-rendering), which will result in routes being rendered for each user at request time. This option is equivalent to `getServerSideProps()` in the `pages` directory. - **`'error'`**: Force static rendering and cache the data of a layout or page by causing an error if any components use [dynamic functions](/docs/app/building-your-application/rendering/server-components#server-rendering-strategies#dynamic-functions) or uncached data. This option is equivalent to: - `getStaticProps()` in the `pages` directory. diff --git a/packages/next/src/server/lib/patch-fetch.ts b/packages/next/src/server/lib/patch-fetch.ts index 401bab5605164..4a831e9788151 100644 --- a/packages/next/src/server/lib/patch-fetch.ts +++ b/packages/next/src/server/lib/patch-fetch.ts @@ -257,8 +257,7 @@ export function patchFetch({ const isOnlyNoStore = staticGenerationStore.fetchCache === 'only-no-store' const isForceNoStore = - staticGenerationStore.fetchCache === 'force-no-store' || - staticGenerationStore.forceDynamic + staticGenerationStore.fetchCache === 'force-no-store' let _cache = getRequestMeta('cache') let cacheReason = '' diff --git a/test/e2e/app-dir/app-static/app-static.test.ts b/test/e2e/app-dir/app-static/app-static.test.ts index 68b8ce979ab4c..6ab4bf5267757 100644 --- a/test/e2e/app-dir/app-static/app-static.test.ts +++ b/test/e2e/app-dir/app-static/app-static.test.ts @@ -598,7 +598,6 @@ createNextDescribe( 'variable-revalidate/post-method/page.js', 'variable-revalidate/status-code/page.js', 'dynamic-no-gen-params-ssr/[slug]/page.js', - 'force-dynamic-no-with-revalidate/page.js', 'hooks/use-search-params/force-static.rsc', 'partial-gen-params/[lang]/[slug]/page.js', 'variable-revalidate/headers-instance.rsc', @@ -632,7 +631,6 @@ createNextDescribe( 'variable-revalidate/headers-instance/page.js', // 'variable-revalidate/status-code.prefetch.rsc', 'force-cache/page_client-reference-manifest.js', - // 'force-dynamic-no-with-revalidate.prefetch.rsc', 'hooks/use-search-params/with-suspense/page.js', 'variable-revalidate-edge/revalidate-3/page.js', '(new)/custom/page_client-reference-manifest.js', @@ -704,7 +702,6 @@ createNextDescribe( 'variable-revalidate/post-method/page_client-reference-manifest.js', 'variable-revalidate/status-code/page_client-reference-manifest.js', 'dynamic-no-gen-params-ssr/[slug]/page_client-reference-manifest.js', - 'force-dynamic-no-with-revalidate/page_client-reference-manifest.js', 'partial-gen-params/[lang]/[slug]/page_client-reference-manifest.js', 'variable-revalidate/revalidate-3/page_client-reference-manifest.js', 'stale-cache-serving-edge/app-page/page_client-reference-manifest.js', @@ -2532,24 +2529,6 @@ createNextDescribe( } }) - it('should force no store with force-dynamic', async () => { - const res = await next.fetch('/force-dynamic-no-with-revalidate') - const html = await res.text() - expect(res.status).toBe(200) - const initData = cheerio.load(html)('#data').text() - - await check(async () => { - const res2 = await next.fetch('/force-dynamic-no-with-revalidate') - - expect(res2.status).toBe(200) - - const $ = cheerio.load(await res2.text()) - expect($('#data').text()).toBeTruthy() - expect($('#data').text()).not.toBe(initData) - return 'success' - }, 'success') - }) - it('should not error with generateStaticParams and dynamic data', async () => { const res = await next.fetch('/gen-params-dynamic/one') const html = await res.text() diff --git a/test/e2e/app-dir/app-static/app/force-dynamic-no-with-revalidate/page.tsx b/test/e2e/app-dir/app-static/app/force-dynamic-no-with-revalidate/page.tsx deleted file mode 100644 index 6fbf2088bb342..0000000000000 --- a/test/e2e/app-dir/app-static/app/force-dynamic-no-with-revalidate/page.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import React from 'react' - -export const dynamic = 'force-dynamic' - -export default async function Page() { - const data = await fetch( - 'https://next-data-api-endpoint.vercel.app/api/random', - { - next: { - revalidate: 100, - }, - } - ).then((res) => res.text()) - - return ( - <> -

/force-dynamic-no-with-revalidate

-

{data}

- - ) -} diff --git a/test/e2e/app-dir/app-static/app/stale-cache-serving/app-page/page.tsx b/test/e2e/app-dir/app-static/app/stale-cache-serving/app-page/page.tsx index 44163265365b2..cd4451c7034ed 100644 --- a/test/e2e/app-dir/app-static/app/stale-cache-serving/app-page/page.tsx +++ b/test/e2e/app-dir/app-static/app/stale-cache-serving/app-page/page.tsx @@ -1,4 +1,4 @@ -export const revalidate = 0 +export const dynamic = 'force-dynamic' const delay = 3000 diff --git a/test/e2e/app-dir/app-static/app/stale-cache-serving/route-handler/route.ts b/test/e2e/app-dir/app-static/app/stale-cache-serving/route-handler/route.ts index ba280534db054..9ae5d9325be9a 100644 --- a/test/e2e/app-dir/app-static/app/stale-cache-serving/route-handler/route.ts +++ b/test/e2e/app-dir/app-static/app/stale-cache-serving/route-handler/route.ts @@ -1,6 +1,6 @@ import { NextRequest, NextResponse } from 'next/server' -export const revalidate = 0 +export const dynamic = 'force-dynamic' const delay = 3000 From 259c4052f8b25091d4b4abab2cd0f8c970e1a264 Mon Sep 17 00:00:00 2001 From: mknichel <7355009+mknichel@users.noreply.github.com> Date: Wed, 22 Nov 2023 12:52:33 -0800 Subject: [PATCH 020/481] [Instrumentation] Don't treat instrumentation hook as pages (#58775) This PR doesn't treat an instrumentation hook as a `PAGES` page which avoids compiling `_app`, `_document`, and `_error` when compiling the instrumentation hook. --- packages/next/src/server/dev/hot-reloader-webpack.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/next/src/server/dev/hot-reloader-webpack.ts b/packages/next/src/server/dev/hot-reloader-webpack.ts index 8acbb1e0ddb7d..e7348cbcf4bcb 100644 --- a/packages/next/src/server/dev/hot-reloader-webpack.ts +++ b/packages/next/src/server/dev/hot-reloader-webpack.ts @@ -51,6 +51,7 @@ import { normalizePathSep } from '../../shared/lib/page-path/normalize-path-sep' import getRouteFromEntrypoint from '../get-route-from-entrypoint' import { difference, + isInstrumentationHookFile, isMiddlewareFile, isMiddlewareFilename, } from '../../build/utils' @@ -955,7 +956,8 @@ export default class HotReloader implements NextJsHotReloaderInterface { } else if ( !isMiddlewareFile(page) && !isInternalComponent(relativeRequest) && - !isNonRoutePagesPage(page) + !isNonRoutePagesPage(page) && + !(isInstrumentationHookFile(page) && pageType === 'root') ) { value = getRouteLoaderEntry({ kind: RouteKind.PAGES, From b3914f617584232475ca898c8fedd9d138705531 Mon Sep 17 00:00:00 2001 From: Will Binns-Smith Date: Wed, 22 Nov 2023 13:22:26 -0800 Subject: [PATCH 021/481] Turbopack: update to turbopack-231122.3 (#58784) Includes vercel/turbo#6525 --- Cargo.lock | 66 +++++++++++++++++++++++++++--------------------------- Cargo.toml | 6 ++--- 2 files changed, 36 insertions(+), 36 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index da772eab006c2..fb9160493a4ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -322,7 +322,7 @@ dependencies = [ [[package]] name = "auto-hash-map" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" dependencies = [ "serde", "smallvec", @@ -3549,7 +3549,7 @@ dependencies = [ [[package]] name = "node-file-trace" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" dependencies = [ "anyhow", "serde", @@ -7695,7 +7695,7 @@ dependencies = [ [[package]] name = "turbo-tasks" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" dependencies = [ "anyhow", "async-trait", @@ -7727,7 +7727,7 @@ dependencies = [ [[package]] name = "turbo-tasks-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" dependencies = [ "anyhow", "cargo-lock", @@ -7739,7 +7739,7 @@ dependencies = [ [[package]] name = "turbo-tasks-bytes" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" dependencies = [ "anyhow", "bytes", @@ -7754,7 +7754,7 @@ dependencies = [ [[package]] name = "turbo-tasks-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" dependencies = [ "anyhow", "dotenvs", @@ -7768,7 +7768,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fetch" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7785,7 +7785,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fs" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" dependencies = [ "anyhow", "auto-hash-map", @@ -7815,7 +7815,7 @@ dependencies = [ [[package]] name = "turbo-tasks-hash" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" dependencies = [ "base16", "hex", @@ -7827,7 +7827,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" dependencies = [ "anyhow", "convert_case 0.6.0", @@ -7841,7 +7841,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros-shared" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" dependencies = [ "proc-macro2", "quote", @@ -7851,7 +7851,7 @@ dependencies = [ [[package]] name = "turbo-tasks-malloc" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" dependencies = [ "mimalloc", ] @@ -7859,7 +7859,7 @@ dependencies = [ [[package]] name = "turbo-tasks-memory" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" dependencies = [ "anyhow", "auto-hash-map", @@ -7884,7 +7884,7 @@ dependencies = [ [[package]] name = "turbopack" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" dependencies = [ "anyhow", "async-recursion", @@ -7915,7 +7915,7 @@ dependencies = [ [[package]] name = "turbopack-binding" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" dependencies = [ "auto-hash-map", "mdxjs", @@ -7955,7 +7955,7 @@ dependencies = [ [[package]] name = "turbopack-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7978,7 +7978,7 @@ dependencies = [ [[package]] name = "turbopack-cli-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" dependencies = [ "anyhow", "clap 4.4.2", @@ -8002,7 +8002,7 @@ dependencies = [ [[package]] name = "turbopack-core" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" dependencies = [ "anyhow", "async-recursion", @@ -8032,7 +8032,7 @@ dependencies = [ [[package]] name = "turbopack-css" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" dependencies = [ "anyhow", "async-trait", @@ -8058,7 +8058,7 @@ dependencies = [ [[package]] name = "turbopack-dev" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -8082,7 +8082,7 @@ dependencies = [ [[package]] name = "turbopack-dev-server" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" dependencies = [ "anyhow", "async-compression", @@ -8119,7 +8119,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" dependencies = [ "anyhow", "async-trait", @@ -8153,7 +8153,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-hmr-protocol" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" dependencies = [ "serde", "serde_json", @@ -8164,7 +8164,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-plugins" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" dependencies = [ "anyhow", "async-trait", @@ -8187,7 +8187,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-runtime" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" dependencies = [ "anyhow", "indoc", @@ -8204,7 +8204,7 @@ dependencies = [ [[package]] name = "turbopack-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -8220,7 +8220,7 @@ dependencies = [ [[package]] name = "turbopack-image" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" dependencies = [ "anyhow", "base64 0.21.4", @@ -8240,7 +8240,7 @@ dependencies = [ [[package]] name = "turbopack-json" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" dependencies = [ "anyhow", "serde", @@ -8255,7 +8255,7 @@ dependencies = [ [[package]] name = "turbopack-mdx" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" dependencies = [ "anyhow", "mdxjs", @@ -8270,7 +8270,7 @@ dependencies = [ [[package]] name = "turbopack-node" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" dependencies = [ "anyhow", "async-stream", @@ -8305,7 +8305,7 @@ dependencies = [ [[package]] name = "turbopack-static" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" dependencies = [ "anyhow", "serde", @@ -8321,7 +8321,7 @@ dependencies = [ [[package]] name = "turbopack-swc-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" dependencies = [ "swc_core", "turbo-tasks", @@ -8332,7 +8332,7 @@ dependencies = [ [[package]] name = "turbopack-wasm" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.2#b26f1172ee529e00a86cd7b3b59e01c0aac99fba" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" dependencies = [ "anyhow", "indexmap 1.9.3", diff --git a/Cargo.toml b/Cargo.toml index cf33d5921fd23..a2809aa38838f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,11 +43,11 @@ next-transform-strip-page-exports = { path = "packages/next-swc/crates/next-tran testing = { version = "0.35.10" } # Turbo crates -turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231122.2" } +turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231122.3" } # [TODO]: need to refactor embed_directory! macro usages, as well as resolving turbo_tasks::function, macros.. -turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231122.2" } +turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231122.3" } # [TODO]: need to refactor embed_directory! macro usage in next-core -turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231122.2" } +turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231122.3" } # General Deps From cf102cf1bda1111ebb93b61c2144d3cfc6a15a16 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Wed, 22 Nov 2023 22:55:06 +0100 Subject: [PATCH 022/481] Fix turboFlag set to false (#58795) ## What? Currently it's always reported as `false` but that is not correct. Needs to reflect the real value. --- packages/next/src/server/lib/router-utils/setup-dev-bundler.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts b/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts index d2a5176230518..783632028b896 100644 --- a/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts +++ b/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts @@ -2504,7 +2504,7 @@ export async function setupDevBundler(opts: SetupOpts) { { webpackVersion: 5, isSrcDir, - turboFlag: false, + turboFlag: !!opts.turbo, cliCommand: 'dev', appDir: !!opts.appDir, pagesDir: !!opts.pagesDir, From 3aa62d1fff4e47fa9cb3288e23268d1393794e24 Mon Sep 17 00:00:00 2001 From: mknichel <7355009+mknichel@users.noreply.github.com> Date: Wed, 22 Nov 2023 14:25:10 -0800 Subject: [PATCH 023/481] [.next/trace] Track server requests and memory usage (#58690) This PR adds more information to `.next/trace` for local development: - Break down server startup times into setting up the dev bundler and running the instrumentation hook - Add top level span for handling a request such as a page request, app router request, or API request - Add span for compilation time tracking the path of the route that triggered the compilation. - Track memory usage after every request - Track event when server is restarted due to reaching the memory limit Platform stats and memory usage on startup: ![Screenshot 2023-11-20 at 8 47 38 AM](https://github.com/vercel/next.js/assets/7355009/870226cc-8caa-41bd-92ae-b0025aecdee7) Memory usage after each request: Screenshot 2023-11-20 at 9 16 44 AM Split server startup times into setting up the dev bundler and running the instrumentation hook: ![Screenshot 2023-11-20 at 8 46 41 AM](https://github.com/vercel/next.js/assets/7355009/eda8b16d-a784-4332-b8b1-5f0dce0611ef) Co-authored-by: Tim Neutkens <6324199+timneutkens@users.noreply.github.com> --- packages/next/src/build/compiler.ts | 2 +- packages/next/src/build/index.ts | 2 +- packages/next/src/build/output/store.ts | 10 ++++- .../next/src/build/webpack-build/index.ts | 2 +- .../webpack/plugins/css-minimizer-plugin.ts | 1 - packages/next/src/cli/next-dev.ts | 13 ++++++ packages/next/src/export/index.ts | 2 +- .../next/src/server/dev/next-dev-server.ts | 31 +++++++++++-- packages/next/src/server/lib/render-server.ts | 2 + packages/next/src/server/lib/router-server.ts | 34 ++++++++------ packages/next/src/server/lib/start-server.ts | 31 ++++++++++++- packages/next/src/trace/trace-uploader.ts | 3 ++ packages/next/src/trace/trace.test.ts | 4 +- packages/next/src/trace/trace.ts | 44 ++++++++++++------- packages/next/src/trace/upload-trace.ts | 9 ++-- 15 files changed, 143 insertions(+), 47 deletions(-) diff --git a/packages/next/src/build/compiler.ts b/packages/next/src/build/compiler.ts index 5206a4d7813ad..0afa41209e920 100644 --- a/packages/next/src/build/compiler.ts +++ b/packages/next/src/build/compiler.ts @@ -51,7 +51,7 @@ export function runCompiler( compiler.fsStartTime = Date.now() compiler.run((err, stats) => { const webpackCloseSpan = runWebpackSpan.traceChild('webpack-close', { - name: config.name, + name: config.name || 'unknown', }) webpackCloseSpan .traceAsyncFn(() => closeCompiler(compiler)) diff --git a/packages/next/src/build/index.ts b/packages/next/src/build/index.ts index a5894d7462502..9fd50672283ed 100644 --- a/packages/next/src/build/index.ts +++ b/packages/next/src/build/index.ts @@ -1605,7 +1605,7 @@ export default async function build( httpAgentOptions: config.httpAgentOptions, locales: config.i18n?.locales, defaultLocale: config.i18n?.defaultLocale, - parentId: isPageStaticSpan.id, + parentId: isPageStaticSpan.getId(), pageRuntime, edgeInfo, pageType, diff --git a/packages/next/src/build/output/store.ts b/packages/next/src/build/output/store.ts index 6ef1b8a749434..0599ccf7157b1 100644 --- a/packages/next/src/build/output/store.ts +++ b/packages/next/src/build/output/store.ts @@ -1,6 +1,6 @@ import createStore from 'next/dist/compiled/unistore' import stripAnsi from 'next/dist/compiled/strip-ansi' -import { flushAllTraces } from '../../trace' +import { type Span, flushAllTraces, trace } from '../../trace' import { teardownCrashReporter, teardownHeapProfiler, @@ -52,6 +52,7 @@ function hasStoreChanged(nextStore: OutputState) { let startTime = 0 let trigger = '' // default, use empty string for trigger let loadingLogTimer: NodeJS.Timeout | null = null +let traceSpan: Span | null = null store.subscribe((state) => { if (!hasStoreChanged(state)) { @@ -66,6 +67,9 @@ store.subscribe((state) => { if (state.trigger) { trigger = state.trigger if (trigger !== 'initial') { + traceSpan = trace('compile-path', undefined, { + trigger: trigger, + }) if (!loadingLogTimer) { // Only log compiling if compiled is not finished in 3 seconds loadingLogTimer = setTimeout(() => { @@ -144,6 +148,10 @@ store.subscribe((state) => { clearTimeout(loadingLogTimer) loadingLogTimer = null } + if (traceSpan) { + traceSpan.stop() + traceSpan = null + } Log.event( `Compiled${trigger ? ' ' + trigger : ''}${timeMessage}${modulesMessage}` ) diff --git a/packages/next/src/build/webpack-build/index.ts b/packages/next/src/build/webpack-build/index.ts index 0469426fb28f8..8e9675d1a2770 100644 --- a/packages/next/src/build/webpack-build/index.ts +++ b/packages/next/src/build/webpack-build/index.ts @@ -86,7 +86,7 @@ async function webpackBuildWithWorker( compilerName, traceState: { ...exportTraceState(), - defaultParentSpanId: nextBuildSpan?.id, + defaultParentSpanId: nextBuildSpan?.getId(), shouldSaveTraceEvents: true, }, }) diff --git a/packages/next/src/build/webpack/plugins/css-minimizer-plugin.ts b/packages/next/src/build/webpack/plugins/css-minimizer-plugin.ts index d79ad14b71b4e..2b09b5a9b8874 100644 --- a/packages/next/src/build/webpack/plugins/css-minimizer-plugin.ts +++ b/packages/next/src/build/webpack/plugins/css-minimizer-plugin.ts @@ -68,7 +68,6 @@ export class CssMinimizerPlugin { const cssMinimizerSpan = compilationSpan!.traceChild( 'css-minimizer-plugin' ) - cssMinimizerSpan.setAttribute('webpackVersion', 5) return cssMinimizerSpan.traceAsyncFn(async () => { const files = Object.keys(assets) diff --git a/packages/next/src/cli/next-dev.ts b/packages/next/src/cli/next-dev.ts index 78831fdfae031..02e920d6971cc 100644 --- a/packages/next/src/cli/next-dev.ts +++ b/packages/next/src/cli/next-dev.ts @@ -272,6 +272,19 @@ const nextDev: CliCommand = async (args) => { return } if (code === RESTART_EXIT_CODE) { + // Starting the dev server will overwrite the `.next/trace` file, so we + // must upload the existing contents before restarting the server to + // preserve the metrics. + if (traceUploadUrl) { + uploadTrace({ + traceUploadUrl, + mode: 'dev', + isTurboSession, + projectDir: dir, + distDir: config.distDir, + sync: true, + }) + } return startServer(options) } await handleSessionStop(signal) diff --git a/packages/next/src/export/index.ts b/packages/next/src/export/index.ts index 4f520e6cc84ef..62569fd09f927 100644 --- a/packages/next/src/export/index.ts +++ b/packages/next/src/export/index.ts @@ -691,7 +691,7 @@ export async function exportAppImpl( optimizeCss: nextConfig.experimental.optimizeCss, disableOptimizedLoading: nextConfig.experimental.disableOptimizedLoading, - parentSpanId: pageExportSpan.id, + parentSpanId: pageExportSpan.getId(), httpAgentOptions: nextConfig.httpAgentOptions, debugOutput: options.debugOutput, isrMemoryCacheSize: nextConfig.experimental.isrMemoryCacheSize, diff --git a/packages/next/src/server/dev/next-dev-server.ts b/packages/next/src/server/dev/next-dev-server.ts index 5a5f9a49527c6..05d428360212c 100644 --- a/packages/next/src/server/dev/next-dev-server.ts +++ b/packages/next/src/server/dev/next-dev-server.ts @@ -40,7 +40,7 @@ import { normalizePagePath } from '../../shared/lib/page-path/normalize-page-pat import { pathHasPrefix } from '../../shared/lib/router/utils/path-has-prefix' import { removePathPrefix } from '../../shared/lib/router/utils/remove-path-prefix' import { Telemetry } from '../../telemetry/storage' -import { setGlobal } from '../../trace' +import { type Span, setGlobal, trace } from '../../trace' import { findPageFile } from '../lib/find-page-file' import { getNodeOptionsWithoutInspect } from '../lib/utils' import { withCoalescedInvoke } from '../../lib/coalesced-function' @@ -84,6 +84,11 @@ export interface Options extends ServerOptions { * Interface to the development bundler. */ bundlerService: DevBundlerService + + /** + * Trace span for server startup. + */ + startServerSpan: Span } export default class DevServer extends Server { @@ -104,6 +109,7 @@ export default class DevServer extends Server { string, UnwrapPromise> > + private startServerSpan: Span protected staticPathsWorker?: { [key: string]: any } & { loadStaticPaths: typeof import('./static-paths-worker').loadStaticPaths @@ -145,6 +151,8 @@ export default class DevServer extends Server { } catch {} super({ ...options, dev: true }) this.bundlerService = options.bundlerService + this.startServerSpan = + options.startServerSpan ?? trace('start-next-dev-server') this.originalFetch = global.fetch this.renderOpts.dev = true this.renderOpts.appDirDevErrorLogger = (err: any) => @@ -268,7 +276,9 @@ export default class DevServer extends Server { const telemetry = new Telemetry({ distDir: this.distDir }) await super.prepareImpl() - await this.runInstrumentationHookIfAvailable() + await this.startServerSpan + .traceChild('run-instrumentation-hook') + .traceAsyncFn(() => this.runInstrumentationHookIfAvailable()) await this.matchers.reload() this.ready?.resolve() @@ -437,8 +447,21 @@ export default class DevServer extends Server { res: BaseNextResponse, parsedUrl?: NextUrlWithParsedQuery ): Promise { - await this.ready?.promise - return await super.handleRequest(req, res, parsedUrl) + const span = trace('handle-request', undefined, { url: req.url }) + const result = await span.traceAsyncFn(async () => { + await this.ready?.promise + return await super.handleRequest(req, res, parsedUrl) + }) + const memoryUsage = process.memoryUsage() + span + .traceChild('memory-usage', { + url: req.url, + 'memory.rss': String(memoryUsage.rss), + 'memory.heapUsed': String(memoryUsage.heapUsed), + 'memory.heapTotal': String(memoryUsage.heapTotal), + }) + .stop() + return result } async run( diff --git a/packages/next/src/server/lib/render-server.ts b/packages/next/src/server/lib/render-server.ts index cf0603588e7d4..7be2a45071668 100644 --- a/packages/next/src/server/lib/render-server.ts +++ b/packages/next/src/server/lib/render-server.ts @@ -3,6 +3,7 @@ import type { DevBundlerService } from './dev-bundler-service' import type { PropagateToWorkersField } from './router-utils/types' import next from '../next' +import type { Span } from '../../trace' let initializations: Record< string, @@ -81,6 +82,7 @@ async function initializeImpl(opts: { _ipcPort?: string _ipcKey?: string bundlerService: DevBundlerService | undefined + startServerSpan: Span | undefined }) { const type = process.env.__NEXT_PRIVATE_RENDER_WORKER if (type) { diff --git a/packages/next/src/server/lib/router-server.ts b/packages/next/src/server/lib/router-server.ts index 644dea1f77c67..c04bb1ce4a4ec 100644 --- a/packages/next/src/server/lib/router-server.ts +++ b/packages/next/src/server/lib/router-server.ts @@ -32,6 +32,7 @@ import { PERMANENT_REDIRECT_STATUS, } from '../../shared/lib/constants' import { DevBundlerService } from './dev-bundler-service' +import { type Span, trace } from '../../trace' const debug = setupDebug('next:router-server:main') @@ -62,6 +63,7 @@ export async function initialize(opts: { customServer?: boolean experimentalTestProxy?: boolean experimentalHttpsServer?: boolean + startServerSpan?: Span }): Promise<[WorkerRequestHandler, WorkerUpgradeHandler]> { if (!process.env.NODE_ENV) { // @ts-ignore not readonly @@ -102,19 +104,24 @@ export async function initialize(opts: { const { setupDevBundler } = require('./router-utils/setup-dev-bundler') as typeof import('./router-utils/setup-dev-bundler') - developmentBundler = await setupDevBundler({ - // Passed here but the initialization of this object happens below, doing the initialization before the setupDev call breaks. - renderServer, - appDir, - pagesDir, - telemetry, - fsChecker, - dir: opts.dir, - nextConfig: config, - isCustomServer: opts.customServer, - turbo: !!process.env.TURBOPACK, - port: opts.port, - }) + const setupDevBundlerSpan = opts.startServerSpan + ? opts.startServerSpan.traceChild('setup-dev-bundler') + : trace('setup-dev-bundler') + developmentBundler = await setupDevBundlerSpan.traceAsyncFn(() => + setupDevBundler({ + // Passed here but the initialization of this object happens below, doing the initialization before the setupDev call breaks. + renderServer, + appDir, + pagesDir, + telemetry, + fsChecker, + dir: opts.dir, + nextConfig: config, + isCustomServer: opts.customServer, + turbo: !!process.env.TURBOPACK, + port: opts.port, + }) + ) devBundlerService = new DevBundlerService( developmentBundler, @@ -141,6 +148,7 @@ export async function initialize(opts: { experimentalTestProxy: !!opts.experimentalTestProxy, experimentalHttpsServer: !!opts.experimentalHttpsServer, bundlerService: devBundlerService, + startServerSpan: opts.startServerSpan, } // pre-initialize workers diff --git a/packages/next/src/server/lib/start-server.ts b/packages/next/src/server/lib/start-server.ts index 288705e0c916b..fd501c6ab8ad0 100644 --- a/packages/next/src/server/lib/start-server.ts +++ b/packages/next/src/server/lib/start-server.ts @@ -13,6 +13,7 @@ import v8 from 'v8' import path from 'path' import http from 'http' import https from 'https' +import os from 'os' import Watchpack from 'watchpack' import * as Log from '../../build/output/log' import setupDebug from 'next/dist/compiled/debug' @@ -22,10 +23,11 @@ import { initialize } from './router-server' import { CONFIG_FILES } from '../../shared/lib/constants' import { getStartServerInfo, logStartInfo } from './app-info-log' import { validateTurboNextConfig } from '../../lib/turbopack-warning' -import { trace } from '../../trace' +import { type Span, trace, flushAllTraces } from '../../trace' import { isPostpone } from './router-utils/is-postpone' const debug = setupDebug('next:start-server') +let startServerSpan: Span | undefined export interface StartServerOptions { dir: string @@ -75,6 +77,7 @@ export async function getRequestHandlers({ keepAliveTimeout, experimentalTestProxy, experimentalHttpsServer, + startServerSpan, }) } @@ -153,6 +156,13 @@ export async function startServer( Log.warn( `Server is approaching the used memory threshold, restarting...` ) + trace('server-restart-close-to-memory-threshold', undefined, { + 'memory.heapSizeLimit': String( + v8.getHeapStatistics().heap_size_limit + ), + 'memory.heapUsed': String(v8.getHeapStatistics().used_heap_size), + }).stop() + await flushAllTraces() process.exit(RESTART_EXIT_CODE) } } @@ -362,9 +372,26 @@ export async function startServer( if (process.env.NEXT_PRIVATE_WORKER && process.send) { process.addListener('message', async (msg: any) => { if (msg && typeof msg && msg.nextWorkerOptions && process.send) { - await trace('start-dev-server').traceAsyncFn(() => + startServerSpan = trace('start-dev-server', undefined, { + cpus: String(os.cpus().length), + platform: os.platform(), + 'memory.freeMem': String(os.freemem()), + 'memory.totalMem': String(os.totalmem()), + 'memory.heapSizeLimit': String(v8.getHeapStatistics().heap_size_limit), + }) + await startServerSpan.traceAsyncFn(() => startServer(msg.nextWorkerOptions) ) + const memoryUsage = process.memoryUsage() + startServerSpan.setAttribute('memory.rss', String(memoryUsage.rss)) + startServerSpan.setAttribute( + 'memory.heapTotal', + String(memoryUsage.heapTotal) + ) + startServerSpan.setAttribute( + 'memory.heapUsed', + String(memoryUsage.heapUsed) + ) process.send({ nextServerReady: true }) } }) diff --git a/packages/next/src/trace/trace-uploader.ts b/packages/next/src/trace/trace-uploader.ts index 2ddf470c34c40..c5126f097cca4 100644 --- a/packages/next/src/trace/trace-uploader.ts +++ b/packages/next/src/trace/trace-uploader.ts @@ -19,6 +19,9 @@ const EVENT_FILTER = new Set([ 'webpack-invalidated-server', 'navigation-to-hydration', 'start-dev-server', + 'compile-path', + 'memory-usage', + 'server-restart-close-to-memory-threshold', ]) const { diff --git a/packages/next/src/trace/trace.test.ts b/packages/next/src/trace/trace.test.ts index 3584b644410ee..42d04fa2e3c9e 100644 --- a/packages/next/src/trace/trace.test.ts +++ b/packages/next/src/trace/trace.test.ts @@ -86,14 +86,14 @@ describe('Trace', () => { describe('Worker', () => { it('exports and initializes trace state', () => { const root = trace('root-span') - expect(root.id).toEqual(1) + expect(root.getId()).toEqual(1) const traceState = exportTraceState() expect(traceState.lastId).toEqual(1) initializeTraceState({ lastId: 101, }) const span = trace('another-span') - expect(span.id).toEqual(102) + expect(span.getId()).toEqual(102) }) it('trace data is serializable to a worker', async () => { diff --git a/packages/next/src/trace/trace.ts b/packages/next/src/trace/trace.ts index d42fd10850445..da876a1cd519e 100644 --- a/packages/next/src/trace/trace.ts +++ b/packages/next/src/trace/trace.ts @@ -14,22 +14,24 @@ let savedTraceEvents: TraceEvent[] = [] // eslint typescript has a bug with TS enums /* eslint-disable no-shadow */ export enum SpanStatus { - Started, - Stopped, + Started = 'started', + Stopped = 'stopped', +} + +interface Attributes { + [key: string]: string } export class Span { - name: string - id: SpanId - parentId?: SpanId - // Duration of the span in *microseconds*. - duration: number | null - attrs: { [key: string]: any } - status: SpanStatus - now: number + private name: string + private id: SpanId + private parentId?: SpanId + private attrs: { [key: string]: any } + private status: SpanStatus + private now: number // Number of nanoseconds since epoch. - _start: bigint + private _start: bigint constructor({ name, @@ -40,11 +42,10 @@ export class Span { name: string parentId?: SpanId startTime?: bigint - attrs?: Object + attrs?: Attributes }) { this.name = name this.parentId = parentId ?? defaultParentSpanId - this.duration = null this.attrs = attrs ? { ...attrs } : {} this.status = SpanStatus.Started this.id = getId() @@ -62,6 +63,11 @@ export class Span { // Additionally, ~285 years can be safely represented as microseconds as // a float64 in both JSON and JavaScript. stop(stopTime?: bigint) { + if (this.status === SpanStatus.Stopped) { + // Don't report the same span twice. + // TODO: In the future this should throw as `.stop()` shouldn't be called multiple times. + return + } const end: bigint = stopTime || process.hrtime.bigint() const duration = (end - this._start) / NUM_OF_MICROSEC_IN_NANOSEC this.status = SpanStatus.Stopped @@ -84,7 +90,7 @@ export class Span { } } - traceChild(name: string, attrs?: Object) { + traceChild(name: string, attrs?: Attributes) { return new Span({ name, parentId: this.id, attrs }) } @@ -94,14 +100,18 @@ export class Span { startTime: bigint, // Stop time in nanoseconds since epoch. stopTime: bigint, - attrs?: Object + attrs?: Attributes ) { const span = new Span({ name, parentId: this.id, attrs, startTime }) span.stop(stopTime) } - setAttribute(key: string, value: any) { - this.attrs[key] = String(value) + getId() { + return this.id + } + + setAttribute(key: string, value: string) { + this.attrs[key] = value } traceFn(fn: (span: Span) => T): T { diff --git a/packages/next/src/trace/upload-trace.ts b/packages/next/src/trace/upload-trace.ts index a5704e32601d8..ee111763d168f 100644 --- a/packages/next/src/trace/upload-trace.ts +++ b/packages/next/src/trace/upload-trace.ts @@ -4,12 +4,14 @@ export default function uploadTrace({ isTurboSession, projectDir, distDir, + sync, }: { traceUploadUrl: string mode: 'dev' isTurboSession: boolean projectDir: string distDir: string + sync?: boolean }) { const { NEXT_TRACE_UPLOAD_DEBUG } = process.env @@ -20,9 +22,10 @@ export default function uploadTrace({ // we use spawnSync when debugging to ensure logs are piped // correctly to stdout/stderr - const spawn = NEXT_TRACE_UPLOAD_DEBUG - ? child_process.spawnSync - : child_process.spawn + const spawn = + NEXT_TRACE_UPLOAD_DEBUG || sync + ? child_process.spawnSync + : child_process.spawn spawn( process.execPath, From 0155ec70d7972cf43f8c284fd3f0f1be9f3f48a8 Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Wed, 22 Nov 2023 23:22:02 +0000 Subject: [PATCH 024/481] v14.0.4-canary.11 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 16 ++++++++-------- 18 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lerna.json b/lerna.json index 13fbd5596520c..9851c2f8090a4 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.10" + "version": "14.0.4-canary.11" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 9fb002b56326c..d9732a1e3efa5 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.10", + "version": "14.0.4-canary.11", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 4c9271347baa2..a4558d4bed0d5 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.10", + "version": "14.0.4-canary.11", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.10", + "@next/eslint-plugin-next": "14.0.4-canary.11", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 85364fb81f66e..aba951d7d34b5 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.10", + "version": "14.0.4-canary.11", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index 96adb981f1b31..d1f45a2e401cb 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.10", + "version": "14.0.4-canary.11", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 14c53e7988f5c..037cc389a892b 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.10", + "version": "14.0.4-canary.11", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 8f36226e87946..0c285e41aa3bf 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.10", + "version": "14.0.4-canary.11", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 73ec7b1d64de8..e51e33a291ed8 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.10", + "version": "14.0.4-canary.11", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 36a0da3351b06..cd1354c71d9f5 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.10", + "version": "14.0.4-canary.11", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 02ccab17c4377..c23c05b7ea451 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.10", + "version": "14.0.4-canary.11", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index a9d2e17c50bcd..c7d7685dc8e1c 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.10", + "version": "14.0.4-canary.11", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index 371be1d840051..7a997781d3223 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.10", + "version": "14.0.4-canary.11", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index 5db5fd3dd4f52..a726d89eb3e38 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.10", + "version": "14.0.4-canary.11", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index 6fcee8ec1bad6..9f6ae20a15414 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.10", + "version": "14.0.4-canary.11", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.10", + "@next/env": "14.0.4-canary.11", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -146,11 +146,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.10", - "@next/polyfill-nomodule": "14.0.4-canary.10", - "@next/react-dev-overlay": "14.0.4-canary.10", - "@next/react-refresh-utils": "14.0.4-canary.10", - "@next/swc": "14.0.4-canary.10", + "@next/polyfill-module": "14.0.4-canary.11", + "@next/polyfill-nomodule": "14.0.4-canary.11", + "@next/react-dev-overlay": "14.0.4-canary.11", + "@next/react-refresh-utils": "14.0.4-canary.11", + "@next/swc": "14.0.4-canary.11", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index 585a658b54667..a9055ae74f90d 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.10", + "version": "14.0.4-canary.11", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index 5c4c494f370f8..dbcb7526e719d 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.10", + "version": "14.0.4-canary.11", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index efeff028925ee..af22fa8d5af5d 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.10", + "version": "14.0.4-canary.11", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -23,7 +23,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.10", + "next": "14.0.4-canary.11", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 95aa246bb4ef3..ab27b4cd58eae 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -735,7 +735,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.10 + specifier: 14.0.4-canary.11 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -800,7 +800,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.10 + specifier: 14.0.4-canary.11 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -924,19 +924,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.10 + specifier: 14.0.4-canary.11 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.10 + specifier: 14.0.4-canary.11 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.10 + specifier: 14.0.4-canary.11 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.10 + specifier: 14.0.4-canary.11 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.10 + specifier: 14.0.4-canary.11 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1587,7 +1587,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.10 + specifier: 14.0.4-canary.11 version: link:../next outdent: specifier: 0.8.0 From 2f07579a50180a29e64f9be2b8a34f62aed0fc9a Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Thu, 23 Nov 2023 00:57:42 +0100 Subject: [PATCH 025/481] place virtual module inside the project directory (#58798) ### What? This virtual module was created in a weird path/filesystem: [node]/.next/server/app/.../page/actions.js. It's in the output filesystem, which can't access the monorepo root, so it can't resolve the tsconfig. But it shouldn't be in that filesystem in first place. Closes PACK-2025 --- packages/next-swc/crates/next-api/src/app.rs | 2 ++ packages/next-swc/crates/next-api/src/server_actions.rs | 8 +++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/next-swc/crates/next-api/src/app.rs b/packages/next-swc/crates/next-api/src/app.rs index bb2b326a2ad65..7e01aeb11d555 100644 --- a/packages/next-swc/crates/next-api/src/app.rs +++ b/packages/next-swc/crates/next-api/src/app.rs @@ -826,6 +826,7 @@ impl AppEndpoint { let (loader, manifest) = create_server_actions_manifest( Vc::upcast(app_entry.rsc_entry), get_app_server_reference_modules(client_reference_types), + this.app_project.project().project_path(), node_root, &app_entry.pathname, &app_entry.original_name, @@ -977,6 +978,7 @@ impl AppEndpoint { let (loader, manifest) = create_server_actions_manifest( Vc::upcast(app_entry.rsc_entry), get_app_server_reference_modules(client_reference_types), + this.app_project.project().project_path(), node_root, &app_entry.pathname, &app_entry.original_name, diff --git a/packages/next-swc/crates/next-api/src/server_actions.rs b/packages/next-swc/crates/next-api/src/server_actions.rs index a88737bc11716..e660fb142b261 100644 --- a/packages/next-swc/crates/next-api/src/server_actions.rs +++ b/packages/next-swc/crates/next-api/src/server_actions.rs @@ -45,6 +45,7 @@ use turbopack_binding::{ pub(crate) async fn create_server_actions_manifest( rsc_entry: Vc>, server_reference_modules: Vc>>>, + project_path: Vc, node_root: Vc, pathname: &str, page_name: &str, @@ -53,7 +54,8 @@ pub(crate) async fn create_server_actions_manifest( chunking_context: Vc>, ) -> Result<(Vc>, Vc>)> { let actions = get_actions(rsc_entry, server_reference_modules, asset_context); - let loader = build_server_actions_loader(node_root, page_name, actions, asset_context).await?; + let loader = + build_server_actions_loader(project_path, page_name, actions, asset_context).await?; let Some(evaluable) = Vc::try_resolve_sidecast::>(loader).await? else { bail!("loader module must be evaluatable"); @@ -75,7 +77,7 @@ pub(crate) async fn create_server_actions_manifest( /// file's name and the action name). This hash matches the id sent to the /// client and present inside the paired manifest. async fn build_server_actions_loader( - node_root: Vc, + project_path: Vc, page_name: &str, actions: Vc, asset_context: Vc>, @@ -100,7 +102,7 @@ async fn build_server_actions_loader( } write!(contents, "}});")?; - let output_path = node_root.join(format!("server/app{page_name}/actions.js")); + let output_path = project_path.join(format!(".next-internal/server/app{page_name}/actions.js")); let file = File::from(contents.build()); let source = VirtualSource::new(output_path, AssetContent::file(file.into())); let import_map = import_map.into_iter().map(|(k, v)| (v, k)).collect(); From 0f642dc340fe1048b72821e32c4779ce04a90e05 Mon Sep 17 00:00:00 2001 From: Zack Tanner Date: Wed, 22 Nov 2023 21:25:00 -0800 Subject: [PATCH 026/481] fix rewrites to edge routes (#58797) ### What? Rewrites to an edge route currently throw an invariant rather than properly serving up the page that is rewritten to. ### Why? The `NextRequest` object that is provided to the edge route handler contains pathname information only for the "origin" request (e.g., when visiting `/one/example` which rewrites to `/two/example`, the pathname is still `/one/example`. This hits an invariant since the route matcher is unable to find `/one/example` since it does not exist. ### How? This updates the module wrapper to grab the pathname from the route definition rather than the request object. For dynamic segments, we extract them from `request.nextUrl` since we know that even if `nextUrl` is referencing the origin path, the parameters it has are relevant for the rewrite. This adds the `getUtils` utility that's also used in base-server to handle the URL normalization, which also provides an interface for normalizing dynamic params from a `ParsedUrlQuery`. Closes NEXT-1724 Fixes #48295 --- .../server/web/edge-route-module-wrapper.ts | 34 ++++++++----------- .../app/dynamic/[slug]/route.ts | 8 +++++ .../app-dir/edge-route-rewrite/app/layout.tsx | 16 +++++++++ .../app/two/example/route.ts | 6 ++++ .../edge-route-rewrite.test.ts | 21 ++++++++++++ .../app-dir/edge-route-rewrite/middleware.ts | 21 ++++++++++++ .../app-dir/edge-route-rewrite/next.config.js | 6 ++++ 7 files changed, 92 insertions(+), 20 deletions(-) create mode 100644 test/e2e/app-dir/edge-route-rewrite/app/dynamic/[slug]/route.ts create mode 100644 test/e2e/app-dir/edge-route-rewrite/app/layout.tsx create mode 100644 test/e2e/app-dir/edge-route-rewrite/app/two/example/route.ts create mode 100644 test/e2e/app-dir/edge-route-rewrite/edge-route-rewrite.test.ts create mode 100644 test/e2e/app-dir/edge-route-rewrite/middleware.ts create mode 100644 test/e2e/app-dir/edge-route-rewrite/next.config.js diff --git a/packages/next/src/server/web/edge-route-module-wrapper.ts b/packages/next/src/server/web/edge-route-module-wrapper.ts index e2c3977614f68..7877c234cf974 100644 --- a/packages/next/src/server/web/edge-route-module-wrapper.ts +++ b/packages/next/src/server/web/edge-route-module-wrapper.ts @@ -10,10 +10,9 @@ import './globals' import { adapter, type AdapterOptions } from './adapter' import { IncrementalCache } from '../lib/incremental-cache' import { RouteMatcher } from '../future/route-matchers/route-matcher' -import { removeTrailingSlash } from '../../shared/lib/router/utils/remove-trailing-slash' -import { removePathPrefix } from '../../shared/lib/router/utils/remove-path-prefix' import type { NextFetchEvent } from './spec-extension/fetch-event' import { internal_getCurrentFunctionWaitUntil } from './internal-edge-wait-until' +import { getUtils } from '../server-utils' type WrapOptions = Partial> @@ -68,24 +67,19 @@ export class EdgeRouteModuleWrapper { request: NextRequest, evt: NextFetchEvent ): Promise { - // Get the pathname for the matcher. Pathnames should not have trailing - // slashes for matching. - let pathname = removeTrailingSlash(new URL(request.url).pathname) + const utils = getUtils({ + pageIsDynamic: this.matcher.isDynamic, + page: this.matcher.definition.pathname, + basePath: request.nextUrl.basePath, + // We don't need the `handleRewrite` util, so can just pass an empty object + rewrites: {}, + // only used for rewrites, so setting an arbitrary default value here + caseSensitive: false, + }) - // Get the base path and strip it from the pathname if it exists. - const { basePath } = request.nextUrl - if (basePath) { - // If the path prefix doesn't exist, then this will do nothing. - pathname = removePathPrefix(pathname, basePath) - } - - // Get the match for this request. - const match = this.matcher.match(pathname) - if (!match) { - throw new Error( - `Invariant: no match found for request. Pathname '${pathname}' should have matched '${this.matcher.definition.pathname}'` - ) - } + const { params } = utils.normalizeDynamicRouteParams( + Object.fromEntries(request.nextUrl.searchParams) + ) const prerenderManifest: PrerenderManifest | undefined = typeof self.__PRERENDER_MANIFEST === 'string' @@ -95,7 +89,7 @@ export class EdgeRouteModuleWrapper { // Create the context for the handler. This contains the params from the // match (if any). const context: AppRouteRouteHandlerContext = { - params: match.params, + params, prerenderManifest: { version: 4, routes: {}, diff --git a/test/e2e/app-dir/edge-route-rewrite/app/dynamic/[slug]/route.ts b/test/e2e/app-dir/edge-route-rewrite/app/dynamic/[slug]/route.ts new file mode 100644 index 0000000000000..70baa7bac15a8 --- /dev/null +++ b/test/e2e/app-dir/edge-route-rewrite/app/dynamic/[slug]/route.ts @@ -0,0 +1,8 @@ +export const runtime = 'edge' +export const dynamic = 'force-dynamic' + +export function GET(req, { params }) { + return new Response( + `Hello from /app/dynamic/[slug]/route.ts. Slug: ${params.slug}` + ) +} diff --git a/test/e2e/app-dir/edge-route-rewrite/app/layout.tsx b/test/e2e/app-dir/edge-route-rewrite/app/layout.tsx new file mode 100644 index 0000000000000..a14e64fcd5e33 --- /dev/null +++ b/test/e2e/app-dir/edge-route-rewrite/app/layout.tsx @@ -0,0 +1,16 @@ +export const metadata = { + title: 'Next.js', + description: 'Generated by Next.js', +} + +export default function RootLayout({ + children, +}: { + children: React.ReactNode +}) { + return ( + + {children} + + ) +} diff --git a/test/e2e/app-dir/edge-route-rewrite/app/two/example/route.ts b/test/e2e/app-dir/edge-route-rewrite/app/two/example/route.ts new file mode 100644 index 0000000000000..b9d99d3ebf74f --- /dev/null +++ b/test/e2e/app-dir/edge-route-rewrite/app/two/example/route.ts @@ -0,0 +1,6 @@ +export const runtime = 'edge' +export const dynamic = 'force-dynamic' + +export function GET() { + return new Response('Hello from /app/two/example/route.ts') +} diff --git a/test/e2e/app-dir/edge-route-rewrite/edge-route-rewrite.test.ts b/test/e2e/app-dir/edge-route-rewrite/edge-route-rewrite.test.ts new file mode 100644 index 0000000000000..f27a6c029d9a7 --- /dev/null +++ b/test/e2e/app-dir/edge-route-rewrite/edge-route-rewrite.test.ts @@ -0,0 +1,21 @@ +import { createNextDescribe } from 'e2e-utils' + +createNextDescribe( + 'edge-route-rewrite', + { + files: __dirname, + }, + ({ next }) => { + it('it should support a rewrite to an edge route', async () => { + const result = await next.render('/one/example') + expect(result).toContain('Hello from /app/two/example/route.ts') + }) + + it('it should support a rewrite to a dynamic edge route', async () => { + const result = await next.render('/dynamic-test/foo') + expect(result).toContain( + 'Hello from /app/dynamic/[slug]/route.ts. Slug: foo' + ) + }) + } +) diff --git a/test/e2e/app-dir/edge-route-rewrite/middleware.ts b/test/e2e/app-dir/edge-route-rewrite/middleware.ts new file mode 100644 index 0000000000000..b6a57a20e4f34 --- /dev/null +++ b/test/e2e/app-dir/edge-route-rewrite/middleware.ts @@ -0,0 +1,21 @@ +import { type NextRequest, NextResponse } from 'next/server' + +export function middleware(request: NextRequest) { + const url = request.nextUrl + + let originalPathname = url.pathname + + if (url.pathname.includes('/one')) { + url.pathname = '/two/example' + } else if (url.pathname.includes('/dynamic-test')) { + url.pathname = '/dynamic/foo' + } + + if (url.pathname !== originalPathname) { + return NextResponse.rewrite(url) + } +} + +export const config = { + matcher: ['/one/:path*', '/dynamic-test/:path*'], +} diff --git a/test/e2e/app-dir/edge-route-rewrite/next.config.js b/test/e2e/app-dir/edge-route-rewrite/next.config.js new file mode 100644 index 0000000000000..807126e4cf0bf --- /dev/null +++ b/test/e2e/app-dir/edge-route-rewrite/next.config.js @@ -0,0 +1,6 @@ +/** + * @type {import('next').NextConfig} + */ +const nextConfig = {} + +module.exports = nextConfig From 31809e42f512a6e1482b709ef94fd5191ca5c240 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Thu, 23 Nov 2023 13:42:20 +0800 Subject: [PATCH 027/481] Polish unsupported metadata warning with doc link (#58750) * Add docs link to the warning, add codemod link to viewport docs section * Only log the warning once after the metadata resolving process, this will avoid multiple duplicated logs showing for one page. Closes NEXT-1723 --- .../04-functions/generate-viewport.mdx | 1 + .../next/src/lib/metadata/resolve-metadata.ts | 21 +++++- .../app/unsupported-metadata/page.js | 7 ++ .../index.test.ts | 71 +++++++++++-------- 4 files changed, 68 insertions(+), 32 deletions(-) create mode 100644 test/e2e/app-dir/metadata-missing-metadata-base/app/unsupported-metadata/page.js diff --git a/docs/02-app/02-api-reference/04-functions/generate-viewport.mdx b/docs/02-app/02-api-reference/04-functions/generate-viewport.mdx index 21d636bc5612e..0662a5b3f5c23 100644 --- a/docs/02-app/02-api-reference/04-functions/generate-viewport.mdx +++ b/docs/02-app/02-api-reference/04-functions/generate-viewport.mdx @@ -15,6 +15,7 @@ You can customize the initial viewport of the page with the static `viewport` ob > > - The `viewport` object and `generateViewport` function exports are **only supported in Server Components**. > - You cannot export both the `viewport` object and `generateViewport` function from the same route segment. +> - If you're coming from migrating `metadata` exports, you can use [metadata-to-viewport-export codemod](/docs/app/building-your-application/upgrading/codemods#metadata-to-viewport-export) to update your changes. ## The `viewport` object diff --git a/packages/next/src/lib/metadata/resolve-metadata.ts b/packages/next/src/lib/metadata/resolve-metadata.ts index c5e02d52da734..ddfc2a2b77d0a 100644 --- a/packages/next/src/lib/metadata/resolve-metadata.ts +++ b/packages/next/src/lib/metadata/resolve-metadata.ts @@ -63,6 +63,10 @@ type TitleTemplates = { openGraph: string | null } +type BuildState = { + warnings: Set +} + function hasIconsProperty( icons: Metadata['icons'], prop: 'icon' | 'apple' @@ -135,12 +139,14 @@ function mergeMetadata({ staticFilesMetadata, titleTemplates, metadataContext, + buildState, }: { source: Metadata | null target: ResolvedMetadata staticFilesMetadata: StaticMetadata titleTemplates: TitleTemplates metadataContext: MetadataContext + buildState: BuildState }): void { // If there's override metadata, prefer it otherwise fallback to the default metadata. const metadataBase = @@ -244,8 +250,8 @@ function mergeMetadata({ key === 'themeColor' || key === 'colorScheme' ) { - Log.warn( - `Unsupported metadata ${key} is configured in metadata export. Please move it to viewport export instead.` + buildState.warnings.add( + `Unsupported metadata ${key} is configured in metadata export in ${metadataContext.pathname}. Please move it to viewport export instead.\nRead more: https://nextjs.org/docs/app/api-reference/functions/generate-viewport` ) } break @@ -685,6 +691,9 @@ export async function accumulateMetadata( resolvers: [], resolvingIndex: 0, } + const buildState = { + warnings: new Set(), + } for (let i = 0; i < metadataItems.length; i++) { const staticFilesMetadata = metadataItems[i][1] @@ -703,6 +712,7 @@ export async function accumulateMetadata( metadataContext, staticFilesMetadata, titleTemplates, + buildState, }) // If the layout is the same layer with page, skip the leaf layout and leaf page @@ -716,6 +726,13 @@ export async function accumulateMetadata( } } + // Only log warnings if there are any, and only once after the metadata resolving process is finished + if (buildState.warnings.size > 0) { + for (const warning of buildState.warnings) { + Log.warn(warning) + } + } + return postProcessMetadata(resolvedMetadata, titleTemplates) } diff --git a/test/e2e/app-dir/metadata-missing-metadata-base/app/unsupported-metadata/page.js b/test/e2e/app-dir/metadata-missing-metadata-base/app/unsupported-metadata/page.js new file mode 100644 index 0000000000000..80d1bbc0e0783 --- /dev/null +++ b/test/e2e/app-dir/metadata-missing-metadata-base/app/unsupported-metadata/page.js @@ -0,0 +1,7 @@ +export default function Page() { + return 'unsupported metadata' +} + +export const metadata = { + themeColor: 'light', +} diff --git a/test/e2e/app-dir/metadata-missing-metadata-base/index.test.ts b/test/e2e/app-dir/metadata-missing-metadata-base/index.test.ts index 7c2406cd216e7..5b9ae08d06c72 100644 --- a/test/e2e/app-dir/metadata-missing-metadata-base/index.test.ts +++ b/test/e2e/app-dir/metadata-missing-metadata-base/index.test.ts @@ -1,34 +1,45 @@ -import { createNext, FileRef } from 'e2e-utils' -import { NextInstance } from 'test/lib/next-modes/base' -import { fetchViaHTTP, findPort } from 'next-test-utils' +import { createNextDescribe } from 'e2e-utils' +import { fetchViaHTTP } from 'next-test-utils' -describe('app dir - metadata missing metadataBase', () => { - let next: NextInstance - let port: number +createNextDescribe( + 'app dir - metadata missing metadataBase', + { + files: __dirname, + skipDeployment: true, + }, + ({ next, isNextStart }) => { + // If it's start mode, we get the whole logs since they're from build process. + // If it's dev mode, we get the logs after request + function getCliOutput(logStartPosition: number) { + return isNextStart + ? next.cliOutput + : next.cliOutput.slice(logStartPosition) + } - if ((global as any).isNextDeploy) { - return it('should skip for deploy', () => {}) - } - - beforeAll(async () => { - port = await findPort() - next = await createNext({ - skipStart: true, - files: new FileRef(__dirname), - forcedPort: port + '', + it('should fallback to localhost if metadataBase is missing for absolute urls resolving', async () => { + const logStartPosition = next.cliOutput.length + await fetchViaHTTP(next.url, '/') + // + const output = getCliOutput(logStartPosition) + expect(output).toInclude( + 'metadata.metadataBase is not set for resolving social open graph or twitter images,' + ) + expect(output).toMatch(/using "http:\/\/localhost:\d+/) + expect(output).toInclude( + '. See https://nextjs.org/docs/app/api-reference/functions/generate-metadata#metadatabase' + ) }) - }) - afterAll(() => next.destroy()) - it('should fallback to localhost if metadataBase is missing for absolute urls resolving', async () => { - await next.start() - await fetchViaHTTP(next.url, '/') - expect(next.cliOutput).toInclude( - 'metadata.metadataBase is not set for resolving social open graph or twitter images, using' - ) - expect(next.cliOutput).toInclude(`"http://localhost:${port}`) - expect(next.cliOutput).toInclude( - '. See https://nextjs.org/docs/app/api-reference/functions/generate-metadata#metadatabase' - ) - }) -}) + it('should warn for unsupported metadata properties', async () => { + const logStartPosition = next.cliOutput.length + await fetchViaHTTP(next.url, '/unsupported-metadata') + const output = getCliOutput(logStartPosition) + expect(output).toInclude( + 'Unsupported metadata themeColor is configured in metadata export in /unsupported-metadata. Please move it to viewport' + ) + expect(output).toInclude( + 'Read more: https://nextjs.org/docs/app/api-reference/functions/generate-viewport' + ) + }) + } +) From ecde250698d37ae098b285177997ca8dea12c23c Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Thu, 23 Nov 2023 13:48:08 +0100 Subject: [PATCH 028/481] make tests more stable (#58765) ### What? We need to give them a bit time to pick up the tsconfig change. Closes PACK-2019 --- test/development/jsconfig-path-reloading/index.test.ts | 2 ++ test/development/tsconfig-path-reloading/index.test.ts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/test/development/jsconfig-path-reloading/index.test.ts b/test/development/jsconfig-path-reloading/index.test.ts index 554a83ab02c1f..137d61dd9a294 100644 --- a/test/development/jsconfig-path-reloading/index.test.ts +++ b/test/development/jsconfig-path-reloading/index.test.ts @@ -43,6 +43,8 @@ describe('jsconfig-path-reloading', () => { if (addAfterStart) { await next.patchFile(tsConfigFile, tsConfigContent) + // wait a bit for the file watcher to pick up the change + await new Promise((resolve) => setTimeout(resolve, 200)) } }) afterAll(() => next.destroy()) diff --git a/test/development/tsconfig-path-reloading/index.test.ts b/test/development/tsconfig-path-reloading/index.test.ts index 551adc459d4a1..ca1e12524bec4 100644 --- a/test/development/tsconfig-path-reloading/index.test.ts +++ b/test/development/tsconfig-path-reloading/index.test.ts @@ -43,6 +43,8 @@ describe('tsconfig-path-reloading', () => { if (addAfterStart) { await next.patchFile(tsConfigFile, tsConfigContent) + // wait a bit for the file watcher to pick up the change + await new Promise((resolve) => setTimeout(resolve, 200)) } }) afterAll(() => next.destroy()) From f514684bbccc364c64eb5998beb22b7c5a6e109e Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Thu, 23 Nov 2023 15:17:36 +0100 Subject: [PATCH 029/481] Enable .mjs extension config in Turbopack (#58825) Enable `.mjs` resolving in Turbopack to match the current webpack config. Added an additional tests for this. --- .../crates/next-core/src/next_client/context.rs | 1 + .../crates/next-core/src/next_edge/context.rs | 1 + .../crates/next-core/src/next_server/context.rs | 1 + test/e2e/app-dir/mjs-as-extension/app/layout.tsx | 7 +++++++ test/e2e/app-dir/mjs-as-extension/app/page.js | 5 +++++ .../mjs-as-extension/mjs-as-extension.test.ts | 14 ++++++++++++++ test/e2e/app-dir/mjs-as-extension/my-file.mjs | 3 +++ test/e2e/app-dir/mjs-as-extension/next.config.js | 6 ++++++ 8 files changed, 38 insertions(+) create mode 100644 test/e2e/app-dir/mjs-as-extension/app/layout.tsx create mode 100644 test/e2e/app-dir/mjs-as-extension/app/page.js create mode 100644 test/e2e/app-dir/mjs-as-extension/mjs-as-extension.test.ts create mode 100644 test/e2e/app-dir/mjs-as-extension/my-file.mjs create mode 100644 test/e2e/app-dir/mjs-as-extension/next.config.js diff --git a/packages/next-swc/crates/next-core/src/next_client/context.rs b/packages/next-swc/crates/next-core/src/next_client/context.rs index 13e10f919fa0d..fd63edfcc0ee0 100644 --- a/packages/next-swc/crates/next-core/src/next_client/context.rs +++ b/packages/next-swc/crates/next-core/src/next_client/context.rs @@ -163,6 +163,7 @@ pub async fn get_client_resolve_options_context( Ok(ResolveOptionsContext { enable_typescript: true, enable_react: true, + enable_mjs_extension: true, rules: vec![( foreign_code_context_condition(next_config, project_path).await?, module_options_context.clone().cell(), diff --git a/packages/next-swc/crates/next-core/src/next_edge/context.rs b/packages/next-swc/crates/next-core/src/next_edge/context.rs index 30407a32cf563..f632b9f43cc6c 100644 --- a/packages/next-swc/crates/next-core/src/next_edge/context.rs +++ b/packages/next-swc/crates/next-core/src/next_edge/context.rs @@ -137,6 +137,7 @@ pub async fn get_edge_resolve_options_context( Ok(ResolveOptionsContext { enable_typescript: true, enable_react: true, + enable_mjs_extension: true, rules: vec![( foreign_code_context_condition(next_config, project_path).await?, resolve_options_context.clone().cell(), diff --git a/packages/next-swc/crates/next-core/src/next_server/context.rs b/packages/next-swc/crates/next-core/src/next_server/context.rs index 7641cd6b868df..9bf41b1a9e9ee 100644 --- a/packages/next-swc/crates/next-core/src/next_server/context.rs +++ b/packages/next-swc/crates/next-core/src/next_server/context.rs @@ -193,6 +193,7 @@ pub async fn get_server_resolve_options_context( Ok(ResolveOptionsContext { enable_typescript: true, enable_react: true, + enable_mjs_extension: true, rules: vec![( foreign_code_context_condition, resolve_options_context.clone().cell(), diff --git a/test/e2e/app-dir/mjs-as-extension/app/layout.tsx b/test/e2e/app-dir/mjs-as-extension/app/layout.tsx new file mode 100644 index 0000000000000..e7077399c03ce --- /dev/null +++ b/test/e2e/app-dir/mjs-as-extension/app/layout.tsx @@ -0,0 +1,7 @@ +export default function Root({ children }: { children: React.ReactNode }) { + return ( + + {children} + + ) +} diff --git a/test/e2e/app-dir/mjs-as-extension/app/page.js b/test/e2e/app-dir/mjs-as-extension/app/page.js new file mode 100644 index 0000000000000..489d9a5419b67 --- /dev/null +++ b/test/e2e/app-dir/mjs-as-extension/app/page.js @@ -0,0 +1,5 @@ +import { myFileFunction } from '../my-file' + +export default function Page() { + return

{myFileFunction()}

+} diff --git a/test/e2e/app-dir/mjs-as-extension/mjs-as-extension.test.ts b/test/e2e/app-dir/mjs-as-extension/mjs-as-extension.test.ts new file mode 100644 index 0000000000000..7b1448e5576a8 --- /dev/null +++ b/test/e2e/app-dir/mjs-as-extension/mjs-as-extension.test.ts @@ -0,0 +1,14 @@ +import { createNextDescribe } from 'e2e-utils' + +createNextDescribe( + 'mjs as extension', + { + files: __dirname, + }, + ({ next }) => { + it('should render the page correctly', async () => { + const $ = await next.render$('/') + expect($('p').text()).toBe('hello world!') + }) + } +) diff --git a/test/e2e/app-dir/mjs-as-extension/my-file.mjs b/test/e2e/app-dir/mjs-as-extension/my-file.mjs new file mode 100644 index 0000000000000..721672892a96b --- /dev/null +++ b/test/e2e/app-dir/mjs-as-extension/my-file.mjs @@ -0,0 +1,3 @@ +export function myFileFunction() { + return 'hello world!' +} diff --git a/test/e2e/app-dir/mjs-as-extension/next.config.js b/test/e2e/app-dir/mjs-as-extension/next.config.js new file mode 100644 index 0000000000000..807126e4cf0bf --- /dev/null +++ b/test/e2e/app-dir/mjs-as-extension/next.config.js @@ -0,0 +1,6 @@ +/** + * @type {import('next').NextConfig} + */ +const nextConfig = {} + +module.exports = nextConfig From 8bdda745fbfc13aa07101bedb5d31e7bf2b16a4a Mon Sep 17 00:00:00 2001 From: Leah Date: Thu, 23 Nov 2023 15:18:03 +0100 Subject: [PATCH 030/481] chore(CI): improve datadog reporting (#58267) --- .github/workflows/build_and_deploy.yml | 19 +++++---- .github/workflows/build_and_test.yml | 29 ++++++++++--- .github/workflows/build_reusable.yml | 34 +++------------ .github/workflows/nextjs-integration-test.yml | 41 +++++++------------ .github/workflows/test_e2e_deploy.yml | 17 ++++---- jest.config.js | 13 +++--- 6 files changed, 68 insertions(+), 85 deletions(-) diff --git a/.github/workflows/build_and_deploy.yml b/.github/workflows/build_and_deploy.yml index 4d6203dd81371..583a5c0be50f5 100644 --- a/.github/workflows/build_and_deploy.yml +++ b/.github/workflows/build_and_deploy.yml @@ -301,12 +301,12 @@ jobs: - name: 'check build cache status' id: check-did-build - run: if [[ ! -z $(ls packages/next-swc/native) ]]; then echo "DID_BUILD=yup" >> $GITHUB_OUTPUT; fi + run: if [[ ! -z $(ls packages/next-swc/native) ]]; then echo "DID_BUILD=true" >> $GITHUB_OUTPUT; fi - # Trying to upload metrics for the Turbopack to datadog's CI pipeline execution + # Try to upload metrics for Turbopack to datadog's CI pipeline execution - name: 'Collect turbopack build metrics' id: check-turbopack-bytesize - if: ${{ steps.check-did-build.outputs.DID_BUILD == 'yup' }} + if: ${{ steps.check-did-build.outputs.DID_BUILD == 'true' }} continue-on-error: true run: | mkdir -p ./turbopack-bin-size @@ -322,7 +322,7 @@ jobs: done - name: Upload turbopack bytesize artifact - if: ${{ steps.check-did-build.outputs.DID_BUILD == 'yup' }} + if: ${{ steps.check-did-build.outputs.DID_BUILD == 'true' }} uses: actions/upload-artifact@v3 with: name: turbopack-bytesize @@ -492,23 +492,26 @@ jobs: NEXT_SKIP_NATIVE_POSTINSTALL: 1 upload_turbopack_bytesize: - name: Upload Turbopack Bytesize trace to Datadog + name: Upload Turbopack Bytesize metrics to Datadog runs-on: ubuntu-latest needs: [build-native] env: DATADOG_API_KEY: ${{ secrets.DATA_DOG_API_KEY }} steps: - - name: Collect bytesize traces + - name: Collect bytesize metrics uses: actions/download-artifact@v3 with: name: turbopack-bytesize path: turbopack-bin-size + - name: Upload to Datadog run: | ls -al turbopack-bin-size - npm install -g @datadog/datadog-ci@2.14.0 @aws-sdk/property-provider@3 + for filename in turbopack-bin-size/*; do export BYTESIZE+=" --metrics $(cat $filename)" done + echo "Reporting $BYTESIZE" - datadog-ci metric --no-fail --level pipeline $BYTESIZE + + npx @datadog/datadog-ci@2.23.1 metric --no-fail --level pipeline $BYTESIZE diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index fee01652130e7..b1534867b9f19 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -22,7 +22,7 @@ env: # canary next-swc binaries in the monorepo NEXT_SKIP_NATIVE_POSTINSTALL: 1 DATADOG_API_KEY: ${{ secrets.DATA_DOG_API_KEY }} - DATADOG_TRACE_NEXTJS_TEST: 'true' + NEXT_JUNIT_TEST_REPORT: 'true' DD_ENV: 'ci' TEST_TIMINGS_TOKEN: ${{ secrets.TEST_TIMINGS_TOKEN }} NEXT_TEST_JOB: 1 @@ -240,11 +240,28 @@ jobs: 'test-turbopack-dev', 'test-turbopack-integration', ] - uses: ./.github/workflows/build_reusable.yml - with: - skipForDocsOnly: 'yes' - uploadTestTrace: 'yes' - secrets: inherit + if: always() + runs-on: ubuntu-latest + name: report test results to datadog + steps: + - name: Download test report artifacts + id: download-test-reports + uses: actions/download-artifact@v3 + with: + name: test-reports + path: test + + - name: Upload test report to datadog + run: | + if [ -d ./test/test-junit-report ]; then + # Add a `test.type` tag to distinguish between turbopack and next.js runs + DD_ENV=ci npx @datadog/datadog-ci@2.23.1 junit upload --tags test.type:nextjs --service nextjs ./test/test-junit-report + fi + + if [ -d ./test/turbopack-test-junit-report ]; then + # Add a `test.type` tag to distinguish between turbopack and next.js runs + DD_ENV=ci npx @datadog/datadog-ci@2.23.1 junit upload --tags test.type:turbopack --service nextjs ./test/turbopack-test-junit-report + fi tests-pass: needs: diff --git a/.github/workflows/build_reusable.yml b/.github/workflows/build_reusable.yml index 9b4e6cb8074a1..f6dd49fc5b386 100644 --- a/.github/workflows/build_reusable.yml +++ b/.github/workflows/build_reusable.yml @@ -49,10 +49,6 @@ on: required: false description: 'if swc artifact needs uploading' type: string - uploadTestTrace: - required: false - description: 'if test trace needs uploading' - type: string rustCacheKey: required: false description: 'rustCacheKey to cache shared target assets' @@ -73,7 +69,7 @@ env: # canary next-swc binaries in the monorepo NEXT_SKIP_NATIVE_POSTINSTALL: 1 DATADOG_API_KEY: ${{ secrets.DATA_DOG_API_KEY }} - DATADOG_TRACE_NEXTJS_TEST: 'true' + NEXT_JUNIT_TEST_REPORT: 'true' DD_ENV: 'ci' TEST_TIMINGS_TOKEN: ${{ secrets.TEST_TIMINGS_TOKEN }} NEXT_TEST_JOB: 1 @@ -187,6 +183,7 @@ jobs: with: name: turbo run summary path: .turbo/runs + if-no-files-found: ignore - name: Upload bundle analyzer artifacts uses: actions/upload-artifact@v3 @@ -195,33 +192,12 @@ jobs: name: webpack bundle analysis stats path: packages/next/dist/compiled/next-server/report.*.html - - name: Upload test reports artifact + - name: Upload test report artifacts uses: actions/upload-artifact@v3 - if: ${{ inputs.afterBuild }} + if: ${{ inputs.afterBuild && always() }} with: - name: Test trace reports + name: test-reports path: | test/test-junit-report test/turbopack-test-junit-report if-no-files-found: ignore - - - name: Download test reports artifact - id: download-test-reports - uses: actions/download-artifact@v3 - continue-on-error: true - if: ${{ inputs.uploadTestTrace == 'yes' && (inputs.skipForDocsOnly != 'yes' || steps.docs-change.outputs.DOCS_CHANGE == 'nope') }} - with: - name: Test trace reports - path: test - - - name: Upload test trace to datadog - if: ${{ inputs.uploadTestTrace == 'yes' && (inputs.skipForDocsOnly != 'yes' || steps.docs-change.outputs.DOCS_CHANGE == 'nope') }} - continue-on-error: true - run: | - ls -al ./test - npm install -g junit-report-merger@6.0.2 @datadog/datadog-ci@2.14.0 @aws-sdk/property-provider@3 - jrm ./nextjs-test-result-junit.xml "test/test-junit-report/**/*.xml" - jrm ./turbopack-test-result-junit.xml "test/turbopack-test-junit-report/**/*.xml" - # Put a separate tag for the tests with turbopack to distinguish between same test names - DD_ENV=ci datadog-ci junit upload --tags test.type:nextjs --service nextjs ./nextjs-test-result-junit.xml - DD_ENV=ci datadog-ci junit upload --tags test.type:turbopack --service nextjs ./turbopack-test-result-junit.xml diff --git a/.github/workflows/nextjs-integration-test.yml b/.github/workflows/nextjs-integration-test.yml index 5618739d72c71..e2cde60a66de4 100644 --- a/.github/workflows/nextjs-integration-test.yml +++ b/.github/workflows/nextjs-integration-test.yml @@ -30,7 +30,7 @@ env: NEXT_TELEMETRY_DISABLED: 1 TEST_CONCURRENCY: 6 DATADOG_API_KEY: ${{ secrets.DATA_DOG_API_KEY }} - DATADOG_TRACE_NEXTJS_TEST: 'true' + NEXT_JUNIT_TEST_REPORT: 'true' DD_ENV: 'ci' # Turbopack specific customization for the test runner TURBOPACK: 1 @@ -96,10 +96,10 @@ jobs: # marker to parse log output, do not delete / change. NEXT_INTEGRATION_TEST: true - - name: Upload test reports artifact + - name: Upload test report artifacts uses: actions/upload-artifact@v3 with: - name: Test trace reports + name: test-reports path: | test/turbopack-test-junit-report @@ -140,10 +140,10 @@ jobs: env: NEXT_INTEGRATION_TEST: true - - name: Upload test reports artifact + - name: Upload test report artifacts uses: actions/upload-artifact@v3 with: - name: Test trace reports + name: test-reports path: | test/turbopack-test-junit-report @@ -183,9 +183,9 @@ jobs: passed-test-path-list.json slack-payload.json - upload_test_trace: + upload_test_report: needs: [test-dev, test-integration] - name: Upload test trace to datadog + name: Upload test report to datadog runs-on: - 'self-hosted' - 'linux' @@ -194,27 +194,14 @@ jobs: if: always() steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Download test reports artifact + - name: Download test report artifacts id: download-test-reports uses: actions/download-artifact@v3 with: - name: Test trace reports - path: test - - name: Upload test trace to datadog + name: test-reports + path: test/reports + + - name: Upload to datadog run: | - npm install -g @datadog/datadog-ci@2.18.1 - ls -al ./test/*.xml - # We'll tag this to the Turbopack service, not the next.js - DD_ENV=ci datadog-ci junit upload --tags test.type:turbopack.daily --service Turbopack test - - # For the debugging purpose, upload the test trace to github artifact. - # So we can manually analyze test reports. - - name: Upload test reports artifact - uses: actions/upload-artifact@v3 - with: - name: Merged test trace reports - path: | - nextjs-test-result-junit.xml - ./**/*.xml + # We'll tag this to the "Turbopack" datadog service, not "nextjs" + DD_ENV=ci npx @datadog/datadog-ci@2.23.1 junit upload --tags test.type:turbopack.daily --service Turbopack ./test/report diff --git a/.github/workflows/test_e2e_deploy.yml b/.github/workflows/test_e2e_deploy.yml index c906b4487afae..91b8a8fdf666b 100644 --- a/.github/workflows/test_e2e_deploy.yml +++ b/.github/workflows/test_e2e_deploy.yml @@ -50,23 +50,22 @@ jobs: - run: RESET_VC_PROJECT=true node scripts/reset-vercel-project.mjs name: Reset test project - - run: docker run --rm -v $(pwd):/work mcr.microsoft.com/playwright:v1.35.1-jammy /bin/bash -c "cd /work && NODE_VERSION=${{ env.NODE_LTS_VERSION }} ./scripts/setup-node.sh && corepack enable > /dev/null && DATADOG_TRACE_NEXTJS_TEST=TRUE DATADOG_API_KEY=${DATADOG_API_KEY} DD_ENV=ci VERCEL_TEST_TOKEN=${{ secrets.VERCEL_TEST_TOKEN }} VERCEL_TEST_TEAM=vtest314-next-e2e-tests NEXT_TEST_JOB=1 NEXT_TEST_MODE=deploy TEST_TIMINGS_TOKEN=${{ secrets.TEST_TIMINGS_TOKEN }} NEXT_TEST_CONTINUE_ON_ERROR=1 xvfb-run node run-tests.js --type e2e --timings -g ${{ matrix.group }}/2 -c 1 >> /proc/1/fd/1" + - run: docker run --rm -v $(pwd):/work mcr.microsoft.com/playwright:v1.35.1-jammy /bin/bash -c "cd /work && NODE_VERSION=${{ env.NODE_LTS_VERSION }} ./scripts/setup-node.sh && corepack enable > /dev/null && NEXT_JUNIT_TEST_REPORT=true DATADOG_API_KEY=${DATADOG_API_KEY} DD_ENV=ci VERCEL_TEST_TOKEN=${{ secrets.VERCEL_TEST_TOKEN }} VERCEL_TEST_TEAM=vtest314-next-e2e-tests NEXT_TEST_JOB=1 NEXT_TEST_MODE=deploy TEST_TIMINGS_TOKEN=${{ secrets.TEST_TIMINGS_TOKEN }} NEXT_TEST_CONTINUE_ON_ERROR=1 xvfb-run node run-tests.js --type e2e --timings -g ${{ matrix.group }}/2 -c 1 >> /proc/1/fd/1" name: Run test/e2e (deploy) - - name: Upload test trace + - name: Upload test report if: always() uses: actions/upload-artifact@v3 with: - name: test-trace + name: test-reports if-no-files-found: ignore retention-days: 2 path: | - test/traces + test/test-junit-report - - name: Upload test trace to datadog + - name: Upload test report to datadog continue-on-error: true run: | - ls -al ./test - npm install -g junit-report-merger@6.0.2 @datadog/datadog-ci@2.14.0 @aws-sdk/property-provider@3 - jrm ./nextjs-test-result-junit.xml "test/test-junit-report/**/*.xml" - DD_ENV=ci datadog-ci junit upload --tags test.type:nextjs_deploy_e2e --service nextjs ./nextjs-test-result-junit.xml + ls -al ./test/*junit + + DD_ENV=ci npx @datadog/datadog-ci@2.23.1 junit upload --tags test.type:nextjs_deploy_e2e --service nextjs ./test/test-junit-report diff --git a/jest.config.js b/jest.config.js index 903096c475f7b..d269f86b57147 100644 --- a/jest.config.js +++ b/jest.config.js @@ -22,14 +22,14 @@ const customJestConfig = { }, } -// Check if the environment variable is set to enable test trace, +// Check if the environment variable is set to enable test report, // Insert a reporter to generate a junit report to upload. -// This won't count for the retry to avoid duplicated test being reported twice -// - which means our test trace will report test results for the flaky test as failed without retry. -const shouldEnableTestTrace = - process.env.DATADOG_API_KEY && process.env.DATADOG_TRACE_NEXTJS_TEST +// +// This won't count retries to avoid tests being reported twice. +// Our test report will report test results for flaky tests as failed without retry. +const enableTestReport = !!process.env.NEXT_JUNIT_TEST_REPORT -if (shouldEnableTestTrace) { +if (enableTestReport) { if (!customJestConfig.reporters) { customJestConfig.reporters = ['default'] } @@ -45,6 +45,7 @@ if (shouldEnableTestTrace) { reportTestSuiteErrors: 'true', uniqueOutputName: 'true', outputName: 'nextjs-test-junit', + addFileAttribute: 'true', }, ]) } From 936becb8b6b981294623570775ebaec304f6b6bd Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Thu, 23 Nov 2023 15:15:06 +0000 Subject: [PATCH 031/481] v14.0.4-canary.12 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 16 ++++++++-------- 18 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lerna.json b/lerna.json index 9851c2f8090a4..68758100e1cfa 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.11" + "version": "14.0.4-canary.12" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index d9732a1e3efa5..47a22d1c7912b 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.11", + "version": "14.0.4-canary.12", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index a4558d4bed0d5..5f74e122503b4 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.11", + "version": "14.0.4-canary.12", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.11", + "@next/eslint-plugin-next": "14.0.4-canary.12", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index aba951d7d34b5..69d9cec714297 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.11", + "version": "14.0.4-canary.12", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index d1f45a2e401cb..a6741a09d7c5e 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.11", + "version": "14.0.4-canary.12", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 037cc389a892b..e08e9c7d2d2f7 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.11", + "version": "14.0.4-canary.12", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 0c285e41aa3bf..e5bf459a740ad 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.11", + "version": "14.0.4-canary.12", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index e51e33a291ed8..dd5077b3815b6 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.11", + "version": "14.0.4-canary.12", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index cd1354c71d9f5..a12dbd4dd1009 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.11", + "version": "14.0.4-canary.12", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index c23c05b7ea451..f001bbc418976 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.11", + "version": "14.0.4-canary.12", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index c7d7685dc8e1c..0b3cc7afe4a02 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.11", + "version": "14.0.4-canary.12", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index 7a997781d3223..bcb2030e35679 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.11", + "version": "14.0.4-canary.12", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index a726d89eb3e38..9ae05fdbe49a0 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.11", + "version": "14.0.4-canary.12", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index 9f6ae20a15414..a538bfcd827f5 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.11", + "version": "14.0.4-canary.12", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.11", + "@next/env": "14.0.4-canary.12", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -146,11 +146,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.11", - "@next/polyfill-nomodule": "14.0.4-canary.11", - "@next/react-dev-overlay": "14.0.4-canary.11", - "@next/react-refresh-utils": "14.0.4-canary.11", - "@next/swc": "14.0.4-canary.11", + "@next/polyfill-module": "14.0.4-canary.12", + "@next/polyfill-nomodule": "14.0.4-canary.12", + "@next/react-dev-overlay": "14.0.4-canary.12", + "@next/react-refresh-utils": "14.0.4-canary.12", + "@next/swc": "14.0.4-canary.12", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index a9055ae74f90d..4b3581d39ea86 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.11", + "version": "14.0.4-canary.12", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index dbcb7526e719d..e3b7cb6a0ca8c 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.11", + "version": "14.0.4-canary.12", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index af22fa8d5af5d..56fbfa0ab3ee0 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.11", + "version": "14.0.4-canary.12", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -23,7 +23,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.11", + "next": "14.0.4-canary.12", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ab27b4cd58eae..657426364aaea 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -735,7 +735,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.11 + specifier: 14.0.4-canary.12 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -800,7 +800,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.11 + specifier: 14.0.4-canary.12 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -924,19 +924,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.11 + specifier: 14.0.4-canary.12 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.11 + specifier: 14.0.4-canary.12 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.11 + specifier: 14.0.4-canary.12 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.11 + specifier: 14.0.4-canary.12 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.11 + specifier: 14.0.4-canary.12 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1587,7 +1587,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.11 + specifier: 14.0.4-canary.12 version: link:../next outdent: specifier: 0.8.0 From d53ac4efee1e5630b92fd945cb7bf86f22603814 Mon Sep 17 00:00:00 2001 From: Leah Date: Thu, 23 Nov 2023 17:45:12 +0100 Subject: [PATCH 032/481] chore(CI): add action to auto retry tests on canary and report failures after retries (#58774) ### What? Due to flaky tests CI will sometimes fail on canary, we want to retry before reporting them as broken on slack Closes PACK-2022 --- .github/workflows/retry_test.yml | 51 ++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 .github/workflows/retry_test.yml diff --git a/.github/workflows/retry_test.yml b/.github/workflows/retry_test.yml new file mode 100644 index 0000000000000..b405c5f098a7b --- /dev/null +++ b/.github/workflows/retry_test.yml @@ -0,0 +1,51 @@ +name: retry-tests + +on: + workflow_run: + workflows: ['build-and-test'] + branches: [canary] + types: + - completed + +env: + MAX_RETRIES: 3 + SLACK_WEBHOOK_URL: ${{ secrets.BROKEN_CANARY_SLACK_WEBHOOK_URL }} + +permissions: + actions: write + +jobs: + retry-on-failure: + name: retry failed jobs + if: ${{ github.event.workflow_run.conclusion == 'failure' && github.event.workflow_run.run_attempt < fromJSON(env.MAX_RETRIES) }} + runs-on: ubuntu-latest + steps: + - name: send retry request to GitHub API + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + gh api \ + --method POST \ + -H "Accept: application/vnd.github+json" \ + -H "X-GitHub-Api-Version: 2022-11-28" \ + /repos/${{ github.repository }}/actions/runs/${{ github.event.workflow_run.id }}/rerun-failed-jobs + + report-failure: + name: report failure to slack + if: ${{ github.event.workflow_run.conclusion == 'failure' && github.event.workflow_run.run_attempt >= fromJSON(env.MAX_RETRIES) }} + runs-on: ubuntu-latest + steps: + - name: send webhook + uses: slackapi/slack-github-action@v1.24.0 + with: + # These urls are intentionally missing the protocol, + # allowing them to be transformed into actual links in the Slack workflow + # (through slightly hacky means). + payload: | + { + "commit_title": "${{ github.event.workflow_run.display_title }}", + "commit_url": "github.com/${{ github.repository }}/commit/${{ github.event.workflow_run.head_sha }}", + "workflow_run_url": "github.com/${{ github.repository }}/actions/runs/${{ github.event.workflow_run.id }}/attempts/${{ github.event.workflow_run.run_attempt }}" + } + env: + SLACK_WEBHOOK_URL: ${{ env.SLACK_WEBHOOK_URL }} From cbcd59889c3ee7bdc984487a3e12f0aed4bf6d0c Mon Sep 17 00:00:00 2001 From: Zack Tanner Date: Thu, 23 Nov 2023 09:40:48 -0800 Subject: [PATCH 033/481] ci: unify reset project script (#58829) We have identical `resetProject` code used in `bench/vercel` and our e2e workflow action -- this updates the `resetProject` script to side-effects free (hence removing the env var) and shared between bench & e2e Closes NEXT-1731 --- .github/workflows/test_e2e_deploy.yml | 2 +- bench/vercel/project-utils.js | 51 ++----------------- ...t-vercel-project.mjs => reset-project.mjs} | 19 ++++--- scripts/run-project-reset.mjs | 3 ++ test/lib/next-modes/next-deploy.ts | 2 +- 5 files changed, 17 insertions(+), 60 deletions(-) rename scripts/{reset-vercel-project.mjs => reset-project.mjs} (75%) create mode 100644 scripts/run-project-reset.mjs diff --git a/.github/workflows/test_e2e_deploy.yml b/.github/workflows/test_e2e_deploy.yml index 91b8a8fdf666b..6eb40da38b8b2 100644 --- a/.github/workflows/test_e2e_deploy.yml +++ b/.github/workflows/test_e2e_deploy.yml @@ -47,7 +47,7 @@ jobs: - run: npm i -g vercel@latest - - run: RESET_VC_PROJECT=true node scripts/reset-vercel-project.mjs + - run: node scripts/run-project-reset.mjs name: Reset test project - run: docker run --rm -v $(pwd):/work mcr.microsoft.com/playwright:v1.35.1-jammy /bin/bash -c "cd /work && NODE_VERSION=${{ env.NODE_LTS_VERSION }} ./scripts/setup-node.sh && corepack enable > /dev/null && NEXT_JUNIT_TEST_REPORT=true DATADOG_API_KEY=${DATADOG_API_KEY} DD_ENV=ci VERCEL_TEST_TOKEN=${{ secrets.VERCEL_TEST_TOKEN }} VERCEL_TEST_TEAM=vtest314-next-e2e-tests NEXT_TEST_JOB=1 NEXT_TEST_MODE=deploy TEST_TIMINGS_TOKEN=${{ secrets.TEST_TIMINGS_TOKEN }} NEXT_TEST_CONTINUE_ON_ERROR=1 xvfb-run node run-tests.js --type e2e --timings -g ${{ matrix.group }}/2 -c 1 >> /proc/1/fd/1" diff --git a/bench/vercel/project-utils.js b/bench/vercel/project-utils.js index 8c78f31d78911..0a083619eb009 100644 --- a/bench/vercel/project-utils.js +++ b/bench/vercel/project-utils.js @@ -1,6 +1,5 @@ import { config } from 'dotenv' -import fetch from 'node-fetch' import execa from 'execa' import path from 'path' import url from 'url' @@ -8,6 +7,7 @@ import { generatePackageJson } from './generate-package-json.js' import { Listr } from 'listr2' import { forceCrash } from './bench.js' import { red } from '../../packages/next/dist/lib/picocolors.js' +import { resetProject } from '../../scripts/reset-project.mjs' config() @@ -36,7 +36,7 @@ export async function generateProjects() { { title: 'Resetting project', task: async () => { - await resetProject(ORIGIN_PROJECT_NAME) + await resetProject(TEST_TEAM_NAME, ORIGIN_PROJECT_NAME) }, }, { @@ -73,7 +73,7 @@ export async function generateProjects() { { title: 'Resetting project', task: async () => { - await resetProject(HEAD_PROJECT_NAME) + await resetProject(TEST_TEAM_NAME, HEAD_PROJECT_NAME) }, }, { @@ -116,51 +116,6 @@ export async function cleanupProjectFolders() { ]) } -async function resetProject(projectName) { - const deleteRes = await fetch( - `https://vercel.com/api/v8/projects/${encodeURIComponent( - projectName - )}?teamId=${TEST_TEAM_NAME}`, - { - method: 'DELETE', - headers: { - Authorization: `Bearer ${TEST_TOKEN}`, - }, - } - ) - - if (!deleteRes.ok && deleteRes.status !== 404) { - throw new Error( - `Failed to delete project got status ${ - deleteRes.status - }, ${await deleteRes.text()}` - ) - } - - const createRes = await fetch( - `https://vercel.com/api/v8/projects?teamId=${TEST_TEAM_NAME}`, - { - method: 'POST', - headers: { - 'content-type': 'application/json', - Authorization: `Bearer ${TEST_TOKEN}`, - }, - body: JSON.stringify({ - framework: 'nextjs', - name: projectName, - }), - } - ) - - if (!createRes.ok) { - throw new Error( - `Failed to create project got status ${ - createRes.status - }, ${await createRes.text()}` - ) - } -} - export async function deployProject(projectName, appFolder) { try { const vercelFlags = ['--scope', TEST_TEAM_NAME] diff --git a/scripts/reset-vercel-project.mjs b/scripts/reset-project.mjs similarity index 75% rename from scripts/reset-vercel-project.mjs rename to scripts/reset-project.mjs index 4cea33a99f681..da0344f8440b2 100644 --- a/scripts/reset-vercel-project.mjs +++ b/scripts/reset-project.mjs @@ -4,12 +4,15 @@ export const TEST_PROJECT_NAME = 'vtest314-e2e-tests' export const TEST_TEAM_NAME = process.env.VERCEL_TEST_TEAM export const TEST_TOKEN = process.env.VERCEL_TEST_TOKEN -async function resetProject() { +export async function resetProject( + teamId = TEST_TEAM_NAME, + projectName = TEST_PROJECT_NAME +) { // TODO: error/bail if existing deployments are pending const deleteRes = await fetch( `https://vercel.com/api/v8/projects/${encodeURIComponent( - TEST_PROJECT_NAME - )}?teamId=${TEST_TEAM_NAME}`, + projectName + )}?teamId=${teamId}`, { method: 'DELETE', headers: { @@ -27,7 +30,7 @@ async function resetProject() { } const createRes = await fetch( - `https://vercel.com/api/v8/projects?teamId=${TEST_TEAM_NAME}`, + `https://vercel.com/api/v8/projects?teamId=${teamId}`, { method: 'POST', headers: { @@ -36,7 +39,7 @@ async function resetProject() { }, body: JSON.stringify({ framework: 'nextjs', - name: TEST_PROJECT_NAME, + name: projectName, }), } ) @@ -50,10 +53,6 @@ async function resetProject() { } console.log( - `Successfully created fresh Vercel project ${TEST_TEAM_NAME}/${TEST_PROJECT_NAME}` + `Successfully created fresh Vercel project ${teamId}/${projectName}` ) } - -if (process.env.RESET_VC_PROJECT) { - resetProject().catch(console.error) -} diff --git a/scripts/run-project-reset.mjs b/scripts/run-project-reset.mjs new file mode 100644 index 0000000000000..3509b09b907b0 --- /dev/null +++ b/scripts/run-project-reset.mjs @@ -0,0 +1,3 @@ +import { resetProject } from './reset-project.mjs' + +resetProject().catch(console.error) diff --git a/test/lib/next-modes/next-deploy.ts b/test/lib/next-modes/next-deploy.ts index 71cf2c2cb09c2..73257bbc530fa 100644 --- a/test/lib/next-modes/next-deploy.ts +++ b/test/lib/next-modes/next-deploy.ts @@ -7,7 +7,7 @@ import { TEST_PROJECT_NAME, TEST_TEAM_NAME, TEST_TOKEN, -} from '../../../scripts/reset-vercel-project.mjs' +} from '../../../scripts/reset-project.mjs' import fetch from 'node-fetch' import { Span } from 'next/src/trace' From 0cb1c404005de79b8cfbf3eac97e90616d5d4f45 Mon Sep 17 00:00:00 2001 From: Zack Tanner Date: Thu, 23 Nov 2023 09:41:34 -0800 Subject: [PATCH 034/481] ci: disable deployment protection for e2e test project (#58830) Since we reset the test project on every e2e CI run, deployment protection is automatically enabled by default. This adds an option to the reset project workflow to disable deployment protection. Our test runners need to be able to hit these pages from an unauthenticated browser in order for the tests to work. Verified tests are running properly in [this run](https://github.com/vercel/next.js/actions/runs/6971348806/job/18971225559) (fixing any failing tests themselves are out of scope for this PR; will evaluate once the run finishes) Closes NEXT-1732 --- .github/workflows/test_e2e_deploy.yml | 2 +- bench/vercel/project-utils.js | 12 +++++-- scripts/reset-project.mjs | 44 +++++++++++++++++++++++--- scripts/run-e2e-test-project-reset.mjs | 11 +++++++ scripts/run-project-reset.mjs | 3 -- 5 files changed, 62 insertions(+), 10 deletions(-) create mode 100644 scripts/run-e2e-test-project-reset.mjs delete mode 100644 scripts/run-project-reset.mjs diff --git a/.github/workflows/test_e2e_deploy.yml b/.github/workflows/test_e2e_deploy.yml index 6eb40da38b8b2..cff07b45f7121 100644 --- a/.github/workflows/test_e2e_deploy.yml +++ b/.github/workflows/test_e2e_deploy.yml @@ -47,7 +47,7 @@ jobs: - run: npm i -g vercel@latest - - run: node scripts/run-project-reset.mjs + - run: node scripts/run-e2e-test-project-reset.mjs name: Reset test project - run: docker run --rm -v $(pwd):/work mcr.microsoft.com/playwright:v1.35.1-jammy /bin/bash -c "cd /work && NODE_VERSION=${{ env.NODE_LTS_VERSION }} ./scripts/setup-node.sh && corepack enable > /dev/null && NEXT_JUNIT_TEST_REPORT=true DATADOG_API_KEY=${DATADOG_API_KEY} DD_ENV=ci VERCEL_TEST_TOKEN=${{ secrets.VERCEL_TEST_TOKEN }} VERCEL_TEST_TEAM=vtest314-next-e2e-tests NEXT_TEST_JOB=1 NEXT_TEST_MODE=deploy TEST_TIMINGS_TOKEN=${{ secrets.TEST_TIMINGS_TOKEN }} NEXT_TEST_CONTINUE_ON_ERROR=1 xvfb-run node run-tests.js --type e2e --timings -g ${{ matrix.group }}/2 -c 1 >> /proc/1/fd/1" diff --git a/bench/vercel/project-utils.js b/bench/vercel/project-utils.js index 0a083619eb009..088b9d0370040 100644 --- a/bench/vercel/project-utils.js +++ b/bench/vercel/project-utils.js @@ -36,7 +36,11 @@ export async function generateProjects() { { title: 'Resetting project', task: async () => { - await resetProject(TEST_TEAM_NAME, ORIGIN_PROJECT_NAME) + await resetProject({ + teamId: TEST_TEAM_NAME, + projectName: ORIGIN_PROJECT_NAME, + disableDeploymentProtection: true, + }) }, }, { @@ -73,7 +77,11 @@ export async function generateProjects() { { title: 'Resetting project', task: async () => { - await resetProject(TEST_TEAM_NAME, HEAD_PROJECT_NAME) + await resetProject({ + teamId: TEST_TEAM_NAME, + projectName: HEAD_PROJECT_NAME, + disableDeploymentProtection: true, + }) }, }, { diff --git a/scripts/reset-project.mjs b/scripts/reset-project.mjs index da0344f8440b2..1d96704002dbd 100644 --- a/scripts/reset-project.mjs +++ b/scripts/reset-project.mjs @@ -4,10 +4,12 @@ export const TEST_PROJECT_NAME = 'vtest314-e2e-tests' export const TEST_TEAM_NAME = process.env.VERCEL_TEST_TEAM export const TEST_TOKEN = process.env.VERCEL_TEST_TOKEN -export async function resetProject( +export async function resetProject({ teamId = TEST_TEAM_NAME, - projectName = TEST_PROJECT_NAME -) { + projectName = TEST_PROJECT_NAME, + disableDeploymentProtection, +}) { + console.log(`Resetting project ${teamId}/${projectName}`) // TODO: error/bail if existing deployments are pending const deleteRes = await fetch( `https://vercel.com/api/v8/projects/${encodeURIComponent( @@ -46,12 +48,46 @@ export async function resetProject( if (!createRes.ok) { throw new Error( - `Failed to create project got status ${ + `Failed to create project. Got status: ${ createRes.status }, ${await createRes.text()}` ) } + const { id: projectId } = await createRes.json() + + if (!projectId) { + throw new Error("Couldn't get projectId from create project response") + } + + if (disableDeploymentProtection) { + console.log('Disabling deployment protection...') + + const patchRes = await fetch( + `https://vercel.com/api/v8/projects/${encodeURIComponent( + projectId + )}?teamId=${teamId}`, + { + method: 'PATCH', + headers: { + 'content-type': 'application/json', + Authorization: `Bearer ${TEST_TOKEN}`, + }, + body: JSON.stringify({ + ssoProtection: null, + }), + } + ) + + if (!patchRes.ok) { + throw new Error( + `Failed to disable deployment protection. Got status: ${ + patchRes.status + }, ${await patchRes.text()}` + ) + } + } + console.log( `Successfully created fresh Vercel project ${teamId}/${projectName}` ) diff --git a/scripts/run-e2e-test-project-reset.mjs b/scripts/run-e2e-test-project-reset.mjs new file mode 100644 index 0000000000000..558e2ed943aad --- /dev/null +++ b/scripts/run-e2e-test-project-reset.mjs @@ -0,0 +1,11 @@ +import { + resetProject, + TEST_PROJECT_NAME, + TEST_TEAM_NAME, +} from './reset-project.mjs' + +resetProject({ + projectName: TEST_PROJECT_NAME, + teamId: TEST_TEAM_NAME, + disableDeploymentProtection: true, +}).catch(console.error) diff --git a/scripts/run-project-reset.mjs b/scripts/run-project-reset.mjs deleted file mode 100644 index 3509b09b907b0..0000000000000 --- a/scripts/run-project-reset.mjs +++ /dev/null @@ -1,3 +0,0 @@ -import { resetProject } from './reset-project.mjs' - -resetProject().catch(console.error) From f6babb4273a837ad417a6b1f78c81e6e6ec98a28 Mon Sep 17 00:00:00 2001 From: Leah Date: Thu, 23 Nov 2023 20:02:41 +0100 Subject: [PATCH 035/481] fix(CI): retry-test action can't use env in `if` (#58838) --- .github/workflows/retry_test.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/retry_test.yml b/.github/workflows/retry_test.yml index b405c5f098a7b..a766f56b02ecc 100644 --- a/.github/workflows/retry_test.yml +++ b/.github/workflows/retry_test.yml @@ -8,7 +8,6 @@ on: - completed env: - MAX_RETRIES: 3 SLACK_WEBHOOK_URL: ${{ secrets.BROKEN_CANARY_SLACK_WEBHOOK_URL }} permissions: @@ -17,7 +16,7 @@ permissions: jobs: retry-on-failure: name: retry failed jobs - if: ${{ github.event.workflow_run.conclusion == 'failure' && github.event.workflow_run.run_attempt < fromJSON(env.MAX_RETRIES) }} + if: ${{ github.event.workflow_run.conclusion == 'failure' && github.event.workflow_run.run_attempt < 3 }} runs-on: ubuntu-latest steps: - name: send retry request to GitHub API @@ -32,7 +31,7 @@ jobs: report-failure: name: report failure to slack - if: ${{ github.event.workflow_run.conclusion == 'failure' && github.event.workflow_run.run_attempt >= fromJSON(env.MAX_RETRIES) }} + if: ${{ github.event.workflow_run.conclusion == 'failure' && github.event.workflow_run.run_attempt >= 3 }} runs-on: ubuntu-latest steps: - name: send webhook From 6bfd1458b2913239779f810d93ee13bb14e98076 Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Thu, 23 Nov 2023 23:22:46 +0000 Subject: [PATCH 036/481] v14.0.4-canary.13 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 16 ++++++++-------- 18 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lerna.json b/lerna.json index 68758100e1cfa..26cfce1bde1de 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.12" + "version": "14.0.4-canary.13" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 47a22d1c7912b..9b34a0bd53e21 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.12", + "version": "14.0.4-canary.13", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 5f74e122503b4..4b5cb12664f07 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.12", + "version": "14.0.4-canary.13", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.12", + "@next/eslint-plugin-next": "14.0.4-canary.13", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 69d9cec714297..3354e1e5dd805 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.12", + "version": "14.0.4-canary.13", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index a6741a09d7c5e..9126c2556d51e 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.12", + "version": "14.0.4-canary.13", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index e08e9c7d2d2f7..a36ee3dba4322 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.12", + "version": "14.0.4-canary.13", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index e5bf459a740ad..116916e4f5ed3 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.12", + "version": "14.0.4-canary.13", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index dd5077b3815b6..86418f4dff494 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.12", + "version": "14.0.4-canary.13", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index a12dbd4dd1009..5f55b2bb9ad2d 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.12", + "version": "14.0.4-canary.13", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index f001bbc418976..3daae33b7f1f9 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.12", + "version": "14.0.4-canary.13", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index 0b3cc7afe4a02..d5544ece1bc2e 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.12", + "version": "14.0.4-canary.13", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index bcb2030e35679..2371e35e58776 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.12", + "version": "14.0.4-canary.13", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index 9ae05fdbe49a0..3f0524b1c38b1 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.12", + "version": "14.0.4-canary.13", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index a538bfcd827f5..5c2714e9943ea 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.12", + "version": "14.0.4-canary.13", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.12", + "@next/env": "14.0.4-canary.13", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -146,11 +146,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.12", - "@next/polyfill-nomodule": "14.0.4-canary.12", - "@next/react-dev-overlay": "14.0.4-canary.12", - "@next/react-refresh-utils": "14.0.4-canary.12", - "@next/swc": "14.0.4-canary.12", + "@next/polyfill-module": "14.0.4-canary.13", + "@next/polyfill-nomodule": "14.0.4-canary.13", + "@next/react-dev-overlay": "14.0.4-canary.13", + "@next/react-refresh-utils": "14.0.4-canary.13", + "@next/swc": "14.0.4-canary.13", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index 4b3581d39ea86..2fc30ddbae4a5 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.12", + "version": "14.0.4-canary.13", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index e3b7cb6a0ca8c..f4d828e0892a4 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.12", + "version": "14.0.4-canary.13", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index 56fbfa0ab3ee0..8f44ff1600ab7 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.12", + "version": "14.0.4-canary.13", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -23,7 +23,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.12", + "next": "14.0.4-canary.13", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 657426364aaea..579d3023f2c56 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -735,7 +735,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.12 + specifier: 14.0.4-canary.13 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -800,7 +800,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.12 + specifier: 14.0.4-canary.13 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -924,19 +924,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.12 + specifier: 14.0.4-canary.13 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.12 + specifier: 14.0.4-canary.13 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.12 + specifier: 14.0.4-canary.13 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.12 + specifier: 14.0.4-canary.13 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.12 + specifier: 14.0.4-canary.13 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1587,7 +1587,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.12 + specifier: 14.0.4-canary.13 version: link:../next outdent: specifier: 0.8.0 From 2e28fa113ead31714ded3eb31c6a21a251f2348e Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Fri, 24 Nov 2023 12:16:13 +0100 Subject: [PATCH 037/481] Turbopack: align automatic externals code with webpack (#58851) ### What? * remove the additional check which verifies identity of resolved and external module. * `serverComponentsExternals` will force it being an external ### Why? ### How? Closes PACK-2032 --------- Co-authored-by: Tim Neutkens --- .../next-core/src/next_server/resolve.rs | 147 +++++------------- 1 file changed, 36 insertions(+), 111 deletions(-) diff --git a/packages/next-swc/crates/next-core/src/next_server/resolve.rs b/packages/next-swc/crates/next-core/src/next_server/resolve.rs index 43c1138f72668..2cee86cf225ab 100644 --- a/packages/next-swc/crates/next-core/src/next_server/resolve.rs +++ b/packages/next-swc/crates/next-core/src/next_server/resolve.rs @@ -3,15 +3,12 @@ use turbo_tasks::{Value, Vc}; use turbopack_binding::{ turbo::tasks_fs::{glob::Glob, FileJsonContent, FileSystemPath}, turbopack::core::{ - reference_type::{ - CommonJsReferenceSubType, EcmaScriptModulesReferenceSubType, ReferenceType, - }, + reference_type::{EcmaScriptModulesReferenceSubType, ReferenceType}, resolve::{ find_context_file, node::{node_cjs_resolve_options, node_esm_resolve_options}, package_json, parse::Request, - pattern::Pattern, plugin::{ResolvePlugin, ResolvePluginCondition}, resolve, FindContextFileResult, ResolveResult, ResolveResultItem, ResolveResultOption, }, @@ -60,44 +57,6 @@ impl ExternalCjsModulesResolvePlugin { } } -#[turbo_tasks::function] -async fn is_node_resolveable( - context: Vc, - request: Vc, - expected: Vc, - is_esm: bool, -) -> Result> { - let node_resolve_result = if is_esm { - resolve( - context, - Value::new(ReferenceType::EcmaScriptModules( - EcmaScriptModulesReferenceSubType::Undefined, - )), - request, - node_esm_resolve_options(context.root()), - ) - } else { - resolve( - context, - Value::new(ReferenceType::CommonJs(CommonJsReferenceSubType::Undefined)), - request, - node_cjs_resolve_options(context.root()), - ) - }; - let primary_node_assets = node_resolve_result.primary_sources().await?; - let Some(&node_asset) = primary_node_assets.first() else { - // can't resolve request with node.js options - return Ok(Vc::cell(false)); - }; - - if node_asset.ident().path().resolve().await? != expected.resolve().await? { - // node.js resolves to a different file - return Ok(Vc::cell(false)); - } - - Ok(Vc::cell(true)) -} - #[turbo_tasks::function] fn condition(root: Vc) -> Vc { ResolvePluginCondition::new(root, Glob::new("**/node_modules/**".to_string())) @@ -151,8 +110,9 @@ impl ResolvePlugin for ExternalCjsModulesResolvePlugin { } } - let is_esm = ReferenceType::EcmaScriptModules(EcmaScriptModulesReferenceSubType::Undefined) - .includes(&reference_type); + let is_esm = self.import_externals + && ReferenceType::EcmaScriptModules(EcmaScriptModulesReferenceSubType::Undefined) + .includes(&reference_type); enum FileType { CommonJs, @@ -197,81 +157,46 @@ impl ResolvePlugin for ExternalCjsModulesResolvePlugin { Ok(FileType::Unsupported) } - let file_type = get_file_type(fs_path, raw_fs_path).await?; + let node_resolved = resolve( + context, + reference_type.clone(), + request, + if is_esm { + node_esm_resolve_options(context.root()) + } else { + node_cjs_resolve_options(context.root()) + }, + ); + let Some(result) = *node_resolved.first_source().await? else { + // this can't resolve with node.js, so bundle it + return Ok(ResolveResultOption::none()); + }; + let path = result.ident().path(); + let file_type = get_file_type(path, &*path.await?).await?; - let (expected, is_esm) = match (file_type, is_esm) { + match (file_type, is_esm) { (FileType::Unsupported, _) => { // unsupported file type, bundle it - return Ok(ResolveResultOption::none()); + Ok(ResolveResultOption::none()) + } + (FileType::CommonJs, _) => { + // mark as external + Ok(ResolveResultOption::some( + ResolveResult::primary(ResolveResultItem::OriginalReferenceExternal).cell(), + )) } - (FileType::CommonJs, false) => (fs_path, false), - (FileType::CommonJs, true) => (fs_path, self.import_externals), - (FileType::EcmaScriptModule, false) => (fs_path, false), (FileType::EcmaScriptModule, true) => { - if self.import_externals { - (fs_path, true) - } else { - // We verify with the CommonJS alternative - let cjs_resolved = resolve( - context, - reference_type.clone(), - request, - node_cjs_resolve_options(context.root()), - ); - let Some(result) = *cjs_resolved.first_source().await? else { - // this can't resolve with commonjs, so bundle it - return Ok(ResolveResultOption::none()); - }; - let path = result.ident().path(); - let file_type = get_file_type(path, &*path.await?).await?; - if !matches!(file_type, FileType::CommonJs) { - // even with require() this resolves to a ESM, which would break node.js - // bundle it - // This happens for invalid packages like `textlinestream` - return Ok(ResolveResultOption::none()); - } - - (path, false) - } + // mark as external + Ok(ResolveResultOption::some( + ResolveResult::primary(ResolveResultItem::OriginalReferenceExternal).cell(), + )) } - }; - - let is_resolveable = - *is_node_resolveable(self.project_path, request, expected, is_esm).await?; - - if !is_resolveable { - if is_esm { - // When it's not resolveable as ESM, there is maybe an extension missing, - // try to add .js - if let Some(mut request_str) = request.await?.request() { - if !request_str.ends_with(".js") { - request_str += ".js"; - let new_request = - Request::parse(Value::new(Pattern::Constant(request_str.clone()))); - let is_resolveable = - *is_node_resolveable(self.project_path, new_request, expected, is_esm) - .await?; - if is_resolveable { - // mark as external, but with .js extension - return Ok(ResolveResultOption::some( - ResolveResult::primary( - ResolveResultItem::OriginalReferenceTypeExternal(request_str), - ) - .cell(), - )); - } - } - } + (FileType::EcmaScriptModule, false) => { + // even with require() this resolves to a ESM, + // which would break node.js, bundle it + Ok(ResolveResultOption::none()) } - - // this can't resolve with node.js, so bundle it - return Ok(ResolveResultOption::none()); } - - // mark as external - Ok(ResolveResultOption::some( - ResolveResult::primary(ResolveResultItem::OriginalReferenceExternal).cell(), - )) } } From c3c006d9f08ea45cc49c3271979ccd7669e7c8ac Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Fri, 24 Nov 2023 13:33:50 +0100 Subject: [PATCH 038/481] Upgrade Turbopack (#58859) * https://github.com/vercel/turbo/pull/6540 * https://github.com/vercel/turbo/pull/6549 * https://github.com/vercel/turbo/pull/6554 * https://github.com/vercel/turbo/pull/6561 * https://github.com/vercel/turbo/pull/6563 * https://github.com/vercel/turbo/pull/6562 * https://github.com/vercel/turbo/pull/6544 --- Cargo.lock | 66 +++++++++++++++++++------------------- Cargo.toml | 6 ++-- packages/next/package.json | 2 +- pnpm-lock.yaml | 10 +++--- 4 files changed, 42 insertions(+), 42 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fb9160493a4ac..f808972adf6aa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -322,7 +322,7 @@ dependencies = [ [[package]] name = "auto-hash-map" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" dependencies = [ "serde", "smallvec", @@ -3549,7 +3549,7 @@ dependencies = [ [[package]] name = "node-file-trace" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" dependencies = [ "anyhow", "serde", @@ -7695,7 +7695,7 @@ dependencies = [ [[package]] name = "turbo-tasks" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" dependencies = [ "anyhow", "async-trait", @@ -7727,7 +7727,7 @@ dependencies = [ [[package]] name = "turbo-tasks-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" dependencies = [ "anyhow", "cargo-lock", @@ -7739,7 +7739,7 @@ dependencies = [ [[package]] name = "turbo-tasks-bytes" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" dependencies = [ "anyhow", "bytes", @@ -7754,7 +7754,7 @@ dependencies = [ [[package]] name = "turbo-tasks-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" dependencies = [ "anyhow", "dotenvs", @@ -7768,7 +7768,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fetch" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7785,7 +7785,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fs" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" dependencies = [ "anyhow", "auto-hash-map", @@ -7815,7 +7815,7 @@ dependencies = [ [[package]] name = "turbo-tasks-hash" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" dependencies = [ "base16", "hex", @@ -7827,7 +7827,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" dependencies = [ "anyhow", "convert_case 0.6.0", @@ -7841,7 +7841,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros-shared" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" dependencies = [ "proc-macro2", "quote", @@ -7851,7 +7851,7 @@ dependencies = [ [[package]] name = "turbo-tasks-malloc" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" dependencies = [ "mimalloc", ] @@ -7859,7 +7859,7 @@ dependencies = [ [[package]] name = "turbo-tasks-memory" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" dependencies = [ "anyhow", "auto-hash-map", @@ -7884,7 +7884,7 @@ dependencies = [ [[package]] name = "turbopack" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" dependencies = [ "anyhow", "async-recursion", @@ -7915,7 +7915,7 @@ dependencies = [ [[package]] name = "turbopack-binding" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" dependencies = [ "auto-hash-map", "mdxjs", @@ -7955,7 +7955,7 @@ dependencies = [ [[package]] name = "turbopack-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7978,7 +7978,7 @@ dependencies = [ [[package]] name = "turbopack-cli-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" dependencies = [ "anyhow", "clap 4.4.2", @@ -8002,7 +8002,7 @@ dependencies = [ [[package]] name = "turbopack-core" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" dependencies = [ "anyhow", "async-recursion", @@ -8032,7 +8032,7 @@ dependencies = [ [[package]] name = "turbopack-css" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" dependencies = [ "anyhow", "async-trait", @@ -8058,7 +8058,7 @@ dependencies = [ [[package]] name = "turbopack-dev" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -8082,7 +8082,7 @@ dependencies = [ [[package]] name = "turbopack-dev-server" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" dependencies = [ "anyhow", "async-compression", @@ -8119,7 +8119,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" dependencies = [ "anyhow", "async-trait", @@ -8153,7 +8153,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-hmr-protocol" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" dependencies = [ "serde", "serde_json", @@ -8164,7 +8164,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-plugins" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" dependencies = [ "anyhow", "async-trait", @@ -8187,7 +8187,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-runtime" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" dependencies = [ "anyhow", "indoc", @@ -8204,7 +8204,7 @@ dependencies = [ [[package]] name = "turbopack-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -8220,7 +8220,7 @@ dependencies = [ [[package]] name = "turbopack-image" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" dependencies = [ "anyhow", "base64 0.21.4", @@ -8240,7 +8240,7 @@ dependencies = [ [[package]] name = "turbopack-json" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" dependencies = [ "anyhow", "serde", @@ -8255,7 +8255,7 @@ dependencies = [ [[package]] name = "turbopack-mdx" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" dependencies = [ "anyhow", "mdxjs", @@ -8270,7 +8270,7 @@ dependencies = [ [[package]] name = "turbopack-node" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" dependencies = [ "anyhow", "async-stream", @@ -8305,7 +8305,7 @@ dependencies = [ [[package]] name = "turbopack-static" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" dependencies = [ "anyhow", "serde", @@ -8321,7 +8321,7 @@ dependencies = [ [[package]] name = "turbopack-swc-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" dependencies = [ "swc_core", "turbo-tasks", @@ -8332,7 +8332,7 @@ dependencies = [ [[package]] name = "turbopack-wasm" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231122.3#39059918c629b620c88aaba02f49c771cf020d73" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" dependencies = [ "anyhow", "indexmap 1.9.3", diff --git a/Cargo.toml b/Cargo.toml index a2809aa38838f..a14ce800042f2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,11 +43,11 @@ next-transform-strip-page-exports = { path = "packages/next-swc/crates/next-tran testing = { version = "0.35.10" } # Turbo crates -turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231122.3" } +turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231124.2" } # [TODO]: need to refactor embed_directory! macro usages, as well as resolving turbo_tasks::function, macros.. -turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231122.3" } +turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231124.2" } # [TODO]: need to refactor embed_directory! macro usage in next-core -turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231122.3" } +turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231124.2" } # General Deps diff --git a/packages/next/package.json b/packages/next/package.json index 5c2714e9943ea..631c87f447907 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -193,7 +193,7 @@ "@types/ws": "8.2.0", "@vercel/ncc": "0.34.0", "@vercel/nft": "0.22.6", - "@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231122.2", + "@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231124.2", "acorn": "8.5.0", "amphtml-validator": "1.0.35", "anser": "1.4.9", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 579d3023f2c56..865a5561be8ac 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1065,8 +1065,8 @@ importers: specifier: 0.22.6 version: 0.22.6 '@vercel/turbopack-ecmascript-runtime': - specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231122.2 - version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231122.2(react-refresh@0.12.0)(webpack@5.86.0)' + specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231124.2 + version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231124.2(react-refresh@0.12.0)(webpack@5.86.0)' acorn: specifier: 8.5.0 version: 8.5.0 @@ -24646,9 +24646,9 @@ packages: /zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} - '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231122.2(react-refresh@0.12.0)(webpack@5.86.0)': - resolution: {registry: https://registry.npmjs.org/, tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231122.2} - id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231122.2' + '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231124.2(react-refresh@0.12.0)(webpack@5.86.0)': + resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231124.2} + id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231124.2' name: '@vercel/turbopack-ecmascript-runtime' version: 0.0.0 dependencies: From b27a3525c7e1921c5e6360c18b88d782eb0c51d9 Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Fri, 24 Nov 2023 13:41:03 +0000 Subject: [PATCH 039/481] v14.0.4-canary.14 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 18 +++++++++--------- 18 files changed, 34 insertions(+), 34 deletions(-) diff --git a/lerna.json b/lerna.json index 26cfce1bde1de..c44596a511b8b 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.13" + "version": "14.0.4-canary.14" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 9b34a0bd53e21..acca66ea84cae 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.13", + "version": "14.0.4-canary.14", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 4b5cb12664f07..d8a9518c9740a 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.13", + "version": "14.0.4-canary.14", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.13", + "@next/eslint-plugin-next": "14.0.4-canary.14", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 3354e1e5dd805..6afcb69c71dbf 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.13", + "version": "14.0.4-canary.14", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index 9126c2556d51e..6549eb45ad989 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.13", + "version": "14.0.4-canary.14", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index a36ee3dba4322..069b384d2f094 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.13", + "version": "14.0.4-canary.14", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 116916e4f5ed3..cfff7093f2a43 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.13", + "version": "14.0.4-canary.14", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 86418f4dff494..58f5f1b761688 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.13", + "version": "14.0.4-canary.14", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 5f55b2bb9ad2d..4ce0219a929ed 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.13", + "version": "14.0.4-canary.14", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 3daae33b7f1f9..53e1dad1a2442 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.13", + "version": "14.0.4-canary.14", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index d5544ece1bc2e..59d97998934d0 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.13", + "version": "14.0.4-canary.14", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index 2371e35e58776..6822914db8d9b 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.13", + "version": "14.0.4-canary.14", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index 3f0524b1c38b1..d973d5606c7e8 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.13", + "version": "14.0.4-canary.14", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index 631c87f447907..1c1fe91be66a3 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.13", + "version": "14.0.4-canary.14", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.13", + "@next/env": "14.0.4-canary.14", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -146,11 +146,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.13", - "@next/polyfill-nomodule": "14.0.4-canary.13", - "@next/react-dev-overlay": "14.0.4-canary.13", - "@next/react-refresh-utils": "14.0.4-canary.13", - "@next/swc": "14.0.4-canary.13", + "@next/polyfill-module": "14.0.4-canary.14", + "@next/polyfill-nomodule": "14.0.4-canary.14", + "@next/react-dev-overlay": "14.0.4-canary.14", + "@next/react-refresh-utils": "14.0.4-canary.14", + "@next/swc": "14.0.4-canary.14", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index 2fc30ddbae4a5..c0833ffdb19ac 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.13", + "version": "14.0.4-canary.14", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index f4d828e0892a4..71af12f5d9a5a 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.13", + "version": "14.0.4-canary.14", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index 8f44ff1600ab7..a31962fd20f55 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.13", + "version": "14.0.4-canary.14", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -23,7 +23,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.13", + "next": "14.0.4-canary.14", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 865a5561be8ac..ffeaa6ab48110 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -735,7 +735,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.13 + specifier: 14.0.4-canary.14 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -800,7 +800,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.13 + specifier: 14.0.4-canary.14 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -924,19 +924,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.13 + specifier: 14.0.4-canary.14 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.13 + specifier: 14.0.4-canary.14 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.13 + specifier: 14.0.4-canary.14 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.13 + specifier: 14.0.4-canary.14 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.13 + specifier: 14.0.4-canary.14 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1587,7 +1587,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.13 + specifier: 14.0.4-canary.14 version: link:../next outdent: specifier: 0.8.0 @@ -24647,7 +24647,7 @@ packages: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231124.2(react-refresh@0.12.0)(webpack@5.86.0)': - resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231124.2} + resolution: {registry: https://registry.npmjs.org/, tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231124.2} id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231124.2' name: '@vercel/turbopack-ecmascript-runtime' version: 0.0.0 From b8a18f6e134d9e8ce964680fdc982b22e492df4e Mon Sep 17 00:00:00 2001 From: Dima Voytenko Date: Fri, 24 Nov 2023 07:02:19 -0800 Subject: [PATCH 040/481] OpenTelemetry: propagate context to sandbox (#58791) The sandboxed request processing do not share the same async context with the `BaseServer` and thus the context should be propagated independently. Notably, the `headers` API is different in `BaseServer` (`Record`) vs in the sandbox (`Headers`), so additionally, we have to use the right `getter`. Co-authored-by: Leah <8845940+ForsakenHarmony@users.noreply.github.com> --- .../crates/next-core/src/next_import_map.rs | 23 +++---- packages/next/src/server/base-server.ts | 2 +- packages/next/src/server/lib/trace/tracer.ts | 10 ++- packages/next/src/server/web/adapter.ts | 61 +++++++++++-------- 4 files changed, 53 insertions(+), 43 deletions(-) diff --git a/packages/next-swc/crates/next-core/src/next_import_map.rs b/packages/next-swc/crates/next-core/src/next_import_map.rs index de639c9fffd71..031fbd8cb0fbc 100644 --- a/packages/next-swc/crates/next-core/src/next_import_map.rs +++ b/packages/next-swc/crates/next-core/src/next_import_map.rs @@ -511,14 +511,16 @@ async fn insert_next_server_special_aliases( NextRuntime::Edge => request_to_import_mapping(context_dir, request), NextRuntime::NodeJs => external_request_to_import_mapping(request), }; + + import_map.insert_exact_alias( + "@opentelemetry/api", + // TODO(WEB-625) this actually need to prefer the local version of + // @opentelemetry/api + external_if_node(project_path, "next/dist/compiled/@opentelemetry/api"), + ); + match ty { ServerContextType::Pages { pages_dir } | ServerContextType::PagesApi { pages_dir } => { - import_map.insert_exact_alias( - "@opentelemetry/api", - // TODO(WEB-625) this actually need to prefer the local version of - // @opentelemetry/api - external_if_node(pages_dir, "next/dist/compiled/@opentelemetry/api/index.js"), - ); insert_alias_to_alternatives( import_map, format!("{VIRTUAL_PACKAGE_NAME}/pages/_app"), @@ -549,15 +551,6 @@ async fn insert_next_server_special_aliases( ServerContextType::AppSSR { app_dir } | ServerContextType::AppRSC { app_dir, .. } | ServerContextType::AppRoute { app_dir } => { - import_map.insert_exact_alias( - "@opentelemetry/api", - // TODO(WEB-625) this actually need to prefer the local version of - // @opentelemetry/api - request_to_import_mapping( - app_dir, - "next/dist/compiled/@opentelemetry/api/index.js", - ), - ); import_map.insert_exact_alias( "styled-jsx", request_to_import_mapping(get_next_package(app_dir), "styled-jsx"), diff --git a/packages/next/src/server/base-server.ts b/packages/next/src/server/base-server.ts index f8813e0e3af5b..093fc3c8ef464 100644 --- a/packages/next/src/server/base-server.ts +++ b/packages/next/src/server/base-server.ts @@ -784,7 +784,7 @@ export default abstract class Server { const method = req.method.toUpperCase() const tracer = getTracer() - return tracer.withPropagatedContext(req, () => { + return tracer.withPropagatedContext(req.headers, () => { return tracer.trace( BaseServerSpan.handleRequest, { diff --git a/packages/next/src/server/lib/trace/tracer.ts b/packages/next/src/server/lib/trace/tracer.ts index 150db18b86602..8abb21aba9ce4 100644 --- a/packages/next/src/server/lib/trace/tracer.ts +++ b/packages/next/src/server/lib/trace/tracer.ts @@ -1,4 +1,3 @@ -import type { BaseNextRequest } from '../../base-http' import type { SpanTypes } from './constants' import { NextVanillaSpanAllowlist } from './constants' @@ -8,6 +7,7 @@ import type { SpanOptions, Tracer, AttributeValue, + TextMapGetter, } from 'next/dist/compiled/@opentelemetry/api' let api: typeof import('next/dist/compiled/@opentelemetry/api') @@ -173,13 +173,17 @@ class NextTracerImpl implements NextTracer { return trace.getSpan(context?.active()) } - public withPropagatedContext(req: BaseNextRequest, fn: () => T): T { + public withPropagatedContext( + carrier: C, + fn: () => T, + getter?: TextMapGetter + ): T { const activeContext = context.active() if (trace.getSpanContext(activeContext)) { // Active span is already set, too late to propagate. return fn() } - const remoteContext = propagation.extract(activeContext, req.headers) + const remoteContext = propagation.extract(activeContext, carrier, getter) return context.with(remoteContext, fn) } diff --git a/packages/next/src/server/web/adapter.ts b/packages/next/src/server/web/adapter.ts index 5f69e0c593161..6609cde770829 100644 --- a/packages/next/src/server/web/adapter.ts +++ b/packages/next/src/server/web/adapter.ts @@ -16,6 +16,8 @@ import { NEXT_QUERY_PARAM_PREFIX } from '../../lib/constants' import { ensureInstrumentationRegistered } from './globals' import { RequestAsyncStorageWrapper } from '../async-storage/request-async-storage-wrapper' import { requestAsyncStorage } from '../../client/components/request-async-storage.external' +import { getTracer } from '../lib/trace/tracer' +import type { TextMapGetter } from 'next/dist/compiled/@opentelemetry/api' class NextRequestHint extends NextRequest { sourcePage: string @@ -43,6 +45,11 @@ class NextRequestHint extends NextRequest { } } +const headersGetter: TextMapGetter = { + keys: (headers) => Array.from(headers.keys()), + get: (headers, key) => headers.get(key) ?? undefined, +} + export type AdapterOptions = { handler: NextMiddleware page: string @@ -176,31 +183,37 @@ export async function adapter( let response let cookiesFromResponse - // we only care to make async storage available for middleware - const isMiddleware = - params.page === '/middleware' || params.page === '/src/middleware' - if (isMiddleware) { - response = await RequestAsyncStorageWrapper.wrap( - requestAsyncStorage, - { - req: request, - renderOpts: { - onUpdateCookies: (cookies) => { - cookiesFromResponse = cookies + const tracer = getTracer() + response = await tracer.withPropagatedContext( + request.headers, + () => { + // we only care to make async storage available for middleware + const isMiddleware = + params.page === '/middleware' || params.page === '/src/middleware' + if (isMiddleware) { + return RequestAsyncStorageWrapper.wrap( + requestAsyncStorage, + { + req: request, + renderOpts: { + onUpdateCookies: (cookies) => { + cookiesFromResponse = cookies + }, + // @ts-expect-error: TODO: investigate why previewProps isn't on RenderOpts + previewProps: prerenderManifest?.preview || { + previewModeId: 'development-id', + previewModeEncryptionKey: '', + previewModeSigningKey: '', + }, + }, }, - // @ts-expect-error: TODO: investigate why previewProps isn't on RenderOpts - previewProps: prerenderManifest?.preview || { - previewModeId: 'development-id', - previewModeEncryptionKey: '', - previewModeSigningKey: '', - }, - }, - }, - () => params.handler(request, event) - ) - } else { - response = await params.handler(request, event) - } + () => params.handler(request, event) + ) + } + return params.handler(request, event) + }, + headersGetter + ) // check if response is a Response object if (response && !(response instanceof Response)) { From 2a8f7ae1b11d78abe3cb9f6a5c15ff811a397f6c Mon Sep 17 00:00:00 2001 From: Leah Date: Fri, 24 Nov 2023 16:48:12 +0100 Subject: [PATCH 041/481] Update Turbopack test manifest from GitHub Actions artifact (#58394) ### What? We can use the GitHub actions artifact (which is already produced right now) instead of a separate git branch to get the latest test results. This also means we don't have a dependency back to the turbo repo for the daily tests. Closes PACK-1951 --- .../actions/next-integration-stat/action.yml | 10 +- .../actions/next-integration-stat/index.js | 31382 ++++++++++++++-- .../next-integration-stat/package.json | 1 - .../next-integration-stat/src/index.ts | 48 +- .../next-integration-stat/src/manifest.d.ts | 49 + package.json | 1 + pnpm-lock.yaml | 3 + test/build-turbopack-tests-manifest.d.ts | 28 + test/build-turbopack-tests-manifest.js | 124 +- 9 files changed, 28784 insertions(+), 2862 deletions(-) create mode 100644 .github/actions/next-integration-stat/src/manifest.d.ts create mode 100644 test/build-turbopack-tests-manifest.d.ts diff --git a/.github/actions/next-integration-stat/action.yml b/.github/actions/next-integration-stat/action.yml index 0a9a379dcd11d..721fc923c33e8 100644 --- a/.github/actions/next-integration-stat/action.yml +++ b/.github/actions/next-integration-stat/action.yml @@ -3,20 +3,18 @@ author: Turbopack team description: 'Display next.js integration test failure status' inputs: - # Github token to use to create test report comment. If not specified, the default token will be used with username 'github-actions' token: default: ${{ github.token }} + description: 'GitHub token used to create the test report comment. If not specified, the default GitHub actions token will be used' - # The base of the test results to compare against. If not specified, will try to compare with latest main branch's test results. diff_base: default: 'main' + description: "The base of the test results to compare against. If not specified, will try to compare with latest main branch's test results." - # Include full test failure message in the report. - # This is currently disabled as we have too many failed test cases, causes - # too many report comment generated. expand_full_result_message: default: 'false' + description: 'Whether to include the full test failure message in the report. This is currently disabled as we have too many failed test cases, which would lead to massive comments.' runs: - using: node16 + using: node20 main: index.js diff --git a/.github/actions/next-integration-stat/index.js b/.github/actions/next-integration-stat/index.js index a2033dac3cdbe..41386ead64c84 100644 --- a/.github/actions/next-integration-stat/index.js +++ b/.github/actions/next-integration-stat/index.js @@ -778,9 +778,9 @@ const res = yield httpclient .getJson(id_token_url) .catch((error) => { - throw new Error(`Failed to get ID Token. \n - Error Code : ${error.statusCode}\n - Error Message: ${error.result.message}`) + throw new Error(`Failed to get ID Token. \n + Error Code : ${error.statusCode}\n + Error Message: ${error.message}`) }) const id_token = (_a = res.result) === null || _a === void 0 ? void 0 : _a.value @@ -1753,12 +1753,21 @@ (Object.create ? function (o, m, k, k2) { if (k2 === undefined) k2 = k - Object.defineProperty(o, k2, { - enumerable: true, - get: function () { - return m[k] - }, - }) + var desc = Object.getOwnPropertyDescriptor(m, k) + if ( + !desc || + ('get' in desc + ? !m.__esModule + : desc.writable || desc.configurable) + ) { + desc = { + enumerable: true, + get: function () { + return m[k] + }, + } + } + Object.defineProperty(o, k2, desc) } : function (o, m, k, k2) { if (k2 === undefined) k2 = k @@ -1783,7 +1792,10 @@ var result = {} if (mod != null) for (var k in mod) - if (k !== 'default' && Object.hasOwnProperty.call(mod, k)) + if ( + k !== 'default' && + Object.prototype.hasOwnProperty.call(mod, k) + ) __createBinding(result, mod, k) __setModuleDefault(result, mod) return result @@ -1837,6 +1849,7 @@ const https = __importStar(__nccwpck_require__(5687)) const pm = __importStar(__nccwpck_require__(9835)) const tunnel = __importStar(__nccwpck_require__(4294)) + const undici_1 = __nccwpck_require__(1773) var HttpCodes ;(function (HttpCodes) { HttpCodes[(HttpCodes['OK'] = 200)] = 'OK' @@ -1869,16 +1882,16 @@ HttpCodes[(HttpCodes['ServiceUnavailable'] = 503)] = 'ServiceUnavailable' HttpCodes[(HttpCodes['GatewayTimeout'] = 504)] = 'GatewayTimeout' - })((HttpCodes = exports.HttpCodes || (exports.HttpCodes = {}))) + })(HttpCodes || (exports.HttpCodes = HttpCodes = {})) var Headers ;(function (Headers) { Headers['Accept'] = 'accept' Headers['ContentType'] = 'content-type' - })((Headers = exports.Headers || (exports.Headers = {}))) + })(Headers || (exports.Headers = Headers = {})) var MediaTypes ;(function (MediaTypes) { MediaTypes['ApplicationJson'] = 'application/json' - })((MediaTypes = exports.MediaTypes || (exports.MediaTypes = {}))) + })(MediaTypes || (exports.MediaTypes = MediaTypes = {})) /** * Returns the proxy URL, depending upon the supplied url and proxy environment variables. * @param serverUrl The server URL where the request will be sent. For example, https://api.github.com @@ -1931,6 +1944,21 @@ ) }) } + readBodyBuffer() { + return __awaiter(this, void 0, void 0, function* () { + return new Promise((resolve) => + __awaiter(this, void 0, void 0, function* () { + const chunks = [] + this.message.on('data', (chunk) => { + chunks.push(chunk) + }) + this.message.on('end', () => { + resolve(Buffer.concat(chunks)) + }) + }) + ) + }) + } } exports.HttpClientResponse = HttpClientResponse function isHttps(requestUrl) { @@ -2321,6 +2349,15 @@ const parsedUrl = new URL(serverUrl) return this._getAgent(parsedUrl) } + getAgentDispatcher(serverUrl) { + const parsedUrl = new URL(serverUrl) + const proxyUrl = pm.getProxyUrl(parsedUrl) + const useProxy = proxyUrl && proxyUrl.hostname + if (!useProxy) { + return + } + return this._getProxyAgentDispatcher(parsedUrl, proxyUrl) + } _prepareRequest(method, requestUrl, headers) { const info = {} info.parsedUrl = requestUrl @@ -2436,6 +2473,38 @@ } return agent } + _getProxyAgentDispatcher(parsedUrl, proxyUrl) { + let proxyAgent + if (this._keepAlive) { + proxyAgent = this._proxyAgentDispatcher + } + // if agent is already assigned use that agent. + if (proxyAgent) { + return proxyAgent + } + const usingSsl = parsedUrl.protocol === 'https:' + proxyAgent = new undici_1.ProxyAgent( + Object.assign( + { uri: proxyUrl.href, pipelining: !this._keepAlive ? 0 : 1 }, + (proxyUrl.username || proxyUrl.password) && { + token: `${proxyUrl.username}:${proxyUrl.password}`, + } + ) + ) + this._proxyAgentDispatcher = proxyAgent + if (usingSsl && this._ignoreSslError) { + // we don't want to set NODE_TLS_REJECT_UNAUTHORIZED=0 since that will affect request for entire process + // http.RequestOptions doesn't expose a way to modify RequestOptions.agent.options + // we have to cast it to any and change it directly + proxyAgent.options = Object.assign( + proxyAgent.options.requestTls || {}, + { + rejectUnauthorized: false, + } + ) + } + return proxyAgent + } _performExponentialBackoff(retryNumber) { return __awaiter(this, void 0, void 0, function* () { retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber) @@ -2535,7 +2604,15 @@ } })() if (proxyVar) { - return new URL(proxyVar) + try { + return new URL(proxyVar) + } catch (_a) { + if ( + !proxyVar.startsWith('http://') && + !proxyVar.startsWith('https://') + ) + return new URL(`http://${proxyVar}`) + } } else { return undefined } @@ -2545,6 +2622,10 @@ if (!reqUrl.hostname) { return false } + const reqHost = reqUrl.hostname + if (isLoopbackAddress(reqHost)) { + return true + } const noProxy = process.env['no_proxy'] || process.env['NO_PROXY'] || '' if (!noProxy) { return false @@ -2568,13 +2649,31 @@ .split(',') .map((x) => x.trim().toUpperCase()) .filter((x) => x)) { - if (upperReqHosts.some((x) => x === upperNoProxyItem)) { + if ( + upperNoProxyItem === '*' || + upperReqHosts.some( + (x) => + x === upperNoProxyItem || + x.endsWith(`.${upperNoProxyItem}`) || + (upperNoProxyItem.startsWith('.') && + x.endsWith(`${upperNoProxyItem}`)) + ) + ) { return true } } return false } exports.checkBypass = checkBypass + function isLoopbackAddress(host) { + const hostLower = host.toLowerCase() + return ( + hostLower === 'localhost' || + hostLower.startsWith('127.') || + hostLower.startsWith('[::1]') || + hostLower.startsWith('[0:0:0:0:0:0:0:1]') + ) + } //# sourceMappingURL=proxy.js.map /***/ @@ -8528,10 +8627,6 @@ agent = agent(parsedURL) } - if (!headers.has('Connection') && !agent) { - headers.set('Connection', 'close') - } - // HTTP-network fetch step 4.2 // chunked encoding is handled by Node.js @@ -8979,8 +9074,11 @@ !headers['content-length'] ) { response.once('close', function (hadError) { + // tests for socket presence, as in some situations the + // the 'socket' event is not triggered for the request + // (happens in deno), avoids `TypeError` // if a data listener is still present we didn't end cleanly - const hasDataListener = socket.listenerCount('data') > 0 + const hasDataListener = socket && socket.listenerCount('data') > 0 if (hasDataListener && !hadError) { const err = new Error('Premature close') @@ -9028,6 +9126,7 @@ exports.Request = Request exports.Response = Response exports.FetchError = FetchError + exports.AbortError = AbortError /***/ }, @@ -9105,6 +9204,7 @@ } } + comp = comp.trim().split(/\s+/).join(' ') debug('comparator', comp, options) this.options = options this.loose = !!options.loose @@ -9169,13 +9269,6 @@ throw new TypeError('a Comparator is required') } - if (!options || typeof options !== 'object') { - options = { - loose: !!options, - includePrerelease: false, - } - } - if (this.operator === '') { if (this.value === '') { return true @@ -9188,39 +9281,62 @@ return new Range(this.value, options).test(comp.semver) } - const sameDirectionIncreasing = - (this.operator === '>=' || this.operator === '>') && - (comp.operator === '>=' || comp.operator === '>') - const sameDirectionDecreasing = - (this.operator === '<=' || this.operator === '<') && - (comp.operator === '<=' || comp.operator === '<') - const sameSemVer = this.semver.version === comp.semver.version - const differentDirectionsInclusive = - (this.operator === '>=' || this.operator === '<=') && - (comp.operator === '>=' || comp.operator === '<=') - const oppositeDirectionsLessThan = + options = parseOptions(options) + + // Special cases where nothing can possibly be lower + if ( + options.includePrerelease && + (this.value === '<0.0.0-0' || comp.value === '<0.0.0-0') + ) { + return false + } + if ( + !options.includePrerelease && + (this.value.startsWith('<0.0.0') || comp.value.startsWith('<0.0.0')) + ) { + return false + } + + // Same direction increasing (> or >=) + if (this.operator.startsWith('>') && comp.operator.startsWith('>')) { + return true + } + // Same direction decreasing (< or <=) + if (this.operator.startsWith('<') && comp.operator.startsWith('<')) { + return true + } + // same SemVer and both sides are inclusive (<= or >=) + if ( + this.semver.version === comp.semver.version && + this.operator.includes('=') && + comp.operator.includes('=') + ) { + return true + } + // opposite directions less than + if ( cmp(this.semver, '<', comp.semver, options) && - (this.operator === '>=' || this.operator === '>') && - (comp.operator === '<=' || comp.operator === '<') - const oppositeDirectionsGreaterThan = + this.operator.startsWith('>') && + comp.operator.startsWith('<') + ) { + return true + } + // opposite directions greater than + if ( cmp(this.semver, '>', comp.semver, options) && - (this.operator === '<=' || this.operator === '<') && - (comp.operator === '>=' || comp.operator === '>') - - return ( - sameDirectionIncreasing || - sameDirectionDecreasing || - (sameSemVer && differentDirectionsInclusive) || - oppositeDirectionsLessThan || - oppositeDirectionsGreaterThan - ) + this.operator.startsWith('<') && + comp.operator.startsWith('>') + ) { + return true + } + return false } } module.exports = Comparator const parseOptions = __nccwpck_require__(785) - const { re, t } = __nccwpck_require__(9523) + const { safeRe: re, t } = __nccwpck_require__(9523) const cmp = __nccwpck_require__(5098) const debug = __nccwpck_require__(427) const SemVer = __nccwpck_require__(8088) @@ -9262,9 +9378,13 @@ this.loose = !!options.loose this.includePrerelease = !!options.includePrerelease - // First, split based on boolean or || - this.raw = range - this.set = range + // First reduce all whitespace as much as possible so we do not have to rely + // on potentially slow regexes like \s*. This is then stored and used for + // future error messages as well. + this.raw = range.trim().split(/\s+/).join(' ') + + // First, split on || + this.set = this.raw .split('||') // map the range to a 2d array of comparators .map((r) => this.parseRange(r.trim())) @@ -9274,7 +9394,7 @@ .filter((c) => c.length) if (!this.set.length) { - throw new TypeError(`Invalid SemVer Range: ${range}`) + throw new TypeError(`Invalid SemVer Range: ${this.raw}`) } // if we have any that are not the null set, throw out null sets. @@ -9300,9 +9420,7 @@ format() { this.range = this.set - .map((comps) => { - return comps.join(' ').trim() - }) + .map((comps) => comps.join(' ').trim()) .join('||') .trim() return this.range @@ -9313,12 +9431,12 @@ } parseRange(range) { - range = range.trim() - // memoize range parsing for performance. // this is a very hot path, and fully deterministic. - const memoOpts = Object.keys(this.options).join(',') - const memoKey = `parseRange:${memoOpts}:${range}` + const memoOpts = + (this.options.includePrerelease && FLAG_INCLUDE_PRERELEASE) | + (this.options.loose && FLAG_LOOSE) + const memoKey = memoOpts + ':' + range const cached = cache.get(memoKey) if (cached) { return cached @@ -9332,18 +9450,18 @@ hyphenReplace(this.options.includePrerelease) ) debug('hyphen replace', range) + // `> 1.2.3 < 1.2.5` => `>1.2.3 <1.2.5` range = range.replace(re[t.COMPARATORTRIM], comparatorTrimReplace) debug('comparator trim', range) // `~ 1.2.3` => `~1.2.3` range = range.replace(re[t.TILDETRIM], tildeTrimReplace) + debug('tilde trim', range) // `^ 1.2.3` => `^1.2.3` range = range.replace(re[t.CARETTRIM], caretTrimReplace) - - // normalize spaces - range = range.split(/\s+/).join(' ') + debug('caret trim', range) // At this point, the range is completely trimmed and // ready to be split into comparators. @@ -9431,6 +9549,7 @@ return false } } + module.exports = Range const LRU = __nccwpck_require__(7129) @@ -9441,12 +9560,13 @@ const debug = __nccwpck_require__(427) const SemVer = __nccwpck_require__(8088) const { - re, + safeRe: re, t, comparatorTrimReplace, tildeTrimReplace, caretTrimReplace, } = __nccwpck_require__(9523) + const { FLAG_INCLUDE_PRERELEASE, FLAG_LOOSE } = __nccwpck_require__(2293) const isNullSet = (c) => c.value === '<0.0.0-0' const isAny = (c) => c.value === '' @@ -9494,14 +9614,13 @@ // ~1.2.3, ~>1.2.3 --> >=1.2.3 <1.3.0-0 // ~1.2.0, ~>1.2.0 --> >=1.2.0 <1.3.0-0 // ~0.0.1 --> >=0.0.1 <0.1.0-0 - const replaceTildes = (comp, options) => - comp + const replaceTildes = (comp, options) => { + return comp .trim() .split(/\s+/) - .map((c) => { - return replaceTilde(c, options) - }) + .map((c) => replaceTilde(c, options)) .join(' ') + } const replaceTilde = (comp, options) => { const r = options.loose ? re[t.TILDELOOSE] : re[t.TILDE] @@ -9537,14 +9656,13 @@ // ^1.2.0 --> >=1.2.0 <2.0.0-0 // ^0.0.1 --> >=0.0.1 <0.0.2-0 // ^0.1.0 --> >=0.1.0 <0.2.0-0 - const replaceCarets = (comp, options) => - comp + const replaceCarets = (comp, options) => { + return comp .trim() .split(/\s+/) - .map((c) => { - return replaceCaret(c, options) - }) + .map((c) => replaceCaret(c, options)) .join(' ') + } const replaceCaret = (comp, options) => { debug('caret', comp, options) @@ -9597,9 +9715,7 @@ debug('replaceXRanges', comp, options) return comp .split(/\s+/) - .map((c) => { - return replaceXRange(c, options) - }) + .map((c) => replaceXRange(c, options)) .join(' ') } @@ -9776,7 +9892,7 @@ ) => { const debug = __nccwpck_require__(427) const { MAX_LENGTH, MAX_SAFE_INTEGER } = __nccwpck_require__(2293) - const { re, t } = __nccwpck_require__(9523) + const { safeRe: re, t } = __nccwpck_require__(9523) const parseOptions = __nccwpck_require__(785) const { compareIdentifiers } = __nccwpck_require__(2463) @@ -9794,7 +9910,9 @@ version = version.version } } else if (typeof version !== 'string') { - throw new TypeError(`Invalid Version: ${version}`) + throw new TypeError( + `Invalid version. Must be a string. Got type "${typeof version}".` + ) } if (version.length > MAX_LENGTH) { @@ -9955,36 +10073,36 @@ // preminor will bump the version up to the next minor release, and immediately // down to pre-release. premajor and prepatch work the same way. - inc(release, identifier) { + inc(release, identifier, identifierBase) { switch (release) { case 'premajor': this.prerelease.length = 0 this.patch = 0 this.minor = 0 this.major++ - this.inc('pre', identifier) + this.inc('pre', identifier, identifierBase) break case 'preminor': this.prerelease.length = 0 this.patch = 0 this.minor++ - this.inc('pre', identifier) + this.inc('pre', identifier, identifierBase) break case 'prepatch': // If this is already a prerelease, it will bump to the next version // drop any prereleases that might already exist, since they are not // relevant at this point. this.prerelease.length = 0 - this.inc('patch', identifier) - this.inc('pre', identifier) + this.inc('patch', identifier, identifierBase) + this.inc('pre', identifier, identifierBase) break // If the input is a non-prerelease version, this acts the same as // prepatch. case 'prerelease': if (this.prerelease.length === 0) { - this.inc('patch', identifier) + this.inc('patch', identifier, identifierBase) } - this.inc('pre', identifier) + this.inc('pre', identifier, identifierBase) break case 'major': @@ -10026,9 +10144,17 @@ break // This probably shouldn't be used publicly. // 1.0.0 'pre' would become 1.0.0-0 which is the wrong direction. - case 'pre': + case 'pre': { + const base = Number(identifierBase) ? 1 : 0 + + if (!identifier && identifierBase === false) { + throw new Error( + 'invalid increment argument: identifier is empty' + ) + } + if (this.prerelease.length === 0) { - this.prerelease = [0] + this.prerelease = [base] } else { let i = this.prerelease.length while (--i >= 0) { @@ -10039,27 +10165,41 @@ } if (i === -1) { // didn't increment anything - this.prerelease.push(0) + if ( + identifier === this.prerelease.join('.') && + identifierBase === false + ) { + throw new Error( + 'invalid increment argument: identifier already exists' + ) + } + this.prerelease.push(base) } } if (identifier) { // 1.2.0-beta.1 bumps to 1.2.0-beta.2, // 1.2.0-beta.fooblz or 1.2.0-beta bumps to 1.2.0-beta.0 + let prerelease = [identifier, base] + if (identifierBase === false) { + prerelease = [identifier] + } if (compareIdentifiers(this.prerelease[0], identifier) === 0) { if (isNaN(this.prerelease[1])) { - this.prerelease = [identifier, 0] + this.prerelease = prerelease } } else { - this.prerelease = [identifier, 0] + this.prerelease = prerelease } } break - + } default: throw new Error(`invalid increment argument: ${release}`) } - this.format() - this.raw = this.version + this.raw = this.format() + if (this.build.length) { + this.raw += `+${this.build.join('.')}` + } return this } } @@ -10152,7 +10292,7 @@ ) => { const SemVer = __nccwpck_require__(8088) const parse = __nccwpck_require__(5925) - const { re, t } = __nccwpck_require__(9523) + const { safeRe: re, t } = __nccwpck_require__(9523) const coerce = (version, options) => { if (version instanceof SemVer) { @@ -10261,27 +10401,69 @@ __nccwpck_require__ ) => { const parse = __nccwpck_require__(5925) - const eq = __nccwpck_require__(1898) const diff = (version1, version2) => { - if (eq(version1, version2)) { + const v1 = parse(version1, null, true) + const v2 = parse(version2, null, true) + const comparison = v1.compare(v2) + + if (comparison === 0) { return null - } else { - const v1 = parse(version1) - const v2 = parse(version2) - const hasPre = v1.prerelease.length || v2.prerelease.length - const prefix = hasPre ? 'pre' : '' - const defaultResult = hasPre ? 'prerelease' : '' - for (const key in v1) { - if (key === 'major' || key === 'minor' || key === 'patch') { - if (v1[key] !== v2[key]) { - return prefix + key - } - } + } + + const v1Higher = comparison > 0 + const highVersion = v1Higher ? v1 : v2 + const lowVersion = v1Higher ? v2 : v1 + const highHasPre = !!highVersion.prerelease.length + const lowHasPre = !!lowVersion.prerelease.length + + if (lowHasPre && !highHasPre) { + // Going from prerelease -> no prerelease requires some special casing + + // If the low version has only a major, then it will always be a major + // Some examples: + // 1.0.0-1 -> 1.0.0 + // 1.0.0-1 -> 1.1.1 + // 1.0.0-1 -> 2.0.0 + if (!lowVersion.patch && !lowVersion.minor) { + return 'major' + } + + // Otherwise it can be determined by checking the high version + + if (highVersion.patch) { + // anything higher than a patch bump would result in the wrong version + return 'patch' + } + + if (highVersion.minor) { + // anything higher than a minor bump would result in the wrong version + return 'minor' } - return defaultResult // may be undefined + + // bumping major/minor/patch all have same result + return 'major' + } + + // add the `pre` prefix if we are going to a prerelease version + const prefix = highHasPre ? 'pre' : '' + + if (v1.major !== v2.major) { + return prefix + 'major' + } + + if (v1.minor !== v2.minor) { + return prefix + 'minor' + } + + if (v1.patch !== v2.patch) { + return prefix + 'patch' } + + // high and low are preleases + return 'prerelease' } + module.exports = diff /***/ @@ -10330,8 +10512,9 @@ ) => { const SemVer = __nccwpck_require__(8088) - const inc = (version, release, options, identifier) => { + const inc = (version, release, options, identifier, identifierBase) => { if (typeof options === 'string') { + identifierBase = identifier identifier = options options = undefined } @@ -10340,7 +10523,7 @@ return new SemVer( version instanceof SemVer ? version.version : version, options - ).inc(release, identifier).version + ).inc(release, identifier, identifierBase).version } catch (er) { return null } @@ -10415,35 +10598,18 @@ __unused_webpack_exports, __nccwpck_require__ ) => { - const { MAX_LENGTH } = __nccwpck_require__(2293) - const { re, t } = __nccwpck_require__(9523) const SemVer = __nccwpck_require__(8088) - - const parseOptions = __nccwpck_require__(785) - const parse = (version, options) => { - options = parseOptions(options) - + const parse = (version, options, throwErrors = false) => { if (version instanceof SemVer) { return version } - - if (typeof version !== 'string') { - return null - } - - if (version.length > MAX_LENGTH) { - return null - } - - const r = options.loose ? re[t.LOOSE] : re[t.FULL] - if (!r.test(version)) { - return null - } - try { return new SemVer(version, options) } catch (er) { - return null + if (!throwErrors) { + return null + } + throw er } } @@ -10641,6 +10807,7 @@ src: internalRe.src, tokens: internalRe.t, SEMVER_SPEC_VERSION: constants.SEMVER_SPEC_VERSION, + RELEASE_TYPES: constants.RELEASE_TYPES, compareIdentifiers: identifiers.compareIdentifiers, rcompareIdentifiers: identifiers.rcompareIdentifiers, } @@ -10660,11 +10827,29 @@ // Max safe segment length for coercion. const MAX_SAFE_COMPONENT_LENGTH = 16 + // Max safe length for a build identifier. The max length minus 6 characters for + // the shortest version with a build 0.0.0+BUILD. + const MAX_SAFE_BUILD_LENGTH = MAX_LENGTH - 6 + + const RELEASE_TYPES = [ + 'major', + 'premajor', + 'minor', + 'preminor', + 'patch', + 'prepatch', + 'prerelease', + ] + module.exports = { - SEMVER_SPEC_VERSION, MAX_LENGTH, - MAX_SAFE_INTEGER, MAX_SAFE_COMPONENT_LENGTH, + MAX_SAFE_BUILD_LENGTH, + MAX_SAFE_INTEGER, + RELEASE_TYPES, + SEMVER_SPEC_VERSION, + FLAG_INCLUDE_PRERELEASE: 0b001, + FLAG_LOOSE: 0b010, } /***/ @@ -10717,42 +10902,71 @@ }, /***/ 785: /***/ (module) => { - // parse out just the options we care about so we always get a consistent - // obj with keys in a consistent order. - const opts = ['includePrerelease', 'loose', 'rtl'] - const parseOptions = (options) => - !options - ? {} - : typeof options !== 'object' - ? { loose: true } - : opts - .filter((k) => options[k]) - .reduce((o, k) => { - o[k] = true - return o - }, {}) + // parse out just the options we care about + const looseOption = Object.freeze({ loose: true }) + const emptyOpts = Object.freeze({}) + const parseOptions = (options) => { + if (!options) { + return emptyOpts + } + + if (typeof options !== 'object') { + return looseOption + } + + return options + } module.exports = parseOptions /***/ }, /***/ 9523: /***/ (module, exports, __nccwpck_require__) => { - const { MAX_SAFE_COMPONENT_LENGTH } = __nccwpck_require__(2293) + const { MAX_SAFE_COMPONENT_LENGTH, MAX_SAFE_BUILD_LENGTH, MAX_LENGTH } = + __nccwpck_require__(2293) const debug = __nccwpck_require__(427) exports = module.exports = {} // The actual regexps go on exports.re const re = (exports.re = []) + const safeRe = (exports.safeRe = []) const src = (exports.src = []) const t = (exports.t = {}) let R = 0 + const LETTERDASHNUMBER = '[a-zA-Z0-9-]' + + // Replace some greedy regex tokens to prevent regex dos issues. These regex are + // used internally via the safeRe object since all inputs in this library get + // normalized first to trim and collapse all extra whitespace. The original + // regexes are exported for userland consumption and lower level usage. A + // future breaking change could export the safer regex only with a note that + // all input should have extra whitespace removed. + const safeRegexReplacements = [ + ['\\s', 1], + ['\\d', MAX_LENGTH], + [LETTERDASHNUMBER, MAX_SAFE_BUILD_LENGTH], + ] + + const makeSafeRegex = (value) => { + for (const [token, max] of safeRegexReplacements) { + value = value + .split(`${token}*`) + .join(`${token}{0,${max}}`) + .split(`${token}+`) + .join(`${token}{1,${max}}`) + } + return value + } + const createToken = (name, value, isGlobal) => { + const safe = makeSafeRegex(value) const index = R++ debug(name, index, value) t[name] = index src[index] = value re[index] = new RegExp(value, isGlobal ? 'g' : undefined) + safeRe[index] = new RegExp(safe, isGlobal ? 'g' : undefined) } // The following Regular Expressions can be used for tokenizing, @@ -10762,13 +10976,13 @@ // A single `0`, or a non-zero digit followed by zero or more digits. createToken('NUMERICIDENTIFIER', '0|[1-9]\\d*') - createToken('NUMERICIDENTIFIERLOOSE', '[0-9]+') + createToken('NUMERICIDENTIFIERLOOSE', '\\d+') // ## Non-numeric Identifier // Zero or more digits, followed by a letter or hyphen, and then zero or // more letters, digits, or hyphens. - createToken('NONNUMERICIDENTIFIER', '\\d*[a-zA-Z-][a-zA-Z0-9-]*') + createToken('NONNUMERICIDENTIFIER', `\\d*[a-zA-Z-]${LETTERDASHNUMBER}*`) // ## Main Version // Three dot-separated numeric identifiers. @@ -10821,7 +11035,7 @@ // ## Build Metadata Identifier // Any combination of digits, letters, or hyphens. - createToken('BUILDIDENTIFIER', '[0-9A-Za-z-]+') + createToken('BUILDIDENTIFIER', `${LETTERDASHNUMBER}+`) // ## Build Metadata // Plus sign, followed by one or more period-separated build metadata @@ -11000,7 +11214,7 @@ const intersects = (r1, r2, options) => { r1 = new Range(r1, options) r2 = new Range(r2, options) - return r1.intersects(r2) + return r1.intersects(r2, options) } module.exports = intersects @@ -11381,6 +11595,9 @@ return true } + const minimumVersionWithPreRelease = [new Comparator('>=0.0.0-0')] + const minimumVersion = [new Comparator('>=0.0.0')] + const simpleSubset = (sub, dom, options) => { if (sub === dom) { return true @@ -11390,9 +11607,9 @@ if (dom.length === 1 && dom[0].semver === ANY) { return true } else if (options.includePrerelease) { - sub = [new Comparator('>=0.0.0-0')] + sub = minimumVersionWithPreRelease } else { - sub = [new Comparator('>=0.0.0')] + sub = minimumVersion } } @@ -11400,7 +11617,7 @@ if (options.includePrerelease) { return true } else { - dom = [new Comparator('>=0.0.0')] + dom = minimumVersion } } @@ -12166,3512 +12383,29092 @@ /***/ }, - /***/ 5030: /***/ (__unused_webpack_module, exports) => { + /***/ 1773: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { 'use strict' - Object.defineProperty(exports, '__esModule', { value: true }) + const Client = __nccwpck_require__(3598) + const Dispatcher = __nccwpck_require__(412) + const errors = __nccwpck_require__(8045) + const Pool = __nccwpck_require__(4634) + const BalancedPool = __nccwpck_require__(7931) + const Agent = __nccwpck_require__(7890) + const util = __nccwpck_require__(3983) + const { InvalidArgumentError } = errors + const api = __nccwpck_require__(4059) + const buildConnector = __nccwpck_require__(2067) + const MockClient = __nccwpck_require__(8687) + const MockAgent = __nccwpck_require__(6771) + const MockPool = __nccwpck_require__(6193) + const mockErrors = __nccwpck_require__(888) + const ProxyAgent = __nccwpck_require__(7858) + const { getGlobalDispatcher, setGlobalDispatcher } = + __nccwpck_require__(1892) + const DecoratorHandler = __nccwpck_require__(6930) + const RedirectHandler = __nccwpck_require__(2860) + const createRedirectInterceptor = __nccwpck_require__(8861) + + let hasCrypto + try { + __nccwpck_require__(6113) + hasCrypto = true + } catch { + hasCrypto = false + } - function getUserAgent() { - if (typeof navigator === 'object' && 'userAgent' in navigator) { - return navigator.userAgent + Object.assign(Dispatcher.prototype, api) + + module.exports.Dispatcher = Dispatcher + module.exports.Client = Client + module.exports.Pool = Pool + module.exports.BalancedPool = BalancedPool + module.exports.Agent = Agent + module.exports.ProxyAgent = ProxyAgent + + module.exports.DecoratorHandler = DecoratorHandler + module.exports.RedirectHandler = RedirectHandler + module.exports.createRedirectInterceptor = createRedirectInterceptor + + module.exports.buildConnector = buildConnector + module.exports.errors = errors + + function makeDispatcher(fn) { + return (url, opts, handler) => { + if (typeof opts === 'function') { + handler = opts + opts = null + } + + if ( + !url || + (typeof url !== 'string' && + typeof url !== 'object' && + !(url instanceof URL)) + ) { + throw new InvalidArgumentError('invalid url') + } + + if (opts != null && typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') + } + + if (opts && opts.path != null) { + if (typeof opts.path !== 'string') { + throw new InvalidArgumentError('invalid opts.path') + } + + let path = opts.path + if (!opts.path.startsWith('/')) { + path = `/${path}` + } + + url = new URL(util.parseOrigin(url).origin + path) + } else { + if (!opts) { + opts = typeof url === 'object' ? url : {} + } + + url = util.parseURL(url) + } + + const { agent, dispatcher = getGlobalDispatcher() } = opts + + if (agent) { + throw new InvalidArgumentError( + 'unsupported opts.agent. Did you mean opts.client?' + ) + } + + return fn.call( + dispatcher, + { + ...opts, + origin: url.origin, + path: url.search ? `${url.pathname}${url.search}` : url.pathname, + method: opts.method || (opts.body ? 'PUT' : 'GET'), + }, + handler + ) } + } - if (typeof process === 'object' && 'version' in process) { - return `Node.js/${process.version.substr(1)} (${process.platform}; ${ - process.arch - })` + module.exports.setGlobalDispatcher = setGlobalDispatcher + module.exports.getGlobalDispatcher = getGlobalDispatcher + + if ( + util.nodeMajor > 16 || + (util.nodeMajor === 16 && util.nodeMinor >= 8) + ) { + let fetchImpl = null + module.exports.fetch = async function fetch(resource) { + if (!fetchImpl) { + fetchImpl = __nccwpck_require__(4881).fetch + } + + try { + return await fetchImpl(...arguments) + } catch (err) { + if (typeof err === 'object') { + Error.captureStackTrace(err, this) + } + + throw err + } } + module.exports.Headers = __nccwpck_require__(554).Headers + module.exports.Response = __nccwpck_require__(7823).Response + module.exports.Request = __nccwpck_require__(8359).Request + module.exports.FormData = __nccwpck_require__(2015).FormData + module.exports.File = __nccwpck_require__(8511).File + module.exports.FileReader = __nccwpck_require__(1446).FileReader - return '' + const { setGlobalOrigin, getGlobalOrigin } = __nccwpck_require__(1246) + + module.exports.setGlobalOrigin = setGlobalOrigin + module.exports.getGlobalOrigin = getGlobalOrigin + + const { CacheStorage } = __nccwpck_require__(7907) + const { kConstruct } = __nccwpck_require__(9174) + + // Cache & CacheStorage are tightly coupled with fetch. Even if it may run + // in an older version of Node, it doesn't have any use without fetch. + module.exports.caches = new CacheStorage(kConstruct) } - exports.getUserAgent = getUserAgent - //# sourceMappingURL=index.js.map + if (util.nodeMajor >= 16) { + const { deleteCookie, getCookies, getSetCookies, setCookie } = + __nccwpck_require__(1724) + + module.exports.deleteCookie = deleteCookie + module.exports.getCookies = getCookies + module.exports.getSetCookies = getSetCookies + module.exports.setCookie = setCookie + + const { parseMIMEType, serializeAMimeType } = __nccwpck_require__(685) + + module.exports.parseMIMEType = parseMIMEType + module.exports.serializeAMimeType = serializeAMimeType + } + + if (util.nodeMajor >= 18 && hasCrypto) { + const { WebSocket } = __nccwpck_require__(4284) + + module.exports.WebSocket = WebSocket + } + + module.exports.request = makeDispatcher(api.request) + module.exports.stream = makeDispatcher(api.stream) + module.exports.pipeline = makeDispatcher(api.pipeline) + module.exports.connect = makeDispatcher(api.connect) + module.exports.upgrade = makeDispatcher(api.upgrade) + + module.exports.MockClient = MockClient + module.exports.MockPool = MockPool + module.exports.MockAgent = MockAgent + module.exports.mockErrors = mockErrors /***/ }, - /***/ 5840: /***/ ( - __unused_webpack_module, - exports, + /***/ 7890: /***/ ( + module, + __unused_webpack_exports, __nccwpck_require__ ) => { 'use strict' - Object.defineProperty(exports, '__esModule', { - value: true, - }) - Object.defineProperty(exports, 'v1', { - enumerable: true, - get: function () { - return _v.default - }, - }) - Object.defineProperty(exports, 'v3', { - enumerable: true, - get: function () { - return _v2.default - }, - }) - Object.defineProperty(exports, 'v4', { - enumerable: true, - get: function () { - return _v3.default - }, - }) - Object.defineProperty(exports, 'v5', { - enumerable: true, - get: function () { - return _v4.default - }, - }) - Object.defineProperty(exports, 'NIL', { - enumerable: true, - get: function () { - return _nil.default - }, - }) - Object.defineProperty(exports, 'version', { - enumerable: true, - get: function () { - return _version.default - }, - }) - Object.defineProperty(exports, 'validate', { - enumerable: true, - get: function () { - return _validate.default - }, - }) - Object.defineProperty(exports, 'stringify', { - enumerable: true, - get: function () { - return _stringify.default - }, - }) - Object.defineProperty(exports, 'parse', { - enumerable: true, - get: function () { - return _parse.default - }, - }) - - var _v = _interopRequireDefault(__nccwpck_require__(8628)) - - var _v2 = _interopRequireDefault(__nccwpck_require__(6409)) + const { InvalidArgumentError } = __nccwpck_require__(8045) + const { kClients, kRunning, kClose, kDestroy, kDispatch, kInterceptors } = + __nccwpck_require__(2785) + const DispatcherBase = __nccwpck_require__(4839) + const Pool = __nccwpck_require__(4634) + const Client = __nccwpck_require__(3598) + const util = __nccwpck_require__(3983) + const createRedirectInterceptor = __nccwpck_require__(8861) + const { WeakRef, FinalizationRegistry } = __nccwpck_require__(6436)() + + const kOnConnect = Symbol('onConnect') + const kOnDisconnect = Symbol('onDisconnect') + const kOnConnectionError = Symbol('onConnectionError') + const kMaxRedirections = Symbol('maxRedirections') + const kOnDrain = Symbol('onDrain') + const kFactory = Symbol('factory') + const kFinalizer = Symbol('finalizer') + const kOptions = Symbol('options') + + function defaultFactory(origin, opts) { + return opts && opts.connections === 1 + ? new Client(origin, opts) + : new Pool(origin, opts) + } + + class Agent extends DispatcherBase { + constructor({ + factory = defaultFactory, + maxRedirections = 0, + connect, + ...options + } = {}) { + super() + + if (typeof factory !== 'function') { + throw new InvalidArgumentError('factory must be a function.') + } - var _v3 = _interopRequireDefault(__nccwpck_require__(5122)) + if ( + connect != null && + typeof connect !== 'function' && + typeof connect !== 'object' + ) { + throw new InvalidArgumentError( + 'connect must be a function or an object' + ) + } - var _v4 = _interopRequireDefault(__nccwpck_require__(9120)) + if (!Number.isInteger(maxRedirections) || maxRedirections < 0) { + throw new InvalidArgumentError( + 'maxRedirections must be a positive number' + ) + } - var _nil = _interopRequireDefault(__nccwpck_require__(5332)) + if (connect && typeof connect !== 'function') { + connect = { ...connect } + } + + this[kInterceptors] = + options.interceptors && + options.interceptors.Agent && + Array.isArray(options.interceptors.Agent) + ? options.interceptors.Agent + : [createRedirectInterceptor({ maxRedirections })] + + this[kOptions] = { ...util.deepClone(options), connect } + this[kOptions].interceptors = options.interceptors + ? { ...options.interceptors } + : undefined + this[kMaxRedirections] = maxRedirections + this[kFactory] = factory + this[kClients] = new Map() + this[kFinalizer] = new FinalizationRegistry( + /* istanbul ignore next: gc is undeterministic */ (key) => { + const ref = this[kClients].get(key) + if (ref !== undefined && ref.deref() === undefined) { + this[kClients].delete(key) + } + } + ) - var _version = _interopRequireDefault(__nccwpck_require__(1595)) + const agent = this - var _validate = _interopRequireDefault(__nccwpck_require__(6900)) + this[kOnDrain] = (origin, targets) => { + agent.emit('drain', origin, [agent, ...targets]) + } - var _stringify = _interopRequireDefault(__nccwpck_require__(8950)) + this[kOnConnect] = (origin, targets) => { + agent.emit('connect', origin, [agent, ...targets]) + } - var _parse = _interopRequireDefault(__nccwpck_require__(2746)) + this[kOnDisconnect] = (origin, targets, err) => { + agent.emit('disconnect', origin, [agent, ...targets], err) + } - function _interopRequireDefault(obj) { - return obj && obj.__esModule ? obj : { default: obj } - } + this[kOnConnectionError] = (origin, targets, err) => { + agent.emit('connectionError', origin, [agent, ...targets], err) + } + } - /***/ - }, + get [kRunning]() { + let ret = 0 + for (const ref of this[kClients].values()) { + const client = ref.deref() + /* istanbul ignore next: gc is undeterministic */ + if (client) { + ret += client[kRunning] + } + } + return ret + } - /***/ 4569: /***/ ( - __unused_webpack_module, - exports, - __nccwpck_require__ - ) => { - 'use strict' + [kDispatch](opts, handler) { + let key + if ( + opts.origin && + (typeof opts.origin === 'string' || opts.origin instanceof URL) + ) { + key = String(opts.origin) + } else { + throw new InvalidArgumentError( + 'opts.origin must be a non-empty string or URL.' + ) + } - Object.defineProperty(exports, '__esModule', { - value: true, - }) - exports['default'] = void 0 + const ref = this[kClients].get(key) - var _crypto = _interopRequireDefault(__nccwpck_require__(6113)) + let dispatcher = ref ? ref.deref() : null + if (!dispatcher) { + dispatcher = this[kFactory](opts.origin, this[kOptions]) + .on('drain', this[kOnDrain]) + .on('connect', this[kOnConnect]) + .on('disconnect', this[kOnDisconnect]) + .on('connectionError', this[kOnConnectionError]) - function _interopRequireDefault(obj) { - return obj && obj.__esModule ? obj : { default: obj } - } + this[kClients].set(key, new WeakRef(dispatcher)) + this[kFinalizer].register(dispatcher, key) + } - function md5(bytes) { - if (Array.isArray(bytes)) { - bytes = Buffer.from(bytes) - } else if (typeof bytes === 'string') { - bytes = Buffer.from(bytes, 'utf8') + return dispatcher.dispatch(opts, handler) } - return _crypto.default.createHash('md5').update(bytes).digest() - } + async [kClose]() { + const closePromises = [] + for (const ref of this[kClients].values()) { + const client = ref.deref() + /* istanbul ignore else: gc is undeterministic */ + if (client) { + closePromises.push(client.close()) + } + } - var _default = md5 - exports['default'] = _default + await Promise.all(closePromises) + } - /***/ - }, + async [kDestroy](err) { + const destroyPromises = [] + for (const ref of this[kClients].values()) { + const client = ref.deref() + /* istanbul ignore else: gc is undeterministic */ + if (client) { + destroyPromises.push(client.destroy(err)) + } + } - /***/ 5332: /***/ (__unused_webpack_module, exports) => { - 'use strict' + await Promise.all(destroyPromises) + } + } - Object.defineProperty(exports, '__esModule', { - value: true, - }) - exports['default'] = void 0 - var _default = '00000000-0000-0000-0000-000000000000' - exports['default'] = _default + module.exports = Agent /***/ }, - /***/ 2746: /***/ ( - __unused_webpack_module, - exports, + /***/ 7032: /***/ ( + module, + __unused_webpack_exports, __nccwpck_require__ ) => { - 'use strict' + const { addAbortListener } = __nccwpck_require__(3983) + const { RequestAbortedError } = __nccwpck_require__(8045) - Object.defineProperty(exports, '__esModule', { - value: true, - }) - exports['default'] = void 0 - - var _validate = _interopRequireDefault(__nccwpck_require__(6900)) - - function _interopRequireDefault(obj) { - return obj && obj.__esModule ? obj : { default: obj } - } + const kListener = Symbol('kListener') + const kSignal = Symbol('kSignal') - function parse(uuid) { - if (!(0, _validate.default)(uuid)) { - throw TypeError('Invalid UUID') + function abort(self) { + if (self.abort) { + self.abort() + } else { + self.onError(new RequestAbortedError()) } + } - let v - const arr = new Uint8Array(16) // Parse ########-....-....-....-............ - - arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24 - arr[1] = (v >>> 16) & 0xff - arr[2] = (v >>> 8) & 0xff - arr[3] = v & 0xff // Parse ........-####-....-....-............ + function addSignal(self, signal) { + self[kSignal] = null + self[kListener] = null - arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8 - arr[5] = v & 0xff // Parse ........-....-####-....-............ + if (!signal) { + return + } - arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8 - arr[7] = v & 0xff // Parse ........-....-....-####-............ + if (signal.aborted) { + abort(self) + return + } - arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8 - arr[9] = v & 0xff // Parse ........-....-....-....-############ - // (Use "/" to avoid 32-bit truncation when bit-shifting high-order bytes) + self[kSignal] = signal + self[kListener] = () => { + abort(self) + } - arr[10] = - ((v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000) & 0xff - arr[11] = (v / 0x100000000) & 0xff - arr[12] = (v >>> 24) & 0xff - arr[13] = (v >>> 16) & 0xff - arr[14] = (v >>> 8) & 0xff - arr[15] = v & 0xff - return arr + addAbortListener(self[kSignal], self[kListener]) } - var _default = parse - exports['default'] = _default + function removeSignal(self) { + if (!self[kSignal]) { + return + } - /***/ - }, + if ('removeEventListener' in self[kSignal]) { + self[kSignal].removeEventListener('abort', self[kListener]) + } else { + self[kSignal].removeListener('abort', self[kListener]) + } - /***/ 814: /***/ (__unused_webpack_module, exports) => { - 'use strict' + self[kSignal] = null + self[kListener] = null + } - Object.defineProperty(exports, '__esModule', { - value: true, - }) - exports['default'] = void 0 - var _default = - /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i - exports['default'] = _default + module.exports = { + addSignal, + removeSignal, + } /***/ }, - /***/ 807: /***/ ( - __unused_webpack_module, - exports, + /***/ 9744: /***/ ( + module, + __unused_webpack_exports, __nccwpck_require__ ) => { 'use strict' - Object.defineProperty(exports, '__esModule', { - value: true, - }) - exports['default'] = rng + const { AsyncResource } = __nccwpck_require__(852) + const { InvalidArgumentError, RequestAbortedError, SocketError } = + __nccwpck_require__(8045) + const util = __nccwpck_require__(3983) + const { addSignal, removeSignal } = __nccwpck_require__(7032) - var _crypto = _interopRequireDefault(__nccwpck_require__(6113)) + class ConnectHandler extends AsyncResource { + constructor(opts, callback) { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') + } - function _interopRequireDefault(obj) { - return obj && obj.__esModule ? obj : { default: obj } - } + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') + } - const rnds8Pool = new Uint8Array(256) // # of random values to pre-allocate + const { signal, opaque, responseHeaders } = opts - let poolPtr = rnds8Pool.length + if ( + signal && + typeof signal.on !== 'function' && + typeof signal.addEventListener !== 'function' + ) { + throw new InvalidArgumentError( + 'signal must be an EventEmitter or EventTarget' + ) + } - function rng() { - if (poolPtr > rnds8Pool.length - 16) { - _crypto.default.randomFillSync(rnds8Pool) + super('UNDICI_CONNECT') - poolPtr = 0 + this.opaque = opaque || null + this.responseHeaders = responseHeaders || null + this.callback = callback + this.abort = null + + addSignal(this, signal) } - return rnds8Pool.slice(poolPtr, (poolPtr += 16)) - } + onConnect(abort, context) { + if (!this.callback) { + throw new RequestAbortedError() + } - /***/ - }, + this.abort = abort + this.context = context + } - /***/ 5274: /***/ ( - __unused_webpack_module, - exports, - __nccwpck_require__ - ) => { - 'use strict' + onHeaders() { + throw new SocketError('bad connect', null) + } - Object.defineProperty(exports, '__esModule', { - value: true, - }) - exports['default'] = void 0 + onUpgrade(statusCode, rawHeaders, socket) { + const { callback, opaque, context } = this - var _crypto = _interopRequireDefault(__nccwpck_require__(6113)) + removeSignal(this) - function _interopRequireDefault(obj) { - return obj && obj.__esModule ? obj : { default: obj } - } + this.callback = null - function sha1(bytes) { - if (Array.isArray(bytes)) { - bytes = Buffer.from(bytes) - } else if (typeof bytes === 'string') { - bytes = Buffer.from(bytes, 'utf8') + let headers = rawHeaders + // Indicates is an HTTP2Session + if (headers != null) { + headers = + this.responseHeaders === 'raw' + ? util.parseRawHeaders(rawHeaders) + : util.parseHeaders(rawHeaders) + } + + this.runInAsyncScope(callback, null, null, { + statusCode, + headers, + socket, + opaque, + context, + }) } - return _crypto.default.createHash('sha1').update(bytes).digest() + onError(err) { + const { callback, opaque } = this + + removeSignal(this) + + if (callback) { + this.callback = null + queueMicrotask(() => { + this.runInAsyncScope(callback, null, err, { opaque }) + }) + } + } } - var _default = sha1 - exports['default'] = _default + function connect(opts, callback) { + if (callback === undefined) { + return new Promise((resolve, reject) => { + connect.call(this, opts, (err, data) => { + return err ? reject(err) : resolve(data) + }) + }) + } + + try { + const connectHandler = new ConnectHandler(opts, callback) + this.dispatch({ ...opts, method: 'CONNECT' }, connectHandler) + } catch (err) { + if (typeof callback !== 'function') { + throw err + } + const opaque = opts && opts.opaque + queueMicrotask(() => callback(err, { opaque })) + } + } + + module.exports = connect /***/ }, - /***/ 8950: /***/ ( - __unused_webpack_module, - exports, + /***/ 8752: /***/ ( + module, + __unused_webpack_exports, __nccwpck_require__ ) => { 'use strict' - Object.defineProperty(exports, '__esModule', { - value: true, - }) - exports['default'] = void 0 + const { Readable, Duplex, PassThrough } = __nccwpck_require__(2781) + const { + InvalidArgumentError, + InvalidReturnValueError, + RequestAbortedError, + } = __nccwpck_require__(8045) + const util = __nccwpck_require__(3983) + const { AsyncResource } = __nccwpck_require__(852) + const { addSignal, removeSignal } = __nccwpck_require__(7032) + const assert = __nccwpck_require__(9491) + + const kResume = Symbol('resume') + + class PipelineRequest extends Readable { + constructor() { + super({ autoDestroy: true }) - var _validate = _interopRequireDefault(__nccwpck_require__(6900)) + this[kResume] = null + } - function _interopRequireDefault(obj) { - return obj && obj.__esModule ? obj : { default: obj } - } + _read() { + const { [kResume]: resume } = this - /** - * Convert array of 16 byte values to UUID string format of the form: - * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX - */ - const byteToHex = [] + if (resume) { + this[kResume] = null + resume() + } + } - for (let i = 0; i < 256; ++i) { - byteToHex.push((i + 0x100).toString(16).substr(1)) + _destroy(err, callback) { + this._read() + + callback(err) + } } - function stringify(arr, offset = 0) { - // Note: Be careful editing this code! It's been tuned for performance - // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434 - const uuid = ( - byteToHex[arr[offset + 0]] + - byteToHex[arr[offset + 1]] + - byteToHex[arr[offset + 2]] + - byteToHex[arr[offset + 3]] + - '-' + - byteToHex[arr[offset + 4]] + - byteToHex[arr[offset + 5]] + - '-' + - byteToHex[arr[offset + 6]] + - byteToHex[arr[offset + 7]] + - '-' + - byteToHex[arr[offset + 8]] + - byteToHex[arr[offset + 9]] + - '-' + - byteToHex[arr[offset + 10]] + - byteToHex[arr[offset + 11]] + - byteToHex[arr[offset + 12]] + - byteToHex[arr[offset + 13]] + - byteToHex[arr[offset + 14]] + - byteToHex[arr[offset + 15]] - ).toLowerCase() // Consistency check for valid UUID. If this throws, it's likely due to one - // of the following: - // - One or more input array values don't map to a hex octet (leading to - // "undefined" in the uuid) - // - Invalid input values for the RFC `version` or `variant` fields + class PipelineResponse extends Readable { + constructor(resume) { + super({ autoDestroy: true }) + this[kResume] = resume + } - if (!(0, _validate.default)(uuid)) { - throw TypeError('Stringified UUID is invalid') + _read() { + this[kResume]() } - return uuid + _destroy(err, callback) { + if (!err && !this._readableState.endEmitted) { + err = new RequestAbortedError() + } + + callback(err) + } } - var _default = stringify - exports['default'] = _default + class PipelineHandler extends AsyncResource { + constructor(opts, handler) { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') + } - /***/ - }, + if (typeof handler !== 'function') { + throw new InvalidArgumentError('invalid handler') + } - /***/ 8628: /***/ ( - __unused_webpack_module, - exports, - __nccwpck_require__ - ) => { - 'use strict' + const { signal, method, opaque, onInfo, responseHeaders } = opts - Object.defineProperty(exports, '__esModule', { - value: true, - }) - exports['default'] = void 0 + if ( + signal && + typeof signal.on !== 'function' && + typeof signal.addEventListener !== 'function' + ) { + throw new InvalidArgumentError( + 'signal must be an EventEmitter or EventTarget' + ) + } - var _rng = _interopRequireDefault(__nccwpck_require__(807)) + if (method === 'CONNECT') { + throw new InvalidArgumentError('invalid method') + } - var _stringify = _interopRequireDefault(__nccwpck_require__(8950)) + if (onInfo && typeof onInfo !== 'function') { + throw new InvalidArgumentError('invalid onInfo callback') + } - function _interopRequireDefault(obj) { - return obj && obj.__esModule ? obj : { default: obj } - } + super('UNDICI_PIPELINE') - // **`v1()` - Generate time-based UUID** - // - // Inspired by https://github.com/LiosK/UUID.js - // and http://docs.python.org/library/uuid.html - let _nodeId + this.opaque = opaque || null + this.responseHeaders = responseHeaders || null + this.handler = handler + this.abort = null + this.context = null + this.onInfo = onInfo || null - let _clockseq // Previous uuid creation time + this.req = new PipelineRequest().on('error', util.nop) - let _lastMSecs = 0 - let _lastNSecs = 0 // See https://github.com/uuidjs/uuid for API details + this.ret = new Duplex({ + readableObjectMode: opts.objectMode, + autoDestroy: true, + read: () => { + const { body } = this - function v1(options, buf, offset) { - let i = (buf && offset) || 0 - const b = buf || new Array(16) - options = options || {} - let node = options.node || _nodeId - let clockseq = - options.clockseq !== undefined ? options.clockseq : _clockseq // node and clockseq need to be initialized to random values if they're not - // specified. We do this lazily to minimize issues related to insufficient - // system entropy. See #189 + if (body && body.resume) { + body.resume() + } + }, + write: (chunk, encoding, callback) => { + const { req } = this - if (node == null || clockseq == null) { - const seedBytes = options.random || (options.rng || _rng.default)() + if (req.push(chunk, encoding) || req._readableState.destroyed) { + callback() + } else { + req[kResume] = callback + } + }, + destroy: (err, callback) => { + const { body, req, res, ret, abort } = this - if (node == null) { - // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) - node = _nodeId = [ - seedBytes[0] | 0x01, - seedBytes[1], - seedBytes[2], - seedBytes[3], - seedBytes[4], - seedBytes[5], - ] - } + if (!err && !ret._readableState.endEmitted) { + err = new RequestAbortedError() + } - if (clockseq == null) { - // Per 4.2.2, randomize (14 bit) clockseq - clockseq = _clockseq = ((seedBytes[6] << 8) | seedBytes[7]) & 0x3fff - } - } // UUID timestamps are 100 nano-second units since the Gregorian epoch, - // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so - // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' - // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. + if (abort && err) { + abort() + } - let msecs = options.msecs !== undefined ? options.msecs : Date.now() // Per 4.2.1.2, use count of uuid's generated during the current clock - // cycle to simulate higher resolution clock + util.destroy(body, err) + util.destroy(req, err) + util.destroy(res, err) - let nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1 // Time since last uuid creation (in msecs) + removeSignal(this) - const dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 10000 // Per 4.2.1.2, Bump clockseq on clock regression + callback(err) + }, + }).on('prefinish', () => { + const { req } = this - if (dt < 0 && options.clockseq === undefined) { - clockseq = (clockseq + 1) & 0x3fff - } // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new - // time interval + // Node < 15 does not call _final in same tick. + req.push(null) + }) - if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { - nsecs = 0 - } // Per 4.2.1.2 Throw error if too many uuids are requested + this.res = null - if (nsecs >= 10000) { - throw new Error("uuid.v1(): Can't create more than 10M uuids/sec") + addSignal(this, signal) } - _lastMSecs = msecs - _lastNSecs = nsecs - _clockseq = clockseq // Per 4.1.4 - Convert from unix epoch to Gregorian epoch + onConnect(abort, context) { + const { ret, res } = this - msecs += 12219292800000 // `time_low` + assert(!res, 'pipeline cannot be retried') - const tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000 - b[i++] = (tl >>> 24) & 0xff - b[i++] = (tl >>> 16) & 0xff - b[i++] = (tl >>> 8) & 0xff - b[i++] = tl & 0xff // `time_mid` + if (ret.destroyed) { + throw new RequestAbortedError() + } - const tmh = ((msecs / 0x100000000) * 10000) & 0xfffffff - b[i++] = (tmh >>> 8) & 0xff - b[i++] = tmh & 0xff // `time_high_and_version` + this.abort = abort + this.context = context + } - b[i++] = ((tmh >>> 24) & 0xf) | 0x10 // include version + onHeaders(statusCode, rawHeaders, resume) { + const { opaque, handler, context } = this - b[i++] = (tmh >>> 16) & 0xff // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) + if (statusCode < 200) { + if (this.onInfo) { + const headers = + this.responseHeaders === 'raw' + ? util.parseRawHeaders(rawHeaders) + : util.parseHeaders(rawHeaders) + this.onInfo({ statusCode, headers }) + } + return + } - b[i++] = (clockseq >>> 8) | 0x80 // `clock_seq_low` + this.res = new PipelineResponse(resume) - b[i++] = clockseq & 0xff // `node` + let body + try { + this.handler = null + const headers = + this.responseHeaders === 'raw' + ? util.parseRawHeaders(rawHeaders) + : util.parseHeaders(rawHeaders) + body = this.runInAsyncScope(handler, null, { + statusCode, + headers, + opaque, + body: this.res, + context, + }) + } catch (err) { + this.res.on('error', util.nop) + throw err + } - for (let n = 0; n < 6; ++n) { - b[i + n] = node[n] - } + if (!body || typeof body.on !== 'function') { + throw new InvalidReturnValueError('expected Readable') + } - return buf || (0, _stringify.default)(b) - } + body + .on('data', (chunk) => { + const { ret, body } = this - var _default = v1 - exports['default'] = _default + if (!ret.push(chunk) && body.pause) { + body.pause() + } + }) + .on('error', (err) => { + const { ret } = this - /***/ - }, + util.destroy(ret, err) + }) + .on('end', () => { + const { ret } = this - /***/ 6409: /***/ ( - __unused_webpack_module, - exports, - __nccwpck_require__ - ) => { - 'use strict' + ret.push(null) + }) + .on('close', () => { + const { ret } = this - Object.defineProperty(exports, '__esModule', { - value: true, - }) - exports['default'] = void 0 + if (!ret._readableState.ended) { + util.destroy(ret, new RequestAbortedError()) + } + }) - var _v = _interopRequireDefault(__nccwpck_require__(5998)) + this.body = body + } - var _md = _interopRequireDefault(__nccwpck_require__(4569)) + onData(chunk) { + const { res } = this + return res.push(chunk) + } - function _interopRequireDefault(obj) { - return obj && obj.__esModule ? obj : { default: obj } + onComplete(trailers) { + const { res } = this + res.push(null) + } + + onError(err) { + const { ret } = this + this.handler = null + util.destroy(ret, err) + } } - const v3 = (0, _v.default)('v3', 0x30, _md.default) - var _default = v3 - exports['default'] = _default + function pipeline(opts, handler) { + try { + const pipelineHandler = new PipelineHandler(opts, handler) + this.dispatch({ ...opts, body: pipelineHandler.req }, pipelineHandler) + return pipelineHandler.ret + } catch (err) { + return new PassThrough().destroy(err) + } + } + + module.exports = pipeline /***/ }, - /***/ 5998: /***/ ( - __unused_webpack_module, - exports, + /***/ 5448: /***/ ( + module, + __unused_webpack_exports, __nccwpck_require__ ) => { 'use strict' - Object.defineProperty(exports, '__esModule', { - value: true, - }) - exports['default'] = _default - exports.URL = exports.DNS = void 0 + const Readable = __nccwpck_require__(3858) + const { InvalidArgumentError, RequestAbortedError } = + __nccwpck_require__(8045) + const util = __nccwpck_require__(3983) + const { getResolveErrorBodyCallback } = __nccwpck_require__(7474) + const { AsyncResource } = __nccwpck_require__(852) + const { addSignal, removeSignal } = __nccwpck_require__(7032) - var _stringify = _interopRequireDefault(__nccwpck_require__(8950)) + class RequestHandler extends AsyncResource { + constructor(opts, callback) { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') + } - var _parse = _interopRequireDefault(__nccwpck_require__(2746)) + const { + signal, + method, + opaque, + body, + onInfo, + responseHeaders, + throwOnError, + highWaterMark, + } = opts - function _interopRequireDefault(obj) { - return obj && obj.__esModule ? obj : { default: obj } - } + try { + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') + } - function stringToBytes(str) { - str = unescape(encodeURIComponent(str)) // UTF8 escape + if ( + highWaterMark && + (typeof highWaterMark !== 'number' || highWaterMark < 0) + ) { + throw new InvalidArgumentError('invalid highWaterMark') + } - const bytes = [] + if ( + signal && + typeof signal.on !== 'function' && + typeof signal.addEventListener !== 'function' + ) { + throw new InvalidArgumentError( + 'signal must be an EventEmitter or EventTarget' + ) + } - for (let i = 0; i < str.length; ++i) { - bytes.push(str.charCodeAt(i)) + if (method === 'CONNECT') { + throw new InvalidArgumentError('invalid method') + } + + if (onInfo && typeof onInfo !== 'function') { + throw new InvalidArgumentError('invalid onInfo callback') + } + + super('UNDICI_REQUEST') + } catch (err) { + if (util.isStream(body)) { + util.destroy(body.on('error', util.nop), err) + } + throw err + } + + this.responseHeaders = responseHeaders || null + this.opaque = opaque || null + this.callback = callback + this.res = null + this.abort = null + this.body = body + this.trailers = {} + this.context = null + this.onInfo = onInfo || null + this.throwOnError = throwOnError + this.highWaterMark = highWaterMark + + if (util.isStream(body)) { + body.on('error', (err) => { + this.onError(err) + }) + } + + addSignal(this, signal) } - return bytes - } + onConnect(abort, context) { + if (!this.callback) { + throw new RequestAbortedError() + } - const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8' - exports.DNS = DNS - const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8' - exports.URL = URL + this.abort = abort + this.context = context + } - function _default(name, version, hashfunc) { - function generateUUID(value, namespace, buf, offset) { - if (typeof value === 'string') { - value = stringToBytes(value) + onHeaders(statusCode, rawHeaders, resume, statusMessage) { + const { + callback, + opaque, + abort, + context, + responseHeaders, + highWaterMark, + } = this + + const headers = + responseHeaders === 'raw' + ? util.parseRawHeaders(rawHeaders) + : util.parseHeaders(rawHeaders) + + if (statusCode < 200) { + if (this.onInfo) { + this.onInfo({ statusCode, headers }) + } + return } - if (typeof namespace === 'string') { - namespace = (0, _parse.default)(namespace) + const parsedHeaders = + responseHeaders === 'raw' ? util.parseHeaders(rawHeaders) : headers + const contentType = parsedHeaders['content-type'] + const body = new Readable({ + resume, + abort, + contentType, + highWaterMark, + }) + + this.callback = null + this.res = body + if (callback !== null) { + if (this.throwOnError && statusCode >= 400) { + this.runInAsyncScope(getResolveErrorBodyCallback, null, { + callback, + body, + contentType, + statusCode, + statusMessage, + headers, + }) + } else { + this.runInAsyncScope(callback, null, null, { + statusCode, + headers, + trailers: this.trailers, + opaque, + body, + context, + }) + } } + } - if (namespace.length !== 16) { - throw TypeError( - 'Namespace must be array-like (16 iterable integer values, 0-255)' - ) - } // Compute hash of namespace and value, Per 4.3 - // Future: Use spread syntax when supported on all platforms, e.g. `bytes = - // hashfunc([...namespace, ... value])` + onData(chunk) { + const { res } = this + return res.push(chunk) + } - let bytes = new Uint8Array(16 + value.length) - bytes.set(namespace) - bytes.set(value, namespace.length) - bytes = hashfunc(bytes) - bytes[6] = (bytes[6] & 0x0f) | version - bytes[8] = (bytes[8] & 0x3f) | 0x80 + onComplete(trailers) { + const { res } = this - if (buf) { - offset = offset || 0 + removeSignal(this) - for (let i = 0; i < 16; ++i) { - buf[offset + i] = bytes[i] - } + util.parseHeaders(trailers, this.trailers) - return buf + res.push(null) + } + + onError(err) { + const { res, callback, body, opaque } = this + + removeSignal(this) + + if (callback) { + // TODO: Does this need queueMicrotask? + this.callback = null + queueMicrotask(() => { + this.runInAsyncScope(callback, null, err, { opaque }) + }) } - return (0, _stringify.default)(bytes) - } // Function#name is not settable on some platforms (#270) + if (res) { + this.res = null + // Ensure all queued handlers are invoked before destroying res. + queueMicrotask(() => { + util.destroy(res, err) + }) + } - try { - generateUUID.name = name // eslint-disable-next-line no-empty - } catch (err) {} // For CommonJS default export support + if (body) { + this.body = null + util.destroy(body, err) + } + } + } - generateUUID.DNS = DNS - generateUUID.URL = URL - return generateUUID + function request(opts, callback) { + if (callback === undefined) { + return new Promise((resolve, reject) => { + request.call(this, opts, (err, data) => { + return err ? reject(err) : resolve(data) + }) + }) + } + + try { + this.dispatch(opts, new RequestHandler(opts, callback)) + } catch (err) { + if (typeof callback !== 'function') { + throw err + } + const opaque = opts && opts.opaque + queueMicrotask(() => callback(err, { opaque })) + } } + module.exports = request + /***/ }, - /***/ 5122: /***/ ( - __unused_webpack_module, - exports, + /***/ 5395: /***/ ( + module, + __unused_webpack_exports, __nccwpck_require__ ) => { 'use strict' - Object.defineProperty(exports, '__esModule', { - value: true, - }) - exports['default'] = void 0 + const { finished, PassThrough } = __nccwpck_require__(2781) + const { + InvalidArgumentError, + InvalidReturnValueError, + RequestAbortedError, + } = __nccwpck_require__(8045) + const util = __nccwpck_require__(3983) + const { getResolveErrorBodyCallback } = __nccwpck_require__(7474) + const { AsyncResource } = __nccwpck_require__(852) + const { addSignal, removeSignal } = __nccwpck_require__(7032) + + class StreamHandler extends AsyncResource { + constructor(opts, factory, callback) { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') + } + + const { + signal, + method, + opaque, + body, + onInfo, + responseHeaders, + throwOnError, + } = opts - var _rng = _interopRequireDefault(__nccwpck_require__(807)) + try { + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') + } - var _stringify = _interopRequireDefault(__nccwpck_require__(8950)) + if (typeof factory !== 'function') { + throw new InvalidArgumentError('invalid factory') + } - function _interopRequireDefault(obj) { - return obj && obj.__esModule ? obj : { default: obj } - } + if ( + signal && + typeof signal.on !== 'function' && + typeof signal.addEventListener !== 'function' + ) { + throw new InvalidArgumentError( + 'signal must be an EventEmitter or EventTarget' + ) + } - function v4(options, buf, offset) { - options = options || {} + if (method === 'CONNECT') { + throw new InvalidArgumentError('invalid method') + } - const rnds = options.random || (options.rng || _rng.default)() // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` + if (onInfo && typeof onInfo !== 'function') { + throw new InvalidArgumentError('invalid onInfo callback') + } - rnds[6] = (rnds[6] & 0x0f) | 0x40 - rnds[8] = (rnds[8] & 0x3f) | 0x80 // Copy bytes to buffer, if provided + super('UNDICI_STREAM') + } catch (err) { + if (util.isStream(body)) { + util.destroy(body.on('error', util.nop), err) + } + throw err + } + + this.responseHeaders = responseHeaders || null + this.opaque = opaque || null + this.factory = factory + this.callback = callback + this.res = null + this.abort = null + this.context = null + this.trailers = null + this.body = body + this.onInfo = onInfo || null + this.throwOnError = throwOnError || false + + if (util.isStream(body)) { + body.on('error', (err) => { + this.onError(err) + }) + } - if (buf) { - offset = offset || 0 + addSignal(this, signal) + } - for (let i = 0; i < 16; ++i) { - buf[offset + i] = rnds[i] + onConnect(abort, context) { + if (!this.callback) { + throw new RequestAbortedError() } - return buf + this.abort = abort + this.context = context } - return (0, _stringify.default)(rnds) - } + onHeaders(statusCode, rawHeaders, resume, statusMessage) { + const { factory, opaque, context, callback, responseHeaders } = this - var _default = v4 - exports['default'] = _default + const headers = + responseHeaders === 'raw' + ? util.parseRawHeaders(rawHeaders) + : util.parseHeaders(rawHeaders) - /***/ - }, + if (statusCode < 200) { + if (this.onInfo) { + this.onInfo({ statusCode, headers }) + } + return + } - /***/ 9120: /***/ ( - __unused_webpack_module, - exports, - __nccwpck_require__ - ) => { - 'use strict' + this.factory = null - Object.defineProperty(exports, '__esModule', { - value: true, - }) - exports['default'] = void 0 + let res - var _v = _interopRequireDefault(__nccwpck_require__(5998)) + if (this.throwOnError && statusCode >= 400) { + const parsedHeaders = + responseHeaders === 'raw' + ? util.parseHeaders(rawHeaders) + : headers + const contentType = parsedHeaders['content-type'] + res = new PassThrough() - var _sha = _interopRequireDefault(__nccwpck_require__(5274)) + this.callback = null + this.runInAsyncScope(getResolveErrorBodyCallback, null, { + callback, + body: res, + contentType, + statusCode, + statusMessage, + headers, + }) + } else { + if (factory === null) { + return + } - function _interopRequireDefault(obj) { - return obj && obj.__esModule ? obj : { default: obj } - } + res = this.runInAsyncScope(factory, null, { + statusCode, + headers, + opaque, + context, + }) - const v5 = (0, _v.default)('v5', 0x50, _sha.default) - var _default = v5 - exports['default'] = _default + if ( + !res || + typeof res.write !== 'function' || + typeof res.end !== 'function' || + typeof res.on !== 'function' + ) { + throw new InvalidReturnValueError('expected Writable') + } - /***/ - }, + // TODO: Avoid finished. It registers an unnecessary amount of listeners. + finished(res, { readable: false }, (err) => { + const { callback, res, opaque, trailers, abort } = this - /***/ 6900: /***/ ( - __unused_webpack_module, - exports, - __nccwpck_require__ - ) => { - 'use strict' + this.res = null + if (err || !res.readable) { + util.destroy(res, err) + } - Object.defineProperty(exports, '__esModule', { - value: true, - }) - exports['default'] = void 0 + this.callback = null + this.runInAsyncScope(callback, null, err || null, { + opaque, + trailers, + }) - var _regex = _interopRequireDefault(__nccwpck_require__(814)) + if (err) { + abort() + } + }) + } - function _interopRequireDefault(obj) { - return obj && obj.__esModule ? obj : { default: obj } - } + res.on('drain', resume) - function validate(uuid) { - return typeof uuid === 'string' && _regex.default.test(uuid) - } + this.res = res - var _default = validate - exports['default'] = _default + const needDrain = + res.writableNeedDrain !== undefined + ? res.writableNeedDrain + : res._writableState && res._writableState.needDrain - /***/ - }, + return needDrain !== true + } - /***/ 1595: /***/ ( - __unused_webpack_module, - exports, - __nccwpck_require__ - ) => { - 'use strict' + onData(chunk) { + const { res } = this - Object.defineProperty(exports, '__esModule', { - value: true, - }) - exports['default'] = void 0 + return res ? res.write(chunk) : true + } - var _validate = _interopRequireDefault(__nccwpck_require__(6900)) + onComplete(trailers) { + const { res } = this - function _interopRequireDefault(obj) { - return obj && obj.__esModule ? obj : { default: obj } + removeSignal(this) + + if (!res) { + return + } + + this.trailers = util.parseHeaders(trailers) + + res.end() + } + + onError(err) { + const { res, callback, opaque, body } = this + + removeSignal(this) + + this.factory = null + + if (res) { + this.res = null + util.destroy(res, err) + } else if (callback) { + this.callback = null + queueMicrotask(() => { + this.runInAsyncScope(callback, null, err, { opaque }) + }) + } + + if (body) { + this.body = null + util.destroy(body, err) + } + } } - function version(uuid) { - if (!(0, _validate.default)(uuid)) { - throw TypeError('Invalid UUID') + function stream(opts, factory, callback) { + if (callback === undefined) { + return new Promise((resolve, reject) => { + stream.call(this, opts, factory, (err, data) => { + return err ? reject(err) : resolve(data) + }) + }) } - return parseInt(uuid.substr(14, 1), 16) + try { + this.dispatch(opts, new StreamHandler(opts, factory, callback)) + } catch (err) { + if (typeof callback !== 'function') { + throw err + } + const opaque = opts && opts.opaque + queueMicrotask(() => callback(err, { opaque })) + } } - var _default = version - exports['default'] = _default + module.exports = stream /***/ }, - /***/ 4886: /***/ (module) => { + /***/ 6923: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { 'use strict' - var conversions = {} - module.exports = conversions + const { InvalidArgumentError, RequestAbortedError, SocketError } = + __nccwpck_require__(8045) + const { AsyncResource } = __nccwpck_require__(852) + const util = __nccwpck_require__(3983) + const { addSignal, removeSignal } = __nccwpck_require__(7032) + const assert = __nccwpck_require__(9491) - function sign(x) { - return x < 0 ? -1 : 1 - } - - function evenRound(x) { - // Round x to the nearest integer, choosing the even integer if it lies halfway between two. - if (x % 1 === 0.5 && (x & 1) === 0) { - // [even number].5; round down (i.e. floor) - return Math.floor(x) - } else { - return Math.round(x) - } - } - - function createNumberConversion(bitLength, typeOpts) { - if (!typeOpts.unsigned) { - --bitLength - } - const lowerBound = typeOpts.unsigned ? 0 : -Math.pow(2, bitLength) - const upperBound = Math.pow(2, bitLength) - 1 - - const moduloVal = typeOpts.moduloBitLength - ? Math.pow(2, typeOpts.moduloBitLength) - : Math.pow(2, bitLength) - const moduloBound = typeOpts.moduloBitLength - ? Math.pow(2, typeOpts.moduloBitLength - 1) - : Math.pow(2, bitLength - 1) - - return function (V, opts) { - if (!opts) opts = {} - - let x = +V - - if (opts.enforceRange) { - if (!Number.isFinite(x)) { - throw new TypeError('Argument is not a finite number') - } - - x = sign(x) * Math.floor(Math.abs(x)) - if (x < lowerBound || x > upperBound) { - throw new TypeError('Argument is not in byte range') - } - - return x - } - - if (!isNaN(x) && opts.clamp) { - x = evenRound(x) - - if (x < lowerBound) x = lowerBound - if (x > upperBound) x = upperBound - return x + class UpgradeHandler extends AsyncResource { + constructor(opts, callback) { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('invalid opts') } - if (!Number.isFinite(x) || x === 0) { - return 0 + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') } - x = sign(x) * Math.floor(Math.abs(x)) - x = x % moduloVal + const { signal, opaque, responseHeaders } = opts - if (!typeOpts.unsigned && x >= moduloBound) { - return x - moduloVal - } else if (typeOpts.unsigned) { - if (x < 0) { - x += moduloVal - } else if (x === -0) { - // don't return negative zero - return 0 - } + if ( + signal && + typeof signal.on !== 'function' && + typeof signal.addEventListener !== 'function' + ) { + throw new InvalidArgumentError( + 'signal must be an EventEmitter or EventTarget' + ) } - return x - } - } - - conversions['void'] = function () { - return undefined - } - - conversions['boolean'] = function (val) { - return !!val - } - - conversions['byte'] = createNumberConversion(8, { unsigned: false }) - conversions['octet'] = createNumberConversion(8, { unsigned: true }) - - conversions['short'] = createNumberConversion(16, { unsigned: false }) - conversions['unsigned short'] = createNumberConversion(16, { - unsigned: true, - }) - - conversions['long'] = createNumberConversion(32, { unsigned: false }) - conversions['unsigned long'] = createNumberConversion(32, { - unsigned: true, - }) - - conversions['long long'] = createNumberConversion(32, { - unsigned: false, - moduloBitLength: 64, - }) - conversions['unsigned long long'] = createNumberConversion(32, { - unsigned: true, - moduloBitLength: 64, - }) + super('UNDICI_UPGRADE') - conversions['double'] = function (V) { - const x = +V + this.responseHeaders = responseHeaders || null + this.opaque = opaque || null + this.callback = callback + this.abort = null + this.context = null - if (!Number.isFinite(x)) { - throw new TypeError('Argument is not a finite floating-point value') + addSignal(this, signal) } - return x - } + onConnect(abort, context) { + if (!this.callback) { + throw new RequestAbortedError() + } - conversions['unrestricted double'] = function (V) { - const x = +V + this.abort = abort + this.context = null + } - if (isNaN(x)) { - throw new TypeError('Argument is NaN') + onHeaders() { + throw new SocketError('bad upgrade', null) } - return x - } + onUpgrade(statusCode, rawHeaders, socket) { + const { callback, opaque, context } = this - // not quite valid, but good enough for JS - conversions['float'] = conversions['double'] - conversions['unrestricted float'] = conversions['unrestricted double'] + assert.strictEqual(statusCode, 101) - conversions['DOMString'] = function (V, opts) { - if (!opts) opts = {} + removeSignal(this) - if (opts.treatNullAsEmptyString && V === null) { - return '' + this.callback = null + const headers = + this.responseHeaders === 'raw' + ? util.parseRawHeaders(rawHeaders) + : util.parseHeaders(rawHeaders) + this.runInAsyncScope(callback, null, null, { + headers, + socket, + opaque, + context, + }) } - return String(V) - } + onError(err) { + const { callback, opaque } = this - conversions['ByteString'] = function (V, opts) { - const x = String(V) - let c = undefined - for (let i = 0; (c = x.codePointAt(i)) !== undefined; ++i) { - if (c > 255) { - throw new TypeError('Argument is not a valid bytestring') + removeSignal(this) + + if (callback) { + this.callback = null + queueMicrotask(() => { + this.runInAsyncScope(callback, null, err, { opaque }) + }) } } - - return x } - conversions['USVString'] = function (V) { - const S = String(V) - const n = S.length - const U = [] - for (let i = 0; i < n; ++i) { - const c = S.charCodeAt(i) - if (c < 0xd800 || c > 0xdfff) { - U.push(String.fromCodePoint(c)) - } else if (0xdc00 <= c && c <= 0xdfff) { - U.push(String.fromCodePoint(0xfffd)) - } else { - if (i === n - 1) { - U.push(String.fromCodePoint(0xfffd)) - } else { - const d = S.charCodeAt(i + 1) - if (0xdc00 <= d && d <= 0xdfff) { - const a = c & 0x3ff - const b = d & 0x3ff - U.push(String.fromCodePoint((2 << 15) + (2 << 9) * a + b)) - ++i - } else { - U.push(String.fromCodePoint(0xfffd)) - } - } - } + function upgrade(opts, callback) { + if (callback === undefined) { + return new Promise((resolve, reject) => { + upgrade.call(this, opts, (err, data) => { + return err ? reject(err) : resolve(data) + }) + }) } - return U.join('') + try { + const upgradeHandler = new UpgradeHandler(opts, callback) + this.dispatch( + { + ...opts, + method: opts.method || 'GET', + upgrade: opts.protocol || 'Websocket', + }, + upgradeHandler + ) + } catch (err) { + if (typeof callback !== 'function') { + throw err + } + const opaque = opts && opts.opaque + queueMicrotask(() => callback(err, { opaque })) + } } - conversions['Date'] = function (V, opts) { - if (!(V instanceof Date)) { - throw new TypeError('Argument is not a Date object') - } - if (isNaN(V)) { - return undefined - } + module.exports = upgrade - return V - } + /***/ + }, - conversions['RegExp'] = function (V, opts) { - if (!(V instanceof RegExp)) { - V = new RegExp(V) - } + /***/ 4059: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' - return V - } + module.exports.request = __nccwpck_require__(5448) + module.exports.stream = __nccwpck_require__(5395) + module.exports.pipeline = __nccwpck_require__(8752) + module.exports.upgrade = __nccwpck_require__(6923) + module.exports.connect = __nccwpck_require__(9744) /***/ }, - /***/ 7537: /***/ ( - __unused_webpack_module, - exports, + /***/ 3858: /***/ ( + module, + __unused_webpack_exports, __nccwpck_require__ ) => { 'use strict' + // Ported from https://github.com/nodejs/undici/pull/907 + + const assert = __nccwpck_require__(9491) + const { Readable } = __nccwpck_require__(2781) + const { RequestAbortedError, NotSupportedError, InvalidArgumentError } = + __nccwpck_require__(8045) + const util = __nccwpck_require__(3983) + const { ReadableStreamFrom, toUSVString } = __nccwpck_require__(3983) + + let Blob + + const kConsume = Symbol('kConsume') + const kReading = Symbol('kReading') + const kBody = Symbol('kBody') + const kAbort = Symbol('abort') + const kContentType = Symbol('kContentType') + + module.exports = class BodyReadable extends Readable { + constructor({ + resume, + abort, + contentType = '', + highWaterMark = 64 * 1024, // Same as nodejs fs streams. + }) { + super({ + autoDestroy: true, + read: resume, + highWaterMark, + }) - const usm = __nccwpck_require__(2158) + this._readableState.dataEmitted = false - exports.implementation = class URLImpl { - constructor(constructorArgs) { - const url = constructorArgs[0] - const base = constructorArgs[1] + this[kAbort] = abort + this[kConsume] = null + this[kBody] = null + this[kContentType] = contentType - let parsedBase = null - if (base !== undefined) { - parsedBase = usm.basicURLParse(base) - if (parsedBase === 'failure') { - throw new TypeError('Invalid base URL') - } + // Is stream being consumed through Readable API? + // This is an optimization so that we avoid checking + // for 'data' and 'readable' listeners in the hot path + // inside push(). + this[kReading] = false + } + + destroy(err) { + if (this.destroyed) { + // Node < 16 + return this } - const parsedURL = usm.basicURLParse(url, { baseURL: parsedBase }) - if (parsedURL === 'failure') { - throw new TypeError('Invalid URL') + if (!err && !this._readableState.endEmitted) { + err = new RequestAbortedError() } - this._url = parsedURL + if (err) { + this[kAbort]() + } - // TODO: query stuff + return super.destroy(err) } - get href() { - return usm.serializeURL(this._url) + emit(ev, ...args) { + if (ev === 'data') { + // Node < 16.7 + this._readableState.dataEmitted = true + } else if (ev === 'error') { + // Node < 16 + this._readableState.errorEmitted = true + } + return super.emit(ev, ...args) } - set href(v) { - const parsedURL = usm.basicURLParse(v) - if (parsedURL === 'failure') { - throw new TypeError('Invalid URL') + on(ev, ...args) { + if (ev === 'data' || ev === 'readable') { + this[kReading] = true } - - this._url = parsedURL + return super.on(ev, ...args) } - get origin() { - return usm.serializeURLOrigin(this._url) + addListener(ev, ...args) { + return this.on(ev, ...args) } - get protocol() { - return this._url.scheme + ':' + off(ev, ...args) { + const ret = super.off(ev, ...args) + if (ev === 'data' || ev === 'readable') { + this[kReading] = + this.listenerCount('data') > 0 || + this.listenerCount('readable') > 0 + } + return ret } - set protocol(v) { - usm.basicURLParse(v + ':', { - url: this._url, - stateOverride: 'scheme start', - }) + removeListener(ev, ...args) { + return this.off(ev, ...args) } - get username() { - return this._url.username + push(chunk) { + if (this[kConsume] && chunk !== null && this.readableLength === 0) { + consumePush(this[kConsume], chunk) + return this[kReading] ? super.push(chunk) : true + } + return super.push(chunk) } - set username(v) { - if (usm.cannotHaveAUsernamePasswordPort(this._url)) { - return - } + // https://fetch.spec.whatwg.org/#dom-body-text + async text() { + return consume(this, 'text') + } - usm.setTheUsername(this._url, v) + // https://fetch.spec.whatwg.org/#dom-body-json + async json() { + return consume(this, 'json') } - get password() { - return this._url.password + // https://fetch.spec.whatwg.org/#dom-body-blob + async blob() { + return consume(this, 'blob') } - set password(v) { - if (usm.cannotHaveAUsernamePasswordPort(this._url)) { - return - } + // https://fetch.spec.whatwg.org/#dom-body-arraybuffer + async arrayBuffer() { + return consume(this, 'arrayBuffer') + } - usm.setThePassword(this._url, v) + // https://fetch.spec.whatwg.org/#dom-body-formdata + async formData() { + // TODO: Implement. + throw new NotSupportedError() } - get host() { - const url = this._url + // https://fetch.spec.whatwg.org/#dom-body-bodyused + get bodyUsed() { + return util.isDisturbed(this) + } - if (url.host === null) { - return '' + // https://fetch.spec.whatwg.org/#dom-body-body + get body() { + if (!this[kBody]) { + this[kBody] = ReadableStreamFrom(this) + if (this[kConsume]) { + // TODO: Is this the best way to force a lock? + this[kBody].getReader() // Ensure stream is locked. + assert(this[kBody].locked) + } } + return this[kBody] + } - if (url.port === null) { - return usm.serializeHost(url.host) + async dump(opts) { + let limit = opts && Number.isFinite(opts.limit) ? opts.limit : 262144 + const signal = opts && opts.signal + const abortFn = () => { + this.destroy() + } + let signalListenerCleanup + if (signal) { + if (typeof signal !== 'object' || !('aborted' in signal)) { + throw new InvalidArgumentError('signal must be an AbortSignal') + } + util.throwIfAborted(signal) + signalListenerCleanup = util.addAbortListener(signal, abortFn) + } + try { + for await (const chunk of this) { + util.throwIfAborted(signal) + limit -= Buffer.byteLength(chunk) + if (limit < 0) { + return + } + } + } catch { + util.throwIfAborted(signal) + } finally { + if (typeof signalListenerCleanup === 'function') { + signalListenerCleanup() + } else if (signalListenerCleanup) { + signalListenerCleanup[Symbol.dispose]() + } } + } + } - return ( - usm.serializeHost(url.host) + ':' + usm.serializeInteger(url.port) - ) + // https://streams.spec.whatwg.org/#readablestream-locked + function isLocked(self) { + // Consume is an implicit lock. + return (self[kBody] && self[kBody].locked === true) || self[kConsume] + } + + // https://fetch.spec.whatwg.org/#body-unusable + function isUnusable(self) { + return util.isDisturbed(self) || isLocked(self) + } + + async function consume(stream, type) { + if (isUnusable(stream)) { + throw new TypeError('unusable') } - set host(v) { - if (this._url.cannotBeABaseURL) { - return + assert(!stream[kConsume]) + + return new Promise((resolve, reject) => { + stream[kConsume] = { + type, + stream, + resolve, + reject, + length: 0, + body: [], } - usm.basicURLParse(v, { url: this._url, stateOverride: 'host' }) + stream + .on('error', function (err) { + consumeFinish(this[kConsume], err) + }) + .on('close', function () { + if (this[kConsume].body !== null) { + consumeFinish(this[kConsume], new RequestAbortedError()) + } + }) + + process.nextTick(consumeStart, stream[kConsume]) + }) + } + + function consumeStart(consume) { + if (consume.body === null) { + return } - get hostname() { - if (this._url.host === null) { - return '' - } + const { _readableState: state } = consume.stream - return usm.serializeHost(this._url.host) + for (const chunk of state.buffer) { + consumePush(consume, chunk) } - set hostname(v) { - if (this._url.cannotBeABaseURL) { - return + if (state.endEmitted) { + consumeEnd(this[kConsume]) + } else { + consume.stream.on('end', function () { + consumeEnd(this[kConsume]) + }) + } + + consume.stream.resume() + + while (consume.stream.read() != null) { + // Loop + } + } + + function consumeEnd(consume) { + const { type, body, resolve, stream, length } = consume + + try { + if (type === 'text') { + resolve(toUSVString(Buffer.concat(body))) + } else if (type === 'json') { + resolve(JSON.parse(Buffer.concat(body))) + } else if (type === 'arrayBuffer') { + const dst = new Uint8Array(length) + + let pos = 0 + for (const buf of body) { + dst.set(buf, pos) + pos += buf.byteLength + } + + resolve(dst.buffer) + } else if (type === 'blob') { + if (!Blob) { + Blob = __nccwpck_require__(4300).Blob + } + resolve(new Blob(body, { type: stream[kContentType] })) } - usm.basicURLParse(v, { url: this._url, stateOverride: 'hostname' }) + consumeFinish(consume) + } catch (err) { + stream.destroy(err) } + } - get port() { - if (this._url.port === null) { - return '' + function consumePush(consume, chunk) { + consume.length += chunk.length + consume.body.push(chunk) + } + + function consumeFinish(consume, err) { + if (consume.body === null) { + return + } + + if (err) { + consume.reject(err) + } else { + consume.resolve() + } + + consume.type = null + consume.stream = null + consume.resolve = null + consume.reject = null + consume.length = 0 + consume.body = null + } + + /***/ + }, + + /***/ 7474: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + const assert = __nccwpck_require__(9491) + const { ResponseStatusCodeError } = __nccwpck_require__(8045) + const { toUSVString } = __nccwpck_require__(3983) + + async function getResolveErrorBodyCallback({ + callback, + body, + contentType, + statusCode, + statusMessage, + headers, + }) { + assert(body) + + let chunks = [] + let limit = 0 + + for await (const chunk of body) { + chunks.push(chunk) + limit += chunk.length + if (limit > 128 * 1024) { + chunks = null + break } + } - return usm.serializeInteger(this._url.port) + if (statusCode === 204 || !contentType || !chunks) { + process.nextTick( + callback, + new ResponseStatusCodeError( + `Response status code ${statusCode}${ + statusMessage ? `: ${statusMessage}` : '' + }`, + statusCode, + headers + ) + ) + return } - set port(v) { - if (usm.cannotHaveAUsernamePasswordPort(this._url)) { + try { + if (contentType.startsWith('application/json')) { + const payload = JSON.parse(toUSVString(Buffer.concat(chunks))) + process.nextTick( + callback, + new ResponseStatusCodeError( + `Response status code ${statusCode}${ + statusMessage ? `: ${statusMessage}` : '' + }`, + statusCode, + headers, + payload + ) + ) return } - if (v === '') { - this._url.port = null - } else { - usm.basicURLParse(v, { url: this._url, stateOverride: 'port' }) + if (contentType.startsWith('text/')) { + const payload = toUSVString(Buffer.concat(chunks)) + process.nextTick( + callback, + new ResponseStatusCodeError( + `Response status code ${statusCode}${ + statusMessage ? `: ${statusMessage}` : '' + }`, + statusCode, + headers, + payload + ) + ) + return } + } catch (err) { + // Process in a fallback if error } - get pathname() { - if (this._url.cannotBeABaseURL) { - return this._url.path[0] + process.nextTick( + callback, + new ResponseStatusCodeError( + `Response status code ${statusCode}${ + statusMessage ? `: ${statusMessage}` : '' + }`, + statusCode, + headers + ) + ) + } + + module.exports = { getResolveErrorBodyCallback } + + /***/ + }, + + /***/ 7931: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const { BalancedPoolMissingUpstreamError, InvalidArgumentError } = + __nccwpck_require__(8045) + const { + PoolBase, + kClients, + kNeedDrain, + kAddClient, + kRemoveClient, + kGetDispatcher, + } = __nccwpck_require__(3198) + const Pool = __nccwpck_require__(4634) + const { kUrl, kInterceptors } = __nccwpck_require__(2785) + const { parseOrigin } = __nccwpck_require__(3983) + const kFactory = Symbol('factory') + + const kOptions = Symbol('options') + const kGreatestCommonDivisor = Symbol('kGreatestCommonDivisor') + const kCurrentWeight = Symbol('kCurrentWeight') + const kIndex = Symbol('kIndex') + const kWeight = Symbol('kWeight') + const kMaxWeightPerServer = Symbol('kMaxWeightPerServer') + const kErrorPenalty = Symbol('kErrorPenalty') + + function getGreatestCommonDivisor(a, b) { + if (b === 0) return a + return getGreatestCommonDivisor(b, a % b) + } + + function defaultFactory(origin, opts) { + return new Pool(origin, opts) + } + + class BalancedPool extends PoolBase { + constructor( + upstreams = [], + { factory = defaultFactory, ...opts } = {} + ) { + super() + + this[kOptions] = opts + this[kIndex] = -1 + this[kCurrentWeight] = 0 + + this[kMaxWeightPerServer] = this[kOptions].maxWeightPerServer || 100 + this[kErrorPenalty] = this[kOptions].errorPenalty || 15 + + if (!Array.isArray(upstreams)) { + upstreams = [upstreams] } - if (this._url.path.length === 0) { - return '' + if (typeof factory !== 'function') { + throw new InvalidArgumentError('factory must be a function.') } - return '/' + this._url.path.join('/') + this[kInterceptors] = + opts.interceptors && + opts.interceptors.BalancedPool && + Array.isArray(opts.interceptors.BalancedPool) + ? opts.interceptors.BalancedPool + : [] + this[kFactory] = factory + + for (const upstream of upstreams) { + this.addUpstream(upstream) + } + this._updateBalancedPoolStats() } - set pathname(v) { - if (this._url.cannotBeABaseURL) { - return + addUpstream(upstream) { + const upstreamOrigin = parseOrigin(upstream).origin + + if ( + this[kClients].find( + (pool) => + pool[kUrl].origin === upstreamOrigin && + pool.closed !== true && + pool.destroyed !== true + ) + ) { + return this } + const pool = this[kFactory]( + upstreamOrigin, + Object.assign({}, this[kOptions]) + ) - this._url.path = [] - usm.basicURLParse(v, { url: this._url, stateOverride: 'path start' }) - } + this[kAddClient](pool) + pool.on('connect', () => { + pool[kWeight] = Math.min( + this[kMaxWeightPerServer], + pool[kWeight] + this[kErrorPenalty] + ) + }) - get search() { - if (this._url.query === null || this._url.query === '') { - return '' + pool.on('connectionError', () => { + pool[kWeight] = Math.max(1, pool[kWeight] - this[kErrorPenalty]) + this._updateBalancedPoolStats() + }) + + pool.on('disconnect', (...args) => { + const err = args[2] + if (err && err.code === 'UND_ERR_SOCKET') { + // decrease the weight of the pool. + pool[kWeight] = Math.max(1, pool[kWeight] - this[kErrorPenalty]) + this._updateBalancedPoolStats() + } + }) + + for (const client of this[kClients]) { + client[kWeight] = this[kMaxWeightPerServer] } - return '?' + this._url.query + this._updateBalancedPoolStats() + + return this } - set search(v) { - // TODO: query stuff + _updateBalancedPoolStats() { + this[kGreatestCommonDivisor] = this[kClients] + .map((p) => p[kWeight]) + .reduce(getGreatestCommonDivisor, 0) + } - const url = this._url + removeUpstream(upstream) { + const upstreamOrigin = parseOrigin(upstream).origin - if (v === '') { - url.query = null - return + const pool = this[kClients].find( + (pool) => + pool[kUrl].origin === upstreamOrigin && + pool.closed !== true && + pool.destroyed !== true + ) + + if (pool) { + this[kRemoveClient](pool) } - const input = v[0] === '?' ? v.substring(1) : v - url.query = '' - usm.basicURLParse(input, { url, stateOverride: 'query' }) + return this } - get hash() { - if (this._url.fragment === null || this._url.fragment === '') { - return '' + get upstreams() { + return this[kClients] + .filter( + (dispatcher) => + dispatcher.closed !== true && dispatcher.destroyed !== true + ) + .map((p) => p[kUrl].origin) + } + + [kGetDispatcher]() { + // We validate that pools is greater than 0, + // otherwise we would have to wait until an upstream + // is added, which might never happen. + if (this[kClients].length === 0) { + throw new BalancedPoolMissingUpstreamError() } - return '#' + this._url.fragment - } + const dispatcher = this[kClients].find( + (dispatcher) => + !dispatcher[kNeedDrain] && + dispatcher.closed !== true && + dispatcher.destroyed !== true + ) - set hash(v) { - if (v === '') { - this._url.fragment = null + if (!dispatcher) { return } - const input = v[0] === '#' ? v.substring(1) : v - this._url.fragment = '' - usm.basicURLParse(input, { - url: this._url, - stateOverride: 'fragment', - }) - } + const allClientsBusy = this[kClients] + .map((pool) => pool[kNeedDrain]) + .reduce((a, b) => a && b, true) - toJSON() { - return this.href + if (allClientsBusy) { + return + } + + let counter = 0 + + let maxWeightIndex = this[kClients].findIndex( + (pool) => !pool[kNeedDrain] + ) + + while (counter++ < this[kClients].length) { + this[kIndex] = (this[kIndex] + 1) % this[kClients].length + const pool = this[kClients][this[kIndex]] + + // find pool index with the largest weight + if ( + pool[kWeight] > this[kClients][maxWeightIndex][kWeight] && + !pool[kNeedDrain] + ) { + maxWeightIndex = this[kIndex] + } + + // decrease the current weight every `this[kClients].length`. + if (this[kIndex] === 0) { + // Set the current weight to the next lower weight. + this[kCurrentWeight] = + this[kCurrentWeight] - this[kGreatestCommonDivisor] + + if (this[kCurrentWeight] <= 0) { + this[kCurrentWeight] = this[kMaxWeightPerServer] + } + } + if (pool[kWeight] >= this[kCurrentWeight] && !pool[kNeedDrain]) { + return pool + } + } + + this[kCurrentWeight] = this[kClients][maxWeightIndex][kWeight] + this[kIndex] = maxWeightIndex + return this[kClients][maxWeightIndex] } } + module.exports = BalancedPool + /***/ }, - /***/ 3394: /***/ ( + /***/ 6101: /***/ ( module, __unused_webpack_exports, __nccwpck_require__ ) => { 'use strict' - const conversions = __nccwpck_require__(4886) - const utils = __nccwpck_require__(3185) - const Impl = __nccwpck_require__(7537) + const { kConstruct } = __nccwpck_require__(9174) + const { urlEquals, fieldValues: getFieldValues } = + __nccwpck_require__(2396) + const { kEnumerableProperty, isDisturbed } = __nccwpck_require__(3983) + const { kHeadersList } = __nccwpck_require__(2785) + const { webidl } = __nccwpck_require__(1744) + const { Response, cloneResponse } = __nccwpck_require__(7823) + const { Request } = __nccwpck_require__(8359) + const { kState, kHeaders, kGuard, kRealm } = __nccwpck_require__(5861) + const { fetching } = __nccwpck_require__(4881) + const { urlIsHttpHttpsScheme, createDeferredPromise, readAllBytes } = + __nccwpck_require__(2538) + const assert = __nccwpck_require__(9491) + const { getGlobalDispatcher } = __nccwpck_require__(1892) - const impl = utils.implSymbol + /** + * @see https://w3c.github.io/ServiceWorker/#dfn-cache-batch-operation + * @typedef {Object} CacheBatchOperation + * @property {'delete' | 'put'} type + * @property {any} request + * @property {any} response + * @property {import('../../types/cache').CacheQueryOptions} options + */ - function URL(url) { - if (!this || this[impl] || !(this instanceof URL)) { - throw new TypeError( - "Failed to construct 'URL': Please use the 'new' operator, this DOM object constructor cannot be called as a function." - ) - } - if (arguments.length < 1) { - throw new TypeError( - "Failed to construct 'URL': 1 argument required, but only " + - arguments.length + - ' present.' - ) - } - const args = [] - for (let i = 0; i < arguments.length && i < 2; ++i) { - args[i] = arguments[i] - } - args[0] = conversions['USVString'](args[0]) - if (args[1] !== undefined) { - args[1] = conversions['USVString'](args[1]) - } + /** + * @see https://w3c.github.io/ServiceWorker/#dfn-request-response-list + * @typedef {[any, any][]} requestResponseList + */ - module.exports.setup(this, args) - } + class Cache { + /** + * @see https://w3c.github.io/ServiceWorker/#dfn-relevant-request-response-list + * @type {requestResponseList} + */ + #relevantRequestResponseList - URL.prototype.toJSON = function toJSON() { - if (!this || !module.exports.is(this)) { - throw new TypeError('Illegal invocation') + constructor() { + if (arguments[0] !== kConstruct) { + webidl.illegalConstructor() + } + + this.#relevantRequestResponseList = arguments[1] } - const args = [] - for (let i = 0; i < arguments.length && i < 0; ++i) { - args[i] = arguments[i] + + async match(request, options = {}) { + webidl.brandCheck(this, Cache) + webidl.argumentLengthCheck(arguments, 1, { header: 'Cache.match' }) + + request = webidl.converters.RequestInfo(request) + options = webidl.converters.CacheQueryOptions(options) + + const p = await this.matchAll(request, options) + + if (p.length === 0) { + return + } + + return p[0] } - return this[impl].toJSON.apply(this[impl], args) - } - Object.defineProperty(URL.prototype, 'href', { - get() { - return this[impl].href - }, - set(V) { - V = conversions['USVString'](V) - this[impl].href = V - }, - enumerable: true, - configurable: true, - }) - URL.prototype.toString = function () { - if (!this || !module.exports.is(this)) { - throw new TypeError('Illegal invocation') - } - return this.href - } + async matchAll(request = undefined, options = {}) { + webidl.brandCheck(this, Cache) - Object.defineProperty(URL.prototype, 'origin', { - get() { - return this[impl].origin - }, - enumerable: true, - configurable: true, - }) + if (request !== undefined) + request = webidl.converters.RequestInfo(request) + options = webidl.converters.CacheQueryOptions(options) - Object.defineProperty(URL.prototype, 'protocol', { - get() { - return this[impl].protocol - }, - set(V) { - V = conversions['USVString'](V) - this[impl].protocol = V - }, - enumerable: true, - configurable: true, - }) + // 1. + let r = null - Object.defineProperty(URL.prototype, 'username', { - get() { - return this[impl].username - }, - set(V) { - V = conversions['USVString'](V) - this[impl].username = V - }, - enumerable: true, - configurable: true, - }) + // 2. + if (request !== undefined) { + if (request instanceof Request) { + // 2.1.1 + r = request[kState] - Object.defineProperty(URL.prototype, 'password', { - get() { - return this[impl].password - }, - set(V) { - V = conversions['USVString'](V) - this[impl].password = V - }, - enumerable: true, - configurable: true, - }) + // 2.1.2 + if (r.method !== 'GET' && !options.ignoreMethod) { + return [] + } + } else if (typeof request === 'string') { + // 2.2.1 + r = new Request(request)[kState] + } + } - Object.defineProperty(URL.prototype, 'host', { - get() { - return this[impl].host - }, - set(V) { - V = conversions['USVString'](V) - this[impl].host = V - }, - enumerable: true, - configurable: true, - }) + // 5. + // 5.1 + const responses = [] - Object.defineProperty(URL.prototype, 'hostname', { - get() { - return this[impl].hostname - }, - set(V) { - V = conversions['USVString'](V) - this[impl].hostname = V - }, - enumerable: true, - configurable: true, - }) + // 5.2 + if (request === undefined) { + // 5.2.1 + for (const requestResponse of this.#relevantRequestResponseList) { + responses.push(requestResponse[1]) + } + } else { + // 5.3 + // 5.3.1 + const requestResponses = this.#queryCache(r, options) - Object.defineProperty(URL.prototype, 'port', { - get() { - return this[impl].port - }, - set(V) { - V = conversions['USVString'](V) - this[impl].port = V - }, - enumerable: true, - configurable: true, - }) + // 5.3.2 + for (const requestResponse of requestResponses) { + responses.push(requestResponse[1]) + } + } - Object.defineProperty(URL.prototype, 'pathname', { - get() { - return this[impl].pathname - }, - set(V) { - V = conversions['USVString'](V) - this[impl].pathname = V - }, - enumerable: true, - configurable: true, - }) + // 5.4 + // We don't implement CORs so we don't need to loop over the responses, yay! - Object.defineProperty(URL.prototype, 'search', { - get() { - return this[impl].search - }, - set(V) { - V = conversions['USVString'](V) - this[impl].search = V - }, - enumerable: true, - configurable: true, - }) + // 5.5.1 + const responseList = [] - Object.defineProperty(URL.prototype, 'hash', { - get() { - return this[impl].hash - }, - set(V) { - V = conversions['USVString'](V) - this[impl].hash = V - }, - enumerable: true, - configurable: true, - }) + // 5.5.2 + for (const response of responses) { + // 5.5.2.1 + const responseObject = new Response(response.body?.source ?? null) + const body = responseObject[kState].body + responseObject[kState] = response + responseObject[kState].body = body + responseObject[kHeaders][kHeadersList] = response.headersList + responseObject[kHeaders][kGuard] = 'immutable' - module.exports = { - is(obj) { - return !!obj && obj[impl] instanceof Impl.implementation - }, - create(constructorArgs, privateData) { - let obj = Object.create(URL.prototype) - this.setup(obj, constructorArgs, privateData) - return obj - }, - setup(obj, constructorArgs, privateData) { - if (!privateData) privateData = {} - privateData.wrapper = obj + responseList.push(responseObject) + } - obj[impl] = new Impl.implementation(constructorArgs, privateData) - obj[impl][utils.wrapperSymbol] = obj - }, - interface: URL, - expose: { - Window: { URL: URL }, - Worker: { URL: URL }, - }, - } + // 6. + return Object.freeze(responseList) + } - /***/ - }, + async add(request) { + webidl.brandCheck(this, Cache) + webidl.argumentLengthCheck(arguments, 1, { header: 'Cache.add' }) - /***/ 8665: /***/ ( - __unused_webpack_module, - exports, - __nccwpck_require__ - ) => { - 'use strict' + request = webidl.converters.RequestInfo(request) - exports.URL = __nccwpck_require__(3394)['interface'] - exports.serializeURL = __nccwpck_require__(2158).serializeURL - exports.serializeURLOrigin = __nccwpck_require__(2158).serializeURLOrigin - exports.basicURLParse = __nccwpck_require__(2158).basicURLParse - exports.setTheUsername = __nccwpck_require__(2158).setTheUsername - exports.setThePassword = __nccwpck_require__(2158).setThePassword - exports.serializeHost = __nccwpck_require__(2158).serializeHost - exports.serializeInteger = __nccwpck_require__(2158).serializeInteger - exports.parseURL = __nccwpck_require__(2158).parseURL + // 1. + const requests = [request] - /***/ - }, + // 2. + const responseArrayPromise = this.addAll(requests) - /***/ 2158: /***/ ( - module, - __unused_webpack_exports, - __nccwpck_require__ - ) => { - 'use strict' + // 3. + return await responseArrayPromise + } - const punycode = __nccwpck_require__(5477) - const tr46 = __nccwpck_require__(4256) + async addAll(requests) { + webidl.brandCheck(this, Cache) + webidl.argumentLengthCheck(arguments, 1, { header: 'Cache.addAll' }) - const specialSchemes = { - ftp: 21, - file: null, - gopher: 70, - http: 80, - https: 443, - ws: 80, - wss: 443, - } + requests = webidl.converters['sequence'](requests) - const failure = Symbol('failure') + // 1. + const responsePromises = [] - function countSymbols(str) { - return punycode.ucs2.decode(str).length - } + // 2. + const requestList = [] - function at(input, idx) { - const c = input[idx] - return isNaN(c) ? undefined : String.fromCodePoint(c) - } + // 3. + for (const request of requests) { + if (typeof request === 'string') { + continue + } - function isASCIIDigit(c) { - return c >= 0x30 && c <= 0x39 - } + // 3.1 + const r = request[kState] - function isASCIIAlpha(c) { - return (c >= 0x41 && c <= 0x5a) || (c >= 0x61 && c <= 0x7a) - } + // 3.2 + if (!urlIsHttpHttpsScheme(r.url) || r.method !== 'GET') { + throw webidl.errors.exception({ + header: 'Cache.addAll', + message: 'Expected http/s scheme when method is not GET.', + }) + } + } - function isASCIIAlphanumeric(c) { - return isASCIIAlpha(c) || isASCIIDigit(c) - } + // 4. + /** @type {ReturnType[]} */ + const fetchControllers = [] - function isASCIIHex(c) { - return ( - isASCIIDigit(c) || - (c >= 0x41 && c <= 0x46) || - (c >= 0x61 && c <= 0x66) - ) - } + // 5. + for (const request of requests) { + // 5.1 + const r = new Request(request)[kState] - function isSingleDot(buffer) { - return buffer === '.' || buffer.toLowerCase() === '%2e' - } + // 5.2 + if (!urlIsHttpHttpsScheme(r.url)) { + throw webidl.errors.exception({ + header: 'Cache.addAll', + message: 'Expected http/s scheme.', + }) + } - function isDoubleDot(buffer) { - buffer = buffer.toLowerCase() - return ( - buffer === '..' || - buffer === '%2e.' || - buffer === '.%2e' || - buffer === '%2e%2e' - ) - } + // 5.4 + r.initiator = 'fetch' + r.destination = 'subresource' - function isWindowsDriveLetterCodePoints(cp1, cp2) { - return isASCIIAlpha(cp1) && (cp2 === 58 || cp2 === 124) - } + // 5.5 + requestList.push(r) - function isWindowsDriveLetterString(string) { - return ( - string.length === 2 && - isASCIIAlpha(string.codePointAt(0)) && - (string[1] === ':' || string[1] === '|') - ) - } + // 5.6 + const responsePromise = createDeferredPromise() - function isNormalizedWindowsDriveLetterString(string) { - return ( - string.length === 2 && - isASCIIAlpha(string.codePointAt(0)) && - string[1] === ':' - ) - } + // 5.7 + fetchControllers.push( + fetching({ + request: r, + dispatcher: getGlobalDispatcher(), + processResponse(response) { + // 1. + if ( + response.type === 'error' || + response.status === 206 || + response.status < 200 || + response.status > 299 + ) { + responsePromise.reject( + webidl.errors.exception({ + header: 'Cache.addAll', + message: + 'Received an invalid status code or the request failed.', + }) + ) + } else if (response.headersList.contains('vary')) { + // 2. + // 2.1 + const fieldValues = getFieldValues( + response.headersList.get('vary') + ) - function containsForbiddenHostCodePoint(string) { - return ( - string.search( - /\u0000|\u0009|\u000A|\u000D|\u0020|#|%|\/|:|\?|@|\[|\\|\]/ - ) !== -1 - ) - } + // 2.2 + for (const fieldValue of fieldValues) { + // 2.2.1 + if (fieldValue === '*') { + responsePromise.reject( + webidl.errors.exception({ + header: 'Cache.addAll', + message: 'invalid vary field value', + }) + ) + + for (const controller of fetchControllers) { + controller.abort() + } + + return + } + } + } + }, + processResponseEndOfBody(response) { + // 1. + if (response.aborted) { + responsePromise.reject( + new DOMException('aborted', 'AbortError') + ) + return + } - function containsForbiddenHostCodePointExcludingPercent(string) { - return ( - string.search( - /\u0000|\u0009|\u000A|\u000D|\u0020|#|\/|:|\?|@|\[|\\|\]/ - ) !== -1 - ) - } + // 2. + responsePromise.resolve(response) + }, + }) + ) - function isSpecialScheme(scheme) { - return specialSchemes[scheme] !== undefined - } + // 5.8 + responsePromises.push(responsePromise.promise) + } - function isSpecial(url) { - return isSpecialScheme(url.scheme) - } + // 6. + const p = Promise.all(responsePromises) - function defaultPort(scheme) { - return specialSchemes[scheme] - } + // 7. + const responses = await p - function percentEncode(c) { - let hex = c.toString(16).toUpperCase() - if (hex.length === 1) { - hex = '0' + hex - } + // 7.1 + const operations = [] - return '%' + hex - } + // 7.2 + let index = 0 - function utf8PercentEncode(c) { - const buf = new Buffer(c) + // 7.3 + for (const response of responses) { + // 7.3.1 + /** @type {CacheBatchOperation} */ + const operation = { + type: 'put', // 7.3.2 + request: requestList[index], // 7.3.3 + response, // 7.3.4 + } - let str = '' + operations.push(operation) // 7.3.5 - for (let i = 0; i < buf.length; ++i) { - str += percentEncode(buf[i]) - } + index++ // 7.3.6 + } - return str - } + // 7.5 + const cacheJobPromise = createDeferredPromise() - function utf8PercentDecode(str) { - const input = new Buffer(str) - const output = [] - for (let i = 0; i < input.length; ++i) { - if (input[i] !== 37) { - output.push(input[i]) - } else if ( - input[i] === 37 && - isASCIIHex(input[i + 1]) && - isASCIIHex(input[i + 2]) - ) { - output.push(parseInt(input.slice(i + 1, i + 3).toString(), 16)) - i += 2 - } else { - output.push(input[i]) + // 7.6.1 + let errorData = null + + // 7.6.2 + try { + this.#batchCacheOperations(operations) + } catch (e) { + errorData = e } + + // 7.6.3 + queueMicrotask(() => { + // 7.6.3.1 + if (errorData === null) { + cacheJobPromise.resolve(undefined) + } else { + // 7.6.3.2 + cacheJobPromise.reject(errorData) + } + }) + + // 7.7 + return cacheJobPromise.promise } - return new Buffer(output).toString() - } - function isC0ControlPercentEncode(c) { - return c <= 0x1f || c > 0x7e - } + async put(request, response) { + webidl.brandCheck(this, Cache) + webidl.argumentLengthCheck(arguments, 2, { header: 'Cache.put' }) - const extraPathPercentEncodeSet = new Set([ - 32, 34, 35, 60, 62, 63, 96, 123, 125, - ]) - function isPathPercentEncode(c) { - return isC0ControlPercentEncode(c) || extraPathPercentEncodeSet.has(c) - } + request = webidl.converters.RequestInfo(request) + response = webidl.converters.Response(response) - const extraUserinfoPercentEncodeSet = new Set([ - 47, 58, 59, 61, 64, 91, 92, 93, 94, 124, - ]) - function isUserinfoPercentEncode(c) { - return isPathPercentEncode(c) || extraUserinfoPercentEncodeSet.has(c) - } + // 1. + let innerRequest = null - function percentEncodeChar(c, encodeSetPredicate) { - const cStr = String.fromCodePoint(c) + // 2. + if (request instanceof Request) { + innerRequest = request[kState] + } else { + // 3. + innerRequest = new Request(request)[kState] + } - if (encodeSetPredicate(c)) { - return utf8PercentEncode(cStr) - } + // 4. + if ( + !urlIsHttpHttpsScheme(innerRequest.url) || + innerRequest.method !== 'GET' + ) { + throw webidl.errors.exception({ + header: 'Cache.put', + message: 'Expected an http/s scheme when method is not GET', + }) + } - return cStr - } + // 5. + const innerResponse = response[kState] - function parseIPv4Number(input) { - let R = 10 + // 6. + if (innerResponse.status === 206) { + throw webidl.errors.exception({ + header: 'Cache.put', + message: 'Got 206 status', + }) + } - if ( - input.length >= 2 && - input.charAt(0) === '0' && - input.charAt(1).toLowerCase() === 'x' - ) { - input = input.substring(2) - R = 16 - } else if (input.length >= 2 && input.charAt(0) === '0') { - input = input.substring(1) - R = 8 - } + // 7. + if (innerResponse.headersList.contains('vary')) { + // 7.1. + const fieldValues = getFieldValues( + innerResponse.headersList.get('vary') + ) - if (input === '') { - return 0 - } + // 7.2. + for (const fieldValue of fieldValues) { + // 7.2.1 + if (fieldValue === '*') { + throw webidl.errors.exception({ + header: 'Cache.put', + message: 'Got * vary field value', + }) + } + } + } - const regex = R === 10 ? /[^0-9]/ : R === 16 ? /[^0-9A-Fa-f]/ : /[^0-7]/ - if (regex.test(input)) { - return failure - } + // 8. + if ( + innerResponse.body && + (isDisturbed(innerResponse.body.stream) || + innerResponse.body.stream.locked) + ) { + throw webidl.errors.exception({ + header: 'Cache.put', + message: 'Response body is locked or disturbed', + }) + } - return parseInt(input, R) - } + // 9. + const clonedResponse = cloneResponse(innerResponse) - function parseIPv4(input) { - const parts = input.split('.') - if (parts[parts.length - 1] === '') { - if (parts.length > 1) { - parts.pop() + // 10. + const bodyReadPromise = createDeferredPromise() + + // 11. + if (innerResponse.body != null) { + // 11.1 + const stream = innerResponse.body.stream + + // 11.2 + const reader = stream.getReader() + + // 11.3 + readAllBytes(reader).then( + bodyReadPromise.resolve, + bodyReadPromise.reject + ) + } else { + bodyReadPromise.resolve(undefined) } - } - if (parts.length > 4) { - return input - } + // 12. + /** @type {CacheBatchOperation[]} */ + const operations = [] - const numbers = [] - for (const part of parts) { - if (part === '') { - return input + // 13. + /** @type {CacheBatchOperation} */ + const operation = { + type: 'put', // 14. + request: innerRequest, // 15. + response: clonedResponse, // 16. } - const n = parseIPv4Number(part) - if (n === failure) { - return input + + // 17. + operations.push(operation) + + // 19. + const bytes = await bodyReadPromise.promise + + if (clonedResponse.body != null) { + clonedResponse.body.source = bytes } - numbers.push(n) - } + // 19.1 + const cacheJobPromise = createDeferredPromise() - for (let i = 0; i < numbers.length - 1; ++i) { - if (numbers[i] > 255) { - return failure + // 19.2.1 + let errorData = null + + // 19.2.2 + try { + this.#batchCacheOperations(operations) + } catch (e) { + errorData = e } - } - if (numbers[numbers.length - 1] >= Math.pow(256, 5 - numbers.length)) { - return failure - } - let ipv4 = numbers.pop() - let counter = 0 + // 19.2.3 + queueMicrotask(() => { + // 19.2.3.1 + if (errorData === null) { + cacheJobPromise.resolve() + } else { + // 19.2.3.2 + cacheJobPromise.reject(errorData) + } + }) - for (const n of numbers) { - ipv4 += n * Math.pow(256, 3 - counter) - ++counter + return cacheJobPromise.promise } - return ipv4 - } + async delete(request, options = {}) { + webidl.brandCheck(this, Cache) + webidl.argumentLengthCheck(arguments, 1, { header: 'Cache.delete' }) - function serializeIPv4(address) { - let output = '' - let n = address + request = webidl.converters.RequestInfo(request) + options = webidl.converters.CacheQueryOptions(options) - for (let i = 1; i <= 4; ++i) { - output = String(n % 256) + output - if (i !== 4) { - output = '.' + output - } - n = Math.floor(n / 256) - } + /** + * @type {Request} + */ + let r = null - return output - } + if (request instanceof Request) { + r = request[kState] - function parseIPv6(input) { - const address = [0, 0, 0, 0, 0, 0, 0, 0] - let pieceIndex = 0 - let compress = null - let pointer = 0 + if (r.method !== 'GET' && !options.ignoreMethod) { + return false + } + } else { + assert(typeof request === 'string') - input = punycode.ucs2.decode(input) + r = new Request(request)[kState] + } - if (input[pointer] === 58) { - if (input[pointer + 1] !== 58) { - return failure + /** @type {CacheBatchOperation[]} */ + const operations = [] + + /** @type {CacheBatchOperation} */ + const operation = { + type: 'delete', + request: r, + options, } - pointer += 2 - ++pieceIndex - compress = pieceIndex - } + operations.push(operation) - while (pointer < input.length) { - if (pieceIndex === 8) { - return failure + const cacheJobPromise = createDeferredPromise() + + let errorData = null + let requestResponses + + try { + requestResponses = this.#batchCacheOperations(operations) + } catch (e) { + errorData = e } - if (input[pointer] === 58) { - if (compress !== null) { - return failure + queueMicrotask(() => { + if (errorData === null) { + cacheJobPromise.resolve(!!requestResponses?.length) + } else { + cacheJobPromise.reject(errorData) } - ++pointer - ++pieceIndex - compress = pieceIndex - continue - } + }) - let value = 0 - let length = 0 + return cacheJobPromise.promise + } - while (length < 4 && isASCIIHex(input[pointer])) { - value = value * 0x10 + parseInt(at(input, pointer), 16) - ++pointer - ++length + /** + * @see https://w3c.github.io/ServiceWorker/#dom-cache-keys + * @param {any} request + * @param {import('../../types/cache').CacheQueryOptions} options + * @returns {readonly Request[]} + */ + async keys(request = undefined, options = {}) { + webidl.brandCheck(this, Cache) + + if (request !== undefined) + request = webidl.converters.RequestInfo(request) + options = webidl.converters.CacheQueryOptions(options) + + // 1. + let r = null + + // 2. + if (request !== undefined) { + // 2.1 + if (request instanceof Request) { + // 2.1.1 + r = request[kState] + + // 2.1.2 + if (r.method !== 'GET' && !options.ignoreMethod) { + return [] + } + } else if (typeof request === 'string') { + // 2.2 + r = new Request(request)[kState] + } } - if (input[pointer] === 46) { - if (length === 0) { - return failure - } + // 4. + const promise = createDeferredPromise() - pointer -= length + // 5. + // 5.1 + const requests = [] - if (pieceIndex > 6) { - return failure + // 5.2 + if (request === undefined) { + // 5.2.1 + for (const requestResponse of this.#relevantRequestResponseList) { + // 5.2.1.1 + requests.push(requestResponse[0]) } + } else { + // 5.3 + // 5.3.1 + const requestResponses = this.#queryCache(r, options) + + // 5.3.2 + for (const requestResponse of requestResponses) { + // 5.3.2.1 + requests.push(requestResponse[0]) + } + } - let numbersSeen = 0 + // 5.4 + queueMicrotask(() => { + // 5.4.1 + const requestList = [] - while (input[pointer] !== undefined) { - let ipv4Piece = null + // 5.4.2 + for (const request of requests) { + const requestObject = new Request('https://a') + requestObject[kState] = request + requestObject[kHeaders][kHeadersList] = request.headersList + requestObject[kHeaders][kGuard] = 'immutable' + requestObject[kRealm] = request.client - if (numbersSeen > 0) { - if (input[pointer] === 46 && numbersSeen < 4) { - ++pointer - } else { - return failure - } + // 5.4.2.1 + requestList.push(requestObject) + } + + // 5.4.3 + promise.resolve(Object.freeze(requestList)) + }) + + return promise.promise + } + + /** + * @see https://w3c.github.io/ServiceWorker/#batch-cache-operations-algorithm + * @param {CacheBatchOperation[]} operations + * @returns {requestResponseList} + */ + #batchCacheOperations(operations) { + // 1. + const cache = this.#relevantRequestResponseList + + // 2. + const backupCache = [...cache] + + // 3. + const addedItems = [] + + // 4.1 + const resultList = [] + + try { + // 4.2 + for (const operation of operations) { + // 4.2.1 + if (operation.type !== 'delete' && operation.type !== 'put') { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: 'operation type does not match "delete" or "put"', + }) } - if (!isASCIIDigit(input[pointer])) { - return failure + // 4.2.2 + if (operation.type === 'delete' && operation.response != null) { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: + 'delete operation should not have an associated response', + }) } - while (isASCIIDigit(input[pointer])) { - const number = parseInt(at(input, pointer)) - if (ipv4Piece === null) { - ipv4Piece = number - } else if (ipv4Piece === 0) { - return failure - } else { - ipv4Piece = ipv4Piece * 10 + number + // 4.2.3 + if ( + this.#queryCache( + operation.request, + operation.options, + addedItems + ).length + ) { + throw new DOMException('???', 'InvalidStateError') + } + + // 4.2.4 + let requestResponses + + // 4.2.5 + if (operation.type === 'delete') { + // 4.2.5.1 + requestResponses = this.#queryCache( + operation.request, + operation.options + ) + + // TODO: the spec is wrong, this is needed to pass WPTs + if (requestResponses.length === 0) { + return [] } - if (ipv4Piece > 255) { - return failure + + // 4.2.5.2 + for (const requestResponse of requestResponses) { + const idx = cache.indexOf(requestResponse) + assert(idx !== -1) + + // 4.2.5.2.1 + cache.splice(idx, 1) + } + } else if (operation.type === 'put') { + // 4.2.6 + // 4.2.6.1 + if (operation.response == null) { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: 'put operation should have an associated response', + }) } - ++pointer - } - address[pieceIndex] = address[pieceIndex] * 0x100 + ipv4Piece + // 4.2.6.2 + const r = operation.request - ++numbersSeen + // 4.2.6.3 + if (!urlIsHttpHttpsScheme(r.url)) { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: 'expected http or https scheme', + }) + } - if (numbersSeen === 2 || numbersSeen === 4) { - ++pieceIndex + // 4.2.6.4 + if (r.method !== 'GET') { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: 'not get method', + }) + } + + // 4.2.6.5 + if (operation.options != null) { + throw webidl.errors.exception({ + header: 'Cache.#batchCacheOperations', + message: 'options must not be defined', + }) + } + + // 4.2.6.6 + requestResponses = this.#queryCache(operation.request) + + // 4.2.6.7 + for (const requestResponse of requestResponses) { + const idx = cache.indexOf(requestResponse) + assert(idx !== -1) + + // 4.2.6.7.1 + cache.splice(idx, 1) + } + + // 4.2.6.8 + cache.push([operation.request, operation.response]) + + // 4.2.6.10 + addedItems.push([operation.request, operation.response]) } - } - if (numbersSeen !== 4) { - return failure + // 4.2.7 + resultList.push([operation.request, operation.response]) } - break - } else if (input[pointer] === 58) { - ++pointer - if (input[pointer] === undefined) { - return failure - } - } else if (input[pointer] !== undefined) { - return failure - } + // 4.3 + return resultList + } catch (e) { + // 5. + // 5.1 + this.#relevantRequestResponseList.length = 0 - address[pieceIndex] = value - ++pieceIndex - } + // 5.2 + this.#relevantRequestResponseList = backupCache - if (compress !== null) { - let swaps = pieceIndex - compress - pieceIndex = 7 - while (pieceIndex !== 0 && swaps > 0) { - const temp = address[compress + swaps - 1] - address[compress + swaps - 1] = address[pieceIndex] - address[pieceIndex] = temp - --pieceIndex - --swaps + // 5.3 + throw e } - } else if (compress === null && pieceIndex !== 8) { - return failure } - return address - } + /** + * @see https://w3c.github.io/ServiceWorker/#query-cache + * @param {any} requestQuery + * @param {import('../../types/cache').CacheQueryOptions} options + * @param {requestResponseList} targetStorage + * @returns {requestResponseList} + */ + #queryCache(requestQuery, options, targetStorage) { + /** @type {requestResponseList} */ + const resultList = [] - function serializeIPv6(address) { - let output = '' - const seqResult = findLongestZeroSequence(address) - const compress = seqResult.idx - let ignore0 = false + const storage = targetStorage ?? this.#relevantRequestResponseList - for (let pieceIndex = 0; pieceIndex <= 7; ++pieceIndex) { - if (ignore0 && address[pieceIndex] === 0) { - continue - } else if (ignore0) { - ignore0 = false + for (const requestResponse of storage) { + const [cachedRequest, cachedResponse] = requestResponse + if ( + this.#requestMatchesCachedItem( + requestQuery, + cachedRequest, + cachedResponse, + options + ) + ) { + resultList.push(requestResponse) + } } - if (compress === pieceIndex) { - const separator = pieceIndex === 0 ? '::' : ':' - output += separator - ignore0 = true - continue + return resultList + } + + /** + * @see https://w3c.github.io/ServiceWorker/#request-matches-cached-item-algorithm + * @param {any} requestQuery + * @param {any} request + * @param {any | null} response + * @param {import('../../types/cache').CacheQueryOptions | undefined} options + * @returns {boolean} + */ + #requestMatchesCachedItem( + requestQuery, + request, + response = null, + options + ) { + // if (options?.ignoreMethod === false && request.method === 'GET') { + // return false + // } + + const queryURL = new URL(requestQuery.url) + + const cachedURL = new URL(request.url) + + if (options?.ignoreSearch) { + cachedURL.search = '' + + queryURL.search = '' } - output += address[pieceIndex].toString(16) + if (!urlEquals(queryURL, cachedURL, true)) { + return false + } - if (pieceIndex !== 7) { - output += ':' + if ( + response == null || + options?.ignoreVary || + !response.headersList.contains('vary') + ) { + return true } - } - return output - } + const fieldValues = getFieldValues(response.headersList.get('vary')) - function parseHost(input, isSpecialArg) { - if (input[0] === '[') { - if (input[input.length - 1] !== ']') { - return failure + for (const fieldValue of fieldValues) { + if (fieldValue === '*') { + return false + } + + const requestValue = request.headersList.get(fieldValue) + const queryValue = requestQuery.headersList.get(fieldValue) + + // If one has the header and the other doesn't, or one has + // a different value than the other, return false + if (requestValue !== queryValue) { + return false + } } - return parseIPv6(input.substring(1, input.length - 1)) + return true } + } - if (!isSpecialArg) { - return parseOpaqueHost(input) - } + Object.defineProperties(Cache.prototype, { + [Symbol.toStringTag]: { + value: 'Cache', + configurable: true, + }, + match: kEnumerableProperty, + matchAll: kEnumerableProperty, + add: kEnumerableProperty, + addAll: kEnumerableProperty, + put: kEnumerableProperty, + delete: kEnumerableProperty, + keys: kEnumerableProperty, + }) - const domain = utf8PercentDecode(input) - const asciiDomain = tr46.toASCII( - domain, - false, - tr46.PROCESSING_OPTIONS.NONTRANSITIONAL, - false - ) - if (asciiDomain === null) { - return failure - } + const cacheQueryOptionConverters = [ + { + key: 'ignoreSearch', + converter: webidl.converters.boolean, + defaultValue: false, + }, + { + key: 'ignoreMethod', + converter: webidl.converters.boolean, + defaultValue: false, + }, + { + key: 'ignoreVary', + converter: webidl.converters.boolean, + defaultValue: false, + }, + ] - if (containsForbiddenHostCodePoint(asciiDomain)) { - return failure - } + webidl.converters.CacheQueryOptions = webidl.dictionaryConverter( + cacheQueryOptionConverters + ) - const ipv4Host = parseIPv4(asciiDomain) - if (typeof ipv4Host === 'number' || ipv4Host === failure) { - return ipv4Host - } + webidl.converters.MultiCacheQueryOptions = webidl.dictionaryConverter([ + ...cacheQueryOptionConverters, + { + key: 'cacheName', + converter: webidl.converters.DOMString, + }, + ]) - return asciiDomain + webidl.converters.Response = webidl.interfaceConverter(Response) + + webidl.converters['sequence'] = webidl.sequenceConverter( + webidl.converters.RequestInfo + ) + + module.exports = { + Cache, } - function parseOpaqueHost(input) { - if (containsForbiddenHostCodePointExcludingPercent(input)) { - return failure - } + /***/ + }, - let output = '' - const decoded = punycode.ucs2.decode(input) - for (let i = 0; i < decoded.length; ++i) { - output += percentEncodeChar(decoded[i], isC0ControlPercentEncode) + /***/ 7907: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const { kConstruct } = __nccwpck_require__(9174) + const { Cache } = __nccwpck_require__(6101) + const { webidl } = __nccwpck_require__(1744) + const { kEnumerableProperty } = __nccwpck_require__(3983) + + class CacheStorage { + /** + * @see https://w3c.github.io/ServiceWorker/#dfn-relevant-name-to-cache-map + * @type {Map 1 - let currStart = null - let currLen = 0 + async match(request, options = {}) { + webidl.brandCheck(this, CacheStorage) + webidl.argumentLengthCheck(arguments, 1, { + header: 'CacheStorage.match', + }) - for (let i = 0; i < arr.length; ++i) { - if (arr[i] !== 0) { - if (currLen > maxLen) { - maxIdx = currStart - maxLen = currLen - } + request = webidl.converters.RequestInfo(request) + options = webidl.converters.MultiCacheQueryOptions(options) - currStart = null - currLen = 0 + // 1. + if (options.cacheName != null) { + // 1.1.1.1 + if (this.#caches.has(options.cacheName)) { + // 1.1.1.1.1 + const cacheList = this.#caches.get(options.cacheName) + const cache = new Cache(kConstruct, cacheList) + + return await cache.match(request, options) + } } else { - if (currStart === null) { - currStart = i + // 2. + // 2.2 + for (const cacheList of this.#caches.values()) { + const cache = new Cache(kConstruct, cacheList) + + // 2.2.1.2 + const response = await cache.match(request, options) + + if (response !== undefined) { + return response + } } - ++currLen } } - // if trailing zeros - if (currLen > maxLen) { - maxIdx = currStart - maxLen = currLen - } + /** + * @see https://w3c.github.io/ServiceWorker/#cache-storage-has + * @param {string} cacheName + * @returns {Promise} + */ + async has(cacheName) { + webidl.brandCheck(this, CacheStorage) + webidl.argumentLengthCheck(arguments, 1, { + header: 'CacheStorage.has', + }) - return { - idx: maxIdx, - len: maxLen, - } - } + cacheName = webidl.converters.DOMString(cacheName) - function serializeHost(host) { - if (typeof host === 'number') { - return serializeIPv4(host) + // 2.1.1 + // 2.2 + return this.#caches.has(cacheName) } - // IPv6 serializer - if (host instanceof Array) { - return '[' + serializeIPv6(host) + ']' - } + /** + * @see https://w3c.github.io/ServiceWorker/#dom-cachestorage-open + * @param {string} cacheName + * @returns {Promise} + */ + async open(cacheName) { + webidl.brandCheck(this, CacheStorage) + webidl.argumentLengthCheck(arguments, 1, { + header: 'CacheStorage.open', + }) - return host - } + cacheName = webidl.converters.DOMString(cacheName) - function trimControlChars(url) { - return url.replace( - /^[\u0000-\u001F\u0020]+|[\u0000-\u001F\u0020]+$/g, - '' - ) - } + // 2.1 + if (this.#caches.has(cacheName)) { + // await caches.open('v1') !== await caches.open('v1') - function trimTabAndNewline(url) { - return url.replace(/\u0009|\u000A|\u000D/g, '') - } + // 2.1.1 + const cache = this.#caches.get(cacheName) - function shortenPath(url) { - const path = url.path - if (path.length === 0) { - return + // 2.1.1.1 + return new Cache(kConstruct, cache) + } + + // 2.2 + const cache = [] + + // 2.3 + this.#caches.set(cacheName, cache) + + // 2.4 + return new Cache(kConstruct, cache) } - if ( - url.scheme === 'file' && - path.length === 1 && - isNormalizedWindowsDriveLetter(path[0]) - ) { - return + + /** + * @see https://w3c.github.io/ServiceWorker/#cache-storage-delete + * @param {string} cacheName + * @returns {Promise} + */ + async delete(cacheName) { + webidl.brandCheck(this, CacheStorage) + webidl.argumentLengthCheck(arguments, 1, { + header: 'CacheStorage.delete', + }) + + cacheName = webidl.converters.DOMString(cacheName) + + return this.#caches.delete(cacheName) } - path.pop() + /** + * @see https://w3c.github.io/ServiceWorker/#cache-storage-keys + * @returns {string[]} + */ + async keys() { + webidl.brandCheck(this, CacheStorage) + + // 2.1 + const keys = this.#caches.keys() + + // 2.2 + return [...keys] + } } - function includesCredentials(url) { - return url.username !== '' || url.password !== '' + Object.defineProperties(CacheStorage.prototype, { + [Symbol.toStringTag]: { + value: 'CacheStorage', + configurable: true, + }, + match: kEnumerableProperty, + has: kEnumerableProperty, + open: kEnumerableProperty, + delete: kEnumerableProperty, + keys: kEnumerableProperty, + }) + + module.exports = { + CacheStorage, } - function cannotHaveAUsernamePasswordPort(url) { - return ( - url.host === null || - url.host === '' || - url.cannotBeABaseURL || - url.scheme === 'file' - ) + /***/ + }, + + /***/ 9174: /***/ (module) => { + 'use strict' + + module.exports = { + kConstruct: Symbol('constructable'), } - function isNormalizedWindowsDriveLetter(string) { - return /^[A-Za-z]:$/.test(string) + /***/ + }, + + /***/ 2396: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const assert = __nccwpck_require__(9491) + const { URLSerializer } = __nccwpck_require__(685) + const { isValidHeaderName } = __nccwpck_require__(2538) + + /** + * @see https://url.spec.whatwg.org/#concept-url-equals + * @param {URL} A + * @param {URL} B + * @param {boolean | undefined} excludeFragment + * @returns {boolean} + */ + function urlEquals(A, B, excludeFragment = false) { + const serializedA = URLSerializer(A, excludeFragment) + + const serializedB = URLSerializer(B, excludeFragment) + + return serializedA === serializedB } - function URLStateMachine( - input, - base, - encodingOverride, - url, - stateOverride - ) { - this.pointer = 0 - this.input = input - this.base = base || null - this.encodingOverride = encodingOverride || 'utf-8' - this.stateOverride = stateOverride - this.url = url - this.failure = false - this.parseError = false + /** + * @see https://github.com/chromium/chromium/blob/694d20d134cb553d8d89e5500b9148012b1ba299/content/browser/cache_storage/cache_storage_cache.cc#L260-L262 + * @param {string} header + */ + function fieldValues(header) { + assert(header !== null) - if (!this.url) { - this.url = { - scheme: '', - username: '', - password: '', - host: null, - port: null, - path: [], - query: null, - fragment: null, + const values = [] - cannotBeABaseURL: false, - } + for (let value of header.split(',')) { + value = value.trim() - const res = trimControlChars(this.input) - if (res !== this.input) { - this.parseError = true + if (!value.length) { + continue + } else if (!isValidHeaderName(value)) { + continue } - this.input = res - } - const res = trimTabAndNewline(this.input) - if (res !== this.input) { - this.parseError = true + values.push(value) } - this.input = res - this.state = stateOverride || 'scheme start' + return values + } - this.buffer = '' - this.atFlag = false - this.arrFlag = false - this.passwordTokenSeenFlag = false + module.exports = { + urlEquals, + fieldValues, + } - this.input = punycode.ucs2.decode(this.input) + /***/ + }, - for (; this.pointer <= this.input.length; ++this.pointer) { - const c = this.input[this.pointer] - const cStr = isNaN(c) ? undefined : String.fromCodePoint(c) + /***/ 3598: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + // @ts-check + + /* global WebAssembly */ + + const assert = __nccwpck_require__(9491) + const net = __nccwpck_require__(1808) + const http = __nccwpck_require__(3685) + const { pipeline } = __nccwpck_require__(2781) + const util = __nccwpck_require__(3983) + const timers = __nccwpck_require__(9459) + const Request = __nccwpck_require__(2905) + const DispatcherBase = __nccwpck_require__(4839) + const { + RequestContentLengthMismatchError, + ResponseContentLengthMismatchError, + InvalidArgumentError, + RequestAbortedError, + HeadersTimeoutError, + HeadersOverflowError, + SocketError, + InformationalError, + BodyTimeoutError, + HTTPParserError, + ResponseExceededMaxSizeError, + ClientDestroyedError, + } = __nccwpck_require__(8045) + const buildConnector = __nccwpck_require__(2067) + const { + kUrl, + kReset, + kServerName, + kClient, + kBusy, + kParser, + kConnect, + kBlocking, + kResuming, + kRunning, + kPending, + kSize, + kWriting, + kQueue, + kConnected, + kConnecting, + kNeedDrain, + kNoRef, + kKeepAliveDefaultTimeout, + kHostHeader, + kPendingIdx, + kRunningIdx, + kError, + kPipelining, + kSocket, + kKeepAliveTimeoutValue, + kMaxHeadersSize, + kKeepAliveMaxTimeout, + kKeepAliveTimeoutThreshold, + kHeadersTimeout, + kBodyTimeout, + kStrictContentLength, + kConnector, + kMaxRedirections, + kMaxRequests, + kCounter, + kClose, + kDestroy, + kDispatch, + kInterceptors, + kLocalAddress, + kMaxResponseSize, + kHTTPConnVersion, + // HTTP2 + kHost, + kHTTP2Session, + kHTTP2SessionState, + kHTTP2BuildRequest, + kHTTP2CopyHeaders, + kHTTP1BuildRequest, + } = __nccwpck_require__(2785) + + /** @type {import('http2')} */ + let http2 + try { + http2 = __nccwpck_require__(5158) + } catch { + // @ts-ignore + http2 = { constants: {} } + } - // exec state machine - const ret = this['parse ' + this.state](c, cStr) - if (!ret) { - break // terminate algorithm - } else if (ret === failure) { - this.failure = true - break - } - } + const { + constants: { + HTTP2_HEADER_AUTHORITY, + HTTP2_HEADER_METHOD, + HTTP2_HEADER_PATH, + HTTP2_HEADER_SCHEME, + HTTP2_HEADER_CONTENT_LENGTH, + HTTP2_HEADER_EXPECT, + HTTP2_HEADER_STATUS, + }, + } = http2 + + // Experimental + let h2ExperimentalWarned = false + + const FastBuffer = Buffer[Symbol.species] + + const kClosedResolve = Symbol('kClosedResolve') + + const channels = {} + + try { + const diagnosticsChannel = __nccwpck_require__(7643) + channels.sendHeaders = diagnosticsChannel.channel( + 'undici:client:sendHeaders' + ) + channels.beforeConnect = diagnosticsChannel.channel( + 'undici:client:beforeConnect' + ) + channels.connectError = diagnosticsChannel.channel( + 'undici:client:connectError' + ) + channels.connected = diagnosticsChannel.channel( + 'undici:client:connected' + ) + } catch { + channels.sendHeaders = { hasSubscribers: false } + channels.beforeConnect = { hasSubscribers: false } + channels.connectError = { hasSubscribers: false } + channels.connected = { hasSubscribers: false } } - URLStateMachine.prototype['parse scheme start'] = - function parseSchemeStart(c, cStr) { - if (isASCIIAlpha(c)) { - this.buffer += cStr.toLowerCase() - this.state = 'scheme' - } else if (!this.stateOverride) { - this.state = 'no scheme' - --this.pointer - } else { - this.parseError = true - return failure + /** + * @type {import('../types/client').default} + */ + class Client extends DispatcherBase { + /** + * + * @param {string|URL} url + * @param {import('../types/client').Client.Options} options + */ + constructor( + url, + { + interceptors, + maxHeaderSize, + headersTimeout, + socketTimeout, + requestTimeout, + connectTimeout, + bodyTimeout, + idleTimeout, + keepAlive, + keepAliveTimeout, + maxKeepAliveTimeout, + keepAliveMaxTimeout, + keepAliveTimeoutThreshold, + socketPath, + pipelining, + tls, + strictContentLength, + maxCachedSessions, + maxRedirections, + connect, + maxRequestsPerClient, + localAddress, + maxResponseSize, + autoSelectFamily, + autoSelectFamilyAttemptTimeout, + // h2 + allowH2, + maxConcurrentStreams, + } = {} + ) { + super() + + if (keepAlive !== undefined) { + throw new InvalidArgumentError( + 'unsupported keepAlive, use pipelining=0 instead' + ) } - return true - } + if (socketTimeout !== undefined) { + throw new InvalidArgumentError( + 'unsupported socketTimeout, use headersTimeout & bodyTimeout instead' + ) + } - URLStateMachine.prototype['parse scheme'] = function parseScheme( - c, - cStr - ) { - if (isASCIIAlphanumeric(c) || c === 43 || c === 45 || c === 46) { - this.buffer += cStr.toLowerCase() - } else if (c === 58) { - if (this.stateOverride) { - if (isSpecial(this.url) && !isSpecialScheme(this.buffer)) { - return false - } + if (requestTimeout !== undefined) { + throw new InvalidArgumentError( + 'unsupported requestTimeout, use headersTimeout & bodyTimeout instead' + ) + } - if (!isSpecial(this.url) && isSpecialScheme(this.buffer)) { - return false - } + if (idleTimeout !== undefined) { + throw new InvalidArgumentError( + 'unsupported idleTimeout, use keepAliveTimeout instead' + ) + } - if ( - (includesCredentials(this.url) || this.url.port !== null) && - this.buffer === 'file' - ) { - return false - } + if (maxKeepAliveTimeout !== undefined) { + throw new InvalidArgumentError( + 'unsupported maxKeepAliveTimeout, use keepAliveMaxTimeout instead' + ) + } - if ( - this.url.scheme === 'file' && - (this.url.host === '' || this.url.host === null) - ) { - return false - } + if (maxHeaderSize != null && !Number.isFinite(maxHeaderSize)) { + throw new InvalidArgumentError('invalid maxHeaderSize') } - this.url.scheme = this.buffer - this.buffer = '' - if (this.stateOverride) { - return false + + if (socketPath != null && typeof socketPath !== 'string') { + throw new InvalidArgumentError('invalid socketPath') } - if (this.url.scheme === 'file') { - if ( - this.input[this.pointer + 1] !== 47 || - this.input[this.pointer + 2] !== 47 - ) { - this.parseError = true - } - this.state = 'file' - } else if ( - isSpecial(this.url) && - this.base !== null && - this.base.scheme === this.url.scheme + + if ( + connectTimeout != null && + (!Number.isFinite(connectTimeout) || connectTimeout < 0) ) { - this.state = 'special relative or authority' - } else if (isSpecial(this.url)) { - this.state = 'special authority slashes' - } else if (this.input[this.pointer + 1] === 47) { - this.state = 'path or authority' - ++this.pointer - } else { - this.url.cannotBeABaseURL = true - this.url.path.push('') - this.state = 'cannot-be-a-base-URL path' + throw new InvalidArgumentError('invalid connectTimeout') } - } else if (!this.stateOverride) { - this.buffer = '' - this.state = 'no scheme' - this.pointer = -1 - } else { - this.parseError = true - return failure - } - return true - } + if ( + keepAliveTimeout != null && + (!Number.isFinite(keepAliveTimeout) || keepAliveTimeout <= 0) + ) { + throw new InvalidArgumentError('invalid keepAliveTimeout') + } - URLStateMachine.prototype['parse no scheme'] = function parseNoScheme(c) { - if (this.base === null || (this.base.cannotBeABaseURL && c !== 35)) { - return failure - } else if (this.base.cannotBeABaseURL && c === 35) { - this.url.scheme = this.base.scheme - this.url.path = this.base.path.slice() - this.url.query = this.base.query - this.url.fragment = '' - this.url.cannotBeABaseURL = true - this.state = 'fragment' - } else if (this.base.scheme === 'file') { - this.state = 'file' - --this.pointer - } else { - this.state = 'relative' - --this.pointer - } + if ( + keepAliveMaxTimeout != null && + (!Number.isFinite(keepAliveMaxTimeout) || keepAliveMaxTimeout <= 0) + ) { + throw new InvalidArgumentError('invalid keepAliveMaxTimeout') + } - return true - } + if ( + keepAliveTimeoutThreshold != null && + !Number.isFinite(keepAliveTimeoutThreshold) + ) { + throw new InvalidArgumentError('invalid keepAliveTimeoutThreshold') + } - URLStateMachine.prototype['parse special relative or authority'] = - function parseSpecialRelativeOrAuthority(c) { - if (c === 47 && this.input[this.pointer + 1] === 47) { - this.state = 'special authority ignore slashes' - ++this.pointer - } else { - this.parseError = true - this.state = 'relative' - --this.pointer + if ( + headersTimeout != null && + (!Number.isInteger(headersTimeout) || headersTimeout < 0) + ) { + throw new InvalidArgumentError( + 'headersTimeout must be a positive integer or zero' + ) } - return true - } + if ( + bodyTimeout != null && + (!Number.isInteger(bodyTimeout) || bodyTimeout < 0) + ) { + throw new InvalidArgumentError( + 'bodyTimeout must be a positive integer or zero' + ) + } - URLStateMachine.prototype['parse path or authority'] = - function parsePathOrAuthority(c) { - if (c === 47) { - this.state = 'authority' - } else { - this.state = 'path' - --this.pointer + if ( + connect != null && + typeof connect !== 'function' && + typeof connect !== 'object' + ) { + throw new InvalidArgumentError( + 'connect must be a function or an object' + ) } - return true + if ( + maxRedirections != null && + (!Number.isInteger(maxRedirections) || maxRedirections < 0) + ) { + throw new InvalidArgumentError( + 'maxRedirections must be a positive number' + ) + } + + if ( + maxRequestsPerClient != null && + (!Number.isInteger(maxRequestsPerClient) || + maxRequestsPerClient < 0) + ) { + throw new InvalidArgumentError( + 'maxRequestsPerClient must be a positive number' + ) + } + + if ( + localAddress != null && + (typeof localAddress !== 'string' || net.isIP(localAddress) === 0) + ) { + throw new InvalidArgumentError( + 'localAddress must be valid string IP address' + ) + } + + if ( + maxResponseSize != null && + (!Number.isInteger(maxResponseSize) || maxResponseSize < -1) + ) { + throw new InvalidArgumentError( + 'maxResponseSize must be a positive number' + ) + } + + if ( + autoSelectFamilyAttemptTimeout != null && + (!Number.isInteger(autoSelectFamilyAttemptTimeout) || + autoSelectFamilyAttemptTimeout < -1) + ) { + throw new InvalidArgumentError( + 'autoSelectFamilyAttemptTimeout must be a positive number' + ) + } + + // h2 + if (allowH2 != null && typeof allowH2 !== 'boolean') { + throw new InvalidArgumentError( + 'allowH2 must be a valid boolean value' + ) + } + + if ( + maxConcurrentStreams != null && + (typeof maxConcurrentStreams !== 'number' || + maxConcurrentStreams < 1) + ) { + throw new InvalidArgumentError( + 'maxConcurrentStreams must be a possitive integer, greater than 0' + ) + } + + if (typeof connect !== 'function') { + connect = buildConnector({ + ...tls, + maxCachedSessions, + allowH2, + socketPath, + timeout: connectTimeout, + ...(util.nodeHasAutoSelectFamily && autoSelectFamily + ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } + : undefined), + ...connect, + }) + } + + this[kInterceptors] = + interceptors && + interceptors.Client && + Array.isArray(interceptors.Client) + ? interceptors.Client + : [createRedirectInterceptor({ maxRedirections })] + this[kUrl] = util.parseOrigin(url) + this[kConnector] = connect + this[kSocket] = null + this[kPipelining] = pipelining != null ? pipelining : 1 + this[kMaxHeadersSize] = maxHeaderSize || http.maxHeaderSize + this[kKeepAliveDefaultTimeout] = + keepAliveTimeout == null ? 4e3 : keepAliveTimeout + this[kKeepAliveMaxTimeout] = + keepAliveMaxTimeout == null ? 600e3 : keepAliveMaxTimeout + this[kKeepAliveTimeoutThreshold] = + keepAliveTimeoutThreshold == null ? 1e3 : keepAliveTimeoutThreshold + this[kKeepAliveTimeoutValue] = this[kKeepAliveDefaultTimeout] + this[kServerName] = null + this[kLocalAddress] = localAddress != null ? localAddress : null + this[kResuming] = 0 // 0, idle, 1, scheduled, 2 resuming + this[kNeedDrain] = 0 // 0, idle, 1, scheduled, 2 resuming + this[kHostHeader] = `host: ${this[kUrl].hostname}${ + this[kUrl].port ? `:${this[kUrl].port}` : '' + }\r\n` + this[kBodyTimeout] = bodyTimeout != null ? bodyTimeout : 300e3 + this[kHeadersTimeout] = + headersTimeout != null ? headersTimeout : 300e3 + this[kStrictContentLength] = + strictContentLength == null ? true : strictContentLength + this[kMaxRedirections] = maxRedirections + this[kMaxRequests] = maxRequestsPerClient + this[kClosedResolve] = null + this[kMaxResponseSize] = maxResponseSize > -1 ? maxResponseSize : -1 + this[kHTTPConnVersion] = 'h1' + + // HTTP/2 + this[kHTTP2Session] = null + this[kHTTP2SessionState] = !allowH2 + ? null + : { + // streams: null, // Fixed queue of streams - For future support of `push` + openStreams: 0, // Keep track of them to decide wether or not unref the session + maxConcurrentStreams: + maxConcurrentStreams != null ? maxConcurrentStreams : 100, // Max peerConcurrentStreams for a Node h2 server + } + this[kHost] = `${this[kUrl].hostname}${ + this[kUrl].port ? `:${this[kUrl].port}` : '' + }` + + // kQueue is built up of 3 sections separated by + // the kRunningIdx and kPendingIdx indices. + // | complete | running | pending | + // ^ kRunningIdx ^ kPendingIdx ^ kQueue.length + // kRunningIdx points to the first running element. + // kPendingIdx points to the first pending element. + // This implements a fast queue with an amortized + // time of O(1). + + this[kQueue] = [] + this[kRunningIdx] = 0 + this[kPendingIdx] = 0 } - URLStateMachine.prototype['parse relative'] = function parseRelative(c) { - this.url.scheme = this.base.scheme - if (isNaN(c)) { - this.url.username = this.base.username - this.url.password = this.base.password - this.url.host = this.base.host - this.url.port = this.base.port - this.url.path = this.base.path.slice() - this.url.query = this.base.query - } else if (c === 47) { - this.state = 'relative slash' - } else if (c === 63) { - this.url.username = this.base.username - this.url.password = this.base.password - this.url.host = this.base.host - this.url.port = this.base.port - this.url.path = this.base.path.slice() - this.url.query = '' - this.state = 'query' - } else if (c === 35) { - this.url.username = this.base.username - this.url.password = this.base.password - this.url.host = this.base.host - this.url.port = this.base.port - this.url.path = this.base.path.slice() - this.url.query = this.base.query - this.url.fragment = '' - this.state = 'fragment' - } else if (isSpecial(this.url) && c === 92) { - this.parseError = true - this.state = 'relative slash' - } else { - this.url.username = this.base.username - this.url.password = this.base.password - this.url.host = this.base.host - this.url.port = this.base.port - this.url.path = this.base.path.slice(0, this.base.path.length - 1) + get pipelining() { + return this[kPipelining] + } - this.state = 'path' - --this.pointer + set pipelining(value) { + this[kPipelining] = value + resume(this, true) } - return true - } + get [kPending]() { + return this[kQueue].length - this[kPendingIdx] + } - URLStateMachine.prototype['parse relative slash'] = - function parseRelativeSlash(c) { - if (isSpecial(this.url) && (c === 47 || c === 92)) { - if (c === 92) { - this.parseError = true - } - this.state = 'special authority ignore slashes' - } else if (c === 47) { - this.state = 'authority' - } else { - this.url.username = this.base.username - this.url.password = this.base.password - this.url.host = this.base.host - this.url.port = this.base.port - this.state = 'path' - --this.pointer - } + get [kRunning]() { + return this[kPendingIdx] - this[kRunningIdx] + } - return true + get [kSize]() { + return this[kQueue].length - this[kRunningIdx] } - URLStateMachine.prototype['parse special authority slashes'] = - function parseSpecialAuthoritySlashes(c) { - if (c === 47 && this.input[this.pointer + 1] === 47) { - this.state = 'special authority ignore slashes' - ++this.pointer - } else { - this.parseError = true - this.state = 'special authority ignore slashes' - --this.pointer - } + get [kConnected]() { + return ( + !!this[kSocket] && !this[kConnecting] && !this[kSocket].destroyed + ) + } - return true + get [kBusy]() { + const socket = this[kSocket] + return ( + (socket && + (socket[kReset] || socket[kWriting] || socket[kBlocking])) || + this[kSize] >= (this[kPipelining] || 1) || + this[kPending] > 0 + ) } - URLStateMachine.prototype['parse special authority ignore slashes'] = - function parseSpecialAuthorityIgnoreSlashes(c) { - if (c !== 47 && c !== 92) { - this.state = 'authority' - --this.pointer + /* istanbul ignore: only used for test */ + [kConnect](cb) { + connect(this) + this.once('connect', cb) + } + + [kDispatch](opts, handler) { + const origin = opts.origin || this[kUrl].origin + + const request = + this[kHTTPConnVersion] === 'h2' + ? Request[kHTTP2BuildRequest](origin, opts, handler) + : Request[kHTTP1BuildRequest](origin, opts, handler) + + this[kQueue].push(request) + if (this[kResuming]) { + // Do nothing. + } else if ( + util.bodyLength(request.body) == null && + util.isIterable(request.body) + ) { + // Wait a tick in case stream/iterator is ended in the same tick. + this[kResuming] = 1 + process.nextTick(resume, this) } else { - this.parseError = true + resume(this, true) } - return true + if (this[kResuming] && this[kNeedDrain] !== 2 && this[kBusy]) { + this[kNeedDrain] = 2 + } + + return this[kNeedDrain] < 2 } - URLStateMachine.prototype['parse authority'] = function parseAuthority( - c, - cStr - ) { - if (c === 64) { - this.parseError = true - if (this.atFlag) { - this.buffer = '%40' + this.buffer - } - this.atFlag = true + async [kClose]() { + // TODO: for H2 we need to gracefully flush the remaining enqueued + // request and close each stream. + return new Promise((resolve) => { + if (!this[kSize]) { + resolve(null) + } else { + this[kClosedResolve] = resolve + } + }) + } - // careful, this is based on buffer and has its own pointer (this.pointer != pointer) and inner chars - const len = countSymbols(this.buffer) - for (let pointer = 0; pointer < len; ++pointer) { - const codePoint = this.buffer.codePointAt(pointer) + async [kDestroy](err) { + return new Promise((resolve) => { + const requests = this[kQueue].splice(this[kPendingIdx]) + for (let i = 0; i < requests.length; i++) { + const request = requests[i] + errorRequest(this, request, err) + } - if (codePoint === 58 && !this.passwordTokenSeenFlag) { - this.passwordTokenSeenFlag = true - continue + const callback = () => { + if (this[kClosedResolve]) { + // TODO (fix): Should we error here with ClientDestroyedError? + this[kClosedResolve]() + this[kClosedResolve] = null + } + resolve() } - const encodedCodePoints = percentEncodeChar( - codePoint, - isUserinfoPercentEncode - ) - if (this.passwordTokenSeenFlag) { - this.url.password += encodedCodePoints + + if (this[kHTTP2Session] != null) { + util.destroy(this[kHTTP2Session], err) + this[kHTTP2Session] = null + this[kHTTP2SessionState] = null + } + + if (!this[kSocket]) { + queueMicrotask(callback) } else { - this.url.username += encodedCodePoints + util.destroy(this[kSocket].on('close', callback), err) } - } - this.buffer = '' - } else if ( - isNaN(c) || - c === 47 || - c === 63 || - c === 35 || - (isSpecial(this.url) && c === 92) - ) { - if (this.atFlag && this.buffer === '') { - this.parseError = true - return failure - } - this.pointer -= countSymbols(this.buffer) + 1 - this.buffer = '' - this.state = 'host' - } else { - this.buffer += cStr - } - return true + resume(this) + }) + } } - URLStateMachine.prototype['parse hostname'] = URLStateMachine.prototype[ - 'parse host' - ] = function parseHostName(c, cStr) { - if (this.stateOverride && this.url.scheme === 'file') { - --this.pointer - this.state = 'file host' - } else if (c === 58 && !this.arrFlag) { - if (this.buffer === '') { - this.parseError = true - return failure - } + function onHttp2SessionError(err) { + assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID') - const host = parseHost(this.buffer, isSpecial(this.url)) - if (host === failure) { - return failure - } + this[kSocket][kError] = err - this.url.host = host - this.buffer = '' - this.state = 'port' - if (this.stateOverride === 'hostname') { - return false - } - } else if ( - isNaN(c) || - c === 47 || - c === 63 || - c === 35 || - (isSpecial(this.url) && c === 92) - ) { - --this.pointer - if (isSpecial(this.url) && this.buffer === '') { - this.parseError = true - return failure - } else if ( - this.stateOverride && - this.buffer === '' && - (includesCredentials(this.url) || this.url.port !== null) - ) { - this.parseError = true - return false - } + onError(this[kClient], err) + } - const host = parseHost(this.buffer, isSpecial(this.url)) - if (host === failure) { - return failure - } + function onHttp2FrameError(type, code, id) { + const err = new InformationalError( + `HTTP/2: "frameError" received - type ${type}, code ${code}` + ) - this.url.host = host - this.buffer = '' - this.state = 'path start' - if (this.stateOverride) { - return false - } - } else { - if (c === 91) { - this.arrFlag = true - } else if (c === 93) { - this.arrFlag = false - } - this.buffer += cStr + if (id === 0) { + this[kSocket][kError] = err + onError(this[kClient], err) } + } - return true + function onHttp2SessionEnd() { + util.destroy(this, new SocketError('other side closed')) + util.destroy(this[kSocket], new SocketError('other side closed')) } - URLStateMachine.prototype['parse port'] = function parsePort(c, cStr) { - if (isASCIIDigit(c)) { - this.buffer += cStr - } else if ( - isNaN(c) || - c === 47 || - c === 63 || - c === 35 || - (isSpecial(this.url) && c === 92) || - this.stateOverride - ) { - if (this.buffer !== '') { - const port = parseInt(this.buffer) - if (port > Math.pow(2, 16) - 1) { - this.parseError = true - return failure - } - this.url.port = port === defaultPort(this.url.scheme) ? null : port - this.buffer = '' - } - if (this.stateOverride) { - return false + function onHTTP2GoAway(code) { + const client = this[kClient] + const err = new InformationalError( + `HTTP/2: "GOAWAY" frame received with code ${code}` + ) + client[kSocket] = null + client[kHTTP2Session] = null + + if (client.destroyed) { + assert(this[kPending] === 0) + + // Fail entire queue. + const requests = client[kQueue].splice(client[kRunningIdx]) + for (let i = 0; i < requests.length; i++) { + const request = requests[i] + errorRequest(this, request, err) } - this.state = 'path start' - --this.pointer - } else { - this.parseError = true - return failure + } else if (client[kRunning] > 0) { + // Fail head of pipeline. + const request = client[kQueue][client[kRunningIdx]] + client[kQueue][client[kRunningIdx]++] = null + + errorRequest(client, request, err) } - return true + client[kPendingIdx] = client[kRunningIdx] + + assert(client[kRunning] === 0) + + client.emit('disconnect', client[kUrl], [client], err) + + resume(client) } - const fileOtherwiseCodePoints = new Set([47, 92, 63, 35]) + const constants = __nccwpck_require__(953) + const createRedirectInterceptor = __nccwpck_require__(8861) + const EMPTY_BUF = Buffer.alloc(0) - URLStateMachine.prototype['parse file'] = function parseFile(c) { - this.url.scheme = 'file' + async function lazyllhttp() { + const llhttpWasmData = process.env.JEST_WORKER_ID + ? __nccwpck_require__(1145) + : undefined - if (c === 47 || c === 92) { - if (c === 92) { - this.parseError = true - } - this.state = 'file slash' - } else if (this.base !== null && this.base.scheme === 'file') { - if (isNaN(c)) { - this.url.host = this.base.host - this.url.path = this.base.path.slice() - this.url.query = this.base.query - } else if (c === 63) { - this.url.host = this.base.host - this.url.path = this.base.path.slice() - this.url.query = '' - this.state = 'query' - } else if (c === 35) { - this.url.host = this.base.host - this.url.path = this.base.path.slice() - this.url.query = this.base.query - this.url.fragment = '' - this.state = 'fragment' - } else { - if ( - this.input.length - this.pointer - 1 === 0 || // remaining consists of 0 code points - !isWindowsDriveLetterCodePoints( - c, - this.input[this.pointer + 1] - ) || - (this.input.length - this.pointer - 1 >= 2 && // remaining has at least 2 code points - !fileOtherwiseCodePoints.has(this.input[this.pointer + 2])) - ) { - this.url.host = this.base.host - this.url.path = this.base.path.slice() - shortenPath(this.url) - } else { - this.parseError = true - } + let mod + try { + mod = await WebAssembly.compile( + Buffer.from(__nccwpck_require__(5627), 'base64') + ) + } catch (e) { + /* istanbul ignore next */ - this.state = 'path' - --this.pointer - } - } else { - this.state = 'path' - --this.pointer + // We could check if the error was caused by the simd option not + // being enabled, but the occurring of this other error + // * https://github.com/emscripten-core/emscripten/issues/11495 + // got me to remove that check to avoid breaking Node 12. + mod = await WebAssembly.compile( + Buffer.from(llhttpWasmData || __nccwpck_require__(1145), 'base64') + ) } - return true + return await WebAssembly.instantiate(mod, { + env: { + /* eslint-disable camelcase */ + + wasm_on_url: (p, at, len) => { + /* istanbul ignore next */ + return 0 + }, + wasm_on_status: (p, at, len) => { + assert.strictEqual(currentParser.ptr, p) + const start = at - currentBufferPtr + currentBufferRef.byteOffset + return ( + currentParser.onStatus( + new FastBuffer(currentBufferRef.buffer, start, len) + ) || 0 + ) + }, + wasm_on_message_begin: (p) => { + assert.strictEqual(currentParser.ptr, p) + return currentParser.onMessageBegin() || 0 + }, + wasm_on_header_field: (p, at, len) => { + assert.strictEqual(currentParser.ptr, p) + const start = at - currentBufferPtr + currentBufferRef.byteOffset + return ( + currentParser.onHeaderField( + new FastBuffer(currentBufferRef.buffer, start, len) + ) || 0 + ) + }, + wasm_on_header_value: (p, at, len) => { + assert.strictEqual(currentParser.ptr, p) + const start = at - currentBufferPtr + currentBufferRef.byteOffset + return ( + currentParser.onHeaderValue( + new FastBuffer(currentBufferRef.buffer, start, len) + ) || 0 + ) + }, + wasm_on_headers_complete: ( + p, + statusCode, + upgrade, + shouldKeepAlive + ) => { + assert.strictEqual(currentParser.ptr, p) + return ( + currentParser.onHeadersComplete( + statusCode, + Boolean(upgrade), + Boolean(shouldKeepAlive) + ) || 0 + ) + }, + wasm_on_body: (p, at, len) => { + assert.strictEqual(currentParser.ptr, p) + const start = at - currentBufferPtr + currentBufferRef.byteOffset + return ( + currentParser.onBody( + new FastBuffer(currentBufferRef.buffer, start, len) + ) || 0 + ) + }, + wasm_on_message_complete: (p) => { + assert.strictEqual(currentParser.ptr, p) + return currentParser.onMessageComplete() || 0 + }, + + /* eslint-enable camelcase */ + }, + }) } - URLStateMachine.prototype['parse file slash'] = function parseFileSlash( - c - ) { - if (c === 47 || c === 92) { - if (c === 92) { - this.parseError = true - } - this.state = 'file host' - } else { - if (this.base !== null && this.base.scheme === 'file') { - if (isNormalizedWindowsDriveLetterString(this.base.path[0])) { - this.url.path.push(this.base.path[0]) + let llhttpInstance = null + let llhttpPromise = lazyllhttp() + llhttpPromise.catch() + + let currentParser = null + let currentBufferRef = null + let currentBufferSize = 0 + let currentBufferPtr = null + + const TIMEOUT_HEADERS = 1 + const TIMEOUT_BODY = 2 + const TIMEOUT_IDLE = 3 + + class Parser { + constructor(client, socket, { exports }) { + assert( + Number.isFinite(client[kMaxHeadersSize]) && + client[kMaxHeadersSize] > 0 + ) + + this.llhttp = exports + this.ptr = this.llhttp.llhttp_alloc(constants.TYPE.RESPONSE) + this.client = client + this.socket = socket + this.timeout = null + this.timeoutValue = null + this.timeoutType = null + this.statusCode = null + this.statusText = '' + this.upgrade = false + this.headers = [] + this.headersSize = 0 + this.headersMaxSize = client[kMaxHeadersSize] + this.shouldKeepAlive = false + this.paused = false + this.resume = this.resume.bind(this) + + this.bytesRead = 0 + + this.keepAlive = '' + this.contentLength = '' + this.connection = '' + this.maxResponseSize = client[kMaxResponseSize] + } + + setTimeout(value, type) { + this.timeoutType = type + if (value !== this.timeoutValue) { + timers.clearTimeout(this.timeout) + if (value) { + this.timeout = timers.setTimeout(onParserTimeout, value, this) + // istanbul ignore else: only for jest + if (this.timeout.unref) { + this.timeout.unref() + } } else { - this.url.host = this.base.host + this.timeout = null + } + this.timeoutValue = value + } else if (this.timeout) { + // istanbul ignore else: only for jest + if (this.timeout.refresh) { + this.timeout.refresh() } } - this.state = 'path' - --this.pointer } - return true - } + resume() { + if (this.socket.destroyed || !this.paused) { + return + } - URLStateMachine.prototype['parse file host'] = function parseFileHost( - c, - cStr - ) { - if (isNaN(c) || c === 47 || c === 92 || c === 63 || c === 35) { - --this.pointer - if (!this.stateOverride && isWindowsDriveLetterString(this.buffer)) { - this.parseError = true - this.state = 'path' - } else if (this.buffer === '') { - this.url.host = '' - if (this.stateOverride) { - return false + assert(this.ptr != null) + assert(currentParser == null) + + this.llhttp.llhttp_resume(this.ptr) + + assert(this.timeoutType === TIMEOUT_BODY) + if (this.timeout) { + // istanbul ignore else: only for jest + if (this.timeout.refresh) { + this.timeout.refresh() } - this.state = 'path start' - } else { - let host = parseHost(this.buffer, isSpecial(this.url)) - if (host === failure) { - return failure + } + + this.paused = false + this.execute(this.socket.read() || EMPTY_BUF) // Flush parser. + this.readMore() + } + + readMore() { + while (!this.paused && this.ptr) { + const chunk = this.socket.read() + if (chunk === null) { + break } - if (host === 'localhost') { - host = '' + this.execute(chunk) + } + } + + execute(data) { + assert(this.ptr != null) + assert(currentParser == null) + assert(!this.paused) + + const { socket, llhttp } = this + + if (data.length > currentBufferSize) { + if (currentBufferPtr) { + llhttp.free(currentBufferPtr) } - this.url.host = host + currentBufferSize = Math.ceil(data.length / 4096) * 4096 + currentBufferPtr = llhttp.malloc(currentBufferSize) + } - if (this.stateOverride) { - return false + new Uint8Array( + llhttp.memory.buffer, + currentBufferPtr, + currentBufferSize + ).set(data) + + // Call `execute` on the wasm parser. + // We pass the `llhttp_parser` pointer address, the pointer address of buffer view data, + // and finally the length of bytes to parse. + // The return value is an error code or `constants.ERROR.OK`. + try { + let ret + + try { + currentBufferRef = data + currentParser = this + ret = llhttp.llhttp_execute( + this.ptr, + currentBufferPtr, + data.length + ) + /* eslint-disable-next-line no-useless-catch */ + } catch (err) { + /* istanbul ignore next: difficult to make a test case for */ + throw err + } finally { + currentParser = null + currentBufferRef = null } - this.buffer = '' - this.state = 'path start' + const offset = + llhttp.llhttp_get_error_pos(this.ptr) - currentBufferPtr + + if (ret === constants.ERROR.PAUSED_UPGRADE) { + this.onUpgrade(data.slice(offset)) + } else if (ret === constants.ERROR.PAUSED) { + this.paused = true + socket.unshift(data.slice(offset)) + } else if (ret !== constants.ERROR.OK) { + const ptr = llhttp.llhttp_get_error_reason(this.ptr) + let message = '' + /* istanbul ignore else: difficult to make a test case for */ + if (ptr) { + const len = new Uint8Array(llhttp.memory.buffer, ptr).indexOf(0) + message = + 'Response does not match the HTTP/1.1 protocol (' + + Buffer.from(llhttp.memory.buffer, ptr, len).toString() + + ')' + } + throw new HTTPParserError( + message, + constants.ERROR[ret], + data.slice(offset) + ) + } + } catch (err) { + util.destroy(socket, err) } - } else { - this.buffer += cStr } - return true - } + destroy() { + assert(this.ptr != null) + assert(currentParser == null) - URLStateMachine.prototype['parse path start'] = function parsePathStart( - c - ) { - if (isSpecial(this.url)) { - if (c === 92) { - this.parseError = true - } - this.state = 'path' + this.llhttp.llhttp_free(this.ptr) + this.ptr = null - if (c !== 47 && c !== 92) { - --this.pointer + timers.clearTimeout(this.timeout) + this.timeout = null + this.timeoutValue = null + this.timeoutType = null + + this.paused = false + } + + onStatus(buf) { + this.statusText = buf.toString() + } + + onMessageBegin() { + const { socket, client } = this + + /* istanbul ignore next: difficult to make a test case for */ + if (socket.destroyed) { + return -1 } - } else if (!this.stateOverride && c === 63) { - this.url.query = '' - this.state = 'query' - } else if (!this.stateOverride && c === 35) { - this.url.fragment = '' - this.state = 'fragment' - } else if (c !== undefined) { - this.state = 'path' - if (c !== 47) { - --this.pointer + + const request = client[kQueue][client[kRunningIdx]] + if (!request) { + return -1 } } - return true - } + onHeaderField(buf) { + const len = this.headers.length - URLStateMachine.prototype['parse path'] = function parsePath(c) { - if ( - isNaN(c) || - c === 47 || - (isSpecial(this.url) && c === 92) || - (!this.stateOverride && (c === 63 || c === 35)) - ) { - if (isSpecial(this.url) && c === 92) { - this.parseError = true + if ((len & 1) === 0) { + this.headers.push(buf) + } else { + this.headers[len - 1] = Buffer.concat([this.headers[len - 1], buf]) } - if (isDoubleDot(this.buffer)) { - shortenPath(this.url) - if (c !== 47 && !(isSpecial(this.url) && c === 92)) { - this.url.path.push('') - } - } else if ( - isSingleDot(this.buffer) && - c !== 47 && - !(isSpecial(this.url) && c === 92) - ) { - this.url.path.push('') - } else if (!isSingleDot(this.buffer)) { - if ( - this.url.scheme === 'file' && - this.url.path.length === 0 && - isWindowsDriveLetterString(this.buffer) - ) { - if (this.url.host !== '' && this.url.host !== null) { - this.parseError = true - this.url.host = '' - } - this.buffer = this.buffer[0] + ':' - } - this.url.path.push(this.buffer) + this.trackHeader(buf.length) + } + + onHeaderValue(buf) { + let len = this.headers.length + + if ((len & 1) === 1) { + this.headers.push(buf) + len += 1 + } else { + this.headers[len - 1] = Buffer.concat([this.headers[len - 1], buf]) } - this.buffer = '' + + const key = this.headers[len - 2] if ( - this.url.scheme === 'file' && - (c === undefined || c === 63 || c === 35) + key.length === 10 && + key.toString().toLowerCase() === 'keep-alive' ) { - while (this.url.path.length > 1 && this.url.path[0] === '') { - this.parseError = true - this.url.path.shift() - } - } - if (c === 63) { - this.url.query = '' - this.state = 'query' + this.keepAlive += buf.toString() + } else if ( + key.length === 10 && + key.toString().toLowerCase() === 'connection' + ) { + this.connection += buf.toString() + } else if ( + key.length === 14 && + key.toString().toLowerCase() === 'content-length' + ) { + this.contentLength += buf.toString() } - if (c === 35) { - this.url.fragment = '' - this.state = 'fragment' + + this.trackHeader(buf.length) + } + + trackHeader(len) { + this.headersSize += len + if (this.headersSize >= this.headersMaxSize) { + util.destroy(this.socket, new HeadersOverflowError()) } - } else { - // TODO: If c is not a URL code point and not "%", parse error. + } - if ( - c === 37 && - (!isASCIIHex(this.input[this.pointer + 1]) || - !isASCIIHex(this.input[this.pointer + 2])) - ) { - this.parseError = true + onUpgrade(head) { + const { upgrade, client, socket, headers, statusCode } = this + + assert(upgrade) + + const request = client[kQueue][client[kRunningIdx]] + assert(request) + + assert(!socket.destroyed) + assert(socket === client[kSocket]) + assert(!this.paused) + assert(request.upgrade || request.method === 'CONNECT') + + this.statusCode = null + this.statusText = '' + this.shouldKeepAlive = null + + assert(this.headers.length % 2 === 0) + this.headers = [] + this.headersSize = 0 + + socket.unshift(head) + + socket[kParser].destroy() + socket[kParser] = null + + socket[kClient] = null + socket[kError] = null + socket + .removeListener('error', onSocketError) + .removeListener('readable', onSocketReadable) + .removeListener('end', onSocketEnd) + .removeListener('close', onSocketClose) + + client[kSocket] = null + client[kQueue][client[kRunningIdx]++] = null + client.emit( + 'disconnect', + client[kUrl], + [client], + new InformationalError('upgrade') + ) + + try { + request.onUpgrade(statusCode, headers, socket) + } catch (err) { + util.destroy(socket, err) } - this.buffer += percentEncodeChar(c, isPathPercentEncode) + resume(client) } - return true - } + onHeadersComplete(statusCode, upgrade, shouldKeepAlive) { + const { client, socket, headers, statusText } = this - URLStateMachine.prototype['parse cannot-be-a-base-URL path'] = - function parseCannotBeABaseURLPath(c) { - if (c === 63) { - this.url.query = '' - this.state = 'query' - } else if (c === 35) { - this.url.fragment = '' - this.state = 'fragment' - } else { - // TODO: Add: not a URL code point - if (!isNaN(c) && c !== 37) { - this.parseError = true - } + /* istanbul ignore next: difficult to make a test case for */ + if (socket.destroyed) { + return -1 + } - if ( - c === 37 && - (!isASCIIHex(this.input[this.pointer + 1]) || - !isASCIIHex(this.input[this.pointer + 2])) - ) { - this.parseError = true - } + const request = client[kQueue][client[kRunningIdx]] - if (!isNaN(c)) { - this.url.path[0] = - this.url.path[0] + - percentEncodeChar(c, isC0ControlPercentEncode) + /* istanbul ignore next: difficult to make a test case for */ + if (!request) { + return -1 + } + + assert(!this.upgrade) + assert(this.statusCode < 200) + + if (statusCode === 100) { + util.destroy( + socket, + new SocketError('bad response', util.getSocketInfo(socket)) + ) + return -1 + } + + /* this can only happen if server is misbehaving */ + if (upgrade && !request.upgrade) { + util.destroy( + socket, + new SocketError('bad upgrade', util.getSocketInfo(socket)) + ) + return -1 + } + + assert.strictEqual(this.timeoutType, TIMEOUT_HEADERS) + + this.statusCode = statusCode + this.shouldKeepAlive = + shouldKeepAlive || + // Override llhttp value which does not allow keepAlive for HEAD. + (request.method === 'HEAD' && + !socket[kReset] && + this.connection.toLowerCase() === 'keep-alive') + + if (this.statusCode >= 200) { + const bodyTimeout = + request.bodyTimeout != null + ? request.bodyTimeout + : client[kBodyTimeout] + this.setTimeout(bodyTimeout, TIMEOUT_BODY) + } else if (this.timeout) { + // istanbul ignore else: only for jest + if (this.timeout.refresh) { + this.timeout.refresh() } } - return true - } + if (request.method === 'CONNECT') { + assert(client[kRunning] === 1) + this.upgrade = true + return 2 + } - URLStateMachine.prototype['parse query'] = function parseQuery(c, cStr) { - if (isNaN(c) || (!this.stateOverride && c === 35)) { - if ( - !isSpecial(this.url) || - this.url.scheme === 'ws' || - this.url.scheme === 'wss' - ) { - this.encodingOverride = 'utf-8' + if (upgrade) { + assert(client[kRunning] === 1) + this.upgrade = true + return 2 } - const buffer = new Buffer(this.buffer) // TODO: Use encoding override instead - for (let i = 0; i < buffer.length; ++i) { - if ( - buffer[i] < 0x21 || - buffer[i] > 0x7e || - buffer[i] === 0x22 || - buffer[i] === 0x23 || - buffer[i] === 0x3c || - buffer[i] === 0x3e - ) { - this.url.query += percentEncode(buffer[i]) + assert(this.headers.length % 2 === 0) + this.headers = [] + this.headersSize = 0 + + if (this.shouldKeepAlive && client[kPipelining]) { + const keepAliveTimeout = this.keepAlive + ? util.parseKeepAliveTimeout(this.keepAlive) + : null + + if (keepAliveTimeout != null) { + const timeout = Math.min( + keepAliveTimeout - client[kKeepAliveTimeoutThreshold], + client[kKeepAliveMaxTimeout] + ) + if (timeout <= 0) { + socket[kReset] = true + } else { + client[kKeepAliveTimeoutValue] = timeout + } } else { - this.url.query += String.fromCodePoint(buffer[i]) + client[kKeepAliveTimeoutValue] = client[kKeepAliveDefaultTimeout] } + } else { + // Stop more requests from being dispatched. + socket[kReset] = true } - this.buffer = '' - if (c === 35) { - this.url.fragment = '' - this.state = 'fragment' + let pause + try { + pause = + request.onHeaders( + statusCode, + headers, + this.resume, + statusText + ) === false + } catch (err) { + util.destroy(socket, err) + return -1 } - } else { - // TODO: If c is not a URL code point and not "%", parse error. - if ( - c === 37 && - (!isASCIIHex(this.input[this.pointer + 1]) || - !isASCIIHex(this.input[this.pointer + 2])) - ) { - this.parseError = true + + if (request.method === 'HEAD') { + return 1 } - this.buffer += cStr + if (statusCode < 200) { + return 1 + } + + if (socket[kBlocking]) { + socket[kBlocking] = false + resume(client) + } + + return pause ? constants.ERROR.PAUSED : 0 } - return true - } + onBody(buf) { + const { client, socket, statusCode, maxResponseSize } = this + + if (socket.destroyed) { + return -1 + } + + const request = client[kQueue][client[kRunningIdx]] + assert(request) + + assert.strictEqual(this.timeoutType, TIMEOUT_BODY) + if (this.timeout) { + // istanbul ignore else: only for jest + if (this.timeout.refresh) { + this.timeout.refresh() + } + } + + assert(statusCode >= 200) - URLStateMachine.prototype['parse fragment'] = function parseFragment(c) { - if (isNaN(c)) { - // do nothing - } else if (c === 0x0) { - this.parseError = true - } else { - // TODO: If c is not a URL code point and not "%", parse error. if ( - c === 37 && - (!isASCIIHex(this.input[this.pointer + 1]) || - !isASCIIHex(this.input[this.pointer + 2])) + maxResponseSize > -1 && + this.bytesRead + buf.length > maxResponseSize ) { - this.parseError = true + util.destroy(socket, new ResponseExceededMaxSizeError()) + return -1 } - this.url.fragment += percentEncodeChar(c, isC0ControlPercentEncode) + this.bytesRead += buf.length + + try { + if (request.onData(buf) === false) { + return constants.ERROR.PAUSED + } + } catch (err) { + util.destroy(socket, err) + return -1 + } } - return true - } + onMessageComplete() { + const { + client, + socket, + statusCode, + upgrade, + headers, + contentLength, + bytesRead, + shouldKeepAlive, + } = this - function serializeURL(url, excludeFragment) { - let output = url.scheme + ':' - if (url.host !== null) { - output += '//' + if (socket.destroyed && (!statusCode || shouldKeepAlive)) { + return -1 + } - if (url.username !== '' || url.password !== '') { - output += url.username - if (url.password !== '') { - output += ':' + url.password - } - output += '@' + if (upgrade) { + return } - output += serializeHost(url.host) + const request = client[kQueue][client[kRunningIdx]] + assert(request) - if (url.port !== null) { - output += ':' + url.port + assert(statusCode >= 100) + + this.statusCode = null + this.statusText = '' + this.bytesRead = 0 + this.contentLength = '' + this.keepAlive = '' + this.connection = '' + + assert(this.headers.length % 2 === 0) + this.headers = [] + this.headersSize = 0 + + if (statusCode < 200) { + return } - } else if (url.host === null && url.scheme === 'file') { - output += '//' - } - if (url.cannotBeABaseURL) { - output += url.path[0] - } else { - for (const string of url.path) { - output += '/' + string + /* istanbul ignore next: should be handled by llhttp? */ + if ( + request.method !== 'HEAD' && + contentLength && + bytesRead !== parseInt(contentLength, 10) + ) { + util.destroy(socket, new ResponseContentLengthMismatchError()) + return -1 + } + + try { + request.onComplete(headers) + } catch (err) { + errorRequest(client, request, err) + } + + client[kQueue][client[kRunningIdx]++] = null + + if (socket[kWriting]) { + assert.strictEqual(client[kRunning], 0) + // Response completed before request. + util.destroy(socket, new InformationalError('reset')) + return constants.ERROR.PAUSED + } else if (!shouldKeepAlive) { + util.destroy(socket, new InformationalError('reset')) + return constants.ERROR.PAUSED + } else if (socket[kReset] && client[kRunning] === 0) { + // Destroy socket once all requests have completed. + // The request at the tail of the pipeline is the one + // that requested reset and no further requests should + // have been queued since then. + util.destroy(socket, new InformationalError('reset')) + return constants.ERROR.PAUSED + } else if (client[kPipelining] === 1) { + // We must wait a full event loop cycle to reuse this socket to make sure + // that non-spec compliant servers are not closing the connection even if they + // said they won't. + setImmediate(resume, client) + } else { + resume(client) } } + } - if (url.query !== null) { - output += '?' + url.query + function onParserTimeout(parser) { + const { socket, timeoutType, client } = parser + + /* istanbul ignore else */ + if (timeoutType === TIMEOUT_HEADERS) { + if ( + !socket[kWriting] || + socket.writableNeedDrain || + client[kRunning] > 1 + ) { + assert(!parser.paused, 'cannot be paused while waiting for headers') + util.destroy(socket, new HeadersTimeoutError()) + } + } else if (timeoutType === TIMEOUT_BODY) { + if (!parser.paused) { + util.destroy(socket, new BodyTimeoutError()) + } + } else if (timeoutType === TIMEOUT_IDLE) { + assert(client[kRunning] === 0 && client[kKeepAliveTimeoutValue]) + util.destroy(socket, new InformationalError('socket idle timeout')) } + } - if (!excludeFragment && url.fragment !== null) { - output += '#' + url.fragment + function onSocketReadable() { + const { [kParser]: parser } = this + if (parser) { + parser.readMore() } + } + + function onSocketError(err) { + const { [kClient]: client, [kParser]: parser } = this + + assert(err.code !== 'ERR_TLS_CERT_ALTNAME_INVALID') + + if (client[kHTTPConnVersion] !== 'h2') { + // On Mac OS, we get an ECONNRESET even if there is a full body to be forwarded + // to the user. + if ( + err.code === 'ECONNRESET' && + parser.statusCode && + !parser.shouldKeepAlive + ) { + // We treat all incoming data so for as a valid response. + parser.onMessageComplete() + return + } + } + + this[kError] = err + + onError(this[kClient], err) + } + + function onError(client, err) { + if ( + client[kRunning] === 0 && + err.code !== 'UND_ERR_INFO' && + err.code !== 'UND_ERR_SOCKET' + ) { + // Error is not caused by running request and not a recoverable + // socket error. + + assert(client[kPendingIdx] === client[kRunningIdx]) + + const requests = client[kQueue].splice(client[kRunningIdx]) + for (let i = 0; i < requests.length; i++) { + const request = requests[i] + errorRequest(client, request, err) + } + assert(client[kSize] === 0) + } + } + + function onSocketEnd() { + const { [kParser]: parser, [kClient]: client } = this + + if (client[kHTTPConnVersion] !== 'h2') { + if (parser.statusCode && !parser.shouldKeepAlive) { + // We treat all incoming data so far as a valid response. + parser.onMessageComplete() + return + } + } + + util.destroy( + this, + new SocketError('other side closed', util.getSocketInfo(this)) + ) + } + + function onSocketClose() { + const { [kClient]: client, [kParser]: parser } = this + + if (client[kHTTPConnVersion] === 'h1' && parser) { + if (!this[kError] && parser.statusCode && !parser.shouldKeepAlive) { + // We treat all incoming data so far as a valid response. + parser.onMessageComplete() + } + + this[kParser].destroy() + this[kParser] = null + } + + const err = + this[kError] || new SocketError('closed', util.getSocketInfo(this)) + + client[kSocket] = null + + if (client.destroyed) { + assert(client[kPending] === 0) + + // Fail entire queue. + const requests = client[kQueue].splice(client[kRunningIdx]) + for (let i = 0; i < requests.length; i++) { + const request = requests[i] + errorRequest(client, request, err) + } + } else if (client[kRunning] > 0 && err.code !== 'UND_ERR_INFO') { + // Fail head of pipeline. + const request = client[kQueue][client[kRunningIdx]] + client[kQueue][client[kRunningIdx]++] = null + + errorRequest(client, request, err) + } + + client[kPendingIdx] = client[kRunningIdx] + + assert(client[kRunning] === 0) + + client.emit('disconnect', client[kUrl], [client], err) + + resume(client) + } + + async function connect(client) { + assert(!client[kConnecting]) + assert(!client[kSocket]) + + let { host, hostname, protocol, port } = client[kUrl] + + // Resolve ipv6 + if (hostname[0] === '[') { + const idx = hostname.indexOf(']') + + assert(idx !== -1) + const ip = hostname.substr(1, idx - 1) + + assert(net.isIP(ip)) + hostname = ip + } + + client[kConnecting] = true + + if (channels.beforeConnect.hasSubscribers) { + channels.beforeConnect.publish({ + connectParams: { + host, + hostname, + protocol, + port, + servername: client[kServerName], + localAddress: client[kLocalAddress], + }, + connector: client[kConnector], + }) + } + + try { + const socket = await new Promise((resolve, reject) => { + client[kConnector]( + { + host, + hostname, + protocol, + port, + servername: client[kServerName], + localAddress: client[kLocalAddress], + }, + (err, socket) => { + if (err) { + reject(err) + } else { + resolve(socket) + } + } + ) + }) + + if (client.destroyed) { + util.destroy( + socket.on('error', () => {}), + new ClientDestroyedError() + ) + return + } + + client[kConnecting] = false + + assert(socket) + + const isH2 = socket.alpnProtocol === 'h2' + if (isH2) { + if (!h2ExperimentalWarned) { + h2ExperimentalWarned = true + process.emitWarning( + 'H2 support is experimental, expect them to change at any time.', + { + code: 'UNDICI-H2', + } + ) + } + + const session = http2.connect(client[kUrl], { + createConnection: () => socket, + peerMaxConcurrentStreams: + client[kHTTP2SessionState].maxConcurrentStreams, + }) + + client[kHTTPConnVersion] = 'h2' + session[kClient] = client + session[kSocket] = socket + session.on('error', onHttp2SessionError) + session.on('frameError', onHttp2FrameError) + session.on('end', onHttp2SessionEnd) + session.on('goaway', onHTTP2GoAway) + session.on('close', onSocketClose) + session.unref() + + client[kHTTP2Session] = session + socket[kHTTP2Session] = session + } else { + if (!llhttpInstance) { + llhttpInstance = await llhttpPromise + llhttpPromise = null + } + + socket[kNoRef] = false + socket[kWriting] = false + socket[kReset] = false + socket[kBlocking] = false + socket[kParser] = new Parser(client, socket, llhttpInstance) + } + + socket[kCounter] = 0 + socket[kMaxRequests] = client[kMaxRequests] + socket[kClient] = client + socket[kError] = null + + socket + .on('error', onSocketError) + .on('readable', onSocketReadable) + .on('end', onSocketEnd) + .on('close', onSocketClose) + + client[kSocket] = socket + + if (channels.connected.hasSubscribers) { + channels.connected.publish({ + connectParams: { + host, + hostname, + protocol, + port, + servername: client[kServerName], + localAddress: client[kLocalAddress], + }, + connector: client[kConnector], + socket, + }) + } + client.emit('connect', client[kUrl], [client]) + } catch (err) { + if (client.destroyed) { + return + } + + client[kConnecting] = false + + if (channels.connectError.hasSubscribers) { + channels.connectError.publish({ + connectParams: { + host, + hostname, + protocol, + port, + servername: client[kServerName], + localAddress: client[kLocalAddress], + }, + connector: client[kConnector], + error: err, + }) + } + + if (err.code === 'ERR_TLS_CERT_ALTNAME_INVALID') { + assert(client[kRunning] === 0) + while ( + client[kPending] > 0 && + client[kQueue][client[kPendingIdx]].servername === + client[kServerName] + ) { + const request = client[kQueue][client[kPendingIdx]++] + errorRequest(client, request, err) + } + } else { + onError(client, err) + } + + client.emit('connectionError', client[kUrl], [client], err) + } + + resume(client) + } + + function emitDrain(client) { + client[kNeedDrain] = 0 + client.emit('drain', client[kUrl], [client]) + } + + function resume(client, sync) { + if (client[kResuming] === 2) { + return + } + + client[kResuming] = 2 + + _resume(client, sync) + client[kResuming] = 0 + + if (client[kRunningIdx] > 256) { + client[kQueue].splice(0, client[kRunningIdx]) + client[kPendingIdx] -= client[kRunningIdx] + client[kRunningIdx] = 0 + } + } + + function _resume(client, sync) { + while (true) { + if (client.destroyed) { + assert(client[kPending] === 0) + return + } + + if (client[kClosedResolve] && !client[kSize]) { + client[kClosedResolve]() + client[kClosedResolve] = null + return + } + + const socket = client[kSocket] + + if (socket && !socket.destroyed && socket.alpnProtocol !== 'h2') { + if (client[kSize] === 0) { + if (!socket[kNoRef] && socket.unref) { + socket.unref() + socket[kNoRef] = true + } + } else if (socket[kNoRef] && socket.ref) { + socket.ref() + socket[kNoRef] = false + } + + if (client[kSize] === 0) { + if (socket[kParser].timeoutType !== TIMEOUT_IDLE) { + socket[kParser].setTimeout( + client[kKeepAliveTimeoutValue], + TIMEOUT_IDLE + ) + } + } else if ( + client[kRunning] > 0 && + socket[kParser].statusCode < 200 + ) { + if (socket[kParser].timeoutType !== TIMEOUT_HEADERS) { + const request = client[kQueue][client[kRunningIdx]] + const headersTimeout = + request.headersTimeout != null + ? request.headersTimeout + : client[kHeadersTimeout] + socket[kParser].setTimeout(headersTimeout, TIMEOUT_HEADERS) + } + } + } + + if (client[kBusy]) { + client[kNeedDrain] = 2 + } else if (client[kNeedDrain] === 2) { + if (sync) { + client[kNeedDrain] = 1 + process.nextTick(emitDrain, client) + } else { + emitDrain(client) + } + continue + } + + if (client[kPending] === 0) { + return + } + + if (client[kRunning] >= (client[kPipelining] || 1)) { + return + } + + const request = client[kQueue][client[kPendingIdx]] + + if ( + client[kUrl].protocol === 'https:' && + client[kServerName] !== request.servername + ) { + if (client[kRunning] > 0) { + return + } + + client[kServerName] = request.servername + + if (socket && socket.servername !== request.servername) { + util.destroy(socket, new InformationalError('servername changed')) + return + } + } + + if (client[kConnecting]) { + return + } + + if (!socket && !client[kHTTP2Session]) { + connect(client) + return + } + + if ( + socket.destroyed || + socket[kWriting] || + socket[kReset] || + socket[kBlocking] + ) { + return + } + + if (client[kRunning] > 0 && !request.idempotent) { + // Non-idempotent request cannot be retried. + // Ensure that no other requests are inflight and + // could cause failure. + return + } + + if ( + client[kRunning] > 0 && + (request.upgrade || request.method === 'CONNECT') + ) { + // Don't dispatch an upgrade until all preceding requests have completed. + // A misbehaving server might upgrade the connection before all pipelined + // request has completed. + return + } + + if ( + client[kRunning] > 0 && + util.bodyLength(request.body) !== 0 && + (util.isStream(request.body) || util.isAsyncIterable(request.body)) + ) { + // Request with stream or iterator body can error while other requests + // are inflight and indirectly error those as well. + // Ensure this doesn't happen by waiting for inflight + // to complete before dispatching. + + // Request with stream or iterator body cannot be retried. + // Ensure that no other requests are inflight and + // could cause failure. + return + } + + if (!request.aborted && write(client, request)) { + client[kPendingIdx]++ + } else { + client[kQueue].splice(client[kPendingIdx], 1) + } + } + } + + // https://www.rfc-editor.org/rfc/rfc7230#section-3.3.2 + function shouldSendContentLength(method) { + return ( + method !== 'GET' && + method !== 'HEAD' && + method !== 'OPTIONS' && + method !== 'TRACE' && + method !== 'CONNECT' + ) + } + + function write(client, request) { + if (client[kHTTPConnVersion] === 'h2') { + writeH2(client, client[kHTTP2Session], request) + return + } + + const { body, method, path, host, upgrade, headers, blocking, reset } = + request + + // https://tools.ietf.org/html/rfc7231#section-4.3.1 + // https://tools.ietf.org/html/rfc7231#section-4.3.2 + // https://tools.ietf.org/html/rfc7231#section-4.3.5 + + // Sending a payload body on a request that does not + // expect it can cause undefined behavior on some + // servers and corrupt connection state. Do not + // re-use the connection for further requests. + + const expectsPayload = + method === 'PUT' || method === 'POST' || method === 'PATCH' + + if (body && typeof body.read === 'function') { + // Try to read EOF in order to get length. + body.read(0) + } + + const bodyLength = util.bodyLength(body) + + let contentLength = bodyLength + + if (contentLength === null) { + contentLength = request.contentLength + } + + if (contentLength === 0 && !expectsPayload) { + // https://tools.ietf.org/html/rfc7230#section-3.3.2 + // A user agent SHOULD NOT send a Content-Length header field when + // the request message does not contain a payload body and the method + // semantics do not anticipate such a body. + + contentLength = null + } + + // https://github.com/nodejs/undici/issues/2046 + // A user agent may send a Content-Length header with 0 value, this should be allowed. + if ( + shouldSendContentLength(method) && + contentLength > 0 && + request.contentLength !== null && + request.contentLength !== contentLength + ) { + if (client[kStrictContentLength]) { + errorRequest( + client, + request, + new RequestContentLengthMismatchError() + ) + return false + } + + process.emitWarning(new RequestContentLengthMismatchError()) + } + + const socket = client[kSocket] + + try { + request.onConnect((err) => { + if (request.aborted || request.completed) { + return + } + + errorRequest(client, request, err || new RequestAbortedError()) + + util.destroy(socket, new InformationalError('aborted')) + }) + } catch (err) { + errorRequest(client, request, err) + } + + if (request.aborted) { + return false + } + + if (method === 'HEAD') { + // https://github.com/mcollina/undici/issues/258 + // Close after a HEAD request to interop with misbehaving servers + // that may send a body in the response. + + socket[kReset] = true + } + + if (upgrade || method === 'CONNECT') { + // On CONNECT or upgrade, block pipeline from dispatching further + // requests on this connection. + + socket[kReset] = true + } + + if (reset != null) { + socket[kReset] = reset + } + + if ( + client[kMaxRequests] && + socket[kCounter]++ >= client[kMaxRequests] + ) { + socket[kReset] = true + } + + if (blocking) { + socket[kBlocking] = true + } + + let header = `${method} ${path} HTTP/1.1\r\n` + + if (typeof host === 'string') { + header += `host: ${host}\r\n` + } else { + header += client[kHostHeader] + } + + if (upgrade) { + header += `connection: upgrade\r\nupgrade: ${upgrade}\r\n` + } else if (client[kPipelining] && !socket[kReset]) { + header += 'connection: keep-alive\r\n' + } else { + header += 'connection: close\r\n' + } + + if (headers) { + header += headers + } + + if (channels.sendHeaders.hasSubscribers) { + channels.sendHeaders.publish({ request, headers: header, socket }) + } + + /* istanbul ignore else: assertion */ + if (!body || bodyLength === 0) { + if (contentLength === 0) { + socket.write(`${header}content-length: 0\r\n\r\n`, 'latin1') + } else { + assert( + contentLength === null, + 'no body must not have content length' + ) + socket.write(`${header}\r\n`, 'latin1') + } + request.onRequestSent() + } else if (util.isBuffer(body)) { + assert( + contentLength === body.byteLength, + 'buffer body must have content length' + ) + + socket.cork() + socket.write( + `${header}content-length: ${contentLength}\r\n\r\n`, + 'latin1' + ) + socket.write(body) + socket.uncork() + request.onBodySent(body) + request.onRequestSent() + if (!expectsPayload) { + socket[kReset] = true + } + } else if (util.isBlobLike(body)) { + if (typeof body.stream === 'function') { + writeIterable({ + body: body.stream(), + client, + request, + socket, + contentLength, + header, + expectsPayload, + }) + } else { + writeBlob({ + body, + client, + request, + socket, + contentLength, + header, + expectsPayload, + }) + } + } else if (util.isStream(body)) { + writeStream({ + body, + client, + request, + socket, + contentLength, + header, + expectsPayload, + }) + } else if (util.isIterable(body)) { + writeIterable({ + body, + client, + request, + socket, + contentLength, + header, + expectsPayload, + }) + } else { + assert(false) + } + + return true + } + + function writeH2(client, session, request) { + const { + body, + method, + path, + host, + upgrade, + expectContinue, + signal, + headers: reqHeaders, + } = request + + let headers + if (typeof reqHeaders === 'string') + headers = Request[kHTTP2CopyHeaders](reqHeaders.trim()) + else headers = reqHeaders + + if (upgrade) { + errorRequest( + client, + request, + new Error('Upgrade not supported for H2') + ) + return false + } + + try { + // TODO(HTTP/2): Should we call onConnect immediately or on stream ready event? + request.onConnect((err) => { + if (request.aborted || request.completed) { + return + } + + errorRequest(client, request, err || new RequestAbortedError()) + }) + } catch (err) { + errorRequest(client, request, err) + } + + if (request.aborted) { + return false + } + + let stream + const h2State = client[kHTTP2SessionState] + + headers[HTTP2_HEADER_AUTHORITY] = host || client[kHost] + headers[HTTP2_HEADER_METHOD] = method + + if (method === 'CONNECT') { + session.ref() + // we are already connected, streams are pending, first request + // will create a new stream. We trigger a request to create the stream and wait until + // `ready` event is triggered + // We disabled endStream to allow the user to write to the stream + stream = session.request(headers, { endStream: false, signal }) + + if (stream.id && !stream.pending) { + request.onUpgrade(null, null, stream) + ++h2State.openStreams + } else { + stream.once('ready', () => { + request.onUpgrade(null, null, stream) + ++h2State.openStreams + }) + } + + stream.once('close', () => { + h2State.openStreams -= 1 + // TODO(HTTP/2): unref only if current streams count is 0 + if (h2State.openStreams === 0) session.unref() + }) + + return true + } + + // https://tools.ietf.org/html/rfc7540#section-8.3 + // :path and :scheme headers must be omited when sending CONNECT + + headers[HTTP2_HEADER_PATH] = path + headers[HTTP2_HEADER_SCHEME] = 'https' + + // https://tools.ietf.org/html/rfc7231#section-4.3.1 + // https://tools.ietf.org/html/rfc7231#section-4.3.2 + // https://tools.ietf.org/html/rfc7231#section-4.3.5 + + // Sending a payload body on a request that does not + // expect it can cause undefined behavior on some + // servers and corrupt connection state. Do not + // re-use the connection for further requests. + + const expectsPayload = + method === 'PUT' || method === 'POST' || method === 'PATCH' + + if (body && typeof body.read === 'function') { + // Try to read EOF in order to get length. + body.read(0) + } + + let contentLength = util.bodyLength(body) + + if (contentLength == null) { + contentLength = request.contentLength + } + + if (contentLength === 0 || !expectsPayload) { + // https://tools.ietf.org/html/rfc7230#section-3.3.2 + // A user agent SHOULD NOT send a Content-Length header field when + // the request message does not contain a payload body and the method + // semantics do not anticipate such a body. + + contentLength = null + } + + // https://github.com/nodejs/undici/issues/2046 + // A user agent may send a Content-Length header with 0 value, this should be allowed. + if ( + shouldSendContentLength(method) && + contentLength > 0 && + request.contentLength != null && + request.contentLength !== contentLength + ) { + if (client[kStrictContentLength]) { + errorRequest( + client, + request, + new RequestContentLengthMismatchError() + ) + return false + } + + process.emitWarning(new RequestContentLengthMismatchError()) + } + + if (contentLength != null) { + assert(body, 'no body must not have content length') + headers[HTTP2_HEADER_CONTENT_LENGTH] = `${contentLength}` + } + + session.ref() + + const shouldEndStream = method === 'GET' || method === 'HEAD' + if (expectContinue) { + headers[HTTP2_HEADER_EXPECT] = '100-continue' + /** + * @type {import('node:http2').ClientHttp2Stream} + */ + stream = session.request(headers, { + endStream: shouldEndStream, + signal, + }) + + stream.once('continue', writeBodyH2) + } else { + /** @type {import('node:http2').ClientHttp2Stream} */ + stream = session.request(headers, { + endStream: shouldEndStream, + signal, + }) + writeBodyH2() + } + + // Increment counter as we have new several streams open + ++h2State.openStreams + + stream.once('response', (headers) => { + if ( + request.onHeaders( + Number(headers[HTTP2_HEADER_STATUS]), + headers, + stream.resume.bind(stream), + '' + ) === false + ) { + stream.pause() + } + }) + + stream.once('end', () => { + request.onComplete([]) + }) + + stream.on('data', (chunk) => { + if (request.onData(chunk) === false) stream.pause() + }) + + stream.once('close', () => { + h2State.openStreams -= 1 + // TODO(HTTP/2): unref only if current streams count is 0 + if (h2State.openStreams === 0) session.unref() + }) + + stream.once('error', function (err) { + if ( + client[kHTTP2Session] && + !client[kHTTP2Session].destroyed && + !this.closed && + !this.destroyed + ) { + h2State.streams -= 1 + util.destroy(stream, err) + } + }) + + stream.once('frameError', (type, code) => { + const err = new InformationalError( + `HTTP/2: "frameError" received - type ${type}, code ${code}` + ) + errorRequest(client, request, err) + + if ( + client[kHTTP2Session] && + !client[kHTTP2Session].destroyed && + !this.closed && + !this.destroyed + ) { + h2State.streams -= 1 + util.destroy(stream, err) + } + }) + + // stream.on('aborted', () => { + // // TODO(HTTP/2): Support aborted + // }) + + // stream.on('timeout', () => { + // // TODO(HTTP/2): Support timeout + // }) + + // stream.on('push', headers => { + // // TODO(HTTP/2): Suppor push + // }) + + // stream.on('trailers', headers => { + // // TODO(HTTP/2): Support trailers + // }) + + return true + + function writeBodyH2() { + /* istanbul ignore else: assertion */ + if (!body) { + request.onRequestSent() + } else if (util.isBuffer(body)) { + assert( + contentLength === body.byteLength, + 'buffer body must have content length' + ) + stream.cork() + stream.write(body) + stream.uncork() + stream.end() + request.onBodySent(body) + request.onRequestSent() + } else if (util.isBlobLike(body)) { + if (typeof body.stream === 'function') { + writeIterable({ + client, + request, + contentLength, + h2stream: stream, + expectsPayload, + body: body.stream(), + socket: client[kSocket], + header: '', + }) + } else { + writeBlob({ + body, + client, + request, + contentLength, + expectsPayload, + h2stream: stream, + header: '', + socket: client[kSocket], + }) + } + } else if (util.isStream(body)) { + writeStream({ + body, + client, + request, + contentLength, + expectsPayload, + socket: client[kSocket], + h2stream: stream, + header: '', + }) + } else if (util.isIterable(body)) { + writeIterable({ + body, + client, + request, + contentLength, + expectsPayload, + header: '', + h2stream: stream, + socket: client[kSocket], + }) + } else { + assert(false) + } + } + } + + function writeStream({ + h2stream, + body, + client, + request, + socket, + contentLength, + header, + expectsPayload, + }) { + assert( + contentLength !== 0 || client[kRunning] === 0, + 'stream body cannot be pipelined' + ) + + if (client[kHTTPConnVersion] === 'h2') { + // For HTTP/2, is enough to pipe the stream + const pipe = pipeline(body, h2stream, (err) => { + if (err) { + util.destroy(body, err) + util.destroy(h2stream, err) + } else { + request.onRequestSent() + } + }) + + pipe.on('data', onPipeData) + pipe.once('end', () => { + pipe.removeListener('data', onPipeData) + util.destroy(pipe) + }) + + function onPipeData(chunk) { + request.onBodySent(chunk) + } + + return + } + + let finished = false + + const writer = new AsyncWriter({ + socket, + request, + contentLength, + client, + expectsPayload, + header, + }) + + const onData = function (chunk) { + if (finished) { + return + } + + try { + if (!writer.write(chunk) && this.pause) { + this.pause() + } + } catch (err) { + util.destroy(this, err) + } + } + const onDrain = function () { + if (finished) { + return + } + + if (body.resume) { + body.resume() + } + } + const onAbort = function () { + onFinished(new RequestAbortedError()) + } + const onFinished = function (err) { + if (finished) { + return + } + + finished = true + + assert( + socket.destroyed || (socket[kWriting] && client[kRunning] <= 1) + ) + + socket.off('drain', onDrain).off('error', onFinished) + + body + .removeListener('data', onData) + .removeListener('end', onFinished) + .removeListener('error', onFinished) + .removeListener('close', onAbort) + + if (!err) { + try { + writer.end() + } catch (er) { + err = er + } + } + + writer.destroy(err) + + if (err && (err.code !== 'UND_ERR_INFO' || err.message !== 'reset')) { + util.destroy(body, err) + } else { + util.destroy(body) + } + } + + body + .on('data', onData) + .on('end', onFinished) + .on('error', onFinished) + .on('close', onAbort) + + if (body.resume) { + body.resume() + } + + socket.on('drain', onDrain).on('error', onFinished) + } + + async function writeBlob({ + h2stream, + body, + client, + request, + socket, + contentLength, + header, + expectsPayload, + }) { + assert( + contentLength === body.size, + 'blob body must have content length' + ) + + const isH2 = client[kHTTPConnVersion] === 'h2' + try { + if (contentLength != null && contentLength !== body.size) { + throw new RequestContentLengthMismatchError() + } + + const buffer = Buffer.from(await body.arrayBuffer()) + + if (isH2) { + h2stream.cork() + h2stream.write(buffer) + h2stream.uncork() + } else { + socket.cork() + socket.write( + `${header}content-length: ${contentLength}\r\n\r\n`, + 'latin1' + ) + socket.write(buffer) + socket.uncork() + } + + request.onBodySent(buffer) + request.onRequestSent() + + if (!expectsPayload) { + socket[kReset] = true + } + + resume(client) + } catch (err) { + util.destroy(isH2 ? h2stream : socket, err) + } + } + + async function writeIterable({ + h2stream, + body, + client, + request, + socket, + contentLength, + header, + expectsPayload, + }) { + assert( + contentLength !== 0 || client[kRunning] === 0, + 'iterator body cannot be pipelined' + ) + + let callback = null + function onDrain() { + if (callback) { + const cb = callback + callback = null + cb() + } + } + + const waitForDrain = () => + new Promise((resolve, reject) => { + assert(callback === null) + + if (socket[kError]) { + reject(socket[kError]) + } else { + callback = resolve + } + }) + + if (client[kHTTPConnVersion] === 'h2') { + h2stream.on('close', onDrain).on('drain', onDrain) + + try { + // It's up to the user to somehow abort the async iterable. + for await (const chunk of body) { + if (socket[kError]) { + throw socket[kError] + } + + const res = h2stream.write(chunk) + request.onBodySent(chunk) + if (!res) { + await waitForDrain() + } + } + } catch (err) { + h2stream.destroy(err) + } finally { + request.onRequestSent() + h2stream.end() + h2stream.off('close', onDrain).off('drain', onDrain) + } + + return + } + + socket.on('close', onDrain).on('drain', onDrain) + + const writer = new AsyncWriter({ + socket, + request, + contentLength, + client, + expectsPayload, + header, + }) + try { + // It's up to the user to somehow abort the async iterable. + for await (const chunk of body) { + if (socket[kError]) { + throw socket[kError] + } + + if (!writer.write(chunk)) { + await waitForDrain() + } + } + + writer.end() + } catch (err) { + writer.destroy(err) + } finally { + socket.off('close', onDrain).off('drain', onDrain) + } + } + + class AsyncWriter { + constructor({ + socket, + request, + contentLength, + client, + expectsPayload, + header, + }) { + this.socket = socket + this.request = request + this.contentLength = contentLength + this.client = client + this.bytesWritten = 0 + this.expectsPayload = expectsPayload + this.header = header + + socket[kWriting] = true + } + + write(chunk) { + const { + socket, + request, + contentLength, + client, + bytesWritten, + expectsPayload, + header, + } = this + + if (socket[kError]) { + throw socket[kError] + } + + if (socket.destroyed) { + return false + } + + const len = Buffer.byteLength(chunk) + if (!len) { + return true + } + + // We should defer writing chunks. + if (contentLength !== null && bytesWritten + len > contentLength) { + if (client[kStrictContentLength]) { + throw new RequestContentLengthMismatchError() + } + + process.emitWarning(new RequestContentLengthMismatchError()) + } + + socket.cork() + + if (bytesWritten === 0) { + if (!expectsPayload) { + socket[kReset] = true + } + + if (contentLength === null) { + socket.write(`${header}transfer-encoding: chunked\r\n`, 'latin1') + } else { + socket.write( + `${header}content-length: ${contentLength}\r\n\r\n`, + 'latin1' + ) + } + } + + if (contentLength === null) { + socket.write(`\r\n${len.toString(16)}\r\n`, 'latin1') + } + + this.bytesWritten += len + + const ret = socket.write(chunk) + + socket.uncork() + + request.onBodySent(chunk) + + if (!ret) { + if ( + socket[kParser].timeout && + socket[kParser].timeoutType === TIMEOUT_HEADERS + ) { + // istanbul ignore else: only for jest + if (socket[kParser].timeout.refresh) { + socket[kParser].timeout.refresh() + } + } + } + + return ret + } + + end() { + const { + socket, + contentLength, + client, + bytesWritten, + expectsPayload, + header, + request, + } = this + request.onRequestSent() + + socket[kWriting] = false + + if (socket[kError]) { + throw socket[kError] + } + + if (socket.destroyed) { + return + } + + if (bytesWritten === 0) { + if (expectsPayload) { + // https://tools.ietf.org/html/rfc7230#section-3.3.2 + // A user agent SHOULD send a Content-Length in a request message when + // no Transfer-Encoding is sent and the request method defines a meaning + // for an enclosed payload body. + + socket.write(`${header}content-length: 0\r\n\r\n`, 'latin1') + } else { + socket.write(`${header}\r\n`, 'latin1') + } + } else if (contentLength === null) { + socket.write('\r\n0\r\n\r\n', 'latin1') + } + + if (contentLength !== null && bytesWritten !== contentLength) { + if (client[kStrictContentLength]) { + throw new RequestContentLengthMismatchError() + } else { + process.emitWarning(new RequestContentLengthMismatchError()) + } + } + + if ( + socket[kParser].timeout && + socket[kParser].timeoutType === TIMEOUT_HEADERS + ) { + // istanbul ignore else: only for jest + if (socket[kParser].timeout.refresh) { + socket[kParser].timeout.refresh() + } + } + + resume(client) + } + + destroy(err) { + const { socket, client } = this + + socket[kWriting] = false + + if (err) { + assert( + client[kRunning] <= 1, + 'pipeline should only contain this request' + ) + util.destroy(socket, err) + } + } + } + + function errorRequest(client, request, err) { + try { + request.onError(err) + assert(request.aborted) + } catch (err) { + client.emit('error', err) + } + } + + module.exports = Client + + /***/ + }, + + /***/ 6436: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + /* istanbul ignore file: only for Node 12 */ + + const { kConnected, kSize } = __nccwpck_require__(2785) + + class CompatWeakRef { + constructor(value) { + this.value = value + } + + deref() { + return this.value[kConnected] === 0 && this.value[kSize] === 0 + ? undefined + : this.value + } + } + + class CompatFinalizer { + constructor(finalizer) { + this.finalizer = finalizer + } + + register(dispatcher, key) { + if (dispatcher.on) { + dispatcher.on('disconnect', () => { + if (dispatcher[kConnected] === 0 && dispatcher[kSize] === 0) { + this.finalizer(key) + } + }) + } + } + } + + module.exports = function () { + // FIXME: remove workaround when the Node bug is fixed + // https://github.com/nodejs/node/issues/49344#issuecomment-1741776308 + if (process.env.NODE_V8_COVERAGE) { + return { + WeakRef: CompatWeakRef, + FinalizationRegistry: CompatFinalizer, + } + } + return { + WeakRef: global.WeakRef || CompatWeakRef, + FinalizationRegistry: global.FinalizationRegistry || CompatFinalizer, + } + } + + /***/ + }, + + /***/ 663: /***/ (module) => { + 'use strict' + + // https://wicg.github.io/cookie-store/#cookie-maximum-attribute-value-size + const maxAttributeValueSize = 1024 + + // https://wicg.github.io/cookie-store/#cookie-maximum-name-value-pair-size + const maxNameValuePairSize = 4096 + + module.exports = { + maxAttributeValueSize, + maxNameValuePairSize, + } + + /***/ + }, + + /***/ 1724: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const { parseSetCookie } = __nccwpck_require__(4408) + const { stringify, getHeadersList } = __nccwpck_require__(3121) + const { webidl } = __nccwpck_require__(1744) + const { Headers } = __nccwpck_require__(554) + + /** + * @typedef {Object} Cookie + * @property {string} name + * @property {string} value + * @property {Date|number|undefined} expires + * @property {number|undefined} maxAge + * @property {string|undefined} domain + * @property {string|undefined} path + * @property {boolean|undefined} secure + * @property {boolean|undefined} httpOnly + * @property {'Strict'|'Lax'|'None'} sameSite + * @property {string[]} unparsed + */ + + /** + * @param {Headers} headers + * @returns {Record} + */ + function getCookies(headers) { + webidl.argumentLengthCheck(arguments, 1, { header: 'getCookies' }) + + webidl.brandCheck(headers, Headers, { strict: false }) + + const cookie = headers.get('cookie') + const out = {} + + if (!cookie) { + return out + } + + for (const piece of cookie.split(';')) { + const [name, ...value] = piece.split('=') + + out[name.trim()] = value.join('=') + } + + return out + } + + /** + * @param {Headers} headers + * @param {string} name + * @param {{ path?: string, domain?: string }|undefined} attributes + * @returns {void} + */ + function deleteCookie(headers, name, attributes) { + webidl.argumentLengthCheck(arguments, 2, { header: 'deleteCookie' }) + + webidl.brandCheck(headers, Headers, { strict: false }) + + name = webidl.converters.DOMString(name) + attributes = webidl.converters.DeleteCookieAttributes(attributes) + + // Matches behavior of + // https://github.com/denoland/deno_std/blob/63827b16330b82489a04614027c33b7904e08be5/http/cookie.ts#L278 + setCookie(headers, { + name, + value: '', + expires: new Date(0), + ...attributes, + }) + } + + /** + * @param {Headers} headers + * @returns {Cookie[]} + */ + function getSetCookies(headers) { + webidl.argumentLengthCheck(arguments, 1, { header: 'getSetCookies' }) + + webidl.brandCheck(headers, Headers, { strict: false }) + + const cookies = getHeadersList(headers).cookies + + if (!cookies) { + return [] + } + + // In older versions of undici, cookies is a list of name:value. + return cookies.map((pair) => + parseSetCookie(Array.isArray(pair) ? pair[1] : pair) + ) + } + + /** + * @param {Headers} headers + * @param {Cookie} cookie + * @returns {void} + */ + function setCookie(headers, cookie) { + webidl.argumentLengthCheck(arguments, 2, { header: 'setCookie' }) + + webidl.brandCheck(headers, Headers, { strict: false }) + + cookie = webidl.converters.Cookie(cookie) + + const str = stringify(cookie) + + if (str) { + headers.append('Set-Cookie', stringify(cookie)) + } + } + + webidl.converters.DeleteCookieAttributes = webidl.dictionaryConverter([ + { + converter: webidl.nullableConverter(webidl.converters.DOMString), + key: 'path', + defaultValue: null, + }, + { + converter: webidl.nullableConverter(webidl.converters.DOMString), + key: 'domain', + defaultValue: null, + }, + ]) + + webidl.converters.Cookie = webidl.dictionaryConverter([ + { + converter: webidl.converters.DOMString, + key: 'name', + }, + { + converter: webidl.converters.DOMString, + key: 'value', + }, + { + converter: webidl.nullableConverter((value) => { + if (typeof value === 'number') { + return webidl.converters['unsigned long long'](value) + } + + return new Date(value) + }), + key: 'expires', + defaultValue: null, + }, + { + converter: webidl.nullableConverter(webidl.converters['long long']), + key: 'maxAge', + defaultValue: null, + }, + { + converter: webidl.nullableConverter(webidl.converters.DOMString), + key: 'domain', + defaultValue: null, + }, + { + converter: webidl.nullableConverter(webidl.converters.DOMString), + key: 'path', + defaultValue: null, + }, + { + converter: webidl.nullableConverter(webidl.converters.boolean), + key: 'secure', + defaultValue: null, + }, + { + converter: webidl.nullableConverter(webidl.converters.boolean), + key: 'httpOnly', + defaultValue: null, + }, + { + converter: webidl.converters.USVString, + key: 'sameSite', + allowedValues: ['Strict', 'Lax', 'None'], + }, + { + converter: webidl.sequenceConverter(webidl.converters.DOMString), + key: 'unparsed', + defaultValue: [], + }, + ]) + + module.exports = { + getCookies, + deleteCookie, + getSetCookies, + setCookie, + } + + /***/ + }, + + /***/ 4408: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const { maxNameValuePairSize, maxAttributeValueSize } = + __nccwpck_require__(663) + const { isCTLExcludingHtab } = __nccwpck_require__(3121) + const { collectASequenceOfCodePointsFast } = __nccwpck_require__(685) + const assert = __nccwpck_require__(9491) + + /** + * @description Parses the field-value attributes of a set-cookie header string. + * @see https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4 + * @param {string} header + * @returns if the header is invalid, null will be returned + */ + function parseSetCookie(header) { + // 1. If the set-cookie-string contains a %x00-08 / %x0A-1F / %x7F + // character (CTL characters excluding HTAB): Abort these steps and + // ignore the set-cookie-string entirely. + if (isCTLExcludingHtab(header)) { + return null + } + + let nameValuePair = '' + let unparsedAttributes = '' + let name = '' + let value = '' + + // 2. If the set-cookie-string contains a %x3B (";") character: + if (header.includes(';')) { + // 1. The name-value-pair string consists of the characters up to, + // but not including, the first %x3B (";"), and the unparsed- + // attributes consist of the remainder of the set-cookie-string + // (including the %x3B (";") in question). + const position = { position: 0 } + + nameValuePair = collectASequenceOfCodePointsFast( + ';', + header, + position + ) + unparsedAttributes = header.slice(position.position) + } else { + // Otherwise: + + // 1. The name-value-pair string consists of all the characters + // contained in the set-cookie-string, and the unparsed- + // attributes is the empty string. + nameValuePair = header + } + + // 3. If the name-value-pair string lacks a %x3D ("=") character, then + // the name string is empty, and the value string is the value of + // name-value-pair. + if (!nameValuePair.includes('=')) { + value = nameValuePair + } else { + // Otherwise, the name string consists of the characters up to, but + // not including, the first %x3D ("=") character, and the (possibly + // empty) value string consists of the characters after the first + // %x3D ("=") character. + const position = { position: 0 } + name = collectASequenceOfCodePointsFast('=', nameValuePair, position) + value = nameValuePair.slice(position.position + 1) + } + + // 4. Remove any leading or trailing WSP characters from the name + // string and the value string. + name = name.trim() + value = value.trim() + + // 5. If the sum of the lengths of the name string and the value string + // is more than 4096 octets, abort these steps and ignore the set- + // cookie-string entirely. + if (name.length + value.length > maxNameValuePairSize) { + return null + } + + // 6. The cookie-name is the name string, and the cookie-value is the + // value string. + return { + name, + value, + ...parseUnparsedAttributes(unparsedAttributes), + } + } + + /** + * Parses the remaining attributes of a set-cookie header + * @see https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4 + * @param {string} unparsedAttributes + * @param {[Object.]={}} cookieAttributeList + */ + function parseUnparsedAttributes( + unparsedAttributes, + cookieAttributeList = {} + ) { + // 1. If the unparsed-attributes string is empty, skip the rest of + // these steps. + if (unparsedAttributes.length === 0) { + return cookieAttributeList + } + + // 2. Discard the first character of the unparsed-attributes (which + // will be a %x3B (";") character). + assert(unparsedAttributes[0] === ';') + unparsedAttributes = unparsedAttributes.slice(1) + + let cookieAv = '' + + // 3. If the remaining unparsed-attributes contains a %x3B (";") + // character: + if (unparsedAttributes.includes(';')) { + // 1. Consume the characters of the unparsed-attributes up to, but + // not including, the first %x3B (";") character. + cookieAv = collectASequenceOfCodePointsFast(';', unparsedAttributes, { + position: 0, + }) + unparsedAttributes = unparsedAttributes.slice(cookieAv.length) + } else { + // Otherwise: + + // 1. Consume the remainder of the unparsed-attributes. + cookieAv = unparsedAttributes + unparsedAttributes = '' + } + + // Let the cookie-av string be the characters consumed in this step. + + let attributeName = '' + let attributeValue = '' + + // 4. If the cookie-av string contains a %x3D ("=") character: + if (cookieAv.includes('=')) { + // 1. The (possibly empty) attribute-name string consists of the + // characters up to, but not including, the first %x3D ("=") + // character, and the (possibly empty) attribute-value string + // consists of the characters after the first %x3D ("=") + // character. + const position = { position: 0 } + + attributeName = collectASequenceOfCodePointsFast( + '=', + cookieAv, + position + ) + attributeValue = cookieAv.slice(position.position + 1) + } else { + // Otherwise: + + // 1. The attribute-name string consists of the entire cookie-av + // string, and the attribute-value string is empty. + attributeName = cookieAv + } + + // 5. Remove any leading or trailing WSP characters from the attribute- + // name string and the attribute-value string. + attributeName = attributeName.trim() + attributeValue = attributeValue.trim() + + // 6. If the attribute-value is longer than 1024 octets, ignore the + // cookie-av string and return to Step 1 of this algorithm. + if (attributeValue.length > maxAttributeValueSize) { + return parseUnparsedAttributes( + unparsedAttributes, + cookieAttributeList + ) + } + + // 7. Process the attribute-name and attribute-value according to the + // requirements in the following subsections. (Notice that + // attributes with unrecognized attribute-names are ignored.) + const attributeNameLowercase = attributeName.toLowerCase() + + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.1 + // If the attribute-name case-insensitively matches the string + // "Expires", the user agent MUST process the cookie-av as follows. + if (attributeNameLowercase === 'expires') { + // 1. Let the expiry-time be the result of parsing the attribute-value + // as cookie-date (see Section 5.1.1). + const expiryTime = new Date(attributeValue) + + // 2. If the attribute-value failed to parse as a cookie date, ignore + // the cookie-av. + + cookieAttributeList.expires = expiryTime + } else if (attributeNameLowercase === 'max-age') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.2 + // If the attribute-name case-insensitively matches the string "Max- + // Age", the user agent MUST process the cookie-av as follows. + + // 1. If the first character of the attribute-value is not a DIGIT or a + // "-" character, ignore the cookie-av. + const charCode = attributeValue.charCodeAt(0) + + if ((charCode < 48 || charCode > 57) && attributeValue[0] !== '-') { + return parseUnparsedAttributes( + unparsedAttributes, + cookieAttributeList + ) + } + + // 2. If the remainder of attribute-value contains a non-DIGIT + // character, ignore the cookie-av. + if (!/^\d+$/.test(attributeValue)) { + return parseUnparsedAttributes( + unparsedAttributes, + cookieAttributeList + ) + } + + // 3. Let delta-seconds be the attribute-value converted to an integer. + const deltaSeconds = Number(attributeValue) + + // 4. Let cookie-age-limit be the maximum age of the cookie (which + // SHOULD be 400 days or less, see Section 4.1.2.2). + + // 5. Set delta-seconds to the smaller of its present value and cookie- + // age-limit. + // deltaSeconds = Math.min(deltaSeconds * 1000, maxExpiresMs) + + // 6. If delta-seconds is less than or equal to zero (0), let expiry- + // time be the earliest representable date and time. Otherwise, let + // the expiry-time be the current date and time plus delta-seconds + // seconds. + // const expiryTime = deltaSeconds <= 0 ? Date.now() : Date.now() + deltaSeconds + + // 7. Append an attribute to the cookie-attribute-list with an + // attribute-name of Max-Age and an attribute-value of expiry-time. + cookieAttributeList.maxAge = deltaSeconds + } else if (attributeNameLowercase === 'domain') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.3 + // If the attribute-name case-insensitively matches the string "Domain", + // the user agent MUST process the cookie-av as follows. + + // 1. Let cookie-domain be the attribute-value. + let cookieDomain = attributeValue + + // 2. If cookie-domain starts with %x2E ("."), let cookie-domain be + // cookie-domain without its leading %x2E ("."). + if (cookieDomain[0] === '.') { + cookieDomain = cookieDomain.slice(1) + } + + // 3. Convert the cookie-domain to lower case. + cookieDomain = cookieDomain.toLowerCase() + + // 4. Append an attribute to the cookie-attribute-list with an + // attribute-name of Domain and an attribute-value of cookie-domain. + cookieAttributeList.domain = cookieDomain + } else if (attributeNameLowercase === 'path') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.4 + // If the attribute-name case-insensitively matches the string "Path", + // the user agent MUST process the cookie-av as follows. + + // 1. If the attribute-value is empty or if the first character of the + // attribute-value is not %x2F ("/"): + let cookiePath = '' + if (attributeValue.length === 0 || attributeValue[0] !== '/') { + // 1. Let cookie-path be the default-path. + cookiePath = '/' + } else { + // Otherwise: + + // 1. Let cookie-path be the attribute-value. + cookiePath = attributeValue + } + + // 2. Append an attribute to the cookie-attribute-list with an + // attribute-name of Path and an attribute-value of cookie-path. + cookieAttributeList.path = cookiePath + } else if (attributeNameLowercase === 'secure') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.5 + // If the attribute-name case-insensitively matches the string "Secure", + // the user agent MUST append an attribute to the cookie-attribute-list + // with an attribute-name of Secure and an empty attribute-value. + + cookieAttributeList.secure = true + } else if (attributeNameLowercase === 'httponly') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.6 + // If the attribute-name case-insensitively matches the string + // "HttpOnly", the user agent MUST append an attribute to the cookie- + // attribute-list with an attribute-name of HttpOnly and an empty + // attribute-value. + + cookieAttributeList.httpOnly = true + } else if (attributeNameLowercase === 'samesite') { + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-rfc6265bis#section-5.4.7 + // If the attribute-name case-insensitively matches the string + // "SameSite", the user agent MUST process the cookie-av as follows: + + // 1. Let enforcement be "Default". + let enforcement = 'Default' + + const attributeValueLowercase = attributeValue.toLowerCase() + // 2. If cookie-av's attribute-value is a case-insensitive match for + // "None", set enforcement to "None". + if (attributeValueLowercase.includes('none')) { + enforcement = 'None' + } + + // 3. If cookie-av's attribute-value is a case-insensitive match for + // "Strict", set enforcement to "Strict". + if (attributeValueLowercase.includes('strict')) { + enforcement = 'Strict' + } + + // 4. If cookie-av's attribute-value is a case-insensitive match for + // "Lax", set enforcement to "Lax". + if (attributeValueLowercase.includes('lax')) { + enforcement = 'Lax' + } + + // 5. Append an attribute to the cookie-attribute-list with an + // attribute-name of "SameSite" and an attribute-value of + // enforcement. + cookieAttributeList.sameSite = enforcement + } else { + cookieAttributeList.unparsed ??= [] + + cookieAttributeList.unparsed.push( + `${attributeName}=${attributeValue}` + ) + } + + // 8. Return to Step 1 of this algorithm. + return parseUnparsedAttributes(unparsedAttributes, cookieAttributeList) + } + + module.exports = { + parseSetCookie, + parseUnparsedAttributes, + } + + /***/ + }, + + /***/ 3121: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const assert = __nccwpck_require__(9491) + const { kHeadersList } = __nccwpck_require__(2785) + + function isCTLExcludingHtab(value) { + if (value.length === 0) { + return false + } + + for (const char of value) { + const code = char.charCodeAt(0) + + if ( + code >= 0x00 || + code <= 0x08 || + code >= 0x0a || + code <= 0x1f || + code === 0x7f + ) { + return false + } + } + } + + /** + CHAR = + token = 1* + separators = "(" | ")" | "<" | ">" | "@" + | "," | ";" | ":" | "\" | <"> + | "/" | "[" | "]" | "?" | "=" + | "{" | "}" | SP | HT + * @param {string} name + */ + function validateCookieName(name) { + for (const char of name) { + const code = char.charCodeAt(0) + + if ( + code <= 0x20 || + code > 0x7f || + char === '(' || + char === ')' || + char === '>' || + char === '<' || + char === '@' || + char === ',' || + char === ';' || + char === ':' || + char === '\\' || + char === '"' || + char === '/' || + char === '[' || + char === ']' || + char === '?' || + char === '=' || + char === '{' || + char === '}' + ) { + throw new Error('Invalid cookie name') + } + } + } + + /** + cookie-value = *cookie-octet / ( DQUOTE *cookie-octet DQUOTE ) + cookie-octet = %x21 / %x23-2B / %x2D-3A / %x3C-5B / %x5D-7E + ; US-ASCII characters excluding CTLs, + ; whitespace DQUOTE, comma, semicolon, + ; and backslash + * @param {string} value + */ + function validateCookieValue(value) { + for (const char of value) { + const code = char.charCodeAt(0) + + if ( + code < 0x21 || // exclude CTLs (0-31) + code === 0x22 || + code === 0x2c || + code === 0x3b || + code === 0x5c || + code > 0x7e // non-ascii + ) { + throw new Error('Invalid header value') + } + } + } + + /** + * path-value = + * @param {string} path + */ + function validateCookiePath(path) { + for (const char of path) { + const code = char.charCodeAt(0) + + if (code < 0x21 || char === ';') { + throw new Error('Invalid cookie path') + } + } + } + + /** + * I have no idea why these values aren't allowed to be honest, + * but Deno tests these. - Khafra + * @param {string} domain + */ + function validateCookieDomain(domain) { + if ( + domain.startsWith('-') || + domain.endsWith('.') || + domain.endsWith('-') + ) { + throw new Error('Invalid cookie domain') + } + } + + /** + * @see https://www.rfc-editor.org/rfc/rfc7231#section-7.1.1.1 + * @param {number|Date} date + IMF-fixdate = day-name "," SP date1 SP time-of-day SP GMT + ; fixed length/zone/capitalization subset of the format + ; see Section 3.3 of [RFC5322] + + day-name = %x4D.6F.6E ; "Mon", case-sensitive + / %x54.75.65 ; "Tue", case-sensitive + / %x57.65.64 ; "Wed", case-sensitive + / %x54.68.75 ; "Thu", case-sensitive + / %x46.72.69 ; "Fri", case-sensitive + / %x53.61.74 ; "Sat", case-sensitive + / %x53.75.6E ; "Sun", case-sensitive + date1 = day SP month SP year + ; e.g., 02 Jun 1982 + + day = 2DIGIT + month = %x4A.61.6E ; "Jan", case-sensitive + / %x46.65.62 ; "Feb", case-sensitive + / %x4D.61.72 ; "Mar", case-sensitive + / %x41.70.72 ; "Apr", case-sensitive + / %x4D.61.79 ; "May", case-sensitive + / %x4A.75.6E ; "Jun", case-sensitive + / %x4A.75.6C ; "Jul", case-sensitive + / %x41.75.67 ; "Aug", case-sensitive + / %x53.65.70 ; "Sep", case-sensitive + / %x4F.63.74 ; "Oct", case-sensitive + / %x4E.6F.76 ; "Nov", case-sensitive + / %x44.65.63 ; "Dec", case-sensitive + year = 4DIGIT + + GMT = %x47.4D.54 ; "GMT", case-sensitive + + time-of-day = hour ":" minute ":" second + ; 00:00:00 - 23:59:60 (leap second) + + hour = 2DIGIT + minute = 2DIGIT + second = 2DIGIT + */ + function toIMFDate(date) { + if (typeof date === 'number') { + date = new Date(date) + } + + const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'] + + const months = [ + 'Jan', + 'Feb', + 'Mar', + 'Apr', + 'May', + 'Jun', + 'Jul', + 'Aug', + 'Sep', + 'Oct', + 'Nov', + 'Dec', + ] + + const dayName = days[date.getUTCDay()] + const day = date.getUTCDate().toString().padStart(2, '0') + const month = months[date.getUTCMonth()] + const year = date.getUTCFullYear() + const hour = date.getUTCHours().toString().padStart(2, '0') + const minute = date.getUTCMinutes().toString().padStart(2, '0') + const second = date.getUTCSeconds().toString().padStart(2, '0') + + return `${dayName}, ${day} ${month} ${year} ${hour}:${minute}:${second} GMT` + } + + /** + max-age-av = "Max-Age=" non-zero-digit *DIGIT + ; In practice, both expires-av and max-age-av + ; are limited to dates representable by the + ; user agent. + * @param {number} maxAge + */ + function validateCookieMaxAge(maxAge) { + if (maxAge < 0) { + throw new Error('Invalid cookie max-age') + } + } + + /** + * @see https://www.rfc-editor.org/rfc/rfc6265#section-4.1.1 + * @param {import('./index').Cookie} cookie + */ + function stringify(cookie) { + if (cookie.name.length === 0) { + return null + } + + validateCookieName(cookie.name) + validateCookieValue(cookie.value) + + const out = [`${cookie.name}=${cookie.value}`] + + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-cookie-prefixes-00#section-3.1 + // https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-cookie-prefixes-00#section-3.2 + if (cookie.name.startsWith('__Secure-')) { + cookie.secure = true + } + + if (cookie.name.startsWith('__Host-')) { + cookie.secure = true + cookie.domain = null + cookie.path = '/' + } + + if (cookie.secure) { + out.push('Secure') + } + + if (cookie.httpOnly) { + out.push('HttpOnly') + } + + if (typeof cookie.maxAge === 'number') { + validateCookieMaxAge(cookie.maxAge) + out.push(`Max-Age=${cookie.maxAge}`) + } + + if (cookie.domain) { + validateCookieDomain(cookie.domain) + out.push(`Domain=${cookie.domain}`) + } + + if (cookie.path) { + validateCookiePath(cookie.path) + out.push(`Path=${cookie.path}`) + } + + if (cookie.expires && cookie.expires.toString() !== 'Invalid Date') { + out.push(`Expires=${toIMFDate(cookie.expires)}`) + } + + if (cookie.sameSite) { + out.push(`SameSite=${cookie.sameSite}`) + } + + for (const part of cookie.unparsed) { + if (!part.includes('=')) { + throw new Error('Invalid unparsed') + } + + const [key, ...value] = part.split('=') + + out.push(`${key.trim()}=${value.join('=')}`) + } + + return out.join('; ') + } + + let kHeadersListNode + + function getHeadersList(headers) { + if (headers[kHeadersList]) { + return headers[kHeadersList] + } + + if (!kHeadersListNode) { + kHeadersListNode = Object.getOwnPropertySymbols(headers).find( + (symbol) => symbol.description === 'headers list' + ) + + assert(kHeadersListNode, 'Headers cannot be parsed') + } + + const headersList = headers[kHeadersListNode] + assert(headersList) + + return headersList + } + + module.exports = { + isCTLExcludingHtab, + stringify, + getHeadersList, + } + + /***/ + }, + + /***/ 2067: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const net = __nccwpck_require__(1808) + const assert = __nccwpck_require__(9491) + const util = __nccwpck_require__(3983) + const { InvalidArgumentError, ConnectTimeoutError } = + __nccwpck_require__(8045) + + let tls // include tls conditionally since it is not always available + + // TODO: session re-use does not wait for the first + // connection to resolve the session and might therefore + // resolve the same servername multiple times even when + // re-use is enabled. + + let SessionCache + // FIXME: remove workaround when the Node bug is fixed + // https://github.com/nodejs/node/issues/49344#issuecomment-1741776308 + if (global.FinalizationRegistry && !process.env.NODE_V8_COVERAGE) { + SessionCache = class WeakSessionCache { + constructor(maxCachedSessions) { + this._maxCachedSessions = maxCachedSessions + this._sessionCache = new Map() + this._sessionRegistry = new global.FinalizationRegistry((key) => { + if (this._sessionCache.size < this._maxCachedSessions) { + return + } + + const ref = this._sessionCache.get(key) + if (ref !== undefined && ref.deref() === undefined) { + this._sessionCache.delete(key) + } + }) + } + + get(sessionKey) { + const ref = this._sessionCache.get(sessionKey) + return ref ? ref.deref() : null + } + + set(sessionKey, session) { + if (this._maxCachedSessions === 0) { + return + } + + this._sessionCache.set(sessionKey, new WeakRef(session)) + this._sessionRegistry.register(session, sessionKey) + } + } + } else { + SessionCache = class SimpleSessionCache { + constructor(maxCachedSessions) { + this._maxCachedSessions = maxCachedSessions + this._sessionCache = new Map() + } + + get(sessionKey) { + return this._sessionCache.get(sessionKey) + } + + set(sessionKey, session) { + if (this._maxCachedSessions === 0) { + return + } + + if (this._sessionCache.size >= this._maxCachedSessions) { + // remove the oldest session + const { value: oldestKey } = this._sessionCache.keys().next() + this._sessionCache.delete(oldestKey) + } + + this._sessionCache.set(sessionKey, session) + } + } + } + + function buildConnector({ + allowH2, + maxCachedSessions, + socketPath, + timeout, + ...opts + }) { + if ( + maxCachedSessions != null && + (!Number.isInteger(maxCachedSessions) || maxCachedSessions < 0) + ) { + throw new InvalidArgumentError( + 'maxCachedSessions must be a positive integer or zero' + ) + } + + const options = { path: socketPath, ...opts } + const sessionCache = new SessionCache( + maxCachedSessions == null ? 100 : maxCachedSessions + ) + timeout = timeout == null ? 10e3 : timeout + allowH2 = allowH2 != null ? allowH2 : false + return function connect( + { + hostname, + host, + protocol, + port, + servername, + localAddress, + httpSocket, + }, + callback + ) { + let socket + if (protocol === 'https:') { + if (!tls) { + tls = __nccwpck_require__(4404) + } + servername = + servername || + options.servername || + util.getServerName(host) || + null + + const sessionKey = servername || hostname + const session = sessionCache.get(sessionKey) || null + + assert(sessionKey) + + socket = tls.connect({ + highWaterMark: 16384, // TLS in node can't have bigger HWM anyway... + ...options, + servername, + session, + localAddress, + // TODO(HTTP/2): Add support for h2c + ALPNProtocols: allowH2 ? ['http/1.1', 'h2'] : ['http/1.1'], + socket: httpSocket, // upgrade socket connection + port: port || 443, + host: hostname, + }) + + socket.on('session', function (session) { + // TODO (fix): Can a session become invalid once established? Don't think so? + sessionCache.set(sessionKey, session) + }) + } else { + assert(!httpSocket, 'httpSocket can only be sent on TLS update') + socket = net.connect({ + highWaterMark: 64 * 1024, // Same as nodejs fs streams. + ...options, + localAddress, + port: port || 80, + host: hostname, + }) + } + + // Set TCP keep alive options on the socket here instead of in connect() for the case of assigning the socket + if (options.keepAlive == null || options.keepAlive) { + const keepAliveInitialDelay = + options.keepAliveInitialDelay === undefined + ? 60e3 + : options.keepAliveInitialDelay + socket.setKeepAlive(true, keepAliveInitialDelay) + } + + const cancelTimeout = setupTimeout( + () => onConnectTimeout(socket), + timeout + ) + + socket + .setNoDelay(true) + .once( + protocol === 'https:' ? 'secureConnect' : 'connect', + function () { + cancelTimeout() + + if (callback) { + const cb = callback + callback = null + cb(null, this) + } + } + ) + .on('error', function (err) { + cancelTimeout() + + if (callback) { + const cb = callback + callback = null + cb(err) + } + }) + + return socket + } + } + + function setupTimeout(onConnectTimeout, timeout) { + if (!timeout) { + return () => {} + } + + let s1 = null + let s2 = null + const timeoutId = setTimeout(() => { + // setImmediate is added to make sure that we priotorise socket error events over timeouts + s1 = setImmediate(() => { + if (process.platform === 'win32') { + // Windows needs an extra setImmediate probably due to implementation differences in the socket logic + s2 = setImmediate(() => onConnectTimeout()) + } else { + onConnectTimeout() + } + }) + }, timeout) + return () => { + clearTimeout(timeoutId) + clearImmediate(s1) + clearImmediate(s2) + } + } + + function onConnectTimeout(socket) { + util.destroy(socket, new ConnectTimeoutError()) + } + + module.exports = buildConnector + + /***/ + }, + + /***/ 8045: /***/ (module) => { + 'use strict' + + class UndiciError extends Error { + constructor(message) { + super(message) + this.name = 'UndiciError' + this.code = 'UND_ERR' + } + } + + class ConnectTimeoutError extends UndiciError { + constructor(message) { + super(message) + Error.captureStackTrace(this, ConnectTimeoutError) + this.name = 'ConnectTimeoutError' + this.message = message || 'Connect Timeout Error' + this.code = 'UND_ERR_CONNECT_TIMEOUT' + } + } + + class HeadersTimeoutError extends UndiciError { + constructor(message) { + super(message) + Error.captureStackTrace(this, HeadersTimeoutError) + this.name = 'HeadersTimeoutError' + this.message = message || 'Headers Timeout Error' + this.code = 'UND_ERR_HEADERS_TIMEOUT' + } + } + + class HeadersOverflowError extends UndiciError { + constructor(message) { + super(message) + Error.captureStackTrace(this, HeadersOverflowError) + this.name = 'HeadersOverflowError' + this.message = message || 'Headers Overflow Error' + this.code = 'UND_ERR_HEADERS_OVERFLOW' + } + } + + class BodyTimeoutError extends UndiciError { + constructor(message) { + super(message) + Error.captureStackTrace(this, BodyTimeoutError) + this.name = 'BodyTimeoutError' + this.message = message || 'Body Timeout Error' + this.code = 'UND_ERR_BODY_TIMEOUT' + } + } + + class ResponseStatusCodeError extends UndiciError { + constructor(message, statusCode, headers, body) { + super(message) + Error.captureStackTrace(this, ResponseStatusCodeError) + this.name = 'ResponseStatusCodeError' + this.message = message || 'Response Status Code Error' + this.code = 'UND_ERR_RESPONSE_STATUS_CODE' + this.body = body + this.status = statusCode + this.statusCode = statusCode + this.headers = headers + } + } + + class InvalidArgumentError extends UndiciError { + constructor(message) { + super(message) + Error.captureStackTrace(this, InvalidArgumentError) + this.name = 'InvalidArgumentError' + this.message = message || 'Invalid Argument Error' + this.code = 'UND_ERR_INVALID_ARG' + } + } + + class InvalidReturnValueError extends UndiciError { + constructor(message) { + super(message) + Error.captureStackTrace(this, InvalidReturnValueError) + this.name = 'InvalidReturnValueError' + this.message = message || 'Invalid Return Value Error' + this.code = 'UND_ERR_INVALID_RETURN_VALUE' + } + } + + class RequestAbortedError extends UndiciError { + constructor(message) { + super(message) + Error.captureStackTrace(this, RequestAbortedError) + this.name = 'AbortError' + this.message = message || 'Request aborted' + this.code = 'UND_ERR_ABORTED' + } + } + + class InformationalError extends UndiciError { + constructor(message) { + super(message) + Error.captureStackTrace(this, InformationalError) + this.name = 'InformationalError' + this.message = message || 'Request information' + this.code = 'UND_ERR_INFO' + } + } + + class RequestContentLengthMismatchError extends UndiciError { + constructor(message) { + super(message) + Error.captureStackTrace(this, RequestContentLengthMismatchError) + this.name = 'RequestContentLengthMismatchError' + this.message = + message || + 'Request body length does not match content-length header' + this.code = 'UND_ERR_REQ_CONTENT_LENGTH_MISMATCH' + } + } + + class ResponseContentLengthMismatchError extends UndiciError { + constructor(message) { + super(message) + Error.captureStackTrace(this, ResponseContentLengthMismatchError) + this.name = 'ResponseContentLengthMismatchError' + this.message = + message || + 'Response body length does not match content-length header' + this.code = 'UND_ERR_RES_CONTENT_LENGTH_MISMATCH' + } + } + + class ClientDestroyedError extends UndiciError { + constructor(message) { + super(message) + Error.captureStackTrace(this, ClientDestroyedError) + this.name = 'ClientDestroyedError' + this.message = message || 'The client is destroyed' + this.code = 'UND_ERR_DESTROYED' + } + } + + class ClientClosedError extends UndiciError { + constructor(message) { + super(message) + Error.captureStackTrace(this, ClientClosedError) + this.name = 'ClientClosedError' + this.message = message || 'The client is closed' + this.code = 'UND_ERR_CLOSED' + } + } + + class SocketError extends UndiciError { + constructor(message, socket) { + super(message) + Error.captureStackTrace(this, SocketError) + this.name = 'SocketError' + this.message = message || 'Socket error' + this.code = 'UND_ERR_SOCKET' + this.socket = socket + } + } + + class NotSupportedError extends UndiciError { + constructor(message) { + super(message) + Error.captureStackTrace(this, NotSupportedError) + this.name = 'NotSupportedError' + this.message = message || 'Not supported error' + this.code = 'UND_ERR_NOT_SUPPORTED' + } + } + + class BalancedPoolMissingUpstreamError extends UndiciError { + constructor(message) { + super(message) + Error.captureStackTrace(this, NotSupportedError) + this.name = 'MissingUpstreamError' + this.message = + message || 'No upstream has been added to the BalancedPool' + this.code = 'UND_ERR_BPL_MISSING_UPSTREAM' + } + } + + class HTTPParserError extends Error { + constructor(message, code, data) { + super(message) + Error.captureStackTrace(this, HTTPParserError) + this.name = 'HTTPParserError' + this.code = code ? `HPE_${code}` : undefined + this.data = data ? data.toString() : undefined + } + } + + class ResponseExceededMaxSizeError extends UndiciError { + constructor(message) { + super(message) + Error.captureStackTrace(this, ResponseExceededMaxSizeError) + this.name = 'ResponseExceededMaxSizeError' + this.message = message || 'Response content exceeded max size' + this.code = 'UND_ERR_RES_EXCEEDED_MAX_SIZE' + } + } + + module.exports = { + HTTPParserError, + UndiciError, + HeadersTimeoutError, + HeadersOverflowError, + BodyTimeoutError, + RequestContentLengthMismatchError, + ConnectTimeoutError, + ResponseStatusCodeError, + InvalidArgumentError, + InvalidReturnValueError, + RequestAbortedError, + ClientDestroyedError, + ClientClosedError, + InformationalError, + SocketError, + NotSupportedError, + ResponseContentLengthMismatchError, + BalancedPoolMissingUpstreamError, + ResponseExceededMaxSizeError, + } + + /***/ + }, + + /***/ 2905: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const { InvalidArgumentError, NotSupportedError } = + __nccwpck_require__(8045) + const assert = __nccwpck_require__(9491) + const { kHTTP2BuildRequest, kHTTP2CopyHeaders, kHTTP1BuildRequest } = + __nccwpck_require__(2785) + const util = __nccwpck_require__(3983) + + // tokenRegExp and headerCharRegex have been lifted from + // https://github.com/nodejs/node/blob/main/lib/_http_common.js + + /** + * Verifies that the given val is a valid HTTP token + * per the rules defined in RFC 7230 + * See https://tools.ietf.org/html/rfc7230#section-3.2.6 + */ + const tokenRegExp = /^[\^_`a-zA-Z\-0-9!#$%&'*+.|~]+$/ + + /** + * Matches if val contains an invalid field-vchar + * field-value = *( field-content / obs-fold ) + * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ] + * field-vchar = VCHAR / obs-text + */ + const headerCharRegex = /[^\t\x20-\x7e\x80-\xff]/ + + // Verifies that a given path is valid does not contain control chars \x00 to \x20 + const invalidPathRegex = /[^\u0021-\u00ff]/ + + const kHandler = Symbol('handler') + + const channels = {} + + let extractBody + + try { + const diagnosticsChannel = __nccwpck_require__(7643) + channels.create = diagnosticsChannel.channel('undici:request:create') + channels.bodySent = diagnosticsChannel.channel( + 'undici:request:bodySent' + ) + channels.headers = diagnosticsChannel.channel('undici:request:headers') + channels.trailers = diagnosticsChannel.channel( + 'undici:request:trailers' + ) + channels.error = diagnosticsChannel.channel('undici:request:error') + } catch { + channels.create = { hasSubscribers: false } + channels.bodySent = { hasSubscribers: false } + channels.headers = { hasSubscribers: false } + channels.trailers = { hasSubscribers: false } + channels.error = { hasSubscribers: false } + } + + class Request { + constructor( + origin, + { + path, + method, + body, + headers, + query, + idempotent, + blocking, + upgrade, + headersTimeout, + bodyTimeout, + reset, + throwOnError, + expectContinue, + }, + handler + ) { + if (typeof path !== 'string') { + throw new InvalidArgumentError('path must be a string') + } else if ( + path[0] !== '/' && + !(path.startsWith('http://') || path.startsWith('https://')) && + method !== 'CONNECT' + ) { + throw new InvalidArgumentError( + 'path must be an absolute URL or start with a slash' + ) + } else if (invalidPathRegex.exec(path) !== null) { + throw new InvalidArgumentError('invalid request path') + } + + if (typeof method !== 'string') { + throw new InvalidArgumentError('method must be a string') + } else if (tokenRegExp.exec(method) === null) { + throw new InvalidArgumentError('invalid request method') + } + + if (upgrade && typeof upgrade !== 'string') { + throw new InvalidArgumentError('upgrade must be a string') + } + + if ( + headersTimeout != null && + (!Number.isFinite(headersTimeout) || headersTimeout < 0) + ) { + throw new InvalidArgumentError('invalid headersTimeout') + } + + if ( + bodyTimeout != null && + (!Number.isFinite(bodyTimeout) || bodyTimeout < 0) + ) { + throw new InvalidArgumentError('invalid bodyTimeout') + } + + if (reset != null && typeof reset !== 'boolean') { + throw new InvalidArgumentError('invalid reset') + } + + if (expectContinue != null && typeof expectContinue !== 'boolean') { + throw new InvalidArgumentError('invalid expectContinue') + } + + this.headersTimeout = headersTimeout + + this.bodyTimeout = bodyTimeout + + this.throwOnError = throwOnError === true + + this.method = method + + this.abort = null + + if (body == null) { + this.body = null + } else if (util.isStream(body)) { + this.body = body + + const rState = this.body._readableState + if (!rState || !rState.autoDestroy) { + this.endHandler = function autoDestroy() { + util.destroy(this) + } + this.body.on('end', this.endHandler) + } + + this.errorHandler = (err) => { + if (this.abort) { + this.abort(err) + } else { + this.error = err + } + } + this.body.on('error', this.errorHandler) + } else if (util.isBuffer(body)) { + this.body = body.byteLength ? body : null + } else if (ArrayBuffer.isView(body)) { + this.body = body.buffer.byteLength + ? Buffer.from(body.buffer, body.byteOffset, body.byteLength) + : null + } else if (body instanceof ArrayBuffer) { + this.body = body.byteLength ? Buffer.from(body) : null + } else if (typeof body === 'string') { + this.body = body.length ? Buffer.from(body) : null + } else if ( + util.isFormDataLike(body) || + util.isIterable(body) || + util.isBlobLike(body) + ) { + this.body = body + } else { + throw new InvalidArgumentError( + 'body must be a string, a Buffer, a Readable stream, an iterable, or an async iterable' + ) + } + + this.completed = false + + this.aborted = false + + this.upgrade = upgrade || null + + this.path = query ? util.buildURL(path, query) : path + + this.origin = origin + + this.idempotent = + idempotent == null + ? method === 'HEAD' || method === 'GET' + : idempotent + + this.blocking = blocking == null ? false : blocking + + this.reset = reset == null ? null : reset + + this.host = null + + this.contentLength = null + + this.contentType = null + + this.headers = '' + + // Only for H2 + this.expectContinue = expectContinue != null ? expectContinue : false + + if (Array.isArray(headers)) { + if (headers.length % 2 !== 0) { + throw new InvalidArgumentError('headers array must be even') + } + for (let i = 0; i < headers.length; i += 2) { + processHeader(this, headers[i], headers[i + 1]) + } + } else if (headers && typeof headers === 'object') { + const keys = Object.keys(headers) + for (let i = 0; i < keys.length; i++) { + const key = keys[i] + processHeader(this, key, headers[key]) + } + } else if (headers != null) { + throw new InvalidArgumentError( + 'headers must be an object or an array' + ) + } + + if (util.isFormDataLike(this.body)) { + if ( + util.nodeMajor < 16 || + (util.nodeMajor === 16 && util.nodeMinor < 8) + ) { + throw new InvalidArgumentError( + 'Form-Data bodies are only supported in node v16.8 and newer.' + ) + } + + if (!extractBody) { + extractBody = __nccwpck_require__(1472).extractBody + } + + const [bodyStream, contentType] = extractBody(body) + if (this.contentType == null) { + this.contentType = contentType + this.headers += `content-type: ${contentType}\r\n` + } + this.body = bodyStream.stream + this.contentLength = bodyStream.length + } else if ( + util.isBlobLike(body) && + this.contentType == null && + body.type + ) { + this.contentType = body.type + this.headers += `content-type: ${body.type}\r\n` + } + + util.validateHandler(handler, method, upgrade) + + this.servername = util.getServerName(this.host) + + this[kHandler] = handler + + if (channels.create.hasSubscribers) { + channels.create.publish({ request: this }) + } + } + + onBodySent(chunk) { + if (this[kHandler].onBodySent) { + try { + this[kHandler].onBodySent(chunk) + } catch (err) { + this.onError(err) + } + } + } + + onRequestSent() { + if (channels.bodySent.hasSubscribers) { + channels.bodySent.publish({ request: this }) + } + + if (this[kHandler].onRequestSent) { + try { + this[kHandler].onRequestSent() + } catch (err) { + this.onError(err) + } + } + } + + onConnect(abort) { + assert(!this.aborted) + assert(!this.completed) + + if (this.error) { + abort(this.error) + } else { + this.abort = abort + return this[kHandler].onConnect(abort) + } + } + + onHeaders(statusCode, headers, resume, statusText) { + assert(!this.aborted) + assert(!this.completed) + + if (channels.headers.hasSubscribers) { + channels.headers.publish({ + request: this, + response: { statusCode, headers, statusText }, + }) + } + + return this[kHandler].onHeaders( + statusCode, + headers, + resume, + statusText + ) + } + + onData(chunk) { + assert(!this.aborted) + assert(!this.completed) + + return this[kHandler].onData(chunk) + } + + onUpgrade(statusCode, headers, socket) { + assert(!this.aborted) + assert(!this.completed) + + return this[kHandler].onUpgrade(statusCode, headers, socket) + } + + onComplete(trailers) { + this.onFinally() + + assert(!this.aborted) + + this.completed = true + if (channels.trailers.hasSubscribers) { + channels.trailers.publish({ request: this, trailers }) + } + return this[kHandler].onComplete(trailers) + } + + onError(error) { + this.onFinally() + + if (channels.error.hasSubscribers) { + channels.error.publish({ request: this, error }) + } + + if (this.aborted) { + return + } + this.aborted = true + return this[kHandler].onError(error) + } + + onFinally() { + if (this.errorHandler) { + this.body.off('error', this.errorHandler) + this.errorHandler = null + } + + if (this.endHandler) { + this.body.off('end', this.endHandler) + this.endHandler = null + } + } + + // TODO: adjust to support H2 + addHeader(key, value) { + processHeader(this, key, value) + return this + } + + static [kHTTP1BuildRequest](origin, opts, handler) { + // TODO: Migrate header parsing here, to make Requests + // HTTP agnostic + return new Request(origin, opts, handler) + } + + static [kHTTP2BuildRequest](origin, opts, handler) { + const headers = opts.headers + opts = { ...opts, headers: null } + + const request = new Request(origin, opts, handler) + + request.headers = {} + + if (Array.isArray(headers)) { + if (headers.length % 2 !== 0) { + throw new InvalidArgumentError('headers array must be even') + } + for (let i = 0; i < headers.length; i += 2) { + processHeader(request, headers[i], headers[i + 1], true) + } + } else if (headers && typeof headers === 'object') { + const keys = Object.keys(headers) + for (let i = 0; i < keys.length; i++) { + const key = keys[i] + processHeader(request, key, headers[key], true) + } + } else if (headers != null) { + throw new InvalidArgumentError( + 'headers must be an object or an array' + ) + } + + return request + } + + static [kHTTP2CopyHeaders](raw) { + const rawHeaders = raw.split('\r\n') + const headers = {} + + for (const header of rawHeaders) { + const [key, value] = header.split(': ') + + if (value == null || value.length === 0) continue + + if (headers[key]) headers[key] += `,${value}` + else headers[key] = value + } + + return headers + } + } + + function processHeaderValue(key, val, skipAppend) { + if (val && typeof val === 'object') { + throw new InvalidArgumentError(`invalid ${key} header`) + } + + val = val != null ? `${val}` : '' + + if (headerCharRegex.exec(val) !== null) { + throw new InvalidArgumentError(`invalid ${key} header`) + } + + return skipAppend ? val : `${key}: ${val}\r\n` + } + + function processHeader(request, key, val, skipAppend = false) { + if (val && typeof val === 'object' && !Array.isArray(val)) { + throw new InvalidArgumentError(`invalid ${key} header`) + } else if (val === undefined) { + return + } + + if ( + request.host === null && + key.length === 4 && + key.toLowerCase() === 'host' + ) { + if (headerCharRegex.exec(val) !== null) { + throw new InvalidArgumentError(`invalid ${key} header`) + } + // Consumed by Client + request.host = val + } else if ( + request.contentLength === null && + key.length === 14 && + key.toLowerCase() === 'content-length' + ) { + request.contentLength = parseInt(val, 10) + if (!Number.isFinite(request.contentLength)) { + throw new InvalidArgumentError('invalid content-length header') + } + } else if ( + request.contentType === null && + key.length === 12 && + key.toLowerCase() === 'content-type' + ) { + request.contentType = val + if (skipAppend) + request.headers[key] = processHeaderValue(key, val, skipAppend) + else request.headers += processHeaderValue(key, val) + } else if ( + key.length === 17 && + key.toLowerCase() === 'transfer-encoding' + ) { + throw new InvalidArgumentError('invalid transfer-encoding header') + } else if (key.length === 10 && key.toLowerCase() === 'connection') { + const value = typeof val === 'string' ? val.toLowerCase() : null + if (value !== 'close' && value !== 'keep-alive') { + throw new InvalidArgumentError('invalid connection header') + } else if (value === 'close') { + request.reset = true + } + } else if (key.length === 10 && key.toLowerCase() === 'keep-alive') { + throw new InvalidArgumentError('invalid keep-alive header') + } else if (key.length === 7 && key.toLowerCase() === 'upgrade') { + throw new InvalidArgumentError('invalid upgrade header') + } else if (key.length === 6 && key.toLowerCase() === 'expect') { + throw new NotSupportedError('expect header not supported') + } else if (tokenRegExp.exec(key) === null) { + throw new InvalidArgumentError('invalid header key') + } else { + if (Array.isArray(val)) { + for (let i = 0; i < val.length; i++) { + if (skipAppend) { + if (request.headers[key]) + request.headers[key] += `,${processHeaderValue( + key, + val[i], + skipAppend + )}` + else + request.headers[key] = processHeaderValue( + key, + val[i], + skipAppend + ) + } else { + request.headers += processHeaderValue(key, val[i]) + } + } + } else { + if (skipAppend) + request.headers[key] = processHeaderValue(key, val, skipAppend) + else request.headers += processHeaderValue(key, val) + } + } + } + + module.exports = Request + + /***/ + }, + + /***/ 2785: /***/ (module) => { + module.exports = { + kClose: Symbol('close'), + kDestroy: Symbol('destroy'), + kDispatch: Symbol('dispatch'), + kUrl: Symbol('url'), + kWriting: Symbol('writing'), + kResuming: Symbol('resuming'), + kQueue: Symbol('queue'), + kConnect: Symbol('connect'), + kConnecting: Symbol('connecting'), + kHeadersList: Symbol('headers list'), + kKeepAliveDefaultTimeout: Symbol('default keep alive timeout'), + kKeepAliveMaxTimeout: Symbol('max keep alive timeout'), + kKeepAliveTimeoutThreshold: Symbol('keep alive timeout threshold'), + kKeepAliveTimeoutValue: Symbol('keep alive timeout'), + kKeepAlive: Symbol('keep alive'), + kHeadersTimeout: Symbol('headers timeout'), + kBodyTimeout: Symbol('body timeout'), + kServerName: Symbol('server name'), + kLocalAddress: Symbol('local address'), + kHost: Symbol('host'), + kNoRef: Symbol('no ref'), + kBodyUsed: Symbol('used'), + kRunning: Symbol('running'), + kBlocking: Symbol('blocking'), + kPending: Symbol('pending'), + kSize: Symbol('size'), + kBusy: Symbol('busy'), + kQueued: Symbol('queued'), + kFree: Symbol('free'), + kConnected: Symbol('connected'), + kClosed: Symbol('closed'), + kNeedDrain: Symbol('need drain'), + kReset: Symbol('reset'), + kDestroyed: Symbol.for('nodejs.stream.destroyed'), + kMaxHeadersSize: Symbol('max headers size'), + kRunningIdx: Symbol('running index'), + kPendingIdx: Symbol('pending index'), + kError: Symbol('error'), + kClients: Symbol('clients'), + kClient: Symbol('client'), + kParser: Symbol('parser'), + kOnDestroyed: Symbol('destroy callbacks'), + kPipelining: Symbol('pipelining'), + kSocket: Symbol('socket'), + kHostHeader: Symbol('host header'), + kConnector: Symbol('connector'), + kStrictContentLength: Symbol('strict content length'), + kMaxRedirections: Symbol('maxRedirections'), + kMaxRequests: Symbol('maxRequestsPerClient'), + kProxy: Symbol('proxy agent options'), + kCounter: Symbol('socket request counter'), + kInterceptors: Symbol('dispatch interceptors'), + kMaxResponseSize: Symbol('max response size'), + kHTTP2Session: Symbol('http2Session'), + kHTTP2SessionState: Symbol('http2Session state'), + kHTTP2BuildRequest: Symbol('http2 build request'), + kHTTP1BuildRequest: Symbol('http1 build request'), + kHTTP2CopyHeaders: Symbol('http2 copy headers'), + kHTTPConnVersion: Symbol('http connection version'), + } + + /***/ + }, + + /***/ 3983: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const assert = __nccwpck_require__(9491) + const { kDestroyed, kBodyUsed } = __nccwpck_require__(2785) + const { IncomingMessage } = __nccwpck_require__(3685) + const stream = __nccwpck_require__(2781) + const net = __nccwpck_require__(1808) + const { InvalidArgumentError } = __nccwpck_require__(8045) + const { Blob } = __nccwpck_require__(4300) + const nodeUtil = __nccwpck_require__(3837) + const { stringify } = __nccwpck_require__(3477) + + const [nodeMajor, nodeMinor] = process.versions.node + .split('.') + .map((v) => Number(v)) + + function nop() {} + + function isStream(obj) { + return ( + obj && + typeof obj === 'object' && + typeof obj.pipe === 'function' && + typeof obj.on === 'function' + ) + } + + // based on https://github.com/node-fetch/fetch-blob/blob/8ab587d34080de94140b54f07168451e7d0b655e/index.js#L229-L241 (MIT License) + function isBlobLike(object) { + return ( + (Blob && object instanceof Blob) || + (object && + typeof object === 'object' && + (typeof object.stream === 'function' || + typeof object.arrayBuffer === 'function') && + /^(Blob|File)$/.test(object[Symbol.toStringTag])) + ) + } + + function buildURL(url, queryParams) { + if (url.includes('?') || url.includes('#')) { + throw new Error( + 'Query params cannot be passed when url already contains "?" or "#".' + ) + } + + const stringified = stringify(queryParams) + + if (stringified) { + url += '?' + stringified + } + + return url + } + + function parseURL(url) { + if (typeof url === 'string') { + url = new URL(url) + + if (!/^https?:/.test(url.origin || url.protocol)) { + throw new InvalidArgumentError( + 'Invalid URL protocol: the URL must start with `http:` or `https:`.' + ) + } + + return url + } + + if (!url || typeof url !== 'object') { + throw new InvalidArgumentError( + 'Invalid URL: The URL argument must be a non-null object.' + ) + } + + if (!/^https?:/.test(url.origin || url.protocol)) { + throw new InvalidArgumentError( + 'Invalid URL protocol: the URL must start with `http:` or `https:`.' + ) + } + + if (!(url instanceof URL)) { + if ( + url.port != null && + url.port !== '' && + !Number.isFinite(parseInt(url.port)) + ) { + throw new InvalidArgumentError( + 'Invalid URL: port must be a valid integer or a string representation of an integer.' + ) + } + + if (url.path != null && typeof url.path !== 'string') { + throw new InvalidArgumentError( + 'Invalid URL path: the path must be a string or null/undefined.' + ) + } + + if (url.pathname != null && typeof url.pathname !== 'string') { + throw new InvalidArgumentError( + 'Invalid URL pathname: the pathname must be a string or null/undefined.' + ) + } + + if (url.hostname != null && typeof url.hostname !== 'string') { + throw new InvalidArgumentError( + 'Invalid URL hostname: the hostname must be a string or null/undefined.' + ) + } + + if (url.origin != null && typeof url.origin !== 'string') { + throw new InvalidArgumentError( + 'Invalid URL origin: the origin must be a string or null/undefined.' + ) + } + + const port = + url.port != null ? url.port : url.protocol === 'https:' ? 443 : 80 + let origin = + url.origin != null + ? url.origin + : `${url.protocol}//${url.hostname}:${port}` + let path = + url.path != null + ? url.path + : `${url.pathname || ''}${url.search || ''}` + + if (origin.endsWith('/')) { + origin = origin.substring(0, origin.length - 1) + } + + if (path && !path.startsWith('/')) { + path = `/${path}` + } + // new URL(path, origin) is unsafe when `path` contains an absolute URL + // From https://developer.mozilla.org/en-US/docs/Web/API/URL/URL: + // If first parameter is a relative URL, second param is required, and will be used as the base URL. + // If first parameter is an absolute URL, a given second param will be ignored. + url = new URL(origin + path) + } + + return url + } + + function parseOrigin(url) { + url = parseURL(url) + + if (url.pathname !== '/' || url.search || url.hash) { + throw new InvalidArgumentError('invalid url') + } + + return url + } + + function getHostname(host) { + if (host[0] === '[') { + const idx = host.indexOf(']') + + assert(idx !== -1) + return host.substr(1, idx - 1) + } + + const idx = host.indexOf(':') + if (idx === -1) return host + + return host.substr(0, idx) + } + + // IP addresses are not valid server names per RFC6066 + // > Currently, the only server names supported are DNS hostnames + function getServerName(host) { + if (!host) { + return null + } + + assert.strictEqual(typeof host, 'string') + + const servername = getHostname(host) + if (net.isIP(servername)) { + return '' + } + + return servername + } + + function deepClone(obj) { + return JSON.parse(JSON.stringify(obj)) + } + + function isAsyncIterable(obj) { + return !!( + obj != null && typeof obj[Symbol.asyncIterator] === 'function' + ) + } + + function isIterable(obj) { + return !!( + obj != null && + (typeof obj[Symbol.iterator] === 'function' || + typeof obj[Symbol.asyncIterator] === 'function') + ) + } + + function bodyLength(body) { + if (body == null) { + return 0 + } else if (isStream(body)) { + const state = body._readableState + return state && + state.objectMode === false && + state.ended === true && + Number.isFinite(state.length) + ? state.length + : null + } else if (isBlobLike(body)) { + return body.size != null ? body.size : null + } else if (isBuffer(body)) { + return body.byteLength + } + + return null + } + + function isDestroyed(stream) { + return !stream || !!(stream.destroyed || stream[kDestroyed]) + } + + function isReadableAborted(stream) { + const state = stream && stream._readableState + return isDestroyed(stream) && state && !state.endEmitted + } + + function destroy(stream, err) { + if (stream == null || !isStream(stream) || isDestroyed(stream)) { + return + } + + if (typeof stream.destroy === 'function') { + if (Object.getPrototypeOf(stream).constructor === IncomingMessage) { + // See: https://github.com/nodejs/node/pull/38505/files + stream.socket = null + } + + stream.destroy(err) + } else if (err) { + process.nextTick( + (stream, err) => { + stream.emit('error', err) + }, + stream, + err + ) + } + + if (stream.destroyed !== true) { + stream[kDestroyed] = true + } + } + + const KEEPALIVE_TIMEOUT_EXPR = /timeout=(\d+)/ + function parseKeepAliveTimeout(val) { + const m = val.toString().match(KEEPALIVE_TIMEOUT_EXPR) + return m ? parseInt(m[1], 10) * 1000 : null + } + + function parseHeaders(headers, obj = {}) { + // For H2 support + if (!Array.isArray(headers)) return headers + + for (let i = 0; i < headers.length; i += 2) { + const key = headers[i].toString().toLowerCase() + let val = obj[key] + + if (!val) { + if (Array.isArray(headers[i + 1])) { + obj[key] = headers[i + 1] + } else { + obj[key] = headers[i + 1].toString('utf8') + } + } else { + if (!Array.isArray(val)) { + val = [val] + obj[key] = val + } + val.push(headers[i + 1].toString('utf8')) + } + } + + // See https://github.com/nodejs/node/pull/46528 + if ('content-length' in obj && 'content-disposition' in obj) { + obj['content-disposition'] = Buffer.from( + obj['content-disposition'] + ).toString('latin1') + } + + return obj + } + + function parseRawHeaders(headers) { + const ret = [] + let hasContentLength = false + let contentDispositionIdx = -1 + + for (let n = 0; n < headers.length; n += 2) { + const key = headers[n + 0].toString() + const val = headers[n + 1].toString('utf8') + + if ( + key.length === 14 && + (key === 'content-length' || key.toLowerCase() === 'content-length') + ) { + ret.push(key, val) + hasContentLength = true + } else if ( + key.length === 19 && + (key === 'content-disposition' || + key.toLowerCase() === 'content-disposition') + ) { + contentDispositionIdx = ret.push(key, val) - 1 + } else { + ret.push(key, val) + } + } + + // See https://github.com/nodejs/node/pull/46528 + if (hasContentLength && contentDispositionIdx !== -1) { + ret[contentDispositionIdx] = Buffer.from( + ret[contentDispositionIdx] + ).toString('latin1') + } + + return ret + } + + function isBuffer(buffer) { + // See, https://github.com/mcollina/undici/pull/319 + return buffer instanceof Uint8Array || Buffer.isBuffer(buffer) + } + + function validateHandler(handler, method, upgrade) { + if (!handler || typeof handler !== 'object') { + throw new InvalidArgumentError('handler must be an object') + } + + if (typeof handler.onConnect !== 'function') { + throw new InvalidArgumentError('invalid onConnect method') + } + + if (typeof handler.onError !== 'function') { + throw new InvalidArgumentError('invalid onError method') + } + + if ( + typeof handler.onBodySent !== 'function' && + handler.onBodySent !== undefined + ) { + throw new InvalidArgumentError('invalid onBodySent method') + } + + if (upgrade || method === 'CONNECT') { + if (typeof handler.onUpgrade !== 'function') { + throw new InvalidArgumentError('invalid onUpgrade method') + } + } else { + if (typeof handler.onHeaders !== 'function') { + throw new InvalidArgumentError('invalid onHeaders method') + } + + if (typeof handler.onData !== 'function') { + throw new InvalidArgumentError('invalid onData method') + } + + if (typeof handler.onComplete !== 'function') { + throw new InvalidArgumentError('invalid onComplete method') + } + } + } + + // A body is disturbed if it has been read from and it cannot + // be re-used without losing state or data. + function isDisturbed(body) { + return !!( + body && + (stream.isDisturbed + ? stream.isDisturbed(body) || body[kBodyUsed] // TODO (fix): Why is body[kBodyUsed] needed? + : body[kBodyUsed] || + body.readableDidRead || + (body._readableState && body._readableState.dataEmitted) || + isReadableAborted(body)) + ) + } + + function isErrored(body) { + return !!( + body && + (stream.isErrored + ? stream.isErrored(body) + : /state: 'errored'/.test(nodeUtil.inspect(body))) + ) + } + + function isReadable(body) { + return !!( + body && + (stream.isReadable + ? stream.isReadable(body) + : /state: 'readable'/.test(nodeUtil.inspect(body))) + ) + } + + function getSocketInfo(socket) { + return { + localAddress: socket.localAddress, + localPort: socket.localPort, + remoteAddress: socket.remoteAddress, + remotePort: socket.remotePort, + remoteFamily: socket.remoteFamily, + timeout: socket.timeout, + bytesWritten: socket.bytesWritten, + bytesRead: socket.bytesRead, + } + } + + async function* convertIterableToBuffer(iterable) { + for await (const chunk of iterable) { + yield Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk) + } + } + + let ReadableStream + function ReadableStreamFrom(iterable) { + if (!ReadableStream) { + ReadableStream = __nccwpck_require__(5356).ReadableStream + } + + if (ReadableStream.from) { + return ReadableStream.from(convertIterableToBuffer(iterable)) + } + + let iterator + return new ReadableStream( + { + async start() { + iterator = iterable[Symbol.asyncIterator]() + }, + async pull(controller) { + const { done, value } = await iterator.next() + if (done) { + queueMicrotask(() => { + controller.close() + }) + } else { + const buf = Buffer.isBuffer(value) ? value : Buffer.from(value) + controller.enqueue(new Uint8Array(buf)) + } + return controller.desiredSize > 0 + }, + async cancel(reason) { + await iterator.return() + }, + }, + 0 + ) + } + + // The chunk should be a FormData instance and contains + // all the required methods. + function isFormDataLike(object) { + return ( + object && + typeof object === 'object' && + typeof object.append === 'function' && + typeof object.delete === 'function' && + typeof object.get === 'function' && + typeof object.getAll === 'function' && + typeof object.has === 'function' && + typeof object.set === 'function' && + object[Symbol.toStringTag] === 'FormData' + ) + } + + function throwIfAborted(signal) { + if (!signal) { + return + } + if (typeof signal.throwIfAborted === 'function') { + signal.throwIfAborted() + } else { + if (signal.aborted) { + // DOMException not available < v17.0.0 + const err = new Error('The operation was aborted') + err.name = 'AbortError' + throw err + } + } + } + + let events + function addAbortListener(signal, listener) { + if (typeof Symbol.dispose === 'symbol') { + if (!events) { + events = __nccwpck_require__(2361) + } + if ( + typeof events.addAbortListener === 'function' && + 'aborted' in signal + ) { + return events.addAbortListener(signal, listener) + } + } + if ('addEventListener' in signal) { + signal.addEventListener('abort', listener, { once: true }) + return () => signal.removeEventListener('abort', listener) + } + signal.addListener('abort', listener) + return () => signal.removeListener('abort', listener) + } + + const hasToWellFormed = !!String.prototype.toWellFormed + + /** + * @param {string} val + */ + function toUSVString(val) { + if (hasToWellFormed) { + return `${val}`.toWellFormed() + } else if (nodeUtil.toUSVString) { + return nodeUtil.toUSVString(val) + } + + return `${val}` + } + + const kEnumerableProperty = Object.create(null) + kEnumerableProperty.enumerable = true + + module.exports = { + kEnumerableProperty, + nop, + isDisturbed, + isErrored, + isReadable, + toUSVString, + isReadableAborted, + isBlobLike, + parseOrigin, + parseURL, + getServerName, + isStream, + isIterable, + isAsyncIterable, + isDestroyed, + parseRawHeaders, + parseHeaders, + parseKeepAliveTimeout, + destroy, + bodyLength, + deepClone, + ReadableStreamFrom, + isBuffer, + validateHandler, + getSocketInfo, + isFormDataLike, + buildURL, + throwIfAborted, + addAbortListener, + nodeMajor, + nodeMinor, + nodeHasAutoSelectFamily: + nodeMajor > 18 || (nodeMajor === 18 && nodeMinor >= 13), + } + + /***/ + }, + + /***/ 4839: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const Dispatcher = __nccwpck_require__(412) + const { ClientDestroyedError, ClientClosedError, InvalidArgumentError } = + __nccwpck_require__(8045) + const { kDestroy, kClose, kDispatch, kInterceptors } = + __nccwpck_require__(2785) + + const kDestroyed = Symbol('destroyed') + const kClosed = Symbol('closed') + const kOnDestroyed = Symbol('onDestroyed') + const kOnClosed = Symbol('onClosed') + const kInterceptedDispatch = Symbol('Intercepted Dispatch') + + class DispatcherBase extends Dispatcher { + constructor() { + super() + + this[kDestroyed] = false + this[kOnDestroyed] = null + this[kClosed] = false + this[kOnClosed] = [] + } + + get destroyed() { + return this[kDestroyed] + } + + get closed() { + return this[kClosed] + } + + get interceptors() { + return this[kInterceptors] + } + + set interceptors(newInterceptors) { + if (newInterceptors) { + for (let i = newInterceptors.length - 1; i >= 0; i--) { + const interceptor = this[kInterceptors][i] + if (typeof interceptor !== 'function') { + throw new InvalidArgumentError( + 'interceptor must be an function' + ) + } + } + } + + this[kInterceptors] = newInterceptors + } + + close(callback) { + if (callback === undefined) { + return new Promise((resolve, reject) => { + this.close((err, data) => { + return err ? reject(err) : resolve(data) + }) + }) + } + + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') + } + + if (this[kDestroyed]) { + queueMicrotask(() => callback(new ClientDestroyedError(), null)) + return + } + + if (this[kClosed]) { + if (this[kOnClosed]) { + this[kOnClosed].push(callback) + } else { + queueMicrotask(() => callback(null, null)) + } + return + } + + this[kClosed] = true + this[kOnClosed].push(callback) + + const onClosed = () => { + const callbacks = this[kOnClosed] + this[kOnClosed] = null + for (let i = 0; i < callbacks.length; i++) { + callbacks[i](null, null) + } + } + + // Should not error. + this[kClose]() + .then(() => this.destroy()) + .then(() => { + queueMicrotask(onClosed) + }) + } + + destroy(err, callback) { + if (typeof err === 'function') { + callback = err + err = null + } + + if (callback === undefined) { + return new Promise((resolve, reject) => { + this.destroy(err, (err, data) => { + return err + ? /* istanbul ignore next: should never error */ reject(err) + : resolve(data) + }) + }) + } + + if (typeof callback !== 'function') { + throw new InvalidArgumentError('invalid callback') + } + + if (this[kDestroyed]) { + if (this[kOnDestroyed]) { + this[kOnDestroyed].push(callback) + } else { + queueMicrotask(() => callback(null, null)) + } + return + } + + if (!err) { + err = new ClientDestroyedError() + } + + this[kDestroyed] = true + this[kOnDestroyed] = this[kOnDestroyed] || [] + this[kOnDestroyed].push(callback) + + const onDestroyed = () => { + const callbacks = this[kOnDestroyed] + this[kOnDestroyed] = null + for (let i = 0; i < callbacks.length; i++) { + callbacks[i](null, null) + } + } + + // Should not error. + this[kDestroy](err).then(() => { + queueMicrotask(onDestroyed) + }) + } + + [kInterceptedDispatch](opts, handler) { + if (!this[kInterceptors] || this[kInterceptors].length === 0) { + this[kInterceptedDispatch] = this[kDispatch] + return this[kDispatch](opts, handler) + } + + let dispatch = this[kDispatch].bind(this) + for (let i = this[kInterceptors].length - 1; i >= 0; i--) { + dispatch = this[kInterceptors][i](dispatch) + } + this[kInterceptedDispatch] = dispatch + return dispatch(opts, handler) + } + + dispatch(opts, handler) { + if (!handler || typeof handler !== 'object') { + throw new InvalidArgumentError('handler must be an object') + } + + try { + if (!opts || typeof opts !== 'object') { + throw new InvalidArgumentError('opts must be an object.') + } + + if (this[kDestroyed] || this[kOnDestroyed]) { + throw new ClientDestroyedError() + } + + if (this[kClosed]) { + throw new ClientClosedError() + } + + return this[kInterceptedDispatch](opts, handler) + } catch (err) { + if (typeof handler.onError !== 'function') { + throw new InvalidArgumentError('invalid onError method') + } + + handler.onError(err) + + return false + } + } + } + + module.exports = DispatcherBase + + /***/ + }, + + /***/ 412: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const EventEmitter = __nccwpck_require__(2361) + + class Dispatcher extends EventEmitter { + dispatch() { + throw new Error('not implemented') + } + + close() { + throw new Error('not implemented') + } + + destroy() { + throw new Error('not implemented') + } + } + + module.exports = Dispatcher + + /***/ + }, + + /***/ 1472: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const Busboy = __nccwpck_require__(727) + const util = __nccwpck_require__(3983) + const { + ReadableStreamFrom, + isBlobLike, + isReadableStreamLike, + readableStreamClose, + createDeferredPromise, + fullyReadBody, + } = __nccwpck_require__(2538) + const { FormData } = __nccwpck_require__(2015) + const { kState } = __nccwpck_require__(5861) + const { webidl } = __nccwpck_require__(1744) + const { DOMException, structuredClone } = __nccwpck_require__(1037) + const { Blob, File: NativeFile } = __nccwpck_require__(4300) + const { kBodyUsed } = __nccwpck_require__(2785) + const assert = __nccwpck_require__(9491) + const { isErrored } = __nccwpck_require__(3983) + const { isUint8Array, isArrayBuffer } = __nccwpck_require__(4978) + const { File: UndiciFile } = __nccwpck_require__(8511) + const { parseMIMEType, serializeAMimeType } = __nccwpck_require__(685) + + let ReadableStream = globalThis.ReadableStream + + /** @type {globalThis['File']} */ + const File = NativeFile ?? UndiciFile + const textEncoder = new TextEncoder() + const textDecoder = new TextDecoder() + + // https://fetch.spec.whatwg.org/#concept-bodyinit-extract + function extractBody(object, keepalive = false) { + if (!ReadableStream) { + ReadableStream = __nccwpck_require__(5356).ReadableStream + } + + // 1. Let stream be null. + let stream = null + + // 2. If object is a ReadableStream object, then set stream to object. + if (object instanceof ReadableStream) { + stream = object + } else if (isBlobLike(object)) { + // 3. Otherwise, if object is a Blob object, set stream to the + // result of running object’s get stream. + stream = object.stream() + } else { + // 4. Otherwise, set stream to a new ReadableStream object, and set + // up stream. + stream = new ReadableStream({ + async pull(controller) { + controller.enqueue( + typeof source === 'string' ? textEncoder.encode(source) : source + ) + queueMicrotask(() => readableStreamClose(controller)) + }, + start() {}, + type: undefined, + }) + } + + // 5. Assert: stream is a ReadableStream object. + assert(isReadableStreamLike(stream)) + + // 6. Let action be null. + let action = null + + // 7. Let source be null. + let source = null + + // 8. Let length be null. + let length = null + + // 9. Let type be null. + let type = null + + // 10. Switch on object: + if (typeof object === 'string') { + // Set source to the UTF-8 encoding of object. + // Note: setting source to a Uint8Array here breaks some mocking assumptions. + source = object + + // Set type to `text/plain;charset=UTF-8`. + type = 'text/plain;charset=UTF-8' + } else if (object instanceof URLSearchParams) { + // URLSearchParams + + // spec says to run application/x-www-form-urlencoded on body.list + // this is implemented in Node.js as apart of an URLSearchParams instance toString method + // See: https://github.com/nodejs/node/blob/e46c680bf2b211bbd52cf959ca17ee98c7f657f5/lib/internal/url.js#L490 + // and https://github.com/nodejs/node/blob/e46c680bf2b211bbd52cf959ca17ee98c7f657f5/lib/internal/url.js#L1100 + + // Set source to the result of running the application/x-www-form-urlencoded serializer with object’s list. + source = object.toString() + + // Set type to `application/x-www-form-urlencoded;charset=UTF-8`. + type = 'application/x-www-form-urlencoded;charset=UTF-8' + } else if (isArrayBuffer(object)) { + // BufferSource/ArrayBuffer + + // Set source to a copy of the bytes held by object. + source = new Uint8Array(object.slice()) + } else if (ArrayBuffer.isView(object)) { + // BufferSource/ArrayBufferView + + // Set source to a copy of the bytes held by object. + source = new Uint8Array( + object.buffer.slice( + object.byteOffset, + object.byteOffset + object.byteLength + ) + ) + } else if (util.isFormDataLike(object)) { + const boundary = `----formdata-undici-0${`${Math.floor( + Math.random() * 1e11 + )}`.padStart(11, '0')}` + const prefix = `--${boundary}\r\nContent-Disposition: form-data` + + /*! formdata-polyfill. MIT License. Jimmy Wärting */ + const escape = (str) => + str.replace(/\n/g, '%0A').replace(/\r/g, '%0D').replace(/"/g, '%22') + const normalizeLinefeeds = (value) => + value.replace(/\r?\n|\r/g, '\r\n') + + // Set action to this step: run the multipart/form-data + // encoding algorithm, with object’s entry list and UTF-8. + // - This ensures that the body is immutable and can't be changed afterwords + // - That the content-length is calculated in advance. + // - And that all parts are pre-encoded and ready to be sent. + + const blobParts = [] + const rn = new Uint8Array([13, 10]) // '\r\n' + length = 0 + let hasUnknownSizeValue = false + + for (const [name, value] of object) { + if (typeof value === 'string') { + const chunk = textEncoder.encode( + prefix + + `; name="${escape(normalizeLinefeeds(name))}"` + + `\r\n\r\n${normalizeLinefeeds(value)}\r\n` + ) + blobParts.push(chunk) + length += chunk.byteLength + } else { + const chunk = textEncoder.encode( + `${prefix}; name="${escape(normalizeLinefeeds(name))}"` + + (value.name ? `; filename="${escape(value.name)}"` : '') + + '\r\n' + + `Content-Type: ${ + value.type || 'application/octet-stream' + }\r\n\r\n` + ) + blobParts.push(chunk, value, rn) + if (typeof value.size === 'number') { + length += chunk.byteLength + value.size + rn.byteLength + } else { + hasUnknownSizeValue = true + } + } + } + + const chunk = textEncoder.encode(`--${boundary}--`) + blobParts.push(chunk) + length += chunk.byteLength + if (hasUnknownSizeValue) { + length = null + } + + // Set source to object. + source = object + + action = async function* () { + for (const part of blobParts) { + if (part.stream) { + yield* part.stream() + } else { + yield part + } + } + } + + // Set type to `multipart/form-data; boundary=`, + // followed by the multipart/form-data boundary string generated + // by the multipart/form-data encoding algorithm. + type = 'multipart/form-data; boundary=' + boundary + } else if (isBlobLike(object)) { + // Blob + + // Set source to object. + source = object + + // Set length to object’s size. + length = object.size + + // If object’s type attribute is not the empty byte sequence, set + // type to its value. + if (object.type) { + type = object.type + } + } else if (typeof object[Symbol.asyncIterator] === 'function') { + // If keepalive is true, then throw a TypeError. + if (keepalive) { + throw new TypeError('keepalive') + } + + // If object is disturbed or locked, then throw a TypeError. + if (util.isDisturbed(object) || object.locked) { + throw new TypeError( + 'Response body object should not be disturbed or locked' + ) + } + + stream = + object instanceof ReadableStream + ? object + : ReadableStreamFrom(object) + } + + // 11. If source is a byte sequence, then set action to a + // step that returns source and length to source’s length. + if (typeof source === 'string' || util.isBuffer(source)) { + length = Buffer.byteLength(source) + } + + // 12. If action is non-null, then run these steps in in parallel: + if (action != null) { + // Run action. + let iterator + stream = new ReadableStream({ + async start() { + iterator = action(object)[Symbol.asyncIterator]() + }, + async pull(controller) { + const { value, done } = await iterator.next() + if (done) { + // When running action is done, close stream. + queueMicrotask(() => { + controller.close() + }) + } else { + // Whenever one or more bytes are available and stream is not errored, + // enqueue a Uint8Array wrapping an ArrayBuffer containing the available + // bytes into stream. + if (!isErrored(stream)) { + controller.enqueue(new Uint8Array(value)) + } + } + return controller.desiredSize > 0 + }, + async cancel(reason) { + await iterator.return() + }, + type: undefined, + }) + } + + // 13. Let body be a body whose stream is stream, source is source, + // and length is length. + const body = { stream, source, length } + + // 14. Return (body, type). + return [body, type] + } + + // https://fetch.spec.whatwg.org/#bodyinit-safely-extract + function safelyExtractBody(object, keepalive = false) { + if (!ReadableStream) { + // istanbul ignore next + ReadableStream = __nccwpck_require__(5356).ReadableStream + } + + // To safely extract a body and a `Content-Type` value from + // a byte sequence or BodyInit object object, run these steps: + + // 1. If object is a ReadableStream object, then: + if (object instanceof ReadableStream) { + // Assert: object is neither disturbed nor locked. + // istanbul ignore next + assert( + !util.isDisturbed(object), + 'The body has already been consumed.' + ) + // istanbul ignore next + assert(!object.locked, 'The stream is locked.') + } + + // 2. Return the results of extracting object. + return extractBody(object, keepalive) + } + + function cloneBody(body) { + // To clone a body body, run these steps: + + // https://fetch.spec.whatwg.org/#concept-body-clone + + // 1. Let « out1, out2 » be the result of teeing body’s stream. + const [out1, out2] = body.stream.tee() + const out2Clone = structuredClone(out2, { transfer: [out2] }) + // This, for whatever reasons, unrefs out2Clone which allows + // the process to exit by itself. + const [, finalClone] = out2Clone.tee() + + // 2. Set body’s stream to out1. + body.stream = out1 + + // 3. Return a body whose stream is out2 and other members are copied from body. + return { + stream: finalClone, + length: body.length, + source: body.source, + } + } + + async function* consumeBody(body) { + if (body) { + if (isUint8Array(body)) { + yield body + } else { + const stream = body.stream + + if (util.isDisturbed(stream)) { + throw new TypeError('The body has already been consumed.') + } + + if (stream.locked) { + throw new TypeError('The stream is locked.') + } + + // Compat. + stream[kBodyUsed] = true + + yield* stream + } + } + } + + function throwIfAborted(state) { + if (state.aborted) { + throw new DOMException('The operation was aborted.', 'AbortError') + } + } + + function bodyMixinMethods(instance) { + const methods = { + blob() { + // The blob() method steps are to return the result of + // running consume body with this and the following step + // given a byte sequence bytes: return a Blob whose + // contents are bytes and whose type attribute is this’s + // MIME type. + return specConsumeBody( + this, + (bytes) => { + let mimeType = bodyMimeType(this) + + if (mimeType === 'failure') { + mimeType = '' + } else if (mimeType) { + mimeType = serializeAMimeType(mimeType) + } + + // Return a Blob whose contents are bytes and type attribute + // is mimeType. + return new Blob([bytes], { type: mimeType }) + }, + instance + ) + }, + + arrayBuffer() { + // The arrayBuffer() method steps are to return the result + // of running consume body with this and the following step + // given a byte sequence bytes: return a new ArrayBuffer + // whose contents are bytes. + return specConsumeBody( + this, + (bytes) => { + return new Uint8Array(bytes).buffer + }, + instance + ) + }, + + text() { + // The text() method steps are to return the result of running + // consume body with this and UTF-8 decode. + return specConsumeBody(this, utf8DecodeBytes, instance) + }, + + json() { + // The json() method steps are to return the result of running + // consume body with this and parse JSON from bytes. + return specConsumeBody(this, parseJSONFromBytes, instance) + }, + + async formData() { + webidl.brandCheck(this, instance) + + throwIfAborted(this[kState]) + + const contentType = this.headers.get('Content-Type') + + // If mimeType’s essence is "multipart/form-data", then: + if (/multipart\/form-data/.test(contentType)) { + const headers = {} + for (const [key, value] of this.headers) + headers[key.toLowerCase()] = value + + const responseFormData = new FormData() + + let busboy + + try { + busboy = new Busboy({ + headers, + preservePath: true, + }) + } catch (err) { + throw new DOMException(`${err}`, 'AbortError') + } + + busboy.on('field', (name, value) => { + responseFormData.append(name, value) + }) + busboy.on('file', (name, value, filename, encoding, mimeType) => { + const chunks = [] + + if ( + encoding === 'base64' || + encoding.toLowerCase() === 'base64' + ) { + let base64chunk = '' + + value.on('data', (chunk) => { + base64chunk += chunk.toString().replace(/[\r\n]/gm, '') + + const end = base64chunk.length - (base64chunk.length % 4) + chunks.push( + Buffer.from(base64chunk.slice(0, end), 'base64') + ) + + base64chunk = base64chunk.slice(end) + }) + value.on('end', () => { + chunks.push(Buffer.from(base64chunk, 'base64')) + responseFormData.append( + name, + new File(chunks, filename, { type: mimeType }) + ) + }) + } else { + value.on('data', (chunk) => { + chunks.push(chunk) + }) + value.on('end', () => { + responseFormData.append( + name, + new File(chunks, filename, { type: mimeType }) + ) + }) + } + }) + + const busboyResolve = new Promise((resolve, reject) => { + busboy.on('finish', resolve) + busboy.on('error', (err) => reject(new TypeError(err))) + }) + + if (this.body !== null) + for await (const chunk of consumeBody(this[kState].body)) + busboy.write(chunk) + busboy.end() + await busboyResolve + + return responseFormData + } else if (/application\/x-www-form-urlencoded/.test(contentType)) { + // Otherwise, if mimeType’s essence is "application/x-www-form-urlencoded", then: + + // 1. Let entries be the result of parsing bytes. + let entries + try { + let text = '' + // application/x-www-form-urlencoded parser will keep the BOM. + // https://url.spec.whatwg.org/#concept-urlencoded-parser + // Note that streaming decoder is stateful and cannot be reused + const streamingDecoder = new TextDecoder('utf-8', { + ignoreBOM: true, + }) + + for await (const chunk of consumeBody(this[kState].body)) { + if (!isUint8Array(chunk)) { + throw new TypeError('Expected Uint8Array chunk') + } + text += streamingDecoder.decode(chunk, { stream: true }) + } + text += streamingDecoder.decode() + entries = new URLSearchParams(text) + } catch (err) { + // istanbul ignore next: Unclear when new URLSearchParams can fail on a string. + // 2. If entries is failure, then throw a TypeError. + throw Object.assign(new TypeError(), { cause: err }) + } + + // 3. Return a new FormData object whose entries are entries. + const formData = new FormData() + for (const [name, value] of entries) { + formData.append(name, value) + } + return formData + } else { + // Wait a tick before checking if the request has been aborted. + // Otherwise, a TypeError can be thrown when an AbortError should. + await Promise.resolve() + + throwIfAborted(this[kState]) + + // Otherwise, throw a TypeError. + throw webidl.errors.exception({ + header: `${instance.name}.formData`, + message: 'Could not parse content as FormData.', + }) + } + }, + } + + return methods + } + + function mixinBody(prototype) { + Object.assign(prototype.prototype, bodyMixinMethods(prototype)) + } + + /** + * @see https://fetch.spec.whatwg.org/#concept-body-consume-body + * @param {Response|Request} object + * @param {(value: unknown) => unknown} convertBytesToJSValue + * @param {Response|Request} instance + */ + async function specConsumeBody(object, convertBytesToJSValue, instance) { + webidl.brandCheck(object, instance) + + throwIfAborted(object[kState]) + + // 1. If object is unusable, then return a promise rejected + // with a TypeError. + if (bodyUnusable(object[kState].body)) { + throw new TypeError('Body is unusable') + } + + // 2. Let promise be a new promise. + const promise = createDeferredPromise() + + // 3. Let errorSteps given error be to reject promise with error. + const errorSteps = (error) => promise.reject(error) + + // 4. Let successSteps given a byte sequence data be to resolve + // promise with the result of running convertBytesToJSValue + // with data. If that threw an exception, then run errorSteps + // with that exception. + const successSteps = (data) => { + try { + promise.resolve(convertBytesToJSValue(data)) + } catch (e) { + errorSteps(e) + } + } + + // 5. If object’s body is null, then run successSteps with an + // empty byte sequence. + if (object[kState].body == null) { + successSteps(new Uint8Array()) + return promise.promise + } + + // 6. Otherwise, fully read object’s body given successSteps, + // errorSteps, and object’s relevant global object. + await fullyReadBody(object[kState].body, successSteps, errorSteps) + + // 7. Return promise. + return promise.promise + } + + // https://fetch.spec.whatwg.org/#body-unusable + function bodyUnusable(body) { + // An object including the Body interface mixin is + // said to be unusable if its body is non-null and + // its body’s stream is disturbed or locked. + return ( + body != null && (body.stream.locked || util.isDisturbed(body.stream)) + ) + } + + /** + * @see https://encoding.spec.whatwg.org/#utf-8-decode + * @param {Buffer} buffer + */ + function utf8DecodeBytes(buffer) { + if (buffer.length === 0) { + return '' + } + + // 1. Let buffer be the result of peeking three bytes from + // ioQueue, converted to a byte sequence. + + // 2. If buffer is 0xEF 0xBB 0xBF, then read three + // bytes from ioQueue. (Do nothing with those bytes.) + if (buffer[0] === 0xef && buffer[1] === 0xbb && buffer[2] === 0xbf) { + buffer = buffer.subarray(3) + } + + // 3. Process a queue with an instance of UTF-8’s + // decoder, ioQueue, output, and "replacement". + const output = textDecoder.decode(buffer) + + // 4. Return output. + return output + } + + /** + * @see https://infra.spec.whatwg.org/#parse-json-bytes-to-a-javascript-value + * @param {Uint8Array} bytes + */ + function parseJSONFromBytes(bytes) { + return JSON.parse(utf8DecodeBytes(bytes)) + } + + /** + * @see https://fetch.spec.whatwg.org/#concept-body-mime-type + * @param {import('./response').Response|import('./request').Request} object + */ + function bodyMimeType(object) { + const { headersList } = object[kState] + const contentType = headersList.get('content-type') + + if (contentType === null) { + return 'failure' + } + + return parseMIMEType(contentType) + } + + module.exports = { + extractBody, + safelyExtractBody, + cloneBody, + mixinBody, + } + + /***/ + }, + + /***/ 1037: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const { MessageChannel, receiveMessageOnPort } = __nccwpck_require__(1267) + + const corsSafeListedMethods = ['GET', 'HEAD', 'POST'] + const corsSafeListedMethodsSet = new Set(corsSafeListedMethods) + + const nullBodyStatus = [101, 204, 205, 304] + + const redirectStatus = [301, 302, 303, 307, 308] + const redirectStatusSet = new Set(redirectStatus) + + // https://fetch.spec.whatwg.org/#block-bad-port + const badPorts = [ + '1', + '7', + '9', + '11', + '13', + '15', + '17', + '19', + '20', + '21', + '22', + '23', + '25', + '37', + '42', + '43', + '53', + '69', + '77', + '79', + '87', + '95', + '101', + '102', + '103', + '104', + '109', + '110', + '111', + '113', + '115', + '117', + '119', + '123', + '135', + '137', + '139', + '143', + '161', + '179', + '389', + '427', + '465', + '512', + '513', + '514', + '515', + '526', + '530', + '531', + '532', + '540', + '548', + '554', + '556', + '563', + '587', + '601', + '636', + '989', + '990', + '993', + '995', + '1719', + '1720', + '1723', + '2049', + '3659', + '4045', + '5060', + '5061', + '6000', + '6566', + '6665', + '6666', + '6667', + '6668', + '6669', + '6697', + '10080', + ] + + const badPortsSet = new Set(badPorts) + + // https://w3c.github.io/webappsec-referrer-policy/#referrer-policies + const referrerPolicy = [ + '', + 'no-referrer', + 'no-referrer-when-downgrade', + 'same-origin', + 'origin', + 'strict-origin', + 'origin-when-cross-origin', + 'strict-origin-when-cross-origin', + 'unsafe-url', + ] + const referrerPolicySet = new Set(referrerPolicy) + + const requestRedirect = ['follow', 'manual', 'error'] + + const safeMethods = ['GET', 'HEAD', 'OPTIONS', 'TRACE'] + const safeMethodsSet = new Set(safeMethods) + + const requestMode = ['navigate', 'same-origin', 'no-cors', 'cors'] + + const requestCredentials = ['omit', 'same-origin', 'include'] + + const requestCache = [ + 'default', + 'no-store', + 'reload', + 'no-cache', + 'force-cache', + 'only-if-cached', + ] + + // https://fetch.spec.whatwg.org/#request-body-header-name + const requestBodyHeader = [ + 'content-encoding', + 'content-language', + 'content-location', + 'content-type', + // See https://github.com/nodejs/undici/issues/2021 + // 'Content-Length' is a forbidden header name, which is typically + // removed in the Headers implementation. However, undici doesn't + // filter out headers, so we add it here. + 'content-length', + ] + + // https://fetch.spec.whatwg.org/#enumdef-requestduplex + const requestDuplex = ['half'] + + // http://fetch.spec.whatwg.org/#forbidden-method + const forbiddenMethods = ['CONNECT', 'TRACE', 'TRACK'] + const forbiddenMethodsSet = new Set(forbiddenMethods) + + const subresource = [ + 'audio', + 'audioworklet', + 'font', + 'image', + 'manifest', + 'paintworklet', + 'script', + 'style', + 'track', + 'video', + 'xslt', + '', + ] + const subresourceSet = new Set(subresource) + + /** @type {globalThis['DOMException']} */ + const DOMException = + globalThis.DOMException ?? + (() => { + // DOMException was only made a global in Node v17.0.0, + // but fetch supports >= v16.8. + try { + atob('~') + } catch (err) { + return Object.getPrototypeOf(err).constructor + } + })() + + let channel + + /** @type {globalThis['structuredClone']} */ + const structuredClone = + globalThis.structuredClone ?? + // https://github.com/nodejs/node/blob/b27ae24dcc4251bad726d9d84baf678d1f707fed/lib/internal/structured_clone.js + // structuredClone was added in v17.0.0, but fetch supports v16.8 + function structuredClone(value, options = undefined) { + if (arguments.length === 0) { + throw new TypeError('missing argument') + } + + if (!channel) { + channel = new MessageChannel() + } + channel.port1.unref() + channel.port2.unref() + channel.port1.postMessage(value, options?.transfer) + return receiveMessageOnPort(channel.port2).message + } + + module.exports = { + DOMException, + structuredClone, + subresource, + forbiddenMethods, + requestBodyHeader, + referrerPolicy, + requestRedirect, + requestMode, + requestCredentials, + requestCache, + redirectStatus, + corsSafeListedMethods, + nullBodyStatus, + safeMethods, + badPorts, + requestDuplex, + subresourceSet, + badPortsSet, + redirectStatusSet, + corsSafeListedMethodsSet, + safeMethodsSet, + forbiddenMethodsSet, + referrerPolicySet, + } + + /***/ + }, + + /***/ 685: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + const assert = __nccwpck_require__(9491) + const { atob } = __nccwpck_require__(4300) + const { isomorphicDecode } = __nccwpck_require__(2538) + + const encoder = new TextEncoder() + + /** + * @see https://mimesniff.spec.whatwg.org/#http-token-code-point + */ + const HTTP_TOKEN_CODEPOINTS = /^[!#$%&'*+-.^_|~A-Za-z0-9]+$/ + const HTTP_WHITESPACE_REGEX = /(\u000A|\u000D|\u0009|\u0020)/ // eslint-disable-line + /** + * @see https://mimesniff.spec.whatwg.org/#http-quoted-string-token-code-point + */ + const HTTP_QUOTED_STRING_TOKENS = /[\u0009|\u0020-\u007E|\u0080-\u00FF]/ // eslint-disable-line + + // https://fetch.spec.whatwg.org/#data-url-processor + /** @param {URL} dataURL */ + function dataURLProcessor(dataURL) { + // 1. Assert: dataURL’s scheme is "data". + assert(dataURL.protocol === 'data:') + + // 2. Let input be the result of running the URL + // serializer on dataURL with exclude fragment + // set to true. + let input = URLSerializer(dataURL, true) + + // 3. Remove the leading "data:" string from input. + input = input.slice(5) + + // 4. Let position point at the start of input. + const position = { position: 0 } + + // 5. Let mimeType be the result of collecting a + // sequence of code points that are not equal + // to U+002C (,), given position. + let mimeType = collectASequenceOfCodePointsFast(',', input, position) + + // 6. Strip leading and trailing ASCII whitespace + // from mimeType. + // Undici implementation note: we need to store the + // length because if the mimetype has spaces removed, + // the wrong amount will be sliced from the input in + // step #9 + const mimeTypeLength = mimeType.length + mimeType = removeASCIIWhitespace(mimeType, true, true) + + // 7. If position is past the end of input, then + // return failure + if (position.position >= input.length) { + return 'failure' + } + + // 8. Advance position by 1. + position.position++ + + // 9. Let encodedBody be the remainder of input. + const encodedBody = input.slice(mimeTypeLength + 1) + + // 10. Let body be the percent-decoding of encodedBody. + let body = stringPercentDecode(encodedBody) + + // 11. If mimeType ends with U+003B (;), followed by + // zero or more U+0020 SPACE, followed by an ASCII + // case-insensitive match for "base64", then: + if (/;(\u0020){0,}base64$/i.test(mimeType)) { + // 1. Let stringBody be the isomorphic decode of body. + const stringBody = isomorphicDecode(body) + + // 2. Set body to the forgiving-base64 decode of + // stringBody. + body = forgivingBase64(stringBody) + + // 3. If body is failure, then return failure. + if (body === 'failure') { + return 'failure' + } + + // 4. Remove the last 6 code points from mimeType. + mimeType = mimeType.slice(0, -6) + + // 5. Remove trailing U+0020 SPACE code points from mimeType, + // if any. + mimeType = mimeType.replace(/(\u0020)+$/, '') + + // 6. Remove the last U+003B (;) code point from mimeType. + mimeType = mimeType.slice(0, -1) + } + + // 12. If mimeType starts with U+003B (;), then prepend + // "text/plain" to mimeType. + if (mimeType.startsWith(';')) { + mimeType = 'text/plain' + mimeType + } + + // 13. Let mimeTypeRecord be the result of parsing + // mimeType. + let mimeTypeRecord = parseMIMEType(mimeType) + + // 14. If mimeTypeRecord is failure, then set + // mimeTypeRecord to text/plain;charset=US-ASCII. + if (mimeTypeRecord === 'failure') { + mimeTypeRecord = parseMIMEType('text/plain;charset=US-ASCII') + } + + // 15. Return a new data: URL struct whose MIME + // type is mimeTypeRecord and body is body. + // https://fetch.spec.whatwg.org/#data-url-struct + return { mimeType: mimeTypeRecord, body } + } + + // https://url.spec.whatwg.org/#concept-url-serializer + /** + * @param {URL} url + * @param {boolean} excludeFragment + */ + function URLSerializer(url, excludeFragment = false) { + const href = url.href + + if (!excludeFragment) { + return href + } + + const hash = href.lastIndexOf('#') + if (hash === -1) { + return href + } + return href.slice(0, hash) + } + + // https://infra.spec.whatwg.org/#collect-a-sequence-of-code-points + /** + * @param {(char: string) => boolean} condition + * @param {string} input + * @param {{ position: number }} position + */ + function collectASequenceOfCodePoints(condition, input, position) { + // 1. Let result be the empty string. + let result = '' + + // 2. While position doesn’t point past the end of input and the + // code point at position within input meets the condition condition: + while ( + position.position < input.length && + condition(input[position.position]) + ) { + // 1. Append that code point to the end of result. + result += input[position.position] + + // 2. Advance position by 1. + position.position++ + } + + // 3. Return result. + return result + } + + /** + * A faster collectASequenceOfCodePoints that only works when comparing a single character. + * @param {string} char + * @param {string} input + * @param {{ position: number }} position + */ + function collectASequenceOfCodePointsFast(char, input, position) { + const idx = input.indexOf(char, position.position) + const start = position.position + + if (idx === -1) { + position.position = input.length + return input.slice(start) + } + + position.position = idx + return input.slice(start, position.position) + } + + // https://url.spec.whatwg.org/#string-percent-decode + /** @param {string} input */ + function stringPercentDecode(input) { + // 1. Let bytes be the UTF-8 encoding of input. + const bytes = encoder.encode(input) + + // 2. Return the percent-decoding of bytes. + return percentDecode(bytes) + } + + // https://url.spec.whatwg.org/#percent-decode + /** @param {Uint8Array} input */ + function percentDecode(input) { + // 1. Let output be an empty byte sequence. + /** @type {number[]} */ + const output = [] + + // 2. For each byte byte in input: + for (let i = 0; i < input.length; i++) { + const byte = input[i] + + // 1. If byte is not 0x25 (%), then append byte to output. + if (byte !== 0x25) { + output.push(byte) + + // 2. Otherwise, if byte is 0x25 (%) and the next two bytes + // after byte in input are not in the ranges + // 0x30 (0) to 0x39 (9), 0x41 (A) to 0x46 (F), + // and 0x61 (a) to 0x66 (f), all inclusive, append byte + // to output. + } else if ( + byte === 0x25 && + !/^[0-9A-Fa-f]{2}$/i.test( + String.fromCharCode(input[i + 1], input[i + 2]) + ) + ) { + output.push(0x25) + + // 3. Otherwise: + } else { + // 1. Let bytePoint be the two bytes after byte in input, + // decoded, and then interpreted as hexadecimal number. + const nextTwoBytes = String.fromCharCode(input[i + 1], input[i + 2]) + const bytePoint = Number.parseInt(nextTwoBytes, 16) + + // 2. Append a byte whose value is bytePoint to output. + output.push(bytePoint) + + // 3. Skip the next two bytes in input. + i += 2 + } + } + + // 3. Return output. + return Uint8Array.from(output) + } + + // https://mimesniff.spec.whatwg.org/#parse-a-mime-type + /** @param {string} input */ + function parseMIMEType(input) { + // 1. Remove any leading and trailing HTTP whitespace + // from input. + input = removeHTTPWhitespace(input, true, true) + + // 2. Let position be a position variable for input, + // initially pointing at the start of input. + const position = { position: 0 } + + // 3. Let type be the result of collecting a sequence + // of code points that are not U+002F (/) from + // input, given position. + const type = collectASequenceOfCodePointsFast('/', input, position) + + // 4. If type is the empty string or does not solely + // contain HTTP token code points, then return failure. + // https://mimesniff.spec.whatwg.org/#http-token-code-point + if (type.length === 0 || !HTTP_TOKEN_CODEPOINTS.test(type)) { + return 'failure' + } + + // 5. If position is past the end of input, then return + // failure + if (position.position > input.length) { + return 'failure' + } + + // 6. Advance position by 1. (This skips past U+002F (/).) + position.position++ + + // 7. Let subtype be the result of collecting a sequence of + // code points that are not U+003B (;) from input, given + // position. + let subtype = collectASequenceOfCodePointsFast(';', input, position) + + // 8. Remove any trailing HTTP whitespace from subtype. + subtype = removeHTTPWhitespace(subtype, false, true) + + // 9. If subtype is the empty string or does not solely + // contain HTTP token code points, then return failure. + if (subtype.length === 0 || !HTTP_TOKEN_CODEPOINTS.test(subtype)) { + return 'failure' + } + + const typeLowercase = type.toLowerCase() + const subtypeLowercase = subtype.toLowerCase() + + // 10. Let mimeType be a new MIME type record whose type + // is type, in ASCII lowercase, and subtype is subtype, + // in ASCII lowercase. + // https://mimesniff.spec.whatwg.org/#mime-type + const mimeType = { + type: typeLowercase, + subtype: subtypeLowercase, + /** @type {Map} */ + parameters: new Map(), + // https://mimesniff.spec.whatwg.org/#mime-type-essence + essence: `${typeLowercase}/${subtypeLowercase}`, + } + + // 11. While position is not past the end of input: + while (position.position < input.length) { + // 1. Advance position by 1. (This skips past U+003B (;).) + position.position++ + + // 2. Collect a sequence of code points that are HTTP + // whitespace from input given position. + collectASequenceOfCodePoints( + // https://fetch.spec.whatwg.org/#http-whitespace + (char) => HTTP_WHITESPACE_REGEX.test(char), + input, + position + ) + + // 3. Let parameterName be the result of collecting a + // sequence of code points that are not U+003B (;) + // or U+003D (=) from input, given position. + let parameterName = collectASequenceOfCodePoints( + (char) => char !== ';' && char !== '=', + input, + position + ) + + // 4. Set parameterName to parameterName, in ASCII + // lowercase. + parameterName = parameterName.toLowerCase() + + // 5. If position is not past the end of input, then: + if (position.position < input.length) { + // 1. If the code point at position within input is + // U+003B (;), then continue. + if (input[position.position] === ';') { + continue + } + + // 2. Advance position by 1. (This skips past U+003D (=).) + position.position++ + } + + // 6. If position is past the end of input, then break. + if (position.position > input.length) { + break + } + + // 7. Let parameterValue be null. + let parameterValue = null + + // 8. If the code point at position within input is + // U+0022 ("), then: + if (input[position.position] === '"') { + // 1. Set parameterValue to the result of collecting + // an HTTP quoted string from input, given position + // and the extract-value flag. + parameterValue = collectAnHTTPQuotedString(input, position, true) + + // 2. Collect a sequence of code points that are not + // U+003B (;) from input, given position. + collectASequenceOfCodePointsFast(';', input, position) + + // 9. Otherwise: + } else { + // 1. Set parameterValue to the result of collecting + // a sequence of code points that are not U+003B (;) + // from input, given position. + parameterValue = collectASequenceOfCodePointsFast( + ';', + input, + position + ) + + // 2. Remove any trailing HTTP whitespace from parameterValue. + parameterValue = removeHTTPWhitespace(parameterValue, false, true) + + // 3. If parameterValue is the empty string, then continue. + if (parameterValue.length === 0) { + continue + } + } + + // 10. If all of the following are true + // - parameterName is not the empty string + // - parameterName solely contains HTTP token code points + // - parameterValue solely contains HTTP quoted-string token code points + // - mimeType’s parameters[parameterName] does not exist + // then set mimeType’s parameters[parameterName] to parameterValue. + if ( + parameterName.length !== 0 && + HTTP_TOKEN_CODEPOINTS.test(parameterName) && + (parameterValue.length === 0 || + HTTP_QUOTED_STRING_TOKENS.test(parameterValue)) && + !mimeType.parameters.has(parameterName) + ) { + mimeType.parameters.set(parameterName, parameterValue) + } + } + + // 12. Return mimeType. + return mimeType + } + + // https://infra.spec.whatwg.org/#forgiving-base64-decode + /** @param {string} data */ + function forgivingBase64(data) { + // 1. Remove all ASCII whitespace from data. + data = data.replace(/[\u0009\u000A\u000C\u000D\u0020]/g, '') // eslint-disable-line + + // 2. If data’s code point length divides by 4 leaving + // no remainder, then: + if (data.length % 4 === 0) { + // 1. If data ends with one or two U+003D (=) code points, + // then remove them from data. + data = data.replace(/=?=$/, '') + } + + // 3. If data’s code point length divides by 4 leaving + // a remainder of 1, then return failure. + if (data.length % 4 === 1) { + return 'failure' + } + + // 4. If data contains a code point that is not one of + // U+002B (+) + // U+002F (/) + // ASCII alphanumeric + // then return failure. + if (/[^+/0-9A-Za-z]/.test(data)) { + return 'failure' + } + + const binary = atob(data) + const bytes = new Uint8Array(binary.length) + + for (let byte = 0; byte < binary.length; byte++) { + bytes[byte] = binary.charCodeAt(byte) + } + + return bytes + } + + // https://fetch.spec.whatwg.org/#collect-an-http-quoted-string + // tests: https://fetch.spec.whatwg.org/#example-http-quoted-string + /** + * @param {string} input + * @param {{ position: number }} position + * @param {boolean?} extractValue + */ + function collectAnHTTPQuotedString(input, position, extractValue) { + // 1. Let positionStart be position. + const positionStart = position.position + + // 2. Let value be the empty string. + let value = '' + + // 3. Assert: the code point at position within input + // is U+0022 ("). + assert(input[position.position] === '"') + + // 4. Advance position by 1. + position.position++ + + // 5. While true: + while (true) { + // 1. Append the result of collecting a sequence of code points + // that are not U+0022 (") or U+005C (\) from input, given + // position, to value. + value += collectASequenceOfCodePoints( + (char) => char !== '"' && char !== '\\', + input, + position + ) + + // 2. If position is past the end of input, then break. + if (position.position >= input.length) { + break + } + + // 3. Let quoteOrBackslash be the code point at position within + // input. + const quoteOrBackslash = input[position.position] + + // 4. Advance position by 1. + position.position++ + + // 5. If quoteOrBackslash is U+005C (\), then: + if (quoteOrBackslash === '\\') { + // 1. If position is past the end of input, then append + // U+005C (\) to value and break. + if (position.position >= input.length) { + value += '\\' + break + } + + // 2. Append the code point at position within input to value. + value += input[position.position] + + // 3. Advance position by 1. + position.position++ + + // 6. Otherwise: + } else { + // 1. Assert: quoteOrBackslash is U+0022 ("). + assert(quoteOrBackslash === '"') + + // 2. Break. + break + } + } + + // 6. If the extract-value flag is set, then return value. + if (extractValue) { + return value + } + + // 7. Return the code points from positionStart to position, + // inclusive, within input. + return input.slice(positionStart, position.position) + } + + /** + * @see https://mimesniff.spec.whatwg.org/#serialize-a-mime-type + */ + function serializeAMimeType(mimeType) { + assert(mimeType !== 'failure') + const { parameters, essence } = mimeType + + // 1. Let serialization be the concatenation of mimeType’s + // type, U+002F (/), and mimeType’s subtype. + let serialization = essence + + // 2. For each name → value of mimeType’s parameters: + for (let [name, value] of parameters.entries()) { + // 1. Append U+003B (;) to serialization. + serialization += ';' + + // 2. Append name to serialization. + serialization += name + + // 3. Append U+003D (=) to serialization. + serialization += '=' + + // 4. If value does not solely contain HTTP token code + // points or value is the empty string, then: + if (!HTTP_TOKEN_CODEPOINTS.test(value)) { + // 1. Precede each occurence of U+0022 (") or + // U+005C (\) in value with U+005C (\). + value = value.replace(/(\\|")/g, '\\$1') + + // 2. Prepend U+0022 (") to value. + value = '"' + value + + // 3. Append U+0022 (") to value. + value += '"' + } + + // 5. Append value to serialization. + serialization += value + } + + // 3. Return serialization. + return serialization + } + + /** + * @see https://fetch.spec.whatwg.org/#http-whitespace + * @param {string} char + */ + function isHTTPWhiteSpace(char) { + return char === '\r' || char === '\n' || char === '\t' || char === ' ' + } + + /** + * @see https://fetch.spec.whatwg.org/#http-whitespace + * @param {string} str + */ + function removeHTTPWhitespace(str, leading = true, trailing = true) { + let lead = 0 + let trail = str.length - 1 + + if (leading) { + for (; lead < str.length && isHTTPWhiteSpace(str[lead]); lead++); + } + + if (trailing) { + for (; trail > 0 && isHTTPWhiteSpace(str[trail]); trail--); + } + + return str.slice(lead, trail + 1) + } + + /** + * @see https://infra.spec.whatwg.org/#ascii-whitespace + * @param {string} char + */ + function isASCIIWhitespace(char) { + return ( + char === '\r' || + char === '\n' || + char === '\t' || + char === '\f' || + char === ' ' + ) + } + + /** + * @see https://infra.spec.whatwg.org/#strip-leading-and-trailing-ascii-whitespace + */ + function removeASCIIWhitespace(str, leading = true, trailing = true) { + let lead = 0 + let trail = str.length - 1 + + if (leading) { + for (; lead < str.length && isASCIIWhitespace(str[lead]); lead++); + } + + if (trailing) { + for (; trail > 0 && isASCIIWhitespace(str[trail]); trail--); + } + + return str.slice(lead, trail + 1) + } + + module.exports = { + dataURLProcessor, + URLSerializer, + collectASequenceOfCodePoints, + collectASequenceOfCodePointsFast, + stringPercentDecode, + parseMIMEType, + collectAnHTTPQuotedString, + serializeAMimeType, + } + + /***/ + }, + + /***/ 8511: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const { Blob, File: NativeFile } = __nccwpck_require__(4300) + const { types } = __nccwpck_require__(3837) + const { kState } = __nccwpck_require__(5861) + const { isBlobLike } = __nccwpck_require__(2538) + const { webidl } = __nccwpck_require__(1744) + const { parseMIMEType, serializeAMimeType } = __nccwpck_require__(685) + const { kEnumerableProperty } = __nccwpck_require__(3983) + const encoder = new TextEncoder() + + class File extends Blob { + constructor(fileBits, fileName, options = {}) { + // The File constructor is invoked with two or three parameters, depending + // on whether the optional dictionary parameter is used. When the File() + // constructor is invoked, user agents must run the following steps: + webidl.argumentLengthCheck(arguments, 2, { + header: 'File constructor', + }) + + fileBits = webidl.converters['sequence'](fileBits) + fileName = webidl.converters.USVString(fileName) + options = webidl.converters.FilePropertyBag(options) + + // 1. Let bytes be the result of processing blob parts given fileBits and + // options. + // Note: Blob handles this for us + + // 2. Let n be the fileName argument to the constructor. + const n = fileName + + // 3. Process FilePropertyBag dictionary argument by running the following + // substeps: + + // 1. If the type member is provided and is not the empty string, let t + // be set to the type dictionary member. If t contains any characters + // outside the range U+0020 to U+007E, then set t to the empty string + // and return from these substeps. + // 2. Convert every character in t to ASCII lowercase. + let t = options.type + let d + + // eslint-disable-next-line no-labels + substep: { + if (t) { + t = parseMIMEType(t) + + if (t === 'failure') { + t = '' + // eslint-disable-next-line no-labels + break substep + } + + t = serializeAMimeType(t).toLowerCase() + } + + // 3. If the lastModified member is provided, let d be set to the + // lastModified dictionary member. If it is not provided, set d to the + // current date and time represented as the number of milliseconds since + // the Unix Epoch (which is the equivalent of Date.now() [ECMA-262]). + d = options.lastModified + } + + // 4. Return a new File object F such that: + // F refers to the bytes byte sequence. + // F.size is set to the number of total bytes in bytes. + // F.name is set to n. + // F.type is set to t. + // F.lastModified is set to d. + + super(processBlobParts(fileBits, options), { type: t }) + this[kState] = { + name: n, + lastModified: d, + type: t, + } + } + + get name() { + webidl.brandCheck(this, File) + + return this[kState].name + } + + get lastModified() { + webidl.brandCheck(this, File) + + return this[kState].lastModified + } + + get type() { + webidl.brandCheck(this, File) + + return this[kState].type + } + } + + class FileLike { + constructor(blobLike, fileName, options = {}) { + // TODO: argument idl type check + + // The File constructor is invoked with two or three parameters, depending + // on whether the optional dictionary parameter is used. When the File() + // constructor is invoked, user agents must run the following steps: + + // 1. Let bytes be the result of processing blob parts given fileBits and + // options. + + // 2. Let n be the fileName argument to the constructor. + const n = fileName + + // 3. Process FilePropertyBag dictionary argument by running the following + // substeps: + + // 1. If the type member is provided and is not the empty string, let t + // be set to the type dictionary member. If t contains any characters + // outside the range U+0020 to U+007E, then set t to the empty string + // and return from these substeps. + // TODO + const t = options.type + + // 2. Convert every character in t to ASCII lowercase. + // TODO + + // 3. If the lastModified member is provided, let d be set to the + // lastModified dictionary member. If it is not provided, set d to the + // current date and time represented as the number of milliseconds since + // the Unix Epoch (which is the equivalent of Date.now() [ECMA-262]). + const d = options.lastModified ?? Date.now() + + // 4. Return a new File object F such that: + // F refers to the bytes byte sequence. + // F.size is set to the number of total bytes in bytes. + // F.name is set to n. + // F.type is set to t. + // F.lastModified is set to d. + + this[kState] = { + blobLike, + name: n, + type: t, + lastModified: d, + } + } + + stream(...args) { + webidl.brandCheck(this, FileLike) + + return this[kState].blobLike.stream(...args) + } + + arrayBuffer(...args) { + webidl.brandCheck(this, FileLike) + + return this[kState].blobLike.arrayBuffer(...args) + } + + slice(...args) { + webidl.brandCheck(this, FileLike) + + return this[kState].blobLike.slice(...args) + } + + text(...args) { + webidl.brandCheck(this, FileLike) + + return this[kState].blobLike.text(...args) + } + + get size() { + webidl.brandCheck(this, FileLike) + + return this[kState].blobLike.size + } + + get type() { + webidl.brandCheck(this, FileLike) + + return this[kState].blobLike.type + } + + get name() { + webidl.brandCheck(this, FileLike) + + return this[kState].name + } + + get lastModified() { + webidl.brandCheck(this, FileLike) + + return this[kState].lastModified + } + + get [Symbol.toStringTag]() { + return 'File' + } + } + + Object.defineProperties(File.prototype, { + [Symbol.toStringTag]: { + value: 'File', + configurable: true, + }, + name: kEnumerableProperty, + lastModified: kEnumerableProperty, + }) + + webidl.converters.Blob = webidl.interfaceConverter(Blob) + + webidl.converters.BlobPart = function (V, opts) { + if (webidl.util.Type(V) === 'Object') { + if (isBlobLike(V)) { + return webidl.converters.Blob(V, { strict: false }) + } + + if (ArrayBuffer.isView(V) || types.isAnyArrayBuffer(V)) { + return webidl.converters.BufferSource(V, opts) + } + } + + return webidl.converters.USVString(V, opts) + } + + webidl.converters['sequence'] = webidl.sequenceConverter( + webidl.converters.BlobPart + ) + + // https://www.w3.org/TR/FileAPI/#dfn-FilePropertyBag + webidl.converters.FilePropertyBag = webidl.dictionaryConverter([ + { + key: 'lastModified', + converter: webidl.converters['long long'], + get defaultValue() { + return Date.now() + }, + }, + { + key: 'type', + converter: webidl.converters.DOMString, + defaultValue: '', + }, + { + key: 'endings', + converter: (value) => { + value = webidl.converters.DOMString(value) + value = value.toLowerCase() + + if (value !== 'native') { + value = 'transparent' + } + + return value + }, + defaultValue: 'transparent', + }, + ]) + + /** + * @see https://www.w3.org/TR/FileAPI/#process-blob-parts + * @param {(NodeJS.TypedArray|Blob|string)[]} parts + * @param {{ type: string, endings: string }} options + */ + function processBlobParts(parts, options) { + // 1. Let bytes be an empty sequence of bytes. + /** @type {NodeJS.TypedArray[]} */ + const bytes = [] + + // 2. For each element in parts: + for (const element of parts) { + // 1. If element is a USVString, run the following substeps: + if (typeof element === 'string') { + // 1. Let s be element. + let s = element + + // 2. If the endings member of options is "native", set s + // to the result of converting line endings to native + // of element. + if (options.endings === 'native') { + s = convertLineEndingsNative(s) + } + + // 3. Append the result of UTF-8 encoding s to bytes. + bytes.push(encoder.encode(s)) + } else if ( + types.isAnyArrayBuffer(element) || + types.isTypedArray(element) + ) { + // 2. If element is a BufferSource, get a copy of the + // bytes held by the buffer source, and append those + // bytes to bytes. + if (!element.buffer) { + // ArrayBuffer + bytes.push(new Uint8Array(element)) + } else { + bytes.push( + new Uint8Array( + element.buffer, + element.byteOffset, + element.byteLength + ) + ) + } + } else if (isBlobLike(element)) { + // 3. If element is a Blob, append the bytes it represents + // to bytes. + bytes.push(element) + } + } + + // 3. Return bytes. + return bytes + } + + /** + * @see https://www.w3.org/TR/FileAPI/#convert-line-endings-to-native + * @param {string} s + */ + function convertLineEndingsNative(s) { + // 1. Let native line ending be be the code point U+000A LF. + let nativeLineEnding = '\n' + + // 2. If the underlying platform’s conventions are to + // represent newlines as a carriage return and line feed + // sequence, set native line ending to the code point + // U+000D CR followed by the code point U+000A LF. + if (process.platform === 'win32') { + nativeLineEnding = '\r\n' + } + + return s.replace(/\r?\n/g, nativeLineEnding) + } + + // If this function is moved to ./util.js, some tools (such as + // rollup) will warn about circular dependencies. See: + // https://github.com/nodejs/undici/issues/1629 + function isFileLike(object) { + return ( + (NativeFile && object instanceof NativeFile) || + object instanceof File || + (object && + (typeof object.stream === 'function' || + typeof object.arrayBuffer === 'function') && + object[Symbol.toStringTag] === 'File') + ) + } + + module.exports = { File, FileLike, isFileLike } + + /***/ + }, + + /***/ 2015: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const { isBlobLike, toUSVString, makeIterator } = + __nccwpck_require__(2538) + const { kState } = __nccwpck_require__(5861) + const { + File: UndiciFile, + FileLike, + isFileLike, + } = __nccwpck_require__(8511) + const { webidl } = __nccwpck_require__(1744) + const { Blob, File: NativeFile } = __nccwpck_require__(4300) + + /** @type {globalThis['File']} */ + const File = NativeFile ?? UndiciFile + + // https://xhr.spec.whatwg.org/#formdata + class FormData { + constructor(form) { + if (form !== undefined) { + throw webidl.errors.conversionFailed({ + prefix: 'FormData constructor', + argument: 'Argument 1', + types: ['undefined'], + }) + } + + this[kState] = [] + } + + append(name, value, filename = undefined) { + webidl.brandCheck(this, FormData) + + webidl.argumentLengthCheck(arguments, 2, { + header: 'FormData.append', + }) + + if (arguments.length === 3 && !isBlobLike(value)) { + throw new TypeError( + "Failed to execute 'append' on 'FormData': parameter 2 is not of type 'Blob'" + ) + } + + // 1. Let value be value if given; otherwise blobValue. + + name = webidl.converters.USVString(name) + value = isBlobLike(value) + ? webidl.converters.Blob(value, { strict: false }) + : webidl.converters.USVString(value) + filename = + arguments.length === 3 + ? webidl.converters.USVString(filename) + : undefined + + // 2. Let entry be the result of creating an entry with + // name, value, and filename if given. + const entry = makeEntry(name, value, filename) + + // 3. Append entry to this’s entry list. + this[kState].push(entry) + } + + delete(name) { + webidl.brandCheck(this, FormData) + + webidl.argumentLengthCheck(arguments, 1, { + header: 'FormData.delete', + }) + + name = webidl.converters.USVString(name) + + // The delete(name) method steps are to remove all entries whose name + // is name from this’s entry list. + this[kState] = this[kState].filter((entry) => entry.name !== name) + } + + get(name) { + webidl.brandCheck(this, FormData) + + webidl.argumentLengthCheck(arguments, 1, { header: 'FormData.get' }) + + name = webidl.converters.USVString(name) + + // 1. If there is no entry whose name is name in this’s entry list, + // then return null. + const idx = this[kState].findIndex((entry) => entry.name === name) + if (idx === -1) { + return null + } + + // 2. Return the value of the first entry whose name is name from + // this’s entry list. + return this[kState][idx].value + } + + getAll(name) { + webidl.brandCheck(this, FormData) + + webidl.argumentLengthCheck(arguments, 1, { + header: 'FormData.getAll', + }) + + name = webidl.converters.USVString(name) + + // 1. If there is no entry whose name is name in this’s entry list, + // then return the empty list. + // 2. Return the values of all entries whose name is name, in order, + // from this’s entry list. + return this[kState] + .filter((entry) => entry.name === name) + .map((entry) => entry.value) + } + + has(name) { + webidl.brandCheck(this, FormData) + + webidl.argumentLengthCheck(arguments, 1, { header: 'FormData.has' }) + + name = webidl.converters.USVString(name) + + // The has(name) method steps are to return true if there is an entry + // whose name is name in this’s entry list; otherwise false. + return this[kState].findIndex((entry) => entry.name === name) !== -1 + } + + set(name, value, filename = undefined) { + webidl.brandCheck(this, FormData) + + webidl.argumentLengthCheck(arguments, 2, { header: 'FormData.set' }) + + if (arguments.length === 3 && !isBlobLike(value)) { + throw new TypeError( + "Failed to execute 'set' on 'FormData': parameter 2 is not of type 'Blob'" + ) + } + + // The set(name, value) and set(name, blobValue, filename) method steps + // are: + + // 1. Let value be value if given; otherwise blobValue. + + name = webidl.converters.USVString(name) + value = isBlobLike(value) + ? webidl.converters.Blob(value, { strict: false }) + : webidl.converters.USVString(value) + filename = arguments.length === 3 ? toUSVString(filename) : undefined + + // 2. Let entry be the result of creating an entry with name, value, and + // filename if given. + const entry = makeEntry(name, value, filename) + + // 3. If there are entries in this’s entry list whose name is name, then + // replace the first such entry with entry and remove the others. + const idx = this[kState].findIndex((entry) => entry.name === name) + if (idx !== -1) { + this[kState] = [ + ...this[kState].slice(0, idx), + entry, + ...this[kState] + .slice(idx + 1) + .filter((entry) => entry.name !== name), + ] + } else { + // 4. Otherwise, append entry to this’s entry list. + this[kState].push(entry) + } + } + + entries() { + webidl.brandCheck(this, FormData) + + return makeIterator( + () => this[kState].map((pair) => [pair.name, pair.value]), + 'FormData', + 'key+value' + ) + } + + keys() { + webidl.brandCheck(this, FormData) + + return makeIterator( + () => this[kState].map((pair) => [pair.name, pair.value]), + 'FormData', + 'key' + ) + } + + values() { + webidl.brandCheck(this, FormData) + + return makeIterator( + () => this[kState].map((pair) => [pair.name, pair.value]), + 'FormData', + 'value' + ) + } + + /** + * @param {(value: string, key: string, self: FormData) => void} callbackFn + * @param {unknown} thisArg + */ + forEach(callbackFn, thisArg = globalThis) { + webidl.brandCheck(this, FormData) + + webidl.argumentLengthCheck(arguments, 1, { + header: 'FormData.forEach', + }) + + if (typeof callbackFn !== 'function') { + throw new TypeError( + "Failed to execute 'forEach' on 'FormData': parameter 1 is not of type 'Function'." + ) + } + + for (const [key, value] of this) { + callbackFn.apply(thisArg, [value, key, this]) + } + } + } + + FormData.prototype[Symbol.iterator] = FormData.prototype.entries + + Object.defineProperties(FormData.prototype, { + [Symbol.toStringTag]: { + value: 'FormData', + configurable: true, + }, + }) + + /** + * @see https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#create-an-entry + * @param {string} name + * @param {string|Blob} value + * @param {?string} filename + * @returns + */ + function makeEntry(name, value, filename) { + // 1. Set name to the result of converting name into a scalar value string. + // "To convert a string into a scalar value string, replace any surrogates + // with U+FFFD." + // see: https://nodejs.org/dist/latest-v18.x/docs/api/buffer.html#buftostringencoding-start-end + name = Buffer.from(name).toString('utf8') + + // 2. If value is a string, then set value to the result of converting + // value into a scalar value string. + if (typeof value === 'string') { + value = Buffer.from(value).toString('utf8') + } else { + // 3. Otherwise: + + // 1. If value is not a File object, then set value to a new File object, + // representing the same bytes, whose name attribute value is "blob" + if (!isFileLike(value)) { + value = + value instanceof Blob + ? new File([value], 'blob', { type: value.type }) + : new FileLike(value, 'blob', { type: value.type }) + } + + // 2. If filename is given, then set value to a new File object, + // representing the same bytes, whose name attribute is filename. + if (filename !== undefined) { + /** @type {FilePropertyBag} */ + const options = { + type: value.type, + lastModified: value.lastModified, + } + + value = + (NativeFile && value instanceof NativeFile) || + value instanceof UndiciFile + ? new File([value], filename, options) + : new FileLike(value, filename, options) + } + } + + // 4. Return an entry whose name is name and whose value is value. + return { name, value } + } + + module.exports = { FormData } + + /***/ + }, + + /***/ 1246: /***/ (module) => { + 'use strict' + + // In case of breaking changes, increase the version + // number to avoid conflicts. + const globalOrigin = Symbol.for('undici.globalOrigin.1') + + function getGlobalOrigin() { + return globalThis[globalOrigin] + } + + function setGlobalOrigin(newOrigin) { + if (newOrigin === undefined) { + Object.defineProperty(globalThis, globalOrigin, { + value: undefined, + writable: true, + enumerable: false, + configurable: false, + }) + + return + } + + const parsedURL = new URL(newOrigin) + + if (parsedURL.protocol !== 'http:' && parsedURL.protocol !== 'https:') { + throw new TypeError( + `Only http & https urls are allowed, received ${parsedURL.protocol}` + ) + } + + Object.defineProperty(globalThis, globalOrigin, { + value: parsedURL, + writable: true, + enumerable: false, + configurable: false, + }) + } + + module.exports = { + getGlobalOrigin, + setGlobalOrigin, + } + + /***/ + }, + + /***/ 554: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + // https://github.com/Ethan-Arrowood/undici-fetch + + const { kHeadersList } = __nccwpck_require__(2785) + const { kGuard } = __nccwpck_require__(5861) + const { kEnumerableProperty } = __nccwpck_require__(3983) + const { makeIterator, isValidHeaderName, isValidHeaderValue } = + __nccwpck_require__(2538) + const { webidl } = __nccwpck_require__(1744) + const assert = __nccwpck_require__(9491) + + const kHeadersMap = Symbol('headers map') + const kHeadersSortedMap = Symbol('headers map sorted') + + /** + * @see https://fetch.spec.whatwg.org/#concept-header-value-normalize + * @param {string} potentialValue + */ + function headerValueNormalize(potentialValue) { + // To normalize a byte sequence potentialValue, remove + // any leading and trailing HTTP whitespace bytes from + // potentialValue. + + // Trimming the end with `.replace()` and a RegExp is typically subject to + // ReDoS. This is safer and faster. + let i = potentialValue.length + while (/[\r\n\t ]/.test(potentialValue.charAt(--i))); + return potentialValue.slice(0, i + 1).replace(/^[\r\n\t ]+/, '') + } + + function fill(headers, object) { + // To fill a Headers object headers with a given object object, run these steps: + + // 1. If object is a sequence, then for each header in object: + // Note: webidl conversion to array has already been done. + if (Array.isArray(object)) { + for (const header of object) { + // 1. If header does not contain exactly two items, then throw a TypeError. + if (header.length !== 2) { + throw webidl.errors.exception({ + header: 'Headers constructor', + message: `expected name/value pair to be length 2, found ${header.length}.`, + }) + } + + // 2. Append (header’s first item, header’s second item) to headers. + headers.append(header[0], header[1]) + } + } else if (typeof object === 'object' && object !== null) { + // Note: null should throw + + // 2. Otherwise, object is a record, then for each key → value in object, + // append (key, value) to headers + for (const [key, value] of Object.entries(object)) { + headers.append(key, value) + } + } else { + throw webidl.errors.conversionFailed({ + prefix: 'Headers constructor', + argument: 'Argument 1', + types: [ + 'sequence>', + 'record', + ], + }) + } + } + + class HeadersList { + /** @type {[string, string][]|null} */ + cookies = null + + constructor(init) { + if (init instanceof HeadersList) { + this[kHeadersMap] = new Map(init[kHeadersMap]) + this[kHeadersSortedMap] = init[kHeadersSortedMap] + this.cookies = init.cookies + } else { + this[kHeadersMap] = new Map(init) + this[kHeadersSortedMap] = null + } + } + + // https://fetch.spec.whatwg.org/#header-list-contains + contains(name) { + // A header list list contains a header name name if list + // contains a header whose name is a byte-case-insensitive + // match for name. + name = name.toLowerCase() + + return this[kHeadersMap].has(name) + } + + clear() { + this[kHeadersMap].clear() + this[kHeadersSortedMap] = null + this.cookies = null + } + + // https://fetch.spec.whatwg.org/#concept-header-list-append + append(name, value) { + this[kHeadersSortedMap] = null + + // 1. If list contains name, then set name to the first such + // header’s name. + const lowercaseName = name.toLowerCase() + const exists = this[kHeadersMap].get(lowercaseName) + + // 2. Append (name, value) to list. + if (exists) { + const delimiter = lowercaseName === 'cookie' ? '; ' : ', ' + this[kHeadersMap].set(lowercaseName, { + name: exists.name, + value: `${exists.value}${delimiter}${value}`, + }) + } else { + this[kHeadersMap].set(lowercaseName, { name, value }) + } + + if (lowercaseName === 'set-cookie') { + this.cookies ??= [] + this.cookies.push(value) + } + } + + // https://fetch.spec.whatwg.org/#concept-header-list-set + set(name, value) { + this[kHeadersSortedMap] = null + const lowercaseName = name.toLowerCase() + + if (lowercaseName === 'set-cookie') { + this.cookies = [value] + } + + // 1. If list contains name, then set the value of + // the first such header to value and remove the + // others. + // 2. Otherwise, append header (name, value) to list. + return this[kHeadersMap].set(lowercaseName, { name, value }) + } + + // https://fetch.spec.whatwg.org/#concept-header-list-delete + delete(name) { + this[kHeadersSortedMap] = null + + name = name.toLowerCase() + + if (name === 'set-cookie') { + this.cookies = null + } + + return this[kHeadersMap].delete(name) + } + + // https://fetch.spec.whatwg.org/#concept-header-list-get + get(name) { + // 1. If list does not contain name, then return null. + if (!this.contains(name)) { + return null + } + + // 2. Return the values of all headers in list whose name + // is a byte-case-insensitive match for name, + // separated from each other by 0x2C 0x20, in order. + return this[kHeadersMap].get(name.toLowerCase())?.value ?? null + } + + *[Symbol.iterator]() { + // use the lowercased name + for (const [name, { value }] of this[kHeadersMap]) { + yield [name, value] + } + } + + get entries() { + const headers = {} + + if (this[kHeadersMap].size) { + for (const { name, value } of this[kHeadersMap].values()) { + headers[name] = value + } + } + + return headers + } + } + + // https://fetch.spec.whatwg.org/#headers-class + class Headers { + constructor(init = undefined) { + this[kHeadersList] = new HeadersList() + + // The new Headers(init) constructor steps are: + + // 1. Set this’s guard to "none". + this[kGuard] = 'none' + + // 2. If init is given, then fill this with init. + if (init !== undefined) { + init = webidl.converters.HeadersInit(init) + fill(this, init) + } + } + + // https://fetch.spec.whatwg.org/#dom-headers-append + append(name, value) { + webidl.brandCheck(this, Headers) + + webidl.argumentLengthCheck(arguments, 2, { header: 'Headers.append' }) + + name = webidl.converters.ByteString(name) + value = webidl.converters.ByteString(value) + + // 1. Normalize value. + value = headerValueNormalize(value) + + // 2. If name is not a header name or value is not a + // header value, then throw a TypeError. + if (!isValidHeaderName(name)) { + throw webidl.errors.invalidArgument({ + prefix: 'Headers.append', + value: name, + type: 'header name', + }) + } else if (!isValidHeaderValue(value)) { + throw webidl.errors.invalidArgument({ + prefix: 'Headers.append', + value, + type: 'header value', + }) + } + + // 3. If headers’s guard is "immutable", then throw a TypeError. + // 4. Otherwise, if headers’s guard is "request" and name is a + // forbidden header name, return. + // Note: undici does not implement forbidden header names + if (this[kGuard] === 'immutable') { + throw new TypeError('immutable') + } else if (this[kGuard] === 'request-no-cors') { + // 5. Otherwise, if headers’s guard is "request-no-cors": + // TODO + } + + // 6. Otherwise, if headers’s guard is "response" and name is a + // forbidden response-header name, return. + + // 7. Append (name, value) to headers’s header list. + // 8. If headers’s guard is "request-no-cors", then remove + // privileged no-CORS request headers from headers + return this[kHeadersList].append(name, value) + } + + // https://fetch.spec.whatwg.org/#dom-headers-delete + delete(name) { + webidl.brandCheck(this, Headers) + + webidl.argumentLengthCheck(arguments, 1, { header: 'Headers.delete' }) + + name = webidl.converters.ByteString(name) + + // 1. If name is not a header name, then throw a TypeError. + if (!isValidHeaderName(name)) { + throw webidl.errors.invalidArgument({ + prefix: 'Headers.delete', + value: name, + type: 'header name', + }) + } + + // 2. If this’s guard is "immutable", then throw a TypeError. + // 3. Otherwise, if this’s guard is "request" and name is a + // forbidden header name, return. + // 4. Otherwise, if this’s guard is "request-no-cors", name + // is not a no-CORS-safelisted request-header name, and + // name is not a privileged no-CORS request-header name, + // return. + // 5. Otherwise, if this’s guard is "response" and name is + // a forbidden response-header name, return. + // Note: undici does not implement forbidden header names + if (this[kGuard] === 'immutable') { + throw new TypeError('immutable') + } else if (this[kGuard] === 'request-no-cors') { + // TODO + } + + // 6. If this’s header list does not contain name, then + // return. + if (!this[kHeadersList].contains(name)) { + return + } + + // 7. Delete name from this’s header list. + // 8. If this’s guard is "request-no-cors", then remove + // privileged no-CORS request headers from this. + return this[kHeadersList].delete(name) + } + + // https://fetch.spec.whatwg.org/#dom-headers-get + get(name) { + webidl.brandCheck(this, Headers) + + webidl.argumentLengthCheck(arguments, 1, { header: 'Headers.get' }) + + name = webidl.converters.ByteString(name) + + // 1. If name is not a header name, then throw a TypeError. + if (!isValidHeaderName(name)) { + throw webidl.errors.invalidArgument({ + prefix: 'Headers.get', + value: name, + type: 'header name', + }) + } + + // 2. Return the result of getting name from this’s header + // list. + return this[kHeadersList].get(name) + } + + // https://fetch.spec.whatwg.org/#dom-headers-has + has(name) { + webidl.brandCheck(this, Headers) + + webidl.argumentLengthCheck(arguments, 1, { header: 'Headers.has' }) + + name = webidl.converters.ByteString(name) + + // 1. If name is not a header name, then throw a TypeError. + if (!isValidHeaderName(name)) { + throw webidl.errors.invalidArgument({ + prefix: 'Headers.has', + value: name, + type: 'header name', + }) + } + + // 2. Return true if this’s header list contains name; + // otherwise false. + return this[kHeadersList].contains(name) + } + + // https://fetch.spec.whatwg.org/#dom-headers-set + set(name, value) { + webidl.brandCheck(this, Headers) + + webidl.argumentLengthCheck(arguments, 2, { header: 'Headers.set' }) + + name = webidl.converters.ByteString(name) + value = webidl.converters.ByteString(value) + + // 1. Normalize value. + value = headerValueNormalize(value) + + // 2. If name is not a header name or value is not a + // header value, then throw a TypeError. + if (!isValidHeaderName(name)) { + throw webidl.errors.invalidArgument({ + prefix: 'Headers.set', + value: name, + type: 'header name', + }) + } else if (!isValidHeaderValue(value)) { + throw webidl.errors.invalidArgument({ + prefix: 'Headers.set', + value, + type: 'header value', + }) + } + + // 3. If this’s guard is "immutable", then throw a TypeError. + // 4. Otherwise, if this’s guard is "request" and name is a + // forbidden header name, return. + // 5. Otherwise, if this’s guard is "request-no-cors" and + // name/value is not a no-CORS-safelisted request-header, + // return. + // 6. Otherwise, if this’s guard is "response" and name is a + // forbidden response-header name, return. + // Note: undici does not implement forbidden header names + if (this[kGuard] === 'immutable') { + throw new TypeError('immutable') + } else if (this[kGuard] === 'request-no-cors') { + // TODO + } + + // 7. Set (name, value) in this’s header list. + // 8. If this’s guard is "request-no-cors", then remove + // privileged no-CORS request headers from this + return this[kHeadersList].set(name, value) + } + + // https://fetch.spec.whatwg.org/#dom-headers-getsetcookie + getSetCookie() { + webidl.brandCheck(this, Headers) + + // 1. If this’s header list does not contain `Set-Cookie`, then return « ». + // 2. Return the values of all headers in this’s header list whose name is + // a byte-case-insensitive match for `Set-Cookie`, in order. + + const list = this[kHeadersList].cookies + + if (list) { + return [...list] + } + + return [] + } + + // https://fetch.spec.whatwg.org/#concept-header-list-sort-and-combine + get [kHeadersSortedMap]() { + if (this[kHeadersList][kHeadersSortedMap]) { + return this[kHeadersList][kHeadersSortedMap] + } + + // 1. Let headers be an empty list of headers with the key being the name + // and value the value. + const headers = [] + + // 2. Let names be the result of convert header names to a sorted-lowercase + // set with all the names of the headers in list. + const names = [...this[kHeadersList]].sort((a, b) => + a[0] < b[0] ? -1 : 1 + ) + const cookies = this[kHeadersList].cookies + + // 3. For each name of names: + for (const [name, value] of names) { + // 1. If name is `set-cookie`, then: + if (name === 'set-cookie') { + // 1. Let values be a list of all values of headers in list whose name + // is a byte-case-insensitive match for name, in order. + + // 2. For each value of values: + // 1. Append (name, value) to headers. + for (const value of cookies) { + headers.push([name, value]) + } + } else { + // 2. Otherwise: + + // 1. Let value be the result of getting name from list. + + // 2. Assert: value is non-null. + assert(value !== null) + + // 3. Append (name, value) to headers. + headers.push([name, value]) + } + } + + this[kHeadersList][kHeadersSortedMap] = headers + + // 4. Return headers. + return headers + } + + keys() { + webidl.brandCheck(this, Headers) + + return makeIterator( + () => [...this[kHeadersSortedMap].values()], + 'Headers', + 'key' + ) + } + + values() { + webidl.brandCheck(this, Headers) + + return makeIterator( + () => [...this[kHeadersSortedMap].values()], + 'Headers', + 'value' + ) + } + + entries() { + webidl.brandCheck(this, Headers) + + return makeIterator( + () => [...this[kHeadersSortedMap].values()], + 'Headers', + 'key+value' + ) + } + + /** + * @param {(value: string, key: string, self: Headers) => void} callbackFn + * @param {unknown} thisArg + */ + forEach(callbackFn, thisArg = globalThis) { + webidl.brandCheck(this, Headers) + + webidl.argumentLengthCheck(arguments, 1, { + header: 'Headers.forEach', + }) + + if (typeof callbackFn !== 'function') { + throw new TypeError( + "Failed to execute 'forEach' on 'Headers': parameter 1 is not of type 'Function'." + ) + } + + for (const [key, value] of this) { + callbackFn.apply(thisArg, [value, key, this]) + } + } + + [Symbol.for('nodejs.util.inspect.custom')]() { + webidl.brandCheck(this, Headers) + + return this[kHeadersList] + } + } + + Headers.prototype[Symbol.iterator] = Headers.prototype.entries + + Object.defineProperties(Headers.prototype, { + append: kEnumerableProperty, + delete: kEnumerableProperty, + get: kEnumerableProperty, + has: kEnumerableProperty, + set: kEnumerableProperty, + getSetCookie: kEnumerableProperty, + keys: kEnumerableProperty, + values: kEnumerableProperty, + entries: kEnumerableProperty, + forEach: kEnumerableProperty, + [Symbol.iterator]: { enumerable: false }, + [Symbol.toStringTag]: { + value: 'Headers', + configurable: true, + }, + }) + + webidl.converters.HeadersInit = function (V) { + if (webidl.util.Type(V) === 'Object') { + if (V[Symbol.iterator]) { + return webidl.converters['sequence>'](V) + } + + return webidl.converters['record'](V) + } + + throw webidl.errors.conversionFailed({ + prefix: 'Headers constructor', + argument: 'Argument 1', + types: [ + 'sequence>', + 'record', + ], + }) + } + + module.exports = { + fill, + Headers, + HeadersList, + } + + /***/ + }, + + /***/ 4881: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + // https://github.com/Ethan-Arrowood/undici-fetch + + const { + Response, + makeNetworkError, + makeAppropriateNetworkError, + filterResponse, + makeResponse, + } = __nccwpck_require__(7823) + const { Headers } = __nccwpck_require__(554) + const { Request, makeRequest } = __nccwpck_require__(8359) + const zlib = __nccwpck_require__(9796) + const { + bytesMatch, + makePolicyContainer, + clonePolicyContainer, + requestBadPort, + TAOCheck, + appendRequestOriginHeader, + responseLocationURL, + requestCurrentURL, + setRequestReferrerPolicyOnRedirect, + tryUpgradeRequestToAPotentiallyTrustworthyURL, + createOpaqueTimingInfo, + appendFetchMetadata, + corsCheck, + crossOriginResourcePolicyCheck, + determineRequestsReferrer, + coarsenedSharedCurrentTime, + createDeferredPromise, + isBlobLike, + sameOrigin, + isCancelled, + isAborted, + isErrorLike, + fullyReadBody, + readableStreamClose, + isomorphicEncode, + urlIsLocal, + urlIsHttpHttpsScheme, + urlHasHttpsScheme, + } = __nccwpck_require__(2538) + const { kState, kHeaders, kGuard, kRealm } = __nccwpck_require__(5861) + const assert = __nccwpck_require__(9491) + const { safelyExtractBody } = __nccwpck_require__(1472) + const { + redirectStatusSet, + nullBodyStatus, + safeMethodsSet, + requestBodyHeader, + subresourceSet, + DOMException, + } = __nccwpck_require__(1037) + const { kHeadersList } = __nccwpck_require__(2785) + const EE = __nccwpck_require__(2361) + const { Readable, pipeline } = __nccwpck_require__(2781) + const { addAbortListener, isErrored, isReadable, nodeMajor, nodeMinor } = + __nccwpck_require__(3983) + const { dataURLProcessor, serializeAMimeType } = __nccwpck_require__(685) + const { TransformStream } = __nccwpck_require__(5356) + const { getGlobalDispatcher } = __nccwpck_require__(1892) + const { webidl } = __nccwpck_require__(1744) + const { STATUS_CODES } = __nccwpck_require__(3685) + const GET_OR_HEAD = ['GET', 'HEAD'] + + /** @type {import('buffer').resolveObjectURL} */ + let resolveObjectURL + let ReadableStream = globalThis.ReadableStream + + class Fetch extends EE { + constructor(dispatcher) { + super() + + this.dispatcher = dispatcher + this.connection = null + this.dump = false + this.state = 'ongoing' + // 2 terminated listeners get added per request, + // but only 1 gets removed. If there are 20 redirects, + // 21 listeners will be added. + // See https://github.com/nodejs/undici/issues/1711 + // TODO (fix): Find and fix root cause for leaked listener. + this.setMaxListeners(21) + } + + terminate(reason) { + if (this.state !== 'ongoing') { + return + } + + this.state = 'terminated' + this.connection?.destroy(reason) + this.emit('terminated', reason) + } + + // https://fetch.spec.whatwg.org/#fetch-controller-abort + abort(error) { + if (this.state !== 'ongoing') { + return + } + + // 1. Set controller’s state to "aborted". + this.state = 'aborted' + + // 2. Let fallbackError be an "AbortError" DOMException. + // 3. Set error to fallbackError if it is not given. + if (!error) { + error = new DOMException('The operation was aborted.', 'AbortError') + } + + // 4. Let serializedError be StructuredSerialize(error). + // If that threw an exception, catch it, and let + // serializedError be StructuredSerialize(fallbackError). + + // 5. Set controller’s serialized abort reason to serializedError. + this.serializedAbortReason = error + + this.connection?.destroy(error) + this.emit('terminated', error) + } + } + + // https://fetch.spec.whatwg.org/#fetch-method + function fetch(input, init = {}) { + webidl.argumentLengthCheck(arguments, 1, { header: 'globalThis.fetch' }) + + // 1. Let p be a new promise. + const p = createDeferredPromise() + + // 2. Let requestObject be the result of invoking the initial value of + // Request as constructor with input and init as arguments. If this throws + // an exception, reject p with it and return p. + let requestObject + + try { + requestObject = new Request(input, init) + } catch (e) { + p.reject(e) + return p.promise + } + + // 3. Let request be requestObject’s request. + const request = requestObject[kState] + + // 4. If requestObject’s signal’s aborted flag is set, then: + if (requestObject.signal.aborted) { + // 1. Abort the fetch() call with p, request, null, and + // requestObject’s signal’s abort reason. + abortFetch(p, request, null, requestObject.signal.reason) + + // 2. Return p. + return p.promise + } + + // 5. Let globalObject be request’s client’s global object. + const globalObject = request.client.globalObject + + // 6. If globalObject is a ServiceWorkerGlobalScope object, then set + // request’s service-workers mode to "none". + if (globalObject?.constructor?.name === 'ServiceWorkerGlobalScope') { + request.serviceWorkers = 'none' + } + + // 7. Let responseObject be null. + let responseObject = null + + // 8. Let relevantRealm be this’s relevant Realm. + const relevantRealm = null + + // 9. Let locallyAborted be false. + let locallyAborted = false + + // 10. Let controller be null. + let controller = null + + // 11. Add the following abort steps to requestObject’s signal: + addAbortListener(requestObject.signal, () => { + // 1. Set locallyAborted to true. + locallyAborted = true + + // 2. Assert: controller is non-null. + assert(controller != null) + + // 3. Abort controller with requestObject’s signal’s abort reason. + controller.abort(requestObject.signal.reason) + + // 4. Abort the fetch() call with p, request, responseObject, + // and requestObject’s signal’s abort reason. + abortFetch(p, request, responseObject, requestObject.signal.reason) + }) + + // 12. Let handleFetchDone given response response be to finalize and + // report timing with response, globalObject, and "fetch". + const handleFetchDone = (response) => + finalizeAndReportTiming(response, 'fetch') + + // 13. Set controller to the result of calling fetch given request, + // with processResponseEndOfBody set to handleFetchDone, and processResponse + // given response being these substeps: + + const processResponse = (response) => { + // 1. If locallyAborted is true, terminate these substeps. + if (locallyAborted) { + return Promise.resolve() + } + + // 2. If response’s aborted flag is set, then: + if (response.aborted) { + // 1. Let deserializedError be the result of deserialize a serialized + // abort reason given controller’s serialized abort reason and + // relevantRealm. + + // 2. Abort the fetch() call with p, request, responseObject, and + // deserializedError. + + abortFetch( + p, + request, + responseObject, + controller.serializedAbortReason + ) + return Promise.resolve() + } + + // 3. If response is a network error, then reject p with a TypeError + // and terminate these substeps. + if (response.type === 'error') { + p.reject( + Object.assign(new TypeError('fetch failed'), { + cause: response.error, + }) + ) + return Promise.resolve() + } + + // 4. Set responseObject to the result of creating a Response object, + // given response, "immutable", and relevantRealm. + responseObject = new Response() + responseObject[kState] = response + responseObject[kRealm] = relevantRealm + responseObject[kHeaders][kHeadersList] = response.headersList + responseObject[kHeaders][kGuard] = 'immutable' + responseObject[kHeaders][kRealm] = relevantRealm + + // 5. Resolve p with responseObject. + p.resolve(responseObject) + } + + controller = fetching({ + request, + processResponseEndOfBody: handleFetchDone, + processResponse, + dispatcher: init.dispatcher ?? getGlobalDispatcher(), // undici + }) + + // 14. Return p. + return p.promise + } + + // https://fetch.spec.whatwg.org/#finalize-and-report-timing + function finalizeAndReportTiming(response, initiatorType = 'other') { + // 1. If response is an aborted network error, then return. + if (response.type === 'error' && response.aborted) { + return + } + + // 2. If response’s URL list is null or empty, then return. + if (!response.urlList?.length) { + return + } + + // 3. Let originalURL be response’s URL list[0]. + const originalURL = response.urlList[0] + + // 4. Let timingInfo be response’s timing info. + let timingInfo = response.timingInfo + + // 5. Let cacheState be response’s cache state. + let cacheState = response.cacheState + + // 6. If originalURL’s scheme is not an HTTP(S) scheme, then return. + if (!urlIsHttpHttpsScheme(originalURL)) { + return + } + + // 7. If timingInfo is null, then return. + if (timingInfo === null) { + return + } + + // 8. If response’s timing allow passed flag is not set, then: + if (!timingInfo.timingAllowPassed) { + // 1. Set timingInfo to a the result of creating an opaque timing info for timingInfo. + timingInfo = createOpaqueTimingInfo({ + startTime: timingInfo.startTime, + }) + + // 2. Set cacheState to the empty string. + cacheState = '' + } + + // 9. Set timingInfo’s end time to the coarsened shared current time + // given global’s relevant settings object’s cross-origin isolated + // capability. + // TODO: given global’s relevant settings object’s cross-origin isolated + // capability? + timingInfo.endTime = coarsenedSharedCurrentTime() + + // 10. Set response’s timing info to timingInfo. + response.timingInfo = timingInfo + + // 11. Mark resource timing for timingInfo, originalURL, initiatorType, + // global, and cacheState. + markResourceTiming( + timingInfo, + originalURL, + initiatorType, + globalThis, + cacheState + ) + } + + // https://w3c.github.io/resource-timing/#dfn-mark-resource-timing + function markResourceTiming( + timingInfo, + originalURL, + initiatorType, + globalThis, + cacheState + ) { + if (nodeMajor > 18 || (nodeMajor === 18 && nodeMinor >= 2)) { + performance.markResourceTiming( + timingInfo, + originalURL.href, + initiatorType, + globalThis, + cacheState + ) + } + } + + // https://fetch.spec.whatwg.org/#abort-fetch + function abortFetch(p, request, responseObject, error) { + // Note: AbortSignal.reason was added in node v17.2.0 + // which would give us an undefined error to reject with. + // Remove this once node v16 is no longer supported. + if (!error) { + error = new DOMException('The operation was aborted.', 'AbortError') + } + + // 1. Reject promise with error. + p.reject(error) + + // 2. If request’s body is not null and is readable, then cancel request’s + // body with error. + if (request.body != null && isReadable(request.body?.stream)) { + request.body.stream.cancel(error).catch((err) => { + if (err.code === 'ERR_INVALID_STATE') { + // Node bug? + return + } + throw err + }) + } + + // 3. If responseObject is null, then return. + if (responseObject == null) { + return + } + + // 4. Let response be responseObject’s response. + const response = responseObject[kState] + + // 5. If response’s body is not null and is readable, then error response’s + // body with error. + if (response.body != null && isReadable(response.body?.stream)) { + response.body.stream.cancel(error).catch((err) => { + if (err.code === 'ERR_INVALID_STATE') { + // Node bug? + return + } + throw err + }) + } + } + + // https://fetch.spec.whatwg.org/#fetching + function fetching({ + request, + processRequestBodyChunkLength, + processRequestEndOfBody, + processResponse, + processResponseEndOfBody, + processResponseConsumeBody, + useParallelQueue = false, + dispatcher, // undici + }) { + // 1. Let taskDestination be null. + let taskDestination = null + + // 2. Let crossOriginIsolatedCapability be false. + let crossOriginIsolatedCapability = false + + // 3. If request’s client is non-null, then: + if (request.client != null) { + // 1. Set taskDestination to request’s client’s global object. + taskDestination = request.client.globalObject + + // 2. Set crossOriginIsolatedCapability to request’s client’s cross-origin + // isolated capability. + crossOriginIsolatedCapability = + request.client.crossOriginIsolatedCapability + } + + // 4. If useParallelQueue is true, then set taskDestination to the result of + // starting a new parallel queue. + // TODO + + // 5. Let timingInfo be a new fetch timing info whose start time and + // post-redirect start time are the coarsened shared current time given + // crossOriginIsolatedCapability. + const currenTime = coarsenedSharedCurrentTime( + crossOriginIsolatedCapability + ) + const timingInfo = createOpaqueTimingInfo({ + startTime: currenTime, + }) + + // 6. Let fetchParams be a new fetch params whose + // request is request, + // timing info is timingInfo, + // process request body chunk length is processRequestBodyChunkLength, + // process request end-of-body is processRequestEndOfBody, + // process response is processResponse, + // process response consume body is processResponseConsumeBody, + // process response end-of-body is processResponseEndOfBody, + // task destination is taskDestination, + // and cross-origin isolated capability is crossOriginIsolatedCapability. + const fetchParams = { + controller: new Fetch(dispatcher), + request, + timingInfo, + processRequestBodyChunkLength, + processRequestEndOfBody, + processResponse, + processResponseConsumeBody, + processResponseEndOfBody, + taskDestination, + crossOriginIsolatedCapability, + } + + // 7. If request’s body is a byte sequence, then set request’s body to + // request’s body as a body. + // NOTE: Since fetching is only called from fetch, body should already be + // extracted. + assert(!request.body || request.body.stream) + + // 8. If request’s window is "client", then set request’s window to request’s + // client, if request’s client’s global object is a Window object; otherwise + // "no-window". + if (request.window === 'client') { + // TODO: What if request.client is null? + request.window = + request.client?.globalObject?.constructor?.name === 'Window' + ? request.client + : 'no-window' + } + + // 9. If request’s origin is "client", then set request’s origin to request’s + // client’s origin. + if (request.origin === 'client') { + // TODO: What if request.client is null? + request.origin = request.client?.origin + } + + // 10. If all of the following conditions are true: + // TODO + + // 11. If request’s policy container is "client", then: + if (request.policyContainer === 'client') { + // 1. If request’s client is non-null, then set request’s policy + // container to a clone of request’s client’s policy container. [HTML] + if (request.client != null) { + request.policyContainer = clonePolicyContainer( + request.client.policyContainer + ) + } else { + // 2. Otherwise, set request’s policy container to a new policy + // container. + request.policyContainer = makePolicyContainer() + } + } + + // 12. If request’s header list does not contain `Accept`, then: + if (!request.headersList.contains('accept')) { + // 1. Let value be `*/*`. + const value = '*/*' + + // 2. A user agent should set value to the first matching statement, if + // any, switching on request’s destination: + // "document" + // "frame" + // "iframe" + // `text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8` + // "image" + // `image/png,image/svg+xml,image/*;q=0.8,*/*;q=0.5` + // "style" + // `text/css,*/*;q=0.1` + // TODO + + // 3. Append `Accept`/value to request’s header list. + request.headersList.append('accept', value) + } + + // 13. If request’s header list does not contain `Accept-Language`, then + // user agents should append `Accept-Language`/an appropriate value to + // request’s header list. + if (!request.headersList.contains('accept-language')) { + request.headersList.append('accept-language', '*') + } + + // 14. If request’s priority is null, then use request’s initiator and + // destination appropriately in setting request’s priority to a + // user-agent-defined object. + if (request.priority === null) { + // TODO + } + + // 15. If request is a subresource request, then: + if (subresourceSet.has(request.destination)) { + // TODO + } + + // 16. Run main fetch given fetchParams. + mainFetch(fetchParams).catch((err) => { + fetchParams.controller.terminate(err) + }) + + // 17. Return fetchParam's controller + return fetchParams.controller + } + + // https://fetch.spec.whatwg.org/#concept-main-fetch + async function mainFetch(fetchParams, recursive = false) { + // 1. Let request be fetchParams’s request. + const request = fetchParams.request + + // 2. Let response be null. + let response = null + + // 3. If request’s local-URLs-only flag is set and request’s current URL is + // not local, then set response to a network error. + if (request.localURLsOnly && !urlIsLocal(requestCurrentURL(request))) { + response = makeNetworkError('local URLs only') + } + + // 4. Run report Content Security Policy violations for request. + // TODO + + // 5. Upgrade request to a potentially trustworthy URL, if appropriate. + tryUpgradeRequestToAPotentiallyTrustworthyURL(request) + + // 6. If should request be blocked due to a bad port, should fetching request + // be blocked as mixed content, or should request be blocked by Content + // Security Policy returns blocked, then set response to a network error. + if (requestBadPort(request) === 'blocked') { + response = makeNetworkError('bad port') + } + // TODO: should fetching request be blocked as mixed content? + // TODO: should request be blocked by Content Security Policy? + + // 7. If request’s referrer policy is the empty string, then set request’s + // referrer policy to request’s policy container’s referrer policy. + if (request.referrerPolicy === '') { + request.referrerPolicy = request.policyContainer.referrerPolicy + } + + // 8. If request’s referrer is not "no-referrer", then set request’s + // referrer to the result of invoking determine request’s referrer. + if (request.referrer !== 'no-referrer') { + request.referrer = determineRequestsReferrer(request) + } + + // 9. Set request’s current URL’s scheme to "https" if all of the following + // conditions are true: + // - request’s current URL’s scheme is "http" + // - request’s current URL’s host is a domain + // - Matching request’s current URL’s host per Known HSTS Host Domain Name + // Matching results in either a superdomain match with an asserted + // includeSubDomains directive or a congruent match (with or without an + // asserted includeSubDomains directive). [HSTS] + // TODO + + // 10. If recursive is false, then run the remaining steps in parallel. + // TODO + + // 11. If response is null, then set response to the result of running + // the steps corresponding to the first matching statement: + if (response === null) { + response = await (async () => { + const currentURL = requestCurrentURL(request) + + if ( + // - request’s current URL’s origin is same origin with request’s origin, + // and request’s response tainting is "basic" + (sameOrigin(currentURL, request.url) && + request.responseTainting === 'basic') || + // request’s current URL’s scheme is "data" + currentURL.protocol === 'data:' || + // - request’s mode is "navigate" or "websocket" + request.mode === 'navigate' || + request.mode === 'websocket' + ) { + // 1. Set request’s response tainting to "basic". + request.responseTainting = 'basic' + + // 2. Return the result of running scheme fetch given fetchParams. + return await schemeFetch(fetchParams) + } + + // request’s mode is "same-origin" + if (request.mode === 'same-origin') { + // 1. Return a network error. + return makeNetworkError('request mode cannot be "same-origin"') + } + + // request’s mode is "no-cors" + if (request.mode === 'no-cors') { + // 1. If request’s redirect mode is not "follow", then return a network + // error. + if (request.redirect !== 'follow') { + return makeNetworkError( + 'redirect mode cannot be "follow" for "no-cors" request' + ) + } + + // 2. Set request’s response tainting to "opaque". + request.responseTainting = 'opaque' + + // 3. Return the result of running scheme fetch given fetchParams. + return await schemeFetch(fetchParams) + } + + // request’s current URL’s scheme is not an HTTP(S) scheme + if (!urlIsHttpHttpsScheme(requestCurrentURL(request))) { + // Return a network error. + return makeNetworkError('URL scheme must be a HTTP(S) scheme') + } + + // - request’s use-CORS-preflight flag is set + // - request’s unsafe-request flag is set and either request’s method is + // not a CORS-safelisted method or CORS-unsafe request-header names with + // request’s header list is not empty + // 1. Set request’s response tainting to "cors". + // 2. Let corsWithPreflightResponse be the result of running HTTP fetch + // given fetchParams and true. + // 3. If corsWithPreflightResponse is a network error, then clear cache + // entries using request. + // 4. Return corsWithPreflightResponse. + // TODO + + // Otherwise + // 1. Set request’s response tainting to "cors". + request.responseTainting = 'cors' + + // 2. Return the result of running HTTP fetch given fetchParams. + return await httpFetch(fetchParams) + })() + } + + // 12. If recursive is true, then return response. + if (recursive) { + return response + } + + // 13. If response is not a network error and response is not a filtered + // response, then: + if (response.status !== 0 && !response.internalResponse) { + // If request’s response tainting is "cors", then: + if (request.responseTainting === 'cors') { + // 1. Let headerNames be the result of extracting header list values + // given `Access-Control-Expose-Headers` and response’s header list. + // TODO + // 2. If request’s credentials mode is not "include" and headerNames + // contains `*`, then set response’s CORS-exposed header-name list to + // all unique header names in response’s header list. + // TODO + // 3. Otherwise, if headerNames is not null or failure, then set + // response’s CORS-exposed header-name list to headerNames. + // TODO + } + + // Set response to the following filtered response with response as its + // internal response, depending on request’s response tainting: + if (request.responseTainting === 'basic') { + response = filterResponse(response, 'basic') + } else if (request.responseTainting === 'cors') { + response = filterResponse(response, 'cors') + } else if (request.responseTainting === 'opaque') { + response = filterResponse(response, 'opaque') + } else { + assert(false) + } + } + + // 14. Let internalResponse be response, if response is a network error, + // and response’s internal response otherwise. + let internalResponse = + response.status === 0 ? response : response.internalResponse + + // 15. If internalResponse’s URL list is empty, then set it to a clone of + // request’s URL list. + if (internalResponse.urlList.length === 0) { + internalResponse.urlList.push(...request.urlList) + } + + // 16. If request’s timing allow failed flag is unset, then set + // internalResponse’s timing allow passed flag. + if (!request.timingAllowFailed) { + response.timingAllowPassed = true + } + + // 17. If response is not a network error and any of the following returns + // blocked + // - should internalResponse to request be blocked as mixed content + // - should internalResponse to request be blocked by Content Security Policy + // - should internalResponse to request be blocked due to its MIME type + // - should internalResponse to request be blocked due to nosniff + // TODO + + // 18. If response’s type is "opaque", internalResponse’s status is 206, + // internalResponse’s range-requested flag is set, and request’s header + // list does not contain `Range`, then set response and internalResponse + // to a network error. + if ( + response.type === 'opaque' && + internalResponse.status === 206 && + internalResponse.rangeRequested && + !request.headers.contains('range') + ) { + response = internalResponse = makeNetworkError() + } + + // 19. If response is not a network error and either request’s method is + // `HEAD` or `CONNECT`, or internalResponse’s status is a null body status, + // set internalResponse’s body to null and disregard any enqueuing toward + // it (if any). + if ( + response.status !== 0 && + (request.method === 'HEAD' || + request.method === 'CONNECT' || + nullBodyStatus.includes(internalResponse.status)) + ) { + internalResponse.body = null + fetchParams.controller.dump = true + } + + // 20. If request’s integrity metadata is not the empty string, then: + if (request.integrity) { + // 1. Let processBodyError be this step: run fetch finale given fetchParams + // and a network error. + const processBodyError = (reason) => + fetchFinale(fetchParams, makeNetworkError(reason)) + + // 2. If request’s response tainting is "opaque", or response’s body is null, + // then run processBodyError and abort these steps. + if (request.responseTainting === 'opaque' || response.body == null) { + processBodyError(response.error) + return + } + + // 3. Let processBody given bytes be these steps: + const processBody = (bytes) => { + // 1. If bytes do not match request’s integrity metadata, + // then run processBodyError and abort these steps. [SRI] + if (!bytesMatch(bytes, request.integrity)) { + processBodyError('integrity mismatch') + return + } + + // 2. Set response’s body to bytes as a body. + response.body = safelyExtractBody(bytes)[0] + + // 3. Run fetch finale given fetchParams and response. + fetchFinale(fetchParams, response) + } + + // 4. Fully read response’s body given processBody and processBodyError. + await fullyReadBody(response.body, processBody, processBodyError) + } else { + // 21. Otherwise, run fetch finale given fetchParams and response. + fetchFinale(fetchParams, response) + } + } + + // https://fetch.spec.whatwg.org/#concept-scheme-fetch + // given a fetch params fetchParams + function schemeFetch(fetchParams) { + // Note: since the connection is destroyed on redirect, which sets fetchParams to a + // cancelled state, we do not want this condition to trigger *unless* there have been + // no redirects. See https://github.com/nodejs/undici/issues/1776 + // 1. If fetchParams is canceled, then return the appropriate network error for fetchParams. + if ( + isCancelled(fetchParams) && + fetchParams.request.redirectCount === 0 + ) { + return Promise.resolve(makeAppropriateNetworkError(fetchParams)) + } + + // 2. Let request be fetchParams’s request. + const { request } = fetchParams + + const { protocol: scheme } = requestCurrentURL(request) + + // 3. Switch on request’s current URL’s scheme and run the associated steps: + switch (scheme) { + case 'about:': { + // If request’s current URL’s path is the string "blank", then return a new response + // whose status message is `OK`, header list is « (`Content-Type`, `text/html;charset=utf-8`) », + // and body is the empty byte sequence as a body. + + // Otherwise, return a network error. + return Promise.resolve( + makeNetworkError('about scheme is not supported') + ) + } + case 'blob:': { + if (!resolveObjectURL) { + resolveObjectURL = __nccwpck_require__(4300).resolveObjectURL + } + + // 1. Let blobURLEntry be request’s current URL’s blob URL entry. + const blobURLEntry = requestCurrentURL(request) + + // https://github.com/web-platform-tests/wpt/blob/7b0ebaccc62b566a1965396e5be7bb2bc06f841f/FileAPI/url/resources/fetch-tests.js#L52-L56 + // Buffer.resolveObjectURL does not ignore URL queries. + if (blobURLEntry.search.length !== 0) { + return Promise.resolve( + makeNetworkError( + 'NetworkError when attempting to fetch resource.' + ) + ) + } + + const blobURLEntryObject = resolveObjectURL(blobURLEntry.toString()) + + // 2. If request’s method is not `GET`, blobURLEntry is null, or blobURLEntry’s + // object is not a Blob object, then return a network error. + if (request.method !== 'GET' || !isBlobLike(blobURLEntryObject)) { + return Promise.resolve(makeNetworkError('invalid method')) + } + + // 3. Let bodyWithType be the result of safely extracting blobURLEntry’s object. + const bodyWithType = safelyExtractBody(blobURLEntryObject) + + // 4. Let body be bodyWithType’s body. + const body = bodyWithType[0] + + // 5. Let length be body’s length, serialized and isomorphic encoded. + const length = isomorphicEncode(`${body.length}`) + + // 6. Let type be bodyWithType’s type if it is non-null; otherwise the empty byte sequence. + const type = bodyWithType[1] ?? '' + + // 7. Return a new response whose status message is `OK`, header list is + // « (`Content-Length`, length), (`Content-Type`, type) », and body is body. + const response = makeResponse({ + statusText: 'OK', + headersList: [ + ['content-length', { name: 'Content-Length', value: length }], + ['content-type', { name: 'Content-Type', value: type }], + ], + }) + + response.body = body + + return Promise.resolve(response) + } + case 'data:': { + // 1. Let dataURLStruct be the result of running the + // data: URL processor on request’s current URL. + const currentURL = requestCurrentURL(request) + const dataURLStruct = dataURLProcessor(currentURL) + + // 2. If dataURLStruct is failure, then return a + // network error. + if (dataURLStruct === 'failure') { + return Promise.resolve( + makeNetworkError('failed to fetch the data URL') + ) + } + + // 3. Let mimeType be dataURLStruct’s MIME type, serialized. + const mimeType = serializeAMimeType(dataURLStruct.mimeType) + + // 4. Return a response whose status message is `OK`, + // header list is « (`Content-Type`, mimeType) », + // and body is dataURLStruct’s body as a body. + return Promise.resolve( + makeResponse({ + statusText: 'OK', + headersList: [ + ['content-type', { name: 'Content-Type', value: mimeType }], + ], + body: safelyExtractBody(dataURLStruct.body)[0], + }) + ) + } + case 'file:': { + // For now, unfortunate as it is, file URLs are left as an exercise for the reader. + // When in doubt, return a network error. + return Promise.resolve( + makeNetworkError('not implemented... yet...') + ) + } + case 'http:': + case 'https:': { + // Return the result of running HTTP fetch given fetchParams. + + return httpFetch(fetchParams).catch((err) => makeNetworkError(err)) + } + default: { + return Promise.resolve(makeNetworkError('unknown scheme')) + } + } + } + + // https://fetch.spec.whatwg.org/#finalize-response + function finalizeResponse(fetchParams, response) { + // 1. Set fetchParams’s request’s done flag. + fetchParams.request.done = true + + // 2, If fetchParams’s process response done is not null, then queue a fetch + // task to run fetchParams’s process response done given response, with + // fetchParams’s task destination. + if (fetchParams.processResponseDone != null) { + queueMicrotask(() => fetchParams.processResponseDone(response)) + } + } + + // https://fetch.spec.whatwg.org/#fetch-finale + function fetchFinale(fetchParams, response) { + // 1. If response is a network error, then: + if (response.type === 'error') { + // 1. Set response’s URL list to « fetchParams’s request’s URL list[0] ». + response.urlList = [fetchParams.request.urlList[0]] + + // 2. Set response’s timing info to the result of creating an opaque timing + // info for fetchParams’s timing info. + response.timingInfo = createOpaqueTimingInfo({ + startTime: fetchParams.timingInfo.startTime, + }) + } + + // 2. Let processResponseEndOfBody be the following steps: + const processResponseEndOfBody = () => { + // 1. Set fetchParams’s request’s done flag. + fetchParams.request.done = true + + // If fetchParams’s process response end-of-body is not null, + // then queue a fetch task to run fetchParams’s process response + // end-of-body given response with fetchParams’s task destination. + if (fetchParams.processResponseEndOfBody != null) { + queueMicrotask(() => fetchParams.processResponseEndOfBody(response)) + } + } + + // 3. If fetchParams’s process response is non-null, then queue a fetch task + // to run fetchParams’s process response given response, with fetchParams’s + // task destination. + if (fetchParams.processResponse != null) { + queueMicrotask(() => fetchParams.processResponse(response)) + } + + // 4. If response’s body is null, then run processResponseEndOfBody. + if (response.body == null) { + processResponseEndOfBody() + } else { + // 5. Otherwise: + + // 1. Let transformStream be a new a TransformStream. + + // 2. Let identityTransformAlgorithm be an algorithm which, given chunk, + // enqueues chunk in transformStream. + const identityTransformAlgorithm = (chunk, controller) => { + controller.enqueue(chunk) + } + + // 3. Set up transformStream with transformAlgorithm set to identityTransformAlgorithm + // and flushAlgorithm set to processResponseEndOfBody. + const transformStream = new TransformStream( + { + start() {}, + transform: identityTransformAlgorithm, + flush: processResponseEndOfBody, + }, + { + size() { + return 1 + }, + }, + { + size() { + return 1 + }, + } + ) + + // 4. Set response’s body to the result of piping response’s body through transformStream. + response.body = { + stream: response.body.stream.pipeThrough(transformStream), + } + } + + // 6. If fetchParams’s process response consume body is non-null, then: + if (fetchParams.processResponseConsumeBody != null) { + // 1. Let processBody given nullOrBytes be this step: run fetchParams’s + // process response consume body given response and nullOrBytes. + const processBody = (nullOrBytes) => + fetchParams.processResponseConsumeBody(response, nullOrBytes) + + // 2. Let processBodyError be this step: run fetchParams’s process + // response consume body given response and failure. + const processBodyError = (failure) => + fetchParams.processResponseConsumeBody(response, failure) + + // 3. If response’s body is null, then queue a fetch task to run processBody + // given null, with fetchParams’s task destination. + if (response.body == null) { + queueMicrotask(() => processBody(null)) + } else { + // 4. Otherwise, fully read response’s body given processBody, processBodyError, + // and fetchParams’s task destination. + return fullyReadBody(response.body, processBody, processBodyError) + } + return Promise.resolve() + } + } + + // https://fetch.spec.whatwg.org/#http-fetch + async function httpFetch(fetchParams) { + // 1. Let request be fetchParams’s request. + const request = fetchParams.request + + // 2. Let response be null. + let response = null + + // 3. Let actualResponse be null. + let actualResponse = null + + // 4. Let timingInfo be fetchParams’s timing info. + const timingInfo = fetchParams.timingInfo + + // 5. If request’s service-workers mode is "all", then: + if (request.serviceWorkers === 'all') { + // TODO + } + + // 6. If response is null, then: + if (response === null) { + // 1. If makeCORSPreflight is true and one of these conditions is true: + // TODO + + // 2. If request’s redirect mode is "follow", then set request’s + // service-workers mode to "none". + if (request.redirect === 'follow') { + request.serviceWorkers = 'none' + } + + // 3. Set response and actualResponse to the result of running + // HTTP-network-or-cache fetch given fetchParams. + actualResponse = response = await httpNetworkOrCacheFetch(fetchParams) + + // 4. If request’s response tainting is "cors" and a CORS check + // for request and response returns failure, then return a network error. + if ( + request.responseTainting === 'cors' && + corsCheck(request, response) === 'failure' + ) { + return makeNetworkError('cors failure') + } + + // 5. If the TAO check for request and response returns failure, then set + // request’s timing allow failed flag. + if (TAOCheck(request, response) === 'failure') { + request.timingAllowFailed = true + } + } + + // 7. If either request’s response tainting or response’s type + // is "opaque", and the cross-origin resource policy check with + // request’s origin, request’s client, request’s destination, + // and actualResponse returns blocked, then return a network error. + if ( + (request.responseTainting === 'opaque' || + response.type === 'opaque') && + crossOriginResourcePolicyCheck( + request.origin, + request.client, + request.destination, + actualResponse + ) === 'blocked' + ) { + return makeNetworkError('blocked') + } + + // 8. If actualResponse’s status is a redirect status, then: + if (redirectStatusSet.has(actualResponse.status)) { + // 1. If actualResponse’s status is not 303, request’s body is not null, + // and the connection uses HTTP/2, then user agents may, and are even + // encouraged to, transmit an RST_STREAM frame. + // See, https://github.com/whatwg/fetch/issues/1288 + if (request.redirect !== 'manual') { + fetchParams.controller.connection.destroy() + } + + // 2. Switch on request’s redirect mode: + if (request.redirect === 'error') { + // Set response to a network error. + response = makeNetworkError('unexpected redirect') + } else if (request.redirect === 'manual') { + // Set response to an opaque-redirect filtered response whose internal + // response is actualResponse. + // NOTE(spec): On the web this would return an `opaqueredirect` response, + // but that doesn't make sense server side. + // See https://github.com/nodejs/undici/issues/1193. + response = actualResponse + } else if (request.redirect === 'follow') { + // Set response to the result of running HTTP-redirect fetch given + // fetchParams and response. + response = await httpRedirectFetch(fetchParams, response) + } else { + assert(false) + } + } + + // 9. Set response’s timing info to timingInfo. + response.timingInfo = timingInfo + + // 10. Return response. + return response + } + + // https://fetch.spec.whatwg.org/#http-redirect-fetch + function httpRedirectFetch(fetchParams, response) { + // 1. Let request be fetchParams’s request. + const request = fetchParams.request + + // 2. Let actualResponse be response, if response is not a filtered response, + // and response’s internal response otherwise. + const actualResponse = response.internalResponse + ? response.internalResponse + : response + + // 3. Let locationURL be actualResponse’s location URL given request’s current + // URL’s fragment. + let locationURL + + try { + locationURL = responseLocationURL( + actualResponse, + requestCurrentURL(request).hash + ) + + // 4. If locationURL is null, then return response. + if (locationURL == null) { + return response + } + } catch (err) { + // 5. If locationURL is failure, then return a network error. + return Promise.resolve(makeNetworkError(err)) + } + + // 6. If locationURL’s scheme is not an HTTP(S) scheme, then return a network + // error. + if (!urlIsHttpHttpsScheme(locationURL)) { + return Promise.resolve( + makeNetworkError('URL scheme must be a HTTP(S) scheme') + ) + } + + // 7. If request’s redirect count is 20, then return a network error. + if (request.redirectCount === 20) { + return Promise.resolve(makeNetworkError('redirect count exceeded')) + } + + // 8. Increase request’s redirect count by 1. + request.redirectCount += 1 + + // 9. If request’s mode is "cors", locationURL includes credentials, and + // request’s origin is not same origin with locationURL’s origin, then return + // a network error. + if ( + request.mode === 'cors' && + (locationURL.username || locationURL.password) && + !sameOrigin(request, locationURL) + ) { + return Promise.resolve( + makeNetworkError('cross origin not allowed for request mode "cors"') + ) + } + + // 10. If request’s response tainting is "cors" and locationURL includes + // credentials, then return a network error. + if ( + request.responseTainting === 'cors' && + (locationURL.username || locationURL.password) + ) { + return Promise.resolve( + makeNetworkError( + 'URL cannot contain credentials for request mode "cors"' + ) + ) + } + + // 11. If actualResponse’s status is not 303, request’s body is non-null, + // and request’s body’s source is null, then return a network error. + if ( + actualResponse.status !== 303 && + request.body != null && + request.body.source == null + ) { + return Promise.resolve(makeNetworkError()) + } + + // 12. If one of the following is true + // - actualResponse’s status is 301 or 302 and request’s method is `POST` + // - actualResponse’s status is 303 and request’s method is not `GET` or `HEAD` + if ( + ([301, 302].includes(actualResponse.status) && + request.method === 'POST') || + (actualResponse.status === 303 && + !GET_OR_HEAD.includes(request.method)) + ) { + // then: + // 1. Set request’s method to `GET` and request’s body to null. + request.method = 'GET' + request.body = null + + // 2. For each headerName of request-body-header name, delete headerName from + // request’s header list. + for (const headerName of requestBodyHeader) { + request.headersList.delete(headerName) + } + } + + // 13. If request’s current URL’s origin is not same origin with locationURL’s + // origin, then for each headerName of CORS non-wildcard request-header name, + // delete headerName from request’s header list. + if (!sameOrigin(requestCurrentURL(request), locationURL)) { + // https://fetch.spec.whatwg.org/#cors-non-wildcard-request-header-name + request.headersList.delete('authorization') + + // "Cookie" and "Host" are forbidden request-headers, which undici doesn't implement. + request.headersList.delete('cookie') + request.headersList.delete('host') + } + + // 14. If request’s body is non-null, then set request’s body to the first return + // value of safely extracting request’s body’s source. + if (request.body != null) { + assert(request.body.source != null) + request.body = safelyExtractBody(request.body.source)[0] + } + + // 15. Let timingInfo be fetchParams’s timing info. + const timingInfo = fetchParams.timingInfo + + // 16. Set timingInfo’s redirect end time and post-redirect start time to the + // coarsened shared current time given fetchParams’s cross-origin isolated + // capability. + timingInfo.redirectEndTime = timingInfo.postRedirectStartTime = + coarsenedSharedCurrentTime(fetchParams.crossOriginIsolatedCapability) + + // 17. If timingInfo’s redirect start time is 0, then set timingInfo’s + // redirect start time to timingInfo’s start time. + if (timingInfo.redirectStartTime === 0) { + timingInfo.redirectStartTime = timingInfo.startTime + } + + // 18. Append locationURL to request’s URL list. + request.urlList.push(locationURL) + + // 19. Invoke set request’s referrer policy on redirect on request and + // actualResponse. + setRequestReferrerPolicyOnRedirect(request, actualResponse) + + // 20. Return the result of running main fetch given fetchParams and true. + return mainFetch(fetchParams, true) + } + + // https://fetch.spec.whatwg.org/#http-network-or-cache-fetch + async function httpNetworkOrCacheFetch( + fetchParams, + isAuthenticationFetch = false, + isNewConnectionFetch = false + ) { + // 1. Let request be fetchParams’s request. + const request = fetchParams.request + + // 2. Let httpFetchParams be null. + let httpFetchParams = null + + // 3. Let httpRequest be null. + let httpRequest = null + + // 4. Let response be null. + let response = null + + // 5. Let storedResponse be null. + // TODO: cache + + // 6. Let httpCache be null. + const httpCache = null + + // 7. Let the revalidatingFlag be unset. + const revalidatingFlag = false + + // 8. Run these steps, but abort when the ongoing fetch is terminated: + + // 1. If request’s window is "no-window" and request’s redirect mode is + // "error", then set httpFetchParams to fetchParams and httpRequest to + // request. + if (request.window === 'no-window' && request.redirect === 'error') { + httpFetchParams = fetchParams + httpRequest = request + } else { + // Otherwise: + + // 1. Set httpRequest to a clone of request. + httpRequest = makeRequest(request) + + // 2. Set httpFetchParams to a copy of fetchParams. + httpFetchParams = { ...fetchParams } + + // 3. Set httpFetchParams’s request to httpRequest. + httpFetchParams.request = httpRequest + } + + // 3. Let includeCredentials be true if one of + const includeCredentials = + request.credentials === 'include' || + (request.credentials === 'same-origin' && + request.responseTainting === 'basic') + + // 4. Let contentLength be httpRequest’s body’s length, if httpRequest’s + // body is non-null; otherwise null. + const contentLength = httpRequest.body ? httpRequest.body.length : null + + // 5. Let contentLengthHeaderValue be null. + let contentLengthHeaderValue = null + + // 6. If httpRequest’s body is null and httpRequest’s method is `POST` or + // `PUT`, then set contentLengthHeaderValue to `0`. + if ( + httpRequest.body == null && + ['POST', 'PUT'].includes(httpRequest.method) + ) { + contentLengthHeaderValue = '0' + } + + // 7. If contentLength is non-null, then set contentLengthHeaderValue to + // contentLength, serialized and isomorphic encoded. + if (contentLength != null) { + contentLengthHeaderValue = isomorphicEncode(`${contentLength}`) + } + + // 8. If contentLengthHeaderValue is non-null, then append + // `Content-Length`/contentLengthHeaderValue to httpRequest’s header + // list. + if (contentLengthHeaderValue != null) { + httpRequest.headersList.append( + 'content-length', + contentLengthHeaderValue + ) + } + + // 9. If contentLengthHeaderValue is non-null, then append (`Content-Length`, + // contentLengthHeaderValue) to httpRequest’s header list. + + // 10. If contentLength is non-null and httpRequest’s keepalive is true, + // then: + if (contentLength != null && httpRequest.keepalive) { + // NOTE: keepalive is a noop outside of browser context. + } + + // 11. If httpRequest’s referrer is a URL, then append + // `Referer`/httpRequest’s referrer, serialized and isomorphic encoded, + // to httpRequest’s header list. + if (httpRequest.referrer instanceof URL) { + httpRequest.headersList.append( + 'referer', + isomorphicEncode(httpRequest.referrer.href) + ) + } + + // 12. Append a request `Origin` header for httpRequest. + appendRequestOriginHeader(httpRequest) + + // 13. Append the Fetch metadata headers for httpRequest. [FETCH-METADATA] + appendFetchMetadata(httpRequest) + + // 14. If httpRequest’s header list does not contain `User-Agent`, then + // user agents should append `User-Agent`/default `User-Agent` value to + // httpRequest’s header list. + if (!httpRequest.headersList.contains('user-agent')) { + httpRequest.headersList.append( + 'user-agent', + typeof esbuildDetection === 'undefined' ? 'undici' : 'node' + ) + } + + // 15. If httpRequest’s cache mode is "default" and httpRequest’s header + // list contains `If-Modified-Since`, `If-None-Match`, + // `If-Unmodified-Since`, `If-Match`, or `If-Range`, then set + // httpRequest’s cache mode to "no-store". + if ( + httpRequest.cache === 'default' && + (httpRequest.headersList.contains('if-modified-since') || + httpRequest.headersList.contains('if-none-match') || + httpRequest.headersList.contains('if-unmodified-since') || + httpRequest.headersList.contains('if-match') || + httpRequest.headersList.contains('if-range')) + ) { + httpRequest.cache = 'no-store' + } + + // 16. If httpRequest’s cache mode is "no-cache", httpRequest’s prevent + // no-cache cache-control header modification flag is unset, and + // httpRequest’s header list does not contain `Cache-Control`, then append + // `Cache-Control`/`max-age=0` to httpRequest’s header list. + if ( + httpRequest.cache === 'no-cache' && + !httpRequest.preventNoCacheCacheControlHeaderModification && + !httpRequest.headersList.contains('cache-control') + ) { + httpRequest.headersList.append('cache-control', 'max-age=0') + } + + // 17. If httpRequest’s cache mode is "no-store" or "reload", then: + if ( + httpRequest.cache === 'no-store' || + httpRequest.cache === 'reload' + ) { + // 1. If httpRequest’s header list does not contain `Pragma`, then append + // `Pragma`/`no-cache` to httpRequest’s header list. + if (!httpRequest.headersList.contains('pragma')) { + httpRequest.headersList.append('pragma', 'no-cache') + } + + // 2. If httpRequest’s header list does not contain `Cache-Control`, + // then append `Cache-Control`/`no-cache` to httpRequest’s header list. + if (!httpRequest.headersList.contains('cache-control')) { + httpRequest.headersList.append('cache-control', 'no-cache') + } + } + + // 18. If httpRequest’s header list contains `Range`, then append + // `Accept-Encoding`/`identity` to httpRequest’s header list. + if (httpRequest.headersList.contains('range')) { + httpRequest.headersList.append('accept-encoding', 'identity') + } + + // 19. Modify httpRequest’s header list per HTTP. Do not append a given + // header if httpRequest’s header list contains that header’s name. + // TODO: https://github.com/whatwg/fetch/issues/1285#issuecomment-896560129 + if (!httpRequest.headersList.contains('accept-encoding')) { + if (urlHasHttpsScheme(requestCurrentURL(httpRequest))) { + httpRequest.headersList.append( + 'accept-encoding', + 'br, gzip, deflate' + ) + } else { + httpRequest.headersList.append('accept-encoding', 'gzip, deflate') + } + } + + httpRequest.headersList.delete('host') + + // 20. If includeCredentials is true, then: + if (includeCredentials) { + // 1. If the user agent is not configured to block cookies for httpRequest + // (see section 7 of [COOKIES]), then: + // TODO: credentials + // 2. If httpRequest’s header list does not contain `Authorization`, then: + // TODO: credentials + } + + // 21. If there’s a proxy-authentication entry, use it as appropriate. + // TODO: proxy-authentication + + // 22. Set httpCache to the result of determining the HTTP cache + // partition, given httpRequest. + // TODO: cache + + // 23. If httpCache is null, then set httpRequest’s cache mode to + // "no-store". + if (httpCache == null) { + httpRequest.cache = 'no-store' + } + + // 24. If httpRequest’s cache mode is neither "no-store" nor "reload", + // then: + if (httpRequest.mode !== 'no-store' && httpRequest.mode !== 'reload') { + // TODO: cache + } + + // 9. If aborted, then return the appropriate network error for fetchParams. + // TODO + + // 10. If response is null, then: + if (response == null) { + // 1. If httpRequest’s cache mode is "only-if-cached", then return a + // network error. + if (httpRequest.mode === 'only-if-cached') { + return makeNetworkError('only if cached') + } + + // 2. Let forwardResponse be the result of running HTTP-network fetch + // given httpFetchParams, includeCredentials, and isNewConnectionFetch. + const forwardResponse = await httpNetworkFetch( + httpFetchParams, + includeCredentials, + isNewConnectionFetch + ) + + // 3. If httpRequest’s method is unsafe and forwardResponse’s status is + // in the range 200 to 399, inclusive, invalidate appropriate stored + // responses in httpCache, as per the "Invalidation" chapter of HTTP + // Caching, and set storedResponse to null. [HTTP-CACHING] + if ( + !safeMethodsSet.has(httpRequest.method) && + forwardResponse.status >= 200 && + forwardResponse.status <= 399 + ) { + // TODO: cache + } + + // 4. If the revalidatingFlag is set and forwardResponse’s status is 304, + // then: + if (revalidatingFlag && forwardResponse.status === 304) { + // TODO: cache + } + + // 5. If response is null, then: + if (response == null) { + // 1. Set response to forwardResponse. + response = forwardResponse + + // 2. Store httpRequest and forwardResponse in httpCache, as per the + // "Storing Responses in Caches" chapter of HTTP Caching. [HTTP-CACHING] + // TODO: cache + } + } + + // 11. Set response’s URL list to a clone of httpRequest’s URL list. + response.urlList = [...httpRequest.urlList] + + // 12. If httpRequest’s header list contains `Range`, then set response’s + // range-requested flag. + if (httpRequest.headersList.contains('range')) { + response.rangeRequested = true + } + + // 13. Set response’s request-includes-credentials to includeCredentials. + response.requestIncludesCredentials = includeCredentials + + // 14. If response’s status is 401, httpRequest’s response tainting is not + // "cors", includeCredentials is true, and request’s window is an environment + // settings object, then: + // TODO + + // 15. If response’s status is 407, then: + if (response.status === 407) { + // 1. If request’s window is "no-window", then return a network error. + if (request.window === 'no-window') { + return makeNetworkError() + } + + // 2. ??? + + // 3. If fetchParams is canceled, then return the appropriate network error for fetchParams. + if (isCancelled(fetchParams)) { + return makeAppropriateNetworkError(fetchParams) + } + + // 4. Prompt the end user as appropriate in request’s window and store + // the result as a proxy-authentication entry. [HTTP-AUTH] + // TODO: Invoke some kind of callback? + + // 5. Set response to the result of running HTTP-network-or-cache fetch given + // fetchParams. + // TODO + return makeNetworkError('proxy authentication required') + } + + // 16. If all of the following are true + if ( + // response’s status is 421 + response.status === 421 && + // isNewConnectionFetch is false + !isNewConnectionFetch && + // request’s body is null, or request’s body is non-null and request’s body’s source is non-null + (request.body == null || request.body.source != null) + ) { + // then: + + // 1. If fetchParams is canceled, then return the appropriate network error for fetchParams. + if (isCancelled(fetchParams)) { + return makeAppropriateNetworkError(fetchParams) + } + + // 2. Set response to the result of running HTTP-network-or-cache + // fetch given fetchParams, isAuthenticationFetch, and true. + + // TODO (spec): The spec doesn't specify this but we need to cancel + // the active response before we can start a new one. + // https://github.com/whatwg/fetch/issues/1293 + fetchParams.controller.connection.destroy() + + response = await httpNetworkOrCacheFetch( + fetchParams, + isAuthenticationFetch, + true + ) + } + + // 17. If isAuthenticationFetch is true, then create an authentication entry + if (isAuthenticationFetch) { + // TODO + } + + // 18. Return response. + return response + } + + // https://fetch.spec.whatwg.org/#http-network-fetch + async function httpNetworkFetch( + fetchParams, + includeCredentials = false, + forceNewConnection = false + ) { + assert( + !fetchParams.controller.connection || + fetchParams.controller.connection.destroyed + ) + + fetchParams.controller.connection = { + abort: null, + destroyed: false, + destroy(err) { + if (!this.destroyed) { + this.destroyed = true + this.abort?.( + err ?? + new DOMException('The operation was aborted.', 'AbortError') + ) + } + }, + } + + // 1. Let request be fetchParams’s request. + const request = fetchParams.request + + // 2. Let response be null. + let response = null + + // 3. Let timingInfo be fetchParams’s timing info. + const timingInfo = fetchParams.timingInfo + + // 4. Let httpCache be the result of determining the HTTP cache partition, + // given request. + // TODO: cache + const httpCache = null + + // 5. If httpCache is null, then set request’s cache mode to "no-store". + if (httpCache == null) { + request.cache = 'no-store' + } + + // 6. Let networkPartitionKey be the result of determining the network + // partition key given request. + // TODO + + // 7. Let newConnection be "yes" if forceNewConnection is true; otherwise + // "no". + const newConnection = forceNewConnection ? 'yes' : 'no' // eslint-disable-line no-unused-vars + + // 8. Switch on request’s mode: + if (request.mode === 'websocket') { + // Let connection be the result of obtaining a WebSocket connection, + // given request’s current URL. + // TODO + } else { + // Let connection be the result of obtaining a connection, given + // networkPartitionKey, request’s current URL’s origin, + // includeCredentials, and forceNewConnection. + // TODO + } + + // 9. Run these steps, but abort when the ongoing fetch is terminated: + + // 1. If connection is failure, then return a network error. + + // 2. Set timingInfo’s final connection timing info to the result of + // calling clamp and coarsen connection timing info with connection’s + // timing info, timingInfo’s post-redirect start time, and fetchParams’s + // cross-origin isolated capability. + + // 3. If connection is not an HTTP/2 connection, request’s body is non-null, + // and request’s body’s source is null, then append (`Transfer-Encoding`, + // `chunked`) to request’s header list. + + // 4. Set timingInfo’s final network-request start time to the coarsened + // shared current time given fetchParams’s cross-origin isolated + // capability. + + // 5. Set response to the result of making an HTTP request over connection + // using request with the following caveats: + + // - Follow the relevant requirements from HTTP. [HTTP] [HTTP-SEMANTICS] + // [HTTP-COND] [HTTP-CACHING] [HTTP-AUTH] + + // - If request’s body is non-null, and request’s body’s source is null, + // then the user agent may have a buffer of up to 64 kibibytes and store + // a part of request’s body in that buffer. If the user agent reads from + // request’s body beyond that buffer’s size and the user agent needs to + // resend request, then instead return a network error. + + // - Set timingInfo’s final network-response start time to the coarsened + // shared current time given fetchParams’s cross-origin isolated capability, + // immediately after the user agent’s HTTP parser receives the first byte + // of the response (e.g., frame header bytes for HTTP/2 or response status + // line for HTTP/1.x). + + // - Wait until all the headers are transmitted. + + // - Any responses whose status is in the range 100 to 199, inclusive, + // and is not 101, are to be ignored, except for the purposes of setting + // timingInfo’s final network-response start time above. + + // - If request’s header list contains `Transfer-Encoding`/`chunked` and + // response is transferred via HTTP/1.0 or older, then return a network + // error. + + // - If the HTTP request results in a TLS client certificate dialog, then: + + // 1. If request’s window is an environment settings object, make the + // dialog available in request’s window. + + // 2. Otherwise, return a network error. + + // To transmit request’s body body, run these steps: + let requestBody = null + // 1. If body is null and fetchParams’s process request end-of-body is + // non-null, then queue a fetch task given fetchParams’s process request + // end-of-body and fetchParams’s task destination. + if (request.body == null && fetchParams.processRequestEndOfBody) { + queueMicrotask(() => fetchParams.processRequestEndOfBody()) + } else if (request.body != null) { + // 2. Otherwise, if body is non-null: + + // 1. Let processBodyChunk given bytes be these steps: + const processBodyChunk = async function* (bytes) { + // 1. If the ongoing fetch is terminated, then abort these steps. + if (isCancelled(fetchParams)) { + return + } + + // 2. Run this step in parallel: transmit bytes. + yield bytes + + // 3. If fetchParams’s process request body is non-null, then run + // fetchParams’s process request body given bytes’s length. + fetchParams.processRequestBodyChunkLength?.(bytes.byteLength) + } + + // 2. Let processEndOfBody be these steps: + const processEndOfBody = () => { + // 1. If fetchParams is canceled, then abort these steps. + if (isCancelled(fetchParams)) { + return + } + + // 2. If fetchParams’s process request end-of-body is non-null, + // then run fetchParams’s process request end-of-body. + if (fetchParams.processRequestEndOfBody) { + fetchParams.processRequestEndOfBody() + } + } + + // 3. Let processBodyError given e be these steps: + const processBodyError = (e) => { + // 1. If fetchParams is canceled, then abort these steps. + if (isCancelled(fetchParams)) { + return + } + + // 2. If e is an "AbortError" DOMException, then abort fetchParams’s controller. + if (e.name === 'AbortError') { + fetchParams.controller.abort() + } else { + fetchParams.controller.terminate(e) + } + } + + // 4. Incrementally read request’s body given processBodyChunk, processEndOfBody, + // processBodyError, and fetchParams’s task destination. + requestBody = (async function* () { + try { + for await (const bytes of request.body.stream) { + yield* processBodyChunk(bytes) + } + processEndOfBody() + } catch (err) { + processBodyError(err) + } + })() + } + + try { + // socket is only provided for websockets + const { body, status, statusText, headersList, socket } = + await dispatch({ body: requestBody }) + + if (socket) { + response = makeResponse({ status, statusText, headersList, socket }) + } else { + const iterator = body[Symbol.asyncIterator]() + fetchParams.controller.next = () => iterator.next() + + response = makeResponse({ status, statusText, headersList }) + } + } catch (err) { + // 10. If aborted, then: + if (err.name === 'AbortError') { + // 1. If connection uses HTTP/2, then transmit an RST_STREAM frame. + fetchParams.controller.connection.destroy() + + // 2. Return the appropriate network error for fetchParams. + return makeAppropriateNetworkError(fetchParams, err) + } + + return makeNetworkError(err) + } + + // 11. Let pullAlgorithm be an action that resumes the ongoing fetch + // if it is suspended. + const pullAlgorithm = () => { + fetchParams.controller.resume() + } + + // 12. Let cancelAlgorithm be an algorithm that aborts fetchParams’s + // controller with reason, given reason. + const cancelAlgorithm = (reason) => { + fetchParams.controller.abort(reason) + } + + // 13. Let highWaterMark be a non-negative, non-NaN number, chosen by + // the user agent. + // TODO + + // 14. Let sizeAlgorithm be an algorithm that accepts a chunk object + // and returns a non-negative, non-NaN, non-infinite number, chosen by the user agent. + // TODO + + // 15. Let stream be a new ReadableStream. + // 16. Set up stream with pullAlgorithm set to pullAlgorithm, + // cancelAlgorithm set to cancelAlgorithm, highWaterMark set to + // highWaterMark, and sizeAlgorithm set to sizeAlgorithm. + if (!ReadableStream) { + ReadableStream = __nccwpck_require__(5356).ReadableStream + } + + const stream = new ReadableStream( + { + async start(controller) { + fetchParams.controller.controller = controller + }, + async pull(controller) { + await pullAlgorithm(controller) + }, + async cancel(reason) { + await cancelAlgorithm(reason) + }, + }, + { + highWaterMark: 0, + size() { + return 1 + }, + } + ) + + // 17. Run these steps, but abort when the ongoing fetch is terminated: + + // 1. Set response’s body to a new body whose stream is stream. + response.body = { stream } + + // 2. If response is not a network error and request’s cache mode is + // not "no-store", then update response in httpCache for request. + // TODO + + // 3. If includeCredentials is true and the user agent is not configured + // to block cookies for request (see section 7 of [COOKIES]), then run the + // "set-cookie-string" parsing algorithm (see section 5.2 of [COOKIES]) on + // the value of each header whose name is a byte-case-insensitive match for + // `Set-Cookie` in response’s header list, if any, and request’s current URL. + // TODO + + // 18. If aborted, then: + // TODO + + // 19. Run these steps in parallel: + + // 1. Run these steps, but abort when fetchParams is canceled: + fetchParams.controller.on('terminated', onAborted) + fetchParams.controller.resume = async () => { + // 1. While true + while (true) { + // 1-3. See onData... + + // 4. Set bytes to the result of handling content codings given + // codings and bytes. + let bytes + let isFailure + try { + const { done, value } = await fetchParams.controller.next() + + if (isAborted(fetchParams)) { + break + } + + bytes = done ? undefined : value + } catch (err) { + if (fetchParams.controller.ended && !timingInfo.encodedBodySize) { + // zlib doesn't like empty streams. + bytes = undefined + } else { + bytes = err + + // err may be propagated from the result of calling readablestream.cancel, + // which might not be an error. https://github.com/nodejs/undici/issues/2009 + isFailure = true + } + } + + if (bytes === undefined) { + // 2. Otherwise, if the bytes transmission for response’s message + // body is done normally and stream is readable, then close + // stream, finalize response for fetchParams and response, and + // abort these in-parallel steps. + readableStreamClose(fetchParams.controller.controller) + + finalizeResponse(fetchParams, response) + + return + } + + // 5. Increase timingInfo’s decoded body size by bytes’s length. + timingInfo.decodedBodySize += bytes?.byteLength ?? 0 + + // 6. If bytes is failure, then terminate fetchParams’s controller. + if (isFailure) { + fetchParams.controller.terminate(bytes) + return + } + + // 7. Enqueue a Uint8Array wrapping an ArrayBuffer containing bytes + // into stream. + fetchParams.controller.controller.enqueue(new Uint8Array(bytes)) + + // 8. If stream is errored, then terminate the ongoing fetch. + if (isErrored(stream)) { + fetchParams.controller.terminate() + return + } + + // 9. If stream doesn’t need more data ask the user agent to suspend + // the ongoing fetch. + if (!fetchParams.controller.controller.desiredSize) { + return + } + } + } + + // 2. If aborted, then: + function onAborted(reason) { + // 2. If fetchParams is aborted, then: + if (isAborted(fetchParams)) { + // 1. Set response’s aborted flag. + response.aborted = true + + // 2. If stream is readable, then error stream with the result of + // deserialize a serialized abort reason given fetchParams’s + // controller’s serialized abort reason and an + // implementation-defined realm. + if (isReadable(stream)) { + fetchParams.controller.controller.error( + fetchParams.controller.serializedAbortReason + ) + } + } else { + // 3. Otherwise, if stream is readable, error stream with a TypeError. + if (isReadable(stream)) { + fetchParams.controller.controller.error( + new TypeError('terminated', { + cause: isErrorLike(reason) ? reason : undefined, + }) + ) + } + } + + // 4. If connection uses HTTP/2, then transmit an RST_STREAM frame. + // 5. Otherwise, the user agent should close connection unless it would be bad for performance to do so. + fetchParams.controller.connection.destroy() + } + + // 20. Return response. + return response + + async function dispatch({ body }) { + const url = requestCurrentURL(request) + /** @type {import('../..').Agent} */ + const agent = fetchParams.controller.dispatcher + + return new Promise((resolve, reject) => + agent.dispatch( + { + path: url.pathname + url.search, + origin: url.origin, + method: request.method, + body: fetchParams.controller.dispatcher.isMockActive + ? request.body && request.body.source + : body, + headers: request.headersList.entries, + maxRedirections: 0, + upgrade: request.mode === 'websocket' ? 'websocket' : undefined, + }, + { + body: null, + abort: null, + + onConnect(abort) { + // TODO (fix): Do we need connection here? + const { connection } = fetchParams.controller + + if (connection.destroyed) { + abort( + new DOMException( + 'The operation was aborted.', + 'AbortError' + ) + ) + } else { + fetchParams.controller.on('terminated', abort) + this.abort = connection.abort = abort + } + }, + + onHeaders(status, headersList, resume, statusText) { + if (status < 200) { + return + } + + let codings = [] + let location = '' + + const headers = new Headers() + + // For H2, the headers are a plain JS object + // We distinguish between them and iterate accordingly + if (Array.isArray(headersList)) { + for (let n = 0; n < headersList.length; n += 2) { + const key = headersList[n + 0].toString('latin1') + const val = headersList[n + 1].toString('latin1') + if (key.toLowerCase() === 'content-encoding') { + // https://www.rfc-editor.org/rfc/rfc7231#section-3.1.2.1 + // "All content-coding values are case-insensitive..." + codings = val + .toLowerCase() + .split(',') + .map((x) => x.trim()) + } else if (key.toLowerCase() === 'location') { + location = val + } + + headers.append(key, val) + } + } else { + const keys = Object.keys(headersList) + for (const key of keys) { + const val = headersList[key] + if (key.toLowerCase() === 'content-encoding') { + // https://www.rfc-editor.org/rfc/rfc7231#section-3.1.2.1 + // "All content-coding values are case-insensitive..." + codings = val + .toLowerCase() + .split(',') + .map((x) => x.trim()) + .reverse() + } else if (key.toLowerCase() === 'location') { + location = val + } + + headers.append(key, val) + } + } + + this.body = new Readable({ read: resume }) + + const decoders = [] + + const willFollow = + request.redirect === 'follow' && + location && + redirectStatusSet.has(status) + + // https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Encoding + if ( + request.method !== 'HEAD' && + request.method !== 'CONNECT' && + !nullBodyStatus.includes(status) && + !willFollow + ) { + for (const coding of codings) { + // https://www.rfc-editor.org/rfc/rfc9112.html#section-7.2 + if (coding === 'x-gzip' || coding === 'gzip') { + decoders.push( + zlib.createGunzip({ + // Be less strict when decoding compressed responses, since sometimes + // servers send slightly invalid responses that are still accepted + // by common browsers. + // Always using Z_SYNC_FLUSH is what cURL does. + flush: zlib.constants.Z_SYNC_FLUSH, + finishFlush: zlib.constants.Z_SYNC_FLUSH, + }) + ) + } else if (coding === 'deflate') { + decoders.push(zlib.createInflate()) + } else if (coding === 'br') { + decoders.push(zlib.createBrotliDecompress()) + } else { + decoders.length = 0 + break + } + } + } + + resolve({ + status, + statusText, + headersList: headers[kHeadersList], + body: decoders.length + ? pipeline(this.body, ...decoders, () => {}) + : this.body.on('error', () => {}), + }) + + return true + }, + + onData(chunk) { + if (fetchParams.controller.dump) { + return + } + + // 1. If one or more bytes have been transmitted from response’s + // message body, then: + + // 1. Let bytes be the transmitted bytes. + const bytes = chunk + + // 2. Let codings be the result of extracting header list values + // given `Content-Encoding` and response’s header list. + // See pullAlgorithm. + + // 3. Increase timingInfo’s encoded body size by bytes’s length. + timingInfo.encodedBodySize += bytes.byteLength + + // 4. See pullAlgorithm... + + return this.body.push(bytes) + }, + + onComplete() { + if (this.abort) { + fetchParams.controller.off('terminated', this.abort) + } + + fetchParams.controller.ended = true + + this.body.push(null) + }, + + onError(error) { + if (this.abort) { + fetchParams.controller.off('terminated', this.abort) + } + + this.body?.destroy(error) + + fetchParams.controller.terminate(error) + + reject(error) + }, + + onUpgrade(status, headersList, socket) { + if (status !== 101) { + return + } + + const headers = new Headers() + + for (let n = 0; n < headersList.length; n += 2) { + const key = headersList[n + 0].toString('latin1') + const val = headersList[n + 1].toString('latin1') + + headers.append(key, val) + } + + resolve({ + status, + statusText: STATUS_CODES[status], + headersList: headers[kHeadersList], + socket, + }) + + return true + }, + } + ) + ) + } + } + + module.exports = { + fetch, + Fetch, + fetching, + finalizeAndReportTiming, + } + + /***/ + }, + + /***/ 8359: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + /* globals AbortController */ + + const { extractBody, mixinBody, cloneBody } = __nccwpck_require__(1472) + const { + Headers, + fill: fillHeaders, + HeadersList, + } = __nccwpck_require__(554) + const { FinalizationRegistry } = __nccwpck_require__(6436)() + const util = __nccwpck_require__(3983) + const { + isValidHTTPToken, + sameOrigin, + normalizeMethod, + makePolicyContainer, + } = __nccwpck_require__(2538) + const { + forbiddenMethodsSet, + corsSafeListedMethodsSet, + referrerPolicy, + requestRedirect, + requestMode, + requestCredentials, + requestCache, + requestDuplex, + } = __nccwpck_require__(1037) + const { kEnumerableProperty } = util + const { kHeaders, kSignal, kState, kGuard, kRealm } = + __nccwpck_require__(5861) + const { webidl } = __nccwpck_require__(1744) + const { getGlobalOrigin } = __nccwpck_require__(1246) + const { URLSerializer } = __nccwpck_require__(685) + const { kHeadersList } = __nccwpck_require__(2785) + const assert = __nccwpck_require__(9491) + const { + getMaxListeners, + setMaxListeners, + getEventListeners, + defaultMaxListeners, + } = __nccwpck_require__(2361) + + let TransformStream = globalThis.TransformStream + + const kInit = Symbol('init') + const kAbortController = Symbol('abortController') + + const requestFinalizer = new FinalizationRegistry(({ signal, abort }) => { + signal.removeEventListener('abort', abort) + }) + + // https://fetch.spec.whatwg.org/#request-class + class Request { + // https://fetch.spec.whatwg.org/#dom-request + constructor(input, init = {}) { + if (input === kInit) { + return + } + + webidl.argumentLengthCheck(arguments, 1, { + header: 'Request constructor', + }) + + input = webidl.converters.RequestInfo(input) + init = webidl.converters.RequestInit(init) + + // https://html.spec.whatwg.org/multipage/webappapis.html#environment-settings-object + this[kRealm] = { + settingsObject: { + baseUrl: getGlobalOrigin(), + get origin() { + return this.baseUrl?.origin + }, + policyContainer: makePolicyContainer(), + }, + } + + // 1. Let request be null. + let request = null + + // 2. Let fallbackMode be null. + let fallbackMode = null + + // 3. Let baseURL be this’s relevant settings object’s API base URL. + const baseUrl = this[kRealm].settingsObject.baseUrl + + // 4. Let signal be null. + let signal = null + + // 5. If input is a string, then: + if (typeof input === 'string') { + // 1. Let parsedURL be the result of parsing input with baseURL. + // 2. If parsedURL is failure, then throw a TypeError. + let parsedURL + try { + parsedURL = new URL(input, baseUrl) + } catch (err) { + throw new TypeError('Failed to parse URL from ' + input, { + cause: err, + }) + } + + // 3. If parsedURL includes credentials, then throw a TypeError. + if (parsedURL.username || parsedURL.password) { + throw new TypeError( + 'Request cannot be constructed from a URL that includes credentials: ' + + input + ) + } + + // 4. Set request to a new request whose URL is parsedURL. + request = makeRequest({ urlList: [parsedURL] }) + + // 5. Set fallbackMode to "cors". + fallbackMode = 'cors' + } else { + // 6. Otherwise: + + // 7. Assert: input is a Request object. + assert(input instanceof Request) + + // 8. Set request to input’s request. + request = input[kState] + + // 9. Set signal to input’s signal. + signal = input[kSignal] + } + + // 7. Let origin be this’s relevant settings object’s origin. + const origin = this[kRealm].settingsObject.origin + + // 8. Let window be "client". + let window = 'client' + + // 9. If request’s window is an environment settings object and its origin + // is same origin with origin, then set window to request’s window. + if ( + request.window?.constructor?.name === 'EnvironmentSettingsObject' && + sameOrigin(request.window, origin) + ) { + window = request.window + } + + // 10. If init["window"] exists and is non-null, then throw a TypeError. + if (init.window != null) { + throw new TypeError(`'window' option '${window}' must be null`) + } + + // 11. If init["window"] exists, then set window to "no-window". + if ('window' in init) { + window = 'no-window' + } + + // 12. Set request to a new request with the following properties: + request = makeRequest({ + // URL request’s URL. + // undici implementation note: this is set as the first item in request's urlList in makeRequest + // method request’s method. + method: request.method, + // header list A copy of request’s header list. + // undici implementation note: headersList is cloned in makeRequest + headersList: request.headersList, + // unsafe-request flag Set. + unsafeRequest: request.unsafeRequest, + // client This’s relevant settings object. + client: this[kRealm].settingsObject, + // window window. + window, + // priority request’s priority. + priority: request.priority, + // origin request’s origin. The propagation of the origin is only significant for navigation requests + // being handled by a service worker. In this scenario a request can have an origin that is different + // from the current client. + origin: request.origin, + // referrer request’s referrer. + referrer: request.referrer, + // referrer policy request’s referrer policy. + referrerPolicy: request.referrerPolicy, + // mode request’s mode. + mode: request.mode, + // credentials mode request’s credentials mode. + credentials: request.credentials, + // cache mode request’s cache mode. + cache: request.cache, + // redirect mode request’s redirect mode. + redirect: request.redirect, + // integrity metadata request’s integrity metadata. + integrity: request.integrity, + // keepalive request’s keepalive. + keepalive: request.keepalive, + // reload-navigation flag request’s reload-navigation flag. + reloadNavigation: request.reloadNavigation, + // history-navigation flag request’s history-navigation flag. + historyNavigation: request.historyNavigation, + // URL list A clone of request’s URL list. + urlList: [...request.urlList], + }) + + // 13. If init is not empty, then: + if (Object.keys(init).length > 0) { + // 1. If request’s mode is "navigate", then set it to "same-origin". + if (request.mode === 'navigate') { + request.mode = 'same-origin' + } + + // 2. Unset request’s reload-navigation flag. + request.reloadNavigation = false + + // 3. Unset request’s history-navigation flag. + request.historyNavigation = false + + // 4. Set request’s origin to "client". + request.origin = 'client' + + // 5. Set request’s referrer to "client" + request.referrer = 'client' + + // 6. Set request’s referrer policy to the empty string. + request.referrerPolicy = '' + + // 7. Set request’s URL to request’s current URL. + request.url = request.urlList[request.urlList.length - 1] + + // 8. Set request’s URL list to « request’s URL ». + request.urlList = [request.url] + } + + // 14. If init["referrer"] exists, then: + if (init.referrer !== undefined) { + // 1. Let referrer be init["referrer"]. + const referrer = init.referrer + + // 2. If referrer is the empty string, then set request’s referrer to "no-referrer". + if (referrer === '') { + request.referrer = 'no-referrer' + } else { + // 1. Let parsedReferrer be the result of parsing referrer with + // baseURL. + // 2. If parsedReferrer is failure, then throw a TypeError. + let parsedReferrer + try { + parsedReferrer = new URL(referrer, baseUrl) + } catch (err) { + throw new TypeError( + `Referrer "${referrer}" is not a valid URL.`, + { cause: err } + ) + } + + // 3. If one of the following is true + // - parsedReferrer’s scheme is "about" and path is the string "client" + // - parsedReferrer’s origin is not same origin with origin + // then set request’s referrer to "client". + if ( + (parsedReferrer.protocol === 'about:' && + parsedReferrer.hostname === 'client') || + (origin && + !sameOrigin( + parsedReferrer, + this[kRealm].settingsObject.baseUrl + )) + ) { + request.referrer = 'client' + } else { + // 4. Otherwise, set request’s referrer to parsedReferrer. + request.referrer = parsedReferrer + } + } + } + + // 15. If init["referrerPolicy"] exists, then set request’s referrer policy + // to it. + if (init.referrerPolicy !== undefined) { + request.referrerPolicy = init.referrerPolicy + } + + // 16. Let mode be init["mode"] if it exists, and fallbackMode otherwise. + let mode + if (init.mode !== undefined) { + mode = init.mode + } else { + mode = fallbackMode + } + + // 17. If mode is "navigate", then throw a TypeError. + if (mode === 'navigate') { + throw webidl.errors.exception({ + header: 'Request constructor', + message: 'invalid request mode navigate.', + }) + } + + // 18. If mode is non-null, set request’s mode to mode. + if (mode != null) { + request.mode = mode + } + + // 19. If init["credentials"] exists, then set request’s credentials mode + // to it. + if (init.credentials !== undefined) { + request.credentials = init.credentials + } + + // 18. If init["cache"] exists, then set request’s cache mode to it. + if (init.cache !== undefined) { + request.cache = init.cache + } + + // 21. If request’s cache mode is "only-if-cached" and request’s mode is + // not "same-origin", then throw a TypeError. + if ( + request.cache === 'only-if-cached' && + request.mode !== 'same-origin' + ) { + throw new TypeError( + "'only-if-cached' can be set only with 'same-origin' mode" + ) + } + + // 22. If init["redirect"] exists, then set request’s redirect mode to it. + if (init.redirect !== undefined) { + request.redirect = init.redirect + } + + // 23. If init["integrity"] exists, then set request’s integrity metadata to it. + if (init.integrity !== undefined && init.integrity != null) { + request.integrity = String(init.integrity) + } + + // 24. If init["keepalive"] exists, then set request’s keepalive to it. + if (init.keepalive !== undefined) { + request.keepalive = Boolean(init.keepalive) + } + + // 25. If init["method"] exists, then: + if (init.method !== undefined) { + // 1. Let method be init["method"]. + let method = init.method + + // 2. If method is not a method or method is a forbidden method, then + // throw a TypeError. + if (!isValidHTTPToken(init.method)) { + throw TypeError(`'${init.method}' is not a valid HTTP method.`) + } + + if (forbiddenMethodsSet.has(method.toUpperCase())) { + throw TypeError(`'${init.method}' HTTP method is unsupported.`) + } + + // 3. Normalize method. + method = normalizeMethod(init.method) + + // 4. Set request’s method to method. + request.method = method + } + + // 26. If init["signal"] exists, then set signal to it. + if (init.signal !== undefined) { + signal = init.signal + } + + // 27. Set this’s request to request. + this[kState] = request + + // 28. Set this’s signal to a new AbortSignal object with this’s relevant + // Realm. + // TODO: could this be simplified with AbortSignal.any + // (https://dom.spec.whatwg.org/#dom-abortsignal-any) + const ac = new AbortController() + this[kSignal] = ac.signal + this[kSignal][kRealm] = this[kRealm] + + // 29. If signal is not null, then make this’s signal follow signal. + if (signal != null) { + if ( + !signal || + typeof signal.aborted !== 'boolean' || + typeof signal.addEventListener !== 'function' + ) { + throw new TypeError( + "Failed to construct 'Request': member signal is not of type AbortSignal." + ) + } + + if (signal.aborted) { + ac.abort(signal.reason) + } else { + // Keep a strong ref to ac while request object + // is alive. This is needed to prevent AbortController + // from being prematurely garbage collected. + // See, https://github.com/nodejs/undici/issues/1926. + this[kAbortController] = ac + + const acRef = new WeakRef(ac) + const abort = function () { + const ac = acRef.deref() + if (ac !== undefined) { + ac.abort(this.reason) + } + } + + // Third-party AbortControllers may not work with these. + // See, https://github.com/nodejs/undici/pull/1910#issuecomment-1464495619. + try { + // If the max amount of listeners is equal to the default, increase it + // This is only available in node >= v19.9.0 + if ( + typeof getMaxListeners === 'function' && + getMaxListeners(signal) === defaultMaxListeners + ) { + setMaxListeners(100, signal) + } else if ( + getEventListeners(signal, 'abort').length >= + defaultMaxListeners + ) { + setMaxListeners(100, signal) + } + } catch {} + + util.addAbortListener(signal, abort) + requestFinalizer.register(ac, { signal, abort }) + } + } + + // 30. Set this’s headers to a new Headers object with this’s relevant + // Realm, whose header list is request’s header list and guard is + // "request". + this[kHeaders] = new Headers() + this[kHeaders][kHeadersList] = request.headersList + this[kHeaders][kGuard] = 'request' + this[kHeaders][kRealm] = this[kRealm] + + // 31. If this’s request’s mode is "no-cors", then: + if (mode === 'no-cors') { + // 1. If this’s request’s method is not a CORS-safelisted method, + // then throw a TypeError. + if (!corsSafeListedMethodsSet.has(request.method)) { + throw new TypeError( + `'${request.method} is unsupported in no-cors mode.` + ) + } + + // 2. Set this’s headers’s guard to "request-no-cors". + this[kHeaders][kGuard] = 'request-no-cors' + } + + // 32. If init is not empty, then: + if (Object.keys(init).length !== 0) { + // 1. Let headers be a copy of this’s headers and its associated header + // list. + let headers = new Headers(this[kHeaders]) + + // 2. If init["headers"] exists, then set headers to init["headers"]. + if (init.headers !== undefined) { + headers = init.headers + } + + // 3. Empty this’s headers’s header list. + this[kHeaders][kHeadersList].clear() + + // 4. If headers is a Headers object, then for each header in its header + // list, append header’s name/header’s value to this’s headers. + if (headers.constructor.name === 'Headers') { + for (const [key, val] of headers) { + this[kHeaders].append(key, val) + } + } else { + // 5. Otherwise, fill this’s headers with headers. + fillHeaders(this[kHeaders], headers) + } + } + + // 33. Let inputBody be input’s request’s body if input is a Request + // object; otherwise null. + const inputBody = input instanceof Request ? input[kState].body : null + + // 34. If either init["body"] exists and is non-null or inputBody is + // non-null, and request’s method is `GET` or `HEAD`, then throw a + // TypeError. + if ( + (init.body != null || inputBody != null) && + (request.method === 'GET' || request.method === 'HEAD') + ) { + throw new TypeError( + 'Request with GET/HEAD method cannot have body.' + ) + } + + // 35. Let initBody be null. + let initBody = null + + // 36. If init["body"] exists and is non-null, then: + if (init.body != null) { + // 1. Let Content-Type be null. + // 2. Set initBody and Content-Type to the result of extracting + // init["body"], with keepalive set to request’s keepalive. + const [extractedBody, contentType] = extractBody( + init.body, + request.keepalive + ) + initBody = extractedBody + + // 3, If Content-Type is non-null and this’s headers’s header list does + // not contain `Content-Type`, then append `Content-Type`/Content-Type to + // this’s headers. + if ( + contentType && + !this[kHeaders][kHeadersList].contains('content-type') + ) { + this[kHeaders].append('content-type', contentType) + } + } + + // 37. Let inputOrInitBody be initBody if it is non-null; otherwise + // inputBody. + const inputOrInitBody = initBody ?? inputBody + + // 38. If inputOrInitBody is non-null and inputOrInitBody’s source is + // null, then: + if (inputOrInitBody != null && inputOrInitBody.source == null) { + // 1. If initBody is non-null and init["duplex"] does not exist, + // then throw a TypeError. + if (initBody != null && init.duplex == null) { + throw new TypeError( + 'RequestInit: duplex option is required when sending a body.' + ) + } + + // 2. If this’s request’s mode is neither "same-origin" nor "cors", + // then throw a TypeError. + if (request.mode !== 'same-origin' && request.mode !== 'cors') { + throw new TypeError( + 'If request is made from ReadableStream, mode should be "same-origin" or "cors"' + ) + } + + // 3. Set this’s request’s use-CORS-preflight flag. + request.useCORSPreflightFlag = true + } + + // 39. Let finalBody be inputOrInitBody. + let finalBody = inputOrInitBody + + // 40. If initBody is null and inputBody is non-null, then: + if (initBody == null && inputBody != null) { + // 1. If input is unusable, then throw a TypeError. + if (util.isDisturbed(inputBody.stream) || inputBody.stream.locked) { + throw new TypeError( + 'Cannot construct a Request with a Request object that has already been used.' + ) + } + + // 2. Set finalBody to the result of creating a proxy for inputBody. + if (!TransformStream) { + TransformStream = __nccwpck_require__(5356).TransformStream + } + + // https://streams.spec.whatwg.org/#readablestream-create-a-proxy + const identityTransform = new TransformStream() + inputBody.stream.pipeThrough(identityTransform) + finalBody = { + source: inputBody.source, + length: inputBody.length, + stream: identityTransform.readable, + } + } + + // 41. Set this’s request’s body to finalBody. + this[kState].body = finalBody + } + + // Returns request’s HTTP method, which is "GET" by default. + get method() { + webidl.brandCheck(this, Request) + + // The method getter steps are to return this’s request’s method. + return this[kState].method + } + + // Returns the URL of request as a string. + get url() { + webidl.brandCheck(this, Request) + + // The url getter steps are to return this’s request’s URL, serialized. + return URLSerializer(this[kState].url) + } + + // Returns a Headers object consisting of the headers associated with request. + // Note that headers added in the network layer by the user agent will not + // be accounted for in this object, e.g., the "Host" header. + get headers() { + webidl.brandCheck(this, Request) + + // The headers getter steps are to return this’s headers. + return this[kHeaders] + } + + // Returns the kind of resource requested by request, e.g., "document" + // or "script". + get destination() { + webidl.brandCheck(this, Request) + + // The destination getter are to return this’s request’s destination. + return this[kState].destination + } + + // Returns the referrer of request. Its value can be a same-origin URL if + // explicitly set in init, the empty string to indicate no referrer, and + // "about:client" when defaulting to the global’s default. This is used + // during fetching to determine the value of the `Referer` header of the + // request being made. + get referrer() { + webidl.brandCheck(this, Request) + + // 1. If this’s request’s referrer is "no-referrer", then return the + // empty string. + if (this[kState].referrer === 'no-referrer') { + return '' + } + + // 2. If this’s request’s referrer is "client", then return + // "about:client". + if (this[kState].referrer === 'client') { + return 'about:client' + } + + // Return this’s request’s referrer, serialized. + return this[kState].referrer.toString() + } + + // Returns the referrer policy associated with request. + // This is used during fetching to compute the value of the request’s + // referrer. + get referrerPolicy() { + webidl.brandCheck(this, Request) + + // The referrerPolicy getter steps are to return this’s request’s referrer policy. + return this[kState].referrerPolicy + } + + // Returns the mode associated with request, which is a string indicating + // whether the request will use CORS, or will be restricted to same-origin + // URLs. + get mode() { + webidl.brandCheck(this, Request) + + // The mode getter steps are to return this’s request’s mode. + return this[kState].mode + } + + // Returns the credentials mode associated with request, + // which is a string indicating whether credentials will be sent with the + // request always, never, or only when sent to a same-origin URL. + get credentials() { + // The credentials getter steps are to return this’s request’s credentials mode. + return this[kState].credentials + } + + // Returns the cache mode associated with request, + // which is a string indicating how the request will + // interact with the browser’s cache when fetching. + get cache() { + webidl.brandCheck(this, Request) + + // The cache getter steps are to return this’s request’s cache mode. + return this[kState].cache + } + + // Returns the redirect mode associated with request, + // which is a string indicating how redirects for the + // request will be handled during fetching. A request + // will follow redirects by default. + get redirect() { + webidl.brandCheck(this, Request) + + // The redirect getter steps are to return this’s request’s redirect mode. + return this[kState].redirect + } + + // Returns request’s subresource integrity metadata, which is a + // cryptographic hash of the resource being fetched. Its value + // consists of multiple hashes separated by whitespace. [SRI] + get integrity() { + webidl.brandCheck(this, Request) + + // The integrity getter steps are to return this’s request’s integrity + // metadata. + return this[kState].integrity + } + + // Returns a boolean indicating whether or not request can outlive the + // global in which it was created. + get keepalive() { + webidl.brandCheck(this, Request) + + // The keepalive getter steps are to return this’s request’s keepalive. + return this[kState].keepalive + } + + // Returns a boolean indicating whether or not request is for a reload + // navigation. + get isReloadNavigation() { + webidl.brandCheck(this, Request) + + // The isReloadNavigation getter steps are to return true if this’s + // request’s reload-navigation flag is set; otherwise false. + return this[kState].reloadNavigation + } + + // Returns a boolean indicating whether or not request is for a history + // navigation (a.k.a. back-foward navigation). + get isHistoryNavigation() { + webidl.brandCheck(this, Request) + + // The isHistoryNavigation getter steps are to return true if this’s request’s + // history-navigation flag is set; otherwise false. + return this[kState].historyNavigation + } + + // Returns the signal associated with request, which is an AbortSignal + // object indicating whether or not request has been aborted, and its + // abort event handler. + get signal() { + webidl.brandCheck(this, Request) + + // The signal getter steps are to return this’s signal. + return this[kSignal] + } + + get body() { + webidl.brandCheck(this, Request) + + return this[kState].body ? this[kState].body.stream : null + } + + get bodyUsed() { + webidl.brandCheck(this, Request) + + return ( + !!this[kState].body && util.isDisturbed(this[kState].body.stream) + ) + } + + get duplex() { + webidl.brandCheck(this, Request) + + return 'half' + } + + // Returns a clone of request. + clone() { + webidl.brandCheck(this, Request) + + // 1. If this is unusable, then throw a TypeError. + if (this.bodyUsed || this.body?.locked) { + throw new TypeError('unusable') + } + + // 2. Let clonedRequest be the result of cloning this’s request. + const clonedRequest = cloneRequest(this[kState]) + + // 3. Let clonedRequestObject be the result of creating a Request object, + // given clonedRequest, this’s headers’s guard, and this’s relevant Realm. + const clonedRequestObject = new Request(kInit) + clonedRequestObject[kState] = clonedRequest + clonedRequestObject[kRealm] = this[kRealm] + clonedRequestObject[kHeaders] = new Headers() + clonedRequestObject[kHeaders][kHeadersList] = + clonedRequest.headersList + clonedRequestObject[kHeaders][kGuard] = this[kHeaders][kGuard] + clonedRequestObject[kHeaders][kRealm] = this[kHeaders][kRealm] + + // 4. Make clonedRequestObject’s signal follow this’s signal. + const ac = new AbortController() + if (this.signal.aborted) { + ac.abort(this.signal.reason) + } else { + util.addAbortListener(this.signal, () => { + ac.abort(this.signal.reason) + }) + } + clonedRequestObject[kSignal] = ac.signal + + // 4. Return clonedRequestObject. + return clonedRequestObject + } + } + + mixinBody(Request) + + function makeRequest(init) { + // https://fetch.spec.whatwg.org/#requests + const request = { + method: 'GET', + localURLsOnly: false, + unsafeRequest: false, + body: null, + client: null, + reservedClient: null, + replacesClientId: '', + window: 'client', + keepalive: false, + serviceWorkers: 'all', + initiator: '', + destination: '', + priority: null, + origin: 'client', + policyContainer: 'client', + referrer: 'client', + referrerPolicy: '', + mode: 'no-cors', + useCORSPreflightFlag: false, + credentials: 'same-origin', + useCredentials: false, + cache: 'default', + redirect: 'follow', + integrity: '', + cryptoGraphicsNonceMetadata: '', + parserMetadata: '', + reloadNavigation: false, + historyNavigation: false, + userActivation: false, + taintedOrigin: false, + redirectCount: 0, + responseTainting: 'basic', + preventNoCacheCacheControlHeaderModification: false, + done: false, + timingAllowFailed: false, + ...init, + headersList: init.headersList + ? new HeadersList(init.headersList) + : new HeadersList(), + } + request.url = request.urlList[0] + return request + } + + // https://fetch.spec.whatwg.org/#concept-request-clone + function cloneRequest(request) { + // To clone a request request, run these steps: + + // 1. Let newRequest be a copy of request, except for its body. + const newRequest = makeRequest({ ...request, body: null }) + + // 2. If request’s body is non-null, set newRequest’s body to the + // result of cloning request’s body. + if (request.body != null) { + newRequest.body = cloneBody(request.body) + } + + // 3. Return newRequest. + return newRequest + } + + Object.defineProperties(Request.prototype, { + method: kEnumerableProperty, + url: kEnumerableProperty, + headers: kEnumerableProperty, + redirect: kEnumerableProperty, + clone: kEnumerableProperty, + signal: kEnumerableProperty, + duplex: kEnumerableProperty, + destination: kEnumerableProperty, + body: kEnumerableProperty, + bodyUsed: kEnumerableProperty, + isHistoryNavigation: kEnumerableProperty, + isReloadNavigation: kEnumerableProperty, + keepalive: kEnumerableProperty, + integrity: kEnumerableProperty, + cache: kEnumerableProperty, + credentials: kEnumerableProperty, + attribute: kEnumerableProperty, + referrerPolicy: kEnumerableProperty, + referrer: kEnumerableProperty, + mode: kEnumerableProperty, + [Symbol.toStringTag]: { + value: 'Request', + configurable: true, + }, + }) + + webidl.converters.Request = webidl.interfaceConverter(Request) + + // https://fetch.spec.whatwg.org/#requestinfo + webidl.converters.RequestInfo = function (V) { + if (typeof V === 'string') { + return webidl.converters.USVString(V) + } + + if (V instanceof Request) { + return webidl.converters.Request(V) + } + + return webidl.converters.USVString(V) + } + + webidl.converters.AbortSignal = webidl.interfaceConverter(AbortSignal) + + // https://fetch.spec.whatwg.org/#requestinit + webidl.converters.RequestInit = webidl.dictionaryConverter([ + { + key: 'method', + converter: webidl.converters.ByteString, + }, + { + key: 'headers', + converter: webidl.converters.HeadersInit, + }, + { + key: 'body', + converter: webidl.nullableConverter(webidl.converters.BodyInit), + }, + { + key: 'referrer', + converter: webidl.converters.USVString, + }, + { + key: 'referrerPolicy', + converter: webidl.converters.DOMString, + // https://w3c.github.io/webappsec-referrer-policy/#referrer-policy + allowedValues: referrerPolicy, + }, + { + key: 'mode', + converter: webidl.converters.DOMString, + // https://fetch.spec.whatwg.org/#concept-request-mode + allowedValues: requestMode, + }, + { + key: 'credentials', + converter: webidl.converters.DOMString, + // https://fetch.spec.whatwg.org/#requestcredentials + allowedValues: requestCredentials, + }, + { + key: 'cache', + converter: webidl.converters.DOMString, + // https://fetch.spec.whatwg.org/#requestcache + allowedValues: requestCache, + }, + { + key: 'redirect', + converter: webidl.converters.DOMString, + // https://fetch.spec.whatwg.org/#requestredirect + allowedValues: requestRedirect, + }, + { + key: 'integrity', + converter: webidl.converters.DOMString, + }, + { + key: 'keepalive', + converter: webidl.converters.boolean, + }, + { + key: 'signal', + converter: webidl.nullableConverter((signal) => + webidl.converters.AbortSignal(signal, { strict: false }) + ), + }, + { + key: 'window', + converter: webidl.converters.any, + }, + { + key: 'duplex', + converter: webidl.converters.DOMString, + allowedValues: requestDuplex, + }, + ]) + + module.exports = { Request, makeRequest } + + /***/ + }, + + /***/ 7823: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const { Headers, HeadersList, fill } = __nccwpck_require__(554) + const { extractBody, cloneBody, mixinBody } = __nccwpck_require__(1472) + const util = __nccwpck_require__(3983) + const { kEnumerableProperty } = util + const { + isValidReasonPhrase, + isCancelled, + isAborted, + isBlobLike, + serializeJavascriptValueToJSONString, + isErrorLike, + isomorphicEncode, + } = __nccwpck_require__(2538) + const { redirectStatusSet, nullBodyStatus, DOMException } = + __nccwpck_require__(1037) + const { kState, kHeaders, kGuard, kRealm } = __nccwpck_require__(5861) + const { webidl } = __nccwpck_require__(1744) + const { FormData } = __nccwpck_require__(2015) + const { getGlobalOrigin } = __nccwpck_require__(1246) + const { URLSerializer } = __nccwpck_require__(685) + const { kHeadersList } = __nccwpck_require__(2785) + const assert = __nccwpck_require__(9491) + const { types } = __nccwpck_require__(3837) + + const ReadableStream = + globalThis.ReadableStream || __nccwpck_require__(5356).ReadableStream + const textEncoder = new TextEncoder('utf-8') + + // https://fetch.spec.whatwg.org/#response-class + class Response { + // Creates network error Response. + static error() { + // TODO + const relevantRealm = { settingsObject: {} } + + // The static error() method steps are to return the result of creating a + // Response object, given a new network error, "immutable", and this’s + // relevant Realm. + const responseObject = new Response() + responseObject[kState] = makeNetworkError() + responseObject[kRealm] = relevantRealm + responseObject[kHeaders][kHeadersList] = + responseObject[kState].headersList + responseObject[kHeaders][kGuard] = 'immutable' + responseObject[kHeaders][kRealm] = relevantRealm + return responseObject + } + + // https://fetch.spec.whatwg.org/#dom-response-json + static json(data, init = {}) { + webidl.argumentLengthCheck(arguments, 1, { header: 'Response.json' }) + + if (init !== null) { + init = webidl.converters.ResponseInit(init) + } + + // 1. Let bytes the result of running serialize a JavaScript value to JSON bytes on data. + const bytes = textEncoder.encode( + serializeJavascriptValueToJSONString(data) + ) + + // 2. Let body be the result of extracting bytes. + const body = extractBody(bytes) + + // 3. Let responseObject be the result of creating a Response object, given a new response, + // "response", and this’s relevant Realm. + const relevantRealm = { settingsObject: {} } + const responseObject = new Response() + responseObject[kRealm] = relevantRealm + responseObject[kHeaders][kGuard] = 'response' + responseObject[kHeaders][kRealm] = relevantRealm + + // 4. Perform initialize a response given responseObject, init, and (body, "application/json"). + initializeResponse(responseObject, init, { + body: body[0], + type: 'application/json', + }) + + // 5. Return responseObject. + return responseObject + } + + // Creates a redirect Response that redirects to url with status status. + static redirect(url, status = 302) { + const relevantRealm = { settingsObject: {} } + + webidl.argumentLengthCheck(arguments, 1, { + header: 'Response.redirect', + }) + + url = webidl.converters.USVString(url) + status = webidl.converters['unsigned short'](status) + + // 1. Let parsedURL be the result of parsing url with current settings + // object’s API base URL. + // 2. If parsedURL is failure, then throw a TypeError. + // TODO: base-URL? + let parsedURL + try { + parsedURL = new URL(url, getGlobalOrigin()) + } catch (err) { + throw Object.assign( + new TypeError('Failed to parse URL from ' + url), + { + cause: err, + } + ) + } + + // 3. If status is not a redirect status, then throw a RangeError. + if (!redirectStatusSet.has(status)) { + throw new RangeError('Invalid status code ' + status) + } + + // 4. Let responseObject be the result of creating a Response object, + // given a new response, "immutable", and this’s relevant Realm. + const responseObject = new Response() + responseObject[kRealm] = relevantRealm + responseObject[kHeaders][kGuard] = 'immutable' + responseObject[kHeaders][kRealm] = relevantRealm + + // 5. Set responseObject’s response’s status to status. + responseObject[kState].status = status + + // 6. Let value be parsedURL, serialized and isomorphic encoded. + const value = isomorphicEncode(URLSerializer(parsedURL)) + + // 7. Append `Location`/value to responseObject’s response’s header list. + responseObject[kState].headersList.append('location', value) + + // 8. Return responseObject. + return responseObject + } + + // https://fetch.spec.whatwg.org/#dom-response + constructor(body = null, init = {}) { + if (body !== null) { + body = webidl.converters.BodyInit(body) + } + + init = webidl.converters.ResponseInit(init) + + // TODO + this[kRealm] = { settingsObject: {} } + + // 1. Set this’s response to a new response. + this[kState] = makeResponse({}) + + // 2. Set this’s headers to a new Headers object with this’s relevant + // Realm, whose header list is this’s response’s header list and guard + // is "response". + this[kHeaders] = new Headers() + this[kHeaders][kGuard] = 'response' + this[kHeaders][kHeadersList] = this[kState].headersList + this[kHeaders][kRealm] = this[kRealm] + + // 3. Let bodyWithType be null. + let bodyWithType = null + + // 4. If body is non-null, then set bodyWithType to the result of extracting body. + if (body != null) { + const [extractedBody, type] = extractBody(body) + bodyWithType = { body: extractedBody, type } + } + + // 5. Perform initialize a response given this, init, and bodyWithType. + initializeResponse(this, init, bodyWithType) + } + + // Returns response’s type, e.g., "cors". + get type() { + webidl.brandCheck(this, Response) + + // The type getter steps are to return this’s response’s type. + return this[kState].type + } + + // Returns response’s URL, if it has one; otherwise the empty string. + get url() { + webidl.brandCheck(this, Response) + + const urlList = this[kState].urlList + + // The url getter steps are to return the empty string if this’s + // response’s URL is null; otherwise this’s response’s URL, + // serialized with exclude fragment set to true. + const url = urlList[urlList.length - 1] ?? null + + if (url === null) { + return '' + } + + return URLSerializer(url, true) + } + + // Returns whether response was obtained through a redirect. + get redirected() { + webidl.brandCheck(this, Response) + + // The redirected getter steps are to return true if this’s response’s URL + // list has more than one item; otherwise false. + return this[kState].urlList.length > 1 + } + + // Returns response’s status. + get status() { + webidl.brandCheck(this, Response) + + // The status getter steps are to return this’s response’s status. + return this[kState].status + } + + // Returns whether response’s status is an ok status. + get ok() { + webidl.brandCheck(this, Response) + + // The ok getter steps are to return true if this’s response’s status is an + // ok status; otherwise false. + return this[kState].status >= 200 && this[kState].status <= 299 + } + + // Returns response’s status message. + get statusText() { + webidl.brandCheck(this, Response) + + // The statusText getter steps are to return this’s response’s status + // message. + return this[kState].statusText + } + + // Returns response’s headers as Headers. + get headers() { + webidl.brandCheck(this, Response) + + // The headers getter steps are to return this’s headers. + return this[kHeaders] + } + + get body() { + webidl.brandCheck(this, Response) + + return this[kState].body ? this[kState].body.stream : null + } + + get bodyUsed() { + webidl.brandCheck(this, Response) + + return ( + !!this[kState].body && util.isDisturbed(this[kState].body.stream) + ) + } + + // Returns a clone of response. + clone() { + webidl.brandCheck(this, Response) + + // 1. If this is unusable, then throw a TypeError. + if (this.bodyUsed || (this.body && this.body.locked)) { + throw webidl.errors.exception({ + header: 'Response.clone', + message: 'Body has already been consumed.', + }) + } + + // 2. Let clonedResponse be the result of cloning this’s response. + const clonedResponse = cloneResponse(this[kState]) + + // 3. Return the result of creating a Response object, given + // clonedResponse, this’s headers’s guard, and this’s relevant Realm. + const clonedResponseObject = new Response() + clonedResponseObject[kState] = clonedResponse + clonedResponseObject[kRealm] = this[kRealm] + clonedResponseObject[kHeaders][kHeadersList] = + clonedResponse.headersList + clonedResponseObject[kHeaders][kGuard] = this[kHeaders][kGuard] + clonedResponseObject[kHeaders][kRealm] = this[kHeaders][kRealm] + + return clonedResponseObject + } + } + + mixinBody(Response) + + Object.defineProperties(Response.prototype, { + type: kEnumerableProperty, + url: kEnumerableProperty, + status: kEnumerableProperty, + ok: kEnumerableProperty, + redirected: kEnumerableProperty, + statusText: kEnumerableProperty, + headers: kEnumerableProperty, + clone: kEnumerableProperty, + body: kEnumerableProperty, + bodyUsed: kEnumerableProperty, + [Symbol.toStringTag]: { + value: 'Response', + configurable: true, + }, + }) + + Object.defineProperties(Response, { + json: kEnumerableProperty, + redirect: kEnumerableProperty, + error: kEnumerableProperty, + }) + + // https://fetch.spec.whatwg.org/#concept-response-clone + function cloneResponse(response) { + // To clone a response response, run these steps: + + // 1. If response is a filtered response, then return a new identical + // filtered response whose internal response is a clone of response’s + // internal response. + if (response.internalResponse) { + return filterResponse( + cloneResponse(response.internalResponse), + response.type + ) + } + + // 2. Let newResponse be a copy of response, except for its body. + const newResponse = makeResponse({ ...response, body: null }) + + // 3. If response’s body is non-null, then set newResponse’s body to the + // result of cloning response’s body. + if (response.body != null) { + newResponse.body = cloneBody(response.body) + } + + // 4. Return newResponse. + return newResponse + } + + function makeResponse(init) { + return { + aborted: false, + rangeRequested: false, + timingAllowPassed: false, + requestIncludesCredentials: false, + type: 'default', + status: 200, + timingInfo: null, + cacheState: '', + statusText: '', + ...init, + headersList: init.headersList + ? new HeadersList(init.headersList) + : new HeadersList(), + urlList: init.urlList ? [...init.urlList] : [], + } + } + + function makeNetworkError(reason) { + const isError = isErrorLike(reason) + return makeResponse({ + type: 'error', + status: 0, + error: isError ? reason : new Error(reason ? String(reason) : reason), + aborted: reason && reason.name === 'AbortError', + }) + } + + function makeFilteredResponse(response, state) { + state = { + internalResponse: response, + ...state, + } + + return new Proxy(response, { + get(target, p) { + return p in state ? state[p] : target[p] + }, + set(target, p, value) { + assert(!(p in state)) + target[p] = value + return true + }, + }) + } + + // https://fetch.spec.whatwg.org/#concept-filtered-response + function filterResponse(response, type) { + // Set response to the following filtered response with response as its + // internal response, depending on request’s response tainting: + if (type === 'basic') { + // A basic filtered response is a filtered response whose type is "basic" + // and header list excludes any headers in internal response’s header list + // whose name is a forbidden response-header name. + + // Note: undici does not implement forbidden response-header names + return makeFilteredResponse(response, { + type: 'basic', + headersList: response.headersList, + }) + } else if (type === 'cors') { + // A CORS filtered response is a filtered response whose type is "cors" + // and header list excludes any headers in internal response’s header + // list whose name is not a CORS-safelisted response-header name, given + // internal response’s CORS-exposed header-name list. + + // Note: undici does not implement CORS-safelisted response-header names + return makeFilteredResponse(response, { + type: 'cors', + headersList: response.headersList, + }) + } else if (type === 'opaque') { + // An opaque filtered response is a filtered response whose type is + // "opaque", URL list is the empty list, status is 0, status message + // is the empty byte sequence, header list is empty, and body is null. + + return makeFilteredResponse(response, { + type: 'opaque', + urlList: Object.freeze([]), + status: 0, + statusText: '', + body: null, + }) + } else if (type === 'opaqueredirect') { + // An opaque-redirect filtered response is a filtered response whose type + // is "opaqueredirect", status is 0, status message is the empty byte + // sequence, header list is empty, and body is null. + + return makeFilteredResponse(response, { + type: 'opaqueredirect', + status: 0, + statusText: '', + headersList: [], + body: null, + }) + } else { + assert(false) + } + } + + // https://fetch.spec.whatwg.org/#appropriate-network-error + function makeAppropriateNetworkError(fetchParams, err = null) { + // 1. Assert: fetchParams is canceled. + assert(isCancelled(fetchParams)) + + // 2. Return an aborted network error if fetchParams is aborted; + // otherwise return a network error. + return isAborted(fetchParams) + ? makeNetworkError( + Object.assign( + new DOMException('The operation was aborted.', 'AbortError'), + { cause: err } + ) + ) + : makeNetworkError( + Object.assign(new DOMException('Request was cancelled.'), { + cause: err, + }) + ) + } + + // https://whatpr.org/fetch/1392.html#initialize-a-response + function initializeResponse(response, init, body) { + // 1. If init["status"] is not in the range 200 to 599, inclusive, then + // throw a RangeError. + if (init.status !== null && (init.status < 200 || init.status > 599)) { + throw new RangeError( + 'init["status"] must be in the range of 200 to 599, inclusive.' + ) + } + + // 2. If init["statusText"] does not match the reason-phrase token production, + // then throw a TypeError. + if ('statusText' in init && init.statusText != null) { + // See, https://datatracker.ietf.org/doc/html/rfc7230#section-3.1.2: + // reason-phrase = *( HTAB / SP / VCHAR / obs-text ) + if (!isValidReasonPhrase(String(init.statusText))) { + throw new TypeError('Invalid statusText') + } + } + + // 3. Set response’s response’s status to init["status"]. + if ('status' in init && init.status != null) { + response[kState].status = init.status + } + + // 4. Set response’s response’s status message to init["statusText"]. + if ('statusText' in init && init.statusText != null) { + response[kState].statusText = init.statusText + } + + // 5. If init["headers"] exists, then fill response’s headers with init["headers"]. + if ('headers' in init && init.headers != null) { + fill(response[kHeaders], init.headers) + } + + // 6. If body was given, then: + if (body) { + // 1. If response's status is a null body status, then throw a TypeError. + if (nullBodyStatus.includes(response.status)) { + throw webidl.errors.exception({ + header: 'Response constructor', + message: 'Invalid response status code ' + response.status, + }) + } + + // 2. Set response's body to body's body. + response[kState].body = body.body + + // 3. If body's type is non-null and response's header list does not contain + // `Content-Type`, then append (`Content-Type`, body's type) to response's header list. + if ( + body.type != null && + !response[kState].headersList.contains('Content-Type') + ) { + response[kState].headersList.append('content-type', body.type) + } + } + } + + webidl.converters.ReadableStream = + webidl.interfaceConverter(ReadableStream) + + webidl.converters.FormData = webidl.interfaceConverter(FormData) + + webidl.converters.URLSearchParams = + webidl.interfaceConverter(URLSearchParams) + + // https://fetch.spec.whatwg.org/#typedefdef-xmlhttprequestbodyinit + webidl.converters.XMLHttpRequestBodyInit = function (V) { + if (typeof V === 'string') { + return webidl.converters.USVString(V) + } + + if (isBlobLike(V)) { + return webidl.converters.Blob(V, { strict: false }) + } + + if ( + types.isAnyArrayBuffer(V) || + types.isTypedArray(V) || + types.isDataView(V) + ) { + return webidl.converters.BufferSource(V) + } + + if (util.isFormDataLike(V)) { + return webidl.converters.FormData(V, { strict: false }) + } + + if (V instanceof URLSearchParams) { + return webidl.converters.URLSearchParams(V) + } + + return webidl.converters.DOMString(V) + } + + // https://fetch.spec.whatwg.org/#bodyinit + webidl.converters.BodyInit = function (V) { + if (V instanceof ReadableStream) { + return webidl.converters.ReadableStream(V) + } + + // Note: the spec doesn't include async iterables, + // this is an undici extension. + if (V?.[Symbol.asyncIterator]) { + return V + } + + return webidl.converters.XMLHttpRequestBodyInit(V) + } + + webidl.converters.ResponseInit = webidl.dictionaryConverter([ + { + key: 'status', + converter: webidl.converters['unsigned short'], + defaultValue: 200, + }, + { + key: 'statusText', + converter: webidl.converters.ByteString, + defaultValue: '', + }, + { + key: 'headers', + converter: webidl.converters.HeadersInit, + }, + ]) + + module.exports = { + makeNetworkError, + makeResponse, + makeAppropriateNetworkError, + filterResponse, + Response, + cloneResponse, + } + + /***/ + }, + + /***/ 5861: /***/ (module) => { + 'use strict' + + module.exports = { + kUrl: Symbol('url'), + kHeaders: Symbol('headers'), + kSignal: Symbol('signal'), + kState: Symbol('state'), + kGuard: Symbol('guard'), + kRealm: Symbol('realm'), + } + + /***/ + }, + + /***/ 2538: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const { + redirectStatusSet, + referrerPolicySet: referrerPolicyTokens, + badPortsSet, + } = __nccwpck_require__(1037) + const { getGlobalOrigin } = __nccwpck_require__(1246) + const { performance } = __nccwpck_require__(4074) + const { isBlobLike, toUSVString, ReadableStreamFrom } = + __nccwpck_require__(3983) + const assert = __nccwpck_require__(9491) + const { isUint8Array } = __nccwpck_require__(4978) + + // https://nodejs.org/api/crypto.html#determining-if-crypto-support-is-unavailable + /** @type {import('crypto')|undefined} */ + let crypto + + try { + crypto = __nccwpck_require__(6113) + } catch {} + + function responseURL(response) { + // https://fetch.spec.whatwg.org/#responses + // A response has an associated URL. It is a pointer to the last URL + // in response’s URL list and null if response’s URL list is empty. + const urlList = response.urlList + const length = urlList.length + return length === 0 ? null : urlList[length - 1].toString() + } + + // https://fetch.spec.whatwg.org/#concept-response-location-url + function responseLocationURL(response, requestFragment) { + // 1. If response’s status is not a redirect status, then return null. + if (!redirectStatusSet.has(response.status)) { + return null + } + + // 2. Let location be the result of extracting header list values given + // `Location` and response’s header list. + let location = response.headersList.get('location') + + // 3. If location is a header value, then set location to the result of + // parsing location with response’s URL. + if (location !== null && isValidHeaderValue(location)) { + location = new URL(location, responseURL(response)) + } + + // 4. If location is a URL whose fragment is null, then set location’s + // fragment to requestFragment. + if (location && !location.hash) { + location.hash = requestFragment + } + + // 5. Return location. + return location + } + + /** @returns {URL} */ + function requestCurrentURL(request) { + return request.urlList[request.urlList.length - 1] + } + + function requestBadPort(request) { + // 1. Let url be request’s current URL. + const url = requestCurrentURL(request) + + // 2. If url’s scheme is an HTTP(S) scheme and url’s port is a bad port, + // then return blocked. + if (urlIsHttpHttpsScheme(url) && badPortsSet.has(url.port)) { + return 'blocked' + } + + // 3. Return allowed. + return 'allowed' + } + + function isErrorLike(object) { + return ( + object instanceof Error || + object?.constructor?.name === 'Error' || + object?.constructor?.name === 'DOMException' + ) + } + + // Check whether |statusText| is a ByteString and + // matches the Reason-Phrase token production. + // RFC 2616: https://tools.ietf.org/html/rfc2616 + // RFC 7230: https://tools.ietf.org/html/rfc7230 + // "reason-phrase = *( HTAB / SP / VCHAR / obs-text )" + // https://github.com/chromium/chromium/blob/94.0.4604.1/third_party/blink/renderer/core/fetch/response.cc#L116 + function isValidReasonPhrase(statusText) { + for (let i = 0; i < statusText.length; ++i) { + const c = statusText.charCodeAt(i) + if ( + !( + ( + c === 0x09 || // HTAB + (c >= 0x20 && c <= 0x7e) || // SP / VCHAR + (c >= 0x80 && c <= 0xff) + ) // obs-text + ) + ) { + return false + } + } + return true + } + + function isTokenChar(c) { + return !( + c >= 0x7f || + c <= 0x20 || + c === '(' || + c === ')' || + c === '<' || + c === '>' || + c === '@' || + c === ',' || + c === ';' || + c === ':' || + c === '\\' || + c === '"' || + c === '/' || + c === '[' || + c === ']' || + c === '?' || + c === '=' || + c === '{' || + c === '}' + ) + } + + // See RFC 7230, Section 3.2.6. + // https://github.com/chromium/chromium/blob/d7da0240cae77824d1eda25745c4022757499131/third_party/blink/renderer/platform/network/http_parsers.cc#L321 + function isValidHTTPToken(characters) { + if (!characters || typeof characters !== 'string') { + return false + } + for (let i = 0; i < characters.length; ++i) { + const c = characters.charCodeAt(i) + if (c > 0x7f || !isTokenChar(c)) { + return false + } + } + return true + } + + // https://fetch.spec.whatwg.org/#header-name + // https://github.com/chromium/chromium/blob/b3d37e6f94f87d59e44662d6078f6a12de845d17/net/http/http_util.cc#L342 + function isValidHeaderName(potentialValue) { + if (potentialValue.length === 0) { + return false + } + + return isValidHTTPToken(potentialValue) + } + + /** + * @see https://fetch.spec.whatwg.org/#header-value + * @param {string} potentialValue + */ + function isValidHeaderValue(potentialValue) { + // - Has no leading or trailing HTTP tab or space bytes. + // - Contains no 0x00 (NUL) or HTTP newline bytes. + if ( + potentialValue.startsWith('\t') || + potentialValue.startsWith(' ') || + potentialValue.endsWith('\t') || + potentialValue.endsWith(' ') + ) { + return false + } + + if ( + potentialValue.includes('\0') || + potentialValue.includes('\r') || + potentialValue.includes('\n') + ) { + return false + } + + return true + } + + // https://w3c.github.io/webappsec-referrer-policy/#set-requests-referrer-policy-on-redirect + function setRequestReferrerPolicyOnRedirect(request, actualResponse) { + // Given a request request and a response actualResponse, this algorithm + // updates request’s referrer policy according to the Referrer-Policy + // header (if any) in actualResponse. + + // 1. Let policy be the result of executing § 8.1 Parse a referrer policy + // from a Referrer-Policy header on actualResponse. + + // 8.1 Parse a referrer policy from a Referrer-Policy header + // 1. Let policy-tokens be the result of extracting header list values given `Referrer-Policy` and response’s header list. + const { headersList } = actualResponse + // 2. Let policy be the empty string. + // 3. For each token in policy-tokens, if token is a referrer policy and token is not the empty string, then set policy to token. + // 4. Return policy. + const policyHeader = (headersList.get('referrer-policy') ?? '').split( + ',' + ) + + // Note: As the referrer-policy can contain multiple policies + // separated by comma, we need to loop through all of them + // and pick the first valid one. + // Ref: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy#specify_a_fallback_policy + let policy = '' + if (policyHeader.length > 0) { + // The right-most policy takes precedence. + // The left-most policy is the fallback. + for (let i = policyHeader.length; i !== 0; i--) { + const token = policyHeader[i - 1].trim() + if (referrerPolicyTokens.has(token)) { + policy = token + break + } + } + } + + // 2. If policy is not the empty string, then set request’s referrer policy to policy. + if (policy !== '') { + request.referrerPolicy = policy + } + } + + // https://fetch.spec.whatwg.org/#cross-origin-resource-policy-check + function crossOriginResourcePolicyCheck() { + // TODO + return 'allowed' + } + + // https://fetch.spec.whatwg.org/#concept-cors-check + function corsCheck() { + // TODO + return 'success' + } + + // https://fetch.spec.whatwg.org/#concept-tao-check + function TAOCheck() { + // TODO + return 'success' + } + + function appendFetchMetadata(httpRequest) { + // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-dest-header + // TODO + + // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-mode-header + + // 1. Assert: r’s url is a potentially trustworthy URL. + // TODO + + // 2. Let header be a Structured Header whose value is a token. + let header = null + + // 3. Set header’s value to r’s mode. + header = httpRequest.mode + + // 4. Set a structured field value `Sec-Fetch-Mode`/header in r’s header list. + httpRequest.headersList.set('sec-fetch-mode', header) + + // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-site-header + // TODO + + // https://w3c.github.io/webappsec-fetch-metadata/#sec-fetch-user-header + // TODO + } + + // https://fetch.spec.whatwg.org/#append-a-request-origin-header + function appendRequestOriginHeader(request) { + // 1. Let serializedOrigin be the result of byte-serializing a request origin with request. + let serializedOrigin = request.origin + + // 2. If request’s response tainting is "cors" or request’s mode is "websocket", then append (`Origin`, serializedOrigin) to request’s header list. + if ( + request.responseTainting === 'cors' || + request.mode === 'websocket' + ) { + if (serializedOrigin) { + request.headersList.append('origin', serializedOrigin) + } + + // 3. Otherwise, if request’s method is neither `GET` nor `HEAD`, then: + } else if (request.method !== 'GET' && request.method !== 'HEAD') { + // 1. Switch on request’s referrer policy: + switch (request.referrerPolicy) { + case 'no-referrer': + // Set serializedOrigin to `null`. + serializedOrigin = null + break + case 'no-referrer-when-downgrade': + case 'strict-origin': + case 'strict-origin-when-cross-origin': + // If request’s origin is a tuple origin, its scheme is "https", and request’s current URL’s scheme is not "https", then set serializedOrigin to `null`. + if ( + request.origin && + urlHasHttpsScheme(request.origin) && + !urlHasHttpsScheme(requestCurrentURL(request)) + ) { + serializedOrigin = null + } + break + case 'same-origin': + // If request’s origin is not same origin with request’s current URL’s origin, then set serializedOrigin to `null`. + if (!sameOrigin(request, requestCurrentURL(request))) { + serializedOrigin = null + } + break + default: + // Do nothing. + } + + if (serializedOrigin) { + // 2. Append (`Origin`, serializedOrigin) to request’s header list. + request.headersList.append('origin', serializedOrigin) + } + } + } + + function coarsenedSharedCurrentTime(crossOriginIsolatedCapability) { + // TODO + return performance.now() + } + + // https://fetch.spec.whatwg.org/#create-an-opaque-timing-info + function createOpaqueTimingInfo(timingInfo) { + return { + startTime: timingInfo.startTime ?? 0, + redirectStartTime: 0, + redirectEndTime: 0, + postRedirectStartTime: timingInfo.startTime ?? 0, + finalServiceWorkerStartTime: 0, + finalNetworkResponseStartTime: 0, + finalNetworkRequestStartTime: 0, + endTime: 0, + encodedBodySize: 0, + decodedBodySize: 0, + finalConnectionTimingInfo: null, + } + } + + // https://html.spec.whatwg.org/multipage/origin.html#policy-container + function makePolicyContainer() { + // Note: the fetch spec doesn't make use of embedder policy or CSP list + return { + referrerPolicy: 'strict-origin-when-cross-origin', + } + } + + // https://html.spec.whatwg.org/multipage/origin.html#clone-a-policy-container + function clonePolicyContainer(policyContainer) { + return { + referrerPolicy: policyContainer.referrerPolicy, + } + } + + // https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer + function determineRequestsReferrer(request) { + // 1. Let policy be request's referrer policy. + const policy = request.referrerPolicy + + // Note: policy cannot (shouldn't) be null or an empty string. + assert(policy) + + // 2. Let environment be request’s client. + + let referrerSource = null + + // 3. Switch on request’s referrer: + if (request.referrer === 'client') { + // Note: node isn't a browser and doesn't implement document/iframes, + // so we bypass this step and replace it with our own. + + const globalOrigin = getGlobalOrigin() + + if (!globalOrigin || globalOrigin.origin === 'null') { + return 'no-referrer' + } + + // note: we need to clone it as it's mutated + referrerSource = new URL(globalOrigin) + } else if (request.referrer instanceof URL) { + // Let referrerSource be request’s referrer. + referrerSource = request.referrer + } + + // 4. Let request’s referrerURL be the result of stripping referrerSource for + // use as a referrer. + let referrerURL = stripURLForReferrer(referrerSource) + + // 5. Let referrerOrigin be the result of stripping referrerSource for use as + // a referrer, with the origin-only flag set to true. + const referrerOrigin = stripURLForReferrer(referrerSource, true) + + // 6. If the result of serializing referrerURL is a string whose length is + // greater than 4096, set referrerURL to referrerOrigin. + if (referrerURL.toString().length > 4096) { + referrerURL = referrerOrigin + } + + const areSameOrigin = sameOrigin(request, referrerURL) + const isNonPotentiallyTrustWorthy = + isURLPotentiallyTrustworthy(referrerURL) && + !isURLPotentiallyTrustworthy(request.url) + + // 8. Execute the switch statements corresponding to the value of policy: + switch (policy) { + case 'origin': + return referrerOrigin != null + ? referrerOrigin + : stripURLForReferrer(referrerSource, true) + case 'unsafe-url': + return referrerURL + case 'same-origin': + return areSameOrigin ? referrerOrigin : 'no-referrer' + case 'origin-when-cross-origin': + return areSameOrigin ? referrerURL : referrerOrigin + case 'strict-origin-when-cross-origin': { + const currentURL = requestCurrentURL(request) + + // 1. If the origin of referrerURL and the origin of request’s current + // URL are the same, then return referrerURL. + if (sameOrigin(referrerURL, currentURL)) { + return referrerURL + } + + // 2. If referrerURL is a potentially trustworthy URL and request’s + // current URL is not a potentially trustworthy URL, then return no + // referrer. + if ( + isURLPotentiallyTrustworthy(referrerURL) && + !isURLPotentiallyTrustworthy(currentURL) + ) { + return 'no-referrer' + } + + // 3. Return referrerOrigin. + return referrerOrigin + } + case 'strict-origin': // eslint-disable-line + /** + * 1. If referrerURL is a potentially trustworthy URL and + * request’s current URL is not a potentially trustworthy URL, + * then return no referrer. + * 2. Return referrerOrigin + */ + case 'no-referrer-when-downgrade': // eslint-disable-line + /** + * 1. If referrerURL is a potentially trustworthy URL and + * request’s current URL is not a potentially trustworthy URL, + * then return no referrer. + * 2. Return referrerOrigin + */ + + default: // eslint-disable-line + return isNonPotentiallyTrustWorthy ? 'no-referrer' : referrerOrigin + } + } + + /** + * @see https://w3c.github.io/webappsec-referrer-policy/#strip-url + * @param {URL} url + * @param {boolean|undefined} originOnly + */ + function stripURLForReferrer(url, originOnly) { + // 1. Assert: url is a URL. + assert(url instanceof URL) + + // 2. If url’s scheme is a local scheme, then return no referrer. + if ( + url.protocol === 'file:' || + url.protocol === 'about:' || + url.protocol === 'blank:' + ) { + return 'no-referrer' + } + + // 3. Set url’s username to the empty string. + url.username = '' + + // 4. Set url’s password to the empty string. + url.password = '' + + // 5. Set url’s fragment to null. + url.hash = '' + + // 6. If the origin-only flag is true, then: + if (originOnly) { + // 1. Set url’s path to « the empty string ». + url.pathname = '' + + // 2. Set url’s query to null. + url.search = '' + } + + // 7. Return url. + return url + } + + function isURLPotentiallyTrustworthy(url) { + if (!(url instanceof URL)) { + return false + } + + // If child of about, return true + if (url.href === 'about:blank' || url.href === 'about:srcdoc') { + return true + } + + // If scheme is data, return true + if (url.protocol === 'data:') return true + + // If file, return true + if (url.protocol === 'file:') return true + + return isOriginPotentiallyTrustworthy(url.origin) + + function isOriginPotentiallyTrustworthy(origin) { + // If origin is explicitly null, return false + if (origin == null || origin === 'null') return false + + const originAsURL = new URL(origin) + + // If secure, return true + if ( + originAsURL.protocol === 'https:' || + originAsURL.protocol === 'wss:' + ) { + return true + } + + // If localhost or variants, return true + if ( + /^127(?:\.[0-9]+){0,2}\.[0-9]+$|^\[(?:0*:)*?:?0*1\]$/.test( + originAsURL.hostname + ) || + originAsURL.hostname === 'localhost' || + originAsURL.hostname.includes('localhost.') || + originAsURL.hostname.endsWith('.localhost') + ) { + return true + } + + // If any other, return false + return false + } + } + + /** + * @see https://w3c.github.io/webappsec-subresource-integrity/#does-response-match-metadatalist + * @param {Uint8Array} bytes + * @param {string} metadataList + */ + function bytesMatch(bytes, metadataList) { + // If node is not built with OpenSSL support, we cannot check + // a request's integrity, so allow it by default (the spec will + // allow requests if an invalid hash is given, as precedence). + /* istanbul ignore if: only if node is built with --without-ssl */ + if (crypto === undefined) { + return true + } + + // 1. Let parsedMetadata be the result of parsing metadataList. + const parsedMetadata = parseMetadata(metadataList) + + // 2. If parsedMetadata is no metadata, return true. + if (parsedMetadata === 'no metadata') { + return true + } + + // 3. If parsedMetadata is the empty set, return true. + if (parsedMetadata.length === 0) { + return true + } + + // 4. Let metadata be the result of getting the strongest + // metadata from parsedMetadata. + const list = parsedMetadata.sort((c, d) => d.algo.localeCompare(c.algo)) + // get the strongest algorithm + const strongest = list[0].algo + // get all entries that use the strongest algorithm; ignore weaker + const metadata = list.filter((item) => item.algo === strongest) + + // 5. For each item in metadata: + for (const item of metadata) { + // 1. Let algorithm be the alg component of item. + const algorithm = item.algo + + // 2. Let expectedValue be the val component of item. + let expectedValue = item.hash + + // See https://github.com/web-platform-tests/wpt/commit/e4c5cc7a5e48093220528dfdd1c4012dc3837a0e + // "be liberal with padding". This is annoying, and it's not even in the spec. + + if (expectedValue.endsWith('==')) { + expectedValue = expectedValue.slice(0, -2) + } + + // 3. Let actualValue be the result of applying algorithm to bytes. + let actualValue = crypto + .createHash(algorithm) + .update(bytes) + .digest('base64') + + if (actualValue.endsWith('==')) { + actualValue = actualValue.slice(0, -2) + } + + // 4. If actualValue is a case-sensitive match for expectedValue, + // return true. + if (actualValue === expectedValue) { + return true + } + + let actualBase64URL = crypto + .createHash(algorithm) + .update(bytes) + .digest('base64url') + + if (actualBase64URL.endsWith('==')) { + actualBase64URL = actualBase64URL.slice(0, -2) + } + + if (actualBase64URL === expectedValue) { + return true + } + } + + // 6. Return false. + return false + } + + // https://w3c.github.io/webappsec-subresource-integrity/#grammardef-hash-with-options + // https://www.w3.org/TR/CSP2/#source-list-syntax + // https://www.rfc-editor.org/rfc/rfc5234#appendix-B.1 + const parseHashWithOptions = + /((?sha256|sha384|sha512)-(?[A-z0-9+/]{1}.*={0,2}))( +[\x21-\x7e]?)?/i + + /** + * @see https://w3c.github.io/webappsec-subresource-integrity/#parse-metadata + * @param {string} metadata + */ + function parseMetadata(metadata) { + // 1. Let result be the empty set. + /** @type {{ algo: string, hash: string }[]} */ + const result = [] + + // 2. Let empty be equal to true. + let empty = true + + const supportedHashes = crypto.getHashes() + + // 3. For each token returned by splitting metadata on spaces: + for (const token of metadata.split(' ')) { + // 1. Set empty to false. + empty = false + + // 2. Parse token as a hash-with-options. + const parsedToken = parseHashWithOptions.exec(token) + + // 3. If token does not parse, continue to the next token. + if (parsedToken === null || parsedToken.groups === undefined) { + // Note: Chromium blocks the request at this point, but Firefox + // gives a warning that an invalid integrity was given. The + // correct behavior is to ignore these, and subsequently not + // check the integrity of the resource. + continue + } + + // 4. Let algorithm be the hash-algo component of token. + const algorithm = parsedToken.groups.algo + + // 5. If algorithm is a hash function recognized by the user + // agent, add the parsed token to result. + if (supportedHashes.includes(algorithm.toLowerCase())) { + result.push(parsedToken.groups) + } + } + + // 4. Return no metadata if empty is true, otherwise return result. + if (empty === true) { + return 'no metadata' + } + + return result + } + + // https://w3c.github.io/webappsec-upgrade-insecure-requests/#upgrade-request + function tryUpgradeRequestToAPotentiallyTrustworthyURL(request) { + // TODO + } + + /** + * @link {https://html.spec.whatwg.org/multipage/origin.html#same-origin} + * @param {URL} A + * @param {URL} B + */ + function sameOrigin(A, B) { + // 1. If A and B are the same opaque origin, then return true. + if (A.origin === B.origin && A.origin === 'null') { + return true + } + + // 2. If A and B are both tuple origins and their schemes, + // hosts, and port are identical, then return true. + if ( + A.protocol === B.protocol && + A.hostname === B.hostname && + A.port === B.port + ) { + return true + } + + // 3. Return false. + return false + } + + function createDeferredPromise() { + let res + let rej + const promise = new Promise((resolve, reject) => { + res = resolve + rej = reject + }) + + return { promise, resolve: res, reject: rej } + } + + function isAborted(fetchParams) { + return fetchParams.controller.state === 'aborted' + } + + function isCancelled(fetchParams) { + return ( + fetchParams.controller.state === 'aborted' || + fetchParams.controller.state === 'terminated' + ) + } + + // https://fetch.spec.whatwg.org/#concept-method-normalize + function normalizeMethod(method) { + return /^(DELETE|GET|HEAD|OPTIONS|POST|PUT)$/i.test(method) + ? method.toUpperCase() + : method + } + + // https://infra.spec.whatwg.org/#serialize-a-javascript-value-to-a-json-string + function serializeJavascriptValueToJSONString(value) { + // 1. Let result be ? Call(%JSON.stringify%, undefined, « value »). + const result = JSON.stringify(value) + + // 2. If result is undefined, then throw a TypeError. + if (result === undefined) { + throw new TypeError('Value is not JSON serializable') + } + + // 3. Assert: result is a string. + assert(typeof result === 'string') + + // 4. Return result. + return result + } + + // https://tc39.es/ecma262/#sec-%25iteratorprototype%25-object + const esIteratorPrototype = Object.getPrototypeOf( + Object.getPrototypeOf([][Symbol.iterator]()) + ) + + /** + * @see https://webidl.spec.whatwg.org/#dfn-iterator-prototype-object + * @param {() => unknown[]} iterator + * @param {string} name name of the instance + * @param {'key'|'value'|'key+value'} kind + */ + function makeIterator(iterator, name, kind) { + const object = { + index: 0, + kind, + target: iterator, + } + + const i = { + next() { + // 1. Let interface be the interface for which the iterator prototype object exists. + + // 2. Let thisValue be the this value. + + // 3. Let object be ? ToObject(thisValue). + + // 4. If object is a platform object, then perform a security + // check, passing: + + // 5. If object is not a default iterator object for interface, + // then throw a TypeError. + if (Object.getPrototypeOf(this) !== i) { + throw new TypeError( + `'next' called on an object that does not implement interface ${name} Iterator.` + ) + } + + // 6. Let index be object’s index. + // 7. Let kind be object’s kind. + // 8. Let values be object’s target's value pairs to iterate over. + const { index, kind, target } = object + const values = target() + + // 9. Let len be the length of values. + const len = values.length + + // 10. If index is greater than or equal to len, then return + // CreateIterResultObject(undefined, true). + if (index >= len) { + return { value: undefined, done: true } + } + + // 11. Let pair be the entry in values at index index. + const pair = values[index] + + // 12. Set object’s index to index + 1. + object.index = index + 1 + + // 13. Return the iterator result for pair and kind. + return iteratorResult(pair, kind) + }, + // The class string of an iterator prototype object for a given interface is the + // result of concatenating the identifier of the interface and the string " Iterator". + [Symbol.toStringTag]: `${name} Iterator`, + } + + // The [[Prototype]] internal slot of an iterator prototype object must be %IteratorPrototype%. + Object.setPrototypeOf(i, esIteratorPrototype) + // esIteratorPrototype needs to be the prototype of i + // which is the prototype of an empty object. Yes, it's confusing. + return Object.setPrototypeOf({}, i) + } + + // https://webidl.spec.whatwg.org/#iterator-result + function iteratorResult(pair, kind) { + let result + + // 1. Let result be a value determined by the value of kind: + switch (kind) { + case 'key': { + // 1. Let idlKey be pair’s key. + // 2. Let key be the result of converting idlKey to an + // ECMAScript value. + // 3. result is key. + result = pair[0] + break + } + case 'value': { + // 1. Let idlValue be pair’s value. + // 2. Let value be the result of converting idlValue to + // an ECMAScript value. + // 3. result is value. + result = pair[1] + break + } + case 'key+value': { + // 1. Let idlKey be pair’s key. + // 2. Let idlValue be pair’s value. + // 3. Let key be the result of converting idlKey to an + // ECMAScript value. + // 4. Let value be the result of converting idlValue to + // an ECMAScript value. + // 5. Let array be ! ArrayCreate(2). + // 6. Call ! CreateDataProperty(array, "0", key). + // 7. Call ! CreateDataProperty(array, "1", value). + // 8. result is array. + result = pair + break + } + } + + // 2. Return CreateIterResultObject(result, false). + return { value: result, done: false } + } + + /** + * @see https://fetch.spec.whatwg.org/#body-fully-read + */ + async function fullyReadBody(body, processBody, processBodyError) { + // 1. If taskDestination is null, then set taskDestination to + // the result of starting a new parallel queue. + + // 2. Let successSteps given a byte sequence bytes be to queue a + // fetch task to run processBody given bytes, with taskDestination. + const successSteps = processBody + + // 3. Let errorSteps be to queue a fetch task to run processBodyError, + // with taskDestination. + const errorSteps = processBodyError + + // 4. Let reader be the result of getting a reader for body’s stream. + // If that threw an exception, then run errorSteps with that + // exception and return. + let reader + + try { + reader = body.stream.getReader() + } catch (e) { + errorSteps(e) + return + } + + // 5. Read all bytes from reader, given successSteps and errorSteps. + try { + const result = await readAllBytes(reader) + successSteps(result) + } catch (e) { + errorSteps(e) + } + } + + /** @type {ReadableStream} */ + let ReadableStream = globalThis.ReadableStream + + function isReadableStreamLike(stream) { + if (!ReadableStream) { + ReadableStream = __nccwpck_require__(5356).ReadableStream + } + + return ( + stream instanceof ReadableStream || + (stream[Symbol.toStringTag] === 'ReadableStream' && + typeof stream.tee === 'function') + ) + } + + const MAXIMUM_ARGUMENT_LENGTH = 65535 + + /** + * @see https://infra.spec.whatwg.org/#isomorphic-decode + * @param {number[]|Uint8Array} input + */ + function isomorphicDecode(input) { + // 1. To isomorphic decode a byte sequence input, return a string whose code point + // length is equal to input’s length and whose code points have the same values + // as the values of input’s bytes, in the same order. + + if (input.length < MAXIMUM_ARGUMENT_LENGTH) { + return String.fromCharCode(...input) + } + + return input.reduce( + (previous, current) => previous + String.fromCharCode(current), + '' + ) + } + + /** + * @param {ReadableStreamController} controller + */ + function readableStreamClose(controller) { + try { + controller.close() + } catch (err) { + // TODO: add comment explaining why this error occurs. + if (!err.message.includes('Controller is already closed')) { + throw err + } + } + } + + /** + * @see https://infra.spec.whatwg.org/#isomorphic-encode + * @param {string} input + */ + function isomorphicEncode(input) { + // 1. Assert: input contains no code points greater than U+00FF. + for (let i = 0; i < input.length; i++) { + assert(input.charCodeAt(i) <= 0xff) + } + + // 2. Return a byte sequence whose length is equal to input’s code + // point length and whose bytes have the same values as the + // values of input’s code points, in the same order + return input + } + + /** + * @see https://streams.spec.whatwg.org/#readablestreamdefaultreader-read-all-bytes + * @see https://streams.spec.whatwg.org/#read-loop + * @param {ReadableStreamDefaultReader} reader + */ + async function readAllBytes(reader) { + const bytes = [] + let byteLength = 0 + + while (true) { + const { done, value: chunk } = await reader.read() + + if (done) { + // 1. Call successSteps with bytes. + return Buffer.concat(bytes, byteLength) + } + + // 1. If chunk is not a Uint8Array object, call failureSteps + // with a TypeError and abort these steps. + if (!isUint8Array(chunk)) { + throw new TypeError('Received non-Uint8Array chunk') + } + + // 2. Append the bytes represented by chunk to bytes. + bytes.push(chunk) + byteLength += chunk.length + + // 3. Read-loop given reader, bytes, successSteps, and failureSteps. + } + } + + /** + * @see https://fetch.spec.whatwg.org/#is-local + * @param {URL} url + */ + function urlIsLocal(url) { + assert('protocol' in url) // ensure it's a url object + + const protocol = url.protocol + + return ( + protocol === 'about:' || protocol === 'blob:' || protocol === 'data:' + ) + } + + /** + * @param {string|URL} url + */ + function urlHasHttpsScheme(url) { + if (typeof url === 'string') { + return url.startsWith('https:') + } + + return url.protocol === 'https:' + } + + /** + * @see https://fetch.spec.whatwg.org/#http-scheme + * @param {URL} url + */ + function urlIsHttpHttpsScheme(url) { + assert('protocol' in url) // ensure it's a url object + + const protocol = url.protocol + + return protocol === 'http:' || protocol === 'https:' + } + + /** + * Fetch supports node >= 16.8.0, but Object.hasOwn was added in v16.9.0. + */ + const hasOwn = + Object.hasOwn || + ((dict, key) => Object.prototype.hasOwnProperty.call(dict, key)) + + module.exports = { + isAborted, + isCancelled, + createDeferredPromise, + ReadableStreamFrom, + toUSVString, + tryUpgradeRequestToAPotentiallyTrustworthyURL, + coarsenedSharedCurrentTime, + determineRequestsReferrer, + makePolicyContainer, + clonePolicyContainer, + appendFetchMetadata, + appendRequestOriginHeader, + TAOCheck, + corsCheck, + crossOriginResourcePolicyCheck, + createOpaqueTimingInfo, + setRequestReferrerPolicyOnRedirect, + isValidHTTPToken, + requestBadPort, + requestCurrentURL, + responseURL, + responseLocationURL, + isBlobLike, + isURLPotentiallyTrustworthy, + isValidReasonPhrase, + sameOrigin, + normalizeMethod, + serializeJavascriptValueToJSONString, + makeIterator, + isValidHeaderName, + isValidHeaderValue, + hasOwn, + isErrorLike, + fullyReadBody, + bytesMatch, + isReadableStreamLike, + readableStreamClose, + isomorphicEncode, + isomorphicDecode, + urlIsLocal, + urlHasHttpsScheme, + urlIsHttpHttpsScheme, + readAllBytes, + } + + /***/ + }, + + /***/ 1744: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const { types } = __nccwpck_require__(3837) + const { hasOwn, toUSVString } = __nccwpck_require__(2538) + + /** @type {import('../../types/webidl').Webidl} */ + const webidl = {} + webidl.converters = {} + webidl.util = {} + webidl.errors = {} + + webidl.errors.exception = function (message) { + return new TypeError(`${message.header}: ${message.message}`) + } + + webidl.errors.conversionFailed = function (context) { + const plural = context.types.length === 1 ? '' : ' one of' + const message = + `${context.argument} could not be converted to` + + `${plural}: ${context.types.join(', ')}.` + + return webidl.errors.exception({ + header: context.prefix, + message, + }) + } + + webidl.errors.invalidArgument = function (context) { + return webidl.errors.exception({ + header: context.prefix, + message: `"${context.value}" is an invalid ${context.type}.`, + }) + } + + // https://webidl.spec.whatwg.org/#implements + webidl.brandCheck = function (V, I, opts = undefined) { + if (opts?.strict !== false && !(V instanceof I)) { + throw new TypeError('Illegal invocation') + } else { + return V?.[Symbol.toStringTag] === I.prototype[Symbol.toStringTag] + } + } + + webidl.argumentLengthCheck = function ({ length }, min, ctx) { + if (length < min) { + throw webidl.errors.exception({ + message: + `${min} argument${min !== 1 ? 's' : ''} required, ` + + `but${length ? ' only' : ''} ${length} found.`, + ...ctx, + }) + } + } + + webidl.illegalConstructor = function () { + throw webidl.errors.exception({ + header: 'TypeError', + message: 'Illegal constructor', + }) + } + + // https://tc39.es/ecma262/#sec-ecmascript-data-types-and-values + webidl.util.Type = function (V) { + switch (typeof V) { + case 'undefined': + return 'Undefined' + case 'boolean': + return 'Boolean' + case 'string': + return 'String' + case 'symbol': + return 'Symbol' + case 'number': + return 'Number' + case 'bigint': + return 'BigInt' + case 'function': + case 'object': { + if (V === null) { + return 'Null' + } + + return 'Object' + } + } + } + + // https://webidl.spec.whatwg.org/#abstract-opdef-converttoint + webidl.util.ConvertToInt = function ( + V, + bitLength, + signedness, + opts = {} + ) { + let upperBound + let lowerBound + + // 1. If bitLength is 64, then: + if (bitLength === 64) { + // 1. Let upperBound be 2^53 − 1. + upperBound = Math.pow(2, 53) - 1 + + // 2. If signedness is "unsigned", then let lowerBound be 0. + if (signedness === 'unsigned') { + lowerBound = 0 + } else { + // 3. Otherwise let lowerBound be −2^53 + 1. + lowerBound = Math.pow(-2, 53) + 1 + } + } else if (signedness === 'unsigned') { + // 2. Otherwise, if signedness is "unsigned", then: + + // 1. Let lowerBound be 0. + lowerBound = 0 + + // 2. Let upperBound be 2^bitLength − 1. + upperBound = Math.pow(2, bitLength) - 1 + } else { + // 3. Otherwise: + + // 1. Let lowerBound be -2^bitLength − 1. + lowerBound = Math.pow(-2, bitLength) - 1 + + // 2. Let upperBound be 2^bitLength − 1 − 1. + upperBound = Math.pow(2, bitLength - 1) - 1 + } + + // 4. Let x be ? ToNumber(V). + let x = Number(V) + + // 5. If x is −0, then set x to +0. + if (x === 0) { + x = 0 + } + + // 6. If the conversion is to an IDL type associated + // with the [EnforceRange] extended attribute, then: + if (opts.enforceRange === true) { + // 1. If x is NaN, +∞, or −∞, then throw a TypeError. + if ( + Number.isNaN(x) || + x === Number.POSITIVE_INFINITY || + x === Number.NEGATIVE_INFINITY + ) { + throw webidl.errors.exception({ + header: 'Integer conversion', + message: `Could not convert ${V} to an integer.`, + }) + } + + // 2. Set x to IntegerPart(x). + x = webidl.util.IntegerPart(x) + + // 3. If x < lowerBound or x > upperBound, then + // throw a TypeError. + if (x < lowerBound || x > upperBound) { + throw webidl.errors.exception({ + header: 'Integer conversion', + message: `Value must be between ${lowerBound}-${upperBound}, got ${x}.`, + }) + } + + // 4. Return x. + return x + } + + // 7. If x is not NaN and the conversion is to an IDL + // type associated with the [Clamp] extended + // attribute, then: + if (!Number.isNaN(x) && opts.clamp === true) { + // 1. Set x to min(max(x, lowerBound), upperBound). + x = Math.min(Math.max(x, lowerBound), upperBound) + + // 2. Round x to the nearest integer, choosing the + // even integer if it lies halfway between two, + // and choosing +0 rather than −0. + if (Math.floor(x) % 2 === 0) { + x = Math.floor(x) + } else { + x = Math.ceil(x) + } + + // 3. Return x. + return x + } + + // 8. If x is NaN, +0, +∞, or −∞, then return +0. + if ( + Number.isNaN(x) || + (x === 0 && Object.is(0, x)) || + x === Number.POSITIVE_INFINITY || + x === Number.NEGATIVE_INFINITY + ) { + return 0 + } + + // 9. Set x to IntegerPart(x). + x = webidl.util.IntegerPart(x) + + // 10. Set x to x modulo 2^bitLength. + x = x % Math.pow(2, bitLength) + + // 11. If signedness is "signed" and x ≥ 2^bitLength − 1, + // then return x − 2^bitLength. + if (signedness === 'signed' && x >= Math.pow(2, bitLength) - 1) { + return x - Math.pow(2, bitLength) + } + + // 12. Otherwise, return x. + return x + } + + // https://webidl.spec.whatwg.org/#abstract-opdef-integerpart + webidl.util.IntegerPart = function (n) { + // 1. Let r be floor(abs(n)). + const r = Math.floor(Math.abs(n)) + + // 2. If n < 0, then return -1 × r. + if (n < 0) { + return -1 * r + } + + // 3. Otherwise, return r. + return r + } + + // https://webidl.spec.whatwg.org/#es-sequence + webidl.sequenceConverter = function (converter) { + return (V) => { + // 1. If Type(V) is not Object, throw a TypeError. + if (webidl.util.Type(V) !== 'Object') { + throw webidl.errors.exception({ + header: 'Sequence', + message: `Value of type ${webidl.util.Type(V)} is not an Object.`, + }) + } + + // 2. Let method be ? GetMethod(V, @@iterator). + /** @type {Generator} */ + const method = V?.[Symbol.iterator]?.() + const seq = [] + + // 3. If method is undefined, throw a TypeError. + if (method === undefined || typeof method.next !== 'function') { + throw webidl.errors.exception({ + header: 'Sequence', + message: 'Object is not an iterator.', + }) + } + + // https://webidl.spec.whatwg.org/#create-sequence-from-iterable + while (true) { + const { done, value } = method.next() + + if (done) { + break + } + + seq.push(converter(value)) + } + + return seq + } + } + + // https://webidl.spec.whatwg.org/#es-to-record + webidl.recordConverter = function (keyConverter, valueConverter) { + return (O) => { + // 1. If Type(O) is not Object, throw a TypeError. + if (webidl.util.Type(O) !== 'Object') { + throw webidl.errors.exception({ + header: 'Record', + message: `Value of type ${webidl.util.Type(O)} is not an Object.`, + }) + } + + // 2. Let result be a new empty instance of record. + const result = {} + + if (!types.isProxy(O)) { + // Object.keys only returns enumerable properties + const keys = Object.keys(O) + + for (const key of keys) { + // 1. Let typedKey be key converted to an IDL value of type K. + const typedKey = keyConverter(key) + + // 2. Let value be ? Get(O, key). + // 3. Let typedValue be value converted to an IDL value of type V. + const typedValue = valueConverter(O[key]) + + // 4. Set result[typedKey] to typedValue. + result[typedKey] = typedValue + } + + // 5. Return result. + return result + } + + // 3. Let keys be ? O.[[OwnPropertyKeys]](). + const keys = Reflect.ownKeys(O) + + // 4. For each key of keys. + for (const key of keys) { + // 1. Let desc be ? O.[[GetOwnProperty]](key). + const desc = Reflect.getOwnPropertyDescriptor(O, key) + + // 2. If desc is not undefined and desc.[[Enumerable]] is true: + if (desc?.enumerable) { + // 1. Let typedKey be key converted to an IDL value of type K. + const typedKey = keyConverter(key) + + // 2. Let value be ? Get(O, key). + // 3. Let typedValue be value converted to an IDL value of type V. + const typedValue = valueConverter(O[key]) + + // 4. Set result[typedKey] to typedValue. + result[typedKey] = typedValue + } + } + + // 5. Return result. + return result + } + } + + webidl.interfaceConverter = function (i) { + return (V, opts = {}) => { + if (opts.strict !== false && !(V instanceof i)) { + throw webidl.errors.exception({ + header: i.name, + message: `Expected ${V} to be an instance of ${i.name}.`, + }) + } + + return V + } + } + + webidl.dictionaryConverter = function (converters) { + return (dictionary) => { + const type = webidl.util.Type(dictionary) + const dict = {} + + if (type === 'Null' || type === 'Undefined') { + return dict + } else if (type !== 'Object') { + throw webidl.errors.exception({ + header: 'Dictionary', + message: `Expected ${dictionary} to be one of: Null, Undefined, Object.`, + }) + } + + for (const options of converters) { + const { key, defaultValue, required, converter } = options + + if (required === true) { + if (!hasOwn(dictionary, key)) { + throw webidl.errors.exception({ + header: 'Dictionary', + message: `Missing required key "${key}".`, + }) + } + } + + let value = dictionary[key] + const hasDefault = hasOwn(options, 'defaultValue') + + // Only use defaultValue if value is undefined and + // a defaultValue options was provided. + if (hasDefault && value !== null) { + value = value ?? defaultValue + } + + // A key can be optional and have no default value. + // When this happens, do not perform a conversion, + // and do not assign the key a value. + if (required || hasDefault || value !== undefined) { + value = converter(value) + + if ( + options.allowedValues && + !options.allowedValues.includes(value) + ) { + throw webidl.errors.exception({ + header: 'Dictionary', + message: `${value} is not an accepted type. Expected one of ${options.allowedValues.join( + ', ' + )}.`, + }) + } + + dict[key] = value + } + } + + return dict + } + } + + webidl.nullableConverter = function (converter) { + return (V) => { + if (V === null) { + return V + } + + return converter(V) + } + } + + // https://webidl.spec.whatwg.org/#es-DOMString + webidl.converters.DOMString = function (V, opts = {}) { + // 1. If V is null and the conversion is to an IDL type + // associated with the [LegacyNullToEmptyString] + // extended attribute, then return the DOMString value + // that represents the empty string. + if (V === null && opts.legacyNullToEmptyString) { + return '' + } + + // 2. Let x be ? ToString(V). + if (typeof V === 'symbol') { + throw new TypeError( + 'Could not convert argument of type symbol to string.' + ) + } + + // 3. Return the IDL DOMString value that represents the + // same sequence of code units as the one the + // ECMAScript String value x represents. + return String(V) + } + + // https://webidl.spec.whatwg.org/#es-ByteString + webidl.converters.ByteString = function (V) { + // 1. Let x be ? ToString(V). + // Note: DOMString converter perform ? ToString(V) + const x = webidl.converters.DOMString(V) + + // 2. If the value of any element of x is greater than + // 255, then throw a TypeError. + for (let index = 0; index < x.length; index++) { + const charCode = x.charCodeAt(index) + + if (charCode > 255) { + throw new TypeError( + 'Cannot convert argument to a ByteString because the character at ' + + `index ${index} has a value of ${charCode} which is greater than 255.` + ) + } + } + + // 3. Return an IDL ByteString value whose length is the + // length of x, and where the value of each element is + // the value of the corresponding element of x. + return x + } + + // https://webidl.spec.whatwg.org/#es-USVString + webidl.converters.USVString = toUSVString + + // https://webidl.spec.whatwg.org/#es-boolean + webidl.converters.boolean = function (V) { + // 1. Let x be the result of computing ToBoolean(V). + const x = Boolean(V) + + // 2. Return the IDL boolean value that is the one that represents + // the same truth value as the ECMAScript Boolean value x. + return x + } + + // https://webidl.spec.whatwg.org/#es-any + webidl.converters.any = function (V) { + return V + } + + // https://webidl.spec.whatwg.org/#es-long-long + webidl.converters['long long'] = function (V) { + // 1. Let x be ? ConvertToInt(V, 64, "signed"). + const x = webidl.util.ConvertToInt(V, 64, 'signed') + + // 2. Return the IDL long long value that represents + // the same numeric value as x. + return x + } + + // https://webidl.spec.whatwg.org/#es-unsigned-long-long + webidl.converters['unsigned long long'] = function (V) { + // 1. Let x be ? ConvertToInt(V, 64, "unsigned"). + const x = webidl.util.ConvertToInt(V, 64, 'unsigned') + + // 2. Return the IDL unsigned long long value that + // represents the same numeric value as x. + return x + } + + // https://webidl.spec.whatwg.org/#es-unsigned-long + webidl.converters['unsigned long'] = function (V) { + // 1. Let x be ? ConvertToInt(V, 32, "unsigned"). + const x = webidl.util.ConvertToInt(V, 32, 'unsigned') + + // 2. Return the IDL unsigned long value that + // represents the same numeric value as x. + return x + } + + // https://webidl.spec.whatwg.org/#es-unsigned-short + webidl.converters['unsigned short'] = function (V, opts) { + // 1. Let x be ? ConvertToInt(V, 16, "unsigned"). + const x = webidl.util.ConvertToInt(V, 16, 'unsigned', opts) + + // 2. Return the IDL unsigned short value that represents + // the same numeric value as x. + return x + } + + // https://webidl.spec.whatwg.org/#idl-ArrayBuffer + webidl.converters.ArrayBuffer = function (V, opts = {}) { + // 1. If Type(V) is not Object, or V does not have an + // [[ArrayBufferData]] internal slot, then throw a + // TypeError. + // see: https://tc39.es/ecma262/#sec-properties-of-the-arraybuffer-instances + // see: https://tc39.es/ecma262/#sec-properties-of-the-sharedarraybuffer-instances + if (webidl.util.Type(V) !== 'Object' || !types.isAnyArrayBuffer(V)) { + throw webidl.errors.conversionFailed({ + prefix: `${V}`, + argument: `${V}`, + types: ['ArrayBuffer'], + }) + } + + // 2. If the conversion is not to an IDL type associated + // with the [AllowShared] extended attribute, and + // IsSharedArrayBuffer(V) is true, then throw a + // TypeError. + if (opts.allowShared === false && types.isSharedArrayBuffer(V)) { + throw webidl.errors.exception({ + header: 'ArrayBuffer', + message: 'SharedArrayBuffer is not allowed.', + }) + } + + // 3. If the conversion is not to an IDL type associated + // with the [AllowResizable] extended attribute, and + // IsResizableArrayBuffer(V) is true, then throw a + // TypeError. + // Note: resizable ArrayBuffers are currently a proposal. + + // 4. Return the IDL ArrayBuffer value that is a + // reference to the same object as V. + return V + } + + webidl.converters.TypedArray = function (V, T, opts = {}) { + // 1. Let T be the IDL type V is being converted to. + + // 2. If Type(V) is not Object, or V does not have a + // [[TypedArrayName]] internal slot with a value + // equal to T’s name, then throw a TypeError. + if ( + webidl.util.Type(V) !== 'Object' || + !types.isTypedArray(V) || + V.constructor.name !== T.name + ) { + throw webidl.errors.conversionFailed({ + prefix: `${T.name}`, + argument: `${V}`, + types: [T.name], + }) + } + + // 3. If the conversion is not to an IDL type associated + // with the [AllowShared] extended attribute, and + // IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is + // true, then throw a TypeError. + if (opts.allowShared === false && types.isSharedArrayBuffer(V.buffer)) { + throw webidl.errors.exception({ + header: 'ArrayBuffer', + message: 'SharedArrayBuffer is not allowed.', + }) + } + + // 4. If the conversion is not to an IDL type associated + // with the [AllowResizable] extended attribute, and + // IsResizableArrayBuffer(V.[[ViewedArrayBuffer]]) is + // true, then throw a TypeError. + // Note: resizable array buffers are currently a proposal + + // 5. Return the IDL value of type T that is a reference + // to the same object as V. + return V + } + + webidl.converters.DataView = function (V, opts = {}) { + // 1. If Type(V) is not Object, or V does not have a + // [[DataView]] internal slot, then throw a TypeError. + if (webidl.util.Type(V) !== 'Object' || !types.isDataView(V)) { + throw webidl.errors.exception({ + header: 'DataView', + message: 'Object is not a DataView.', + }) + } + + // 2. If the conversion is not to an IDL type associated + // with the [AllowShared] extended attribute, and + // IsSharedArrayBuffer(V.[[ViewedArrayBuffer]]) is true, + // then throw a TypeError. + if (opts.allowShared === false && types.isSharedArrayBuffer(V.buffer)) { + throw webidl.errors.exception({ + header: 'ArrayBuffer', + message: 'SharedArrayBuffer is not allowed.', + }) + } + + // 3. If the conversion is not to an IDL type associated + // with the [AllowResizable] extended attribute, and + // IsResizableArrayBuffer(V.[[ViewedArrayBuffer]]) is + // true, then throw a TypeError. + // Note: resizable ArrayBuffers are currently a proposal + + // 4. Return the IDL DataView value that is a reference + // to the same object as V. + return V + } + + // https://webidl.spec.whatwg.org/#BufferSource + webidl.converters.BufferSource = function (V, opts = {}) { + if (types.isAnyArrayBuffer(V)) { + return webidl.converters.ArrayBuffer(V, opts) + } + + if (types.isTypedArray(V)) { + return webidl.converters.TypedArray(V, V.constructor) + } + + if (types.isDataView(V)) { + return webidl.converters.DataView(V, opts) + } + + throw new TypeError(`Could not convert ${V} to a BufferSource.`) + } + + webidl.converters['sequence'] = webidl.sequenceConverter( + webidl.converters.ByteString + ) + + webidl.converters['sequence>'] = + webidl.sequenceConverter(webidl.converters['sequence']) + + webidl.converters['record'] = + webidl.recordConverter( + webidl.converters.ByteString, + webidl.converters.ByteString + ) + + module.exports = { + webidl, + } + + /***/ + }, + + /***/ 4854: /***/ (module) => { + 'use strict' + + /** + * @see https://encoding.spec.whatwg.org/#concept-encoding-get + * @param {string|undefined} label + */ + function getEncoding(label) { + if (!label) { + return 'failure' + } + + // 1. Remove any leading and trailing ASCII whitespace from label. + // 2. If label is an ASCII case-insensitive match for any of the + // labels listed in the table below, then return the + // corresponding encoding; otherwise return failure. + switch (label.trim().toLowerCase()) { + case 'unicode-1-1-utf-8': + case 'unicode11utf8': + case 'unicode20utf8': + case 'utf-8': + case 'utf8': + case 'x-unicode20utf8': + return 'UTF-8' + case '866': + case 'cp866': + case 'csibm866': + case 'ibm866': + return 'IBM866' + case 'csisolatin2': + case 'iso-8859-2': + case 'iso-ir-101': + case 'iso8859-2': + case 'iso88592': + case 'iso_8859-2': + case 'iso_8859-2:1987': + case 'l2': + case 'latin2': + return 'ISO-8859-2' + case 'csisolatin3': + case 'iso-8859-3': + case 'iso-ir-109': + case 'iso8859-3': + case 'iso88593': + case 'iso_8859-3': + case 'iso_8859-3:1988': + case 'l3': + case 'latin3': + return 'ISO-8859-3' + case 'csisolatin4': + case 'iso-8859-4': + case 'iso-ir-110': + case 'iso8859-4': + case 'iso88594': + case 'iso_8859-4': + case 'iso_8859-4:1988': + case 'l4': + case 'latin4': + return 'ISO-8859-4' + case 'csisolatincyrillic': + case 'cyrillic': + case 'iso-8859-5': + case 'iso-ir-144': + case 'iso8859-5': + case 'iso88595': + case 'iso_8859-5': + case 'iso_8859-5:1988': + return 'ISO-8859-5' + case 'arabic': + case 'asmo-708': + case 'csiso88596e': + case 'csiso88596i': + case 'csisolatinarabic': + case 'ecma-114': + case 'iso-8859-6': + case 'iso-8859-6-e': + case 'iso-8859-6-i': + case 'iso-ir-127': + case 'iso8859-6': + case 'iso88596': + case 'iso_8859-6': + case 'iso_8859-6:1987': + return 'ISO-8859-6' + case 'csisolatingreek': + case 'ecma-118': + case 'elot_928': + case 'greek': + case 'greek8': + case 'iso-8859-7': + case 'iso-ir-126': + case 'iso8859-7': + case 'iso88597': + case 'iso_8859-7': + case 'iso_8859-7:1987': + case 'sun_eu_greek': + return 'ISO-8859-7' + case 'csiso88598e': + case 'csisolatinhebrew': + case 'hebrew': + case 'iso-8859-8': + case 'iso-8859-8-e': + case 'iso-ir-138': + case 'iso8859-8': + case 'iso88598': + case 'iso_8859-8': + case 'iso_8859-8:1988': + case 'visual': + return 'ISO-8859-8' + case 'csiso88598i': + case 'iso-8859-8-i': + case 'logical': + return 'ISO-8859-8-I' + case 'csisolatin6': + case 'iso-8859-10': + case 'iso-ir-157': + case 'iso8859-10': + case 'iso885910': + case 'l6': + case 'latin6': + return 'ISO-8859-10' + case 'iso-8859-13': + case 'iso8859-13': + case 'iso885913': + return 'ISO-8859-13' + case 'iso-8859-14': + case 'iso8859-14': + case 'iso885914': + return 'ISO-8859-14' + case 'csisolatin9': + case 'iso-8859-15': + case 'iso8859-15': + case 'iso885915': + case 'iso_8859-15': + case 'l9': + return 'ISO-8859-15' + case 'iso-8859-16': + return 'ISO-8859-16' + case 'cskoi8r': + case 'koi': + case 'koi8': + case 'koi8-r': + case 'koi8_r': + return 'KOI8-R' + case 'koi8-ru': + case 'koi8-u': + return 'KOI8-U' + case 'csmacintosh': + case 'mac': + case 'macintosh': + case 'x-mac-roman': + return 'macintosh' + case 'iso-8859-11': + case 'iso8859-11': + case 'iso885911': + case 'tis-620': + case 'windows-874': + return 'windows-874' + case 'cp1250': + case 'windows-1250': + case 'x-cp1250': + return 'windows-1250' + case 'cp1251': + case 'windows-1251': + case 'x-cp1251': + return 'windows-1251' + case 'ansi_x3.4-1968': + case 'ascii': + case 'cp1252': + case 'cp819': + case 'csisolatin1': + case 'ibm819': + case 'iso-8859-1': + case 'iso-ir-100': + case 'iso8859-1': + case 'iso88591': + case 'iso_8859-1': + case 'iso_8859-1:1987': + case 'l1': + case 'latin1': + case 'us-ascii': + case 'windows-1252': + case 'x-cp1252': + return 'windows-1252' + case 'cp1253': + case 'windows-1253': + case 'x-cp1253': + return 'windows-1253' + case 'cp1254': + case 'csisolatin5': + case 'iso-8859-9': + case 'iso-ir-148': + case 'iso8859-9': + case 'iso88599': + case 'iso_8859-9': + case 'iso_8859-9:1989': + case 'l5': + case 'latin5': + case 'windows-1254': + case 'x-cp1254': + return 'windows-1254' + case 'cp1255': + case 'windows-1255': + case 'x-cp1255': + return 'windows-1255' + case 'cp1256': + case 'windows-1256': + case 'x-cp1256': + return 'windows-1256' + case 'cp1257': + case 'windows-1257': + case 'x-cp1257': + return 'windows-1257' + case 'cp1258': + case 'windows-1258': + case 'x-cp1258': + return 'windows-1258' + case 'x-mac-cyrillic': + case 'x-mac-ukrainian': + return 'x-mac-cyrillic' + case 'chinese': + case 'csgb2312': + case 'csiso58gb231280': + case 'gb2312': + case 'gb_2312': + case 'gb_2312-80': + case 'gbk': + case 'iso-ir-58': + case 'x-gbk': + return 'GBK' + case 'gb18030': + return 'gb18030' + case 'big5': + case 'big5-hkscs': + case 'cn-big5': + case 'csbig5': + case 'x-x-big5': + return 'Big5' + case 'cseucpkdfmtjapanese': + case 'euc-jp': + case 'x-euc-jp': + return 'EUC-JP' + case 'csiso2022jp': + case 'iso-2022-jp': + return 'ISO-2022-JP' + case 'csshiftjis': + case 'ms932': + case 'ms_kanji': + case 'shift-jis': + case 'shift_jis': + case 'sjis': + case 'windows-31j': + case 'x-sjis': + return 'Shift_JIS' + case 'cseuckr': + case 'csksc56011987': + case 'euc-kr': + case 'iso-ir-149': + case 'korean': + case 'ks_c_5601-1987': + case 'ks_c_5601-1989': + case 'ksc5601': + case 'ksc_5601': + case 'windows-949': + return 'EUC-KR' + case 'csiso2022kr': + case 'hz-gb-2312': + case 'iso-2022-cn': + case 'iso-2022-cn-ext': + case 'iso-2022-kr': + case 'replacement': + return 'replacement' + case 'unicodefffe': + case 'utf-16be': + return 'UTF-16BE' + case 'csunicode': + case 'iso-10646-ucs-2': + case 'ucs-2': + case 'unicode': + case 'unicodefeff': + case 'utf-16': + case 'utf-16le': + return 'UTF-16LE' + case 'x-user-defined': + return 'x-user-defined' + default: + return 'failure' + } + } + + module.exports = { + getEncoding, + } + + /***/ + }, + + /***/ 1446: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const { staticPropertyDescriptors, readOperation, fireAProgressEvent } = + __nccwpck_require__(7530) + const { kState, kError, kResult, kEvents, kAborted } = + __nccwpck_require__(9054) + const { webidl } = __nccwpck_require__(1744) + const { kEnumerableProperty } = __nccwpck_require__(3983) + + class FileReader extends EventTarget { + constructor() { + super() + + this[kState] = 'empty' + this[kResult] = null + this[kError] = null + this[kEvents] = { + loadend: null, + error: null, + abort: null, + load: null, + progress: null, + loadstart: null, + } + } + + /** + * @see https://w3c.github.io/FileAPI/#dfn-readAsArrayBuffer + * @param {import('buffer').Blob} blob + */ + readAsArrayBuffer(blob) { + webidl.brandCheck(this, FileReader) + + webidl.argumentLengthCheck(arguments, 1, { + header: 'FileReader.readAsArrayBuffer', + }) + + blob = webidl.converters.Blob(blob, { strict: false }) + + // The readAsArrayBuffer(blob) method, when invoked, + // must initiate a read operation for blob with ArrayBuffer. + readOperation(this, blob, 'ArrayBuffer') + } + + /** + * @see https://w3c.github.io/FileAPI/#readAsBinaryString + * @param {import('buffer').Blob} blob + */ + readAsBinaryString(blob) { + webidl.brandCheck(this, FileReader) + + webidl.argumentLengthCheck(arguments, 1, { + header: 'FileReader.readAsBinaryString', + }) + + blob = webidl.converters.Blob(blob, { strict: false }) + + // The readAsBinaryString(blob) method, when invoked, + // must initiate a read operation for blob with BinaryString. + readOperation(this, blob, 'BinaryString') + } + + /** + * @see https://w3c.github.io/FileAPI/#readAsDataText + * @param {import('buffer').Blob} blob + * @param {string?} encoding + */ + readAsText(blob, encoding = undefined) { + webidl.brandCheck(this, FileReader) + + webidl.argumentLengthCheck(arguments, 1, { + header: 'FileReader.readAsText', + }) + + blob = webidl.converters.Blob(blob, { strict: false }) + + if (encoding !== undefined) { + encoding = webidl.converters.DOMString(encoding) + } + + // The readAsText(blob, encoding) method, when invoked, + // must initiate a read operation for blob with Text and encoding. + readOperation(this, blob, 'Text', encoding) + } + + /** + * @see https://w3c.github.io/FileAPI/#dfn-readAsDataURL + * @param {import('buffer').Blob} blob + */ + readAsDataURL(blob) { + webidl.brandCheck(this, FileReader) + + webidl.argumentLengthCheck(arguments, 1, { + header: 'FileReader.readAsDataURL', + }) + + blob = webidl.converters.Blob(blob, { strict: false }) + + // The readAsDataURL(blob) method, when invoked, must + // initiate a read operation for blob with DataURL. + readOperation(this, blob, 'DataURL') + } + + /** + * @see https://w3c.github.io/FileAPI/#dfn-abort + */ + abort() { + // 1. If this's state is "empty" or if this's state is + // "done" set this's result to null and terminate + // this algorithm. + if (this[kState] === 'empty' || this[kState] === 'done') { + this[kResult] = null + return + } + + // 2. If this's state is "loading" set this's state to + // "done" and set this's result to null. + if (this[kState] === 'loading') { + this[kState] = 'done' + this[kResult] = null + } + + // 3. If there are any tasks from this on the file reading + // task source in an affiliated task queue, then remove + // those tasks from that task queue. + this[kAborted] = true + + // 4. Terminate the algorithm for the read method being processed. + // TODO + + // 5. Fire a progress event called abort at this. + fireAProgressEvent('abort', this) + + // 6. If this's state is not "loading", fire a progress + // event called loadend at this. + if (this[kState] !== 'loading') { + fireAProgressEvent('loadend', this) + } + } + + /** + * @see https://w3c.github.io/FileAPI/#dom-filereader-readystate + */ + get readyState() { + webidl.brandCheck(this, FileReader) + + switch (this[kState]) { + case 'empty': + return this.EMPTY + case 'loading': + return this.LOADING + case 'done': + return this.DONE + } + } + + /** + * @see https://w3c.github.io/FileAPI/#dom-filereader-result + */ + get result() { + webidl.brandCheck(this, FileReader) + + // The result attribute’s getter, when invoked, must return + // this's result. + return this[kResult] + } + + /** + * @see https://w3c.github.io/FileAPI/#dom-filereader-error + */ + get error() { + webidl.brandCheck(this, FileReader) + + // The error attribute’s getter, when invoked, must return + // this's error. + return this[kError] + } + + get onloadend() { + webidl.brandCheck(this, FileReader) + + return this[kEvents].loadend + } + + set onloadend(fn) { + webidl.brandCheck(this, FileReader) + + if (this[kEvents].loadend) { + this.removeEventListener('loadend', this[kEvents].loadend) + } + + if (typeof fn === 'function') { + this[kEvents].loadend = fn + this.addEventListener('loadend', fn) + } else { + this[kEvents].loadend = null + } + } + + get onerror() { + webidl.brandCheck(this, FileReader) + + return this[kEvents].error + } + + set onerror(fn) { + webidl.brandCheck(this, FileReader) + + if (this[kEvents].error) { + this.removeEventListener('error', this[kEvents].error) + } + + if (typeof fn === 'function') { + this[kEvents].error = fn + this.addEventListener('error', fn) + } else { + this[kEvents].error = null + } + } + + get onloadstart() { + webidl.brandCheck(this, FileReader) + + return this[kEvents].loadstart + } + + set onloadstart(fn) { + webidl.brandCheck(this, FileReader) + + if (this[kEvents].loadstart) { + this.removeEventListener('loadstart', this[kEvents].loadstart) + } + + if (typeof fn === 'function') { + this[kEvents].loadstart = fn + this.addEventListener('loadstart', fn) + } else { + this[kEvents].loadstart = null + } + } + + get onprogress() { + webidl.brandCheck(this, FileReader) + + return this[kEvents].progress + } + + set onprogress(fn) { + webidl.brandCheck(this, FileReader) + + if (this[kEvents].progress) { + this.removeEventListener('progress', this[kEvents].progress) + } + + if (typeof fn === 'function') { + this[kEvents].progress = fn + this.addEventListener('progress', fn) + } else { + this[kEvents].progress = null + } + } + + get onload() { + webidl.brandCheck(this, FileReader) + + return this[kEvents].load + } + + set onload(fn) { + webidl.brandCheck(this, FileReader) + + if (this[kEvents].load) { + this.removeEventListener('load', this[kEvents].load) + } + + if (typeof fn === 'function') { + this[kEvents].load = fn + this.addEventListener('load', fn) + } else { + this[kEvents].load = null + } + } + + get onabort() { + webidl.brandCheck(this, FileReader) + + return this[kEvents].abort + } + + set onabort(fn) { + webidl.brandCheck(this, FileReader) + + if (this[kEvents].abort) { + this.removeEventListener('abort', this[kEvents].abort) + } + + if (typeof fn === 'function') { + this[kEvents].abort = fn + this.addEventListener('abort', fn) + } else { + this[kEvents].abort = null + } + } + } + + // https://w3c.github.io/FileAPI/#dom-filereader-empty + FileReader.EMPTY = FileReader.prototype.EMPTY = 0 + // https://w3c.github.io/FileAPI/#dom-filereader-loading + FileReader.LOADING = FileReader.prototype.LOADING = 1 + // https://w3c.github.io/FileAPI/#dom-filereader-done + FileReader.DONE = FileReader.prototype.DONE = 2 + + Object.defineProperties(FileReader.prototype, { + EMPTY: staticPropertyDescriptors, + LOADING: staticPropertyDescriptors, + DONE: staticPropertyDescriptors, + readAsArrayBuffer: kEnumerableProperty, + readAsBinaryString: kEnumerableProperty, + readAsText: kEnumerableProperty, + readAsDataURL: kEnumerableProperty, + abort: kEnumerableProperty, + readyState: kEnumerableProperty, + result: kEnumerableProperty, + error: kEnumerableProperty, + onloadstart: kEnumerableProperty, + onprogress: kEnumerableProperty, + onload: kEnumerableProperty, + onabort: kEnumerableProperty, + onerror: kEnumerableProperty, + onloadend: kEnumerableProperty, + [Symbol.toStringTag]: { + value: 'FileReader', + writable: false, + enumerable: false, + configurable: true, + }, + }) + + Object.defineProperties(FileReader, { + EMPTY: staticPropertyDescriptors, + LOADING: staticPropertyDescriptors, + DONE: staticPropertyDescriptors, + }) + + module.exports = { + FileReader, + } + + /***/ + }, + + /***/ 5504: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const { webidl } = __nccwpck_require__(1744) + + const kState = Symbol('ProgressEvent state') + + /** + * @see https://xhr.spec.whatwg.org/#progressevent + */ + class ProgressEvent extends Event { + constructor(type, eventInitDict = {}) { + type = webidl.converters.DOMString(type) + eventInitDict = webidl.converters.ProgressEventInit( + eventInitDict ?? {} + ) + + super(type, eventInitDict) + + this[kState] = { + lengthComputable: eventInitDict.lengthComputable, + loaded: eventInitDict.loaded, + total: eventInitDict.total, + } + } + + get lengthComputable() { + webidl.brandCheck(this, ProgressEvent) + + return this[kState].lengthComputable + } + + get loaded() { + webidl.brandCheck(this, ProgressEvent) + + return this[kState].loaded + } + + get total() { + webidl.brandCheck(this, ProgressEvent) + + return this[kState].total + } + } + + webidl.converters.ProgressEventInit = webidl.dictionaryConverter([ + { + key: 'lengthComputable', + converter: webidl.converters.boolean, + defaultValue: false, + }, + { + key: 'loaded', + converter: webidl.converters['unsigned long long'], + defaultValue: 0, + }, + { + key: 'total', + converter: webidl.converters['unsigned long long'], + defaultValue: 0, + }, + { + key: 'bubbles', + converter: webidl.converters.boolean, + defaultValue: false, + }, + { + key: 'cancelable', + converter: webidl.converters.boolean, + defaultValue: false, + }, + { + key: 'composed', + converter: webidl.converters.boolean, + defaultValue: false, + }, + ]) + + module.exports = { + ProgressEvent, + } + + /***/ + }, + + /***/ 9054: /***/ (module) => { + 'use strict' + + module.exports = { + kState: Symbol('FileReader state'), + kResult: Symbol('FileReader result'), + kError: Symbol('FileReader error'), + kLastProgressEventFired: Symbol( + 'FileReader last progress event fired timestamp' + ), + kEvents: Symbol('FileReader events'), + kAborted: Symbol('FileReader aborted'), + } + + /***/ + }, + + /***/ 7530: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const { kState, kError, kResult, kAborted, kLastProgressEventFired } = + __nccwpck_require__(9054) + const { ProgressEvent } = __nccwpck_require__(5504) + const { getEncoding } = __nccwpck_require__(4854) + const { DOMException } = __nccwpck_require__(1037) + const { serializeAMimeType, parseMIMEType } = __nccwpck_require__(685) + const { types } = __nccwpck_require__(3837) + const { StringDecoder } = __nccwpck_require__(1576) + const { btoa } = __nccwpck_require__(4300) + + /** @type {PropertyDescriptor} */ + const staticPropertyDescriptors = { + enumerable: true, + writable: false, + configurable: false, + } + + /** + * @see https://w3c.github.io/FileAPI/#readOperation + * @param {import('./filereader').FileReader} fr + * @param {import('buffer').Blob} blob + * @param {string} type + * @param {string?} encodingName + */ + function readOperation(fr, blob, type, encodingName) { + // 1. If fr’s state is "loading", throw an InvalidStateError + // DOMException. + if (fr[kState] === 'loading') { + throw new DOMException('Invalid state', 'InvalidStateError') + } + + // 2. Set fr’s state to "loading". + fr[kState] = 'loading' + + // 3. Set fr’s result to null. + fr[kResult] = null + + // 4. Set fr’s error to null. + fr[kError] = null + + // 5. Let stream be the result of calling get stream on blob. + /** @type {import('stream/web').ReadableStream} */ + const stream = blob.stream() + + // 6. Let reader be the result of getting a reader from stream. + const reader = stream.getReader() + + // 7. Let bytes be an empty byte sequence. + /** @type {Uint8Array[]} */ + const bytes = [] + + // 8. Let chunkPromise be the result of reading a chunk from + // stream with reader. + let chunkPromise = reader.read() + + // 9. Let isFirstChunk be true. + let isFirstChunk = true + + // 10. In parallel, while true: + // Note: "In parallel" just means non-blocking + // Note 2: readOperation itself cannot be async as double + // reading the body would then reject the promise, instead + // of throwing an error. + ;(async () => { + while (!fr[kAborted]) { + // 1. Wait for chunkPromise to be fulfilled or rejected. + try { + const { done, value } = await chunkPromise + + // 2. If chunkPromise is fulfilled, and isFirstChunk is + // true, queue a task to fire a progress event called + // loadstart at fr. + if (isFirstChunk && !fr[kAborted]) { + queueMicrotask(() => { + fireAProgressEvent('loadstart', fr) + }) + } + + // 3. Set isFirstChunk to false. + isFirstChunk = false + + // 4. If chunkPromise is fulfilled with an object whose + // done property is false and whose value property is + // a Uint8Array object, run these steps: + if (!done && types.isUint8Array(value)) { + // 1. Let bs be the byte sequence represented by the + // Uint8Array object. + + // 2. Append bs to bytes. + bytes.push(value) + + // 3. If roughly 50ms have passed since these steps + // were last invoked, queue a task to fire a + // progress event called progress at fr. + if ( + (fr[kLastProgressEventFired] === undefined || + Date.now() - fr[kLastProgressEventFired] >= 50) && + !fr[kAborted] + ) { + fr[kLastProgressEventFired] = Date.now() + queueMicrotask(() => { + fireAProgressEvent('progress', fr) + }) + } + + // 4. Set chunkPromise to the result of reading a + // chunk from stream with reader. + chunkPromise = reader.read() + } else if (done) { + // 5. Otherwise, if chunkPromise is fulfilled with an + // object whose done property is true, queue a task + // to run the following steps and abort this algorithm: + queueMicrotask(() => { + // 1. Set fr’s state to "done". + fr[kState] = 'done' + + // 2. Let result be the result of package data given + // bytes, type, blob’s type, and encodingName. + try { + const result = packageData( + bytes, + type, + blob.type, + encodingName + ) + + // 4. Else: + + if (fr[kAborted]) { + return + } + + // 1. Set fr’s result to result. + fr[kResult] = result + + // 2. Fire a progress event called load at the fr. + fireAProgressEvent('load', fr) + } catch (error) { + // 3. If package data threw an exception error: + + // 1. Set fr’s error to error. + fr[kError] = error + + // 2. Fire a progress event called error at fr. + fireAProgressEvent('error', fr) + } + + // 5. If fr’s state is not "loading", fire a progress + // event called loadend at the fr. + if (fr[kState] !== 'loading') { + fireAProgressEvent('loadend', fr) + } + }) + + break + } + } catch (error) { + if (fr[kAborted]) { + return + } + + // 6. Otherwise, if chunkPromise is rejected with an + // error error, queue a task to run the following + // steps and abort this algorithm: + queueMicrotask(() => { + // 1. Set fr’s state to "done". + fr[kState] = 'done' + + // 2. Set fr’s error to error. + fr[kError] = error + + // 3. Fire a progress event called error at fr. + fireAProgressEvent('error', fr) + + // 4. If fr’s state is not "loading", fire a progress + // event called loadend at fr. + if (fr[kState] !== 'loading') { + fireAProgressEvent('loadend', fr) + } + }) + + break + } + } + })() + } + + /** + * @see https://w3c.github.io/FileAPI/#fire-a-progress-event + * @see https://dom.spec.whatwg.org/#concept-event-fire + * @param {string} e The name of the event + * @param {import('./filereader').FileReader} reader + */ + function fireAProgressEvent(e, reader) { + // The progress event e does not bubble. e.bubbles must be false + // The progress event e is NOT cancelable. e.cancelable must be false + const event = new ProgressEvent(e, { + bubbles: false, + cancelable: false, + }) + + reader.dispatchEvent(event) + } + + /** + * @see https://w3c.github.io/FileAPI/#blob-package-data + * @param {Uint8Array[]} bytes + * @param {string} type + * @param {string?} mimeType + * @param {string?} encodingName + */ + function packageData(bytes, type, mimeType, encodingName) { + // 1. A Blob has an associated package data algorithm, given + // bytes, a type, a optional mimeType, and a optional + // encodingName, which switches on type and runs the + // associated steps: + + switch (type) { + case 'DataURL': { + // 1. Return bytes as a DataURL [RFC2397] subject to + // the considerations below: + // * Use mimeType as part of the Data URL if it is + // available in keeping with the Data URL + // specification [RFC2397]. + // * If mimeType is not available return a Data URL + // without a media-type. [RFC2397]. + + // https://datatracker.ietf.org/doc/html/rfc2397#section-3 + // dataurl := "data:" [ mediatype ] [ ";base64" ] "," data + // mediatype := [ type "/" subtype ] *( ";" parameter ) + // data := *urlchar + // parameter := attribute "=" value + let dataURL = 'data:' + + const parsed = parseMIMEType(mimeType || 'application/octet-stream') + + if (parsed !== 'failure') { + dataURL += serializeAMimeType(parsed) + } + + dataURL += ';base64,' + + const decoder = new StringDecoder('latin1') + + for (const chunk of bytes) { + dataURL += btoa(decoder.write(chunk)) + } + + dataURL += btoa(decoder.end()) + + return dataURL + } + case 'Text': { + // 1. Let encoding be failure + let encoding = 'failure' + + // 2. If the encodingName is present, set encoding to the + // result of getting an encoding from encodingName. + if (encodingName) { + encoding = getEncoding(encodingName) + } + + // 3. If encoding is failure, and mimeType is present: + if (encoding === 'failure' && mimeType) { + // 1. Let type be the result of parse a MIME type + // given mimeType. + const type = parseMIMEType(mimeType) + + // 2. If type is not failure, set encoding to the result + // of getting an encoding from type’s parameters["charset"]. + if (type !== 'failure') { + encoding = getEncoding(type.parameters.get('charset')) + } + } + + // 4. If encoding is failure, then set encoding to UTF-8. + if (encoding === 'failure') { + encoding = 'UTF-8' + } + + // 5. Decode bytes using fallback encoding encoding, and + // return the result. + return decode(bytes, encoding) + } + case 'ArrayBuffer': { + // Return a new ArrayBuffer whose contents are bytes. + const sequence = combineByteSequences(bytes) + + return sequence.buffer + } + case 'BinaryString': { + // Return bytes as a binary string, in which every byte + // is represented by a code unit of equal value [0..255]. + let binaryString = '' + + const decoder = new StringDecoder('latin1') + + for (const chunk of bytes) { + binaryString += decoder.write(chunk) + } + + binaryString += decoder.end() + + return binaryString + } + } + } + + /** + * @see https://encoding.spec.whatwg.org/#decode + * @param {Uint8Array[]} ioQueue + * @param {string} encoding + */ + function decode(ioQueue, encoding) { + const bytes = combineByteSequences(ioQueue) + + // 1. Let BOMEncoding be the result of BOM sniffing ioQueue. + const BOMEncoding = BOMSniffing(bytes) + + let slice = 0 + + // 2. If BOMEncoding is non-null: + if (BOMEncoding !== null) { + // 1. Set encoding to BOMEncoding. + encoding = BOMEncoding + + // 2. Read three bytes from ioQueue, if BOMEncoding is + // UTF-8; otherwise read two bytes. + // (Do nothing with those bytes.) + slice = BOMEncoding === 'UTF-8' ? 3 : 2 + } + + // 3. Process a queue with an instance of encoding’s + // decoder, ioQueue, output, and "replacement". + + // 4. Return output. + + const sliced = bytes.slice(slice) + return new TextDecoder(encoding).decode(sliced) + } + + /** + * @see https://encoding.spec.whatwg.org/#bom-sniff + * @param {Uint8Array} ioQueue + */ + function BOMSniffing(ioQueue) { + // 1. Let BOM be the result of peeking 3 bytes from ioQueue, + // converted to a byte sequence. + const [a, b, c] = ioQueue + + // 2. For each of the rows in the table below, starting with + // the first one and going down, if BOM starts with the + // bytes given in the first column, then return the + // encoding given in the cell in the second column of that + // row. Otherwise, return null. + if (a === 0xef && b === 0xbb && c === 0xbf) { + return 'UTF-8' + } else if (a === 0xfe && b === 0xff) { + return 'UTF-16BE' + } else if (a === 0xff && b === 0xfe) { + return 'UTF-16LE' + } + + return null + } + + /** + * @param {Uint8Array[]} sequences + */ + function combineByteSequences(sequences) { + const size = sequences.reduce((a, b) => { + return a + b.byteLength + }, 0) + + let offset = 0 + + return sequences.reduce((a, b) => { + a.set(b, offset) + offset += b.byteLength + return a + }, new Uint8Array(size)) + } + + module.exports = { + staticPropertyDescriptors, + readOperation, + fireAProgressEvent, + } + + /***/ + }, + + /***/ 1892: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + // We include a version number for the Dispatcher API. In case of breaking changes, + // this version number must be increased to avoid conflicts. + const globalDispatcher = Symbol.for('undici.globalDispatcher.1') + const { InvalidArgumentError } = __nccwpck_require__(8045) + const Agent = __nccwpck_require__(7890) + + if (getGlobalDispatcher() === undefined) { + setGlobalDispatcher(new Agent()) + } + + function setGlobalDispatcher(agent) { + if (!agent || typeof agent.dispatch !== 'function') { + throw new InvalidArgumentError('Argument agent must implement Agent') + } + Object.defineProperty(globalThis, globalDispatcher, { + value: agent, + writable: true, + enumerable: false, + configurable: false, + }) + } + + function getGlobalDispatcher() { + return globalThis[globalDispatcher] + } + + module.exports = { + setGlobalDispatcher, + getGlobalDispatcher, + } + + /***/ + }, + + /***/ 6930: /***/ (module) => { + 'use strict' + + module.exports = class DecoratorHandler { + constructor(handler) { + this.handler = handler + } + + onConnect(...args) { + return this.handler.onConnect(...args) + } + + onError(...args) { + return this.handler.onError(...args) + } + + onUpgrade(...args) { + return this.handler.onUpgrade(...args) + } + + onHeaders(...args) { + return this.handler.onHeaders(...args) + } + + onData(...args) { + return this.handler.onData(...args) + } + + onComplete(...args) { + return this.handler.onComplete(...args) + } + + onBodySent(...args) { + return this.handler.onBodySent(...args) + } + } + + /***/ + }, + + /***/ 2860: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const util = __nccwpck_require__(3983) + const { kBodyUsed } = __nccwpck_require__(2785) + const assert = __nccwpck_require__(9491) + const { InvalidArgumentError } = __nccwpck_require__(8045) + const EE = __nccwpck_require__(2361) + + const redirectableStatusCodes = [300, 301, 302, 303, 307, 308] + + const kBody = Symbol('body') + + class BodyAsyncIterable { + constructor(body) { + this[kBody] = body + this[kBodyUsed] = false + } + + async *[Symbol.asyncIterator]() { + assert(!this[kBodyUsed], 'disturbed') + this[kBodyUsed] = true + yield* this[kBody] + } + } + + class RedirectHandler { + constructor(dispatch, maxRedirections, opts, handler) { + if ( + maxRedirections != null && + (!Number.isInteger(maxRedirections) || maxRedirections < 0) + ) { + throw new InvalidArgumentError( + 'maxRedirections must be a positive number' + ) + } + + util.validateHandler(handler, opts.method, opts.upgrade) + + this.dispatch = dispatch + this.location = null + this.abort = null + this.opts = { ...opts, maxRedirections: 0 } // opts must be a copy + this.maxRedirections = maxRedirections + this.handler = handler + this.history = [] + + if (util.isStream(this.opts.body)) { + // TODO (fix): Provide some way for the user to cache the file to e.g. /tmp + // so that it can be dispatched again? + // TODO (fix): Do we need 100-expect support to provide a way to do this properly? + if (util.bodyLength(this.opts.body) === 0) { + this.opts.body.on('data', function () { + assert(false) + }) + } + + if (typeof this.opts.body.readableDidRead !== 'boolean') { + this.opts.body[kBodyUsed] = false + EE.prototype.on.call(this.opts.body, 'data', function () { + this[kBodyUsed] = true + }) + } + } else if ( + this.opts.body && + typeof this.opts.body.pipeTo === 'function' + ) { + // TODO (fix): We can't access ReadableStream internal state + // to determine whether or not it has been disturbed. This is just + // a workaround. + this.opts.body = new BodyAsyncIterable(this.opts.body) + } else if ( + this.opts.body && + typeof this.opts.body !== 'string' && + !ArrayBuffer.isView(this.opts.body) && + util.isIterable(this.opts.body) + ) { + // TODO: Should we allow re-using iterable if !this.opts.idempotent + // or through some other flag? + this.opts.body = new BodyAsyncIterable(this.opts.body) + } + } + + onConnect(abort) { + this.abort = abort + this.handler.onConnect(abort, { history: this.history }) + } + + onUpgrade(statusCode, headers, socket) { + this.handler.onUpgrade(statusCode, headers, socket) + } + + onError(error) { + this.handler.onError(error) + } + + onHeaders(statusCode, headers, resume, statusText) { + this.location = + this.history.length >= this.maxRedirections || + util.isDisturbed(this.opts.body) + ? null + : parseLocation(statusCode, headers) + + if (this.opts.origin) { + this.history.push(new URL(this.opts.path, this.opts.origin)) + } + + if (!this.location) { + return this.handler.onHeaders( + statusCode, + headers, + resume, + statusText + ) + } + + const { origin, pathname, search } = util.parseURL( + new URL( + this.location, + this.opts.origin && new URL(this.opts.path, this.opts.origin) + ) + ) + const path = search ? `${pathname}${search}` : pathname + + // Remove headers referring to the original URL. + // By default it is Host only, unless it's a 303 (see below), which removes also all Content-* headers. + // https://tools.ietf.org/html/rfc7231#section-6.4 + this.opts.headers = cleanRequestHeaders( + this.opts.headers, + statusCode === 303, + this.opts.origin !== origin + ) + this.opts.path = path + this.opts.origin = origin + this.opts.maxRedirections = 0 + this.opts.query = null + + // https://tools.ietf.org/html/rfc7231#section-6.4.4 + // In case of HTTP 303, always replace method to be either HEAD or GET + if (statusCode === 303 && this.opts.method !== 'HEAD') { + this.opts.method = 'GET' + this.opts.body = null + } + } + + onData(chunk) { + if (this.location) { + /* + https://tools.ietf.org/html/rfc7231#section-6.4 + + TLDR: undici always ignores 3xx response bodies. + + Redirection is used to serve the requested resource from another URL, so it is assumes that + no body is generated (and thus can be ignored). Even though generating a body is not prohibited. + + For status 301, 302, 303, 307 and 308 (the latter from RFC 7238), the specs mention that the body usually + (which means it's optional and not mandated) contain just an hyperlink to the value of + the Location response header, so the body can be ignored safely. + + For status 300, which is "Multiple Choices", the spec mentions both generating a Location + response header AND a response body with the other possible location to follow. + Since the spec explicitily chooses not to specify a format for such body and leave it to + servers and browsers implementors, we ignore the body as there is no specified way to eventually parse it. + */ + } else { + return this.handler.onData(chunk) + } + } + + onComplete(trailers) { + if (this.location) { + /* + https://tools.ietf.org/html/rfc7231#section-6.4 + + TLDR: undici always ignores 3xx response trailers as they are not expected in case of redirections + and neither are useful if present. + + See comment on onData method above for more detailed informations. + */ + + this.location = null + this.abort = null + + this.dispatch(this.opts, this) + } else { + this.handler.onComplete(trailers) + } + } + + onBodySent(chunk) { + if (this.handler.onBodySent) { + this.handler.onBodySent(chunk) + } + } + } + + function parseLocation(statusCode, headers) { + if (redirectableStatusCodes.indexOf(statusCode) === -1) { + return null + } + + for (let i = 0; i < headers.length; i += 2) { + if (headers[i].toString().toLowerCase() === 'location') { + return headers[i + 1] + } + } + } + + // https://tools.ietf.org/html/rfc7231#section-6.4.4 + function shouldRemoveHeader(header, removeContent, unknownOrigin) { + return ( + (header.length === 4 && header.toString().toLowerCase() === 'host') || + (removeContent && + header.toString().toLowerCase().indexOf('content-') === 0) || + (unknownOrigin && + header.length === 13 && + header.toString().toLowerCase() === 'authorization') || + (unknownOrigin && + header.length === 6 && + header.toString().toLowerCase() === 'cookie') + ) + } + + // https://tools.ietf.org/html/rfc7231#section-6.4 + function cleanRequestHeaders(headers, removeContent, unknownOrigin) { + const ret = [] + if (Array.isArray(headers)) { + for (let i = 0; i < headers.length; i += 2) { + if (!shouldRemoveHeader(headers[i], removeContent, unknownOrigin)) { + ret.push(headers[i], headers[i + 1]) + } + } + } else if (headers && typeof headers === 'object') { + for (const key of Object.keys(headers)) { + if (!shouldRemoveHeader(key, removeContent, unknownOrigin)) { + ret.push(key, headers[key]) + } + } + } else { + assert(headers == null, 'headers must be an object or an array') + } + return ret + } + + module.exports = RedirectHandler + + /***/ + }, + + /***/ 8861: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const RedirectHandler = __nccwpck_require__(2860) + + function createRedirectInterceptor({ + maxRedirections: defaultMaxRedirections, + }) { + return (dispatch) => { + return function Intercept(opts, handler) { + const { maxRedirections = defaultMaxRedirections } = opts + + if (!maxRedirections) { + return dispatch(opts, handler) + } + + const redirectHandler = new RedirectHandler( + dispatch, + maxRedirections, + opts, + handler + ) + opts = { ...opts, maxRedirections: 0 } // Stop sub dispatcher from also redirecting. + return dispatch(opts, redirectHandler) + } + } + } + + module.exports = createRedirectInterceptor + + /***/ + }, + + /***/ 953: /***/ ( + __unused_webpack_module, + exports, + __nccwpck_require__ + ) => { + 'use strict' + + Object.defineProperty(exports, '__esModule', { value: true }) + exports.SPECIAL_HEADERS = + exports.HEADER_STATE = + exports.MINOR = + exports.MAJOR = + exports.CONNECTION_TOKEN_CHARS = + exports.HEADER_CHARS = + exports.TOKEN = + exports.STRICT_TOKEN = + exports.HEX = + exports.URL_CHAR = + exports.STRICT_URL_CHAR = + exports.USERINFO_CHARS = + exports.MARK = + exports.ALPHANUM = + exports.NUM = + exports.HEX_MAP = + exports.NUM_MAP = + exports.ALPHA = + exports.FINISH = + exports.H_METHOD_MAP = + exports.METHOD_MAP = + exports.METHODS_RTSP = + exports.METHODS_ICE = + exports.METHODS_HTTP = + exports.METHODS = + exports.LENIENT_FLAGS = + exports.FLAGS = + exports.TYPE = + exports.ERROR = + void 0 + const utils_1 = __nccwpck_require__(1891) + // C headers + var ERROR + ;(function (ERROR) { + ERROR[(ERROR['OK'] = 0)] = 'OK' + ERROR[(ERROR['INTERNAL'] = 1)] = 'INTERNAL' + ERROR[(ERROR['STRICT'] = 2)] = 'STRICT' + ERROR[(ERROR['LF_EXPECTED'] = 3)] = 'LF_EXPECTED' + ERROR[(ERROR['UNEXPECTED_CONTENT_LENGTH'] = 4)] = + 'UNEXPECTED_CONTENT_LENGTH' + ERROR[(ERROR['CLOSED_CONNECTION'] = 5)] = 'CLOSED_CONNECTION' + ERROR[(ERROR['INVALID_METHOD'] = 6)] = 'INVALID_METHOD' + ERROR[(ERROR['INVALID_URL'] = 7)] = 'INVALID_URL' + ERROR[(ERROR['INVALID_CONSTANT'] = 8)] = 'INVALID_CONSTANT' + ERROR[(ERROR['INVALID_VERSION'] = 9)] = 'INVALID_VERSION' + ERROR[(ERROR['INVALID_HEADER_TOKEN'] = 10)] = 'INVALID_HEADER_TOKEN' + ERROR[(ERROR['INVALID_CONTENT_LENGTH'] = 11)] = 'INVALID_CONTENT_LENGTH' + ERROR[(ERROR['INVALID_CHUNK_SIZE'] = 12)] = 'INVALID_CHUNK_SIZE' + ERROR[(ERROR['INVALID_STATUS'] = 13)] = 'INVALID_STATUS' + ERROR[(ERROR['INVALID_EOF_STATE'] = 14)] = 'INVALID_EOF_STATE' + ERROR[(ERROR['INVALID_TRANSFER_ENCODING'] = 15)] = + 'INVALID_TRANSFER_ENCODING' + ERROR[(ERROR['CB_MESSAGE_BEGIN'] = 16)] = 'CB_MESSAGE_BEGIN' + ERROR[(ERROR['CB_HEADERS_COMPLETE'] = 17)] = 'CB_HEADERS_COMPLETE' + ERROR[(ERROR['CB_MESSAGE_COMPLETE'] = 18)] = 'CB_MESSAGE_COMPLETE' + ERROR[(ERROR['CB_CHUNK_HEADER'] = 19)] = 'CB_CHUNK_HEADER' + ERROR[(ERROR['CB_CHUNK_COMPLETE'] = 20)] = 'CB_CHUNK_COMPLETE' + ERROR[(ERROR['PAUSED'] = 21)] = 'PAUSED' + ERROR[(ERROR['PAUSED_UPGRADE'] = 22)] = 'PAUSED_UPGRADE' + ERROR[(ERROR['PAUSED_H2_UPGRADE'] = 23)] = 'PAUSED_H2_UPGRADE' + ERROR[(ERROR['USER'] = 24)] = 'USER' + })((ERROR = exports.ERROR || (exports.ERROR = {}))) + var TYPE + ;(function (TYPE) { + TYPE[(TYPE['BOTH'] = 0)] = 'BOTH' + TYPE[(TYPE['REQUEST'] = 1)] = 'REQUEST' + TYPE[(TYPE['RESPONSE'] = 2)] = 'RESPONSE' + })((TYPE = exports.TYPE || (exports.TYPE = {}))) + var FLAGS + ;(function (FLAGS) { + FLAGS[(FLAGS['CONNECTION_KEEP_ALIVE'] = 1)] = 'CONNECTION_KEEP_ALIVE' + FLAGS[(FLAGS['CONNECTION_CLOSE'] = 2)] = 'CONNECTION_CLOSE' + FLAGS[(FLAGS['CONNECTION_UPGRADE'] = 4)] = 'CONNECTION_UPGRADE' + FLAGS[(FLAGS['CHUNKED'] = 8)] = 'CHUNKED' + FLAGS[(FLAGS['UPGRADE'] = 16)] = 'UPGRADE' + FLAGS[(FLAGS['CONTENT_LENGTH'] = 32)] = 'CONTENT_LENGTH' + FLAGS[(FLAGS['SKIPBODY'] = 64)] = 'SKIPBODY' + FLAGS[(FLAGS['TRAILING'] = 128)] = 'TRAILING' + // 1 << 8 is unused + FLAGS[(FLAGS['TRANSFER_ENCODING'] = 512)] = 'TRANSFER_ENCODING' + })((FLAGS = exports.FLAGS || (exports.FLAGS = {}))) + var LENIENT_FLAGS + ;(function (LENIENT_FLAGS) { + LENIENT_FLAGS[(LENIENT_FLAGS['HEADERS'] = 1)] = 'HEADERS' + LENIENT_FLAGS[(LENIENT_FLAGS['CHUNKED_LENGTH'] = 2)] = 'CHUNKED_LENGTH' + LENIENT_FLAGS[(LENIENT_FLAGS['KEEP_ALIVE'] = 4)] = 'KEEP_ALIVE' + })( + (LENIENT_FLAGS = exports.LENIENT_FLAGS || (exports.LENIENT_FLAGS = {})) + ) + var METHODS + ;(function (METHODS) { + METHODS[(METHODS['DELETE'] = 0)] = 'DELETE' + METHODS[(METHODS['GET'] = 1)] = 'GET' + METHODS[(METHODS['HEAD'] = 2)] = 'HEAD' + METHODS[(METHODS['POST'] = 3)] = 'POST' + METHODS[(METHODS['PUT'] = 4)] = 'PUT' + /* pathological */ + METHODS[(METHODS['CONNECT'] = 5)] = 'CONNECT' + METHODS[(METHODS['OPTIONS'] = 6)] = 'OPTIONS' + METHODS[(METHODS['TRACE'] = 7)] = 'TRACE' + /* WebDAV */ + METHODS[(METHODS['COPY'] = 8)] = 'COPY' + METHODS[(METHODS['LOCK'] = 9)] = 'LOCK' + METHODS[(METHODS['MKCOL'] = 10)] = 'MKCOL' + METHODS[(METHODS['MOVE'] = 11)] = 'MOVE' + METHODS[(METHODS['PROPFIND'] = 12)] = 'PROPFIND' + METHODS[(METHODS['PROPPATCH'] = 13)] = 'PROPPATCH' + METHODS[(METHODS['SEARCH'] = 14)] = 'SEARCH' + METHODS[(METHODS['UNLOCK'] = 15)] = 'UNLOCK' + METHODS[(METHODS['BIND'] = 16)] = 'BIND' + METHODS[(METHODS['REBIND'] = 17)] = 'REBIND' + METHODS[(METHODS['UNBIND'] = 18)] = 'UNBIND' + METHODS[(METHODS['ACL'] = 19)] = 'ACL' + /* subversion */ + METHODS[(METHODS['REPORT'] = 20)] = 'REPORT' + METHODS[(METHODS['MKACTIVITY'] = 21)] = 'MKACTIVITY' + METHODS[(METHODS['CHECKOUT'] = 22)] = 'CHECKOUT' + METHODS[(METHODS['MERGE'] = 23)] = 'MERGE' + /* upnp */ + METHODS[(METHODS['M-SEARCH'] = 24)] = 'M-SEARCH' + METHODS[(METHODS['NOTIFY'] = 25)] = 'NOTIFY' + METHODS[(METHODS['SUBSCRIBE'] = 26)] = 'SUBSCRIBE' + METHODS[(METHODS['UNSUBSCRIBE'] = 27)] = 'UNSUBSCRIBE' + /* RFC-5789 */ + METHODS[(METHODS['PATCH'] = 28)] = 'PATCH' + METHODS[(METHODS['PURGE'] = 29)] = 'PURGE' + /* CalDAV */ + METHODS[(METHODS['MKCALENDAR'] = 30)] = 'MKCALENDAR' + /* RFC-2068, section 19.6.1.2 */ + METHODS[(METHODS['LINK'] = 31)] = 'LINK' + METHODS[(METHODS['UNLINK'] = 32)] = 'UNLINK' + /* icecast */ + METHODS[(METHODS['SOURCE'] = 33)] = 'SOURCE' + /* RFC-7540, section 11.6 */ + METHODS[(METHODS['PRI'] = 34)] = 'PRI' + /* RFC-2326 RTSP */ + METHODS[(METHODS['DESCRIBE'] = 35)] = 'DESCRIBE' + METHODS[(METHODS['ANNOUNCE'] = 36)] = 'ANNOUNCE' + METHODS[(METHODS['SETUP'] = 37)] = 'SETUP' + METHODS[(METHODS['PLAY'] = 38)] = 'PLAY' + METHODS[(METHODS['PAUSE'] = 39)] = 'PAUSE' + METHODS[(METHODS['TEARDOWN'] = 40)] = 'TEARDOWN' + METHODS[(METHODS['GET_PARAMETER'] = 41)] = 'GET_PARAMETER' + METHODS[(METHODS['SET_PARAMETER'] = 42)] = 'SET_PARAMETER' + METHODS[(METHODS['REDIRECT'] = 43)] = 'REDIRECT' + METHODS[(METHODS['RECORD'] = 44)] = 'RECORD' + /* RAOP */ + METHODS[(METHODS['FLUSH'] = 45)] = 'FLUSH' + })((METHODS = exports.METHODS || (exports.METHODS = {}))) + exports.METHODS_HTTP = [ + METHODS.DELETE, + METHODS.GET, + METHODS.HEAD, + METHODS.POST, + METHODS.PUT, + METHODS.CONNECT, + METHODS.OPTIONS, + METHODS.TRACE, + METHODS.COPY, + METHODS.LOCK, + METHODS.MKCOL, + METHODS.MOVE, + METHODS.PROPFIND, + METHODS.PROPPATCH, + METHODS.SEARCH, + METHODS.UNLOCK, + METHODS.BIND, + METHODS.REBIND, + METHODS.UNBIND, + METHODS.ACL, + METHODS.REPORT, + METHODS.MKACTIVITY, + METHODS.CHECKOUT, + METHODS.MERGE, + METHODS['M-SEARCH'], + METHODS.NOTIFY, + METHODS.SUBSCRIBE, + METHODS.UNSUBSCRIBE, + METHODS.PATCH, + METHODS.PURGE, + METHODS.MKCALENDAR, + METHODS.LINK, + METHODS.UNLINK, + METHODS.PRI, + // TODO(indutny): should we allow it with HTTP? + METHODS.SOURCE, + ] + exports.METHODS_ICE = [METHODS.SOURCE] + exports.METHODS_RTSP = [ + METHODS.OPTIONS, + METHODS.DESCRIBE, + METHODS.ANNOUNCE, + METHODS.SETUP, + METHODS.PLAY, + METHODS.PAUSE, + METHODS.TEARDOWN, + METHODS.GET_PARAMETER, + METHODS.SET_PARAMETER, + METHODS.REDIRECT, + METHODS.RECORD, + METHODS.FLUSH, + // For AirPlay + METHODS.GET, + METHODS.POST, + ] + exports.METHOD_MAP = utils_1.enumToMap(METHODS) + exports.H_METHOD_MAP = {} + Object.keys(exports.METHOD_MAP).forEach((key) => { + if (/^H/.test(key)) { + exports.H_METHOD_MAP[key] = exports.METHOD_MAP[key] + } + }) + var FINISH + ;(function (FINISH) { + FINISH[(FINISH['SAFE'] = 0)] = 'SAFE' + FINISH[(FINISH['SAFE_WITH_CB'] = 1)] = 'SAFE_WITH_CB' + FINISH[(FINISH['UNSAFE'] = 2)] = 'UNSAFE' + })((FINISH = exports.FINISH || (exports.FINISH = {}))) + exports.ALPHA = [] + for (let i = 'A'.charCodeAt(0); i <= 'Z'.charCodeAt(0); i++) { + // Upper case + exports.ALPHA.push(String.fromCharCode(i)) + // Lower case + exports.ALPHA.push(String.fromCharCode(i + 0x20)) + } + exports.NUM_MAP = { + 0: 0, + 1: 1, + 2: 2, + 3: 3, + 4: 4, + 5: 5, + 6: 6, + 7: 7, + 8: 8, + 9: 9, + } + exports.HEX_MAP = { + 0: 0, + 1: 1, + 2: 2, + 3: 3, + 4: 4, + 5: 5, + 6: 6, + 7: 7, + 8: 8, + 9: 9, + A: 0xa, + B: 0xb, + C: 0xc, + D: 0xd, + E: 0xe, + F: 0xf, + a: 0xa, + b: 0xb, + c: 0xc, + d: 0xd, + e: 0xe, + f: 0xf, + } + exports.NUM = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'] + exports.ALPHANUM = exports.ALPHA.concat(exports.NUM) + exports.MARK = ['-', '_', '.', '!', '~', '*', "'", '(', ')'] + exports.USERINFO_CHARS = exports.ALPHANUM.concat(exports.MARK).concat([ + '%', + ';', + ':', + '&', + '=', + '+', + '$', + ',', + ]) + // TODO(indutny): use RFC + exports.STRICT_URL_CHAR = [ + '!', + '"', + '$', + '%', + '&', + "'", + '(', + ')', + '*', + '+', + ',', + '-', + '.', + '/', + ':', + ';', + '<', + '=', + '>', + '@', + '[', + '\\', + ']', + '^', + '_', + '`', + '{', + '|', + '}', + '~', + ].concat(exports.ALPHANUM) + exports.URL_CHAR = exports.STRICT_URL_CHAR.concat(['\t', '\f']) + // All characters with 0x80 bit set to 1 + for (let i = 0x80; i <= 0xff; i++) { + exports.URL_CHAR.push(i) + } + exports.HEX = exports.NUM.concat([ + 'a', + 'b', + 'c', + 'd', + 'e', + 'f', + 'A', + 'B', + 'C', + 'D', + 'E', + 'F', + ]) + /* Tokens as defined by rfc 2616. Also lowercases them. + * token = 1* + * separators = "(" | ")" | "<" | ">" | "@" + * | "," | ";" | ":" | "\" | <"> + * | "/" | "[" | "]" | "?" | "=" + * | "{" | "}" | SP | HT + */ + exports.STRICT_TOKEN = [ + '!', + '#', + '$', + '%', + '&', + "'", + '*', + '+', + '-', + '.', + '^', + '_', + '`', + '|', + '~', + ].concat(exports.ALPHANUM) + exports.TOKEN = exports.STRICT_TOKEN.concat([' ']) + /* + * Verify that a char is a valid visible (printable) US-ASCII + * character or %x80-FF + */ + exports.HEADER_CHARS = ['\t'] + for (let i = 32; i <= 255; i++) { + if (i !== 127) { + exports.HEADER_CHARS.push(i) + } + } + // ',' = \x44 + exports.CONNECTION_TOKEN_CHARS = exports.HEADER_CHARS.filter( + (c) => c !== 44 + ) + exports.MAJOR = exports.NUM_MAP + exports.MINOR = exports.MAJOR + var HEADER_STATE + ;(function (HEADER_STATE) { + HEADER_STATE[(HEADER_STATE['GENERAL'] = 0)] = 'GENERAL' + HEADER_STATE[(HEADER_STATE['CONNECTION'] = 1)] = 'CONNECTION' + HEADER_STATE[(HEADER_STATE['CONTENT_LENGTH'] = 2)] = 'CONTENT_LENGTH' + HEADER_STATE[(HEADER_STATE['TRANSFER_ENCODING'] = 3)] = + 'TRANSFER_ENCODING' + HEADER_STATE[(HEADER_STATE['UPGRADE'] = 4)] = 'UPGRADE' + HEADER_STATE[(HEADER_STATE['CONNECTION_KEEP_ALIVE'] = 5)] = + 'CONNECTION_KEEP_ALIVE' + HEADER_STATE[(HEADER_STATE['CONNECTION_CLOSE'] = 6)] = + 'CONNECTION_CLOSE' + HEADER_STATE[(HEADER_STATE['CONNECTION_UPGRADE'] = 7)] = + 'CONNECTION_UPGRADE' + HEADER_STATE[(HEADER_STATE['TRANSFER_ENCODING_CHUNKED'] = 8)] = + 'TRANSFER_ENCODING_CHUNKED' + })((HEADER_STATE = exports.HEADER_STATE || (exports.HEADER_STATE = {}))) + exports.SPECIAL_HEADERS = { + connection: HEADER_STATE.CONNECTION, + 'content-length': HEADER_STATE.CONTENT_LENGTH, + 'proxy-connection': HEADER_STATE.CONNECTION, + 'transfer-encoding': HEADER_STATE.TRANSFER_ENCODING, + upgrade: HEADER_STATE.UPGRADE, + } + //# sourceMappingURL=constants.js.map + + /***/ + }, + + /***/ 1145: /***/ (module) => { + module.exports = + 'AGFzbQEAAAABMAhgAX8Bf2ADf39/AX9gBH9/f38Bf2AAAGADf39/AGABfwBgAn9/AGAGf39/f39/AALLAQgDZW52GHdhc21fb25faGVhZGVyc19jb21wbGV0ZQACA2VudhV3YXNtX29uX21lc3NhZ2VfYmVnaW4AAANlbnYLd2FzbV9vbl91cmwAAQNlbnYOd2FzbV9vbl9zdGF0dXMAAQNlbnYUd2FzbV9vbl9oZWFkZXJfZmllbGQAAQNlbnYUd2FzbV9vbl9oZWFkZXJfdmFsdWUAAQNlbnYMd2FzbV9vbl9ib2R5AAEDZW52GHdhc21fb25fbWVzc2FnZV9jb21wbGV0ZQAAA0ZFAwMEAAAFAAAAAAAABQEFAAUFBQAABgAAAAAGBgYGAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAABAQcAAAUFAwABBAUBcAESEgUDAQACBggBfwFBgNQECwfRBSIGbWVtb3J5AgALX2luaXRpYWxpemUACRlfX2luZGlyZWN0X2Z1bmN0aW9uX3RhYmxlAQALbGxodHRwX2luaXQAChhsbGh0dHBfc2hvdWxkX2tlZXBfYWxpdmUAQQxsbGh0dHBfYWxsb2MADAZtYWxsb2MARgtsbGh0dHBfZnJlZQANBGZyZWUASA9sbGh0dHBfZ2V0X3R5cGUADhVsbGh0dHBfZ2V0X2h0dHBfbWFqb3IADxVsbGh0dHBfZ2V0X2h0dHBfbWlub3IAEBFsbGh0dHBfZ2V0X21ldGhvZAARFmxsaHR0cF9nZXRfc3RhdHVzX2NvZGUAEhJsbGh0dHBfZ2V0X3VwZ3JhZGUAEwxsbGh0dHBfcmVzZXQAFA5sbGh0dHBfZXhlY3V0ZQAVFGxsaHR0cF9zZXR0aW5nc19pbml0ABYNbGxodHRwX2ZpbmlzaAAXDGxsaHR0cF9wYXVzZQAYDWxsaHR0cF9yZXN1bWUAGRtsbGh0dHBfcmVzdW1lX2FmdGVyX3VwZ3JhZGUAGhBsbGh0dHBfZ2V0X2Vycm5vABsXbGxodHRwX2dldF9lcnJvcl9yZWFzb24AHBdsbGh0dHBfc2V0X2Vycm9yX3JlYXNvbgAdFGxsaHR0cF9nZXRfZXJyb3JfcG9zAB4RbGxodHRwX2Vycm5vX25hbWUAHxJsbGh0dHBfbWV0aG9kX25hbWUAIBJsbGh0dHBfc3RhdHVzX25hbWUAIRpsbGh0dHBfc2V0X2xlbmllbnRfaGVhZGVycwAiIWxsaHR0cF9zZXRfbGVuaWVudF9jaHVua2VkX2xlbmd0aAAjHWxsaHR0cF9zZXRfbGVuaWVudF9rZWVwX2FsaXZlACQkbGxodHRwX3NldF9sZW5pZW50X3RyYW5zZmVyX2VuY29kaW5nACUYbGxodHRwX21lc3NhZ2VfbmVlZHNfZW9mAD8JFwEAQQELEQECAwQFCwYHNTk3MS8tJyspCsLgAkUCAAsIABCIgICAAAsZACAAEMKAgIAAGiAAIAI2AjggACABOgAoCxwAIAAgAC8BMiAALQAuIAAQwYCAgAAQgICAgAALKgEBf0HAABDGgICAACIBEMKAgIAAGiABQYCIgIAANgI4IAEgADoAKCABCwoAIAAQyICAgAALBwAgAC0AKAsHACAALQAqCwcAIAAtACsLBwAgAC0AKQsHACAALwEyCwcAIAAtAC4LRQEEfyAAKAIYIQEgAC0ALSECIAAtACghAyAAKAI4IQQgABDCgICAABogACAENgI4IAAgAzoAKCAAIAI6AC0gACABNgIYCxEAIAAgASABIAJqEMOAgIAACxAAIABBAEHcABDMgICAABoLZwEBf0EAIQECQCAAKAIMDQACQAJAAkACQCAALQAvDgMBAAMCCyAAKAI4IgFFDQAgASgCLCIBRQ0AIAAgARGAgICAAAAiAQ0DC0EADwsQyoCAgAAACyAAQcOWgIAANgIQQQ4hAQsgAQseAAJAIAAoAgwNACAAQdGbgIAANgIQIABBFTYCDAsLFgACQCAAKAIMQRVHDQAgAEEANgIMCwsWAAJAIAAoAgxBFkcNACAAQQA2AgwLCwcAIAAoAgwLBwAgACgCEAsJACAAIAE2AhALBwAgACgCFAsiAAJAIABBJEkNABDKgICAAAALIABBAnRBoLOAgABqKAIACyIAAkAgAEEuSQ0AEMqAgIAAAAsgAEECdEGwtICAAGooAgAL7gsBAX9B66iAgAAhAQJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIABBnH9qDvQDY2IAAWFhYWFhYQIDBAVhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhBgcICQoLDA0OD2FhYWFhEGFhYWFhYWFhYWFhEWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYRITFBUWFxgZGhthYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2YTc4OTphYWFhYWFhYTthYWE8YWFhYT0+P2FhYWFhYWFhQGFhQWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYUJDREVGR0hJSktMTU5PUFFSU2FhYWFhYWFhVFVWV1hZWlthXF1hYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFeYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhX2BhC0Hhp4CAAA8LQaShgIAADwtBy6yAgAAPC0H+sYCAAA8LQcCkgIAADwtBq6SAgAAPC0GNqICAAA8LQeKmgIAADwtBgLCAgAAPC0G5r4CAAA8LQdekgIAADwtB75+AgAAPC0Hhn4CAAA8LQfqfgIAADwtB8qCAgAAPC0Gor4CAAA8LQa6ygIAADwtBiLCAgAAPC0Hsp4CAAA8LQYKigIAADwtBjp2AgAAPC0HQroCAAA8LQcqjgIAADwtBxbKAgAAPC0HfnICAAA8LQdKcgIAADwtBxKCAgAAPC0HXoICAAA8LQaKfgIAADwtB7a6AgAAPC0GrsICAAA8LQdSlgIAADwtBzK6AgAAPC0H6roCAAA8LQfyrgIAADwtB0rCAgAAPC0HxnYCAAA8LQbuggIAADwtB96uAgAAPC0GQsYCAAA8LQdexgIAADwtBoq2AgAAPC0HUp4CAAA8LQeCrgIAADwtBn6yAgAAPC0HrsYCAAA8LQdWfgIAADwtByrGAgAAPC0HepYCAAA8LQdSegIAADwtB9JyAgAAPC0GnsoCAAA8LQbGdgIAADwtBoJ2AgAAPC0G5sYCAAA8LQbywgIAADwtBkqGAgAAPC0GzpoCAAA8LQemsgIAADwtBrJ6AgAAPC0HUq4CAAA8LQfemgIAADwtBgKaAgAAPC0GwoYCAAA8LQf6egIAADwtBjaOAgAAPC0GJrYCAAA8LQfeigIAADwtBoLGAgAAPC0Gun4CAAA8LQcalgIAADwtB6J6AgAAPC0GTooCAAA8LQcKvgIAADwtBw52AgAAPC0GLrICAAA8LQeGdgIAADwtBja+AgAAPC0HqoYCAAA8LQbStgIAADwtB0q+AgAAPC0HfsoCAAA8LQdKygIAADwtB8LCAgAAPC0GpooCAAA8LQfmjgIAADwtBmZ6AgAAPC0G1rICAAA8LQZuwgIAADwtBkrKAgAAPC0G2q4CAAA8LQcKigIAADwtB+LKAgAAPC0GepYCAAA8LQdCigIAADwtBup6AgAAPC0GBnoCAAA8LEMqAgIAAAAtB1qGAgAAhAQsgAQsWACAAIAAtAC1B/gFxIAFBAEdyOgAtCxkAIAAgAC0ALUH9AXEgAUEAR0EBdHI6AC0LGQAgACAALQAtQfsBcSABQQBHQQJ0cjoALQsZACAAIAAtAC1B9wFxIAFBAEdBA3RyOgAtCy4BAn9BACEDAkAgACgCOCIERQ0AIAQoAgAiBEUNACAAIAQRgICAgAAAIQMLIAMLSQECf0EAIQMCQCAAKAI4IgRFDQAgBCgCBCIERQ0AIAAgASACIAFrIAQRgYCAgAAAIgNBf0cNACAAQcaRgIAANgIQQRghAwsgAwsuAQJ/QQAhAwJAIAAoAjgiBEUNACAEKAIwIgRFDQAgACAEEYCAgIAAACEDCyADC0kBAn9BACEDAkAgACgCOCIERQ0AIAQoAggiBEUNACAAIAEgAiABayAEEYGAgIAAACIDQX9HDQAgAEH2ioCAADYCEEEYIQMLIAMLLgECf0EAIQMCQCAAKAI4IgRFDQAgBCgCNCIERQ0AIAAgBBGAgICAAAAhAwsgAwtJAQJ/QQAhAwJAIAAoAjgiBEUNACAEKAIMIgRFDQAgACABIAIgAWsgBBGBgICAAAAiA0F/Rw0AIABB7ZqAgAA2AhBBGCEDCyADCy4BAn9BACEDAkAgACgCOCIERQ0AIAQoAjgiBEUNACAAIAQRgICAgAAAIQMLIAMLSQECf0EAIQMCQCAAKAI4IgRFDQAgBCgCECIERQ0AIAAgASACIAFrIAQRgYCAgAAAIgNBf0cNACAAQZWQgIAANgIQQRghAwsgAwsuAQJ/QQAhAwJAIAAoAjgiBEUNACAEKAI8IgRFDQAgACAEEYCAgIAAACEDCyADC0kBAn9BACEDAkAgACgCOCIERQ0AIAQoAhQiBEUNACAAIAEgAiABayAEEYGAgIAAACIDQX9HDQAgAEGqm4CAADYCEEEYIQMLIAMLLgECf0EAIQMCQCAAKAI4IgRFDQAgBCgCQCIERQ0AIAAgBBGAgICAAAAhAwsgAwtJAQJ/QQAhAwJAIAAoAjgiBEUNACAEKAIYIgRFDQAgACABIAIgAWsgBBGBgICAAAAiA0F/Rw0AIABB7ZOAgAA2AhBBGCEDCyADCy4BAn9BACEDAkAgACgCOCIERQ0AIAQoAkQiBEUNACAAIAQRgICAgAAAIQMLIAMLLgECf0EAIQMCQCAAKAI4IgRFDQAgBCgCJCIERQ0AIAAgBBGAgICAAAAhAwsgAwsuAQJ/QQAhAwJAIAAoAjgiBEUNACAEKAIsIgRFDQAgACAEEYCAgIAAACEDCyADC0kBAn9BACEDAkAgACgCOCIERQ0AIAQoAigiBEUNACAAIAEgAiABayAEEYGAgIAAACIDQX9HDQAgAEH2iICAADYCEEEYIQMLIAMLLgECf0EAIQMCQCAAKAI4IgRFDQAgBCgCUCIERQ0AIAAgBBGAgICAAAAhAwsgAwtJAQJ/QQAhAwJAIAAoAjgiBEUNACAEKAIcIgRFDQAgACABIAIgAWsgBBGBgICAAAAiA0F/Rw0AIABBwpmAgAA2AhBBGCEDCyADCy4BAn9BACEDAkAgACgCOCIERQ0AIAQoAkgiBEUNACAAIAQRgICAgAAAIQMLIAMLSQECf0EAIQMCQCAAKAI4IgRFDQAgBCgCICIERQ0AIAAgASACIAFrIAQRgYCAgAAAIgNBf0cNACAAQZSUgIAANgIQQRghAwsgAwsuAQJ/QQAhAwJAIAAoAjgiBEUNACAEKAJMIgRFDQAgACAEEYCAgIAAACEDCyADCy4BAn9BACEDAkAgACgCOCIERQ0AIAQoAlQiBEUNACAAIAQRgICAgAAAIQMLIAMLLgECf0EAIQMCQCAAKAI4IgRFDQAgBCgCWCIERQ0AIAAgBBGAgICAAAAhAwsgAwtFAQF/AkACQCAALwEwQRRxQRRHDQBBASEDIAAtAChBAUYNASAALwEyQeUARiEDDAELIAAtAClBBUYhAwsgACADOgAuQQAL/gEBA39BASEDAkAgAC8BMCIEQQhxDQAgACkDIEIAUiEDCwJAAkAgAC0ALkUNAEEBIQUgAC0AKUEFRg0BQQEhBSAEQcAAcUUgA3FBAUcNAQtBACEFIARBwABxDQBBAiEFIARB//8DcSIDQQhxDQACQCADQYAEcUUNAAJAIAAtAChBAUcNACAALQAtQQpxDQBBBQ8LQQQPCwJAIANBIHENAAJAIAAtAChBAUYNACAALwEyQf//A3EiAEGcf2pB5ABJDQAgAEHMAUYNACAAQbACRg0AQQQhBSAEQShxRQ0CIANBiARxQYAERg0CC0EADwtBAEEDIAApAyBQGyEFCyAFC2IBAn9BACEBAkAgAC0AKEEBRg0AIAAvATJB//8DcSICQZx/akHkAEkNACACQcwBRg0AIAJBsAJGDQAgAC8BMCIAQcAAcQ0AQQEhASAAQYgEcUGABEYNACAAQShxRSEBCyABC6cBAQN/AkACQAJAIAAtACpFDQAgAC0AK0UNAEEAIQMgAC8BMCIEQQJxRQ0BDAILQQAhAyAALwEwIgRBAXFFDQELQQEhAyAALQAoQQFGDQAgAC8BMkH//wNxIgVBnH9qQeQASQ0AIAVBzAFGDQAgBUGwAkYNACAEQcAAcQ0AQQAhAyAEQYgEcUGABEYNACAEQShxQQBHIQMLIABBADsBMCAAQQA6AC8gAwuZAQECfwJAAkACQCAALQAqRQ0AIAAtACtFDQBBACEBIAAvATAiAkECcUUNAQwCC0EAIQEgAC8BMCICQQFxRQ0BC0EBIQEgAC0AKEEBRg0AIAAvATJB//8DcSIAQZx/akHkAEkNACAAQcwBRg0AIABBsAJGDQAgAkHAAHENAEEAIQEgAkGIBHFBgARGDQAgAkEocUEARyEBCyABC1kAIABBGGpCADcDACAAQgA3AwAgAEE4akIANwMAIABBMGpCADcDACAAQShqQgA3AwAgAEEgakIANwMAIABBEGpCADcDACAAQQhqQgA3AwAgAEHdATYCHEEAC3sBAX8CQCAAKAIMIgMNAAJAIAAoAgRFDQAgACABNgIECwJAIAAgASACEMSAgIAAIgMNACAAKAIMDwsgACADNgIcQQAhAyAAKAIEIgFFDQAgACABIAIgACgCCBGBgICAAAAiAUUNACAAIAI2AhQgACABNgIMIAEhAwsgAwvk8wEDDn8DfgR/I4CAgIAAQRBrIgMkgICAgAAgASEEIAEhBSABIQYgASEHIAEhCCABIQkgASEKIAEhCyABIQwgASENIAEhDiABIQ8CQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgACgCHCIQQX9qDt0B2gEB2QECAwQFBgcICQoLDA0O2AEPENcBERLWARMUFRYXGBkaG+AB3wEcHR7VAR8gISIjJCXUASYnKCkqKyzTAdIBLS7RAdABLzAxMjM0NTY3ODk6Ozw9Pj9AQUJDREVG2wFHSElKzwHOAUvNAUzMAU1OT1BRUlNUVVZXWFlaW1xdXl9gYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXp7fH1+f4ABgQGCAYMBhAGFAYYBhwGIAYkBigGLAYwBjQGOAY8BkAGRAZIBkwGUAZUBlgGXAZgBmQGaAZsBnAGdAZ4BnwGgAaEBogGjAaQBpQGmAacBqAGpAaoBqwGsAa0BrgGvAbABsQGyAbMBtAG1AbYBtwHLAcoBuAHJAbkByAG6AbsBvAG9Ab4BvwHAAcEBwgHDAcQBxQHGAQDcAQtBACEQDMYBC0EOIRAMxQELQQ0hEAzEAQtBDyEQDMMBC0EQIRAMwgELQRMhEAzBAQtBFCEQDMABC0EVIRAMvwELQRYhEAy+AQtBFyEQDL0BC0EYIRAMvAELQRkhEAy7AQtBGiEQDLoBC0EbIRAMuQELQRwhEAy4AQtBCCEQDLcBC0EdIRAMtgELQSAhEAy1AQtBHyEQDLQBC0EHIRAMswELQSEhEAyyAQtBIiEQDLEBC0EeIRAMsAELQSMhEAyvAQtBEiEQDK4BC0ERIRAMrQELQSQhEAysAQtBJSEQDKsBC0EmIRAMqgELQSchEAypAQtBwwEhEAyoAQtBKSEQDKcBC0ErIRAMpgELQSwhEAylAQtBLSEQDKQBC0EuIRAMowELQS8hEAyiAQtBxAEhEAyhAQtBMCEQDKABC0E0IRAMnwELQQwhEAyeAQtBMSEQDJ0BC0EyIRAMnAELQTMhEAybAQtBOSEQDJoBC0E1IRAMmQELQcUBIRAMmAELQQshEAyXAQtBOiEQDJYBC0E2IRAMlQELQQohEAyUAQtBNyEQDJMBC0E4IRAMkgELQTwhEAyRAQtBOyEQDJABC0E9IRAMjwELQQkhEAyOAQtBKCEQDI0BC0E+IRAMjAELQT8hEAyLAQtBwAAhEAyKAQtBwQAhEAyJAQtBwgAhEAyIAQtBwwAhEAyHAQtBxAAhEAyGAQtBxQAhEAyFAQtBxgAhEAyEAQtBKiEQDIMBC0HHACEQDIIBC0HIACEQDIEBC0HJACEQDIABC0HKACEQDH8LQcsAIRAMfgtBzQAhEAx9C0HMACEQDHwLQc4AIRAMewtBzwAhEAx6C0HQACEQDHkLQdEAIRAMeAtB0gAhEAx3C0HTACEQDHYLQdQAIRAMdQtB1gAhEAx0C0HVACEQDHMLQQYhEAxyC0HXACEQDHELQQUhEAxwC0HYACEQDG8LQQQhEAxuC0HZACEQDG0LQdoAIRAMbAtB2wAhEAxrC0HcACEQDGoLQQMhEAxpC0HdACEQDGgLQd4AIRAMZwtB3wAhEAxmC0HhACEQDGULQeAAIRAMZAtB4gAhEAxjC0HjACEQDGILQQIhEAxhC0HkACEQDGALQeUAIRAMXwtB5gAhEAxeC0HnACEQDF0LQegAIRAMXAtB6QAhEAxbC0HqACEQDFoLQesAIRAMWQtB7AAhEAxYC0HtACEQDFcLQe4AIRAMVgtB7wAhEAxVC0HwACEQDFQLQfEAIRAMUwtB8gAhEAxSC0HzACEQDFELQfQAIRAMUAtB9QAhEAxPC0H2ACEQDE4LQfcAIRAMTQtB+AAhEAxMC0H5ACEQDEsLQfoAIRAMSgtB+wAhEAxJC0H8ACEQDEgLQf0AIRAMRwtB/gAhEAxGC0H/ACEQDEULQYABIRAMRAtBgQEhEAxDC0GCASEQDEILQYMBIRAMQQtBhAEhEAxAC0GFASEQDD8LQYYBIRAMPgtBhwEhEAw9C0GIASEQDDwLQYkBIRAMOwtBigEhEAw6C0GLASEQDDkLQYwBIRAMOAtBjQEhEAw3C0GOASEQDDYLQY8BIRAMNQtBkAEhEAw0C0GRASEQDDMLQZIBIRAMMgtBkwEhEAwxC0GUASEQDDALQZUBIRAMLwtBlgEhEAwuC0GXASEQDC0LQZgBIRAMLAtBmQEhEAwrC0GaASEQDCoLQZsBIRAMKQtBnAEhEAwoC0GdASEQDCcLQZ4BIRAMJgtBnwEhEAwlC0GgASEQDCQLQaEBIRAMIwtBogEhEAwiC0GjASEQDCELQaQBIRAMIAtBpQEhEAwfC0GmASEQDB4LQacBIRAMHQtBqAEhEAwcC0GpASEQDBsLQaoBIRAMGgtBqwEhEAwZC0GsASEQDBgLQa0BIRAMFwtBrgEhEAwWC0EBIRAMFQtBrwEhEAwUC0GwASEQDBMLQbEBIRAMEgtBswEhEAwRC0GyASEQDBALQbQBIRAMDwtBtQEhEAwOC0G2ASEQDA0LQbcBIRAMDAtBuAEhEAwLC0G5ASEQDAoLQboBIRAMCQtBuwEhEAwIC0HGASEQDAcLQbwBIRAMBgtBvQEhEAwFC0G+ASEQDAQLQb8BIRAMAwtBwAEhEAwCC0HCASEQDAELQcEBIRALA0ACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCAQDscBAAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxweHyAhIyUoP0BBREVGR0hJSktMTU9QUVJT3gNXWVtcXWBiZWZnaGlqa2xtb3BxcnN0dXZ3eHl6e3x9foABggGFAYYBhwGJAYsBjAGNAY4BjwGQAZEBlAGVAZYBlwGYAZkBmgGbAZwBnQGeAZ8BoAGhAaIBowGkAaUBpgGnAagBqQGqAasBrAGtAa4BrwGwAbEBsgGzAbQBtQG2AbcBuAG5AboBuwG8Ab0BvgG/AcABwQHCAcMBxAHFAcYBxwHIAckBygHLAcwBzQHOAc8B0AHRAdIB0wHUAdUB1gHXAdgB2QHaAdsB3AHdAd4B4AHhAeIB4wHkAeUB5gHnAegB6QHqAesB7AHtAe4B7wHwAfEB8gHzAZkCpAKwAv4C/gILIAEiBCACRw3zAUHdASEQDP8DCyABIhAgAkcN3QFBwwEhEAz+AwsgASIBIAJHDZABQfcAIRAM/QMLIAEiASACRw2GAUHvACEQDPwDCyABIgEgAkcNf0HqACEQDPsDCyABIgEgAkcNe0HoACEQDPoDCyABIgEgAkcNeEHmACEQDPkDCyABIgEgAkcNGkEYIRAM+AMLIAEiASACRw0UQRIhEAz3AwsgASIBIAJHDVlBxQAhEAz2AwsgASIBIAJHDUpBPyEQDPUDCyABIgEgAkcNSEE8IRAM9AMLIAEiASACRw1BQTEhEAzzAwsgAC0ALkEBRg3rAwyHAgsgACABIgEgAhDAgICAAEEBRw3mASAAQgA3AyAM5wELIAAgASIBIAIQtICAgAAiEA3nASABIQEM9QILAkAgASIBIAJHDQBBBiEQDPADCyAAIAFBAWoiASACELuAgIAAIhAN6AEgASEBDDELIABCADcDIEESIRAM1QMLIAEiECACRw0rQR0hEAztAwsCQCABIgEgAkYNACABQQFqIQFBECEQDNQDC0EHIRAM7AMLIABCACAAKQMgIhEgAiABIhBrrSISfSITIBMgEVYbNwMgIBEgElYiFEUN5QFBCCEQDOsDCwJAIAEiASACRg0AIABBiYCAgAA2AgggACABNgIEIAEhAUEUIRAM0gMLQQkhEAzqAwsgASEBIAApAyBQDeQBIAEhAQzyAgsCQCABIgEgAkcNAEELIRAM6QMLIAAgAUEBaiIBIAIQtoCAgAAiEA3lASABIQEM8gILIAAgASIBIAIQuICAgAAiEA3lASABIQEM8gILIAAgASIBIAIQuICAgAAiEA3mASABIQEMDQsgACABIgEgAhC6gICAACIQDecBIAEhAQzwAgsCQCABIgEgAkcNAEEPIRAM5QMLIAEtAAAiEEE7Rg0IIBBBDUcN6AEgAUEBaiEBDO8CCyAAIAEiASACELqAgIAAIhAN6AEgASEBDPICCwNAAkAgAS0AAEHwtYCAAGotAAAiEEEBRg0AIBBBAkcN6wEgACgCBCEQIABBADYCBCAAIBAgAUEBaiIBELmAgIAAIhAN6gEgASEBDPQCCyABQQFqIgEgAkcNAAtBEiEQDOIDCyAAIAEiASACELqAgIAAIhAN6QEgASEBDAoLIAEiASACRw0GQRshEAzgAwsCQCABIgEgAkcNAEEWIRAM4AMLIABBioCAgAA2AgggACABNgIEIAAgASACELiAgIAAIhAN6gEgASEBQSAhEAzGAwsCQCABIgEgAkYNAANAAkAgAS0AAEHwt4CAAGotAAAiEEECRg0AAkAgEEF/ag4E5QHsAQDrAewBCyABQQFqIQFBCCEQDMgDCyABQQFqIgEgAkcNAAtBFSEQDN8DC0EVIRAM3gMLA0ACQCABLQAAQfC5gIAAai0AACIQQQJGDQAgEEF/ag4E3gHsAeAB6wHsAQsgAUEBaiIBIAJHDQALQRghEAzdAwsCQCABIgEgAkYNACAAQYuAgIAANgIIIAAgATYCBCABIQFBByEQDMQDC0EZIRAM3AMLIAFBAWohAQwCCwJAIAEiFCACRw0AQRohEAzbAwsgFCEBAkAgFC0AAEFzag4U3QLuAu4C7gLuAu4C7gLuAu4C7gLuAu4C7gLuAu4C7gLuAu4C7gIA7gILQQAhECAAQQA2AhwgAEGvi4CAADYCECAAQQI2AgwgACAUQQFqNgIUDNoDCwJAIAEtAAAiEEE7Rg0AIBBBDUcN6AEgAUEBaiEBDOUCCyABQQFqIQELQSIhEAy/AwsCQCABIhAgAkcNAEEcIRAM2AMLQgAhESAQIQEgEC0AAEFQag435wHmAQECAwQFBgcIAAAAAAAAAAkKCwwNDgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADxAREhMUAAtBHiEQDL0DC0ICIREM5QELQgMhEQzkAQtCBCERDOMBC0IFIREM4gELQgYhEQzhAQtCByERDOABC0IIIREM3wELQgkhEQzeAQtCCiERDN0BC0ILIREM3AELQgwhEQzbAQtCDSERDNoBC0IOIREM2QELQg8hEQzYAQtCCiERDNcBC0ILIREM1gELQgwhEQzVAQtCDSERDNQBC0IOIREM0wELQg8hEQzSAQtCACERAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCAQLQAAQVBqDjflAeQBAAECAwQFBgfmAeYB5gHmAeYB5gHmAQgJCgsMDeYB5gHmAeYB5gHmAeYB5gHmAeYB5gHmAeYB5gHmAeYB5gHmAeYB5gHmAeYB5gHmAeYB5gEODxAREhPmAQtCAiERDOQBC0IDIREM4wELQgQhEQziAQtCBSERDOEBC0IGIREM4AELQgchEQzfAQtCCCERDN4BC0IJIREM3QELQgohEQzcAQtCCyERDNsBC0IMIREM2gELQg0hEQzZAQtCDiERDNgBC0IPIREM1wELQgohEQzWAQtCCyERDNUBC0IMIREM1AELQg0hEQzTAQtCDiERDNIBC0IPIREM0QELIABCACAAKQMgIhEgAiABIhBrrSISfSITIBMgEVYbNwMgIBEgElYiFEUN0gFBHyEQDMADCwJAIAEiASACRg0AIABBiYCAgAA2AgggACABNgIEIAEhAUEkIRAMpwMLQSAhEAy/AwsgACABIhAgAhC+gICAAEF/ag4FtgEAxQIB0QHSAQtBESEQDKQDCyAAQQE6AC8gECEBDLsDCyABIgEgAkcN0gFBJCEQDLsDCyABIg0gAkcNHkHGACEQDLoDCyAAIAEiASACELKAgIAAIhAN1AEgASEBDLUBCyABIhAgAkcNJkHQACEQDLgDCwJAIAEiASACRw0AQSghEAy4AwsgAEEANgIEIABBjICAgAA2AgggACABIAEQsYCAgAAiEA3TASABIQEM2AELAkAgASIQIAJHDQBBKSEQDLcDCyAQLQAAIgFBIEYNFCABQQlHDdMBIBBBAWohAQwVCwJAIAEiASACRg0AIAFBAWohAQwXC0EqIRAMtQMLAkAgASIQIAJHDQBBKyEQDLUDCwJAIBAtAAAiAUEJRg0AIAFBIEcN1QELIAAtACxBCEYN0wEgECEBDJEDCwJAIAEiASACRw0AQSwhEAy0AwsgAS0AAEEKRw3VASABQQFqIQEMyQILIAEiDiACRw3VAUEvIRAMsgMLA0ACQCABLQAAIhBBIEYNAAJAIBBBdmoOBADcAdwBANoBCyABIQEM4AELIAFBAWoiASACRw0AC0ExIRAMsQMLQTIhECABIhQgAkYNsAMgAiAUayAAKAIAIgFqIRUgFCABa0EDaiEWAkADQCAULQAAIhdBIHIgFyAXQb9/akH/AXFBGkkbQf8BcSABQfC7gIAAai0AAEcNAQJAIAFBA0cNAEEGIQEMlgMLIAFBAWohASAUQQFqIhQgAkcNAAsgACAVNgIADLEDCyAAQQA2AgAgFCEBDNkBC0EzIRAgASIUIAJGDa8DIAIgFGsgACgCACIBaiEVIBQgAWtBCGohFgJAA0AgFC0AACIXQSByIBcgF0G/f2pB/wFxQRpJG0H/AXEgAUH0u4CAAGotAABHDQECQCABQQhHDQBBBSEBDJUDCyABQQFqIQEgFEEBaiIUIAJHDQALIAAgFTYCAAywAwsgAEEANgIAIBQhAQzYAQtBNCEQIAEiFCACRg2uAyACIBRrIAAoAgAiAWohFSAUIAFrQQVqIRYCQANAIBQtAAAiF0EgciAXIBdBv39qQf8BcUEaSRtB/wFxIAFB0MKAgABqLQAARw0BAkAgAUEFRw0AQQchAQyUAwsgAUEBaiEBIBRBAWoiFCACRw0ACyAAIBU2AgAMrwMLIABBADYCACAUIQEM1wELAkAgASIBIAJGDQADQAJAIAEtAABBgL6AgABqLQAAIhBBAUYNACAQQQJGDQogASEBDN0BCyABQQFqIgEgAkcNAAtBMCEQDK4DC0EwIRAMrQMLAkAgASIBIAJGDQADQAJAIAEtAAAiEEEgRg0AIBBBdmoOBNkB2gHaAdkB2gELIAFBAWoiASACRw0AC0E4IRAMrQMLQTghEAysAwsDQAJAIAEtAAAiEEEgRg0AIBBBCUcNAwsgAUEBaiIBIAJHDQALQTwhEAyrAwsDQAJAIAEtAAAiEEEgRg0AAkACQCAQQXZqDgTaAQEB2gEACyAQQSxGDdsBCyABIQEMBAsgAUEBaiIBIAJHDQALQT8hEAyqAwsgASEBDNsBC0HAACEQIAEiFCACRg2oAyACIBRrIAAoAgAiAWohFiAUIAFrQQZqIRcCQANAIBQtAABBIHIgAUGAwICAAGotAABHDQEgAUEGRg2OAyABQQFqIQEgFEEBaiIUIAJHDQALIAAgFjYCAAypAwsgAEEANgIAIBQhAQtBNiEQDI4DCwJAIAEiDyACRw0AQcEAIRAMpwMLIABBjICAgAA2AgggACAPNgIEIA8hASAALQAsQX9qDgTNAdUB1wHZAYcDCyABQQFqIQEMzAELAkAgASIBIAJGDQADQAJAIAEtAAAiEEEgciAQIBBBv39qQf8BcUEaSRtB/wFxIhBBCUYNACAQQSBGDQACQAJAAkACQCAQQZ1/ag4TAAMDAwMDAwMBAwMDAwMDAwMDAgMLIAFBAWohAUExIRAMkQMLIAFBAWohAUEyIRAMkAMLIAFBAWohAUEzIRAMjwMLIAEhAQzQAQsgAUEBaiIBIAJHDQALQTUhEAylAwtBNSEQDKQDCwJAIAEiASACRg0AA0ACQCABLQAAQYC8gIAAai0AAEEBRg0AIAEhAQzTAQsgAUEBaiIBIAJHDQALQT0hEAykAwtBPSEQDKMDCyAAIAEiASACELCAgIAAIhAN1gEgASEBDAELIBBBAWohAQtBPCEQDIcDCwJAIAEiASACRw0AQcIAIRAMoAMLAkADQAJAIAEtAABBd2oOGAAC/gL+AoQD/gL+Av4C/gL+Av4C/gL+Av4C/gL+Av4C/gL+Av4C/gL+Av4CAP4CCyABQQFqIgEgAkcNAAtBwgAhEAygAwsgAUEBaiEBIAAtAC1BAXFFDb0BIAEhAQtBLCEQDIUDCyABIgEgAkcN0wFBxAAhEAydAwsDQAJAIAEtAABBkMCAgABqLQAAQQFGDQAgASEBDLcCCyABQQFqIgEgAkcNAAtBxQAhEAycAwsgDS0AACIQQSBGDbMBIBBBOkcNgQMgACgCBCEBIABBADYCBCAAIAEgDRCvgICAACIBDdABIA1BAWohAQyzAgtBxwAhECABIg0gAkYNmgMgAiANayAAKAIAIgFqIRYgDSABa0EFaiEXA0AgDS0AACIUQSByIBQgFEG/f2pB/wFxQRpJG0H/AXEgAUGQwoCAAGotAABHDYADIAFBBUYN9AIgAUEBaiEBIA1BAWoiDSACRw0ACyAAIBY2AgAMmgMLQcgAIRAgASINIAJGDZkDIAIgDWsgACgCACIBaiEWIA0gAWtBCWohFwNAIA0tAAAiFEEgciAUIBRBv39qQf8BcUEaSRtB/wFxIAFBlsKAgABqLQAARw3/AgJAIAFBCUcNAEECIQEM9QILIAFBAWohASANQQFqIg0gAkcNAAsgACAWNgIADJkDCwJAIAEiDSACRw0AQckAIRAMmQMLAkACQCANLQAAIgFBIHIgASABQb9/akH/AXFBGkkbQf8BcUGSf2oOBwCAA4ADgAOAA4ADAYADCyANQQFqIQFBPiEQDIADCyANQQFqIQFBPyEQDP8CC0HKACEQIAEiDSACRg2XAyACIA1rIAAoAgAiAWohFiANIAFrQQFqIRcDQCANLQAAIhRBIHIgFCAUQb9/akH/AXFBGkkbQf8BcSABQaDCgIAAai0AAEcN/QIgAUEBRg3wAiABQQFqIQEgDUEBaiINIAJHDQALIAAgFjYCAAyXAwtBywAhECABIg0gAkYNlgMgAiANayAAKAIAIgFqIRYgDSABa0EOaiEXA0AgDS0AACIUQSByIBQgFEG/f2pB/wFxQRpJG0H/AXEgAUGiwoCAAGotAABHDfwCIAFBDkYN8AIgAUEBaiEBIA1BAWoiDSACRw0ACyAAIBY2AgAMlgMLQcwAIRAgASINIAJGDZUDIAIgDWsgACgCACIBaiEWIA0gAWtBD2ohFwNAIA0tAAAiFEEgciAUIBRBv39qQf8BcUEaSRtB/wFxIAFBwMKAgABqLQAARw37AgJAIAFBD0cNAEEDIQEM8QILIAFBAWohASANQQFqIg0gAkcNAAsgACAWNgIADJUDC0HNACEQIAEiDSACRg2UAyACIA1rIAAoAgAiAWohFiANIAFrQQVqIRcDQCANLQAAIhRBIHIgFCAUQb9/akH/AXFBGkkbQf8BcSABQdDCgIAAai0AAEcN+gICQCABQQVHDQBBBCEBDPACCyABQQFqIQEgDUEBaiINIAJHDQALIAAgFjYCAAyUAwsCQCABIg0gAkcNAEHOACEQDJQDCwJAAkACQAJAIA0tAAAiAUEgciABIAFBv39qQf8BcUEaSRtB/wFxQZ1/ag4TAP0C/QL9Av0C/QL9Av0C/QL9Av0C/QL9AgH9Av0C/QICA/0CCyANQQFqIQFBwQAhEAz9AgsgDUEBaiEBQcIAIRAM/AILIA1BAWohAUHDACEQDPsCCyANQQFqIQFBxAAhEAz6AgsCQCABIgEgAkYNACAAQY2AgIAANgIIIAAgATYCBCABIQFBxQAhEAz6AgtBzwAhEAySAwsgECEBAkACQCAQLQAAQXZqDgQBqAKoAgCoAgsgEEEBaiEBC0EnIRAM+AILAkAgASIBIAJHDQBB0QAhEAyRAwsCQCABLQAAQSBGDQAgASEBDI0BCyABQQFqIQEgAC0ALUEBcUUNxwEgASEBDIwBCyABIhcgAkcNyAFB0gAhEAyPAwtB0wAhECABIhQgAkYNjgMgAiAUayAAKAIAIgFqIRYgFCABa0EBaiEXA0AgFC0AACABQdbCgIAAai0AAEcNzAEgAUEBRg3HASABQQFqIQEgFEEBaiIUIAJHDQALIAAgFjYCAAyOAwsCQCABIgEgAkcNAEHVACEQDI4DCyABLQAAQQpHDcwBIAFBAWohAQzHAQsCQCABIgEgAkcNAEHWACEQDI0DCwJAAkAgAS0AAEF2ag4EAM0BzQEBzQELIAFBAWohAQzHAQsgAUEBaiEBQcoAIRAM8wILIAAgASIBIAIQroCAgAAiEA3LASABIQFBzQAhEAzyAgsgAC0AKUEiRg2FAwymAgsCQCABIgEgAkcNAEHbACEQDIoDC0EAIRRBASEXQQEhFkEAIRACQAJAAkACQAJAAkACQAJAAkAgAS0AAEFQag4K1AHTAQABAgMEBQYI1QELQQIhEAwGC0EDIRAMBQtBBCEQDAQLQQUhEAwDC0EGIRAMAgtBByEQDAELQQghEAtBACEXQQAhFkEAIRQMzAELQQkhEEEBIRRBACEXQQAhFgzLAQsCQCABIgEgAkcNAEHdACEQDIkDCyABLQAAQS5HDcwBIAFBAWohAQymAgsgASIBIAJHDcwBQd8AIRAMhwMLAkAgASIBIAJGDQAgAEGOgICAADYCCCAAIAE2AgQgASEBQdAAIRAM7gILQeAAIRAMhgMLQeEAIRAgASIBIAJGDYUDIAIgAWsgACgCACIUaiEWIAEgFGtBA2ohFwNAIAEtAAAgFEHiwoCAAGotAABHDc0BIBRBA0YNzAEgFEEBaiEUIAFBAWoiASACRw0ACyAAIBY2AgAMhQMLQeIAIRAgASIBIAJGDYQDIAIgAWsgACgCACIUaiEWIAEgFGtBAmohFwNAIAEtAAAgFEHmwoCAAGotAABHDcwBIBRBAkYNzgEgFEEBaiEUIAFBAWoiASACRw0ACyAAIBY2AgAMhAMLQeMAIRAgASIBIAJGDYMDIAIgAWsgACgCACIUaiEWIAEgFGtBA2ohFwNAIAEtAAAgFEHpwoCAAGotAABHDcsBIBRBA0YNzgEgFEEBaiEUIAFBAWoiASACRw0ACyAAIBY2AgAMgwMLAkAgASIBIAJHDQBB5QAhEAyDAwsgACABQQFqIgEgAhCogICAACIQDc0BIAEhAUHWACEQDOkCCwJAIAEiASACRg0AA0ACQCABLQAAIhBBIEYNAAJAAkACQCAQQbh/ag4LAAHPAc8BzwHPAc8BzwHPAc8BAs8BCyABQQFqIQFB0gAhEAztAgsgAUEBaiEBQdMAIRAM7AILIAFBAWohAUHUACEQDOsCCyABQQFqIgEgAkcNAAtB5AAhEAyCAwtB5AAhEAyBAwsDQAJAIAEtAABB8MKAgABqLQAAIhBBAUYNACAQQX5qDgPPAdAB0QHSAQsgAUEBaiIBIAJHDQALQeYAIRAMgAMLAkAgASIBIAJGDQAgAUEBaiEBDAMLQecAIRAM/wILA0ACQCABLQAAQfDEgIAAai0AACIQQQFGDQACQCAQQX5qDgTSAdMB1AEA1QELIAEhAUHXACEQDOcCCyABQQFqIgEgAkcNAAtB6AAhEAz+AgsCQCABIgEgAkcNAEHpACEQDP4CCwJAIAEtAAAiEEF2ag4augHVAdUBvAHVAdUB1QHVAdUB1QHVAdUB1QHVAdUB1QHVAdUB1QHVAdUB1QHKAdUB1QEA0wELIAFBAWohAQtBBiEQDOMCCwNAAkAgAS0AAEHwxoCAAGotAABBAUYNACABIQEMngILIAFBAWoiASACRw0AC0HqACEQDPsCCwJAIAEiASACRg0AIAFBAWohAQwDC0HrACEQDPoCCwJAIAEiASACRw0AQewAIRAM+gILIAFBAWohAQwBCwJAIAEiASACRw0AQe0AIRAM+QILIAFBAWohAQtBBCEQDN4CCwJAIAEiFCACRw0AQe4AIRAM9wILIBQhAQJAAkACQCAULQAAQfDIgIAAai0AAEF/ag4H1AHVAdYBAJwCAQLXAQsgFEEBaiEBDAoLIBRBAWohAQzNAQtBACEQIABBADYCHCAAQZuSgIAANgIQIABBBzYCDCAAIBRBAWo2AhQM9gILAkADQAJAIAEtAABB8MiAgABqLQAAIhBBBEYNAAJAAkAgEEF/ag4H0gHTAdQB2QEABAHZAQsgASEBQdoAIRAM4AILIAFBAWohAUHcACEQDN8CCyABQQFqIgEgAkcNAAtB7wAhEAz2AgsgAUEBaiEBDMsBCwJAIAEiFCACRw0AQfAAIRAM9QILIBQtAABBL0cN1AEgFEEBaiEBDAYLAkAgASIUIAJHDQBB8QAhEAz0AgsCQCAULQAAIgFBL0cNACAUQQFqIQFB3QAhEAzbAgsgAUF2aiIEQRZLDdMBQQEgBHRBiYCAAnFFDdMBDMoCCwJAIAEiASACRg0AIAFBAWohAUHeACEQDNoCC0HyACEQDPICCwJAIAEiFCACRw0AQfQAIRAM8gILIBQhAQJAIBQtAABB8MyAgABqLQAAQX9qDgPJApQCANQBC0HhACEQDNgCCwJAIAEiFCACRg0AA0ACQCAULQAAQfDKgIAAai0AACIBQQNGDQACQCABQX9qDgLLAgDVAQsgFCEBQd8AIRAM2gILIBRBAWoiFCACRw0AC0HzACEQDPECC0HzACEQDPACCwJAIAEiASACRg0AIABBj4CAgAA2AgggACABNgIEIAEhAUHgACEQDNcCC0H1ACEQDO8CCwJAIAEiASACRw0AQfYAIRAM7wILIABBj4CAgAA2AgggACABNgIEIAEhAQtBAyEQDNQCCwNAIAEtAABBIEcNwwIgAUEBaiIBIAJHDQALQfcAIRAM7AILAkAgASIBIAJHDQBB+AAhEAzsAgsgAS0AAEEgRw3OASABQQFqIQEM7wELIAAgASIBIAIQrICAgAAiEA3OASABIQEMjgILAkAgASIEIAJHDQBB+gAhEAzqAgsgBC0AAEHMAEcN0QEgBEEBaiEBQRMhEAzPAQsCQCABIgQgAkcNAEH7ACEQDOkCCyACIARrIAAoAgAiAWohFCAEIAFrQQVqIRADQCAELQAAIAFB8M6AgABqLQAARw3QASABQQVGDc4BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQfsAIRAM6AILAkAgASIEIAJHDQBB/AAhEAzoAgsCQAJAIAQtAABBvX9qDgwA0QHRAdEB0QHRAdEB0QHRAdEB0QEB0QELIARBAWohAUHmACEQDM8CCyAEQQFqIQFB5wAhEAzOAgsCQCABIgQgAkcNAEH9ACEQDOcCCyACIARrIAAoAgAiAWohFCAEIAFrQQJqIRACQANAIAQtAAAgAUHtz4CAAGotAABHDc8BIAFBAkYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEH9ACEQDOcCCyAAQQA2AgAgEEEBaiEBQRAhEAzMAQsCQCABIgQgAkcNAEH+ACEQDOYCCyACIARrIAAoAgAiAWohFCAEIAFrQQVqIRACQANAIAQtAAAgAUH2zoCAAGotAABHDc4BIAFBBUYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEH+ACEQDOYCCyAAQQA2AgAgEEEBaiEBQRYhEAzLAQsCQCABIgQgAkcNAEH/ACEQDOUCCyACIARrIAAoAgAiAWohFCAEIAFrQQNqIRACQANAIAQtAAAgAUH8zoCAAGotAABHDc0BIAFBA0YNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEH/ACEQDOUCCyAAQQA2AgAgEEEBaiEBQQUhEAzKAQsCQCABIgQgAkcNAEGAASEQDOQCCyAELQAAQdkARw3LASAEQQFqIQFBCCEQDMkBCwJAIAEiBCACRw0AQYEBIRAM4wILAkACQCAELQAAQbJ/ag4DAMwBAcwBCyAEQQFqIQFB6wAhEAzKAgsgBEEBaiEBQewAIRAMyQILAkAgASIEIAJHDQBBggEhEAziAgsCQAJAIAQtAABBuH9qDggAywHLAcsBywHLAcsBAcsBCyAEQQFqIQFB6gAhEAzJAgsgBEEBaiEBQe0AIRAMyAILAkAgASIEIAJHDQBBgwEhEAzhAgsgAiAEayAAKAIAIgFqIRAgBCABa0ECaiEUAkADQCAELQAAIAFBgM+AgABqLQAARw3JASABQQJGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIBA2AgBBgwEhEAzhAgtBACEQIABBADYCACAUQQFqIQEMxgELAkAgASIEIAJHDQBBhAEhEAzgAgsgAiAEayAAKAIAIgFqIRQgBCABa0EEaiEQAkADQCAELQAAIAFBg8+AgABqLQAARw3IASABQQRGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIBQ2AgBBhAEhEAzgAgsgAEEANgIAIBBBAWohAUEjIRAMxQELAkAgASIEIAJHDQBBhQEhEAzfAgsCQAJAIAQtAABBtH9qDggAyAHIAcgByAHIAcgBAcgBCyAEQQFqIQFB7wAhEAzGAgsgBEEBaiEBQfAAIRAMxQILAkAgASIEIAJHDQBBhgEhEAzeAgsgBC0AAEHFAEcNxQEgBEEBaiEBDIMCCwJAIAEiBCACRw0AQYcBIRAM3QILIAIgBGsgACgCACIBaiEUIAQgAWtBA2ohEAJAA0AgBC0AACABQYjPgIAAai0AAEcNxQEgAUEDRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQYcBIRAM3QILIABBADYCACAQQQFqIQFBLSEQDMIBCwJAIAEiBCACRw0AQYgBIRAM3AILIAIgBGsgACgCACIBaiEUIAQgAWtBCGohEAJAA0AgBC0AACABQdDPgIAAai0AAEcNxAEgAUEIRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQYgBIRAM3AILIABBADYCACAQQQFqIQFBKSEQDMEBCwJAIAEiASACRw0AQYkBIRAM2wILQQEhECABLQAAQd8ARw3AASABQQFqIQEMgQILAkAgASIEIAJHDQBBigEhEAzaAgsgAiAEayAAKAIAIgFqIRQgBCABa0EBaiEQA0AgBC0AACABQYzPgIAAai0AAEcNwQEgAUEBRg2vAiABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEGKASEQDNkCCwJAIAEiBCACRw0AQYsBIRAM2QILIAIgBGsgACgCACIBaiEUIAQgAWtBAmohEAJAA0AgBC0AACABQY7PgIAAai0AAEcNwQEgAUECRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQYsBIRAM2QILIABBADYCACAQQQFqIQFBAiEQDL4BCwJAIAEiBCACRw0AQYwBIRAM2AILIAIgBGsgACgCACIBaiEUIAQgAWtBAWohEAJAA0AgBC0AACABQfDPgIAAai0AAEcNwAEgAUEBRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQYwBIRAM2AILIABBADYCACAQQQFqIQFBHyEQDL0BCwJAIAEiBCACRw0AQY0BIRAM1wILIAIgBGsgACgCACIBaiEUIAQgAWtBAWohEAJAA0AgBC0AACABQfLPgIAAai0AAEcNvwEgAUEBRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQY0BIRAM1wILIABBADYCACAQQQFqIQFBCSEQDLwBCwJAIAEiBCACRw0AQY4BIRAM1gILAkACQCAELQAAQbd/ag4HAL8BvwG/Ab8BvwEBvwELIARBAWohAUH4ACEQDL0CCyAEQQFqIQFB+QAhEAy8AgsCQCABIgQgAkcNAEGPASEQDNUCCyACIARrIAAoAgAiAWohFCAEIAFrQQVqIRACQANAIAQtAAAgAUGRz4CAAGotAABHDb0BIAFBBUYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEGPASEQDNUCCyAAQQA2AgAgEEEBaiEBQRghEAy6AQsCQCABIgQgAkcNAEGQASEQDNQCCyACIARrIAAoAgAiAWohFCAEIAFrQQJqIRACQANAIAQtAAAgAUGXz4CAAGotAABHDbwBIAFBAkYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEGQASEQDNQCCyAAQQA2AgAgEEEBaiEBQRchEAy5AQsCQCABIgQgAkcNAEGRASEQDNMCCyACIARrIAAoAgAiAWohFCAEIAFrQQZqIRACQANAIAQtAAAgAUGaz4CAAGotAABHDbsBIAFBBkYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEGRASEQDNMCCyAAQQA2AgAgEEEBaiEBQRUhEAy4AQsCQCABIgQgAkcNAEGSASEQDNICCyACIARrIAAoAgAiAWohFCAEIAFrQQVqIRACQANAIAQtAAAgAUGhz4CAAGotAABHDboBIAFBBUYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEGSASEQDNICCyAAQQA2AgAgEEEBaiEBQR4hEAy3AQsCQCABIgQgAkcNAEGTASEQDNECCyAELQAAQcwARw24ASAEQQFqIQFBCiEQDLYBCwJAIAQgAkcNAEGUASEQDNACCwJAAkAgBC0AAEG/f2oODwC5AbkBuQG5AbkBuQG5AbkBuQG5AbkBuQG5AQG5AQsgBEEBaiEBQf4AIRAMtwILIARBAWohAUH/ACEQDLYCCwJAIAQgAkcNAEGVASEQDM8CCwJAAkAgBC0AAEG/f2oOAwC4AQG4AQsgBEEBaiEBQf0AIRAMtgILIARBAWohBEGAASEQDLUCCwJAIAQgAkcNAEGWASEQDM4CCyACIARrIAAoAgAiAWohFCAEIAFrQQFqIRACQANAIAQtAAAgAUGnz4CAAGotAABHDbYBIAFBAUYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEGWASEQDM4CCyAAQQA2AgAgEEEBaiEBQQshEAyzAQsCQCAEIAJHDQBBlwEhEAzNAgsCQAJAAkACQCAELQAAQVNqDiMAuAG4AbgBuAG4AbgBuAG4AbgBuAG4AbgBuAG4AbgBuAG4AbgBuAG4AbgBuAG4AQG4AbgBuAG4AbgBArgBuAG4AQO4AQsgBEEBaiEBQfsAIRAMtgILIARBAWohAUH8ACEQDLUCCyAEQQFqIQRBgQEhEAy0AgsgBEEBaiEEQYIBIRAMswILAkAgBCACRw0AQZgBIRAMzAILIAIgBGsgACgCACIBaiEUIAQgAWtBBGohEAJAA0AgBC0AACABQanPgIAAai0AAEcNtAEgAUEERg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQZgBIRAMzAILIABBADYCACAQQQFqIQFBGSEQDLEBCwJAIAQgAkcNAEGZASEQDMsCCyACIARrIAAoAgAiAWohFCAEIAFrQQVqIRACQANAIAQtAAAgAUGuz4CAAGotAABHDbMBIAFBBUYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEGZASEQDMsCCyAAQQA2AgAgEEEBaiEBQQYhEAywAQsCQCAEIAJHDQBBmgEhEAzKAgsgAiAEayAAKAIAIgFqIRQgBCABa0EBaiEQAkADQCAELQAAIAFBtM+AgABqLQAARw2yASABQQFGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIBQ2AgBBmgEhEAzKAgsgAEEANgIAIBBBAWohAUEcIRAMrwELAkAgBCACRw0AQZsBIRAMyQILIAIgBGsgACgCACIBaiEUIAQgAWtBAWohEAJAA0AgBC0AACABQbbPgIAAai0AAEcNsQEgAUEBRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQZsBIRAMyQILIABBADYCACAQQQFqIQFBJyEQDK4BCwJAIAQgAkcNAEGcASEQDMgCCwJAAkAgBC0AAEGsf2oOAgABsQELIARBAWohBEGGASEQDK8CCyAEQQFqIQRBhwEhEAyuAgsCQCAEIAJHDQBBnQEhEAzHAgsgAiAEayAAKAIAIgFqIRQgBCABa0EBaiEQAkADQCAELQAAIAFBuM+AgABqLQAARw2vASABQQFGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIBQ2AgBBnQEhEAzHAgsgAEEANgIAIBBBAWohAUEmIRAMrAELAkAgBCACRw0AQZ4BIRAMxgILIAIgBGsgACgCACIBaiEUIAQgAWtBAWohEAJAA0AgBC0AACABQbrPgIAAai0AAEcNrgEgAUEBRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQZ4BIRAMxgILIABBADYCACAQQQFqIQFBAyEQDKsBCwJAIAQgAkcNAEGfASEQDMUCCyACIARrIAAoAgAiAWohFCAEIAFrQQJqIRACQANAIAQtAAAgAUHtz4CAAGotAABHDa0BIAFBAkYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEGfASEQDMUCCyAAQQA2AgAgEEEBaiEBQQwhEAyqAQsCQCAEIAJHDQBBoAEhEAzEAgsgAiAEayAAKAIAIgFqIRQgBCABa0EDaiEQAkADQCAELQAAIAFBvM+AgABqLQAARw2sASABQQNGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIBQ2AgBBoAEhEAzEAgsgAEEANgIAIBBBAWohAUENIRAMqQELAkAgBCACRw0AQaEBIRAMwwILAkACQCAELQAAQbp/ag4LAKwBrAGsAawBrAGsAawBrAGsAQGsAQsgBEEBaiEEQYsBIRAMqgILIARBAWohBEGMASEQDKkCCwJAIAQgAkcNAEGiASEQDMICCyAELQAAQdAARw2pASAEQQFqIQQM6QELAkAgBCACRw0AQaMBIRAMwQILAkACQCAELQAAQbd/ag4HAaoBqgGqAaoBqgEAqgELIARBAWohBEGOASEQDKgCCyAEQQFqIQFBIiEQDKYBCwJAIAQgAkcNAEGkASEQDMACCyACIARrIAAoAgAiAWohFCAEIAFrQQFqIRACQANAIAQtAAAgAUHAz4CAAGotAABHDagBIAFBAUYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEGkASEQDMACCyAAQQA2AgAgEEEBaiEBQR0hEAylAQsCQCAEIAJHDQBBpQEhEAy/AgsCQAJAIAQtAABBrn9qDgMAqAEBqAELIARBAWohBEGQASEQDKYCCyAEQQFqIQFBBCEQDKQBCwJAIAQgAkcNAEGmASEQDL4CCwJAAkACQAJAAkAgBC0AAEG/f2oOFQCqAaoBqgGqAaoBqgGqAaoBqgGqAQGqAaoBAqoBqgEDqgGqAQSqAQsgBEEBaiEEQYgBIRAMqAILIARBAWohBEGJASEQDKcCCyAEQQFqIQRBigEhEAymAgsgBEEBaiEEQY8BIRAMpQILIARBAWohBEGRASEQDKQCCwJAIAQgAkcNAEGnASEQDL0CCyACIARrIAAoAgAiAWohFCAEIAFrQQJqIRACQANAIAQtAAAgAUHtz4CAAGotAABHDaUBIAFBAkYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEGnASEQDL0CCyAAQQA2AgAgEEEBaiEBQREhEAyiAQsCQCAEIAJHDQBBqAEhEAy8AgsgAiAEayAAKAIAIgFqIRQgBCABa0ECaiEQAkADQCAELQAAIAFBws+AgABqLQAARw2kASABQQJGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIBQ2AgBBqAEhEAy8AgsgAEEANgIAIBBBAWohAUEsIRAMoQELAkAgBCACRw0AQakBIRAMuwILIAIgBGsgACgCACIBaiEUIAQgAWtBBGohEAJAA0AgBC0AACABQcXPgIAAai0AAEcNowEgAUEERg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQakBIRAMuwILIABBADYCACAQQQFqIQFBKyEQDKABCwJAIAQgAkcNAEGqASEQDLoCCyACIARrIAAoAgAiAWohFCAEIAFrQQJqIRACQANAIAQtAAAgAUHKz4CAAGotAABHDaIBIAFBAkYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEGqASEQDLoCCyAAQQA2AgAgEEEBaiEBQRQhEAyfAQsCQCAEIAJHDQBBqwEhEAy5AgsCQAJAAkACQCAELQAAQb5/ag4PAAECpAGkAaQBpAGkAaQBpAGkAaQBpAGkAQOkAQsgBEEBaiEEQZMBIRAMogILIARBAWohBEGUASEQDKECCyAEQQFqIQRBlQEhEAygAgsgBEEBaiEEQZYBIRAMnwILAkAgBCACRw0AQawBIRAMuAILIAQtAABBxQBHDZ8BIARBAWohBAzgAQsCQCAEIAJHDQBBrQEhEAy3AgsgAiAEayAAKAIAIgFqIRQgBCABa0ECaiEQAkADQCAELQAAIAFBzc+AgABqLQAARw2fASABQQJGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIBQ2AgBBrQEhEAy3AgsgAEEANgIAIBBBAWohAUEOIRAMnAELAkAgBCACRw0AQa4BIRAMtgILIAQtAABB0ABHDZ0BIARBAWohAUElIRAMmwELAkAgBCACRw0AQa8BIRAMtQILIAIgBGsgACgCACIBaiEUIAQgAWtBCGohEAJAA0AgBC0AACABQdDPgIAAai0AAEcNnQEgAUEIRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQa8BIRAMtQILIABBADYCACAQQQFqIQFBKiEQDJoBCwJAIAQgAkcNAEGwASEQDLQCCwJAAkAgBC0AAEGrf2oOCwCdAZ0BnQGdAZ0BnQGdAZ0BnQEBnQELIARBAWohBEGaASEQDJsCCyAEQQFqIQRBmwEhEAyaAgsCQCAEIAJHDQBBsQEhEAyzAgsCQAJAIAQtAABBv39qDhQAnAGcAZwBnAGcAZwBnAGcAZwBnAGcAZwBnAGcAZwBnAGcAZwBAZwBCyAEQQFqIQRBmQEhEAyaAgsgBEEBaiEEQZwBIRAMmQILAkAgBCACRw0AQbIBIRAMsgILIAIgBGsgACgCACIBaiEUIAQgAWtBA2ohEAJAA0AgBC0AACABQdnPgIAAai0AAEcNmgEgAUEDRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQbIBIRAMsgILIABBADYCACAQQQFqIQFBISEQDJcBCwJAIAQgAkcNAEGzASEQDLECCyACIARrIAAoAgAiAWohFCAEIAFrQQZqIRACQANAIAQtAAAgAUHdz4CAAGotAABHDZkBIAFBBkYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEGzASEQDLECCyAAQQA2AgAgEEEBaiEBQRohEAyWAQsCQCAEIAJHDQBBtAEhEAywAgsCQAJAAkAgBC0AAEG7f2oOEQCaAZoBmgGaAZoBmgGaAZoBmgEBmgGaAZoBmgGaAQKaAQsgBEEBaiEEQZ0BIRAMmAILIARBAWohBEGeASEQDJcCCyAEQQFqIQRBnwEhEAyWAgsCQCAEIAJHDQBBtQEhEAyvAgsgAiAEayAAKAIAIgFqIRQgBCABa0EFaiEQAkADQCAELQAAIAFB5M+AgABqLQAARw2XASABQQVGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIBQ2AgBBtQEhEAyvAgsgAEEANgIAIBBBAWohAUEoIRAMlAELAkAgBCACRw0AQbYBIRAMrgILIAIgBGsgACgCACIBaiEUIAQgAWtBAmohEAJAA0AgBC0AACABQerPgIAAai0AAEcNlgEgAUECRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQbYBIRAMrgILIABBADYCACAQQQFqIQFBByEQDJMBCwJAIAQgAkcNAEG3ASEQDK0CCwJAAkAgBC0AAEG7f2oODgCWAZYBlgGWAZYBlgGWAZYBlgGWAZYBlgEBlgELIARBAWohBEGhASEQDJQCCyAEQQFqIQRBogEhEAyTAgsCQCAEIAJHDQBBuAEhEAysAgsgAiAEayAAKAIAIgFqIRQgBCABa0ECaiEQAkADQCAELQAAIAFB7c+AgABqLQAARw2UASABQQJGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIBQ2AgBBuAEhEAysAgsgAEEANgIAIBBBAWohAUESIRAMkQELAkAgBCACRw0AQbkBIRAMqwILIAIgBGsgACgCACIBaiEUIAQgAWtBAWohEAJAA0AgBC0AACABQfDPgIAAai0AAEcNkwEgAUEBRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQbkBIRAMqwILIABBADYCACAQQQFqIQFBICEQDJABCwJAIAQgAkcNAEG6ASEQDKoCCyACIARrIAAoAgAiAWohFCAEIAFrQQFqIRACQANAIAQtAAAgAUHyz4CAAGotAABHDZIBIAFBAUYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEG6ASEQDKoCCyAAQQA2AgAgEEEBaiEBQQ8hEAyPAQsCQCAEIAJHDQBBuwEhEAypAgsCQAJAIAQtAABBt39qDgcAkgGSAZIBkgGSAQGSAQsgBEEBaiEEQaUBIRAMkAILIARBAWohBEGmASEQDI8CCwJAIAQgAkcNAEG8ASEQDKgCCyACIARrIAAoAgAiAWohFCAEIAFrQQdqIRACQANAIAQtAAAgAUH0z4CAAGotAABHDZABIAFBB0YNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEG8ASEQDKgCCyAAQQA2AgAgEEEBaiEBQRshEAyNAQsCQCAEIAJHDQBBvQEhEAynAgsCQAJAAkAgBC0AAEG+f2oOEgCRAZEBkQGRAZEBkQGRAZEBkQEBkQGRAZEBkQGRAZEBApEBCyAEQQFqIQRBpAEhEAyPAgsgBEEBaiEEQacBIRAMjgILIARBAWohBEGoASEQDI0CCwJAIAQgAkcNAEG+ASEQDKYCCyAELQAAQc4ARw2NASAEQQFqIQQMzwELAkAgBCACRw0AQb8BIRAMpQILAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkAgBC0AAEG/f2oOFQABAgOcAQQFBpwBnAGcAQcICQoLnAEMDQ4PnAELIARBAWohAUHoACEQDJoCCyAEQQFqIQFB6QAhEAyZAgsgBEEBaiEBQe4AIRAMmAILIARBAWohAUHyACEQDJcCCyAEQQFqIQFB8wAhEAyWAgsgBEEBaiEBQfYAIRAMlQILIARBAWohAUH3ACEQDJQCCyAEQQFqIQFB+gAhEAyTAgsgBEEBaiEEQYMBIRAMkgILIARBAWohBEGEASEQDJECCyAEQQFqIQRBhQEhEAyQAgsgBEEBaiEEQZIBIRAMjwILIARBAWohBEGYASEQDI4CCyAEQQFqIQRBoAEhEAyNAgsgBEEBaiEEQaMBIRAMjAILIARBAWohBEGqASEQDIsCCwJAIAQgAkYNACAAQZCAgIAANgIIIAAgBDYCBEGrASEQDIsCC0HAASEQDKMCCyAAIAUgAhCqgICAACIBDYsBIAUhAQxcCwJAIAYgAkYNACAGQQFqIQUMjQELQcIBIRAMoQILA0ACQCAQLQAAQXZqDgSMAQAAjwEACyAQQQFqIhAgAkcNAAtBwwEhEAygAgsCQCAHIAJGDQAgAEGRgICAADYCCCAAIAc2AgQgByEBQQEhEAyHAgtBxAEhEAyfAgsCQCAHIAJHDQBBxQEhEAyfAgsCQAJAIActAABBdmoOBAHOAc4BAM4BCyAHQQFqIQYMjQELIAdBAWohBQyJAQsCQCAHIAJHDQBBxgEhEAyeAgsCQAJAIActAABBdmoOFwGPAY8BAY8BjwGPAY8BjwGPAY8BjwGPAY8BjwGPAY8BjwGPAY8BjwGPAQCPAQsgB0EBaiEHC0GwASEQDIQCCwJAIAggAkcNAEHIASEQDJ0CCyAILQAAQSBHDY0BIABBADsBMiAIQQFqIQFBswEhEAyDAgsgASEXAkADQCAXIgcgAkYNASAHLQAAQVBqQf8BcSIQQQpPDcwBAkAgAC8BMiIUQZkzSw0AIAAgFEEKbCIUOwEyIBBB//8DcyAUQf7/A3FJDQAgB0EBaiEXIAAgFCAQaiIQOwEyIBBB//8DcUHoB0kNAQsLQQAhECAAQQA2AhwgAEHBiYCAADYCECAAQQ02AgwgACAHQQFqNgIUDJwCC0HHASEQDJsCCyAAIAggAhCugICAACIQRQ3KASAQQRVHDYwBIABByAE2AhwgACAINgIUIABByZeAgAA2AhAgAEEVNgIMQQAhEAyaAgsCQCAJIAJHDQBBzAEhEAyaAgtBACEUQQEhF0EBIRZBACEQAkACQAJAAkACQAJAAkACQAJAIAktAABBUGoOCpYBlQEAAQIDBAUGCJcBC0ECIRAMBgtBAyEQDAULQQQhEAwEC0EFIRAMAwtBBiEQDAILQQchEAwBC0EIIRALQQAhF0EAIRZBACEUDI4BC0EJIRBBASEUQQAhF0EAIRYMjQELAkAgCiACRw0AQc4BIRAMmQILIAotAABBLkcNjgEgCkEBaiEJDMoBCyALIAJHDY4BQdABIRAMlwILAkAgCyACRg0AIABBjoCAgAA2AgggACALNgIEQbcBIRAM/gELQdEBIRAMlgILAkAgBCACRw0AQdIBIRAMlgILIAIgBGsgACgCACIQaiEUIAQgEGtBBGohCwNAIAQtAAAgEEH8z4CAAGotAABHDY4BIBBBBEYN6QEgEEEBaiEQIARBAWoiBCACRw0ACyAAIBQ2AgBB0gEhEAyVAgsgACAMIAIQrICAgAAiAQ2NASAMIQEMuAELAkAgBCACRw0AQdQBIRAMlAILIAIgBGsgACgCACIQaiEUIAQgEGtBAWohDANAIAQtAAAgEEGB0ICAAGotAABHDY8BIBBBAUYNjgEgEEEBaiEQIARBAWoiBCACRw0ACyAAIBQ2AgBB1AEhEAyTAgsCQCAEIAJHDQBB1gEhEAyTAgsgAiAEayAAKAIAIhBqIRQgBCAQa0ECaiELA0AgBC0AACAQQYPQgIAAai0AAEcNjgEgEEECRg2QASAQQQFqIRAgBEEBaiIEIAJHDQALIAAgFDYCAEHWASEQDJICCwJAIAQgAkcNAEHXASEQDJICCwJAAkAgBC0AAEG7f2oOEACPAY8BjwGPAY8BjwGPAY8BjwGPAY8BjwGPAY8BAY8BCyAEQQFqIQRBuwEhEAz5AQsgBEEBaiEEQbwBIRAM+AELAkAgBCACRw0AQdgBIRAMkQILIAQtAABByABHDYwBIARBAWohBAzEAQsCQCAEIAJGDQAgAEGQgICAADYCCCAAIAQ2AgRBvgEhEAz3AQtB2QEhEAyPAgsCQCAEIAJHDQBB2gEhEAyPAgsgBC0AAEHIAEYNwwEgAEEBOgAoDLkBCyAAQQI6AC8gACAEIAIQpoCAgAAiEA2NAUHCASEQDPQBCyAALQAoQX9qDgK3AbkBuAELA0ACQCAELQAAQXZqDgQAjgGOAQCOAQsgBEEBaiIEIAJHDQALQd0BIRAMiwILIABBADoALyAALQAtQQRxRQ2EAgsgAEEAOgAvIABBAToANCABIQEMjAELIBBBFUYN2gEgAEEANgIcIAAgATYCFCAAQaeOgIAANgIQIABBEjYCDEEAIRAMiAILAkAgACAQIAIQtICAgAAiBA0AIBAhAQyBAgsCQCAEQRVHDQAgAEEDNgIcIAAgEDYCFCAAQbCYgIAANgIQIABBFTYCDEEAIRAMiAILIABBADYCHCAAIBA2AhQgAEGnjoCAADYCECAAQRI2AgxBACEQDIcCCyAQQRVGDdYBIABBADYCHCAAIAE2AhQgAEHajYCAADYCECAAQRQ2AgxBACEQDIYCCyAAKAIEIRcgAEEANgIEIBAgEadqIhYhASAAIBcgECAWIBQbIhAQtYCAgAAiFEUNjQEgAEEHNgIcIAAgEDYCFCAAIBQ2AgxBACEQDIUCCyAAIAAvATBBgAFyOwEwIAEhAQtBKiEQDOoBCyAQQRVGDdEBIABBADYCHCAAIAE2AhQgAEGDjICAADYCECAAQRM2AgxBACEQDIICCyAQQRVGDc8BIABBADYCHCAAIAE2AhQgAEGaj4CAADYCECAAQSI2AgxBACEQDIECCyAAKAIEIRAgAEEANgIEAkAgACAQIAEQt4CAgAAiEA0AIAFBAWohAQyNAQsgAEEMNgIcIAAgEDYCDCAAIAFBAWo2AhRBACEQDIACCyAQQRVGDcwBIABBADYCHCAAIAE2AhQgAEGaj4CAADYCECAAQSI2AgxBACEQDP8BCyAAKAIEIRAgAEEANgIEAkAgACAQIAEQt4CAgAAiEA0AIAFBAWohAQyMAQsgAEENNgIcIAAgEDYCDCAAIAFBAWo2AhRBACEQDP4BCyAQQRVGDckBIABBADYCHCAAIAE2AhQgAEHGjICAADYCECAAQSM2AgxBACEQDP0BCyAAKAIEIRAgAEEANgIEAkAgACAQIAEQuYCAgAAiEA0AIAFBAWohAQyLAQsgAEEONgIcIAAgEDYCDCAAIAFBAWo2AhRBACEQDPwBCyAAQQA2AhwgACABNgIUIABBwJWAgAA2AhAgAEECNgIMQQAhEAz7AQsgEEEVRg3FASAAQQA2AhwgACABNgIUIABBxoyAgAA2AhAgAEEjNgIMQQAhEAz6AQsgAEEQNgIcIAAgATYCFCAAIBA2AgxBACEQDPkBCyAAKAIEIQQgAEEANgIEAkAgACAEIAEQuYCAgAAiBA0AIAFBAWohAQzxAQsgAEERNgIcIAAgBDYCDCAAIAFBAWo2AhRBACEQDPgBCyAQQRVGDcEBIABBADYCHCAAIAE2AhQgAEHGjICAADYCECAAQSM2AgxBACEQDPcBCyAAKAIEIRAgAEEANgIEAkAgACAQIAEQuYCAgAAiEA0AIAFBAWohAQyIAQsgAEETNgIcIAAgEDYCDCAAIAFBAWo2AhRBACEQDPYBCyAAKAIEIQQgAEEANgIEAkAgACAEIAEQuYCAgAAiBA0AIAFBAWohAQztAQsgAEEUNgIcIAAgBDYCDCAAIAFBAWo2AhRBACEQDPUBCyAQQRVGDb0BIABBADYCHCAAIAE2AhQgAEGaj4CAADYCECAAQSI2AgxBACEQDPQBCyAAKAIEIRAgAEEANgIEAkAgACAQIAEQt4CAgAAiEA0AIAFBAWohAQyGAQsgAEEWNgIcIAAgEDYCDCAAIAFBAWo2AhRBACEQDPMBCyAAKAIEIQQgAEEANgIEAkAgACAEIAEQt4CAgAAiBA0AIAFBAWohAQzpAQsgAEEXNgIcIAAgBDYCDCAAIAFBAWo2AhRBACEQDPIBCyAAQQA2AhwgACABNgIUIABBzZOAgAA2AhAgAEEMNgIMQQAhEAzxAQtCASERCyAQQQFqIQECQCAAKQMgIhJC//////////8PVg0AIAAgEkIEhiARhDcDICABIQEMhAELIABBADYCHCAAIAE2AhQgAEGtiYCAADYCECAAQQw2AgxBACEQDO8BCyAAQQA2AhwgACAQNgIUIABBzZOAgAA2AhAgAEEMNgIMQQAhEAzuAQsgACgCBCEXIABBADYCBCAQIBGnaiIWIQEgACAXIBAgFiAUGyIQELWAgIAAIhRFDXMgAEEFNgIcIAAgEDYCFCAAIBQ2AgxBACEQDO0BCyAAQQA2AhwgACAQNgIUIABBqpyAgAA2AhAgAEEPNgIMQQAhEAzsAQsgACAQIAIQtICAgAAiAQ0BIBAhAQtBDiEQDNEBCwJAIAFBFUcNACAAQQI2AhwgACAQNgIUIABBsJiAgAA2AhAgAEEVNgIMQQAhEAzqAQsgAEEANgIcIAAgEDYCFCAAQaeOgIAANgIQIABBEjYCDEEAIRAM6QELIAFBAWohEAJAIAAvATAiAUGAAXFFDQACQCAAIBAgAhC7gICAACIBDQAgECEBDHALIAFBFUcNugEgAEEFNgIcIAAgEDYCFCAAQfmXgIAANgIQIABBFTYCDEEAIRAM6QELAkAgAUGgBHFBoARHDQAgAC0ALUECcQ0AIABBADYCHCAAIBA2AhQgAEGWk4CAADYCECAAQQQ2AgxBACEQDOkBCyAAIBAgAhC9gICAABogECEBAkACQAJAAkACQCAAIBAgAhCzgICAAA4WAgEABAQEBAQEBAQEBAQEBAQEBAQEAwQLIABBAToALgsgACAALwEwQcAAcjsBMCAQIQELQSYhEAzRAQsgAEEjNgIcIAAgEDYCFCAAQaWWgIAANgIQIABBFTYCDEEAIRAM6QELIABBADYCHCAAIBA2AhQgAEHVi4CAADYCECAAQRE2AgxBACEQDOgBCyAALQAtQQFxRQ0BQcMBIRAMzgELAkAgDSACRg0AA0ACQCANLQAAQSBGDQAgDSEBDMQBCyANQQFqIg0gAkcNAAtBJSEQDOcBC0ElIRAM5gELIAAoAgQhBCAAQQA2AgQgACAEIA0Qr4CAgAAiBEUNrQEgAEEmNgIcIAAgBDYCDCAAIA1BAWo2AhRBACEQDOUBCyAQQRVGDasBIABBADYCHCAAIAE2AhQgAEH9jYCAADYCECAAQR02AgxBACEQDOQBCyAAQSc2AhwgACABNgIUIAAgEDYCDEEAIRAM4wELIBAhAUEBIRQCQAJAAkACQAJAAkACQCAALQAsQX5qDgcGBQUDAQIABQsgACAALwEwQQhyOwEwDAMLQQIhFAwBC0EEIRQLIABBAToALCAAIAAvATAgFHI7ATALIBAhAQtBKyEQDMoBCyAAQQA2AhwgACAQNgIUIABBq5KAgAA2AhAgAEELNgIMQQAhEAziAQsgAEEANgIcIAAgATYCFCAAQeGPgIAANgIQIABBCjYCDEEAIRAM4QELIABBADoALCAQIQEMvQELIBAhAUEBIRQCQAJAAkACQAJAIAAtACxBe2oOBAMBAgAFCyAAIAAvATBBCHI7ATAMAwtBAiEUDAELQQQhFAsgAEEBOgAsIAAgAC8BMCAUcjsBMAsgECEBC0EpIRAMxQELIABBADYCHCAAIAE2AhQgAEHwlICAADYCECAAQQM2AgxBACEQDN0BCwJAIA4tAABBDUcNACAAKAIEIQEgAEEANgIEAkAgACABIA4QsYCAgAAiAQ0AIA5BAWohAQx1CyAAQSw2AhwgACABNgIMIAAgDkEBajYCFEEAIRAM3QELIAAtAC1BAXFFDQFBxAEhEAzDAQsCQCAOIAJHDQBBLSEQDNwBCwJAAkADQAJAIA4tAABBdmoOBAIAAAMACyAOQQFqIg4gAkcNAAtBLSEQDN0BCyAAKAIEIQEgAEEANgIEAkAgACABIA4QsYCAgAAiAQ0AIA4hAQx0CyAAQSw2AhwgACAONgIUIAAgATYCDEEAIRAM3AELIAAoAgQhASAAQQA2AgQCQCAAIAEgDhCxgICAACIBDQAgDkEBaiEBDHMLIABBLDYCHCAAIAE2AgwgACAOQQFqNgIUQQAhEAzbAQsgACgCBCEEIABBADYCBCAAIAQgDhCxgICAACIEDaABIA4hAQzOAQsgEEEsRw0BIAFBAWohEEEBIQECQAJAAkACQAJAIAAtACxBe2oOBAMBAgQACyAQIQEMBAtBAiEBDAELQQQhAQsgAEEBOgAsIAAgAC8BMCABcjsBMCAQIQEMAQsgACAALwEwQQhyOwEwIBAhAQtBOSEQDL8BCyAAQQA6ACwgASEBC0E0IRAMvQELIAAgAC8BMEEgcjsBMCABIQEMAgsgACgCBCEEIABBADYCBAJAIAAgBCABELGAgIAAIgQNACABIQEMxwELIABBNzYCHCAAIAE2AhQgACAENgIMQQAhEAzUAQsgAEEIOgAsIAEhAQtBMCEQDLkBCwJAIAAtAChBAUYNACABIQEMBAsgAC0ALUEIcUUNkwEgASEBDAMLIAAtADBBIHENlAFBxQEhEAy3AQsCQCAPIAJGDQACQANAAkAgDy0AAEFQaiIBQf8BcUEKSQ0AIA8hAUE1IRAMugELIAApAyAiEUKZs+bMmbPmzBlWDQEgACARQgp+IhE3AyAgESABrUL/AYMiEkJ/hVYNASAAIBEgEnw3AyAgD0EBaiIPIAJHDQALQTkhEAzRAQsgACgCBCECIABBADYCBCAAIAIgD0EBaiIEELGAgIAAIgINlQEgBCEBDMMBC0E5IRAMzwELAkAgAC8BMCIBQQhxRQ0AIAAtAChBAUcNACAALQAtQQhxRQ2QAQsgACABQff7A3FBgARyOwEwIA8hAQtBNyEQDLQBCyAAIAAvATBBEHI7ATAMqwELIBBBFUYNiwEgAEEANgIcIAAgATYCFCAAQfCOgIAANgIQIABBHDYCDEEAIRAMywELIABBwwA2AhwgACABNgIMIAAgDUEBajYCFEEAIRAMygELAkAgAS0AAEE6Rw0AIAAoAgQhECAAQQA2AgQCQCAAIBAgARCvgICAACIQDQAgAUEBaiEBDGMLIABBwwA2AhwgACAQNgIMIAAgAUEBajYCFEEAIRAMygELIABBADYCHCAAIAE2AhQgAEGxkYCAADYCECAAQQo2AgxBACEQDMkBCyAAQQA2AhwgACABNgIUIABBoJmAgAA2AhAgAEEeNgIMQQAhEAzIAQsgAEEANgIACyAAQYASOwEqIAAgF0EBaiIBIAIQqICAgAAiEA0BIAEhAQtBxwAhEAysAQsgEEEVRw2DASAAQdEANgIcIAAgATYCFCAAQeOXgIAANgIQIABBFTYCDEEAIRAMxAELIAAoAgQhECAAQQA2AgQCQCAAIBAgARCngICAACIQDQAgASEBDF4LIABB0gA2AhwgACABNgIUIAAgEDYCDEEAIRAMwwELIABBADYCHCAAIBQ2AhQgAEHBqICAADYCECAAQQc2AgwgAEEANgIAQQAhEAzCAQsgACgCBCEQIABBADYCBAJAIAAgECABEKeAgIAAIhANACABIQEMXQsgAEHTADYCHCAAIAE2AhQgACAQNgIMQQAhEAzBAQtBACEQIABBADYCHCAAIAE2AhQgAEGAkYCAADYCECAAQQk2AgwMwAELIBBBFUYNfSAAQQA2AhwgACABNgIUIABBlI2AgAA2AhAgAEEhNgIMQQAhEAy/AQtBASEWQQAhF0EAIRRBASEQCyAAIBA6ACsgAUEBaiEBAkACQCAALQAtQRBxDQACQAJAAkAgAC0AKg4DAQACBAsgFkUNAwwCCyAUDQEMAgsgF0UNAQsgACgCBCEQIABBADYCBAJAIAAgECABEK2AgIAAIhANACABIQEMXAsgAEHYADYCHCAAIAE2AhQgACAQNgIMQQAhEAy+AQsgACgCBCEEIABBADYCBAJAIAAgBCABEK2AgIAAIgQNACABIQEMrQELIABB2QA2AhwgACABNgIUIAAgBDYCDEEAIRAMvQELIAAoAgQhBCAAQQA2AgQCQCAAIAQgARCtgICAACIEDQAgASEBDKsBCyAAQdoANgIcIAAgATYCFCAAIAQ2AgxBACEQDLwBCyAAKAIEIQQgAEEANgIEAkAgACAEIAEQrYCAgAAiBA0AIAEhAQypAQsgAEHcADYCHCAAIAE2AhQgACAENgIMQQAhEAy7AQsCQCABLQAAQVBqIhBB/wFxQQpPDQAgACAQOgAqIAFBAWohAUHPACEQDKIBCyAAKAIEIQQgAEEANgIEAkAgACAEIAEQrYCAgAAiBA0AIAEhAQynAQsgAEHeADYCHCAAIAE2AhQgACAENgIMQQAhEAy6AQsgAEEANgIAIBdBAWohAQJAIAAtAClBI08NACABIQEMWQsgAEEANgIcIAAgATYCFCAAQdOJgIAANgIQIABBCDYCDEEAIRAMuQELIABBADYCAAtBACEQIABBADYCHCAAIAE2AhQgAEGQs4CAADYCECAAQQg2AgwMtwELIABBADYCACAXQQFqIQECQCAALQApQSFHDQAgASEBDFYLIABBADYCHCAAIAE2AhQgAEGbioCAADYCECAAQQg2AgxBACEQDLYBCyAAQQA2AgAgF0EBaiEBAkAgAC0AKSIQQV1qQQtPDQAgASEBDFULAkAgEEEGSw0AQQEgEHRBygBxRQ0AIAEhAQxVC0EAIRAgAEEANgIcIAAgATYCFCAAQfeJgIAANgIQIABBCDYCDAy1AQsgEEEVRg1xIABBADYCHCAAIAE2AhQgAEG5jYCAADYCECAAQRo2AgxBACEQDLQBCyAAKAIEIRAgAEEANgIEAkAgACAQIAEQp4CAgAAiEA0AIAEhAQxUCyAAQeUANgIcIAAgATYCFCAAIBA2AgxBACEQDLMBCyAAKAIEIRAgAEEANgIEAkAgACAQIAEQp4CAgAAiEA0AIAEhAQxNCyAAQdIANgIcIAAgATYCFCAAIBA2AgxBACEQDLIBCyAAKAIEIRAgAEEANgIEAkAgACAQIAEQp4CAgAAiEA0AIAEhAQxNCyAAQdMANgIcIAAgATYCFCAAIBA2AgxBACEQDLEBCyAAKAIEIRAgAEEANgIEAkAgACAQIAEQp4CAgAAiEA0AIAEhAQxRCyAAQeUANgIcIAAgATYCFCAAIBA2AgxBACEQDLABCyAAQQA2AhwgACABNgIUIABBxoqAgAA2AhAgAEEHNgIMQQAhEAyvAQsgACgCBCEQIABBADYCBAJAIAAgECABEKeAgIAAIhANACABIQEMSQsgAEHSADYCHCAAIAE2AhQgACAQNgIMQQAhEAyuAQsgACgCBCEQIABBADYCBAJAIAAgECABEKeAgIAAIhANACABIQEMSQsgAEHTADYCHCAAIAE2AhQgACAQNgIMQQAhEAytAQsgACgCBCEQIABBADYCBAJAIAAgECABEKeAgIAAIhANACABIQEMTQsgAEHlADYCHCAAIAE2AhQgACAQNgIMQQAhEAysAQsgAEEANgIcIAAgATYCFCAAQdyIgIAANgIQIABBBzYCDEEAIRAMqwELIBBBP0cNASABQQFqIQELQQUhEAyQAQtBACEQIABBADYCHCAAIAE2AhQgAEH9koCAADYCECAAQQc2AgwMqAELIAAoAgQhECAAQQA2AgQCQCAAIBAgARCngICAACIQDQAgASEBDEILIABB0gA2AhwgACABNgIUIAAgEDYCDEEAIRAMpwELIAAoAgQhECAAQQA2AgQCQCAAIBAgARCngICAACIQDQAgASEBDEILIABB0wA2AhwgACABNgIUIAAgEDYCDEEAIRAMpgELIAAoAgQhECAAQQA2AgQCQCAAIBAgARCngICAACIQDQAgASEBDEYLIABB5QA2AhwgACABNgIUIAAgEDYCDEEAIRAMpQELIAAoAgQhASAAQQA2AgQCQCAAIAEgFBCngICAACIBDQAgFCEBDD8LIABB0gA2AhwgACAUNgIUIAAgATYCDEEAIRAMpAELIAAoAgQhASAAQQA2AgQCQCAAIAEgFBCngICAACIBDQAgFCEBDD8LIABB0wA2AhwgACAUNgIUIAAgATYCDEEAIRAMowELIAAoAgQhASAAQQA2AgQCQCAAIAEgFBCngICAACIBDQAgFCEBDEMLIABB5QA2AhwgACAUNgIUIAAgATYCDEEAIRAMogELIABBADYCHCAAIBQ2AhQgAEHDj4CAADYCECAAQQc2AgxBACEQDKEBCyAAQQA2AhwgACABNgIUIABBw4+AgAA2AhAgAEEHNgIMQQAhEAygAQtBACEQIABBADYCHCAAIBQ2AhQgAEGMnICAADYCECAAQQc2AgwMnwELIABBADYCHCAAIBQ2AhQgAEGMnICAADYCECAAQQc2AgxBACEQDJ4BCyAAQQA2AhwgACAUNgIUIABB/pGAgAA2AhAgAEEHNgIMQQAhEAydAQsgAEEANgIcIAAgATYCFCAAQY6bgIAANgIQIABBBjYCDEEAIRAMnAELIBBBFUYNVyAAQQA2AhwgACABNgIUIABBzI6AgAA2AhAgAEEgNgIMQQAhEAybAQsgAEEANgIAIBBBAWohAUEkIRALIAAgEDoAKSAAKAIEIRAgAEEANgIEIAAgECABEKuAgIAAIhANVCABIQEMPgsgAEEANgIAC0EAIRAgAEEANgIcIAAgBDYCFCAAQfGbgIAANgIQIABBBjYCDAyXAQsgAUEVRg1QIABBADYCHCAAIAU2AhQgAEHwjICAADYCECAAQRs2AgxBACEQDJYBCyAAKAIEIQUgAEEANgIEIAAgBSAQEKmAgIAAIgUNASAQQQFqIQULQa0BIRAMewsgAEHBATYCHCAAIAU2AgwgACAQQQFqNgIUQQAhEAyTAQsgACgCBCEGIABBADYCBCAAIAYgEBCpgICAACIGDQEgEEEBaiEGC0GuASEQDHgLIABBwgE2AhwgACAGNgIMIAAgEEEBajYCFEEAIRAMkAELIABBADYCHCAAIAc2AhQgAEGXi4CAADYCECAAQQ02AgxBACEQDI8BCyAAQQA2AhwgACAINgIUIABB45CAgAA2AhAgAEEJNgIMQQAhEAyOAQsgAEEANgIcIAAgCDYCFCAAQZSNgIAANgIQIABBITYCDEEAIRAMjQELQQEhFkEAIRdBACEUQQEhEAsgACAQOgArIAlBAWohCAJAAkAgAC0ALUEQcQ0AAkACQAJAIAAtACoOAwEAAgQLIBZFDQMMAgsgFA0BDAILIBdFDQELIAAoAgQhECAAQQA2AgQgACAQIAgQrYCAgAAiEEUNPSAAQckBNgIcIAAgCDYCFCAAIBA2AgxBACEQDIwBCyAAKAIEIQQgAEEANgIEIAAgBCAIEK2AgIAAIgRFDXYgAEHKATYCHCAAIAg2AhQgACAENgIMQQAhEAyLAQsgACgCBCEEIABBADYCBCAAIAQgCRCtgICAACIERQ10IABBywE2AhwgACAJNgIUIAAgBDYCDEEAIRAMigELIAAoAgQhBCAAQQA2AgQgACAEIAoQrYCAgAAiBEUNciAAQc0BNgIcIAAgCjYCFCAAIAQ2AgxBACEQDIkBCwJAIAstAABBUGoiEEH/AXFBCk8NACAAIBA6ACogC0EBaiEKQbYBIRAMcAsgACgCBCEEIABBADYCBCAAIAQgCxCtgICAACIERQ1wIABBzwE2AhwgACALNgIUIAAgBDYCDEEAIRAMiAELIABBADYCHCAAIAQ2AhQgAEGQs4CAADYCECAAQQg2AgwgAEEANgIAQQAhEAyHAQsgAUEVRg0/IABBADYCHCAAIAw2AhQgAEHMjoCAADYCECAAQSA2AgxBACEQDIYBCyAAQYEEOwEoIAAoAgQhECAAQgA3AwAgACAQIAxBAWoiDBCrgICAACIQRQ04IABB0wE2AhwgACAMNgIUIAAgEDYCDEEAIRAMhQELIABBADYCAAtBACEQIABBADYCHCAAIAQ2AhQgAEHYm4CAADYCECAAQQg2AgwMgwELIAAoAgQhECAAQgA3AwAgACAQIAtBAWoiCxCrgICAACIQDQFBxgEhEAxpCyAAQQI6ACgMVQsgAEHVATYCHCAAIAs2AhQgACAQNgIMQQAhEAyAAQsgEEEVRg03IABBADYCHCAAIAQ2AhQgAEGkjICAADYCECAAQRA2AgxBACEQDH8LIAAtADRBAUcNNCAAIAQgAhC8gICAACIQRQ00IBBBFUcNNSAAQdwBNgIcIAAgBDYCFCAAQdWWgIAANgIQIABBFTYCDEEAIRAMfgtBACEQIABBADYCHCAAQa+LgIAANgIQIABBAjYCDCAAIBRBAWo2AhQMfQtBACEQDGMLQQIhEAxiC0ENIRAMYQtBDyEQDGALQSUhEAxfC0ETIRAMXgtBFSEQDF0LQRYhEAxcC0EXIRAMWwtBGCEQDFoLQRkhEAxZC0EaIRAMWAtBGyEQDFcLQRwhEAxWC0EdIRAMVQtBHyEQDFQLQSEhEAxTC0EjIRAMUgtBxgAhEAxRC0EuIRAMUAtBLyEQDE8LQTshEAxOC0E9IRAMTQtByAAhEAxMC0HJACEQDEsLQcsAIRAMSgtBzAAhEAxJC0HOACEQDEgLQdEAIRAMRwtB1QAhEAxGC0HYACEQDEULQdkAIRAMRAtB2wAhEAxDC0HkACEQDEILQeUAIRAMQQtB8QAhEAxAC0H0ACEQDD8LQY0BIRAMPgtBlwEhEAw9C0GpASEQDDwLQawBIRAMOwtBwAEhEAw6C0G5ASEQDDkLQa8BIRAMOAtBsQEhEAw3C0GyASEQDDYLQbQBIRAMNQtBtQEhEAw0C0G6ASEQDDMLQb0BIRAMMgtBvwEhEAwxC0HBASEQDDALIABBADYCHCAAIAQ2AhQgAEHpi4CAADYCECAAQR82AgxBACEQDEgLIABB2wE2AhwgACAENgIUIABB+paAgAA2AhAgAEEVNgIMQQAhEAxHCyAAQfgANgIcIAAgDDYCFCAAQcqYgIAANgIQIABBFTYCDEEAIRAMRgsgAEHRADYCHCAAIAU2AhQgAEGwl4CAADYCECAAQRU2AgxBACEQDEULIABB+QA2AhwgACABNgIUIAAgEDYCDEEAIRAMRAsgAEH4ADYCHCAAIAE2AhQgAEHKmICAADYCECAAQRU2AgxBACEQDEMLIABB5AA2AhwgACABNgIUIABB45eAgAA2AhAgAEEVNgIMQQAhEAxCCyAAQdcANgIcIAAgATYCFCAAQcmXgIAANgIQIABBFTYCDEEAIRAMQQsgAEEANgIcIAAgATYCFCAAQbmNgIAANgIQIABBGjYCDEEAIRAMQAsgAEHCADYCHCAAIAE2AhQgAEHjmICAADYCECAAQRU2AgxBACEQDD8LIABBADYCBCAAIA8gDxCxgICAACIERQ0BIABBOjYCHCAAIAQ2AgwgACAPQQFqNgIUQQAhEAw+CyAAKAIEIQQgAEEANgIEAkAgACAEIAEQsYCAgAAiBEUNACAAQTs2AhwgACAENgIMIAAgAUEBajYCFEEAIRAMPgsgAUEBaiEBDC0LIA9BAWohAQwtCyAAQQA2AhwgACAPNgIUIABB5JKAgAA2AhAgAEEENgIMQQAhEAw7CyAAQTY2AhwgACAENgIUIAAgAjYCDEEAIRAMOgsgAEEuNgIcIAAgDjYCFCAAIAQ2AgxBACEQDDkLIABB0AA2AhwgACABNgIUIABBkZiAgAA2AhAgAEEVNgIMQQAhEAw4CyANQQFqIQEMLAsgAEEVNgIcIAAgATYCFCAAQYKZgIAANgIQIABBFTYCDEEAIRAMNgsgAEEbNgIcIAAgATYCFCAAQZGXgIAANgIQIABBFTYCDEEAIRAMNQsgAEEPNgIcIAAgATYCFCAAQZGXgIAANgIQIABBFTYCDEEAIRAMNAsgAEELNgIcIAAgATYCFCAAQZGXgIAANgIQIABBFTYCDEEAIRAMMwsgAEEaNgIcIAAgATYCFCAAQYKZgIAANgIQIABBFTYCDEEAIRAMMgsgAEELNgIcIAAgATYCFCAAQYKZgIAANgIQIABBFTYCDEEAIRAMMQsgAEEKNgIcIAAgATYCFCAAQeSWgIAANgIQIABBFTYCDEEAIRAMMAsgAEEeNgIcIAAgATYCFCAAQfmXgIAANgIQIABBFTYCDEEAIRAMLwsgAEEANgIcIAAgEDYCFCAAQdqNgIAANgIQIABBFDYCDEEAIRAMLgsgAEEENgIcIAAgATYCFCAAQbCYgIAANgIQIABBFTYCDEEAIRAMLQsgAEEANgIAIAtBAWohCwtBuAEhEAwSCyAAQQA2AgAgEEEBaiEBQfUAIRAMEQsgASEBAkAgAC0AKUEFRw0AQeMAIRAMEQtB4gAhEAwQC0EAIRAgAEEANgIcIABB5JGAgAA2AhAgAEEHNgIMIAAgFEEBajYCFAwoCyAAQQA2AgAgF0EBaiEBQcAAIRAMDgtBASEBCyAAIAE6ACwgAEEANgIAIBdBAWohAQtBKCEQDAsLIAEhAQtBOCEQDAkLAkAgASIPIAJGDQADQAJAIA8tAABBgL6AgABqLQAAIgFBAUYNACABQQJHDQMgD0EBaiEBDAQLIA9BAWoiDyACRw0AC0E+IRAMIgtBPiEQDCELIABBADoALCAPIQEMAQtBCyEQDAYLQTohEAwFCyABQQFqIQFBLSEQDAQLIAAgAToALCAAQQA2AgAgFkEBaiEBQQwhEAwDCyAAQQA2AgAgF0EBaiEBQQohEAwCCyAAQQA2AgALIABBADoALCANIQFBCSEQDAALC0EAIRAgAEEANgIcIAAgCzYCFCAAQc2QgIAANgIQIABBCTYCDAwXC0EAIRAgAEEANgIcIAAgCjYCFCAAQemKgIAANgIQIABBCTYCDAwWC0EAIRAgAEEANgIcIAAgCTYCFCAAQbeQgIAANgIQIABBCTYCDAwVC0EAIRAgAEEANgIcIAAgCDYCFCAAQZyRgIAANgIQIABBCTYCDAwUC0EAIRAgAEEANgIcIAAgATYCFCAAQc2QgIAANgIQIABBCTYCDAwTC0EAIRAgAEEANgIcIAAgATYCFCAAQemKgIAANgIQIABBCTYCDAwSC0EAIRAgAEEANgIcIAAgATYCFCAAQbeQgIAANgIQIABBCTYCDAwRC0EAIRAgAEEANgIcIAAgATYCFCAAQZyRgIAANgIQIABBCTYCDAwQC0EAIRAgAEEANgIcIAAgATYCFCAAQZeVgIAANgIQIABBDzYCDAwPC0EAIRAgAEEANgIcIAAgATYCFCAAQZeVgIAANgIQIABBDzYCDAwOC0EAIRAgAEEANgIcIAAgATYCFCAAQcCSgIAANgIQIABBCzYCDAwNC0EAIRAgAEEANgIcIAAgATYCFCAAQZWJgIAANgIQIABBCzYCDAwMC0EAIRAgAEEANgIcIAAgATYCFCAAQeGPgIAANgIQIABBCjYCDAwLC0EAIRAgAEEANgIcIAAgATYCFCAAQfuPgIAANgIQIABBCjYCDAwKC0EAIRAgAEEANgIcIAAgATYCFCAAQfGZgIAANgIQIABBAjYCDAwJC0EAIRAgAEEANgIcIAAgATYCFCAAQcSUgIAANgIQIABBAjYCDAwIC0EAIRAgAEEANgIcIAAgATYCFCAAQfKVgIAANgIQIABBAjYCDAwHCyAAQQI2AhwgACABNgIUIABBnJqAgAA2AhAgAEEWNgIMQQAhEAwGC0EBIRAMBQtB1AAhECABIgQgAkYNBCADQQhqIAAgBCACQdjCgIAAQQoQxYCAgAAgAygCDCEEIAMoAggOAwEEAgALEMqAgIAAAAsgAEEANgIcIABBtZqAgAA2AhAgAEEXNgIMIAAgBEEBajYCFEEAIRAMAgsgAEEANgIcIAAgBDYCFCAAQcqagIAANgIQIABBCTYCDEEAIRAMAQsCQCABIgQgAkcNAEEiIRAMAQsgAEGJgICAADYCCCAAIAQ2AgRBISEQCyADQRBqJICAgIAAIBALrwEBAn8gASgCACEGAkACQCACIANGDQAgBCAGaiEEIAYgA2ogAmshByACIAZBf3MgBWoiBmohBQNAAkAgAi0AACAELQAARg0AQQIhBAwDCwJAIAYNAEEAIQQgBSECDAMLIAZBf2ohBiAEQQFqIQQgAkEBaiICIANHDQALIAchBiADIQILIABBATYCACABIAY2AgAgACACNgIEDwsgAUEANgIAIAAgBDYCACAAIAI2AgQLCgAgABDHgICAAAvyNgELfyOAgICAAEEQayIBJICAgIAAAkBBACgCoNCAgAANAEEAEMuAgIAAQYDUhIAAayICQdkASQ0AQQAhAwJAQQAoAuDTgIAAIgQNAEEAQn83AuzTgIAAQQBCgICEgICAwAA3AuTTgIAAQQAgAUEIakFwcUHYqtWqBXMiBDYC4NOAgABBAEEANgL004CAAEEAQQA2AsTTgIAAC0EAIAI2AszTgIAAQQBBgNSEgAA2AsjTgIAAQQBBgNSEgAA2ApjQgIAAQQAgBDYCrNCAgABBAEF/NgKo0ICAAANAIANBxNCAgABqIANBuNCAgABqIgQ2AgAgBCADQbDQgIAAaiIFNgIAIANBvNCAgABqIAU2AgAgA0HM0ICAAGogA0HA0ICAAGoiBTYCACAFIAQ2AgAgA0HU0ICAAGogA0HI0ICAAGoiBDYCACAEIAU2AgAgA0HQ0ICAAGogBDYCACADQSBqIgNBgAJHDQALQYDUhIAAQXhBgNSEgABrQQ9xQQBBgNSEgABBCGpBD3EbIgNqIgRBBGogAkFIaiIFIANrIgNBAXI2AgBBAEEAKALw04CAADYCpNCAgABBACADNgKU0ICAAEEAIAQ2AqDQgIAAQYDUhIAAIAVqQTg2AgQLAkACQAJAAkACQAJAAkACQAJAAkACQAJAIABB7AFLDQACQEEAKAKI0ICAACIGQRAgAEETakFwcSAAQQtJGyICQQN2IgR2IgNBA3FFDQACQAJAIANBAXEgBHJBAXMiBUEDdCIEQbDQgIAAaiIDIARBuNCAgABqKAIAIgQoAggiAkcNAEEAIAZBfiAFd3E2AojQgIAADAELIAMgAjYCCCACIAM2AgwLIARBCGohAyAEIAVBA3QiBUEDcjYCBCAEIAVqIgQgBCgCBEEBcjYCBAwMCyACQQAoApDQgIAAIgdNDQECQCADRQ0AAkACQCADIAR0QQIgBHQiA0EAIANrcnEiA0EAIANrcUF/aiIDIANBDHZBEHEiA3YiBEEFdkEIcSIFIANyIAQgBXYiA0ECdkEEcSIEciADIAR2IgNBAXZBAnEiBHIgAyAEdiIDQQF2QQFxIgRyIAMgBHZqIgRBA3QiA0Gw0ICAAGoiBSADQbjQgIAAaigCACIDKAIIIgBHDQBBACAGQX4gBHdxIgY2AojQgIAADAELIAUgADYCCCAAIAU2AgwLIAMgAkEDcjYCBCADIARBA3QiBGogBCACayIFNgIAIAMgAmoiACAFQQFyNgIEAkAgB0UNACAHQXhxQbDQgIAAaiECQQAoApzQgIAAIQQCQAJAIAZBASAHQQN2dCIIcQ0AQQAgBiAIcjYCiNCAgAAgAiEIDAELIAIoAgghCAsgCCAENgIMIAIgBDYCCCAEIAI2AgwgBCAINgIICyADQQhqIQNBACAANgKc0ICAAEEAIAU2ApDQgIAADAwLQQAoAozQgIAAIglFDQEgCUEAIAlrcUF/aiIDIANBDHZBEHEiA3YiBEEFdkEIcSIFIANyIAQgBXYiA0ECdkEEcSIEciADIAR2IgNBAXZBAnEiBHIgAyAEdiIDQQF2QQFxIgRyIAMgBHZqQQJ0QbjSgIAAaigCACIAKAIEQXhxIAJrIQQgACEFAkADQAJAIAUoAhAiAw0AIAVBFGooAgAiA0UNAgsgAygCBEF4cSACayIFIAQgBSAESSIFGyEEIAMgACAFGyEAIAMhBQwACwsgACgCGCEKAkAgACgCDCIIIABGDQAgACgCCCIDQQAoApjQgIAASRogCCADNgIIIAMgCDYCDAwLCwJAIABBFGoiBSgCACIDDQAgACgCECIDRQ0DIABBEGohBQsDQCAFIQsgAyIIQRRqIgUoAgAiAw0AIAhBEGohBSAIKAIQIgMNAAsgC0EANgIADAoLQX8hAiAAQb9/Sw0AIABBE2oiA0FwcSECQQAoAozQgIAAIgdFDQBBACELAkAgAkGAAkkNAEEfIQsgAkH///8HSw0AIANBCHYiAyADQYD+P2pBEHZBCHEiA3QiBCAEQYDgH2pBEHZBBHEiBHQiBSAFQYCAD2pBEHZBAnEiBXRBD3YgAyAEciAFcmsiA0EBdCACIANBFWp2QQFxckEcaiELC0EAIAJrIQQCQAJAAkACQCALQQJ0QbjSgIAAaigCACIFDQBBACEDQQAhCAwBC0EAIQMgAkEAQRkgC0EBdmsgC0EfRht0IQBBACEIA0ACQCAFKAIEQXhxIAJrIgYgBE8NACAGIQQgBSEIIAYNAEEAIQQgBSEIIAUhAwwDCyADIAVBFGooAgAiBiAGIAUgAEEddkEEcWpBEGooAgAiBUYbIAMgBhshAyAAQQF0IQAgBQ0ACwsCQCADIAhyDQBBACEIQQIgC3QiA0EAIANrciAHcSIDRQ0DIANBACADa3FBf2oiAyADQQx2QRBxIgN2IgVBBXZBCHEiACADciAFIAB2IgNBAnZBBHEiBXIgAyAFdiIDQQF2QQJxIgVyIAMgBXYiA0EBdkEBcSIFciADIAV2akECdEG40oCAAGooAgAhAwsgA0UNAQsDQCADKAIEQXhxIAJrIgYgBEkhAAJAIAMoAhAiBQ0AIANBFGooAgAhBQsgBiAEIAAbIQQgAyAIIAAbIQggBSEDIAUNAAsLIAhFDQAgBEEAKAKQ0ICAACACa08NACAIKAIYIQsCQCAIKAIMIgAgCEYNACAIKAIIIgNBACgCmNCAgABJGiAAIAM2AgggAyAANgIMDAkLAkAgCEEUaiIFKAIAIgMNACAIKAIQIgNFDQMgCEEQaiEFCwNAIAUhBiADIgBBFGoiBSgCACIDDQAgAEEQaiEFIAAoAhAiAw0ACyAGQQA2AgAMCAsCQEEAKAKQ0ICAACIDIAJJDQBBACgCnNCAgAAhBAJAAkAgAyACayIFQRBJDQAgBCACaiIAIAVBAXI2AgRBACAFNgKQ0ICAAEEAIAA2ApzQgIAAIAQgA2ogBTYCACAEIAJBA3I2AgQMAQsgBCADQQNyNgIEIAQgA2oiAyADKAIEQQFyNgIEQQBBADYCnNCAgABBAEEANgKQ0ICAAAsgBEEIaiEDDAoLAkBBACgClNCAgAAiACACTQ0AQQAoAqDQgIAAIgMgAmoiBCAAIAJrIgVBAXI2AgRBACAFNgKU0ICAAEEAIAQ2AqDQgIAAIAMgAkEDcjYCBCADQQhqIQMMCgsCQAJAQQAoAuDTgIAARQ0AQQAoAujTgIAAIQQMAQtBAEJ/NwLs04CAAEEAQoCAhICAgMAANwLk04CAAEEAIAFBDGpBcHFB2KrVqgVzNgLg04CAAEEAQQA2AvTTgIAAQQBBADYCxNOAgABBgIAEIQQLQQAhAwJAIAQgAkHHAGoiB2oiBkEAIARrIgtxIgggAksNAEEAQTA2AvjTgIAADAoLAkBBACgCwNOAgAAiA0UNAAJAQQAoArjTgIAAIgQgCGoiBSAETQ0AIAUgA00NAQtBACEDQQBBMDYC+NOAgAAMCgtBAC0AxNOAgABBBHENBAJAAkACQEEAKAKg0ICAACIERQ0AQcjTgIAAIQMDQAJAIAMoAgAiBSAESw0AIAUgAygCBGogBEsNAwsgAygCCCIDDQALC0EAEMuAgIAAIgBBf0YNBSAIIQYCQEEAKALk04CAACIDQX9qIgQgAHFFDQAgCCAAayAEIABqQQAgA2txaiEGCyAGIAJNDQUgBkH+////B0sNBQJAQQAoAsDTgIAAIgNFDQBBACgCuNOAgAAiBCAGaiIFIARNDQYgBSADSw0GCyAGEMuAgIAAIgMgAEcNAQwHCyAGIABrIAtxIgZB/v///wdLDQQgBhDLgICAACIAIAMoAgAgAygCBGpGDQMgACEDCwJAIANBf0YNACACQcgAaiAGTQ0AAkAgByAGa0EAKALo04CAACIEakEAIARrcSIEQf7///8HTQ0AIAMhAAwHCwJAIAQQy4CAgABBf0YNACAEIAZqIQYgAyEADAcLQQAgBmsQy4CAgAAaDAQLIAMhACADQX9HDQUMAwtBACEIDAcLQQAhAAwFCyAAQX9HDQILQQBBACgCxNOAgABBBHI2AsTTgIAACyAIQf7///8HSw0BIAgQy4CAgAAhAEEAEMuAgIAAIQMgAEF/Rg0BIANBf0YNASAAIANPDQEgAyAAayIGIAJBOGpNDQELQQBBACgCuNOAgAAgBmoiAzYCuNOAgAACQCADQQAoArzTgIAATQ0AQQAgAzYCvNOAgAALAkACQAJAAkBBACgCoNCAgAAiBEUNAEHI04CAACEDA0AgACADKAIAIgUgAygCBCIIakYNAiADKAIIIgMNAAwDCwsCQAJAQQAoApjQgIAAIgNFDQAgACADTw0BC0EAIAA2ApjQgIAAC0EAIQNBACAGNgLM04CAAEEAIAA2AsjTgIAAQQBBfzYCqNCAgABBAEEAKALg04CAADYCrNCAgABBAEEANgLU04CAAANAIANBxNCAgABqIANBuNCAgABqIgQ2AgAgBCADQbDQgIAAaiIFNgIAIANBvNCAgABqIAU2AgAgA0HM0ICAAGogA0HA0ICAAGoiBTYCACAFIAQ2AgAgA0HU0ICAAGogA0HI0ICAAGoiBDYCACAEIAU2AgAgA0HQ0ICAAGogBDYCACADQSBqIgNBgAJHDQALIABBeCAAa0EPcUEAIABBCGpBD3EbIgNqIgQgBkFIaiIFIANrIgNBAXI2AgRBAEEAKALw04CAADYCpNCAgABBACADNgKU0ICAAEEAIAQ2AqDQgIAAIAAgBWpBODYCBAwCCyADLQAMQQhxDQAgBCAFSQ0AIAQgAE8NACAEQXggBGtBD3FBACAEQQhqQQ9xGyIFaiIAQQAoApTQgIAAIAZqIgsgBWsiBUEBcjYCBCADIAggBmo2AgRBAEEAKALw04CAADYCpNCAgABBACAFNgKU0ICAAEEAIAA2AqDQgIAAIAQgC2pBODYCBAwBCwJAIABBACgCmNCAgAAiCE8NAEEAIAA2ApjQgIAAIAAhCAsgACAGaiEFQcjTgIAAIQMCQAJAAkACQAJAAkACQANAIAMoAgAgBUYNASADKAIIIgMNAAwCCwsgAy0ADEEIcUUNAQtByNOAgAAhAwNAAkAgAygCACIFIARLDQAgBSADKAIEaiIFIARLDQMLIAMoAgghAwwACwsgAyAANgIAIAMgAygCBCAGajYCBCAAQXggAGtBD3FBACAAQQhqQQ9xG2oiCyACQQNyNgIEIAVBeCAFa0EPcUEAIAVBCGpBD3EbaiIGIAsgAmoiAmshAwJAIAYgBEcNAEEAIAI2AqDQgIAAQQBBACgClNCAgAAgA2oiAzYClNCAgAAgAiADQQFyNgIEDAMLAkAgBkEAKAKc0ICAAEcNAEEAIAI2ApzQgIAAQQBBACgCkNCAgAAgA2oiAzYCkNCAgAAgAiADQQFyNgIEIAIgA2ogAzYCAAwDCwJAIAYoAgQiBEEDcUEBRw0AIARBeHEhBwJAAkAgBEH/AUsNACAGKAIIIgUgBEEDdiIIQQN0QbDQgIAAaiIARhoCQCAGKAIMIgQgBUcNAEEAQQAoAojQgIAAQX4gCHdxNgKI0ICAAAwCCyAEIABGGiAEIAU2AgggBSAENgIMDAELIAYoAhghCQJAAkAgBigCDCIAIAZGDQAgBigCCCIEIAhJGiAAIAQ2AgggBCAANgIMDAELAkAgBkEUaiIEKAIAIgUNACAGQRBqIgQoAgAiBQ0AQQAhAAwBCwNAIAQhCCAFIgBBFGoiBCgCACIFDQAgAEEQaiEEIAAoAhAiBQ0ACyAIQQA2AgALIAlFDQACQAJAIAYgBigCHCIFQQJ0QbjSgIAAaiIEKAIARw0AIAQgADYCACAADQFBAEEAKAKM0ICAAEF+IAV3cTYCjNCAgAAMAgsgCUEQQRQgCSgCECAGRhtqIAA2AgAgAEUNAQsgACAJNgIYAkAgBigCECIERQ0AIAAgBDYCECAEIAA2AhgLIAYoAhQiBEUNACAAQRRqIAQ2AgAgBCAANgIYCyAHIANqIQMgBiAHaiIGKAIEIQQLIAYgBEF+cTYCBCACIANqIAM2AgAgAiADQQFyNgIEAkAgA0H/AUsNACADQXhxQbDQgIAAaiEEAkACQEEAKAKI0ICAACIFQQEgA0EDdnQiA3ENAEEAIAUgA3I2AojQgIAAIAQhAwwBCyAEKAIIIQMLIAMgAjYCDCAEIAI2AgggAiAENgIMIAIgAzYCCAwDC0EfIQQCQCADQf///wdLDQAgA0EIdiIEIARBgP4/akEQdkEIcSIEdCIFIAVBgOAfakEQdkEEcSIFdCIAIABBgIAPakEQdkECcSIAdEEPdiAEIAVyIAByayIEQQF0IAMgBEEVanZBAXFyQRxqIQQLIAIgBDYCHCACQgA3AhAgBEECdEG40oCAAGohBQJAQQAoAozQgIAAIgBBASAEdCIIcQ0AIAUgAjYCAEEAIAAgCHI2AozQgIAAIAIgBTYCGCACIAI2AgggAiACNgIMDAMLIANBAEEZIARBAXZrIARBH0YbdCEEIAUoAgAhAANAIAAiBSgCBEF4cSADRg0CIARBHXYhACAEQQF0IQQgBSAAQQRxakEQaiIIKAIAIgANAAsgCCACNgIAIAIgBTYCGCACIAI2AgwgAiACNgIIDAILIABBeCAAa0EPcUEAIABBCGpBD3EbIgNqIgsgBkFIaiIIIANrIgNBAXI2AgQgACAIakE4NgIEIAQgBUE3IAVrQQ9xQQAgBUFJakEPcRtqQUFqIgggCCAEQRBqSRsiCEEjNgIEQQBBACgC8NOAgAA2AqTQgIAAQQAgAzYClNCAgABBACALNgKg0ICAACAIQRBqQQApAtDTgIAANwIAIAhBACkCyNOAgAA3AghBACAIQQhqNgLQ04CAAEEAIAY2AszTgIAAQQAgADYCyNOAgABBAEEANgLU04CAACAIQSRqIQMDQCADQQc2AgAgA0EEaiIDIAVJDQALIAggBEYNAyAIIAgoAgRBfnE2AgQgCCAIIARrIgA2AgAgBCAAQQFyNgIEAkAgAEH/AUsNACAAQXhxQbDQgIAAaiEDAkACQEEAKAKI0ICAACIFQQEgAEEDdnQiAHENAEEAIAUgAHI2AojQgIAAIAMhBQwBCyADKAIIIQULIAUgBDYCDCADIAQ2AgggBCADNgIMIAQgBTYCCAwEC0EfIQMCQCAAQf///wdLDQAgAEEIdiIDIANBgP4/akEQdkEIcSIDdCIFIAVBgOAfakEQdkEEcSIFdCIIIAhBgIAPakEQdkECcSIIdEEPdiADIAVyIAhyayIDQQF0IAAgA0EVanZBAXFyQRxqIQMLIAQgAzYCHCAEQgA3AhAgA0ECdEG40oCAAGohBQJAQQAoAozQgIAAIghBASADdCIGcQ0AIAUgBDYCAEEAIAggBnI2AozQgIAAIAQgBTYCGCAEIAQ2AgggBCAENgIMDAQLIABBAEEZIANBAXZrIANBH0YbdCEDIAUoAgAhCANAIAgiBSgCBEF4cSAARg0DIANBHXYhCCADQQF0IQMgBSAIQQRxakEQaiIGKAIAIggNAAsgBiAENgIAIAQgBTYCGCAEIAQ2AgwgBCAENgIIDAMLIAUoAggiAyACNgIMIAUgAjYCCCACQQA2AhggAiAFNgIMIAIgAzYCCAsgC0EIaiEDDAULIAUoAggiAyAENgIMIAUgBDYCCCAEQQA2AhggBCAFNgIMIAQgAzYCCAtBACgClNCAgAAiAyACTQ0AQQAoAqDQgIAAIgQgAmoiBSADIAJrIgNBAXI2AgRBACADNgKU0ICAAEEAIAU2AqDQgIAAIAQgAkEDcjYCBCAEQQhqIQMMAwtBACEDQQBBMDYC+NOAgAAMAgsCQCALRQ0AAkACQCAIIAgoAhwiBUECdEG40oCAAGoiAygCAEcNACADIAA2AgAgAA0BQQAgB0F+IAV3cSIHNgKM0ICAAAwCCyALQRBBFCALKAIQIAhGG2ogADYCACAARQ0BCyAAIAs2AhgCQCAIKAIQIgNFDQAgACADNgIQIAMgADYCGAsgCEEUaigCACIDRQ0AIABBFGogAzYCACADIAA2AhgLAkACQCAEQQ9LDQAgCCAEIAJqIgNBA3I2AgQgCCADaiIDIAMoAgRBAXI2AgQMAQsgCCACaiIAIARBAXI2AgQgCCACQQNyNgIEIAAgBGogBDYCAAJAIARB/wFLDQAgBEF4cUGw0ICAAGohAwJAAkBBACgCiNCAgAAiBUEBIARBA3Z0IgRxDQBBACAFIARyNgKI0ICAACADIQQMAQsgAygCCCEECyAEIAA2AgwgAyAANgIIIAAgAzYCDCAAIAQ2AggMAQtBHyEDAkAgBEH///8HSw0AIARBCHYiAyADQYD+P2pBEHZBCHEiA3QiBSAFQYDgH2pBEHZBBHEiBXQiAiACQYCAD2pBEHZBAnEiAnRBD3YgAyAFciACcmsiA0EBdCAEIANBFWp2QQFxckEcaiEDCyAAIAM2AhwgAEIANwIQIANBAnRBuNKAgABqIQUCQCAHQQEgA3QiAnENACAFIAA2AgBBACAHIAJyNgKM0ICAACAAIAU2AhggACAANgIIIAAgADYCDAwBCyAEQQBBGSADQQF2ayADQR9GG3QhAyAFKAIAIQICQANAIAIiBSgCBEF4cSAERg0BIANBHXYhAiADQQF0IQMgBSACQQRxakEQaiIGKAIAIgINAAsgBiAANgIAIAAgBTYCGCAAIAA2AgwgACAANgIIDAELIAUoAggiAyAANgIMIAUgADYCCCAAQQA2AhggACAFNgIMIAAgAzYCCAsgCEEIaiEDDAELAkAgCkUNAAJAAkAgACAAKAIcIgVBAnRBuNKAgABqIgMoAgBHDQAgAyAINgIAIAgNAUEAIAlBfiAFd3E2AozQgIAADAILIApBEEEUIAooAhAgAEYbaiAINgIAIAhFDQELIAggCjYCGAJAIAAoAhAiA0UNACAIIAM2AhAgAyAINgIYCyAAQRRqKAIAIgNFDQAgCEEUaiADNgIAIAMgCDYCGAsCQAJAIARBD0sNACAAIAQgAmoiA0EDcjYCBCAAIANqIgMgAygCBEEBcjYCBAwBCyAAIAJqIgUgBEEBcjYCBCAAIAJBA3I2AgQgBSAEaiAENgIAAkAgB0UNACAHQXhxQbDQgIAAaiECQQAoApzQgIAAIQMCQAJAQQEgB0EDdnQiCCAGcQ0AQQAgCCAGcjYCiNCAgAAgAiEIDAELIAIoAgghCAsgCCADNgIMIAIgAzYCCCADIAI2AgwgAyAINgIIC0EAIAU2ApzQgIAAQQAgBDYCkNCAgAALIABBCGohAwsgAUEQaiSAgICAACADCwoAIAAQyYCAgAAL4g0BB38CQCAARQ0AIABBeGoiASAAQXxqKAIAIgJBeHEiAGohAwJAIAJBAXENACACQQNxRQ0BIAEgASgCACICayIBQQAoApjQgIAAIgRJDQEgAiAAaiEAAkAgAUEAKAKc0ICAAEYNAAJAIAJB/wFLDQAgASgCCCIEIAJBA3YiBUEDdEGw0ICAAGoiBkYaAkAgASgCDCICIARHDQBBAEEAKAKI0ICAAEF+IAV3cTYCiNCAgAAMAwsgAiAGRhogAiAENgIIIAQgAjYCDAwCCyABKAIYIQcCQAJAIAEoAgwiBiABRg0AIAEoAggiAiAESRogBiACNgIIIAIgBjYCDAwBCwJAIAFBFGoiAigCACIEDQAgAUEQaiICKAIAIgQNAEEAIQYMAQsDQCACIQUgBCIGQRRqIgIoAgAiBA0AIAZBEGohAiAGKAIQIgQNAAsgBUEANgIACyAHRQ0BAkACQCABIAEoAhwiBEECdEG40oCAAGoiAigCAEcNACACIAY2AgAgBg0BQQBBACgCjNCAgABBfiAEd3E2AozQgIAADAMLIAdBEEEUIAcoAhAgAUYbaiAGNgIAIAZFDQILIAYgBzYCGAJAIAEoAhAiAkUNACAGIAI2AhAgAiAGNgIYCyABKAIUIgJFDQEgBkEUaiACNgIAIAIgBjYCGAwBCyADKAIEIgJBA3FBA0cNACADIAJBfnE2AgRBACAANgKQ0ICAACABIABqIAA2AgAgASAAQQFyNgIEDwsgASADTw0AIAMoAgQiAkEBcUUNAAJAAkAgAkECcQ0AAkAgA0EAKAKg0ICAAEcNAEEAIAE2AqDQgIAAQQBBACgClNCAgAAgAGoiADYClNCAgAAgASAAQQFyNgIEIAFBACgCnNCAgABHDQNBAEEANgKQ0ICAAEEAQQA2ApzQgIAADwsCQCADQQAoApzQgIAARw0AQQAgATYCnNCAgABBAEEAKAKQ0ICAACAAaiIANgKQ0ICAACABIABBAXI2AgQgASAAaiAANgIADwsgAkF4cSAAaiEAAkACQCACQf8BSw0AIAMoAggiBCACQQN2IgVBA3RBsNCAgABqIgZGGgJAIAMoAgwiAiAERw0AQQBBACgCiNCAgABBfiAFd3E2AojQgIAADAILIAIgBkYaIAIgBDYCCCAEIAI2AgwMAQsgAygCGCEHAkACQCADKAIMIgYgA0YNACADKAIIIgJBACgCmNCAgABJGiAGIAI2AgggAiAGNgIMDAELAkAgA0EUaiICKAIAIgQNACADQRBqIgIoAgAiBA0AQQAhBgwBCwNAIAIhBSAEIgZBFGoiAigCACIEDQAgBkEQaiECIAYoAhAiBA0ACyAFQQA2AgALIAdFDQACQAJAIAMgAygCHCIEQQJ0QbjSgIAAaiICKAIARw0AIAIgBjYCACAGDQFBAEEAKAKM0ICAAEF+IAR3cTYCjNCAgAAMAgsgB0EQQRQgBygCECADRhtqIAY2AgAgBkUNAQsgBiAHNgIYAkAgAygCECICRQ0AIAYgAjYCECACIAY2AhgLIAMoAhQiAkUNACAGQRRqIAI2AgAgAiAGNgIYCyABIABqIAA2AgAgASAAQQFyNgIEIAFBACgCnNCAgABHDQFBACAANgKQ0ICAAA8LIAMgAkF+cTYCBCABIABqIAA2AgAgASAAQQFyNgIECwJAIABB/wFLDQAgAEF4cUGw0ICAAGohAgJAAkBBACgCiNCAgAAiBEEBIABBA3Z0IgBxDQBBACAEIAByNgKI0ICAACACIQAMAQsgAigCCCEACyAAIAE2AgwgAiABNgIIIAEgAjYCDCABIAA2AggPC0EfIQICQCAAQf///wdLDQAgAEEIdiICIAJBgP4/akEQdkEIcSICdCIEIARBgOAfakEQdkEEcSIEdCIGIAZBgIAPakEQdkECcSIGdEEPdiACIARyIAZyayICQQF0IAAgAkEVanZBAXFyQRxqIQILIAEgAjYCHCABQgA3AhAgAkECdEG40oCAAGohBAJAAkBBACgCjNCAgAAiBkEBIAJ0IgNxDQAgBCABNgIAQQAgBiADcjYCjNCAgAAgASAENgIYIAEgATYCCCABIAE2AgwMAQsgAEEAQRkgAkEBdmsgAkEfRht0IQIgBCgCACEGAkADQCAGIgQoAgRBeHEgAEYNASACQR12IQYgAkEBdCECIAQgBkEEcWpBEGoiAygCACIGDQALIAMgATYCACABIAQ2AhggASABNgIMIAEgATYCCAwBCyAEKAIIIgAgATYCDCAEIAE2AgggAUEANgIYIAEgBDYCDCABIAA2AggLQQBBACgCqNCAgABBf2oiAUF/IAEbNgKo0ICAAAsLBAAAAAtOAAJAIAANAD8AQRB0DwsCQCAAQf//A3ENACAAQX9MDQACQCAAQRB2QAAiAEF/Rw0AQQBBMDYC+NOAgABBfw8LIABBEHQPCxDKgICAAAAL8gICA38BfgJAIAJFDQAgACABOgAAIAIgAGoiA0F/aiABOgAAIAJBA0kNACAAIAE6AAIgACABOgABIANBfWogAToAACADQX5qIAE6AAAgAkEHSQ0AIAAgAToAAyADQXxqIAE6AAAgAkEJSQ0AIABBACAAa0EDcSIEaiIDIAFB/wFxQYGChAhsIgE2AgAgAyACIARrQXxxIgRqIgJBfGogATYCACAEQQlJDQAgAyABNgIIIAMgATYCBCACQXhqIAE2AgAgAkF0aiABNgIAIARBGUkNACADIAE2AhggAyABNgIUIAMgATYCECADIAE2AgwgAkFwaiABNgIAIAJBbGogATYCACACQWhqIAE2AgAgAkFkaiABNgIAIAQgA0EEcUEYciIFayICQSBJDQAgAa1CgYCAgBB+IQYgAyAFaiEBA0AgASAGNwMYIAEgBjcDECABIAY3AwggASAGNwMAIAFBIGohASACQWBqIgJBH0sNAAsLIAALC45IAQBBgAgLhkgBAAAAAgAAAAMAAAAAAAAAAAAAAAQAAAAFAAAAAAAAAAAAAAAGAAAABwAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEludmFsaWQgY2hhciBpbiB1cmwgcXVlcnkAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9ib2R5AENvbnRlbnQtTGVuZ3RoIG92ZXJmbG93AENodW5rIHNpemUgb3ZlcmZsb3cAUmVzcG9uc2Ugb3ZlcmZsb3cASW52YWxpZCBtZXRob2QgZm9yIEhUVFAveC54IHJlcXVlc3QASW52YWxpZCBtZXRob2QgZm9yIFJUU1AveC54IHJlcXVlc3QARXhwZWN0ZWQgU09VUkNFIG1ldGhvZCBmb3IgSUNFL3gueCByZXF1ZXN0AEludmFsaWQgY2hhciBpbiB1cmwgZnJhZ21lbnQgc3RhcnQARXhwZWN0ZWQgZG90AFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fc3RhdHVzAEludmFsaWQgcmVzcG9uc2Ugc3RhdHVzAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMAVXNlciBjYWxsYmFjayBlcnJvcgBgb25fcmVzZXRgIGNhbGxiYWNrIGVycm9yAGBvbl9jaHVua19oZWFkZXJgIGNhbGxiYWNrIGVycm9yAGBvbl9tZXNzYWdlX2JlZ2luYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfZXh0ZW5zaW9uX3ZhbHVlYCBjYWxsYmFjayBlcnJvcgBgb25fc3RhdHVzX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fdmVyc2lvbl9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX3VybF9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2NodW5rX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25faGVhZGVyX3ZhbHVlX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fbWVzc2FnZV9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX21ldGhvZF9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2hlYWRlcl9maWVsZF9jb21wbGV0ZWAgY2FsbGJhY2sgZXJyb3IAYG9uX2NodW5rX2V4dGVuc2lvbl9uYW1lYCBjYWxsYmFjayBlcnJvcgBVbmV4cGVjdGVkIGNoYXIgaW4gdXJsIHNlcnZlcgBJbnZhbGlkIGhlYWRlciB2YWx1ZSBjaGFyAEludmFsaWQgaGVhZGVyIGZpZWxkIGNoYXIAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl92ZXJzaW9uAEludmFsaWQgbWlub3IgdmVyc2lvbgBJbnZhbGlkIG1ham9yIHZlcnNpb24ARXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgdmVyc2lvbgBFeHBlY3RlZCBDUkxGIGFmdGVyIHZlcnNpb24ASW52YWxpZCBIVFRQIHZlcnNpb24ASW52YWxpZCBoZWFkZXIgdG9rZW4AU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl91cmwASW52YWxpZCBjaGFyYWN0ZXJzIGluIHVybABVbmV4cGVjdGVkIHN0YXJ0IGNoYXIgaW4gdXJsAERvdWJsZSBAIGluIHVybABFbXB0eSBDb250ZW50LUxlbmd0aABJbnZhbGlkIGNoYXJhY3RlciBpbiBDb250ZW50LUxlbmd0aABEdXBsaWNhdGUgQ29udGVudC1MZW5ndGgASW52YWxpZCBjaGFyIGluIHVybCBwYXRoAENvbnRlbnQtTGVuZ3RoIGNhbid0IGJlIHByZXNlbnQgd2l0aCBUcmFuc2Zlci1FbmNvZGluZwBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBzaXplAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25faGVhZGVyX3ZhbHVlAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25fY2h1bmtfZXh0ZW5zaW9uX3ZhbHVlAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgdmFsdWUATWlzc2luZyBleHBlY3RlZCBMRiBhZnRlciBoZWFkZXIgdmFsdWUASW52YWxpZCBgVHJhbnNmZXItRW5jb2RpbmdgIGhlYWRlciB2YWx1ZQBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zIHF1b3RlIHZhbHVlAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgcXVvdGVkIHZhbHVlAFBhdXNlZCBieSBvbl9oZWFkZXJzX2NvbXBsZXRlAEludmFsaWQgRU9GIHN0YXRlAG9uX3Jlc2V0IHBhdXNlAG9uX2NodW5rX2hlYWRlciBwYXVzZQBvbl9tZXNzYWdlX2JlZ2luIHBhdXNlAG9uX2NodW5rX2V4dGVuc2lvbl92YWx1ZSBwYXVzZQBvbl9zdGF0dXNfY29tcGxldGUgcGF1c2UAb25fdmVyc2lvbl9jb21wbGV0ZSBwYXVzZQBvbl91cmxfY29tcGxldGUgcGF1c2UAb25fY2h1bmtfY29tcGxldGUgcGF1c2UAb25faGVhZGVyX3ZhbHVlX2NvbXBsZXRlIHBhdXNlAG9uX21lc3NhZ2VfY29tcGxldGUgcGF1c2UAb25fbWV0aG9kX2NvbXBsZXRlIHBhdXNlAG9uX2hlYWRlcl9maWVsZF9jb21wbGV0ZSBwYXVzZQBvbl9jaHVua19leHRlbnNpb25fbmFtZSBwYXVzZQBVbmV4cGVjdGVkIHNwYWNlIGFmdGVyIHN0YXJ0IGxpbmUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9jaHVua19leHRlbnNpb25fbmFtZQBJbnZhbGlkIGNoYXJhY3RlciBpbiBjaHVuayBleHRlbnNpb25zIG5hbWUAUGF1c2Ugb24gQ09OTkVDVC9VcGdyYWRlAFBhdXNlIG9uIFBSSS9VcGdyYWRlAEV4cGVjdGVkIEhUVFAvMiBDb25uZWN0aW9uIFByZWZhY2UAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9tZXRob2QARXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgbWV0aG9kAFNwYW4gY2FsbGJhY2sgZXJyb3IgaW4gb25faGVhZGVyX2ZpZWxkAFBhdXNlZABJbnZhbGlkIHdvcmQgZW5jb3VudGVyZWQASW52YWxpZCBtZXRob2QgZW5jb3VudGVyZWQAVW5leHBlY3RlZCBjaGFyIGluIHVybCBzY2hlbWEAUmVxdWVzdCBoYXMgaW52YWxpZCBgVHJhbnNmZXItRW5jb2RpbmdgAFNXSVRDSF9QUk9YWQBVU0VfUFJPWFkATUtBQ1RJVklUWQBVTlBST0NFU1NBQkxFX0VOVElUWQBDT1BZAE1PVkVEX1BFUk1BTkVOVExZAFRPT19FQVJMWQBOT1RJRlkARkFJTEVEX0RFUEVOREVOQ1kAQkFEX0dBVEVXQVkAUExBWQBQVVQAQ0hFQ0tPVVQAR0FURVdBWV9USU1FT1VUAFJFUVVFU1RfVElNRU9VVABORVRXT1JLX0NPTk5FQ1RfVElNRU9VVABDT05ORUNUSU9OX1RJTUVPVVQATE9HSU5fVElNRU9VVABORVRXT1JLX1JFQURfVElNRU9VVABQT1NUAE1JU0RJUkVDVEVEX1JFUVVFU1QAQ0xJRU5UX0NMT1NFRF9SRVFVRVNUAENMSUVOVF9DTE9TRURfTE9BRF9CQUxBTkNFRF9SRVFVRVNUAEJBRF9SRVFVRVNUAEhUVFBfUkVRVUVTVF9TRU5UX1RPX0hUVFBTX1BPUlQAUkVQT1JUAElNX0FfVEVBUE9UAFJFU0VUX0NPTlRFTlQATk9fQ09OVEVOVABQQVJUSUFMX0NPTlRFTlQASFBFX0lOVkFMSURfQ09OU1RBTlQASFBFX0NCX1JFU0VUAEdFVABIUEVfU1RSSUNUAENPTkZMSUNUAFRFTVBPUkFSWV9SRURJUkVDVABQRVJNQU5FTlRfUkVESVJFQ1QAQ09OTkVDVABNVUxUSV9TVEFUVVMASFBFX0lOVkFMSURfU1RBVFVTAFRPT19NQU5ZX1JFUVVFU1RTAEVBUkxZX0hJTlRTAFVOQVZBSUxBQkxFX0ZPUl9MRUdBTF9SRUFTT05TAE9QVElPTlMAU1dJVENISU5HX1BST1RPQ09MUwBWQVJJQU5UX0FMU09fTkVHT1RJQVRFUwBNVUxUSVBMRV9DSE9JQ0VTAElOVEVSTkFMX1NFUlZFUl9FUlJPUgBXRUJfU0VSVkVSX1VOS05PV05fRVJST1IAUkFJTEdVTl9FUlJPUgBJREVOVElUWV9QUk9WSURFUl9BVVRIRU5USUNBVElPTl9FUlJPUgBTU0xfQ0VSVElGSUNBVEVfRVJST1IASU5WQUxJRF9YX0ZPUldBUkRFRF9GT1IAU0VUX1BBUkFNRVRFUgBHRVRfUEFSQU1FVEVSAEhQRV9VU0VSAFNFRV9PVEhFUgBIUEVfQ0JfQ0hVTktfSEVBREVSAE1LQ0FMRU5EQVIAU0VUVVAAV0VCX1NFUlZFUl9JU19ET1dOAFRFQVJET1dOAEhQRV9DTE9TRURfQ09OTkVDVElPTgBIRVVSSVNUSUNfRVhQSVJBVElPTgBESVNDT05ORUNURURfT1BFUkFUSU9OAE5PTl9BVVRIT1JJVEFUSVZFX0lORk9STUFUSU9OAEhQRV9JTlZBTElEX1ZFUlNJT04ASFBFX0NCX01FU1NBR0VfQkVHSU4AU0lURV9JU19GUk9aRU4ASFBFX0lOVkFMSURfSEVBREVSX1RPS0VOAElOVkFMSURfVE9LRU4ARk9SQklEREVOAEVOSEFOQ0VfWU9VUl9DQUxNAEhQRV9JTlZBTElEX1VSTABCTE9DS0VEX0JZX1BBUkVOVEFMX0NPTlRST0wATUtDT0wAQUNMAEhQRV9JTlRFUk5BTABSRVFVRVNUX0hFQURFUl9GSUVMRFNfVE9PX0xBUkdFX1VOT0ZGSUNJQUwASFBFX09LAFVOTElOSwBVTkxPQ0sAUFJJAFJFVFJZX1dJVEgASFBFX0lOVkFMSURfQ09OVEVOVF9MRU5HVEgASFBFX1VORVhQRUNURURfQ09OVEVOVF9MRU5HVEgARkxVU0gAUFJPUFBBVENIAE0tU0VBUkNIAFVSSV9UT09fTE9ORwBQUk9DRVNTSU5HAE1JU0NFTExBTkVPVVNfUEVSU0lTVEVOVF9XQVJOSU5HAE1JU0NFTExBTkVPVVNfV0FSTklORwBIUEVfSU5WQUxJRF9UUkFOU0ZFUl9FTkNPRElORwBFeHBlY3RlZCBDUkxGAEhQRV9JTlZBTElEX0NIVU5LX1NJWkUATU9WRQBDT05USU5VRQBIUEVfQ0JfU1RBVFVTX0NPTVBMRVRFAEhQRV9DQl9IRUFERVJTX0NPTVBMRVRFAEhQRV9DQl9WRVJTSU9OX0NPTVBMRVRFAEhQRV9DQl9VUkxfQ09NUExFVEUASFBFX0NCX0NIVU5LX0NPTVBMRVRFAEhQRV9DQl9IRUFERVJfVkFMVUVfQ09NUExFVEUASFBFX0NCX0NIVU5LX0VYVEVOU0lPTl9WQUxVRV9DT01QTEVURQBIUEVfQ0JfQ0hVTktfRVhURU5TSU9OX05BTUVfQ09NUExFVEUASFBFX0NCX01FU1NBR0VfQ09NUExFVEUASFBFX0NCX01FVEhPRF9DT01QTEVURQBIUEVfQ0JfSEVBREVSX0ZJRUxEX0NPTVBMRVRFAERFTEVURQBIUEVfSU5WQUxJRF9FT0ZfU1RBVEUASU5WQUxJRF9TU0xfQ0VSVElGSUNBVEUAUEFVU0UATk9fUkVTUE9OU0UAVU5TVVBQT1JURURfTUVESUFfVFlQRQBHT05FAE5PVF9BQ0NFUFRBQkxFAFNFUlZJQ0VfVU5BVkFJTEFCTEUAUkFOR0VfTk9UX1NBVElTRklBQkxFAE9SSUdJTl9JU19VTlJFQUNIQUJMRQBSRVNQT05TRV9JU19TVEFMRQBQVVJHRQBNRVJHRQBSRVFVRVNUX0hFQURFUl9GSUVMRFNfVE9PX0xBUkdFAFJFUVVFU1RfSEVBREVSX1RPT19MQVJHRQBQQVlMT0FEX1RPT19MQVJHRQBJTlNVRkZJQ0lFTlRfU1RPUkFHRQBIUEVfUEFVU0VEX1VQR1JBREUASFBFX1BBVVNFRF9IMl9VUEdSQURFAFNPVVJDRQBBTk5PVU5DRQBUUkFDRQBIUEVfVU5FWFBFQ1RFRF9TUEFDRQBERVNDUklCRQBVTlNVQlNDUklCRQBSRUNPUkQASFBFX0lOVkFMSURfTUVUSE9EAE5PVF9GT1VORABQUk9QRklORABVTkJJTkQAUkVCSU5EAFVOQVVUSE9SSVpFRABNRVRIT0RfTk9UX0FMTE9XRUQASFRUUF9WRVJTSU9OX05PVF9TVVBQT1JURUQAQUxSRUFEWV9SRVBPUlRFRABBQ0NFUFRFRABOT1RfSU1QTEVNRU5URUQATE9PUF9ERVRFQ1RFRABIUEVfQ1JfRVhQRUNURUQASFBFX0xGX0VYUEVDVEVEAENSRUFURUQASU1fVVNFRABIUEVfUEFVU0VEAFRJTUVPVVRfT0NDVVJFRABQQVlNRU5UX1JFUVVJUkVEAFBSRUNPTkRJVElPTl9SRVFVSVJFRABQUk9YWV9BVVRIRU5USUNBVElPTl9SRVFVSVJFRABORVRXT1JLX0FVVEhFTlRJQ0FUSU9OX1JFUVVJUkVEAExFTkdUSF9SRVFVSVJFRABTU0xfQ0VSVElGSUNBVEVfUkVRVUlSRUQAVVBHUkFERV9SRVFVSVJFRABQQUdFX0VYUElSRUQAUFJFQ09ORElUSU9OX0ZBSUxFRABFWFBFQ1RBVElPTl9GQUlMRUQAUkVWQUxJREFUSU9OX0ZBSUxFRABTU0xfSEFORFNIQUtFX0ZBSUxFRABMT0NLRUQAVFJBTlNGT1JNQVRJT05fQVBQTElFRABOT1RfTU9ESUZJRUQATk9UX0VYVEVOREVEAEJBTkRXSURUSF9MSU1JVF9FWENFRURFRABTSVRFX0lTX09WRVJMT0FERUQASEVBRABFeHBlY3RlZCBIVFRQLwAAXhMAACYTAAAwEAAA8BcAAJ0TAAAVEgAAORcAAPASAAAKEAAAdRIAAK0SAACCEwAATxQAAH8QAACgFQAAIxQAAIkSAACLFAAATRUAANQRAADPFAAAEBgAAMkWAADcFgAAwREAAOAXAAC7FAAAdBQAAHwVAADlFAAACBcAAB8QAABlFQAAoxQAACgVAAACFQAAmRUAACwQAACLGQAATw8AANQOAABqEAAAzhAAAAIXAACJDgAAbhMAABwTAABmFAAAVhcAAMETAADNEwAAbBMAAGgXAABmFwAAXxcAACITAADODwAAaQ4AANgOAABjFgAAyxMAAKoOAAAoFwAAJhcAAMUTAABdFgAA6BEAAGcTAABlEwAA8hYAAHMTAAAdFwAA+RYAAPMRAADPDgAAzhUAAAwSAACzEQAApREAAGEQAAAyFwAAuxMAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQIBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIDAgICAgIAAAICAAICAAICAgICAgICAgIABAAAAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgICAgACAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAACAAICAgICAAACAgACAgACAgICAgICAgICAAMABAAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIAAgACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAbG9zZWVlcC1hbGl2ZQAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQIBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBY2h1bmtlZAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEAAQEBAQEAAAEBAAEBAAEBAQEBAQEBAQEAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABlY3Rpb25lbnQtbGVuZ3Rob25yb3h5LWNvbm5lY3Rpb24AAAAAAAAAAAAAAAAAAAByYW5zZmVyLWVuY29kaW5ncGdyYWRlDQoNCg0KU00NCg0KVFRQL0NFL1RTUC8AAAAAAAAAAAAAAAABAgABAwAAAAAAAAAAAAAAAAAAAAAAAAQBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAQIAAQMAAAAAAAAAAAAAAAAAAAAAAAAEAQEFAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAEAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAQAAAgAAAAAAAAAAAAAAAAAAAAAAAAMEAAAEBAQEBAQEBAQEBAUEBAQEBAQEBAQEBAQABAAGBwQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEAAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAEAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAABAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAIAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABOT1VOQ0VFQ0tPVVRORUNURVRFQ1JJQkVMVVNIRVRFQURTRUFSQ0hSR0VDVElWSVRZTEVOREFSVkVPVElGWVBUSU9OU0NIU0VBWVNUQVRDSEdFT1JESVJFQ1RPUlRSQ0hQQVJBTUVURVJVUkNFQlNDUklCRUFSRE9XTkFDRUlORE5LQ0tVQlNDUklCRUhUVFAvQURUUC8=' + + /***/ + }, + + /***/ 5627: /***/ (module) => { + module.exports = + 'AGFzbQEAAAABMAhgAX8Bf2ADf39/AX9gBH9/f38Bf2AAAGADf39/AGABfwBgAn9/AGAGf39/f39/AALLAQgDZW52GHdhc21fb25faGVhZGVyc19jb21wbGV0ZQACA2VudhV3YXNtX29uX21lc3NhZ2VfYmVnaW4AAANlbnYLd2FzbV9vbl91cmwAAQNlbnYOd2FzbV9vbl9zdGF0dXMAAQNlbnYUd2FzbV9vbl9oZWFkZXJfZmllbGQAAQNlbnYUd2FzbV9vbl9oZWFkZXJfdmFsdWUAAQNlbnYMd2FzbV9vbl9ib2R5AAEDZW52GHdhc21fb25fbWVzc2FnZV9jb21wbGV0ZQAAA0ZFAwMEAAAFAAAAAAAABQEFAAUFBQAABgAAAAAGBgYGAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAAABAQcAAAUFAwABBAUBcAESEgUDAQACBggBfwFBgNQECwfRBSIGbWVtb3J5AgALX2luaXRpYWxpemUACRlfX2luZGlyZWN0X2Z1bmN0aW9uX3RhYmxlAQALbGxodHRwX2luaXQAChhsbGh0dHBfc2hvdWxkX2tlZXBfYWxpdmUAQQxsbGh0dHBfYWxsb2MADAZtYWxsb2MARgtsbGh0dHBfZnJlZQANBGZyZWUASA9sbGh0dHBfZ2V0X3R5cGUADhVsbGh0dHBfZ2V0X2h0dHBfbWFqb3IADxVsbGh0dHBfZ2V0X2h0dHBfbWlub3IAEBFsbGh0dHBfZ2V0X21ldGhvZAARFmxsaHR0cF9nZXRfc3RhdHVzX2NvZGUAEhJsbGh0dHBfZ2V0X3VwZ3JhZGUAEwxsbGh0dHBfcmVzZXQAFA5sbGh0dHBfZXhlY3V0ZQAVFGxsaHR0cF9zZXR0aW5nc19pbml0ABYNbGxodHRwX2ZpbmlzaAAXDGxsaHR0cF9wYXVzZQAYDWxsaHR0cF9yZXN1bWUAGRtsbGh0dHBfcmVzdW1lX2FmdGVyX3VwZ3JhZGUAGhBsbGh0dHBfZ2V0X2Vycm5vABsXbGxodHRwX2dldF9lcnJvcl9yZWFzb24AHBdsbGh0dHBfc2V0X2Vycm9yX3JlYXNvbgAdFGxsaHR0cF9nZXRfZXJyb3JfcG9zAB4RbGxodHRwX2Vycm5vX25hbWUAHxJsbGh0dHBfbWV0aG9kX25hbWUAIBJsbGh0dHBfc3RhdHVzX25hbWUAIRpsbGh0dHBfc2V0X2xlbmllbnRfaGVhZGVycwAiIWxsaHR0cF9zZXRfbGVuaWVudF9jaHVua2VkX2xlbmd0aAAjHWxsaHR0cF9zZXRfbGVuaWVudF9rZWVwX2FsaXZlACQkbGxodHRwX3NldF9sZW5pZW50X3RyYW5zZmVyX2VuY29kaW5nACUYbGxodHRwX21lc3NhZ2VfbmVlZHNfZW9mAD8JFwEAQQELEQECAwQFCwYHNTk3MS8tJyspCrLgAkUCAAsIABCIgICAAAsZACAAEMKAgIAAGiAAIAI2AjggACABOgAoCxwAIAAgAC8BMiAALQAuIAAQwYCAgAAQgICAgAALKgEBf0HAABDGgICAACIBEMKAgIAAGiABQYCIgIAANgI4IAEgADoAKCABCwoAIAAQyICAgAALBwAgAC0AKAsHACAALQAqCwcAIAAtACsLBwAgAC0AKQsHACAALwEyCwcAIAAtAC4LRQEEfyAAKAIYIQEgAC0ALSECIAAtACghAyAAKAI4IQQgABDCgICAABogACAENgI4IAAgAzoAKCAAIAI6AC0gACABNgIYCxEAIAAgASABIAJqEMOAgIAACxAAIABBAEHcABDMgICAABoLZwEBf0EAIQECQCAAKAIMDQACQAJAAkACQCAALQAvDgMBAAMCCyAAKAI4IgFFDQAgASgCLCIBRQ0AIAAgARGAgICAAAAiAQ0DC0EADwsQyoCAgAAACyAAQcOWgIAANgIQQQ4hAQsgAQseAAJAIAAoAgwNACAAQdGbgIAANgIQIABBFTYCDAsLFgACQCAAKAIMQRVHDQAgAEEANgIMCwsWAAJAIAAoAgxBFkcNACAAQQA2AgwLCwcAIAAoAgwLBwAgACgCEAsJACAAIAE2AhALBwAgACgCFAsiAAJAIABBJEkNABDKgICAAAALIABBAnRBoLOAgABqKAIACyIAAkAgAEEuSQ0AEMqAgIAAAAsgAEECdEGwtICAAGooAgAL7gsBAX9B66iAgAAhAQJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIABBnH9qDvQDY2IAAWFhYWFhYQIDBAVhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhBgcICQoLDA0OD2FhYWFhEGFhYWFhYWFhYWFhEWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYRITFBUWFxgZGhthYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhHB0eHyAhIiMkJSYnKCkqKywtLi8wMTIzNDU2YTc4OTphYWFhYWFhYTthYWE8YWFhYT0+P2FhYWFhYWFhQGFhQWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYUJDREVGR0hJSktMTU5PUFFSU2FhYWFhYWFhVFVWV1hZWlthXF1hYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFeYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFhX2BhC0Hhp4CAAA8LQaShgIAADwtBy6yAgAAPC0H+sYCAAA8LQcCkgIAADwtBq6SAgAAPC0GNqICAAA8LQeKmgIAADwtBgLCAgAAPC0G5r4CAAA8LQdekgIAADwtB75+AgAAPC0Hhn4CAAA8LQfqfgIAADwtB8qCAgAAPC0Gor4CAAA8LQa6ygIAADwtBiLCAgAAPC0Hsp4CAAA8LQYKigIAADwtBjp2AgAAPC0HQroCAAA8LQcqjgIAADwtBxbKAgAAPC0HfnICAAA8LQdKcgIAADwtBxKCAgAAPC0HXoICAAA8LQaKfgIAADwtB7a6AgAAPC0GrsICAAA8LQdSlgIAADwtBzK6AgAAPC0H6roCAAA8LQfyrgIAADwtB0rCAgAAPC0HxnYCAAA8LQbuggIAADwtB96uAgAAPC0GQsYCAAA8LQdexgIAADwtBoq2AgAAPC0HUp4CAAA8LQeCrgIAADwtBn6yAgAAPC0HrsYCAAA8LQdWfgIAADwtByrGAgAAPC0HepYCAAA8LQdSegIAADwtB9JyAgAAPC0GnsoCAAA8LQbGdgIAADwtBoJ2AgAAPC0G5sYCAAA8LQbywgIAADwtBkqGAgAAPC0GzpoCAAA8LQemsgIAADwtBrJ6AgAAPC0HUq4CAAA8LQfemgIAADwtBgKaAgAAPC0GwoYCAAA8LQf6egIAADwtBjaOAgAAPC0GJrYCAAA8LQfeigIAADwtBoLGAgAAPC0Gun4CAAA8LQcalgIAADwtB6J6AgAAPC0GTooCAAA8LQcKvgIAADwtBw52AgAAPC0GLrICAAA8LQeGdgIAADwtBja+AgAAPC0HqoYCAAA8LQbStgIAADwtB0q+AgAAPC0HfsoCAAA8LQdKygIAADwtB8LCAgAAPC0GpooCAAA8LQfmjgIAADwtBmZ6AgAAPC0G1rICAAA8LQZuwgIAADwtBkrKAgAAPC0G2q4CAAA8LQcKigIAADwtB+LKAgAAPC0GepYCAAA8LQdCigIAADwtBup6AgAAPC0GBnoCAAA8LEMqAgIAAAAtB1qGAgAAhAQsgAQsWACAAIAAtAC1B/gFxIAFBAEdyOgAtCxkAIAAgAC0ALUH9AXEgAUEAR0EBdHI6AC0LGQAgACAALQAtQfsBcSABQQBHQQJ0cjoALQsZACAAIAAtAC1B9wFxIAFBAEdBA3RyOgAtCy4BAn9BACEDAkAgACgCOCIERQ0AIAQoAgAiBEUNACAAIAQRgICAgAAAIQMLIAMLSQECf0EAIQMCQCAAKAI4IgRFDQAgBCgCBCIERQ0AIAAgASACIAFrIAQRgYCAgAAAIgNBf0cNACAAQcaRgIAANgIQQRghAwsgAwsuAQJ/QQAhAwJAIAAoAjgiBEUNACAEKAIwIgRFDQAgACAEEYCAgIAAACEDCyADC0kBAn9BACEDAkAgACgCOCIERQ0AIAQoAggiBEUNACAAIAEgAiABayAEEYGAgIAAACIDQX9HDQAgAEH2ioCAADYCEEEYIQMLIAMLLgECf0EAIQMCQCAAKAI4IgRFDQAgBCgCNCIERQ0AIAAgBBGAgICAAAAhAwsgAwtJAQJ/QQAhAwJAIAAoAjgiBEUNACAEKAIMIgRFDQAgACABIAIgAWsgBBGBgICAAAAiA0F/Rw0AIABB7ZqAgAA2AhBBGCEDCyADCy4BAn9BACEDAkAgACgCOCIERQ0AIAQoAjgiBEUNACAAIAQRgICAgAAAIQMLIAMLSQECf0EAIQMCQCAAKAI4IgRFDQAgBCgCECIERQ0AIAAgASACIAFrIAQRgYCAgAAAIgNBf0cNACAAQZWQgIAANgIQQRghAwsgAwsuAQJ/QQAhAwJAIAAoAjgiBEUNACAEKAI8IgRFDQAgACAEEYCAgIAAACEDCyADC0kBAn9BACEDAkAgACgCOCIERQ0AIAQoAhQiBEUNACAAIAEgAiABayAEEYGAgIAAACIDQX9HDQAgAEGqm4CAADYCEEEYIQMLIAMLLgECf0EAIQMCQCAAKAI4IgRFDQAgBCgCQCIERQ0AIAAgBBGAgICAAAAhAwsgAwtJAQJ/QQAhAwJAIAAoAjgiBEUNACAEKAIYIgRFDQAgACABIAIgAWsgBBGBgICAAAAiA0F/Rw0AIABB7ZOAgAA2AhBBGCEDCyADCy4BAn9BACEDAkAgACgCOCIERQ0AIAQoAkQiBEUNACAAIAQRgICAgAAAIQMLIAMLLgECf0EAIQMCQCAAKAI4IgRFDQAgBCgCJCIERQ0AIAAgBBGAgICAAAAhAwsgAwsuAQJ/QQAhAwJAIAAoAjgiBEUNACAEKAIsIgRFDQAgACAEEYCAgIAAACEDCyADC0kBAn9BACEDAkAgACgCOCIERQ0AIAQoAigiBEUNACAAIAEgAiABayAEEYGAgIAAACIDQX9HDQAgAEH2iICAADYCEEEYIQMLIAMLLgECf0EAIQMCQCAAKAI4IgRFDQAgBCgCUCIERQ0AIAAgBBGAgICAAAAhAwsgAwtJAQJ/QQAhAwJAIAAoAjgiBEUNACAEKAIcIgRFDQAgACABIAIgAWsgBBGBgICAAAAiA0F/Rw0AIABBwpmAgAA2AhBBGCEDCyADCy4BAn9BACEDAkAgACgCOCIERQ0AIAQoAkgiBEUNACAAIAQRgICAgAAAIQMLIAMLSQECf0EAIQMCQCAAKAI4IgRFDQAgBCgCICIERQ0AIAAgASACIAFrIAQRgYCAgAAAIgNBf0cNACAAQZSUgIAANgIQQRghAwsgAwsuAQJ/QQAhAwJAIAAoAjgiBEUNACAEKAJMIgRFDQAgACAEEYCAgIAAACEDCyADCy4BAn9BACEDAkAgACgCOCIERQ0AIAQoAlQiBEUNACAAIAQRgICAgAAAIQMLIAMLLgECf0EAIQMCQCAAKAI4IgRFDQAgBCgCWCIERQ0AIAAgBBGAgICAAAAhAwsgAwtFAQF/AkACQCAALwEwQRRxQRRHDQBBASEDIAAtAChBAUYNASAALwEyQeUARiEDDAELIAAtAClBBUYhAwsgACADOgAuQQAL/gEBA39BASEDAkAgAC8BMCIEQQhxDQAgACkDIEIAUiEDCwJAAkAgAC0ALkUNAEEBIQUgAC0AKUEFRg0BQQEhBSAEQcAAcUUgA3FBAUcNAQtBACEFIARBwABxDQBBAiEFIARB//8DcSIDQQhxDQACQCADQYAEcUUNAAJAIAAtAChBAUcNACAALQAtQQpxDQBBBQ8LQQQPCwJAIANBIHENAAJAIAAtAChBAUYNACAALwEyQf//A3EiAEGcf2pB5ABJDQAgAEHMAUYNACAAQbACRg0AQQQhBSAEQShxRQ0CIANBiARxQYAERg0CC0EADwtBAEEDIAApAyBQGyEFCyAFC2IBAn9BACEBAkAgAC0AKEEBRg0AIAAvATJB//8DcSICQZx/akHkAEkNACACQcwBRg0AIAJBsAJGDQAgAC8BMCIAQcAAcQ0AQQEhASAAQYgEcUGABEYNACAAQShxRSEBCyABC6cBAQN/AkACQAJAIAAtACpFDQAgAC0AK0UNAEEAIQMgAC8BMCIEQQJxRQ0BDAILQQAhAyAALwEwIgRBAXFFDQELQQEhAyAALQAoQQFGDQAgAC8BMkH//wNxIgVBnH9qQeQASQ0AIAVBzAFGDQAgBUGwAkYNACAEQcAAcQ0AQQAhAyAEQYgEcUGABEYNACAEQShxQQBHIQMLIABBADsBMCAAQQA6AC8gAwuZAQECfwJAAkACQCAALQAqRQ0AIAAtACtFDQBBACEBIAAvATAiAkECcUUNAQwCC0EAIQEgAC8BMCICQQFxRQ0BC0EBIQEgAC0AKEEBRg0AIAAvATJB//8DcSIAQZx/akHkAEkNACAAQcwBRg0AIABBsAJGDQAgAkHAAHENAEEAIQEgAkGIBHFBgARGDQAgAkEocUEARyEBCyABC0kBAXsgAEEQav0MAAAAAAAAAAAAAAAAAAAAACIB/QsDACAAIAH9CwMAIABBMGogAf0LAwAgAEEgaiAB/QsDACAAQd0BNgIcQQALewEBfwJAIAAoAgwiAw0AAkAgACgCBEUNACAAIAE2AgQLAkAgACABIAIQxICAgAAiAw0AIAAoAgwPCyAAIAM2AhxBACEDIAAoAgQiAUUNACAAIAEgAiAAKAIIEYGAgIAAACIBRQ0AIAAgAjYCFCAAIAE2AgwgASEDCyADC+TzAQMOfwN+BH8jgICAgABBEGsiAySAgICAACABIQQgASEFIAEhBiABIQcgASEIIAEhCSABIQogASELIAEhDCABIQ0gASEOIAEhDwJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCAAKAIcIhBBf2oO3QHaAQHZAQIDBAUGBwgJCgsMDQ7YAQ8Q1wEREtYBExQVFhcYGRob4AHfARwdHtUBHyAhIiMkJdQBJicoKSorLNMB0gEtLtEB0AEvMDEyMzQ1Njc4OTo7PD0+P0BBQkNERUbbAUdISUrPAc4BS80BTMwBTU5PUFFSU1RVVldYWVpbXF1eX2BhYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ent8fX5/gAGBAYIBgwGEAYUBhgGHAYgBiQGKAYsBjAGNAY4BjwGQAZEBkgGTAZQBlQGWAZcBmAGZAZoBmwGcAZ0BngGfAaABoQGiAaMBpAGlAaYBpwGoAakBqgGrAawBrQGuAa8BsAGxAbIBswG0AbUBtgG3AcsBygG4AckBuQHIAboBuwG8Ab0BvgG/AcABwQHCAcMBxAHFAcYBANwBC0EAIRAMxgELQQ4hEAzFAQtBDSEQDMQBC0EPIRAMwwELQRAhEAzCAQtBEyEQDMEBC0EUIRAMwAELQRUhEAy/AQtBFiEQDL4BC0EXIRAMvQELQRghEAy8AQtBGSEQDLsBC0EaIRAMugELQRshEAy5AQtBHCEQDLgBC0EIIRAMtwELQR0hEAy2AQtBICEQDLUBC0EfIRAMtAELQQchEAyzAQtBISEQDLIBC0EiIRAMsQELQR4hEAywAQtBIyEQDK8BC0ESIRAMrgELQREhEAytAQtBJCEQDKwBC0ElIRAMqwELQSYhEAyqAQtBJyEQDKkBC0HDASEQDKgBC0EpIRAMpwELQSshEAymAQtBLCEQDKUBC0EtIRAMpAELQS4hEAyjAQtBLyEQDKIBC0HEASEQDKEBC0EwIRAMoAELQTQhEAyfAQtBDCEQDJ4BC0ExIRAMnQELQTIhEAycAQtBMyEQDJsBC0E5IRAMmgELQTUhEAyZAQtBxQEhEAyYAQtBCyEQDJcBC0E6IRAMlgELQTYhEAyVAQtBCiEQDJQBC0E3IRAMkwELQTghEAySAQtBPCEQDJEBC0E7IRAMkAELQT0hEAyPAQtBCSEQDI4BC0EoIRAMjQELQT4hEAyMAQtBPyEQDIsBC0HAACEQDIoBC0HBACEQDIkBC0HCACEQDIgBC0HDACEQDIcBC0HEACEQDIYBC0HFACEQDIUBC0HGACEQDIQBC0EqIRAMgwELQccAIRAMggELQcgAIRAMgQELQckAIRAMgAELQcoAIRAMfwtBywAhEAx+C0HNACEQDH0LQcwAIRAMfAtBzgAhEAx7C0HPACEQDHoLQdAAIRAMeQtB0QAhEAx4C0HSACEQDHcLQdMAIRAMdgtB1AAhEAx1C0HWACEQDHQLQdUAIRAMcwtBBiEQDHILQdcAIRAMcQtBBSEQDHALQdgAIRAMbwtBBCEQDG4LQdkAIRAMbQtB2gAhEAxsC0HbACEQDGsLQdwAIRAMagtBAyEQDGkLQd0AIRAMaAtB3gAhEAxnC0HfACEQDGYLQeEAIRAMZQtB4AAhEAxkC0HiACEQDGMLQeMAIRAMYgtBAiEQDGELQeQAIRAMYAtB5QAhEAxfC0HmACEQDF4LQecAIRAMXQtB6AAhEAxcC0HpACEQDFsLQeoAIRAMWgtB6wAhEAxZC0HsACEQDFgLQe0AIRAMVwtB7gAhEAxWC0HvACEQDFULQfAAIRAMVAtB8QAhEAxTC0HyACEQDFILQfMAIRAMUQtB9AAhEAxQC0H1ACEQDE8LQfYAIRAMTgtB9wAhEAxNC0H4ACEQDEwLQfkAIRAMSwtB+gAhEAxKC0H7ACEQDEkLQfwAIRAMSAtB/QAhEAxHC0H+ACEQDEYLQf8AIRAMRQtBgAEhEAxEC0GBASEQDEMLQYIBIRAMQgtBgwEhEAxBC0GEASEQDEALQYUBIRAMPwtBhgEhEAw+C0GHASEQDD0LQYgBIRAMPAtBiQEhEAw7C0GKASEQDDoLQYsBIRAMOQtBjAEhEAw4C0GNASEQDDcLQY4BIRAMNgtBjwEhEAw1C0GQASEQDDQLQZEBIRAMMwtBkgEhEAwyC0GTASEQDDELQZQBIRAMMAtBlQEhEAwvC0GWASEQDC4LQZcBIRAMLQtBmAEhEAwsC0GZASEQDCsLQZoBIRAMKgtBmwEhEAwpC0GcASEQDCgLQZ0BIRAMJwtBngEhEAwmC0GfASEQDCULQaABIRAMJAtBoQEhEAwjC0GiASEQDCILQaMBIRAMIQtBpAEhEAwgC0GlASEQDB8LQaYBIRAMHgtBpwEhEAwdC0GoASEQDBwLQakBIRAMGwtBqgEhEAwaC0GrASEQDBkLQawBIRAMGAtBrQEhEAwXC0GuASEQDBYLQQEhEAwVC0GvASEQDBQLQbABIRAMEwtBsQEhEAwSC0GzASEQDBELQbIBIRAMEAtBtAEhEAwPC0G1ASEQDA4LQbYBIRAMDQtBtwEhEAwMC0G4ASEQDAsLQbkBIRAMCgtBugEhEAwJC0G7ASEQDAgLQcYBIRAMBwtBvAEhEAwGC0G9ASEQDAULQb4BIRAMBAtBvwEhEAwDC0HAASEQDAILQcIBIRAMAQtBwQEhEAsDQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIBAOxwEAAQIDBAUGBwgJCgsMDQ4PEBESExQVFhcYGRobHB4fICEjJSg/QEFERUZHSElKS0xNT1BRUlPeA1dZW1xdYGJlZmdoaWprbG1vcHFyc3R1dnd4eXp7fH1+gAGCAYUBhgGHAYkBiwGMAY0BjgGPAZABkQGUAZUBlgGXAZgBmQGaAZsBnAGdAZ4BnwGgAaEBogGjAaQBpQGmAacBqAGpAaoBqwGsAa0BrgGvAbABsQGyAbMBtAG1AbYBtwG4AbkBugG7AbwBvQG+Ab8BwAHBAcIBwwHEAcUBxgHHAcgByQHKAcsBzAHNAc4BzwHQAdEB0gHTAdQB1QHWAdcB2AHZAdoB2wHcAd0B3gHgAeEB4gHjAeQB5QHmAecB6AHpAeoB6wHsAe0B7gHvAfAB8QHyAfMBmQKkArAC/gL+AgsgASIEIAJHDfMBQd0BIRAM/wMLIAEiECACRw3dAUHDASEQDP4DCyABIgEgAkcNkAFB9wAhEAz9AwsgASIBIAJHDYYBQe8AIRAM/AMLIAEiASACRw1/QeoAIRAM+wMLIAEiASACRw17QegAIRAM+gMLIAEiASACRw14QeYAIRAM+QMLIAEiASACRw0aQRghEAz4AwsgASIBIAJHDRRBEiEQDPcDCyABIgEgAkcNWUHFACEQDPYDCyABIgEgAkcNSkE/IRAM9QMLIAEiASACRw1IQTwhEAz0AwsgASIBIAJHDUFBMSEQDPMDCyAALQAuQQFGDesDDIcCCyAAIAEiASACEMCAgIAAQQFHDeYBIABCADcDIAznAQsgACABIgEgAhC0gICAACIQDecBIAEhAQz1AgsCQCABIgEgAkcNAEEGIRAM8AMLIAAgAUEBaiIBIAIQu4CAgAAiEA3oASABIQEMMQsgAEIANwMgQRIhEAzVAwsgASIQIAJHDStBHSEQDO0DCwJAIAEiASACRg0AIAFBAWohAUEQIRAM1AMLQQchEAzsAwsgAEIAIAApAyAiESACIAEiEGutIhJ9IhMgEyARVhs3AyAgESASViIURQ3lAUEIIRAM6wMLAkAgASIBIAJGDQAgAEGJgICAADYCCCAAIAE2AgQgASEBQRQhEAzSAwtBCSEQDOoDCyABIQEgACkDIFAN5AEgASEBDPICCwJAIAEiASACRw0AQQshEAzpAwsgACABQQFqIgEgAhC2gICAACIQDeUBIAEhAQzyAgsgACABIgEgAhC4gICAACIQDeUBIAEhAQzyAgsgACABIgEgAhC4gICAACIQDeYBIAEhAQwNCyAAIAEiASACELqAgIAAIhAN5wEgASEBDPACCwJAIAEiASACRw0AQQ8hEAzlAwsgAS0AACIQQTtGDQggEEENRw3oASABQQFqIQEM7wILIAAgASIBIAIQuoCAgAAiEA3oASABIQEM8gILA0ACQCABLQAAQfC1gIAAai0AACIQQQFGDQAgEEECRw3rASAAKAIEIRAgAEEANgIEIAAgECABQQFqIgEQuYCAgAAiEA3qASABIQEM9AILIAFBAWoiASACRw0AC0ESIRAM4gMLIAAgASIBIAIQuoCAgAAiEA3pASABIQEMCgsgASIBIAJHDQZBGyEQDOADCwJAIAEiASACRw0AQRYhEAzgAwsgAEGKgICAADYCCCAAIAE2AgQgACABIAIQuICAgAAiEA3qASABIQFBICEQDMYDCwJAIAEiASACRg0AA0ACQCABLQAAQfC3gIAAai0AACIQQQJGDQACQCAQQX9qDgTlAewBAOsB7AELIAFBAWohAUEIIRAMyAMLIAFBAWoiASACRw0AC0EVIRAM3wMLQRUhEAzeAwsDQAJAIAEtAABB8LmAgABqLQAAIhBBAkYNACAQQX9qDgTeAewB4AHrAewBCyABQQFqIgEgAkcNAAtBGCEQDN0DCwJAIAEiASACRg0AIABBi4CAgAA2AgggACABNgIEIAEhAUEHIRAMxAMLQRkhEAzcAwsgAUEBaiEBDAILAkAgASIUIAJHDQBBGiEQDNsDCyAUIQECQCAULQAAQXNqDhTdAu4C7gLuAu4C7gLuAu4C7gLuAu4C7gLuAu4C7gLuAu4C7gLuAgDuAgtBACEQIABBADYCHCAAQa+LgIAANgIQIABBAjYCDCAAIBRBAWo2AhQM2gMLAkAgAS0AACIQQTtGDQAgEEENRw3oASABQQFqIQEM5QILIAFBAWohAQtBIiEQDL8DCwJAIAEiECACRw0AQRwhEAzYAwtCACERIBAhASAQLQAAQVBqDjfnAeYBAQIDBAUGBwgAAAAAAAAACQoLDA0OAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPEBESExQAC0EeIRAMvQMLQgIhEQzlAQtCAyERDOQBC0IEIREM4wELQgUhEQziAQtCBiERDOEBC0IHIREM4AELQgghEQzfAQtCCSERDN4BC0IKIREM3QELQgshEQzcAQtCDCERDNsBC0INIREM2gELQg4hEQzZAQtCDyERDNgBC0IKIREM1wELQgshEQzWAQtCDCERDNUBC0INIREM1AELQg4hEQzTAQtCDyERDNIBC0IAIRECQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAIBAtAABBUGoON+UB5AEAAQIDBAUGB+YB5gHmAeYB5gHmAeYBCAkKCwwN5gHmAeYB5gHmAeYB5gHmAeYB5gHmAeYB5gHmAeYB5gHmAeYB5gHmAeYB5gHmAeYB5gHmAQ4PEBESE+YBC0ICIREM5AELQgMhEQzjAQtCBCERDOIBC0IFIREM4QELQgYhEQzgAQtCByERDN8BC0IIIREM3gELQgkhEQzdAQtCCiERDNwBC0ILIREM2wELQgwhEQzaAQtCDSERDNkBC0IOIREM2AELQg8hEQzXAQtCCiERDNYBC0ILIREM1QELQgwhEQzUAQtCDSERDNMBC0IOIREM0gELQg8hEQzRAQsgAEIAIAApAyAiESACIAEiEGutIhJ9IhMgEyARVhs3AyAgESASViIURQ3SAUEfIRAMwAMLAkAgASIBIAJGDQAgAEGJgICAADYCCCAAIAE2AgQgASEBQSQhEAynAwtBICEQDL8DCyAAIAEiECACEL6AgIAAQX9qDgW2AQDFAgHRAdIBC0ERIRAMpAMLIABBAToALyAQIQEMuwMLIAEiASACRw3SAUEkIRAMuwMLIAEiDSACRw0eQcYAIRAMugMLIAAgASIBIAIQsoCAgAAiEA3UASABIQEMtQELIAEiECACRw0mQdAAIRAMuAMLAkAgASIBIAJHDQBBKCEQDLgDCyAAQQA2AgQgAEGMgICAADYCCCAAIAEgARCxgICAACIQDdMBIAEhAQzYAQsCQCABIhAgAkcNAEEpIRAMtwMLIBAtAAAiAUEgRg0UIAFBCUcN0wEgEEEBaiEBDBULAkAgASIBIAJGDQAgAUEBaiEBDBcLQSohEAy1AwsCQCABIhAgAkcNAEErIRAMtQMLAkAgEC0AACIBQQlGDQAgAUEgRw3VAQsgAC0ALEEIRg3TASAQIQEMkQMLAkAgASIBIAJHDQBBLCEQDLQDCyABLQAAQQpHDdUBIAFBAWohAQzJAgsgASIOIAJHDdUBQS8hEAyyAwsDQAJAIAEtAAAiEEEgRg0AAkAgEEF2ag4EANwB3AEA2gELIAEhAQzgAQsgAUEBaiIBIAJHDQALQTEhEAyxAwtBMiEQIAEiFCACRg2wAyACIBRrIAAoAgAiAWohFSAUIAFrQQNqIRYCQANAIBQtAAAiF0EgciAXIBdBv39qQf8BcUEaSRtB/wFxIAFB8LuAgABqLQAARw0BAkAgAUEDRw0AQQYhAQyWAwsgAUEBaiEBIBRBAWoiFCACRw0ACyAAIBU2AgAMsQMLIABBADYCACAUIQEM2QELQTMhECABIhQgAkYNrwMgAiAUayAAKAIAIgFqIRUgFCABa0EIaiEWAkADQCAULQAAIhdBIHIgFyAXQb9/akH/AXFBGkkbQf8BcSABQfS7gIAAai0AAEcNAQJAIAFBCEcNAEEFIQEMlQMLIAFBAWohASAUQQFqIhQgAkcNAAsgACAVNgIADLADCyAAQQA2AgAgFCEBDNgBC0E0IRAgASIUIAJGDa4DIAIgFGsgACgCACIBaiEVIBQgAWtBBWohFgJAA0AgFC0AACIXQSByIBcgF0G/f2pB/wFxQRpJG0H/AXEgAUHQwoCAAGotAABHDQECQCABQQVHDQBBByEBDJQDCyABQQFqIQEgFEEBaiIUIAJHDQALIAAgFTYCAAyvAwsgAEEANgIAIBQhAQzXAQsCQCABIgEgAkYNAANAAkAgAS0AAEGAvoCAAGotAAAiEEEBRg0AIBBBAkYNCiABIQEM3QELIAFBAWoiASACRw0AC0EwIRAMrgMLQTAhEAytAwsCQCABIgEgAkYNAANAAkAgAS0AACIQQSBGDQAgEEF2ag4E2QHaAdoB2QHaAQsgAUEBaiIBIAJHDQALQTghEAytAwtBOCEQDKwDCwNAAkAgAS0AACIQQSBGDQAgEEEJRw0DCyABQQFqIgEgAkcNAAtBPCEQDKsDCwNAAkAgAS0AACIQQSBGDQACQAJAIBBBdmoOBNoBAQHaAQALIBBBLEYN2wELIAEhAQwECyABQQFqIgEgAkcNAAtBPyEQDKoDCyABIQEM2wELQcAAIRAgASIUIAJGDagDIAIgFGsgACgCACIBaiEWIBQgAWtBBmohFwJAA0AgFC0AAEEgciABQYDAgIAAai0AAEcNASABQQZGDY4DIAFBAWohASAUQQFqIhQgAkcNAAsgACAWNgIADKkDCyAAQQA2AgAgFCEBC0E2IRAMjgMLAkAgASIPIAJHDQBBwQAhEAynAwsgAEGMgICAADYCCCAAIA82AgQgDyEBIAAtACxBf2oOBM0B1QHXAdkBhwMLIAFBAWohAQzMAQsCQCABIgEgAkYNAANAAkAgAS0AACIQQSByIBAgEEG/f2pB/wFxQRpJG0H/AXEiEEEJRg0AIBBBIEYNAAJAAkACQAJAIBBBnX9qDhMAAwMDAwMDAwEDAwMDAwMDAwMCAwsgAUEBaiEBQTEhEAyRAwsgAUEBaiEBQTIhEAyQAwsgAUEBaiEBQTMhEAyPAwsgASEBDNABCyABQQFqIgEgAkcNAAtBNSEQDKUDC0E1IRAMpAMLAkAgASIBIAJGDQADQAJAIAEtAABBgLyAgABqLQAAQQFGDQAgASEBDNMBCyABQQFqIgEgAkcNAAtBPSEQDKQDC0E9IRAMowMLIAAgASIBIAIQsICAgAAiEA3WASABIQEMAQsgEEEBaiEBC0E8IRAMhwMLAkAgASIBIAJHDQBBwgAhEAygAwsCQANAAkAgAS0AAEF3ag4YAAL+Av4ChAP+Av4C/gL+Av4C/gL+Av4C/gL+Av4C/gL+Av4C/gL+Av4C/gIA/gILIAFBAWoiASACRw0AC0HCACEQDKADCyABQQFqIQEgAC0ALUEBcUUNvQEgASEBC0EsIRAMhQMLIAEiASACRw3TAUHEACEQDJ0DCwNAAkAgAS0AAEGQwICAAGotAABBAUYNACABIQEMtwILIAFBAWoiASACRw0AC0HFACEQDJwDCyANLQAAIhBBIEYNswEgEEE6Rw2BAyAAKAIEIQEgAEEANgIEIAAgASANEK+AgIAAIgEN0AEgDUEBaiEBDLMCC0HHACEQIAEiDSACRg2aAyACIA1rIAAoAgAiAWohFiANIAFrQQVqIRcDQCANLQAAIhRBIHIgFCAUQb9/akH/AXFBGkkbQf8BcSABQZDCgIAAai0AAEcNgAMgAUEFRg30AiABQQFqIQEgDUEBaiINIAJHDQALIAAgFjYCAAyaAwtByAAhECABIg0gAkYNmQMgAiANayAAKAIAIgFqIRYgDSABa0EJaiEXA0AgDS0AACIUQSByIBQgFEG/f2pB/wFxQRpJG0H/AXEgAUGWwoCAAGotAABHDf8CAkAgAUEJRw0AQQIhAQz1AgsgAUEBaiEBIA1BAWoiDSACRw0ACyAAIBY2AgAMmQMLAkAgASINIAJHDQBByQAhEAyZAwsCQAJAIA0tAAAiAUEgciABIAFBv39qQf8BcUEaSRtB/wFxQZJ/ag4HAIADgAOAA4ADgAMBgAMLIA1BAWohAUE+IRAMgAMLIA1BAWohAUE/IRAM/wILQcoAIRAgASINIAJGDZcDIAIgDWsgACgCACIBaiEWIA0gAWtBAWohFwNAIA0tAAAiFEEgciAUIBRBv39qQf8BcUEaSRtB/wFxIAFBoMKAgABqLQAARw39AiABQQFGDfACIAFBAWohASANQQFqIg0gAkcNAAsgACAWNgIADJcDC0HLACEQIAEiDSACRg2WAyACIA1rIAAoAgAiAWohFiANIAFrQQ5qIRcDQCANLQAAIhRBIHIgFCAUQb9/akH/AXFBGkkbQf8BcSABQaLCgIAAai0AAEcN/AIgAUEORg3wAiABQQFqIQEgDUEBaiINIAJHDQALIAAgFjYCAAyWAwtBzAAhECABIg0gAkYNlQMgAiANayAAKAIAIgFqIRYgDSABa0EPaiEXA0AgDS0AACIUQSByIBQgFEG/f2pB/wFxQRpJG0H/AXEgAUHAwoCAAGotAABHDfsCAkAgAUEPRw0AQQMhAQzxAgsgAUEBaiEBIA1BAWoiDSACRw0ACyAAIBY2AgAMlQMLQc0AIRAgASINIAJGDZQDIAIgDWsgACgCACIBaiEWIA0gAWtBBWohFwNAIA0tAAAiFEEgciAUIBRBv39qQf8BcUEaSRtB/wFxIAFB0MKAgABqLQAARw36AgJAIAFBBUcNAEEEIQEM8AILIAFBAWohASANQQFqIg0gAkcNAAsgACAWNgIADJQDCwJAIAEiDSACRw0AQc4AIRAMlAMLAkACQAJAAkAgDS0AACIBQSByIAEgAUG/f2pB/wFxQRpJG0H/AXFBnX9qDhMA/QL9Av0C/QL9Av0C/QL9Av0C/QL9Av0CAf0C/QL9AgID/QILIA1BAWohAUHBACEQDP0CCyANQQFqIQFBwgAhEAz8AgsgDUEBaiEBQcMAIRAM+wILIA1BAWohAUHEACEQDPoCCwJAIAEiASACRg0AIABBjYCAgAA2AgggACABNgIEIAEhAUHFACEQDPoCC0HPACEQDJIDCyAQIQECQAJAIBAtAABBdmoOBAGoAqgCAKgCCyAQQQFqIQELQSchEAz4AgsCQCABIgEgAkcNAEHRACEQDJEDCwJAIAEtAABBIEYNACABIQEMjQELIAFBAWohASAALQAtQQFxRQ3HASABIQEMjAELIAEiFyACRw3IAUHSACEQDI8DC0HTACEQIAEiFCACRg2OAyACIBRrIAAoAgAiAWohFiAUIAFrQQFqIRcDQCAULQAAIAFB1sKAgABqLQAARw3MASABQQFGDccBIAFBAWohASAUQQFqIhQgAkcNAAsgACAWNgIADI4DCwJAIAEiASACRw0AQdUAIRAMjgMLIAEtAABBCkcNzAEgAUEBaiEBDMcBCwJAIAEiASACRw0AQdYAIRAMjQMLAkACQCABLQAAQXZqDgQAzQHNAQHNAQsgAUEBaiEBDMcBCyABQQFqIQFBygAhEAzzAgsgACABIgEgAhCugICAACIQDcsBIAEhAUHNACEQDPICCyAALQApQSJGDYUDDKYCCwJAIAEiASACRw0AQdsAIRAMigMLQQAhFEEBIRdBASEWQQAhEAJAAkACQAJAAkACQAJAAkACQCABLQAAQVBqDgrUAdMBAAECAwQFBgjVAQtBAiEQDAYLQQMhEAwFC0EEIRAMBAtBBSEQDAMLQQYhEAwCC0EHIRAMAQtBCCEQC0EAIRdBACEWQQAhFAzMAQtBCSEQQQEhFEEAIRdBACEWDMsBCwJAIAEiASACRw0AQd0AIRAMiQMLIAEtAABBLkcNzAEgAUEBaiEBDKYCCyABIgEgAkcNzAFB3wAhEAyHAwsCQCABIgEgAkYNACAAQY6AgIAANgIIIAAgATYCBCABIQFB0AAhEAzuAgtB4AAhEAyGAwtB4QAhECABIgEgAkYNhQMgAiABayAAKAIAIhRqIRYgASAUa0EDaiEXA0AgAS0AACAUQeLCgIAAai0AAEcNzQEgFEEDRg3MASAUQQFqIRQgAUEBaiIBIAJHDQALIAAgFjYCAAyFAwtB4gAhECABIgEgAkYNhAMgAiABayAAKAIAIhRqIRYgASAUa0ECaiEXA0AgAS0AACAUQebCgIAAai0AAEcNzAEgFEECRg3OASAUQQFqIRQgAUEBaiIBIAJHDQALIAAgFjYCAAyEAwtB4wAhECABIgEgAkYNgwMgAiABayAAKAIAIhRqIRYgASAUa0EDaiEXA0AgAS0AACAUQenCgIAAai0AAEcNywEgFEEDRg3OASAUQQFqIRQgAUEBaiIBIAJHDQALIAAgFjYCAAyDAwsCQCABIgEgAkcNAEHlACEQDIMDCyAAIAFBAWoiASACEKiAgIAAIhANzQEgASEBQdYAIRAM6QILAkAgASIBIAJGDQADQAJAIAEtAAAiEEEgRg0AAkACQAJAIBBBuH9qDgsAAc8BzwHPAc8BzwHPAc8BzwECzwELIAFBAWohAUHSACEQDO0CCyABQQFqIQFB0wAhEAzsAgsgAUEBaiEBQdQAIRAM6wILIAFBAWoiASACRw0AC0HkACEQDIIDC0HkACEQDIEDCwNAAkAgAS0AAEHwwoCAAGotAAAiEEEBRg0AIBBBfmoOA88B0AHRAdIBCyABQQFqIgEgAkcNAAtB5gAhEAyAAwsCQCABIgEgAkYNACABQQFqIQEMAwtB5wAhEAz/AgsDQAJAIAEtAABB8MSAgABqLQAAIhBBAUYNAAJAIBBBfmoOBNIB0wHUAQDVAQsgASEBQdcAIRAM5wILIAFBAWoiASACRw0AC0HoACEQDP4CCwJAIAEiASACRw0AQekAIRAM/gILAkAgAS0AACIQQXZqDhq6AdUB1QG8AdUB1QHVAdUB1QHVAdUB1QHVAdUB1QHVAdUB1QHVAdUB1QHVAcoB1QHVAQDTAQsgAUEBaiEBC0EGIRAM4wILA0ACQCABLQAAQfDGgIAAai0AAEEBRg0AIAEhAQyeAgsgAUEBaiIBIAJHDQALQeoAIRAM+wILAkAgASIBIAJGDQAgAUEBaiEBDAMLQesAIRAM+gILAkAgASIBIAJHDQBB7AAhEAz6AgsgAUEBaiEBDAELAkAgASIBIAJHDQBB7QAhEAz5AgsgAUEBaiEBC0EEIRAM3gILAkAgASIUIAJHDQBB7gAhEAz3AgsgFCEBAkACQAJAIBQtAABB8MiAgABqLQAAQX9qDgfUAdUB1gEAnAIBAtcBCyAUQQFqIQEMCgsgFEEBaiEBDM0BC0EAIRAgAEEANgIcIABBm5KAgAA2AhAgAEEHNgIMIAAgFEEBajYCFAz2AgsCQANAAkAgAS0AAEHwyICAAGotAAAiEEEERg0AAkACQCAQQX9qDgfSAdMB1AHZAQAEAdkBCyABIQFB2gAhEAzgAgsgAUEBaiEBQdwAIRAM3wILIAFBAWoiASACRw0AC0HvACEQDPYCCyABQQFqIQEMywELAkAgASIUIAJHDQBB8AAhEAz1AgsgFC0AAEEvRw3UASAUQQFqIQEMBgsCQCABIhQgAkcNAEHxACEQDPQCCwJAIBQtAAAiAUEvRw0AIBRBAWohAUHdACEQDNsCCyABQXZqIgRBFksN0wFBASAEdEGJgIACcUUN0wEMygILAkAgASIBIAJGDQAgAUEBaiEBQd4AIRAM2gILQfIAIRAM8gILAkAgASIUIAJHDQBB9AAhEAzyAgsgFCEBAkAgFC0AAEHwzICAAGotAABBf2oOA8kClAIA1AELQeEAIRAM2AILAkAgASIUIAJGDQADQAJAIBQtAABB8MqAgABqLQAAIgFBA0YNAAJAIAFBf2oOAssCANUBCyAUIQFB3wAhEAzaAgsgFEEBaiIUIAJHDQALQfMAIRAM8QILQfMAIRAM8AILAkAgASIBIAJGDQAgAEGPgICAADYCCCAAIAE2AgQgASEBQeAAIRAM1wILQfUAIRAM7wILAkAgASIBIAJHDQBB9gAhEAzvAgsgAEGPgICAADYCCCAAIAE2AgQgASEBC0EDIRAM1AILA0AgAS0AAEEgRw3DAiABQQFqIgEgAkcNAAtB9wAhEAzsAgsCQCABIgEgAkcNAEH4ACEQDOwCCyABLQAAQSBHDc4BIAFBAWohAQzvAQsgACABIgEgAhCsgICAACIQDc4BIAEhAQyOAgsCQCABIgQgAkcNAEH6ACEQDOoCCyAELQAAQcwARw3RASAEQQFqIQFBEyEQDM8BCwJAIAEiBCACRw0AQfsAIRAM6QILIAIgBGsgACgCACIBaiEUIAQgAWtBBWohEANAIAQtAAAgAUHwzoCAAGotAABHDdABIAFBBUYNzgEgAUEBaiEBIARBAWoiBCACRw0ACyAAIBQ2AgBB+wAhEAzoAgsCQCABIgQgAkcNAEH8ACEQDOgCCwJAAkAgBC0AAEG9f2oODADRAdEB0QHRAdEB0QHRAdEB0QHRAQHRAQsgBEEBaiEBQeYAIRAMzwILIARBAWohAUHnACEQDM4CCwJAIAEiBCACRw0AQf0AIRAM5wILIAIgBGsgACgCACIBaiEUIAQgAWtBAmohEAJAA0AgBC0AACABQe3PgIAAai0AAEcNzwEgAUECRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQf0AIRAM5wILIABBADYCACAQQQFqIQFBECEQDMwBCwJAIAEiBCACRw0AQf4AIRAM5gILIAIgBGsgACgCACIBaiEUIAQgAWtBBWohEAJAA0AgBC0AACABQfbOgIAAai0AAEcNzgEgAUEFRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQf4AIRAM5gILIABBADYCACAQQQFqIQFBFiEQDMsBCwJAIAEiBCACRw0AQf8AIRAM5QILIAIgBGsgACgCACIBaiEUIAQgAWtBA2ohEAJAA0AgBC0AACABQfzOgIAAai0AAEcNzQEgAUEDRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQf8AIRAM5QILIABBADYCACAQQQFqIQFBBSEQDMoBCwJAIAEiBCACRw0AQYABIRAM5AILIAQtAABB2QBHDcsBIARBAWohAUEIIRAMyQELAkAgASIEIAJHDQBBgQEhEAzjAgsCQAJAIAQtAABBsn9qDgMAzAEBzAELIARBAWohAUHrACEQDMoCCyAEQQFqIQFB7AAhEAzJAgsCQCABIgQgAkcNAEGCASEQDOICCwJAAkAgBC0AAEG4f2oOCADLAcsBywHLAcsBywEBywELIARBAWohAUHqACEQDMkCCyAEQQFqIQFB7QAhEAzIAgsCQCABIgQgAkcNAEGDASEQDOECCyACIARrIAAoAgAiAWohECAEIAFrQQJqIRQCQANAIAQtAAAgAUGAz4CAAGotAABHDckBIAFBAkYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgEDYCAEGDASEQDOECC0EAIRAgAEEANgIAIBRBAWohAQzGAQsCQCABIgQgAkcNAEGEASEQDOACCyACIARrIAAoAgAiAWohFCAEIAFrQQRqIRACQANAIAQtAAAgAUGDz4CAAGotAABHDcgBIAFBBEYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEGEASEQDOACCyAAQQA2AgAgEEEBaiEBQSMhEAzFAQsCQCABIgQgAkcNAEGFASEQDN8CCwJAAkAgBC0AAEG0f2oOCADIAcgByAHIAcgByAEByAELIARBAWohAUHvACEQDMYCCyAEQQFqIQFB8AAhEAzFAgsCQCABIgQgAkcNAEGGASEQDN4CCyAELQAAQcUARw3FASAEQQFqIQEMgwILAkAgASIEIAJHDQBBhwEhEAzdAgsgAiAEayAAKAIAIgFqIRQgBCABa0EDaiEQAkADQCAELQAAIAFBiM+AgABqLQAARw3FASABQQNGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIBQ2AgBBhwEhEAzdAgsgAEEANgIAIBBBAWohAUEtIRAMwgELAkAgASIEIAJHDQBBiAEhEAzcAgsgAiAEayAAKAIAIgFqIRQgBCABa0EIaiEQAkADQCAELQAAIAFB0M+AgABqLQAARw3EASABQQhGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIBQ2AgBBiAEhEAzcAgsgAEEANgIAIBBBAWohAUEpIRAMwQELAkAgASIBIAJHDQBBiQEhEAzbAgtBASEQIAEtAABB3wBHDcABIAFBAWohAQyBAgsCQCABIgQgAkcNAEGKASEQDNoCCyACIARrIAAoAgAiAWohFCAEIAFrQQFqIRADQCAELQAAIAFBjM+AgABqLQAARw3BASABQQFGDa8CIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQYoBIRAM2QILAkAgASIEIAJHDQBBiwEhEAzZAgsgAiAEayAAKAIAIgFqIRQgBCABa0ECaiEQAkADQCAELQAAIAFBjs+AgABqLQAARw3BASABQQJGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIBQ2AgBBiwEhEAzZAgsgAEEANgIAIBBBAWohAUECIRAMvgELAkAgASIEIAJHDQBBjAEhEAzYAgsgAiAEayAAKAIAIgFqIRQgBCABa0EBaiEQAkADQCAELQAAIAFB8M+AgABqLQAARw3AASABQQFGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIBQ2AgBBjAEhEAzYAgsgAEEANgIAIBBBAWohAUEfIRAMvQELAkAgASIEIAJHDQBBjQEhEAzXAgsgAiAEayAAKAIAIgFqIRQgBCABa0EBaiEQAkADQCAELQAAIAFB8s+AgABqLQAARw2/ASABQQFGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIBQ2AgBBjQEhEAzXAgsgAEEANgIAIBBBAWohAUEJIRAMvAELAkAgASIEIAJHDQBBjgEhEAzWAgsCQAJAIAQtAABBt39qDgcAvwG/Ab8BvwG/AQG/AQsgBEEBaiEBQfgAIRAMvQILIARBAWohAUH5ACEQDLwCCwJAIAEiBCACRw0AQY8BIRAM1QILIAIgBGsgACgCACIBaiEUIAQgAWtBBWohEAJAA0AgBC0AACABQZHPgIAAai0AAEcNvQEgAUEFRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQY8BIRAM1QILIABBADYCACAQQQFqIQFBGCEQDLoBCwJAIAEiBCACRw0AQZABIRAM1AILIAIgBGsgACgCACIBaiEUIAQgAWtBAmohEAJAA0AgBC0AACABQZfPgIAAai0AAEcNvAEgAUECRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQZABIRAM1AILIABBADYCACAQQQFqIQFBFyEQDLkBCwJAIAEiBCACRw0AQZEBIRAM0wILIAIgBGsgACgCACIBaiEUIAQgAWtBBmohEAJAA0AgBC0AACABQZrPgIAAai0AAEcNuwEgAUEGRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQZEBIRAM0wILIABBADYCACAQQQFqIQFBFSEQDLgBCwJAIAEiBCACRw0AQZIBIRAM0gILIAIgBGsgACgCACIBaiEUIAQgAWtBBWohEAJAA0AgBC0AACABQaHPgIAAai0AAEcNugEgAUEFRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQZIBIRAM0gILIABBADYCACAQQQFqIQFBHiEQDLcBCwJAIAEiBCACRw0AQZMBIRAM0QILIAQtAABBzABHDbgBIARBAWohAUEKIRAMtgELAkAgBCACRw0AQZQBIRAM0AILAkACQCAELQAAQb9/ag4PALkBuQG5AbkBuQG5AbkBuQG5AbkBuQG5AbkBAbkBCyAEQQFqIQFB/gAhEAy3AgsgBEEBaiEBQf8AIRAMtgILAkAgBCACRw0AQZUBIRAMzwILAkACQCAELQAAQb9/ag4DALgBAbgBCyAEQQFqIQFB/QAhEAy2AgsgBEEBaiEEQYABIRAMtQILAkAgBCACRw0AQZYBIRAMzgILIAIgBGsgACgCACIBaiEUIAQgAWtBAWohEAJAA0AgBC0AACABQafPgIAAai0AAEcNtgEgAUEBRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQZYBIRAMzgILIABBADYCACAQQQFqIQFBCyEQDLMBCwJAIAQgAkcNAEGXASEQDM0CCwJAAkACQAJAIAQtAABBU2oOIwC4AbgBuAG4AbgBuAG4AbgBuAG4AbgBuAG4AbgBuAG4AbgBuAG4AbgBuAG4AbgBAbgBuAG4AbgBuAECuAG4AbgBA7gBCyAEQQFqIQFB+wAhEAy2AgsgBEEBaiEBQfwAIRAMtQILIARBAWohBEGBASEQDLQCCyAEQQFqIQRBggEhEAyzAgsCQCAEIAJHDQBBmAEhEAzMAgsgAiAEayAAKAIAIgFqIRQgBCABa0EEaiEQAkADQCAELQAAIAFBqc+AgABqLQAARw20ASABQQRGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIBQ2AgBBmAEhEAzMAgsgAEEANgIAIBBBAWohAUEZIRAMsQELAkAgBCACRw0AQZkBIRAMywILIAIgBGsgACgCACIBaiEUIAQgAWtBBWohEAJAA0AgBC0AACABQa7PgIAAai0AAEcNswEgAUEFRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQZkBIRAMywILIABBADYCACAQQQFqIQFBBiEQDLABCwJAIAQgAkcNAEGaASEQDMoCCyACIARrIAAoAgAiAWohFCAEIAFrQQFqIRACQANAIAQtAAAgAUG0z4CAAGotAABHDbIBIAFBAUYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEGaASEQDMoCCyAAQQA2AgAgEEEBaiEBQRwhEAyvAQsCQCAEIAJHDQBBmwEhEAzJAgsgAiAEayAAKAIAIgFqIRQgBCABa0EBaiEQAkADQCAELQAAIAFBts+AgABqLQAARw2xASABQQFGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIBQ2AgBBmwEhEAzJAgsgAEEANgIAIBBBAWohAUEnIRAMrgELAkAgBCACRw0AQZwBIRAMyAILAkACQCAELQAAQax/ag4CAAGxAQsgBEEBaiEEQYYBIRAMrwILIARBAWohBEGHASEQDK4CCwJAIAQgAkcNAEGdASEQDMcCCyACIARrIAAoAgAiAWohFCAEIAFrQQFqIRACQANAIAQtAAAgAUG4z4CAAGotAABHDa8BIAFBAUYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEGdASEQDMcCCyAAQQA2AgAgEEEBaiEBQSYhEAysAQsCQCAEIAJHDQBBngEhEAzGAgsgAiAEayAAKAIAIgFqIRQgBCABa0EBaiEQAkADQCAELQAAIAFBus+AgABqLQAARw2uASABQQFGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIBQ2AgBBngEhEAzGAgsgAEEANgIAIBBBAWohAUEDIRAMqwELAkAgBCACRw0AQZ8BIRAMxQILIAIgBGsgACgCACIBaiEUIAQgAWtBAmohEAJAA0AgBC0AACABQe3PgIAAai0AAEcNrQEgAUECRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQZ8BIRAMxQILIABBADYCACAQQQFqIQFBDCEQDKoBCwJAIAQgAkcNAEGgASEQDMQCCyACIARrIAAoAgAiAWohFCAEIAFrQQNqIRACQANAIAQtAAAgAUG8z4CAAGotAABHDawBIAFBA0YNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEGgASEQDMQCCyAAQQA2AgAgEEEBaiEBQQ0hEAypAQsCQCAEIAJHDQBBoQEhEAzDAgsCQAJAIAQtAABBun9qDgsArAGsAawBrAGsAawBrAGsAawBAawBCyAEQQFqIQRBiwEhEAyqAgsgBEEBaiEEQYwBIRAMqQILAkAgBCACRw0AQaIBIRAMwgILIAQtAABB0ABHDakBIARBAWohBAzpAQsCQCAEIAJHDQBBowEhEAzBAgsCQAJAIAQtAABBt39qDgcBqgGqAaoBqgGqAQCqAQsgBEEBaiEEQY4BIRAMqAILIARBAWohAUEiIRAMpgELAkAgBCACRw0AQaQBIRAMwAILIAIgBGsgACgCACIBaiEUIAQgAWtBAWohEAJAA0AgBC0AACABQcDPgIAAai0AAEcNqAEgAUEBRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQaQBIRAMwAILIABBADYCACAQQQFqIQFBHSEQDKUBCwJAIAQgAkcNAEGlASEQDL8CCwJAAkAgBC0AAEGuf2oOAwCoAQGoAQsgBEEBaiEEQZABIRAMpgILIARBAWohAUEEIRAMpAELAkAgBCACRw0AQaYBIRAMvgILAkACQAJAAkACQCAELQAAQb9/ag4VAKoBqgGqAaoBqgGqAaoBqgGqAaoBAaoBqgECqgGqAQOqAaoBBKoBCyAEQQFqIQRBiAEhEAyoAgsgBEEBaiEEQYkBIRAMpwILIARBAWohBEGKASEQDKYCCyAEQQFqIQRBjwEhEAylAgsgBEEBaiEEQZEBIRAMpAILAkAgBCACRw0AQacBIRAMvQILIAIgBGsgACgCACIBaiEUIAQgAWtBAmohEAJAA0AgBC0AACABQe3PgIAAai0AAEcNpQEgAUECRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQacBIRAMvQILIABBADYCACAQQQFqIQFBESEQDKIBCwJAIAQgAkcNAEGoASEQDLwCCyACIARrIAAoAgAiAWohFCAEIAFrQQJqIRACQANAIAQtAAAgAUHCz4CAAGotAABHDaQBIAFBAkYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEGoASEQDLwCCyAAQQA2AgAgEEEBaiEBQSwhEAyhAQsCQCAEIAJHDQBBqQEhEAy7AgsgAiAEayAAKAIAIgFqIRQgBCABa0EEaiEQAkADQCAELQAAIAFBxc+AgABqLQAARw2jASABQQRGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIBQ2AgBBqQEhEAy7AgsgAEEANgIAIBBBAWohAUErIRAMoAELAkAgBCACRw0AQaoBIRAMugILIAIgBGsgACgCACIBaiEUIAQgAWtBAmohEAJAA0AgBC0AACABQcrPgIAAai0AAEcNogEgAUECRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQaoBIRAMugILIABBADYCACAQQQFqIQFBFCEQDJ8BCwJAIAQgAkcNAEGrASEQDLkCCwJAAkACQAJAIAQtAABBvn9qDg8AAQKkAaQBpAGkAaQBpAGkAaQBpAGkAaQBA6QBCyAEQQFqIQRBkwEhEAyiAgsgBEEBaiEEQZQBIRAMoQILIARBAWohBEGVASEQDKACCyAEQQFqIQRBlgEhEAyfAgsCQCAEIAJHDQBBrAEhEAy4AgsgBC0AAEHFAEcNnwEgBEEBaiEEDOABCwJAIAQgAkcNAEGtASEQDLcCCyACIARrIAAoAgAiAWohFCAEIAFrQQJqIRACQANAIAQtAAAgAUHNz4CAAGotAABHDZ8BIAFBAkYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEGtASEQDLcCCyAAQQA2AgAgEEEBaiEBQQ4hEAycAQsCQCAEIAJHDQBBrgEhEAy2AgsgBC0AAEHQAEcNnQEgBEEBaiEBQSUhEAybAQsCQCAEIAJHDQBBrwEhEAy1AgsgAiAEayAAKAIAIgFqIRQgBCABa0EIaiEQAkADQCAELQAAIAFB0M+AgABqLQAARw2dASABQQhGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIBQ2AgBBrwEhEAy1AgsgAEEANgIAIBBBAWohAUEqIRAMmgELAkAgBCACRw0AQbABIRAMtAILAkACQCAELQAAQat/ag4LAJ0BnQGdAZ0BnQGdAZ0BnQGdAQGdAQsgBEEBaiEEQZoBIRAMmwILIARBAWohBEGbASEQDJoCCwJAIAQgAkcNAEGxASEQDLMCCwJAAkAgBC0AAEG/f2oOFACcAZwBnAGcAZwBnAGcAZwBnAGcAZwBnAGcAZwBnAGcAZwBnAEBnAELIARBAWohBEGZASEQDJoCCyAEQQFqIQRBnAEhEAyZAgsCQCAEIAJHDQBBsgEhEAyyAgsgAiAEayAAKAIAIgFqIRQgBCABa0EDaiEQAkADQCAELQAAIAFB2c+AgABqLQAARw2aASABQQNGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIBQ2AgBBsgEhEAyyAgsgAEEANgIAIBBBAWohAUEhIRAMlwELAkAgBCACRw0AQbMBIRAMsQILIAIgBGsgACgCACIBaiEUIAQgAWtBBmohEAJAA0AgBC0AACABQd3PgIAAai0AAEcNmQEgAUEGRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQbMBIRAMsQILIABBADYCACAQQQFqIQFBGiEQDJYBCwJAIAQgAkcNAEG0ASEQDLACCwJAAkACQCAELQAAQbt/ag4RAJoBmgGaAZoBmgGaAZoBmgGaAQGaAZoBmgGaAZoBApoBCyAEQQFqIQRBnQEhEAyYAgsgBEEBaiEEQZ4BIRAMlwILIARBAWohBEGfASEQDJYCCwJAIAQgAkcNAEG1ASEQDK8CCyACIARrIAAoAgAiAWohFCAEIAFrQQVqIRACQANAIAQtAAAgAUHkz4CAAGotAABHDZcBIAFBBUYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEG1ASEQDK8CCyAAQQA2AgAgEEEBaiEBQSghEAyUAQsCQCAEIAJHDQBBtgEhEAyuAgsgAiAEayAAKAIAIgFqIRQgBCABa0ECaiEQAkADQCAELQAAIAFB6s+AgABqLQAARw2WASABQQJGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIBQ2AgBBtgEhEAyuAgsgAEEANgIAIBBBAWohAUEHIRAMkwELAkAgBCACRw0AQbcBIRAMrQILAkACQCAELQAAQbt/ag4OAJYBlgGWAZYBlgGWAZYBlgGWAZYBlgGWAQGWAQsgBEEBaiEEQaEBIRAMlAILIARBAWohBEGiASEQDJMCCwJAIAQgAkcNAEG4ASEQDKwCCyACIARrIAAoAgAiAWohFCAEIAFrQQJqIRACQANAIAQtAAAgAUHtz4CAAGotAABHDZQBIAFBAkYNASABQQFqIQEgBEEBaiIEIAJHDQALIAAgFDYCAEG4ASEQDKwCCyAAQQA2AgAgEEEBaiEBQRIhEAyRAQsCQCAEIAJHDQBBuQEhEAyrAgsgAiAEayAAKAIAIgFqIRQgBCABa0EBaiEQAkADQCAELQAAIAFB8M+AgABqLQAARw2TASABQQFGDQEgAUEBaiEBIARBAWoiBCACRw0ACyAAIBQ2AgBBuQEhEAyrAgsgAEEANgIAIBBBAWohAUEgIRAMkAELAkAgBCACRw0AQboBIRAMqgILIAIgBGsgACgCACIBaiEUIAQgAWtBAWohEAJAA0AgBC0AACABQfLPgIAAai0AAEcNkgEgAUEBRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQboBIRAMqgILIABBADYCACAQQQFqIQFBDyEQDI8BCwJAIAQgAkcNAEG7ASEQDKkCCwJAAkAgBC0AAEG3f2oOBwCSAZIBkgGSAZIBAZIBCyAEQQFqIQRBpQEhEAyQAgsgBEEBaiEEQaYBIRAMjwILAkAgBCACRw0AQbwBIRAMqAILIAIgBGsgACgCACIBaiEUIAQgAWtBB2ohEAJAA0AgBC0AACABQfTPgIAAai0AAEcNkAEgAUEHRg0BIAFBAWohASAEQQFqIgQgAkcNAAsgACAUNgIAQbwBIRAMqAILIABBADYCACAQQQFqIQFBGyEQDI0BCwJAIAQgAkcNAEG9ASEQDKcCCwJAAkACQCAELQAAQb5/ag4SAJEBkQGRAZEBkQGRAZEBkQGRAQGRAZEBkQGRAZEBkQECkQELIARBAWohBEGkASEQDI8CCyAEQQFqIQRBpwEhEAyOAgsgBEEBaiEEQagBIRAMjQILAkAgBCACRw0AQb4BIRAMpgILIAQtAABBzgBHDY0BIARBAWohBAzPAQsCQCAEIAJHDQBBvwEhEAylAgsCQAJAAkACQAJAAkACQAJAAkACQAJAAkACQAJAAkACQCAELQAAQb9/ag4VAAECA5wBBAUGnAGcAZwBBwgJCgucAQwNDg+cAQsgBEEBaiEBQegAIRAMmgILIARBAWohAUHpACEQDJkCCyAEQQFqIQFB7gAhEAyYAgsgBEEBaiEBQfIAIRAMlwILIARBAWohAUHzACEQDJYCCyAEQQFqIQFB9gAhEAyVAgsgBEEBaiEBQfcAIRAMlAILIARBAWohAUH6ACEQDJMCCyAEQQFqIQRBgwEhEAySAgsgBEEBaiEEQYQBIRAMkQILIARBAWohBEGFASEQDJACCyAEQQFqIQRBkgEhEAyPAgsgBEEBaiEEQZgBIRAMjgILIARBAWohBEGgASEQDI0CCyAEQQFqIQRBowEhEAyMAgsgBEEBaiEEQaoBIRAMiwILAkAgBCACRg0AIABBkICAgAA2AgggACAENgIEQasBIRAMiwILQcABIRAMowILIAAgBSACEKqAgIAAIgENiwEgBSEBDFwLAkAgBiACRg0AIAZBAWohBQyNAQtBwgEhEAyhAgsDQAJAIBAtAABBdmoOBIwBAACPAQALIBBBAWoiECACRw0AC0HDASEQDKACCwJAIAcgAkYNACAAQZGAgIAANgIIIAAgBzYCBCAHIQFBASEQDIcCC0HEASEQDJ8CCwJAIAcgAkcNAEHFASEQDJ8CCwJAAkAgBy0AAEF2ag4EAc4BzgEAzgELIAdBAWohBgyNAQsgB0EBaiEFDIkBCwJAIAcgAkcNAEHGASEQDJ4CCwJAAkAgBy0AAEF2ag4XAY8BjwEBjwGPAY8BjwGPAY8BjwGPAY8BjwGPAY8BjwGPAY8BjwGPAY8BAI8BCyAHQQFqIQcLQbABIRAMhAILAkAgCCACRw0AQcgBIRAMnQILIAgtAABBIEcNjQEgAEEAOwEyIAhBAWohAUGzASEQDIMCCyABIRcCQANAIBciByACRg0BIActAABBUGpB/wFxIhBBCk8NzAECQCAALwEyIhRBmTNLDQAgACAUQQpsIhQ7ATIgEEH//wNzIBRB/v8DcUkNACAHQQFqIRcgACAUIBBqIhA7ATIgEEH//wNxQegHSQ0BCwtBACEQIABBADYCHCAAQcGJgIAANgIQIABBDTYCDCAAIAdBAWo2AhQMnAILQccBIRAMmwILIAAgCCACEK6AgIAAIhBFDcoBIBBBFUcNjAEgAEHIATYCHCAAIAg2AhQgAEHJl4CAADYCECAAQRU2AgxBACEQDJoCCwJAIAkgAkcNAEHMASEQDJoCC0EAIRRBASEXQQEhFkEAIRACQAJAAkACQAJAAkACQAJAAkAgCS0AAEFQag4KlgGVAQABAgMEBQYIlwELQQIhEAwGC0EDIRAMBQtBBCEQDAQLQQUhEAwDC0EGIRAMAgtBByEQDAELQQghEAtBACEXQQAhFkEAIRQMjgELQQkhEEEBIRRBACEXQQAhFgyNAQsCQCAKIAJHDQBBzgEhEAyZAgsgCi0AAEEuRw2OASAKQQFqIQkMygELIAsgAkcNjgFB0AEhEAyXAgsCQCALIAJGDQAgAEGOgICAADYCCCAAIAs2AgRBtwEhEAz+AQtB0QEhEAyWAgsCQCAEIAJHDQBB0gEhEAyWAgsgAiAEayAAKAIAIhBqIRQgBCAQa0EEaiELA0AgBC0AACAQQfzPgIAAai0AAEcNjgEgEEEERg3pASAQQQFqIRAgBEEBaiIEIAJHDQALIAAgFDYCAEHSASEQDJUCCyAAIAwgAhCsgICAACIBDY0BIAwhAQy4AQsCQCAEIAJHDQBB1AEhEAyUAgsgAiAEayAAKAIAIhBqIRQgBCAQa0EBaiEMA0AgBC0AACAQQYHQgIAAai0AAEcNjwEgEEEBRg2OASAQQQFqIRAgBEEBaiIEIAJHDQALIAAgFDYCAEHUASEQDJMCCwJAIAQgAkcNAEHWASEQDJMCCyACIARrIAAoAgAiEGohFCAEIBBrQQJqIQsDQCAELQAAIBBBg9CAgABqLQAARw2OASAQQQJGDZABIBBBAWohECAEQQFqIgQgAkcNAAsgACAUNgIAQdYBIRAMkgILAkAgBCACRw0AQdcBIRAMkgILAkACQCAELQAAQbt/ag4QAI8BjwGPAY8BjwGPAY8BjwGPAY8BjwGPAY8BjwEBjwELIARBAWohBEG7ASEQDPkBCyAEQQFqIQRBvAEhEAz4AQsCQCAEIAJHDQBB2AEhEAyRAgsgBC0AAEHIAEcNjAEgBEEBaiEEDMQBCwJAIAQgAkYNACAAQZCAgIAANgIIIAAgBDYCBEG+ASEQDPcBC0HZASEQDI8CCwJAIAQgAkcNAEHaASEQDI8CCyAELQAAQcgARg3DASAAQQE6ACgMuQELIABBAjoALyAAIAQgAhCmgICAACIQDY0BQcIBIRAM9AELIAAtAChBf2oOArcBuQG4AQsDQAJAIAQtAABBdmoOBACOAY4BAI4BCyAEQQFqIgQgAkcNAAtB3QEhEAyLAgsgAEEAOgAvIAAtAC1BBHFFDYQCCyAAQQA6AC8gAEEBOgA0IAEhAQyMAQsgEEEVRg3aASAAQQA2AhwgACABNgIUIABBp46AgAA2AhAgAEESNgIMQQAhEAyIAgsCQCAAIBAgAhC0gICAACIEDQAgECEBDIECCwJAIARBFUcNACAAQQM2AhwgACAQNgIUIABBsJiAgAA2AhAgAEEVNgIMQQAhEAyIAgsgAEEANgIcIAAgEDYCFCAAQaeOgIAANgIQIABBEjYCDEEAIRAMhwILIBBBFUYN1gEgAEEANgIcIAAgATYCFCAAQdqNgIAANgIQIABBFDYCDEEAIRAMhgILIAAoAgQhFyAAQQA2AgQgECARp2oiFiEBIAAgFyAQIBYgFBsiEBC1gICAACIURQ2NASAAQQc2AhwgACAQNgIUIAAgFDYCDEEAIRAMhQILIAAgAC8BMEGAAXI7ATAgASEBC0EqIRAM6gELIBBBFUYN0QEgAEEANgIcIAAgATYCFCAAQYOMgIAANgIQIABBEzYCDEEAIRAMggILIBBBFUYNzwEgAEEANgIcIAAgATYCFCAAQZqPgIAANgIQIABBIjYCDEEAIRAMgQILIAAoAgQhECAAQQA2AgQCQCAAIBAgARC3gICAACIQDQAgAUEBaiEBDI0BCyAAQQw2AhwgACAQNgIMIAAgAUEBajYCFEEAIRAMgAILIBBBFUYNzAEgAEEANgIcIAAgATYCFCAAQZqPgIAANgIQIABBIjYCDEEAIRAM/wELIAAoAgQhECAAQQA2AgQCQCAAIBAgARC3gICAACIQDQAgAUEBaiEBDIwBCyAAQQ02AhwgACAQNgIMIAAgAUEBajYCFEEAIRAM/gELIBBBFUYNyQEgAEEANgIcIAAgATYCFCAAQcaMgIAANgIQIABBIzYCDEEAIRAM/QELIAAoAgQhECAAQQA2AgQCQCAAIBAgARC5gICAACIQDQAgAUEBaiEBDIsBCyAAQQ42AhwgACAQNgIMIAAgAUEBajYCFEEAIRAM/AELIABBADYCHCAAIAE2AhQgAEHAlYCAADYCECAAQQI2AgxBACEQDPsBCyAQQRVGDcUBIABBADYCHCAAIAE2AhQgAEHGjICAADYCECAAQSM2AgxBACEQDPoBCyAAQRA2AhwgACABNgIUIAAgEDYCDEEAIRAM+QELIAAoAgQhBCAAQQA2AgQCQCAAIAQgARC5gICAACIEDQAgAUEBaiEBDPEBCyAAQRE2AhwgACAENgIMIAAgAUEBajYCFEEAIRAM+AELIBBBFUYNwQEgAEEANgIcIAAgATYCFCAAQcaMgIAANgIQIABBIzYCDEEAIRAM9wELIAAoAgQhECAAQQA2AgQCQCAAIBAgARC5gICAACIQDQAgAUEBaiEBDIgBCyAAQRM2AhwgACAQNgIMIAAgAUEBajYCFEEAIRAM9gELIAAoAgQhBCAAQQA2AgQCQCAAIAQgARC5gICAACIEDQAgAUEBaiEBDO0BCyAAQRQ2AhwgACAENgIMIAAgAUEBajYCFEEAIRAM9QELIBBBFUYNvQEgAEEANgIcIAAgATYCFCAAQZqPgIAANgIQIABBIjYCDEEAIRAM9AELIAAoAgQhECAAQQA2AgQCQCAAIBAgARC3gICAACIQDQAgAUEBaiEBDIYBCyAAQRY2AhwgACAQNgIMIAAgAUEBajYCFEEAIRAM8wELIAAoAgQhBCAAQQA2AgQCQCAAIAQgARC3gICAACIEDQAgAUEBaiEBDOkBCyAAQRc2AhwgACAENgIMIAAgAUEBajYCFEEAIRAM8gELIABBADYCHCAAIAE2AhQgAEHNk4CAADYCECAAQQw2AgxBACEQDPEBC0IBIRELIBBBAWohAQJAIAApAyAiEkL//////////w9WDQAgACASQgSGIBGENwMgIAEhAQyEAQsgAEEANgIcIAAgATYCFCAAQa2JgIAANgIQIABBDDYCDEEAIRAM7wELIABBADYCHCAAIBA2AhQgAEHNk4CAADYCECAAQQw2AgxBACEQDO4BCyAAKAIEIRcgAEEANgIEIBAgEadqIhYhASAAIBcgECAWIBQbIhAQtYCAgAAiFEUNcyAAQQU2AhwgACAQNgIUIAAgFDYCDEEAIRAM7QELIABBADYCHCAAIBA2AhQgAEGqnICAADYCECAAQQ82AgxBACEQDOwBCyAAIBAgAhC0gICAACIBDQEgECEBC0EOIRAM0QELAkAgAUEVRw0AIABBAjYCHCAAIBA2AhQgAEGwmICAADYCECAAQRU2AgxBACEQDOoBCyAAQQA2AhwgACAQNgIUIABBp46AgAA2AhAgAEESNgIMQQAhEAzpAQsgAUEBaiEQAkAgAC8BMCIBQYABcUUNAAJAIAAgECACELuAgIAAIgENACAQIQEMcAsgAUEVRw26ASAAQQU2AhwgACAQNgIUIABB+ZeAgAA2AhAgAEEVNgIMQQAhEAzpAQsCQCABQaAEcUGgBEcNACAALQAtQQJxDQAgAEEANgIcIAAgEDYCFCAAQZaTgIAANgIQIABBBDYCDEEAIRAM6QELIAAgECACEL2AgIAAGiAQIQECQAJAAkACQAJAIAAgECACELOAgIAADhYCAQAEBAQEBAQEBAQEBAQEBAQEBAQDBAsgAEEBOgAuCyAAIAAvATBBwAByOwEwIBAhAQtBJiEQDNEBCyAAQSM2AhwgACAQNgIUIABBpZaAgAA2AhAgAEEVNgIMQQAhEAzpAQsgAEEANgIcIAAgEDYCFCAAQdWLgIAANgIQIABBETYCDEEAIRAM6AELIAAtAC1BAXFFDQFBwwEhEAzOAQsCQCANIAJGDQADQAJAIA0tAABBIEYNACANIQEMxAELIA1BAWoiDSACRw0AC0ElIRAM5wELQSUhEAzmAQsgACgCBCEEIABBADYCBCAAIAQgDRCvgICAACIERQ2tASAAQSY2AhwgACAENgIMIAAgDUEBajYCFEEAIRAM5QELIBBBFUYNqwEgAEEANgIcIAAgATYCFCAAQf2NgIAANgIQIABBHTYCDEEAIRAM5AELIABBJzYCHCAAIAE2AhQgACAQNgIMQQAhEAzjAQsgECEBQQEhFAJAAkACQAJAAkACQAJAIAAtACxBfmoOBwYFBQMBAgAFCyAAIAAvATBBCHI7ATAMAwtBAiEUDAELQQQhFAsgAEEBOgAsIAAgAC8BMCAUcjsBMAsgECEBC0ErIRAMygELIABBADYCHCAAIBA2AhQgAEGrkoCAADYCECAAQQs2AgxBACEQDOIBCyAAQQA2AhwgACABNgIUIABB4Y+AgAA2AhAgAEEKNgIMQQAhEAzhAQsgAEEAOgAsIBAhAQy9AQsgECEBQQEhFAJAAkACQAJAAkAgAC0ALEF7ag4EAwECAAULIAAgAC8BMEEIcjsBMAwDC0ECIRQMAQtBBCEUCyAAQQE6ACwgACAALwEwIBRyOwEwCyAQIQELQSkhEAzFAQsgAEEANgIcIAAgATYCFCAAQfCUgIAANgIQIABBAzYCDEEAIRAM3QELAkAgDi0AAEENRw0AIAAoAgQhASAAQQA2AgQCQCAAIAEgDhCxgICAACIBDQAgDkEBaiEBDHULIABBLDYCHCAAIAE2AgwgACAOQQFqNgIUQQAhEAzdAQsgAC0ALUEBcUUNAUHEASEQDMMBCwJAIA4gAkcNAEEtIRAM3AELAkACQANAAkAgDi0AAEF2ag4EAgAAAwALIA5BAWoiDiACRw0AC0EtIRAM3QELIAAoAgQhASAAQQA2AgQCQCAAIAEgDhCxgICAACIBDQAgDiEBDHQLIABBLDYCHCAAIA42AhQgACABNgIMQQAhEAzcAQsgACgCBCEBIABBADYCBAJAIAAgASAOELGAgIAAIgENACAOQQFqIQEMcwsgAEEsNgIcIAAgATYCDCAAIA5BAWo2AhRBACEQDNsBCyAAKAIEIQQgAEEANgIEIAAgBCAOELGAgIAAIgQNoAEgDiEBDM4BCyAQQSxHDQEgAUEBaiEQQQEhAQJAAkACQAJAAkAgAC0ALEF7ag4EAwECBAALIBAhAQwEC0ECIQEMAQtBBCEBCyAAQQE6ACwgACAALwEwIAFyOwEwIBAhAQwBCyAAIAAvATBBCHI7ATAgECEBC0E5IRAMvwELIABBADoALCABIQELQTQhEAy9AQsgACAALwEwQSByOwEwIAEhAQwCCyAAKAIEIQQgAEEANgIEAkAgACAEIAEQsYCAgAAiBA0AIAEhAQzHAQsgAEE3NgIcIAAgATYCFCAAIAQ2AgxBACEQDNQBCyAAQQg6ACwgASEBC0EwIRAMuQELAkAgAC0AKEEBRg0AIAEhAQwECyAALQAtQQhxRQ2TASABIQEMAwsgAC0AMEEgcQ2UAUHFASEQDLcBCwJAIA8gAkYNAAJAA0ACQCAPLQAAQVBqIgFB/wFxQQpJDQAgDyEBQTUhEAy6AQsgACkDICIRQpmz5syZs+bMGVYNASAAIBFCCn4iETcDICARIAGtQv8BgyISQn+FVg0BIAAgESASfDcDICAPQQFqIg8gAkcNAAtBOSEQDNEBCyAAKAIEIQIgAEEANgIEIAAgAiAPQQFqIgQQsYCAgAAiAg2VASAEIQEMwwELQTkhEAzPAQsCQCAALwEwIgFBCHFFDQAgAC0AKEEBRw0AIAAtAC1BCHFFDZABCyAAIAFB9/sDcUGABHI7ATAgDyEBC0E3IRAMtAELIAAgAC8BMEEQcjsBMAyrAQsgEEEVRg2LASAAQQA2AhwgACABNgIUIABB8I6AgAA2AhAgAEEcNgIMQQAhEAzLAQsgAEHDADYCHCAAIAE2AgwgACANQQFqNgIUQQAhEAzKAQsCQCABLQAAQTpHDQAgACgCBCEQIABBADYCBAJAIAAgECABEK+AgIAAIhANACABQQFqIQEMYwsgAEHDADYCHCAAIBA2AgwgACABQQFqNgIUQQAhEAzKAQsgAEEANgIcIAAgATYCFCAAQbGRgIAANgIQIABBCjYCDEEAIRAMyQELIABBADYCHCAAIAE2AhQgAEGgmYCAADYCECAAQR42AgxBACEQDMgBCyAAQQA2AgALIABBgBI7ASogACAXQQFqIgEgAhCogICAACIQDQEgASEBC0HHACEQDKwBCyAQQRVHDYMBIABB0QA2AhwgACABNgIUIABB45eAgAA2AhAgAEEVNgIMQQAhEAzEAQsgACgCBCEQIABBADYCBAJAIAAgECABEKeAgIAAIhANACABIQEMXgsgAEHSADYCHCAAIAE2AhQgACAQNgIMQQAhEAzDAQsgAEEANgIcIAAgFDYCFCAAQcGogIAANgIQIABBBzYCDCAAQQA2AgBBACEQDMIBCyAAKAIEIRAgAEEANgIEAkAgACAQIAEQp4CAgAAiEA0AIAEhAQxdCyAAQdMANgIcIAAgATYCFCAAIBA2AgxBACEQDMEBC0EAIRAgAEEANgIcIAAgATYCFCAAQYCRgIAANgIQIABBCTYCDAzAAQsgEEEVRg19IABBADYCHCAAIAE2AhQgAEGUjYCAADYCECAAQSE2AgxBACEQDL8BC0EBIRZBACEXQQAhFEEBIRALIAAgEDoAKyABQQFqIQECQAJAIAAtAC1BEHENAAJAAkACQCAALQAqDgMBAAIECyAWRQ0DDAILIBQNAQwCCyAXRQ0BCyAAKAIEIRAgAEEANgIEAkAgACAQIAEQrYCAgAAiEA0AIAEhAQxcCyAAQdgANgIcIAAgATYCFCAAIBA2AgxBACEQDL4BCyAAKAIEIQQgAEEANgIEAkAgACAEIAEQrYCAgAAiBA0AIAEhAQytAQsgAEHZADYCHCAAIAE2AhQgACAENgIMQQAhEAy9AQsgACgCBCEEIABBADYCBAJAIAAgBCABEK2AgIAAIgQNACABIQEMqwELIABB2gA2AhwgACABNgIUIAAgBDYCDEEAIRAMvAELIAAoAgQhBCAAQQA2AgQCQCAAIAQgARCtgICAACIEDQAgASEBDKkBCyAAQdwANgIcIAAgATYCFCAAIAQ2AgxBACEQDLsBCwJAIAEtAABBUGoiEEH/AXFBCk8NACAAIBA6ACogAUEBaiEBQc8AIRAMogELIAAoAgQhBCAAQQA2AgQCQCAAIAQgARCtgICAACIEDQAgASEBDKcBCyAAQd4ANgIcIAAgATYCFCAAIAQ2AgxBACEQDLoBCyAAQQA2AgAgF0EBaiEBAkAgAC0AKUEjTw0AIAEhAQxZCyAAQQA2AhwgACABNgIUIABB04mAgAA2AhAgAEEINgIMQQAhEAy5AQsgAEEANgIAC0EAIRAgAEEANgIcIAAgATYCFCAAQZCzgIAANgIQIABBCDYCDAy3AQsgAEEANgIAIBdBAWohAQJAIAAtAClBIUcNACABIQEMVgsgAEEANgIcIAAgATYCFCAAQZuKgIAANgIQIABBCDYCDEEAIRAMtgELIABBADYCACAXQQFqIQECQCAALQApIhBBXWpBC08NACABIQEMVQsCQCAQQQZLDQBBASAQdEHKAHFFDQAgASEBDFULQQAhECAAQQA2AhwgACABNgIUIABB94mAgAA2AhAgAEEINgIMDLUBCyAQQRVGDXEgAEEANgIcIAAgATYCFCAAQbmNgIAANgIQIABBGjYCDEEAIRAMtAELIAAoAgQhECAAQQA2AgQCQCAAIBAgARCngICAACIQDQAgASEBDFQLIABB5QA2AhwgACABNgIUIAAgEDYCDEEAIRAMswELIAAoAgQhECAAQQA2AgQCQCAAIBAgARCngICAACIQDQAgASEBDE0LIABB0gA2AhwgACABNgIUIAAgEDYCDEEAIRAMsgELIAAoAgQhECAAQQA2AgQCQCAAIBAgARCngICAACIQDQAgASEBDE0LIABB0wA2AhwgACABNgIUIAAgEDYCDEEAIRAMsQELIAAoAgQhECAAQQA2AgQCQCAAIBAgARCngICAACIQDQAgASEBDFELIABB5QA2AhwgACABNgIUIAAgEDYCDEEAIRAMsAELIABBADYCHCAAIAE2AhQgAEHGioCAADYCECAAQQc2AgxBACEQDK8BCyAAKAIEIRAgAEEANgIEAkAgACAQIAEQp4CAgAAiEA0AIAEhAQxJCyAAQdIANgIcIAAgATYCFCAAIBA2AgxBACEQDK4BCyAAKAIEIRAgAEEANgIEAkAgACAQIAEQp4CAgAAiEA0AIAEhAQxJCyAAQdMANgIcIAAgATYCFCAAIBA2AgxBACEQDK0BCyAAKAIEIRAgAEEANgIEAkAgACAQIAEQp4CAgAAiEA0AIAEhAQxNCyAAQeUANgIcIAAgATYCFCAAIBA2AgxBACEQDKwBCyAAQQA2AhwgACABNgIUIABB3IiAgAA2AhAgAEEHNgIMQQAhEAyrAQsgEEE/Rw0BIAFBAWohAQtBBSEQDJABC0EAIRAgAEEANgIcIAAgATYCFCAAQf2SgIAANgIQIABBBzYCDAyoAQsgACgCBCEQIABBADYCBAJAIAAgECABEKeAgIAAIhANACABIQEMQgsgAEHSADYCHCAAIAE2AhQgACAQNgIMQQAhEAynAQsgACgCBCEQIABBADYCBAJAIAAgECABEKeAgIAAIhANACABIQEMQgsgAEHTADYCHCAAIAE2AhQgACAQNgIMQQAhEAymAQsgACgCBCEQIABBADYCBAJAIAAgECABEKeAgIAAIhANACABIQEMRgsgAEHlADYCHCAAIAE2AhQgACAQNgIMQQAhEAylAQsgACgCBCEBIABBADYCBAJAIAAgASAUEKeAgIAAIgENACAUIQEMPwsgAEHSADYCHCAAIBQ2AhQgACABNgIMQQAhEAykAQsgACgCBCEBIABBADYCBAJAIAAgASAUEKeAgIAAIgENACAUIQEMPwsgAEHTADYCHCAAIBQ2AhQgACABNgIMQQAhEAyjAQsgACgCBCEBIABBADYCBAJAIAAgASAUEKeAgIAAIgENACAUIQEMQwsgAEHlADYCHCAAIBQ2AhQgACABNgIMQQAhEAyiAQsgAEEANgIcIAAgFDYCFCAAQcOPgIAANgIQIABBBzYCDEEAIRAMoQELIABBADYCHCAAIAE2AhQgAEHDj4CAADYCECAAQQc2AgxBACEQDKABC0EAIRAgAEEANgIcIAAgFDYCFCAAQYycgIAANgIQIABBBzYCDAyfAQsgAEEANgIcIAAgFDYCFCAAQYycgIAANgIQIABBBzYCDEEAIRAMngELIABBADYCHCAAIBQ2AhQgAEH+kYCAADYCECAAQQc2AgxBACEQDJ0BCyAAQQA2AhwgACABNgIUIABBjpuAgAA2AhAgAEEGNgIMQQAhEAycAQsgEEEVRg1XIABBADYCHCAAIAE2AhQgAEHMjoCAADYCECAAQSA2AgxBACEQDJsBCyAAQQA2AgAgEEEBaiEBQSQhEAsgACAQOgApIAAoAgQhECAAQQA2AgQgACAQIAEQq4CAgAAiEA1UIAEhAQw+CyAAQQA2AgALQQAhECAAQQA2AhwgACAENgIUIABB8ZuAgAA2AhAgAEEGNgIMDJcBCyABQRVGDVAgAEEANgIcIAAgBTYCFCAAQfCMgIAANgIQIABBGzYCDEEAIRAMlgELIAAoAgQhBSAAQQA2AgQgACAFIBAQqYCAgAAiBQ0BIBBBAWohBQtBrQEhEAx7CyAAQcEBNgIcIAAgBTYCDCAAIBBBAWo2AhRBACEQDJMBCyAAKAIEIQYgAEEANgIEIAAgBiAQEKmAgIAAIgYNASAQQQFqIQYLQa4BIRAMeAsgAEHCATYCHCAAIAY2AgwgACAQQQFqNgIUQQAhEAyQAQsgAEEANgIcIAAgBzYCFCAAQZeLgIAANgIQIABBDTYCDEEAIRAMjwELIABBADYCHCAAIAg2AhQgAEHjkICAADYCECAAQQk2AgxBACEQDI4BCyAAQQA2AhwgACAINgIUIABBlI2AgAA2AhAgAEEhNgIMQQAhEAyNAQtBASEWQQAhF0EAIRRBASEQCyAAIBA6ACsgCUEBaiEIAkACQCAALQAtQRBxDQACQAJAAkAgAC0AKg4DAQACBAsgFkUNAwwCCyAUDQEMAgsgF0UNAQsgACgCBCEQIABBADYCBCAAIBAgCBCtgICAACIQRQ09IABByQE2AhwgACAINgIUIAAgEDYCDEEAIRAMjAELIAAoAgQhBCAAQQA2AgQgACAEIAgQrYCAgAAiBEUNdiAAQcoBNgIcIAAgCDYCFCAAIAQ2AgxBACEQDIsBCyAAKAIEIQQgAEEANgIEIAAgBCAJEK2AgIAAIgRFDXQgAEHLATYCHCAAIAk2AhQgACAENgIMQQAhEAyKAQsgACgCBCEEIABBADYCBCAAIAQgChCtgICAACIERQ1yIABBzQE2AhwgACAKNgIUIAAgBDYCDEEAIRAMiQELAkAgCy0AAEFQaiIQQf8BcUEKTw0AIAAgEDoAKiALQQFqIQpBtgEhEAxwCyAAKAIEIQQgAEEANgIEIAAgBCALEK2AgIAAIgRFDXAgAEHPATYCHCAAIAs2AhQgACAENgIMQQAhEAyIAQsgAEEANgIcIAAgBDYCFCAAQZCzgIAANgIQIABBCDYCDCAAQQA2AgBBACEQDIcBCyABQRVGDT8gAEEANgIcIAAgDDYCFCAAQcyOgIAANgIQIABBIDYCDEEAIRAMhgELIABBgQQ7ASggACgCBCEQIABCADcDACAAIBAgDEEBaiIMEKuAgIAAIhBFDTggAEHTATYCHCAAIAw2AhQgACAQNgIMQQAhEAyFAQsgAEEANgIAC0EAIRAgAEEANgIcIAAgBDYCFCAAQdibgIAANgIQIABBCDYCDAyDAQsgACgCBCEQIABCADcDACAAIBAgC0EBaiILEKuAgIAAIhANAUHGASEQDGkLIABBAjoAKAxVCyAAQdUBNgIcIAAgCzYCFCAAIBA2AgxBACEQDIABCyAQQRVGDTcgAEEANgIcIAAgBDYCFCAAQaSMgIAANgIQIABBEDYCDEEAIRAMfwsgAC0ANEEBRw00IAAgBCACELyAgIAAIhBFDTQgEEEVRw01IABB3AE2AhwgACAENgIUIABB1ZaAgAA2AhAgAEEVNgIMQQAhEAx+C0EAIRAgAEEANgIcIABBr4uAgAA2AhAgAEECNgIMIAAgFEEBajYCFAx9C0EAIRAMYwtBAiEQDGILQQ0hEAxhC0EPIRAMYAtBJSEQDF8LQRMhEAxeC0EVIRAMXQtBFiEQDFwLQRchEAxbC0EYIRAMWgtBGSEQDFkLQRohEAxYC0EbIRAMVwtBHCEQDFYLQR0hEAxVC0EfIRAMVAtBISEQDFMLQSMhEAxSC0HGACEQDFELQS4hEAxQC0EvIRAMTwtBOyEQDE4LQT0hEAxNC0HIACEQDEwLQckAIRAMSwtBywAhEAxKC0HMACEQDEkLQc4AIRAMSAtB0QAhEAxHC0HVACEQDEYLQdgAIRAMRQtB2QAhEAxEC0HbACEQDEMLQeQAIRAMQgtB5QAhEAxBC0HxACEQDEALQfQAIRAMPwtBjQEhEAw+C0GXASEQDD0LQakBIRAMPAtBrAEhEAw7C0HAASEQDDoLQbkBIRAMOQtBrwEhEAw4C0GxASEQDDcLQbIBIRAMNgtBtAEhEAw1C0G1ASEQDDQLQboBIRAMMwtBvQEhEAwyC0G/ASEQDDELQcEBIRAMMAsgAEEANgIcIAAgBDYCFCAAQemLgIAANgIQIABBHzYCDEEAIRAMSAsgAEHbATYCHCAAIAQ2AhQgAEH6loCAADYCECAAQRU2AgxBACEQDEcLIABB+AA2AhwgACAMNgIUIABBypiAgAA2AhAgAEEVNgIMQQAhEAxGCyAAQdEANgIcIAAgBTYCFCAAQbCXgIAANgIQIABBFTYCDEEAIRAMRQsgAEH5ADYCHCAAIAE2AhQgACAQNgIMQQAhEAxECyAAQfgANgIcIAAgATYCFCAAQcqYgIAANgIQIABBFTYCDEEAIRAMQwsgAEHkADYCHCAAIAE2AhQgAEHjl4CAADYCECAAQRU2AgxBACEQDEILIABB1wA2AhwgACABNgIUIABByZeAgAA2AhAgAEEVNgIMQQAhEAxBCyAAQQA2AhwgACABNgIUIABBuY2AgAA2AhAgAEEaNgIMQQAhEAxACyAAQcIANgIcIAAgATYCFCAAQeOYgIAANgIQIABBFTYCDEEAIRAMPwsgAEEANgIEIAAgDyAPELGAgIAAIgRFDQEgAEE6NgIcIAAgBDYCDCAAIA9BAWo2AhRBACEQDD4LIAAoAgQhBCAAQQA2AgQCQCAAIAQgARCxgICAACIERQ0AIABBOzYCHCAAIAQ2AgwgACABQQFqNgIUQQAhEAw+CyABQQFqIQEMLQsgD0EBaiEBDC0LIABBADYCHCAAIA82AhQgAEHkkoCAADYCECAAQQQ2AgxBACEQDDsLIABBNjYCHCAAIAQ2AhQgACACNgIMQQAhEAw6CyAAQS42AhwgACAONgIUIAAgBDYCDEEAIRAMOQsgAEHQADYCHCAAIAE2AhQgAEGRmICAADYCECAAQRU2AgxBACEQDDgLIA1BAWohAQwsCyAAQRU2AhwgACABNgIUIABBgpmAgAA2AhAgAEEVNgIMQQAhEAw2CyAAQRs2AhwgACABNgIUIABBkZeAgAA2AhAgAEEVNgIMQQAhEAw1CyAAQQ82AhwgACABNgIUIABBkZeAgAA2AhAgAEEVNgIMQQAhEAw0CyAAQQs2AhwgACABNgIUIABBkZeAgAA2AhAgAEEVNgIMQQAhEAwzCyAAQRo2AhwgACABNgIUIABBgpmAgAA2AhAgAEEVNgIMQQAhEAwyCyAAQQs2AhwgACABNgIUIABBgpmAgAA2AhAgAEEVNgIMQQAhEAwxCyAAQQo2AhwgACABNgIUIABB5JaAgAA2AhAgAEEVNgIMQQAhEAwwCyAAQR42AhwgACABNgIUIABB+ZeAgAA2AhAgAEEVNgIMQQAhEAwvCyAAQQA2AhwgACAQNgIUIABB2o2AgAA2AhAgAEEUNgIMQQAhEAwuCyAAQQQ2AhwgACABNgIUIABBsJiAgAA2AhAgAEEVNgIMQQAhEAwtCyAAQQA2AgAgC0EBaiELC0G4ASEQDBILIABBADYCACAQQQFqIQFB9QAhEAwRCyABIQECQCAALQApQQVHDQBB4wAhEAwRC0HiACEQDBALQQAhECAAQQA2AhwgAEHkkYCAADYCECAAQQc2AgwgACAUQQFqNgIUDCgLIABBADYCACAXQQFqIQFBwAAhEAwOC0EBIQELIAAgAToALCAAQQA2AgAgF0EBaiEBC0EoIRAMCwsgASEBC0E4IRAMCQsCQCABIg8gAkYNAANAAkAgDy0AAEGAvoCAAGotAAAiAUEBRg0AIAFBAkcNAyAPQQFqIQEMBAsgD0EBaiIPIAJHDQALQT4hEAwiC0E+IRAMIQsgAEEAOgAsIA8hAQwBC0ELIRAMBgtBOiEQDAULIAFBAWohAUEtIRAMBAsgACABOgAsIABBADYCACAWQQFqIQFBDCEQDAMLIABBADYCACAXQQFqIQFBCiEQDAILIABBADYCAAsgAEEAOgAsIA0hAUEJIRAMAAsLQQAhECAAQQA2AhwgACALNgIUIABBzZCAgAA2AhAgAEEJNgIMDBcLQQAhECAAQQA2AhwgACAKNgIUIABB6YqAgAA2AhAgAEEJNgIMDBYLQQAhECAAQQA2AhwgACAJNgIUIABBt5CAgAA2AhAgAEEJNgIMDBULQQAhECAAQQA2AhwgACAINgIUIABBnJGAgAA2AhAgAEEJNgIMDBQLQQAhECAAQQA2AhwgACABNgIUIABBzZCAgAA2AhAgAEEJNgIMDBMLQQAhECAAQQA2AhwgACABNgIUIABB6YqAgAA2AhAgAEEJNgIMDBILQQAhECAAQQA2AhwgACABNgIUIABBt5CAgAA2AhAgAEEJNgIMDBELQQAhECAAQQA2AhwgACABNgIUIABBnJGAgAA2AhAgAEEJNgIMDBALQQAhECAAQQA2AhwgACABNgIUIABBl5WAgAA2AhAgAEEPNgIMDA8LQQAhECAAQQA2AhwgACABNgIUIABBl5WAgAA2AhAgAEEPNgIMDA4LQQAhECAAQQA2AhwgACABNgIUIABBwJKAgAA2AhAgAEELNgIMDA0LQQAhECAAQQA2AhwgACABNgIUIABBlYmAgAA2AhAgAEELNgIMDAwLQQAhECAAQQA2AhwgACABNgIUIABB4Y+AgAA2AhAgAEEKNgIMDAsLQQAhECAAQQA2AhwgACABNgIUIABB+4+AgAA2AhAgAEEKNgIMDAoLQQAhECAAQQA2AhwgACABNgIUIABB8ZmAgAA2AhAgAEECNgIMDAkLQQAhECAAQQA2AhwgACABNgIUIABBxJSAgAA2AhAgAEECNgIMDAgLQQAhECAAQQA2AhwgACABNgIUIABB8pWAgAA2AhAgAEECNgIMDAcLIABBAjYCHCAAIAE2AhQgAEGcmoCAADYCECAAQRY2AgxBACEQDAYLQQEhEAwFC0HUACEQIAEiBCACRg0EIANBCGogACAEIAJB2MKAgABBChDFgICAACADKAIMIQQgAygCCA4DAQQCAAsQyoCAgAAACyAAQQA2AhwgAEG1moCAADYCECAAQRc2AgwgACAEQQFqNgIUQQAhEAwCCyAAQQA2AhwgACAENgIUIABBypqAgAA2AhAgAEEJNgIMQQAhEAwBCwJAIAEiBCACRw0AQSIhEAwBCyAAQYmAgIAANgIIIAAgBDYCBEEhIRALIANBEGokgICAgAAgEAuvAQECfyABKAIAIQYCQAJAIAIgA0YNACAEIAZqIQQgBiADaiACayEHIAIgBkF/cyAFaiIGaiEFA0ACQCACLQAAIAQtAABGDQBBAiEEDAMLAkAgBg0AQQAhBCAFIQIMAwsgBkF/aiEGIARBAWohBCACQQFqIgIgA0cNAAsgByEGIAMhAgsgAEEBNgIAIAEgBjYCACAAIAI2AgQPCyABQQA2AgAgACAENgIAIAAgAjYCBAsKACAAEMeAgIAAC/I2AQt/I4CAgIAAQRBrIgEkgICAgAACQEEAKAKg0ICAAA0AQQAQy4CAgABBgNSEgABrIgJB2QBJDQBBACEDAkBBACgC4NOAgAAiBA0AQQBCfzcC7NOAgABBAEKAgISAgIDAADcC5NOAgABBACABQQhqQXBxQdiq1aoFcyIENgLg04CAAEEAQQA2AvTTgIAAQQBBADYCxNOAgAALQQAgAjYCzNOAgABBAEGA1ISAADYCyNOAgABBAEGA1ISAADYCmNCAgABBACAENgKs0ICAAEEAQX82AqjQgIAAA0AgA0HE0ICAAGogA0G40ICAAGoiBDYCACAEIANBsNCAgABqIgU2AgAgA0G80ICAAGogBTYCACADQczQgIAAaiADQcDQgIAAaiIFNgIAIAUgBDYCACADQdTQgIAAaiADQcjQgIAAaiIENgIAIAQgBTYCACADQdDQgIAAaiAENgIAIANBIGoiA0GAAkcNAAtBgNSEgABBeEGA1ISAAGtBD3FBAEGA1ISAAEEIakEPcRsiA2oiBEEEaiACQUhqIgUgA2siA0EBcjYCAEEAQQAoAvDTgIAANgKk0ICAAEEAIAM2ApTQgIAAQQAgBDYCoNCAgABBgNSEgAAgBWpBODYCBAsCQAJAAkACQAJAAkACQAJAAkACQAJAAkAgAEHsAUsNAAJAQQAoAojQgIAAIgZBECAAQRNqQXBxIABBC0kbIgJBA3YiBHYiA0EDcUUNAAJAAkAgA0EBcSAEckEBcyIFQQN0IgRBsNCAgABqIgMgBEG40ICAAGooAgAiBCgCCCICRw0AQQAgBkF+IAV3cTYCiNCAgAAMAQsgAyACNgIIIAIgAzYCDAsgBEEIaiEDIAQgBUEDdCIFQQNyNgIEIAQgBWoiBCAEKAIEQQFyNgIEDAwLIAJBACgCkNCAgAAiB00NAQJAIANFDQACQAJAIAMgBHRBAiAEdCIDQQAgA2tycSIDQQAgA2txQX9qIgMgA0EMdkEQcSIDdiIEQQV2QQhxIgUgA3IgBCAFdiIDQQJ2QQRxIgRyIAMgBHYiA0EBdkECcSIEciADIAR2IgNBAXZBAXEiBHIgAyAEdmoiBEEDdCIDQbDQgIAAaiIFIANBuNCAgABqKAIAIgMoAggiAEcNAEEAIAZBfiAEd3EiBjYCiNCAgAAMAQsgBSAANgIIIAAgBTYCDAsgAyACQQNyNgIEIAMgBEEDdCIEaiAEIAJrIgU2AgAgAyACaiIAIAVBAXI2AgQCQCAHRQ0AIAdBeHFBsNCAgABqIQJBACgCnNCAgAAhBAJAAkAgBkEBIAdBA3Z0IghxDQBBACAGIAhyNgKI0ICAACACIQgMAQsgAigCCCEICyAIIAQ2AgwgAiAENgIIIAQgAjYCDCAEIAg2AggLIANBCGohA0EAIAA2ApzQgIAAQQAgBTYCkNCAgAAMDAtBACgCjNCAgAAiCUUNASAJQQAgCWtxQX9qIgMgA0EMdkEQcSIDdiIEQQV2QQhxIgUgA3IgBCAFdiIDQQJ2QQRxIgRyIAMgBHYiA0EBdkECcSIEciADIAR2IgNBAXZBAXEiBHIgAyAEdmpBAnRBuNKAgABqKAIAIgAoAgRBeHEgAmshBCAAIQUCQANAAkAgBSgCECIDDQAgBUEUaigCACIDRQ0CCyADKAIEQXhxIAJrIgUgBCAFIARJIgUbIQQgAyAAIAUbIQAgAyEFDAALCyAAKAIYIQoCQCAAKAIMIgggAEYNACAAKAIIIgNBACgCmNCAgABJGiAIIAM2AgggAyAINgIMDAsLAkAgAEEUaiIFKAIAIgMNACAAKAIQIgNFDQMgAEEQaiEFCwNAIAUhCyADIghBFGoiBSgCACIDDQAgCEEQaiEFIAgoAhAiAw0ACyALQQA2AgAMCgtBfyECIABBv39LDQAgAEETaiIDQXBxIQJBACgCjNCAgAAiB0UNAEEAIQsCQCACQYACSQ0AQR8hCyACQf///wdLDQAgA0EIdiIDIANBgP4/akEQdkEIcSIDdCIEIARBgOAfakEQdkEEcSIEdCIFIAVBgIAPakEQdkECcSIFdEEPdiADIARyIAVyayIDQQF0IAIgA0EVanZBAXFyQRxqIQsLQQAgAmshBAJAAkACQAJAIAtBAnRBuNKAgABqKAIAIgUNAEEAIQNBACEIDAELQQAhAyACQQBBGSALQQF2ayALQR9GG3QhAEEAIQgDQAJAIAUoAgRBeHEgAmsiBiAETw0AIAYhBCAFIQggBg0AQQAhBCAFIQggBSEDDAMLIAMgBUEUaigCACIGIAYgBSAAQR12QQRxakEQaigCACIFRhsgAyAGGyEDIABBAXQhACAFDQALCwJAIAMgCHINAEEAIQhBAiALdCIDQQAgA2tyIAdxIgNFDQMgA0EAIANrcUF/aiIDIANBDHZBEHEiA3YiBUEFdkEIcSIAIANyIAUgAHYiA0ECdkEEcSIFciADIAV2IgNBAXZBAnEiBXIgAyAFdiIDQQF2QQFxIgVyIAMgBXZqQQJ0QbjSgIAAaigCACEDCyADRQ0BCwNAIAMoAgRBeHEgAmsiBiAESSEAAkAgAygCECIFDQAgA0EUaigCACEFCyAGIAQgABshBCADIAggABshCCAFIQMgBQ0ACwsgCEUNACAEQQAoApDQgIAAIAJrTw0AIAgoAhghCwJAIAgoAgwiACAIRg0AIAgoAggiA0EAKAKY0ICAAEkaIAAgAzYCCCADIAA2AgwMCQsCQCAIQRRqIgUoAgAiAw0AIAgoAhAiA0UNAyAIQRBqIQULA0AgBSEGIAMiAEEUaiIFKAIAIgMNACAAQRBqIQUgACgCECIDDQALIAZBADYCAAwICwJAQQAoApDQgIAAIgMgAkkNAEEAKAKc0ICAACEEAkACQCADIAJrIgVBEEkNACAEIAJqIgAgBUEBcjYCBEEAIAU2ApDQgIAAQQAgADYCnNCAgAAgBCADaiAFNgIAIAQgAkEDcjYCBAwBCyAEIANBA3I2AgQgBCADaiIDIAMoAgRBAXI2AgRBAEEANgKc0ICAAEEAQQA2ApDQgIAACyAEQQhqIQMMCgsCQEEAKAKU0ICAACIAIAJNDQBBACgCoNCAgAAiAyACaiIEIAAgAmsiBUEBcjYCBEEAIAU2ApTQgIAAQQAgBDYCoNCAgAAgAyACQQNyNgIEIANBCGohAwwKCwJAAkBBACgC4NOAgABFDQBBACgC6NOAgAAhBAwBC0EAQn83AuzTgIAAQQBCgICEgICAwAA3AuTTgIAAQQAgAUEMakFwcUHYqtWqBXM2AuDTgIAAQQBBADYC9NOAgABBAEEANgLE04CAAEGAgAQhBAtBACEDAkAgBCACQccAaiIHaiIGQQAgBGsiC3EiCCACSw0AQQBBMDYC+NOAgAAMCgsCQEEAKALA04CAACIDRQ0AAkBBACgCuNOAgAAiBCAIaiIFIARNDQAgBSADTQ0BC0EAIQNBAEEwNgL404CAAAwKC0EALQDE04CAAEEEcQ0EAkACQAJAQQAoAqDQgIAAIgRFDQBByNOAgAAhAwNAAkAgAygCACIFIARLDQAgBSADKAIEaiAESw0DCyADKAIIIgMNAAsLQQAQy4CAgAAiAEF/Rg0FIAghBgJAQQAoAuTTgIAAIgNBf2oiBCAAcUUNACAIIABrIAQgAGpBACADa3FqIQYLIAYgAk0NBSAGQf7///8HSw0FAkBBACgCwNOAgAAiA0UNAEEAKAK404CAACIEIAZqIgUgBE0NBiAFIANLDQYLIAYQy4CAgAAiAyAARw0BDAcLIAYgAGsgC3EiBkH+////B0sNBCAGEMuAgIAAIgAgAygCACADKAIEakYNAyAAIQMLAkAgA0F/Rg0AIAJByABqIAZNDQACQCAHIAZrQQAoAujTgIAAIgRqQQAgBGtxIgRB/v///wdNDQAgAyEADAcLAkAgBBDLgICAAEF/Rg0AIAQgBmohBiADIQAMBwtBACAGaxDLgICAABoMBAsgAyEAIANBf0cNBQwDC0EAIQgMBwtBACEADAULIABBf0cNAgtBAEEAKALE04CAAEEEcjYCxNOAgAALIAhB/v///wdLDQEgCBDLgICAACEAQQAQy4CAgAAhAyAAQX9GDQEgA0F/Rg0BIAAgA08NASADIABrIgYgAkE4ak0NAQtBAEEAKAK404CAACAGaiIDNgK404CAAAJAIANBACgCvNOAgABNDQBBACADNgK804CAAAsCQAJAAkACQEEAKAKg0ICAACIERQ0AQcjTgIAAIQMDQCAAIAMoAgAiBSADKAIEIghqRg0CIAMoAggiAw0ADAMLCwJAAkBBACgCmNCAgAAiA0UNACAAIANPDQELQQAgADYCmNCAgAALQQAhA0EAIAY2AszTgIAAQQAgADYCyNOAgABBAEF/NgKo0ICAAEEAQQAoAuDTgIAANgKs0ICAAEEAQQA2AtTTgIAAA0AgA0HE0ICAAGogA0G40ICAAGoiBDYCACAEIANBsNCAgABqIgU2AgAgA0G80ICAAGogBTYCACADQczQgIAAaiADQcDQgIAAaiIFNgIAIAUgBDYCACADQdTQgIAAaiADQcjQgIAAaiIENgIAIAQgBTYCACADQdDQgIAAaiAENgIAIANBIGoiA0GAAkcNAAsgAEF4IABrQQ9xQQAgAEEIakEPcRsiA2oiBCAGQUhqIgUgA2siA0EBcjYCBEEAQQAoAvDTgIAANgKk0ICAAEEAIAM2ApTQgIAAQQAgBDYCoNCAgAAgACAFakE4NgIEDAILIAMtAAxBCHENACAEIAVJDQAgBCAATw0AIARBeCAEa0EPcUEAIARBCGpBD3EbIgVqIgBBACgClNCAgAAgBmoiCyAFayIFQQFyNgIEIAMgCCAGajYCBEEAQQAoAvDTgIAANgKk0ICAAEEAIAU2ApTQgIAAQQAgADYCoNCAgAAgBCALakE4NgIEDAELAkAgAEEAKAKY0ICAACIITw0AQQAgADYCmNCAgAAgACEICyAAIAZqIQVByNOAgAAhAwJAAkACQAJAAkACQAJAA0AgAygCACAFRg0BIAMoAggiAw0ADAILCyADLQAMQQhxRQ0BC0HI04CAACEDA0ACQCADKAIAIgUgBEsNACAFIAMoAgRqIgUgBEsNAwsgAygCCCEDDAALCyADIAA2AgAgAyADKAIEIAZqNgIEIABBeCAAa0EPcUEAIABBCGpBD3EbaiILIAJBA3I2AgQgBUF4IAVrQQ9xQQAgBUEIakEPcRtqIgYgCyACaiICayEDAkAgBiAERw0AQQAgAjYCoNCAgABBAEEAKAKU0ICAACADaiIDNgKU0ICAACACIANBAXI2AgQMAwsCQCAGQQAoApzQgIAARw0AQQAgAjYCnNCAgABBAEEAKAKQ0ICAACADaiIDNgKQ0ICAACACIANBAXI2AgQgAiADaiADNgIADAMLAkAgBigCBCIEQQNxQQFHDQAgBEF4cSEHAkACQCAEQf8BSw0AIAYoAggiBSAEQQN2IghBA3RBsNCAgABqIgBGGgJAIAYoAgwiBCAFRw0AQQBBACgCiNCAgABBfiAId3E2AojQgIAADAILIAQgAEYaIAQgBTYCCCAFIAQ2AgwMAQsgBigCGCEJAkACQCAGKAIMIgAgBkYNACAGKAIIIgQgCEkaIAAgBDYCCCAEIAA2AgwMAQsCQCAGQRRqIgQoAgAiBQ0AIAZBEGoiBCgCACIFDQBBACEADAELA0AgBCEIIAUiAEEUaiIEKAIAIgUNACAAQRBqIQQgACgCECIFDQALIAhBADYCAAsgCUUNAAJAAkAgBiAGKAIcIgVBAnRBuNKAgABqIgQoAgBHDQAgBCAANgIAIAANAUEAQQAoAozQgIAAQX4gBXdxNgKM0ICAAAwCCyAJQRBBFCAJKAIQIAZGG2ogADYCACAARQ0BCyAAIAk2AhgCQCAGKAIQIgRFDQAgACAENgIQIAQgADYCGAsgBigCFCIERQ0AIABBFGogBDYCACAEIAA2AhgLIAcgA2ohAyAGIAdqIgYoAgQhBAsgBiAEQX5xNgIEIAIgA2ogAzYCACACIANBAXI2AgQCQCADQf8BSw0AIANBeHFBsNCAgABqIQQCQAJAQQAoAojQgIAAIgVBASADQQN2dCIDcQ0AQQAgBSADcjYCiNCAgAAgBCEDDAELIAQoAgghAwsgAyACNgIMIAQgAjYCCCACIAQ2AgwgAiADNgIIDAMLQR8hBAJAIANB////B0sNACADQQh2IgQgBEGA/j9qQRB2QQhxIgR0IgUgBUGA4B9qQRB2QQRxIgV0IgAgAEGAgA9qQRB2QQJxIgB0QQ92IAQgBXIgAHJrIgRBAXQgAyAEQRVqdkEBcXJBHGohBAsgAiAENgIcIAJCADcCECAEQQJ0QbjSgIAAaiEFAkBBACgCjNCAgAAiAEEBIAR0IghxDQAgBSACNgIAQQAgACAIcjYCjNCAgAAgAiAFNgIYIAIgAjYCCCACIAI2AgwMAwsgA0EAQRkgBEEBdmsgBEEfRht0IQQgBSgCACEAA0AgACIFKAIEQXhxIANGDQIgBEEddiEAIARBAXQhBCAFIABBBHFqQRBqIggoAgAiAA0ACyAIIAI2AgAgAiAFNgIYIAIgAjYCDCACIAI2AggMAgsgAEF4IABrQQ9xQQAgAEEIakEPcRsiA2oiCyAGQUhqIgggA2siA0EBcjYCBCAAIAhqQTg2AgQgBCAFQTcgBWtBD3FBACAFQUlqQQ9xG2pBQWoiCCAIIARBEGpJGyIIQSM2AgRBAEEAKALw04CAADYCpNCAgABBACADNgKU0ICAAEEAIAs2AqDQgIAAIAhBEGpBACkC0NOAgAA3AgAgCEEAKQLI04CAADcCCEEAIAhBCGo2AtDTgIAAQQAgBjYCzNOAgABBACAANgLI04CAAEEAQQA2AtTTgIAAIAhBJGohAwNAIANBBzYCACADQQRqIgMgBUkNAAsgCCAERg0DIAggCCgCBEF+cTYCBCAIIAggBGsiADYCACAEIABBAXI2AgQCQCAAQf8BSw0AIABBeHFBsNCAgABqIQMCQAJAQQAoAojQgIAAIgVBASAAQQN2dCIAcQ0AQQAgBSAAcjYCiNCAgAAgAyEFDAELIAMoAgghBQsgBSAENgIMIAMgBDYCCCAEIAM2AgwgBCAFNgIIDAQLQR8hAwJAIABB////B0sNACAAQQh2IgMgA0GA/j9qQRB2QQhxIgN0IgUgBUGA4B9qQRB2QQRxIgV0IgggCEGAgA9qQRB2QQJxIgh0QQ92IAMgBXIgCHJrIgNBAXQgACADQRVqdkEBcXJBHGohAwsgBCADNgIcIARCADcCECADQQJ0QbjSgIAAaiEFAkBBACgCjNCAgAAiCEEBIAN0IgZxDQAgBSAENgIAQQAgCCAGcjYCjNCAgAAgBCAFNgIYIAQgBDYCCCAEIAQ2AgwMBAsgAEEAQRkgA0EBdmsgA0EfRht0IQMgBSgCACEIA0AgCCIFKAIEQXhxIABGDQMgA0EddiEIIANBAXQhAyAFIAhBBHFqQRBqIgYoAgAiCA0ACyAGIAQ2AgAgBCAFNgIYIAQgBDYCDCAEIAQ2AggMAwsgBSgCCCIDIAI2AgwgBSACNgIIIAJBADYCGCACIAU2AgwgAiADNgIICyALQQhqIQMMBQsgBSgCCCIDIAQ2AgwgBSAENgIIIARBADYCGCAEIAU2AgwgBCADNgIIC0EAKAKU0ICAACIDIAJNDQBBACgCoNCAgAAiBCACaiIFIAMgAmsiA0EBcjYCBEEAIAM2ApTQgIAAQQAgBTYCoNCAgAAgBCACQQNyNgIEIARBCGohAwwDC0EAIQNBAEEwNgL404CAAAwCCwJAIAtFDQACQAJAIAggCCgCHCIFQQJ0QbjSgIAAaiIDKAIARw0AIAMgADYCACAADQFBACAHQX4gBXdxIgc2AozQgIAADAILIAtBEEEUIAsoAhAgCEYbaiAANgIAIABFDQELIAAgCzYCGAJAIAgoAhAiA0UNACAAIAM2AhAgAyAANgIYCyAIQRRqKAIAIgNFDQAgAEEUaiADNgIAIAMgADYCGAsCQAJAIARBD0sNACAIIAQgAmoiA0EDcjYCBCAIIANqIgMgAygCBEEBcjYCBAwBCyAIIAJqIgAgBEEBcjYCBCAIIAJBA3I2AgQgACAEaiAENgIAAkAgBEH/AUsNACAEQXhxQbDQgIAAaiEDAkACQEEAKAKI0ICAACIFQQEgBEEDdnQiBHENAEEAIAUgBHI2AojQgIAAIAMhBAwBCyADKAIIIQQLIAQgADYCDCADIAA2AgggACADNgIMIAAgBDYCCAwBC0EfIQMCQCAEQf///wdLDQAgBEEIdiIDIANBgP4/akEQdkEIcSIDdCIFIAVBgOAfakEQdkEEcSIFdCICIAJBgIAPakEQdkECcSICdEEPdiADIAVyIAJyayIDQQF0IAQgA0EVanZBAXFyQRxqIQMLIAAgAzYCHCAAQgA3AhAgA0ECdEG40oCAAGohBQJAIAdBASADdCICcQ0AIAUgADYCAEEAIAcgAnI2AozQgIAAIAAgBTYCGCAAIAA2AgggACAANgIMDAELIARBAEEZIANBAXZrIANBH0YbdCEDIAUoAgAhAgJAA0AgAiIFKAIEQXhxIARGDQEgA0EddiECIANBAXQhAyAFIAJBBHFqQRBqIgYoAgAiAg0ACyAGIAA2AgAgACAFNgIYIAAgADYCDCAAIAA2AggMAQsgBSgCCCIDIAA2AgwgBSAANgIIIABBADYCGCAAIAU2AgwgACADNgIICyAIQQhqIQMMAQsCQCAKRQ0AAkACQCAAIAAoAhwiBUECdEG40oCAAGoiAygCAEcNACADIAg2AgAgCA0BQQAgCUF+IAV3cTYCjNCAgAAMAgsgCkEQQRQgCigCECAARhtqIAg2AgAgCEUNAQsgCCAKNgIYAkAgACgCECIDRQ0AIAggAzYCECADIAg2AhgLIABBFGooAgAiA0UNACAIQRRqIAM2AgAgAyAINgIYCwJAAkAgBEEPSw0AIAAgBCACaiIDQQNyNgIEIAAgA2oiAyADKAIEQQFyNgIEDAELIAAgAmoiBSAEQQFyNgIEIAAgAkEDcjYCBCAFIARqIAQ2AgACQCAHRQ0AIAdBeHFBsNCAgABqIQJBACgCnNCAgAAhAwJAAkBBASAHQQN2dCIIIAZxDQBBACAIIAZyNgKI0ICAACACIQgMAQsgAigCCCEICyAIIAM2AgwgAiADNgIIIAMgAjYCDCADIAg2AggLQQAgBTYCnNCAgABBACAENgKQ0ICAAAsgAEEIaiEDCyABQRBqJICAgIAAIAMLCgAgABDJgICAAAviDQEHfwJAIABFDQAgAEF4aiIBIABBfGooAgAiAkF4cSIAaiEDAkAgAkEBcQ0AIAJBA3FFDQEgASABKAIAIgJrIgFBACgCmNCAgAAiBEkNASACIABqIQACQCABQQAoApzQgIAARg0AAkAgAkH/AUsNACABKAIIIgQgAkEDdiIFQQN0QbDQgIAAaiIGRhoCQCABKAIMIgIgBEcNAEEAQQAoAojQgIAAQX4gBXdxNgKI0ICAAAwDCyACIAZGGiACIAQ2AgggBCACNgIMDAILIAEoAhghBwJAAkAgASgCDCIGIAFGDQAgASgCCCICIARJGiAGIAI2AgggAiAGNgIMDAELAkAgAUEUaiICKAIAIgQNACABQRBqIgIoAgAiBA0AQQAhBgwBCwNAIAIhBSAEIgZBFGoiAigCACIEDQAgBkEQaiECIAYoAhAiBA0ACyAFQQA2AgALIAdFDQECQAJAIAEgASgCHCIEQQJ0QbjSgIAAaiICKAIARw0AIAIgBjYCACAGDQFBAEEAKAKM0ICAAEF+IAR3cTYCjNCAgAAMAwsgB0EQQRQgBygCECABRhtqIAY2AgAgBkUNAgsgBiAHNgIYAkAgASgCECICRQ0AIAYgAjYCECACIAY2AhgLIAEoAhQiAkUNASAGQRRqIAI2AgAgAiAGNgIYDAELIAMoAgQiAkEDcUEDRw0AIAMgAkF+cTYCBEEAIAA2ApDQgIAAIAEgAGogADYCACABIABBAXI2AgQPCyABIANPDQAgAygCBCICQQFxRQ0AAkACQCACQQJxDQACQCADQQAoAqDQgIAARw0AQQAgATYCoNCAgABBAEEAKAKU0ICAACAAaiIANgKU0ICAACABIABBAXI2AgQgAUEAKAKc0ICAAEcNA0EAQQA2ApDQgIAAQQBBADYCnNCAgAAPCwJAIANBACgCnNCAgABHDQBBACABNgKc0ICAAEEAQQAoApDQgIAAIABqIgA2ApDQgIAAIAEgAEEBcjYCBCABIABqIAA2AgAPCyACQXhxIABqIQACQAJAIAJB/wFLDQAgAygCCCIEIAJBA3YiBUEDdEGw0ICAAGoiBkYaAkAgAygCDCICIARHDQBBAEEAKAKI0ICAAEF+IAV3cTYCiNCAgAAMAgsgAiAGRhogAiAENgIIIAQgAjYCDAwBCyADKAIYIQcCQAJAIAMoAgwiBiADRg0AIAMoAggiAkEAKAKY0ICAAEkaIAYgAjYCCCACIAY2AgwMAQsCQCADQRRqIgIoAgAiBA0AIANBEGoiAigCACIEDQBBACEGDAELA0AgAiEFIAQiBkEUaiICKAIAIgQNACAGQRBqIQIgBigCECIEDQALIAVBADYCAAsgB0UNAAJAAkAgAyADKAIcIgRBAnRBuNKAgABqIgIoAgBHDQAgAiAGNgIAIAYNAUEAQQAoAozQgIAAQX4gBHdxNgKM0ICAAAwCCyAHQRBBFCAHKAIQIANGG2ogBjYCACAGRQ0BCyAGIAc2AhgCQCADKAIQIgJFDQAgBiACNgIQIAIgBjYCGAsgAygCFCICRQ0AIAZBFGogAjYCACACIAY2AhgLIAEgAGogADYCACABIABBAXI2AgQgAUEAKAKc0ICAAEcNAUEAIAA2ApDQgIAADwsgAyACQX5xNgIEIAEgAGogADYCACABIABBAXI2AgQLAkAgAEH/AUsNACAAQXhxQbDQgIAAaiECAkACQEEAKAKI0ICAACIEQQEgAEEDdnQiAHENAEEAIAQgAHI2AojQgIAAIAIhAAwBCyACKAIIIQALIAAgATYCDCACIAE2AgggASACNgIMIAEgADYCCA8LQR8hAgJAIABB////B0sNACAAQQh2IgIgAkGA/j9qQRB2QQhxIgJ0IgQgBEGA4B9qQRB2QQRxIgR0IgYgBkGAgA9qQRB2QQJxIgZ0QQ92IAIgBHIgBnJrIgJBAXQgACACQRVqdkEBcXJBHGohAgsgASACNgIcIAFCADcCECACQQJ0QbjSgIAAaiEEAkACQEEAKAKM0ICAACIGQQEgAnQiA3ENACAEIAE2AgBBACAGIANyNgKM0ICAACABIAQ2AhggASABNgIIIAEgATYCDAwBCyAAQQBBGSACQQF2ayACQR9GG3QhAiAEKAIAIQYCQANAIAYiBCgCBEF4cSAARg0BIAJBHXYhBiACQQF0IQIgBCAGQQRxakEQaiIDKAIAIgYNAAsgAyABNgIAIAEgBDYCGCABIAE2AgwgASABNgIIDAELIAQoAggiACABNgIMIAQgATYCCCABQQA2AhggASAENgIMIAEgADYCCAtBAEEAKAKo0ICAAEF/aiIBQX8gARs2AqjQgIAACwsEAAAAC04AAkAgAA0APwBBEHQPCwJAIABB//8DcQ0AIABBf0wNAAJAIABBEHZAACIAQX9HDQBBAEEwNgL404CAAEF/DwsgAEEQdA8LEMqAgIAAAAvyAgIDfwF+AkAgAkUNACAAIAE6AAAgAiAAaiIDQX9qIAE6AAAgAkEDSQ0AIAAgAToAAiAAIAE6AAEgA0F9aiABOgAAIANBfmogAToAACACQQdJDQAgACABOgADIANBfGogAToAACACQQlJDQAgAEEAIABrQQNxIgRqIgMgAUH/AXFBgYKECGwiATYCACADIAIgBGtBfHEiBGoiAkF8aiABNgIAIARBCUkNACADIAE2AgggAyABNgIEIAJBeGogATYCACACQXRqIAE2AgAgBEEZSQ0AIAMgATYCGCADIAE2AhQgAyABNgIQIAMgATYCDCACQXBqIAE2AgAgAkFsaiABNgIAIAJBaGogATYCACACQWRqIAE2AgAgBCADQQRxQRhyIgVrIgJBIEkNACABrUKBgICAEH4hBiADIAVqIQEDQCABIAY3AxggASAGNwMQIAEgBjcDCCABIAY3AwAgAUEgaiEBIAJBYGoiAkEfSw0ACwsgAAsLjkgBAEGACAuGSAEAAAACAAAAAwAAAAAAAAAAAAAABAAAAAUAAAAAAAAAAAAAAAYAAAAHAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAASW52YWxpZCBjaGFyIGluIHVybCBxdWVyeQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2JvZHkAQ29udGVudC1MZW5ndGggb3ZlcmZsb3cAQ2h1bmsgc2l6ZSBvdmVyZmxvdwBSZXNwb25zZSBvdmVyZmxvdwBJbnZhbGlkIG1ldGhvZCBmb3IgSFRUUC94LnggcmVxdWVzdABJbnZhbGlkIG1ldGhvZCBmb3IgUlRTUC94LnggcmVxdWVzdABFeHBlY3RlZCBTT1VSQ0UgbWV0aG9kIGZvciBJQ0UveC54IHJlcXVlc3QASW52YWxpZCBjaGFyIGluIHVybCBmcmFnbWVudCBzdGFydABFeHBlY3RlZCBkb3QAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9zdGF0dXMASW52YWxpZCByZXNwb25zZSBzdGF0dXMASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucwBVc2VyIGNhbGxiYWNrIGVycm9yAGBvbl9yZXNldGAgY2FsbGJhY2sgZXJyb3IAYG9uX2NodW5rX2hlYWRlcmAgY2FsbGJhY2sgZXJyb3IAYG9uX21lc3NhZ2VfYmVnaW5gIGNhbGxiYWNrIGVycm9yAGBvbl9jaHVua19leHRlbnNpb25fdmFsdWVgIGNhbGxiYWNrIGVycm9yAGBvbl9zdGF0dXNfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl92ZXJzaW9uX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fdXJsX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9oZWFkZXJfdmFsdWVfY29tcGxldGVgIGNhbGxiYWNrIGVycm9yAGBvbl9tZXNzYWdlX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fbWV0aG9kX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25faGVhZGVyX2ZpZWxkX2NvbXBsZXRlYCBjYWxsYmFjayBlcnJvcgBgb25fY2h1bmtfZXh0ZW5zaW9uX25hbWVgIGNhbGxiYWNrIGVycm9yAFVuZXhwZWN0ZWQgY2hhciBpbiB1cmwgc2VydmVyAEludmFsaWQgaGVhZGVyIHZhbHVlIGNoYXIASW52YWxpZCBoZWFkZXIgZmllbGQgY2hhcgBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3ZlcnNpb24ASW52YWxpZCBtaW5vciB2ZXJzaW9uAEludmFsaWQgbWFqb3IgdmVyc2lvbgBFeHBlY3RlZCBzcGFjZSBhZnRlciB2ZXJzaW9uAEV4cGVjdGVkIENSTEYgYWZ0ZXIgdmVyc2lvbgBJbnZhbGlkIEhUVFAgdmVyc2lvbgBJbnZhbGlkIGhlYWRlciB0b2tlbgBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX3VybABJbnZhbGlkIGNoYXJhY3RlcnMgaW4gdXJsAFVuZXhwZWN0ZWQgc3RhcnQgY2hhciBpbiB1cmwARG91YmxlIEAgaW4gdXJsAEVtcHR5IENvbnRlbnQtTGVuZ3RoAEludmFsaWQgY2hhcmFjdGVyIGluIENvbnRlbnQtTGVuZ3RoAER1cGxpY2F0ZSBDb250ZW50LUxlbmd0aABJbnZhbGlkIGNoYXIgaW4gdXJsIHBhdGgAQ29udGVudC1MZW5ndGggY2FuJ3QgYmUgcHJlc2VudCB3aXRoIFRyYW5zZmVyLUVuY29kaW5nAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIHNpemUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9oZWFkZXJfdmFsdWUAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9jaHVua19leHRlbnNpb25fdmFsdWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyB2YWx1ZQBNaXNzaW5nIGV4cGVjdGVkIExGIGFmdGVyIGhlYWRlciB2YWx1ZQBJbnZhbGlkIGBUcmFuc2Zlci1FbmNvZGluZ2AgaGVhZGVyIHZhbHVlAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgcXVvdGUgdmFsdWUASW52YWxpZCBjaGFyYWN0ZXIgaW4gY2h1bmsgZXh0ZW5zaW9ucyBxdW90ZWQgdmFsdWUAUGF1c2VkIGJ5IG9uX2hlYWRlcnNfY29tcGxldGUASW52YWxpZCBFT0Ygc3RhdGUAb25fcmVzZXQgcGF1c2UAb25fY2h1bmtfaGVhZGVyIHBhdXNlAG9uX21lc3NhZ2VfYmVnaW4gcGF1c2UAb25fY2h1bmtfZXh0ZW5zaW9uX3ZhbHVlIHBhdXNlAG9uX3N0YXR1c19jb21wbGV0ZSBwYXVzZQBvbl92ZXJzaW9uX2NvbXBsZXRlIHBhdXNlAG9uX3VybF9jb21wbGV0ZSBwYXVzZQBvbl9jaHVua19jb21wbGV0ZSBwYXVzZQBvbl9oZWFkZXJfdmFsdWVfY29tcGxldGUgcGF1c2UAb25fbWVzc2FnZV9jb21wbGV0ZSBwYXVzZQBvbl9tZXRob2RfY29tcGxldGUgcGF1c2UAb25faGVhZGVyX2ZpZWxkX2NvbXBsZXRlIHBhdXNlAG9uX2NodW5rX2V4dGVuc2lvbl9uYW1lIHBhdXNlAFVuZXhwZWN0ZWQgc3BhY2UgYWZ0ZXIgc3RhcnQgbGluZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX2NodW5rX2V4dGVuc2lvbl9uYW1lAEludmFsaWQgY2hhcmFjdGVyIGluIGNodW5rIGV4dGVuc2lvbnMgbmFtZQBQYXVzZSBvbiBDT05ORUNUL1VwZ3JhZGUAUGF1c2Ugb24gUFJJL1VwZ3JhZGUARXhwZWN0ZWQgSFRUUC8yIENvbm5lY3Rpb24gUHJlZmFjZQBTcGFuIGNhbGxiYWNrIGVycm9yIGluIG9uX21ldGhvZABFeHBlY3RlZCBzcGFjZSBhZnRlciBtZXRob2QAU3BhbiBjYWxsYmFjayBlcnJvciBpbiBvbl9oZWFkZXJfZmllbGQAUGF1c2VkAEludmFsaWQgd29yZCBlbmNvdW50ZXJlZABJbnZhbGlkIG1ldGhvZCBlbmNvdW50ZXJlZABVbmV4cGVjdGVkIGNoYXIgaW4gdXJsIHNjaGVtYQBSZXF1ZXN0IGhhcyBpbnZhbGlkIGBUcmFuc2Zlci1FbmNvZGluZ2AAU1dJVENIX1BST1hZAFVTRV9QUk9YWQBNS0FDVElWSVRZAFVOUFJPQ0VTU0FCTEVfRU5USVRZAENPUFkATU9WRURfUEVSTUFORU5UTFkAVE9PX0VBUkxZAE5PVElGWQBGQUlMRURfREVQRU5ERU5DWQBCQURfR0FURVdBWQBQTEFZAFBVVABDSEVDS09VVABHQVRFV0FZX1RJTUVPVVQAUkVRVUVTVF9USU1FT1VUAE5FVFdPUktfQ09OTkVDVF9USU1FT1VUAENPTk5FQ1RJT05fVElNRU9VVABMT0dJTl9USU1FT1VUAE5FVFdPUktfUkVBRF9USU1FT1VUAFBPU1QATUlTRElSRUNURURfUkVRVUVTVABDTElFTlRfQ0xPU0VEX1JFUVVFU1QAQ0xJRU5UX0NMT1NFRF9MT0FEX0JBTEFOQ0VEX1JFUVVFU1QAQkFEX1JFUVVFU1QASFRUUF9SRVFVRVNUX1NFTlRfVE9fSFRUUFNfUE9SVABSRVBPUlQASU1fQV9URUFQT1QAUkVTRVRfQ09OVEVOVABOT19DT05URU5UAFBBUlRJQUxfQ09OVEVOVABIUEVfSU5WQUxJRF9DT05TVEFOVABIUEVfQ0JfUkVTRVQAR0VUAEhQRV9TVFJJQ1QAQ09ORkxJQ1QAVEVNUE9SQVJZX1JFRElSRUNUAFBFUk1BTkVOVF9SRURJUkVDVABDT05ORUNUAE1VTFRJX1NUQVRVUwBIUEVfSU5WQUxJRF9TVEFUVVMAVE9PX01BTllfUkVRVUVTVFMARUFSTFlfSElOVFMAVU5BVkFJTEFCTEVfRk9SX0xFR0FMX1JFQVNPTlMAT1BUSU9OUwBTV0lUQ0hJTkdfUFJPVE9DT0xTAFZBUklBTlRfQUxTT19ORUdPVElBVEVTAE1VTFRJUExFX0NIT0lDRVMASU5URVJOQUxfU0VSVkVSX0VSUk9SAFdFQl9TRVJWRVJfVU5LTk9XTl9FUlJPUgBSQUlMR1VOX0VSUk9SAElERU5USVRZX1BST1ZJREVSX0FVVEhFTlRJQ0FUSU9OX0VSUk9SAFNTTF9DRVJUSUZJQ0FURV9FUlJPUgBJTlZBTElEX1hfRk9SV0FSREVEX0ZPUgBTRVRfUEFSQU1FVEVSAEdFVF9QQVJBTUVURVIASFBFX1VTRVIAU0VFX09USEVSAEhQRV9DQl9DSFVOS19IRUFERVIATUtDQUxFTkRBUgBTRVRVUABXRUJfU0VSVkVSX0lTX0RPV04AVEVBUkRPV04ASFBFX0NMT1NFRF9DT05ORUNUSU9OAEhFVVJJU1RJQ19FWFBJUkFUSU9OAERJU0NPTk5FQ1RFRF9PUEVSQVRJT04ATk9OX0FVVEhPUklUQVRJVkVfSU5GT1JNQVRJT04ASFBFX0lOVkFMSURfVkVSU0lPTgBIUEVfQ0JfTUVTU0FHRV9CRUdJTgBTSVRFX0lTX0ZST1pFTgBIUEVfSU5WQUxJRF9IRUFERVJfVE9LRU4ASU5WQUxJRF9UT0tFTgBGT1JCSURERU4ARU5IQU5DRV9ZT1VSX0NBTE0ASFBFX0lOVkFMSURfVVJMAEJMT0NLRURfQllfUEFSRU5UQUxfQ09OVFJPTABNS0NPTABBQ0wASFBFX0lOVEVSTkFMAFJFUVVFU1RfSEVBREVSX0ZJRUxEU19UT09fTEFSR0VfVU5PRkZJQ0lBTABIUEVfT0sAVU5MSU5LAFVOTE9DSwBQUkkAUkVUUllfV0lUSABIUEVfSU5WQUxJRF9DT05URU5UX0xFTkdUSABIUEVfVU5FWFBFQ1RFRF9DT05URU5UX0xFTkdUSABGTFVTSABQUk9QUEFUQ0gATS1TRUFSQ0gAVVJJX1RPT19MT05HAFBST0NFU1NJTkcATUlTQ0VMTEFORU9VU19QRVJTSVNURU5UX1dBUk5JTkcATUlTQ0VMTEFORU9VU19XQVJOSU5HAEhQRV9JTlZBTElEX1RSQU5TRkVSX0VOQ09ESU5HAEV4cGVjdGVkIENSTEYASFBFX0lOVkFMSURfQ0hVTktfU0laRQBNT1ZFAENPTlRJTlVFAEhQRV9DQl9TVEFUVVNfQ09NUExFVEUASFBFX0NCX0hFQURFUlNfQ09NUExFVEUASFBFX0NCX1ZFUlNJT05fQ09NUExFVEUASFBFX0NCX1VSTF9DT01QTEVURQBIUEVfQ0JfQ0hVTktfQ09NUExFVEUASFBFX0NCX0hFQURFUl9WQUxVRV9DT01QTEVURQBIUEVfQ0JfQ0hVTktfRVhURU5TSU9OX1ZBTFVFX0NPTVBMRVRFAEhQRV9DQl9DSFVOS19FWFRFTlNJT05fTkFNRV9DT01QTEVURQBIUEVfQ0JfTUVTU0FHRV9DT01QTEVURQBIUEVfQ0JfTUVUSE9EX0NPTVBMRVRFAEhQRV9DQl9IRUFERVJfRklFTERfQ09NUExFVEUAREVMRVRFAEhQRV9JTlZBTElEX0VPRl9TVEFURQBJTlZBTElEX1NTTF9DRVJUSUZJQ0FURQBQQVVTRQBOT19SRVNQT05TRQBVTlNVUFBPUlRFRF9NRURJQV9UWVBFAEdPTkUATk9UX0FDQ0VQVEFCTEUAU0VSVklDRV9VTkFWQUlMQUJMRQBSQU5HRV9OT1RfU0FUSVNGSUFCTEUAT1JJR0lOX0lTX1VOUkVBQ0hBQkxFAFJFU1BPTlNFX0lTX1NUQUxFAFBVUkdFAE1FUkdFAFJFUVVFU1RfSEVBREVSX0ZJRUxEU19UT09fTEFSR0UAUkVRVUVTVF9IRUFERVJfVE9PX0xBUkdFAFBBWUxPQURfVE9PX0xBUkdFAElOU1VGRklDSUVOVF9TVE9SQUdFAEhQRV9QQVVTRURfVVBHUkFERQBIUEVfUEFVU0VEX0gyX1VQR1JBREUAU09VUkNFAEFOTk9VTkNFAFRSQUNFAEhQRV9VTkVYUEVDVEVEX1NQQUNFAERFU0NSSUJFAFVOU1VCU0NSSUJFAFJFQ09SRABIUEVfSU5WQUxJRF9NRVRIT0QATk9UX0ZPVU5EAFBST1BGSU5EAFVOQklORABSRUJJTkQAVU5BVVRIT1JJWkVEAE1FVEhPRF9OT1RfQUxMT1dFRABIVFRQX1ZFUlNJT05fTk9UX1NVUFBPUlRFRABBTFJFQURZX1JFUE9SVEVEAEFDQ0VQVEVEAE5PVF9JTVBMRU1FTlRFRABMT09QX0RFVEVDVEVEAEhQRV9DUl9FWFBFQ1RFRABIUEVfTEZfRVhQRUNURUQAQ1JFQVRFRABJTV9VU0VEAEhQRV9QQVVTRUQAVElNRU9VVF9PQ0NVUkVEAFBBWU1FTlRfUkVRVUlSRUQAUFJFQ09ORElUSU9OX1JFUVVJUkVEAFBST1hZX0FVVEhFTlRJQ0FUSU9OX1JFUVVJUkVEAE5FVFdPUktfQVVUSEVOVElDQVRJT05fUkVRVUlSRUQATEVOR1RIX1JFUVVJUkVEAFNTTF9DRVJUSUZJQ0FURV9SRVFVSVJFRABVUEdSQURFX1JFUVVJUkVEAFBBR0VfRVhQSVJFRABQUkVDT05ESVRJT05fRkFJTEVEAEVYUEVDVEFUSU9OX0ZBSUxFRABSRVZBTElEQVRJT05fRkFJTEVEAFNTTF9IQU5EU0hBS0VfRkFJTEVEAExPQ0tFRABUUkFOU0ZPUk1BVElPTl9BUFBMSUVEAE5PVF9NT0RJRklFRABOT1RfRVhURU5ERUQAQkFORFdJRFRIX0xJTUlUX0VYQ0VFREVEAFNJVEVfSVNfT1ZFUkxPQURFRABIRUFEAEV4cGVjdGVkIEhUVFAvAABeEwAAJhMAADAQAADwFwAAnRMAABUSAAA5FwAA8BIAAAoQAAB1EgAArRIAAIITAABPFAAAfxAAAKAVAAAjFAAAiRIAAIsUAABNFQAA1BEAAM8UAAAQGAAAyRYAANwWAADBEQAA4BcAALsUAAB0FAAAfBUAAOUUAAAIFwAAHxAAAGUVAACjFAAAKBUAAAIVAACZFQAALBAAAIsZAABPDwAA1A4AAGoQAADOEAAAAhcAAIkOAABuEwAAHBMAAGYUAABWFwAAwRMAAM0TAABsEwAAaBcAAGYXAABfFwAAIhMAAM4PAABpDgAA2A4AAGMWAADLEwAAqg4AACgXAAAmFwAAxRMAAF0WAADoEQAAZxMAAGUTAADyFgAAcxMAAB0XAAD5FgAA8xEAAM8OAADOFQAADBIAALMRAAClEQAAYRAAADIXAAC7EwAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAgEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAgMCAgICAgAAAgIAAgIAAgICAgICAgICAgAEAAAAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgAAAAICAgICAgICAgICAgICAgICAgICAgICAgICAgICAAIAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAIAAgICAgIAAAICAAICAAICAgICAgICAgIAAwAEAAAAAgICAgICAgICAgICAgICAgICAgICAgICAgIAAAACAgICAgICAgICAgICAgICAgICAgICAgICAgICAgACAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsb3NlZWVwLWFsaXZlAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAgEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQFjaHVua2VkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQABAQEBAQAAAQEAAQEAAQEBAQEBAQEBAQAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGVjdGlvbmVudC1sZW5ndGhvbnJveHktY29ubmVjdGlvbgAAAAAAAAAAAAAAAAAAAHJhbnNmZXItZW5jb2RpbmdwZ3JhZGUNCg0KDQpTTQ0KDQpUVFAvQ0UvVFNQLwAAAAAAAAAAAAAAAAECAAEDAAAAAAAAAAAAAAAAAAAAAAAABAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAABAgABAwAAAAAAAAAAAAAAAAAAAAAAAAQBAQUBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAQAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAQEAAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQABAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAABAAACAAAAAAAAAAAAAAAAAAAAAAAAAwQAAAQEBAQEBAQEBAQEBQQEBAQEBAQEBAQEBAAEAAYHBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAAQABAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAQAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAEAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAgAAAAACAAAAAAAAAAAAAAAAAAAAAAADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwAAAAAAAAMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE5PVU5DRUVDS09VVE5FQ1RFVEVDUklCRUxVU0hFVEVBRFNFQVJDSFJHRUNUSVZJVFlMRU5EQVJWRU9USUZZUFRJT05TQ0hTRUFZU1RBVENIR0VPUkRJUkVDVE9SVFJDSFBBUkFNRVRFUlVSQ0VCU0NSSUJFQVJET1dOQUNFSU5ETktDS1VCU0NSSUJFSFRUUC9BRFRQLw==' + + /***/ + }, + + /***/ 1891: /***/ (__unused_webpack_module, exports) => { + 'use strict' + + Object.defineProperty(exports, '__esModule', { value: true }) + exports.enumToMap = void 0 + function enumToMap(obj) { + const res = {} + Object.keys(obj).forEach((key) => { + const value = obj[key] + if (typeof value === 'number') { + res[key] = value + } + }) + return res + } + exports.enumToMap = enumToMap + //# sourceMappingURL=utils.js.map + + /***/ + }, + + /***/ 6771: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const { kClients } = __nccwpck_require__(2785) + const Agent = __nccwpck_require__(7890) + const { + kAgent, + kMockAgentSet, + kMockAgentGet, + kDispatches, + kIsMockActive, + kNetConnect, + kGetNetConnect, + kOptions, + kFactory, + } = __nccwpck_require__(4347) + const MockClient = __nccwpck_require__(8687) + const MockPool = __nccwpck_require__(6193) + const { matchValue, buildMockOptions } = __nccwpck_require__(9323) + const { InvalidArgumentError, UndiciError } = __nccwpck_require__(8045) + const Dispatcher = __nccwpck_require__(412) + const Pluralizer = __nccwpck_require__(8891) + const PendingInterceptorsFormatter = __nccwpck_require__(6823) + + class FakeWeakRef { + constructor(value) { + this.value = value + } + + deref() { + return this.value + } + } + + class MockAgent extends Dispatcher { + constructor(opts) { + super(opts) + + this[kNetConnect] = true + this[kIsMockActive] = true + + // Instantiate Agent and encapsulate + if (opts && opts.agent && typeof opts.agent.dispatch !== 'function') { + throw new InvalidArgumentError( + 'Argument opts.agent must implement Agent' + ) + } + const agent = opts && opts.agent ? opts.agent : new Agent(opts) + this[kAgent] = agent + + this[kClients] = agent[kClients] + this[kOptions] = buildMockOptions(opts) + } + + get(origin) { + let dispatcher = this[kMockAgentGet](origin) + + if (!dispatcher) { + dispatcher = this[kFactory](origin) + this[kMockAgentSet](origin, dispatcher) + } + return dispatcher + } + + dispatch(opts, handler) { + // Call MockAgent.get to perform additional setup before dispatching as normal + this.get(opts.origin) + return this[kAgent].dispatch(opts, handler) + } + + async close() { + await this[kAgent].close() + this[kClients].clear() + } + + deactivate() { + this[kIsMockActive] = false + } + + activate() { + this[kIsMockActive] = true + } + + enableNetConnect(matcher) { + if ( + typeof matcher === 'string' || + typeof matcher === 'function' || + matcher instanceof RegExp + ) { + if (Array.isArray(this[kNetConnect])) { + this[kNetConnect].push(matcher) + } else { + this[kNetConnect] = [matcher] + } + } else if (typeof matcher === 'undefined') { + this[kNetConnect] = true + } else { + throw new InvalidArgumentError( + 'Unsupported matcher. Must be one of String|Function|RegExp.' + ) + } + } + + disableNetConnect() { + this[kNetConnect] = false + } + + // This is required to bypass issues caused by using global symbols - see: + // https://github.com/nodejs/undici/issues/1447 + get isMockActive() { + return this[kIsMockActive] + } + + [kMockAgentSet](origin, dispatcher) { + this[kClients].set(origin, new FakeWeakRef(dispatcher)) + } + + [kFactory](origin) { + const mockOptions = Object.assign({ agent: this }, this[kOptions]) + return this[kOptions] && this[kOptions].connections === 1 + ? new MockClient(origin, mockOptions) + : new MockPool(origin, mockOptions) + } + + [kMockAgentGet](origin) { + // First check if we can immediately find it + const ref = this[kClients].get(origin) + if (ref) { + return ref.deref() + } + + // If the origin is not a string create a dummy parent pool and return to user + if (typeof origin !== 'string') { + const dispatcher = this[kFactory]('http://localhost:9999') + this[kMockAgentSet](origin, dispatcher) + return dispatcher + } + + // If we match, create a pool and assign the same dispatches + for (const [keyMatcher, nonExplicitRef] of Array.from( + this[kClients] + )) { + const nonExplicitDispatcher = nonExplicitRef.deref() + if ( + nonExplicitDispatcher && + typeof keyMatcher !== 'string' && + matchValue(keyMatcher, origin) + ) { + const dispatcher = this[kFactory](origin) + this[kMockAgentSet](origin, dispatcher) + dispatcher[kDispatches] = nonExplicitDispatcher[kDispatches] + return dispatcher + } + } + } + + [kGetNetConnect]() { + return this[kNetConnect] + } + + pendingInterceptors() { + const mockAgentClients = this[kClients] + + return Array.from(mockAgentClients.entries()) + .flatMap(([origin, scope]) => + scope + .deref() + [kDispatches].map((dispatch) => ({ ...dispatch, origin })) + ) + .filter(({ pending }) => pending) + } + + assertNoPendingInterceptors({ + pendingInterceptorsFormatter = new PendingInterceptorsFormatter(), + } = {}) { + const pending = this.pendingInterceptors() + + if (pending.length === 0) { + return + } + + const pluralizer = new Pluralizer( + 'interceptor', + 'interceptors' + ).pluralize(pending.length) + + throw new UndiciError( + ` +${pluralizer.count} ${pluralizer.noun} ${pluralizer.is} pending: + +${pendingInterceptorsFormatter.format(pending)} +`.trim() + ) + } + } + + module.exports = MockAgent + + /***/ + }, + + /***/ 8687: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const { promisify } = __nccwpck_require__(3837) + const Client = __nccwpck_require__(3598) + const { buildMockDispatch } = __nccwpck_require__(9323) + const { + kDispatches, + kMockAgent, + kClose, + kOriginalClose, + kOrigin, + kOriginalDispatch, + kConnected, + } = __nccwpck_require__(4347) + const { MockInterceptor } = __nccwpck_require__(410) + const Symbols = __nccwpck_require__(2785) + const { InvalidArgumentError } = __nccwpck_require__(8045) + + /** + * MockClient provides an API that extends the Client to influence the mockDispatches. + */ + class MockClient extends Client { + constructor(origin, opts) { + super(origin, opts) + + if ( + !opts || + !opts.agent || + typeof opts.agent.dispatch !== 'function' + ) { + throw new InvalidArgumentError( + 'Argument opts.agent must implement Agent' + ) + } + + this[kMockAgent] = opts.agent + this[kOrigin] = origin + this[kDispatches] = [] + this[kConnected] = 1 + this[kOriginalDispatch] = this.dispatch + this[kOriginalClose] = this.close.bind(this) + + this.dispatch = buildMockDispatch.call(this) + this.close = this[kClose] + } + + get [Symbols.kConnected]() { + return this[kConnected] + } + + /** + * Sets up the base interceptor for mocking replies from undici. + */ + intercept(opts) { + return new MockInterceptor(opts, this[kDispatches]) + } + + async [kClose]() { + await promisify(this[kOriginalClose])() + this[kConnected] = 0 + this[kMockAgent][Symbols.kClients].delete(this[kOrigin]) + } + } + + module.exports = MockClient + + /***/ + }, + + /***/ 888: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const { UndiciError } = __nccwpck_require__(8045) + + class MockNotMatchedError extends UndiciError { + constructor(message) { + super(message) + Error.captureStackTrace(this, MockNotMatchedError) + this.name = 'MockNotMatchedError' + this.message = + message || + 'The request does not match any registered mock dispatches' + this.code = 'UND_MOCK_ERR_MOCK_NOT_MATCHED' + } + } + + module.exports = { + MockNotMatchedError, + } + + /***/ + }, + + /***/ 410: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const { getResponseData, buildKey, addMockDispatch } = + __nccwpck_require__(9323) + const { + kDispatches, + kDispatchKey, + kDefaultHeaders, + kDefaultTrailers, + kContentLength, + kMockDispatch, + } = __nccwpck_require__(4347) + const { InvalidArgumentError } = __nccwpck_require__(8045) + const { buildURL } = __nccwpck_require__(3983) + + /** + * Defines the scope API for an interceptor reply + */ + class MockScope { + constructor(mockDispatch) { + this[kMockDispatch] = mockDispatch + } + + /** + * Delay a reply by a set amount in ms. + */ + delay(waitInMs) { + if ( + typeof waitInMs !== 'number' || + !Number.isInteger(waitInMs) || + waitInMs <= 0 + ) { + throw new InvalidArgumentError( + 'waitInMs must be a valid integer > 0' + ) + } + + this[kMockDispatch].delay = waitInMs + return this + } + + /** + * For a defined reply, never mark as consumed. + */ + persist() { + this[kMockDispatch].persist = true + return this + } + + /** + * Allow one to define a reply for a set amount of matching requests. + */ + times(repeatTimes) { + if ( + typeof repeatTimes !== 'number' || + !Number.isInteger(repeatTimes) || + repeatTimes <= 0 + ) { + throw new InvalidArgumentError( + 'repeatTimes must be a valid integer > 0' + ) + } + + this[kMockDispatch].times = repeatTimes + return this + } + } + + /** + * Defines an interceptor for a Mock + */ + class MockInterceptor { + constructor(opts, mockDispatches) { + if (typeof opts !== 'object') { + throw new InvalidArgumentError('opts must be an object') + } + if (typeof opts.path === 'undefined') { + throw new InvalidArgumentError('opts.path must be defined') + } + if (typeof opts.method === 'undefined') { + opts.method = 'GET' + } + // See https://github.com/nodejs/undici/issues/1245 + // As per RFC 3986, clients are not supposed to send URI + // fragments to servers when they retrieve a document, + if (typeof opts.path === 'string') { + if (opts.query) { + opts.path = buildURL(opts.path, opts.query) + } else { + // Matches https://github.com/nodejs/undici/blob/main/lib/fetch/index.js#L1811 + const parsedURL = new URL(opts.path, 'data://') + opts.path = parsedURL.pathname + parsedURL.search + } + } + if (typeof opts.method === 'string') { + opts.method = opts.method.toUpperCase() + } + + this[kDispatchKey] = buildKey(opts) + this[kDispatches] = mockDispatches + this[kDefaultHeaders] = {} + this[kDefaultTrailers] = {} + this[kContentLength] = false + } + + createMockScopeDispatchData(statusCode, data, responseOptions = {}) { + const responseData = getResponseData(data) + const contentLength = this[kContentLength] + ? { 'content-length': responseData.length } + : {} + const headers = { + ...this[kDefaultHeaders], + ...contentLength, + ...responseOptions.headers, + } + const trailers = { + ...this[kDefaultTrailers], + ...responseOptions.trailers, + } + + return { statusCode, data, headers, trailers } + } + + validateReplyParameters(statusCode, data, responseOptions) { + if (typeof statusCode === 'undefined') { + throw new InvalidArgumentError('statusCode must be defined') + } + if (typeof data === 'undefined') { + throw new InvalidArgumentError('data must be defined') + } + if (typeof responseOptions !== 'object') { + throw new InvalidArgumentError('responseOptions must be an object') + } + } + + /** + * Mock an undici request with a defined reply. + */ + reply(replyData) { + // Values of reply aren't available right now as they + // can only be available when the reply callback is invoked. + if (typeof replyData === 'function') { + // We'll first wrap the provided callback in another function, + // this function will properly resolve the data from the callback + // when invoked. + const wrappedDefaultsCallback = (opts) => { + // Our reply options callback contains the parameter for statusCode, data and options. + const resolvedData = replyData(opts) + + // Check if it is in the right format + if (typeof resolvedData !== 'object') { + throw new InvalidArgumentError( + 'reply options callback must return an object' + ) + } + + const { + statusCode, + data = '', + responseOptions = {}, + } = resolvedData + this.validateReplyParameters(statusCode, data, responseOptions) + // Since the values can be obtained immediately we return them + // from this higher order function that will be resolved later. + return { + ...this.createMockScopeDispatchData( + statusCode, + data, + responseOptions + ), + } + } + + // Add usual dispatch data, but this time set the data parameter to function that will eventually provide data. + const newMockDispatch = addMockDispatch( + this[kDispatches], + this[kDispatchKey], + wrappedDefaultsCallback + ) + return new MockScope(newMockDispatch) + } + + // We can have either one or three parameters, if we get here, + // we should have 1-3 parameters. So we spread the arguments of + // this function to obtain the parameters, since replyData will always + // just be the statusCode. + const [statusCode, data = '', responseOptions = {}] = [...arguments] + this.validateReplyParameters(statusCode, data, responseOptions) + + // Send in-already provided data like usual + const dispatchData = this.createMockScopeDispatchData( + statusCode, + data, + responseOptions + ) + const newMockDispatch = addMockDispatch( + this[kDispatches], + this[kDispatchKey], + dispatchData + ) + return new MockScope(newMockDispatch) + } + + /** + * Mock an undici request with a defined error. + */ + replyWithError(error) { + if (typeof error === 'undefined') { + throw new InvalidArgumentError('error must be defined') + } + + const newMockDispatch = addMockDispatch( + this[kDispatches], + this[kDispatchKey], + { error } + ) + return new MockScope(newMockDispatch) + } + + /** + * Set default reply headers on the interceptor for subsequent replies + */ + defaultReplyHeaders(headers) { + if (typeof headers === 'undefined') { + throw new InvalidArgumentError('headers must be defined') + } + + this[kDefaultHeaders] = headers + return this + } + + /** + * Set default reply trailers on the interceptor for subsequent replies + */ + defaultReplyTrailers(trailers) { + if (typeof trailers === 'undefined') { + throw new InvalidArgumentError('trailers must be defined') + } + + this[kDefaultTrailers] = trailers + return this + } + + /** + * Set reply content length header for replies on the interceptor + */ + replyContentLength() { + this[kContentLength] = true + return this + } + } + + module.exports.MockInterceptor = MockInterceptor + module.exports.MockScope = MockScope + + /***/ + }, + + /***/ 6193: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const { promisify } = __nccwpck_require__(3837) + const Pool = __nccwpck_require__(4634) + const { buildMockDispatch } = __nccwpck_require__(9323) + const { + kDispatches, + kMockAgent, + kClose, + kOriginalClose, + kOrigin, + kOriginalDispatch, + kConnected, + } = __nccwpck_require__(4347) + const { MockInterceptor } = __nccwpck_require__(410) + const Symbols = __nccwpck_require__(2785) + const { InvalidArgumentError } = __nccwpck_require__(8045) + + /** + * MockPool provides an API that extends the Pool to influence the mockDispatches. + */ + class MockPool extends Pool { + constructor(origin, opts) { + super(origin, opts) + + if ( + !opts || + !opts.agent || + typeof opts.agent.dispatch !== 'function' + ) { + throw new InvalidArgumentError( + 'Argument opts.agent must implement Agent' + ) + } + + this[kMockAgent] = opts.agent + this[kOrigin] = origin + this[kDispatches] = [] + this[kConnected] = 1 + this[kOriginalDispatch] = this.dispatch + this[kOriginalClose] = this.close.bind(this) + + this.dispatch = buildMockDispatch.call(this) + this.close = this[kClose] + } + + get [Symbols.kConnected]() { + return this[kConnected] + } + + /** + * Sets up the base interceptor for mocking replies from undici. + */ + intercept(opts) { + return new MockInterceptor(opts, this[kDispatches]) + } + + async [kClose]() { + await promisify(this[kOriginalClose])() + this[kConnected] = 0 + this[kMockAgent][Symbols.kClients].delete(this[kOrigin]) + } + } + + module.exports = MockPool + + /***/ + }, + + /***/ 4347: /***/ (module) => { + 'use strict' + + module.exports = { + kAgent: Symbol('agent'), + kOptions: Symbol('options'), + kFactory: Symbol('factory'), + kDispatches: Symbol('dispatches'), + kDispatchKey: Symbol('dispatch key'), + kDefaultHeaders: Symbol('default headers'), + kDefaultTrailers: Symbol('default trailers'), + kContentLength: Symbol('content length'), + kMockAgent: Symbol('mock agent'), + kMockAgentSet: Symbol('mock agent set'), + kMockAgentGet: Symbol('mock agent get'), + kMockDispatch: Symbol('mock dispatch'), + kClose: Symbol('close'), + kOriginalClose: Symbol('original agent close'), + kOrigin: Symbol('origin'), + kIsMockActive: Symbol('is mock active'), + kNetConnect: Symbol('net connect'), + kGetNetConnect: Symbol('get net connect'), + kConnected: Symbol('connected'), + } + + /***/ + }, + + /***/ 9323: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const { MockNotMatchedError } = __nccwpck_require__(888) + const { + kDispatches, + kMockAgent, + kOriginalDispatch, + kOrigin, + kGetNetConnect, + } = __nccwpck_require__(4347) + const { buildURL, nop } = __nccwpck_require__(3983) + const { STATUS_CODES } = __nccwpck_require__(3685) + const { + types: { isPromise }, + } = __nccwpck_require__(3837) + + function matchValue(match, value) { + if (typeof match === 'string') { + return match === value + } + if (match instanceof RegExp) { + return match.test(value) + } + if (typeof match === 'function') { + return match(value) === true + } + return false + } + + function lowerCaseEntries(headers) { + return Object.fromEntries( + Object.entries(headers).map(([headerName, headerValue]) => { + return [headerName.toLocaleLowerCase(), headerValue] + }) + ) + } + + /** + * @param {import('../../index').Headers|string[]|Record} headers + * @param {string} key + */ + function getHeaderByName(headers, key) { + if (Array.isArray(headers)) { + for (let i = 0; i < headers.length; i += 2) { + if (headers[i].toLocaleLowerCase() === key.toLocaleLowerCase()) { + return headers[i + 1] + } + } + + return undefined + } else if (typeof headers.get === 'function') { + return headers.get(key) + } else { + return lowerCaseEntries(headers)[key.toLocaleLowerCase()] + } + } + + /** @param {string[]} headers */ + function buildHeadersFromArray(headers) { + // fetch HeadersList + const clone = headers.slice() + const entries = [] + for (let index = 0; index < clone.length; index += 2) { + entries.push([clone[index], clone[index + 1]]) + } + return Object.fromEntries(entries) + } + + function matchHeaders(mockDispatch, headers) { + if (typeof mockDispatch.headers === 'function') { + if (Array.isArray(headers)) { + // fetch HeadersList + headers = buildHeadersFromArray(headers) + } + return mockDispatch.headers(headers ? lowerCaseEntries(headers) : {}) + } + if (typeof mockDispatch.headers === 'undefined') { + return true + } + if ( + typeof headers !== 'object' || + typeof mockDispatch.headers !== 'object' + ) { + return false + } + + for (const [matchHeaderName, matchHeaderValue] of Object.entries( + mockDispatch.headers + )) { + const headerValue = getHeaderByName(headers, matchHeaderName) + + if (!matchValue(matchHeaderValue, headerValue)) { + return false + } + } + return true + } + + function safeUrl(path) { + if (typeof path !== 'string') { + return path + } + + const pathSegments = path.split('?') + + if (pathSegments.length !== 2) { + return path + } + + const qp = new URLSearchParams(pathSegments.pop()) + qp.sort() + return [...pathSegments, qp.toString()].join('?') + } + + function matchKey(mockDispatch, { path, method, body, headers }) { + const pathMatch = matchValue(mockDispatch.path, path) + const methodMatch = matchValue(mockDispatch.method, method) + const bodyMatch = + typeof mockDispatch.body !== 'undefined' + ? matchValue(mockDispatch.body, body) + : true + const headersMatch = matchHeaders(mockDispatch, headers) + return pathMatch && methodMatch && bodyMatch && headersMatch + } + + function getResponseData(data) { + if (Buffer.isBuffer(data)) { + return data + } else if (typeof data === 'object') { + return JSON.stringify(data) + } else { + return data.toString() + } + } + + function getMockDispatch(mockDispatches, key) { + const basePath = key.query ? buildURL(key.path, key.query) : key.path + const resolvedPath = + typeof basePath === 'string' ? safeUrl(basePath) : basePath + + // Match path + let matchedMockDispatches = mockDispatches + .filter(({ consumed }) => !consumed) + .filter(({ path }) => matchValue(safeUrl(path), resolvedPath)) + if (matchedMockDispatches.length === 0) { + throw new MockNotMatchedError( + `Mock dispatch not matched for path '${resolvedPath}'` + ) + } + + // Match method + matchedMockDispatches = matchedMockDispatches.filter(({ method }) => + matchValue(method, key.method) + ) + if (matchedMockDispatches.length === 0) { + throw new MockNotMatchedError( + `Mock dispatch not matched for method '${key.method}'` + ) + } + + // Match body + matchedMockDispatches = matchedMockDispatches.filter(({ body }) => + typeof body !== 'undefined' ? matchValue(body, key.body) : true + ) + if (matchedMockDispatches.length === 0) { + throw new MockNotMatchedError( + `Mock dispatch not matched for body '${key.body}'` + ) + } + + // Match headers + matchedMockDispatches = matchedMockDispatches.filter((mockDispatch) => + matchHeaders(mockDispatch, key.headers) + ) + if (matchedMockDispatches.length === 0) { + throw new MockNotMatchedError( + `Mock dispatch not matched for headers '${ + typeof key.headers === 'object' + ? JSON.stringify(key.headers) + : key.headers + }'` + ) + } + + return matchedMockDispatches[0] + } + + function addMockDispatch(mockDispatches, key, data) { + const baseData = { + timesInvoked: 0, + times: 1, + persist: false, + consumed: false, + } + const replyData = + typeof data === 'function' ? { callback: data } : { ...data } + const newMockDispatch = { + ...baseData, + ...key, + pending: true, + data: { error: null, ...replyData }, + } + mockDispatches.push(newMockDispatch) + return newMockDispatch + } + + function deleteMockDispatch(mockDispatches, key) { + const index = mockDispatches.findIndex((dispatch) => { + if (!dispatch.consumed) { + return false + } + return matchKey(dispatch, key) + }) + if (index !== -1) { + mockDispatches.splice(index, 1) + } + } + + function buildKey(opts) { + const { path, method, body, headers, query } = opts + return { + path, + method, + body, + headers, + query, + } + } + + function generateKeyValues(data) { + return Object.entries(data).reduce( + (keyValuePairs, [key, value]) => [ + ...keyValuePairs, + Buffer.from(`${key}`), + Array.isArray(value) + ? value.map((x) => Buffer.from(`${x}`)) + : Buffer.from(`${value}`), + ], + [] + ) + } + + /** + * @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Status + * @param {number} statusCode + */ + function getStatusText(statusCode) { + return STATUS_CODES[statusCode] || 'unknown' + } + + async function getResponse(body) { + const buffers = [] + for await (const data of body) { + buffers.push(data) + } + return Buffer.concat(buffers).toString('utf8') + } + + /** + * Mock dispatch function used to simulate undici dispatches + */ + function mockDispatch(opts, handler) { + // Get mock dispatch from built key + const key = buildKey(opts) + const mockDispatch = getMockDispatch(this[kDispatches], key) + + mockDispatch.timesInvoked++ + + // Here's where we resolve a callback if a callback is present for the dispatch data. + if (mockDispatch.data.callback) { + mockDispatch.data = { + ...mockDispatch.data, + ...mockDispatch.data.callback(opts), + } + } + + // Parse mockDispatch data + const { + data: { statusCode, data, headers, trailers, error }, + delay, + persist, + } = mockDispatch + const { timesInvoked, times } = mockDispatch + + // If it's used up and not persistent, mark as consumed + mockDispatch.consumed = !persist && timesInvoked >= times + mockDispatch.pending = timesInvoked < times + + // If specified, trigger dispatch error + if (error !== null) { + deleteMockDispatch(this[kDispatches], key) + handler.onError(error) + return true + } + + // Handle the request with a delay if necessary + if (typeof delay === 'number' && delay > 0) { + setTimeout(() => { + handleReply(this[kDispatches]) + }, delay) + } else { + handleReply(this[kDispatches]) + } + + function handleReply(mockDispatches, _data = data) { + // fetch's HeadersList is a 1D string array + const optsHeaders = Array.isArray(opts.headers) + ? buildHeadersFromArray(opts.headers) + : opts.headers + const body = + typeof _data === 'function' + ? _data({ ...opts, headers: optsHeaders }) + : _data + + // util.types.isPromise is likely needed for jest. + if (isPromise(body)) { + // If handleReply is asynchronous, throwing an error + // in the callback will reject the promise, rather than + // synchronously throw the error, which breaks some tests. + // Rather, we wait for the callback to resolve if it is a + // promise, and then re-run handleReply with the new body. + body.then((newData) => handleReply(mockDispatches, newData)) + return + } + + const responseData = getResponseData(body) + const responseHeaders = generateKeyValues(headers) + const responseTrailers = generateKeyValues(trailers) + + handler.abort = nop + handler.onHeaders( + statusCode, + responseHeaders, + resume, + getStatusText(statusCode) + ) + handler.onData(Buffer.from(responseData)) + handler.onComplete(responseTrailers) + deleteMockDispatch(mockDispatches, key) + } + + function resume() {} + + return true + } + + function buildMockDispatch() { + const agent = this[kMockAgent] + const origin = this[kOrigin] + const originalDispatch = this[kOriginalDispatch] + + return function dispatch(opts, handler) { + if (agent.isMockActive) { + try { + mockDispatch.call(this, opts, handler) + } catch (error) { + if (error instanceof MockNotMatchedError) { + const netConnect = agent[kGetNetConnect]() + if (netConnect === false) { + throw new MockNotMatchedError( + `${error.message}: subsequent request to origin ${origin} was not allowed (net.connect disabled)` + ) + } + if (checkNetConnect(netConnect, origin)) { + originalDispatch.call(this, opts, handler) + } else { + throw new MockNotMatchedError( + `${error.message}: subsequent request to origin ${origin} was not allowed (net.connect is not enabled for this origin)` + ) + } + } else { + throw error + } + } + } else { + originalDispatch.call(this, opts, handler) + } + } + } + + function checkNetConnect(netConnect, origin) { + const url = new URL(origin) + if (netConnect === true) { + return true + } else if ( + Array.isArray(netConnect) && + netConnect.some((matcher) => matchValue(matcher, url.host)) + ) { + return true + } + return false + } + + function buildMockOptions(opts) { + if (opts) { + const { agent, ...mockOptions } = opts + return mockOptions + } + } + + module.exports = { + getResponseData, + getMockDispatch, + addMockDispatch, + deleteMockDispatch, + buildKey, + generateKeyValues, + matchValue, + getResponse, + getStatusText, + mockDispatch, + buildMockDispatch, + checkNetConnect, + buildMockOptions, + getHeaderByName, + } + + /***/ + }, + + /***/ 6823: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const { Transform } = __nccwpck_require__(2781) + const { Console } = __nccwpck_require__(6206) + + /** + * Gets the output of `console.table(…)` as a string. + */ + module.exports = class PendingInterceptorsFormatter { + constructor({ disableColors } = {}) { + this.transform = new Transform({ + transform(chunk, _enc, cb) { + cb(null, chunk) + }, + }) + + this.logger = new Console({ + stdout: this.transform, + inspectOptions: { + colors: !disableColors && !process.env.CI, + }, + }) + } + + format(pendingInterceptors) { + const withPrettyHeaders = pendingInterceptors.map( + ({ + method, + path, + data: { statusCode }, + persist, + times, + timesInvoked, + origin, + }) => ({ + Method: method, + Origin: origin, + Path: path, + 'Status code': statusCode, + Persistent: persist ? '✅' : '❌', + Invocations: timesInvoked, + Remaining: persist ? Infinity : times - timesInvoked, + }) + ) + + this.logger.table(withPrettyHeaders) + return this.transform.read().toString() + } + } + + /***/ + }, + + /***/ 8891: /***/ (module) => { + 'use strict' + + const singulars = { + pronoun: 'it', + is: 'is', + was: 'was', + this: 'this', + } + + const plurals = { + pronoun: 'they', + is: 'are', + was: 'were', + this: 'these', + } + + module.exports = class Pluralizer { + constructor(singular, plural) { + this.singular = singular + this.plural = plural + } + + pluralize(count) { + const one = count === 1 + const keys = one ? singulars : plurals + const noun = one ? this.singular : this.plural + return { ...keys, count, noun } + } + } + + /***/ + }, + + /***/ 8266: /***/ (module) => { + 'use strict' + /* eslint-disable */ + + // Extracted from node/lib/internal/fixed_queue.js + + // Currently optimal queue size, tested on V8 6.0 - 6.6. Must be power of two. + const kSize = 2048 + const kMask = kSize - 1 + + // The FixedQueue is implemented as a singly-linked list of fixed-size + // circular buffers. It looks something like this: + // + // head tail + // | | + // v v + // +-----------+ <-----\ +-----------+ <------\ +-----------+ + // | [null] | \----- | next | \------- | next | + // +-----------+ +-----------+ +-----------+ + // | item | <-- bottom | item | <-- bottom | [empty] | + // | item | | item | | [empty] | + // | item | | item | | [empty] | + // | item | | item | | [empty] | + // | item | | item | bottom --> | item | + // | item | | item | | item | + // | ... | | ... | | ... | + // | item | | item | | item | + // | item | | item | | item | + // | [empty] | <-- top | item | | item | + // | [empty] | | item | | item | + // | [empty] | | [empty] | <-- top top --> | [empty] | + // +-----------+ +-----------+ +-----------+ + // + // Or, if there is only one circular buffer, it looks something + // like either of these: + // + // head tail head tail + // | | | | + // v v v v + // +-----------+ +-----------+ + // | [null] | | [null] | + // +-----------+ +-----------+ + // | [empty] | | item | + // | [empty] | | item | + // | item | <-- bottom top --> | [empty] | + // | item | | [empty] | + // | [empty] | <-- top bottom --> | item | + // | [empty] | | item | + // +-----------+ +-----------+ + // + // Adding a value means moving `top` forward by one, removing means + // moving `bottom` forward by one. After reaching the end, the queue + // wraps around. + // + // When `top === bottom` the current queue is empty and when + // `top + 1 === bottom` it's full. This wastes a single space of storage + // but allows much quicker checks. + + class FixedCircularBuffer { + constructor() { + this.bottom = 0 + this.top = 0 + this.list = new Array(kSize) + this.next = null + } + + isEmpty() { + return this.top === this.bottom + } + + isFull() { + return ((this.top + 1) & kMask) === this.bottom + } + + push(data) { + this.list[this.top] = data + this.top = (this.top + 1) & kMask + } + + shift() { + const nextItem = this.list[this.bottom] + if (nextItem === undefined) return null + this.list[this.bottom] = undefined + this.bottom = (this.bottom + 1) & kMask + return nextItem + } + } + + module.exports = class FixedQueue { + constructor() { + this.head = this.tail = new FixedCircularBuffer() + } + + isEmpty() { + return this.head.isEmpty() + } + + push(data) { + if (this.head.isFull()) { + // Head is full: Creates a new queue, sets the old queue's `.next` to it, + // and sets it as the new main queue. + this.head = this.head.next = new FixedCircularBuffer() + } + this.head.push(data) + } + + shift() { + const tail = this.tail + const next = tail.shift() + if (tail.isEmpty() && tail.next !== null) { + // If there is another queue, it forms the new tail. + this.tail = tail.next + } + return next + } + } + + /***/ + }, + + /***/ 3198: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const DispatcherBase = __nccwpck_require__(4839) + const FixedQueue = __nccwpck_require__(8266) + const { + kConnected, + kSize, + kRunning, + kPending, + kQueued, + kBusy, + kFree, + kUrl, + kClose, + kDestroy, + kDispatch, + } = __nccwpck_require__(2785) + const PoolStats = __nccwpck_require__(9689) + + const kClients = Symbol('clients') + const kNeedDrain = Symbol('needDrain') + const kQueue = Symbol('queue') + const kClosedResolve = Symbol('closed resolve') + const kOnDrain = Symbol('onDrain') + const kOnConnect = Symbol('onConnect') + const kOnDisconnect = Symbol('onDisconnect') + const kOnConnectionError = Symbol('onConnectionError') + const kGetDispatcher = Symbol('get dispatcher') + const kAddClient = Symbol('add client') + const kRemoveClient = Symbol('remove client') + const kStats = Symbol('stats') + + class PoolBase extends DispatcherBase { + constructor() { + super() + + this[kQueue] = new FixedQueue() + this[kClients] = [] + this[kQueued] = 0 + + const pool = this + + this[kOnDrain] = function onDrain(origin, targets) { + const queue = pool[kQueue] + + let needDrain = false + + while (!needDrain) { + const item = queue.shift() + if (!item) { + break + } + pool[kQueued]-- + needDrain = !this.dispatch(item.opts, item.handler) + } + + this[kNeedDrain] = needDrain + + if (!this[kNeedDrain] && pool[kNeedDrain]) { + pool[kNeedDrain] = false + pool.emit('drain', origin, [pool, ...targets]) + } + + if (pool[kClosedResolve] && queue.isEmpty()) { + Promise.all(pool[kClients].map((c) => c.close())).then( + pool[kClosedResolve] + ) + } + } + + this[kOnConnect] = (origin, targets) => { + pool.emit('connect', origin, [pool, ...targets]) + } + + this[kOnDisconnect] = (origin, targets, err) => { + pool.emit('disconnect', origin, [pool, ...targets], err) + } + + this[kOnConnectionError] = (origin, targets, err) => { + pool.emit('connectionError', origin, [pool, ...targets], err) + } + + this[kStats] = new PoolStats(this) + } + + get [kBusy]() { + return this[kNeedDrain] + } + + get [kConnected]() { + return this[kClients].filter((client) => client[kConnected]).length + } + + get [kFree]() { + return this[kClients].filter( + (client) => client[kConnected] && !client[kNeedDrain] + ).length + } + + get [kPending]() { + let ret = this[kQueued] + for (const { [kPending]: pending } of this[kClients]) { + ret += pending + } + return ret + } + + get [kRunning]() { + let ret = 0 + for (const { [kRunning]: running } of this[kClients]) { + ret += running + } + return ret + } + + get [kSize]() { + let ret = this[kQueued] + for (const { [kSize]: size } of this[kClients]) { + ret += size + } + return ret + } + + get stats() { + return this[kStats] + } + + async [kClose]() { + if (this[kQueue].isEmpty()) { + return Promise.all(this[kClients].map((c) => c.close())) + } else { + return new Promise((resolve) => { + this[kClosedResolve] = resolve + }) + } + } + + async [kDestroy](err) { + while (true) { + const item = this[kQueue].shift() + if (!item) { + break + } + item.handler.onError(err) + } + + return Promise.all(this[kClients].map((c) => c.destroy(err))) + } + + [kDispatch](opts, handler) { + const dispatcher = this[kGetDispatcher]() + + if (!dispatcher) { + this[kNeedDrain] = true + this[kQueue].push({ opts, handler }) + this[kQueued]++ + } else if (!dispatcher.dispatch(opts, handler)) { + dispatcher[kNeedDrain] = true + this[kNeedDrain] = !this[kGetDispatcher]() + } + + return !this[kNeedDrain] + } + + [kAddClient](client) { + client + .on('drain', this[kOnDrain]) + .on('connect', this[kOnConnect]) + .on('disconnect', this[kOnDisconnect]) + .on('connectionError', this[kOnConnectionError]) + + this[kClients].push(client) + + if (this[kNeedDrain]) { + process.nextTick(() => { + if (this[kNeedDrain]) { + this[kOnDrain](client[kUrl], [this, client]) + } + }) + } + + return this + } + + [kRemoveClient](client) { + client.close(() => { + const idx = this[kClients].indexOf(client) + if (idx !== -1) { + this[kClients].splice(idx, 1) + } + }) + + this[kNeedDrain] = this[kClients].some( + (dispatcher) => + !dispatcher[kNeedDrain] && + dispatcher.closed !== true && + dispatcher.destroyed !== true + ) + } + } + + module.exports = { + PoolBase, + kClients, + kNeedDrain, + kAddClient, + kRemoveClient, + kGetDispatcher, + } + + /***/ + }, + + /***/ 9689: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + const { kFree, kConnected, kPending, kQueued, kRunning, kSize } = + __nccwpck_require__(2785) + const kPool = Symbol('pool') + + class PoolStats { + constructor(pool) { + this[kPool] = pool + } + + get connected() { + return this[kPool][kConnected] + } + + get free() { + return this[kPool][kFree] + } + + get pending() { + return this[kPool][kPending] + } + + get queued() { + return this[kPool][kQueued] + } + + get running() { + return this[kPool][kRunning] + } + + get size() { + return this[kPool][kSize] + } + } + + module.exports = PoolStats + + /***/ + }, + + /***/ 4634: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const { PoolBase, kClients, kNeedDrain, kAddClient, kGetDispatcher } = + __nccwpck_require__(3198) + const Client = __nccwpck_require__(3598) + const { InvalidArgumentError } = __nccwpck_require__(8045) + const util = __nccwpck_require__(3983) + const { kUrl, kInterceptors } = __nccwpck_require__(2785) + const buildConnector = __nccwpck_require__(2067) + + const kOptions = Symbol('options') + const kConnections = Symbol('connections') + const kFactory = Symbol('factory') + + function defaultFactory(origin, opts) { + return new Client(origin, opts) + } + + class Pool extends PoolBase { + constructor( + origin, + { + connections, + factory = defaultFactory, + connect, + connectTimeout, + tls, + maxCachedSessions, + socketPath, + autoSelectFamily, + autoSelectFamilyAttemptTimeout, + allowH2, + ...options + } = {} + ) { + super() + + if ( + connections != null && + (!Number.isFinite(connections) || connections < 0) + ) { + throw new InvalidArgumentError('invalid connections') + } + + if (typeof factory !== 'function') { + throw new InvalidArgumentError('factory must be a function.') + } + + if ( + connect != null && + typeof connect !== 'function' && + typeof connect !== 'object' + ) { + throw new InvalidArgumentError( + 'connect must be a function or an object' + ) + } + + if (typeof connect !== 'function') { + connect = buildConnector({ + ...tls, + maxCachedSessions, + allowH2, + socketPath, + timeout: connectTimeout, + ...(util.nodeHasAutoSelectFamily && autoSelectFamily + ? { autoSelectFamily, autoSelectFamilyAttemptTimeout } + : undefined), + ...connect, + }) + } + + this[kInterceptors] = + options.interceptors && + options.interceptors.Pool && + Array.isArray(options.interceptors.Pool) + ? options.interceptors.Pool + : [] + this[kConnections] = connections || null + this[kUrl] = util.parseOrigin(origin) + this[kOptions] = { ...util.deepClone(options), connect, allowH2 } + this[kOptions].interceptors = options.interceptors + ? { ...options.interceptors } + : undefined + this[kFactory] = factory + } + + [kGetDispatcher]() { + let dispatcher = this[kClients].find( + (dispatcher) => !dispatcher[kNeedDrain] + ) + + if (dispatcher) { + return dispatcher + } + + if ( + !this[kConnections] || + this[kClients].length < this[kConnections] + ) { + dispatcher = this[kFactory](this[kUrl], this[kOptions]) + this[kAddClient](dispatcher) + } + + return dispatcher + } + } + + module.exports = Pool + + /***/ + }, + + /***/ 7858: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const { kProxy, kClose, kDestroy, kInterceptors } = + __nccwpck_require__(2785) + const { URL } = __nccwpck_require__(7310) + const Agent = __nccwpck_require__(7890) + const Pool = __nccwpck_require__(4634) + const DispatcherBase = __nccwpck_require__(4839) + const { InvalidArgumentError, RequestAbortedError } = + __nccwpck_require__(8045) + const buildConnector = __nccwpck_require__(2067) + + const kAgent = Symbol('proxy agent') + const kClient = Symbol('proxy client') + const kProxyHeaders = Symbol('proxy headers') + const kRequestTls = Symbol('request tls settings') + const kProxyTls = Symbol('proxy tls settings') + const kConnectEndpoint = Symbol('connect endpoint function') + + function defaultProtocolPort(protocol) { + return protocol === 'https:' ? 443 : 80 + } + + function buildProxyOptions(opts) { + if (typeof opts === 'string') { + opts = { uri: opts } + } + + if (!opts || !opts.uri) { + throw new InvalidArgumentError('Proxy opts.uri is mandatory') + } + + return { + uri: opts.uri, + protocol: opts.protocol || 'https', + } + } + + function defaultFactory(origin, opts) { + return new Pool(origin, opts) + } + + class ProxyAgent extends DispatcherBase { + constructor(opts) { + super(opts) + this[kProxy] = buildProxyOptions(opts) + this[kAgent] = new Agent(opts) + this[kInterceptors] = + opts.interceptors && + opts.interceptors.ProxyAgent && + Array.isArray(opts.interceptors.ProxyAgent) + ? opts.interceptors.ProxyAgent + : [] + + if (typeof opts === 'string') { + opts = { uri: opts } + } + + if (!opts || !opts.uri) { + throw new InvalidArgumentError('Proxy opts.uri is mandatory') + } + + const { clientFactory = defaultFactory } = opts + + if (typeof clientFactory !== 'function') { + throw new InvalidArgumentError( + 'Proxy opts.clientFactory must be a function.' + ) + } + + this[kRequestTls] = opts.requestTls + this[kProxyTls] = opts.proxyTls + this[kProxyHeaders] = opts.headers || {} + + if (opts.auth && opts.token) { + throw new InvalidArgumentError( + 'opts.auth cannot be used in combination with opts.token' + ) + } else if (opts.auth) { + /* @deprecated in favour of opts.token */ + this[kProxyHeaders]['proxy-authorization'] = `Basic ${opts.auth}` + } else if (opts.token) { + this[kProxyHeaders]['proxy-authorization'] = opts.token + } + + const resolvedUrl = new URL(opts.uri) + const { origin, port, host } = resolvedUrl + + const connect = buildConnector({ ...opts.proxyTls }) + this[kConnectEndpoint] = buildConnector({ ...opts.requestTls }) + this[kClient] = clientFactory(resolvedUrl, { connect }) + this[kAgent] = new Agent({ + ...opts, + connect: async (opts, callback) => { + let requestedHost = opts.host + if (!opts.port) { + requestedHost += `:${defaultProtocolPort(opts.protocol)}` + } + try { + const { socket, statusCode } = await this[kClient].connect({ + origin, + port, + path: requestedHost, + signal: opts.signal, + headers: { + ...this[kProxyHeaders], + host, + }, + }) + if (statusCode !== 200) { + socket.on('error', () => {}).destroy() + callback( + new RequestAbortedError( + 'Proxy response !== 200 when HTTP Tunneling' + ) + ) + } + if (opts.protocol !== 'https:') { + callback(null, socket) + return + } + let servername + if (this[kRequestTls]) { + servername = this[kRequestTls].servername + } else { + servername = opts.servername + } + this[kConnectEndpoint]( + { ...opts, servername, httpSocket: socket }, + callback + ) + } catch (err) { + callback(err) + } + }, + }) + } + + dispatch(opts, handler) { + const { host } = new URL(opts.origin) + const headers = buildHeaders(opts.headers) + throwIfProxyAuthIsSent(headers) + return this[kAgent].dispatch( + { + ...opts, + headers: { + ...headers, + host, + }, + }, + handler + ) + } + + async [kClose]() { + await this[kAgent].close() + await this[kClient].close() + } + + async [kDestroy]() { + await this[kAgent].destroy() + await this[kClient].destroy() + } + } + + /** + * @param {string[] | Record} headers + * @returns {Record} + */ + function buildHeaders(headers) { + // When using undici.fetch, the headers list is stored + // as an array. + if (Array.isArray(headers)) { + /** @type {Record} */ + const headersPair = {} + + for (let i = 0; i < headers.length; i += 2) { + headersPair[headers[i]] = headers[i + 1] + } + + return headersPair + } + + return headers + } + + /** + * @param {Record} headers + * + * Previous versions of ProxyAgent suggests the Proxy-Authorization in request headers + * Nevertheless, it was changed and to avoid a security vulnerability by end users + * this check was created. + * It should be removed in the next major version for performance reasons + */ + function throwIfProxyAuthIsSent(headers) { + const existProxyAuth = + headers && + Object.keys(headers).find( + (key) => key.toLowerCase() === 'proxy-authorization' + ) + if (existProxyAuth) { + throw new InvalidArgumentError( + 'Proxy-Authorization should be sent in ProxyAgent constructor' + ) + } + } + + module.exports = ProxyAgent + + /***/ + }, + + /***/ 9459: /***/ (module) => { + 'use strict' + + let fastNow = Date.now() + let fastNowTimeout + + const fastTimers = [] + + function onTimeout() { + fastNow = Date.now() + + let len = fastTimers.length + let idx = 0 + while (idx < len) { + const timer = fastTimers[idx] + + if (timer.state === 0) { + timer.state = fastNow + timer.delay + } else if (timer.state > 0 && fastNow >= timer.state) { + timer.state = -1 + timer.callback(timer.opaque) + } + + if (timer.state === -1) { + timer.state = -2 + if (idx !== len - 1) { + fastTimers[idx] = fastTimers.pop() + } else { + fastTimers.pop() + } + len -= 1 + } else { + idx += 1 + } + } + + if (fastTimers.length > 0) { + refreshTimeout() + } + } + + function refreshTimeout() { + if (fastNowTimeout && fastNowTimeout.refresh) { + fastNowTimeout.refresh() + } else { + clearTimeout(fastNowTimeout) + fastNowTimeout = setTimeout(onTimeout, 1e3) + if (fastNowTimeout.unref) { + fastNowTimeout.unref() + } + } + } + + class Timeout { + constructor(callback, delay, opaque) { + this.callback = callback + this.delay = delay + this.opaque = opaque + + // -2 not in timer list + // -1 in timer list but inactive + // 0 in timer list waiting for time + // > 0 in timer list waiting for time to expire + this.state = -2 + + this.refresh() + } + + refresh() { + if (this.state === -2) { + fastTimers.push(this) + if (!fastNowTimeout || fastTimers.length === 1) { + refreshTimeout() + } + } + + this.state = 0 + } + + clear() { + this.state = -1 + } + } + + module.exports = { + setTimeout(callback, delay, opaque) { + return delay < 1e3 + ? setTimeout(callback, delay, opaque) + : new Timeout(callback, delay, opaque) + }, + clearTimeout(timeout) { + if (timeout instanceof Timeout) { + timeout.clear() + } else { + clearTimeout(timeout) + } + }, + } + + /***/ + }, + + /***/ 5354: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const diagnosticsChannel = __nccwpck_require__(7643) + const { uid, states } = __nccwpck_require__(9188) + const { kReadyState, kSentClose, kByteParser, kReceivedClose } = + __nccwpck_require__(7578) + const { fireEvent, failWebsocketConnection } = __nccwpck_require__(5515) + const { CloseEvent } = __nccwpck_require__(2611) + const { makeRequest } = __nccwpck_require__(8359) + const { fetching } = __nccwpck_require__(4881) + const { Headers } = __nccwpck_require__(554) + const { getGlobalDispatcher } = __nccwpck_require__(1892) + const { kHeadersList } = __nccwpck_require__(2785) + + const channels = {} + channels.open = diagnosticsChannel.channel('undici:websocket:open') + channels.close = diagnosticsChannel.channel('undici:websocket:close') + channels.socketError = diagnosticsChannel.channel( + 'undici:websocket:socket_error' + ) + + /** @type {import('crypto')} */ + let crypto + try { + crypto = __nccwpck_require__(6113) + } catch {} + + /** + * @see https://websockets.spec.whatwg.org/#concept-websocket-establish + * @param {URL} url + * @param {string|string[]} protocols + * @param {import('./websocket').WebSocket} ws + * @param {(response: any) => void} onEstablish + * @param {Partial} options + */ + function establishWebSocketConnection( + url, + protocols, + ws, + onEstablish, + options + ) { + // 1. Let requestURL be a copy of url, with its scheme set to "http", if url’s + // scheme is "ws", and to "https" otherwise. + const requestURL = url + + requestURL.protocol = url.protocol === 'ws:' ? 'http:' : 'https:' + + // 2. Let request be a new request, whose URL is requestURL, client is client, + // service-workers mode is "none", referrer is "no-referrer", mode is + // "websocket", credentials mode is "include", cache mode is "no-store" , + // and redirect mode is "error". + const request = makeRequest({ + urlList: [requestURL], + serviceWorkers: 'none', + referrer: 'no-referrer', + mode: 'websocket', + credentials: 'include', + cache: 'no-store', + redirect: 'error', + }) + + // Note: undici extension, allow setting custom headers. + if (options.headers) { + const headersList = new Headers(options.headers)[kHeadersList] + + request.headersList = headersList + } + + // 3. Append (`Upgrade`, `websocket`) to request’s header list. + // 4. Append (`Connection`, `Upgrade`) to request’s header list. + // Note: both of these are handled by undici currently. + // https://github.com/nodejs/undici/blob/68c269c4144c446f3f1220951338daef4a6b5ec4/lib/client.js#L1397 + + // 5. Let keyValue be a nonce consisting of a randomly selected + // 16-byte value that has been forgiving-base64-encoded and + // isomorphic encoded. + const keyValue = crypto.randomBytes(16).toString('base64') + + // 6. Append (`Sec-WebSocket-Key`, keyValue) to request’s + // header list. + request.headersList.append('sec-websocket-key', keyValue) + + // 7. Append (`Sec-WebSocket-Version`, `13`) to request’s + // header list. + request.headersList.append('sec-websocket-version', '13') + + // 8. For each protocol in protocols, combine + // (`Sec-WebSocket-Protocol`, protocol) in request’s header + // list. + for (const protocol of protocols) { + request.headersList.append('sec-websocket-protocol', protocol) + } + + // 9. Let permessageDeflate be a user-agent defined + // "permessage-deflate" extension header value. + // https://github.com/mozilla/gecko-dev/blob/ce78234f5e653a5d3916813ff990f053510227bc/netwerk/protocol/websocket/WebSocketChannel.cpp#L2673 + // TODO: enable once permessage-deflate is supported + const permessageDeflate = '' // 'permessage-deflate; 15' + + // 10. Append (`Sec-WebSocket-Extensions`, permessageDeflate) to + // request’s header list. + // request.headersList.append('sec-websocket-extensions', permessageDeflate) + + // 11. Fetch request with useParallelQueue set to true, and + // processResponse given response being these steps: + const controller = fetching({ + request, + useParallelQueue: true, + dispatcher: options.dispatcher ?? getGlobalDispatcher(), + processResponse(response) { + // 1. If response is a network error or its status is not 101, + // fail the WebSocket connection. + if (response.type === 'error' || response.status !== 101) { + failWebsocketConnection( + ws, + 'Received network error or non-101 status code.' + ) + return + } + + // 2. If protocols is not the empty list and extracting header + // list values given `Sec-WebSocket-Protocol` and response’s + // header list results in null, failure, or the empty byte + // sequence, then fail the WebSocket connection. + if ( + protocols.length !== 0 && + !response.headersList.get('Sec-WebSocket-Protocol') + ) { + failWebsocketConnection( + ws, + 'Server did not respond with sent protocols.' + ) + return + } + + // 3. Follow the requirements stated step 2 to step 6, inclusive, + // of the last set of steps in section 4.1 of The WebSocket + // Protocol to validate response. This either results in fail + // the WebSocket connection or the WebSocket connection is + // established. + + // 2. If the response lacks an |Upgrade| header field or the |Upgrade| + // header field contains a value that is not an ASCII case- + // insensitive match for the value "websocket", the client MUST + // _Fail the WebSocket Connection_. + if ( + response.headersList.get('Upgrade')?.toLowerCase() !== 'websocket' + ) { + failWebsocketConnection( + ws, + 'Server did not set Upgrade header to "websocket".' + ) + return + } + + // 3. If the response lacks a |Connection| header field or the + // |Connection| header field doesn't contain a token that is an + // ASCII case-insensitive match for the value "Upgrade", the client + // MUST _Fail the WebSocket Connection_. + if ( + response.headersList.get('Connection')?.toLowerCase() !== + 'upgrade' + ) { + failWebsocketConnection( + ws, + 'Server did not set Connection header to "upgrade".' + ) + return + } + + // 4. If the response lacks a |Sec-WebSocket-Accept| header field or + // the |Sec-WebSocket-Accept| contains a value other than the + // base64-encoded SHA-1 of the concatenation of the |Sec-WebSocket- + // Key| (as a string, not base64-decoded) with the string "258EAFA5- + // E914-47DA-95CA-C5AB0DC85B11" but ignoring any leading and + // trailing whitespace, the client MUST _Fail the WebSocket + // Connection_. + const secWSAccept = response.headersList.get('Sec-WebSocket-Accept') + const digest = crypto + .createHash('sha1') + .update(keyValue + uid) + .digest('base64') + if (secWSAccept !== digest) { + failWebsocketConnection( + ws, + 'Incorrect hash received in Sec-WebSocket-Accept header.' + ) + return + } + + // 5. If the response includes a |Sec-WebSocket-Extensions| header + // field and this header field indicates the use of an extension + // that was not present in the client's handshake (the server has + // indicated an extension not requested by the client), the client + // MUST _Fail the WebSocket Connection_. (The parsing of this + // header field to determine which extensions are requested is + // discussed in Section 9.1.) + const secExtension = response.headersList.get( + 'Sec-WebSocket-Extensions' + ) + + if (secExtension !== null && secExtension !== permessageDeflate) { + failWebsocketConnection( + ws, + 'Received different permessage-deflate than the one set.' + ) + return + } + + // 6. If the response includes a |Sec-WebSocket-Protocol| header field + // and this header field indicates the use of a subprotocol that was + // not present in the client's handshake (the server has indicated a + // subprotocol not requested by the client), the client MUST _Fail + // the WebSocket Connection_. + const secProtocol = response.headersList.get( + 'Sec-WebSocket-Protocol' + ) + + if ( + secProtocol !== null && + secProtocol !== request.headersList.get('Sec-WebSocket-Protocol') + ) { + failWebsocketConnection( + ws, + 'Protocol was not set in the opening handshake.' + ) + return + } + + response.socket.on('data', onSocketData) + response.socket.on('close', onSocketClose) + response.socket.on('error', onSocketError) + + if (channels.open.hasSubscribers) { + channels.open.publish({ + address: response.socket.address(), + protocol: secProtocol, + extensions: secExtension, + }) + } + + onEstablish(response) + }, + }) + + return controller + } + + /** + * @param {Buffer} chunk + */ + function onSocketData(chunk) { + if (!this.ws[kByteParser].write(chunk)) { + this.pause() + } + } + + /** + * @see https://websockets.spec.whatwg.org/#feedback-from-the-protocol + * @see https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.4 + */ + function onSocketClose() { + const { ws } = this + + // If the TCP connection was closed after the + // WebSocket closing handshake was completed, the WebSocket connection + // is said to have been closed _cleanly_. + const wasClean = ws[kSentClose] && ws[kReceivedClose] + + let code = 1005 + let reason = '' + + const result = ws[kByteParser].closingInfo + + if (result) { + code = result.code ?? 1005 + reason = result.reason + } else if (!ws[kSentClose]) { + // If _The WebSocket + // Connection is Closed_ and no Close control frame was received by the + // endpoint (such as could occur if the underlying transport connection + // is lost), _The WebSocket Connection Close Code_ is considered to be + // 1006. + code = 1006 + } + + // 1. Change the ready state to CLOSED (3). + ws[kReadyState] = states.CLOSED + + // 2. If the user agent was required to fail the WebSocket + // connection, or if the WebSocket connection was closed + // after being flagged as full, fire an event named error + // at the WebSocket object. + // TODO + + // 3. Fire an event named close at the WebSocket object, + // using CloseEvent, with the wasClean attribute + // initialized to true if the connection closed cleanly + // and false otherwise, the code attribute initialized to + // the WebSocket connection close code, and the reason + // attribute initialized to the result of applying UTF-8 + // decode without BOM to the WebSocket connection close + // reason. + fireEvent('close', ws, CloseEvent, { + wasClean, + code, + reason, + }) + + if (channels.close.hasSubscribers) { + channels.close.publish({ + websocket: ws, + code, + reason, + }) + } + } + + function onSocketError(error) { + const { ws } = this + + ws[kReadyState] = states.CLOSING + + if (channels.socketError.hasSubscribers) { + channels.socketError.publish(error) + } + + this.destroy() + } + + module.exports = { + establishWebSocketConnection, + } + + /***/ + }, + + /***/ 9188: /***/ (module) => { + 'use strict' + + // This is a Globally Unique Identifier unique used + // to validate that the endpoint accepts websocket + // connections. + // See https://www.rfc-editor.org/rfc/rfc6455.html#section-1.3 + const uid = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11' + + /** @type {PropertyDescriptor} */ + const staticPropertyDescriptors = { + enumerable: true, + writable: false, + configurable: false, + } + + const states = { + CONNECTING: 0, + OPEN: 1, + CLOSING: 2, + CLOSED: 3, + } + + const opcodes = { + CONTINUATION: 0x0, + TEXT: 0x1, + BINARY: 0x2, + CLOSE: 0x8, + PING: 0x9, + PONG: 0xa, + } + + const maxUnsigned16Bit = 2 ** 16 - 1 // 65535 + + const parserStates = { + INFO: 0, + PAYLOADLENGTH_16: 2, + PAYLOADLENGTH_64: 3, + READ_DATA: 4, + } + + const emptyBuffer = Buffer.allocUnsafe(0) + + module.exports = { + uid, + staticPropertyDescriptors, + states, + opcodes, + maxUnsigned16Bit, + parserStates, + emptyBuffer, + } + + /***/ + }, + + /***/ 2611: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const { webidl } = __nccwpck_require__(1744) + const { kEnumerableProperty } = __nccwpck_require__(3983) + const { MessagePort } = __nccwpck_require__(1267) + + /** + * @see https://html.spec.whatwg.org/multipage/comms.html#messageevent + */ + class MessageEvent extends Event { + #eventInit + + constructor(type, eventInitDict = {}) { + webidl.argumentLengthCheck(arguments, 1, { + header: 'MessageEvent constructor', + }) + + type = webidl.converters.DOMString(type) + eventInitDict = webidl.converters.MessageEventInit(eventInitDict) + + super(type, eventInitDict) + + this.#eventInit = eventInitDict + } + + get data() { + webidl.brandCheck(this, MessageEvent) + + return this.#eventInit.data + } + + get origin() { + webidl.brandCheck(this, MessageEvent) + + return this.#eventInit.origin + } + + get lastEventId() { + webidl.brandCheck(this, MessageEvent) + + return this.#eventInit.lastEventId + } + + get source() { + webidl.brandCheck(this, MessageEvent) + + return this.#eventInit.source + } + + get ports() { + webidl.brandCheck(this, MessageEvent) + + if (!Object.isFrozen(this.#eventInit.ports)) { + Object.freeze(this.#eventInit.ports) + } + + return this.#eventInit.ports + } + + initMessageEvent( + type, + bubbles = false, + cancelable = false, + data = null, + origin = '', + lastEventId = '', + source = null, + ports = [] + ) { + webidl.brandCheck(this, MessageEvent) + + webidl.argumentLengthCheck(arguments, 1, { + header: 'MessageEvent.initMessageEvent', + }) + + return new MessageEvent(type, { + bubbles, + cancelable, + data, + origin, + lastEventId, + source, + ports, + }) + } + } + + /** + * @see https://websockets.spec.whatwg.org/#the-closeevent-interface + */ + class CloseEvent extends Event { + #eventInit + + constructor(type, eventInitDict = {}) { + webidl.argumentLengthCheck(arguments, 1, { + header: 'CloseEvent constructor', + }) + + type = webidl.converters.DOMString(type) + eventInitDict = webidl.converters.CloseEventInit(eventInitDict) + + super(type, eventInitDict) + + this.#eventInit = eventInitDict + } + + get wasClean() { + webidl.brandCheck(this, CloseEvent) + + return this.#eventInit.wasClean + } + + get code() { + webidl.brandCheck(this, CloseEvent) + + return this.#eventInit.code + } + + get reason() { + webidl.brandCheck(this, CloseEvent) + + return this.#eventInit.reason + } + } + + // https://html.spec.whatwg.org/multipage/webappapis.html#the-errorevent-interface + class ErrorEvent extends Event { + #eventInit + + constructor(type, eventInitDict) { + webidl.argumentLengthCheck(arguments, 1, { + header: 'ErrorEvent constructor', + }) + + super(type, eventInitDict) + + type = webidl.converters.DOMString(type) + eventInitDict = webidl.converters.ErrorEventInit(eventInitDict ?? {}) + + this.#eventInit = eventInitDict + } + + get message() { + webidl.brandCheck(this, ErrorEvent) + + return this.#eventInit.message + } + + get filename() { + webidl.brandCheck(this, ErrorEvent) + + return this.#eventInit.filename + } + + get lineno() { + webidl.brandCheck(this, ErrorEvent) + + return this.#eventInit.lineno + } + + get colno() { + webidl.brandCheck(this, ErrorEvent) + + return this.#eventInit.colno + } + + get error() { + webidl.brandCheck(this, ErrorEvent) + + return this.#eventInit.error + } + } + + Object.defineProperties(MessageEvent.prototype, { + [Symbol.toStringTag]: { + value: 'MessageEvent', + configurable: true, + }, + data: kEnumerableProperty, + origin: kEnumerableProperty, + lastEventId: kEnumerableProperty, + source: kEnumerableProperty, + ports: kEnumerableProperty, + initMessageEvent: kEnumerableProperty, + }) + + Object.defineProperties(CloseEvent.prototype, { + [Symbol.toStringTag]: { + value: 'CloseEvent', + configurable: true, + }, + reason: kEnumerableProperty, + code: kEnumerableProperty, + wasClean: kEnumerableProperty, + }) + + Object.defineProperties(ErrorEvent.prototype, { + [Symbol.toStringTag]: { + value: 'ErrorEvent', + configurable: true, + }, + message: kEnumerableProperty, + filename: kEnumerableProperty, + lineno: kEnumerableProperty, + colno: kEnumerableProperty, + error: kEnumerableProperty, + }) + + webidl.converters.MessagePort = webidl.interfaceConverter(MessagePort) + + webidl.converters['sequence'] = webidl.sequenceConverter( + webidl.converters.MessagePort + ) + + const eventInit = [ + { + key: 'bubbles', + converter: webidl.converters.boolean, + defaultValue: false, + }, + { + key: 'cancelable', + converter: webidl.converters.boolean, + defaultValue: false, + }, + { + key: 'composed', + converter: webidl.converters.boolean, + defaultValue: false, + }, + ] + + webidl.converters.MessageEventInit = webidl.dictionaryConverter([ + ...eventInit, + { + key: 'data', + converter: webidl.converters.any, + defaultValue: null, + }, + { + key: 'origin', + converter: webidl.converters.USVString, + defaultValue: '', + }, + { + key: 'lastEventId', + converter: webidl.converters.DOMString, + defaultValue: '', + }, + { + key: 'source', + // Node doesn't implement WindowProxy or ServiceWorker, so the only + // valid value for source is a MessagePort. + converter: webidl.nullableConverter(webidl.converters.MessagePort), + defaultValue: null, + }, + { + key: 'ports', + converter: webidl.converters['sequence'], + get defaultValue() { + return [] + }, + }, + ]) + + webidl.converters.CloseEventInit = webidl.dictionaryConverter([ + ...eventInit, + { + key: 'wasClean', + converter: webidl.converters.boolean, + defaultValue: false, + }, + { + key: 'code', + converter: webidl.converters['unsigned short'], + defaultValue: 0, + }, + { + key: 'reason', + converter: webidl.converters.USVString, + defaultValue: '', + }, + ]) + + webidl.converters.ErrorEventInit = webidl.dictionaryConverter([ + ...eventInit, + { + key: 'message', + converter: webidl.converters.DOMString, + defaultValue: '', + }, + { + key: 'filename', + converter: webidl.converters.USVString, + defaultValue: '', + }, + { + key: 'lineno', + converter: webidl.converters['unsigned long'], + defaultValue: 0, + }, + { + key: 'colno', + converter: webidl.converters['unsigned long'], + defaultValue: 0, + }, + { + key: 'error', + converter: webidl.converters.any, + }, + ]) + + module.exports = { + MessageEvent, + CloseEvent, + ErrorEvent, + } + + /***/ + }, + + /***/ 5444: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const { maxUnsigned16Bit } = __nccwpck_require__(9188) + + /** @type {import('crypto')} */ + let crypto + try { + crypto = __nccwpck_require__(6113) + } catch {} + + class WebsocketFrameSend { + /** + * @param {Buffer|undefined} data + */ + constructor(data) { + this.frameData = data + this.maskKey = crypto.randomBytes(4) + } + + createFrame(opcode) { + const bodyLength = this.frameData?.byteLength ?? 0 + + /** @type {number} */ + let payloadLength = bodyLength // 0-125 + let offset = 6 + + if (bodyLength > maxUnsigned16Bit) { + offset += 8 // payload length is next 8 bytes + payloadLength = 127 + } else if (bodyLength > 125) { + offset += 2 // payload length is next 2 bytes + payloadLength = 126 + } + + const buffer = Buffer.allocUnsafe(bodyLength + offset) + + // Clear first 2 bytes, everything else is overwritten + buffer[0] = buffer[1] = 0 + buffer[0] |= 0x80 // FIN + buffer[0] = (buffer[0] & 0xf0) + opcode // opcode + + /*! ws. MIT License. Einar Otto Stangvik */ + buffer[offset - 4] = this.maskKey[0] + buffer[offset - 3] = this.maskKey[1] + buffer[offset - 2] = this.maskKey[2] + buffer[offset - 1] = this.maskKey[3] + + buffer[1] = payloadLength + + if (payloadLength === 126) { + buffer.writeUInt16BE(bodyLength, 2) + } else if (payloadLength === 127) { + // Clear extended payload length + buffer[2] = buffer[3] = 0 + buffer.writeUIntBE(bodyLength, 4, 6) + } + + buffer[1] |= 0x80 // MASK + + // mask body + for (let i = 0; i < bodyLength; i++) { + buffer[offset + i] = this.frameData[i] ^ this.maskKey[i % 4] + } + + return buffer + } + } + + module.exports = { + WebsocketFrameSend, + } + + /***/ + }, + + /***/ 1688: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const { Writable } = __nccwpck_require__(2781) + const diagnosticsChannel = __nccwpck_require__(7643) + const { parserStates, opcodes, states, emptyBuffer } = + __nccwpck_require__(9188) + const { kReadyState, kSentClose, kResponse, kReceivedClose } = + __nccwpck_require__(7578) + const { + isValidStatusCode, + failWebsocketConnection, + websocketMessageReceived, + } = __nccwpck_require__(5515) + const { WebsocketFrameSend } = __nccwpck_require__(5444) + + // This code was influenced by ws released under the MIT license. + // Copyright (c) 2011 Einar Otto Stangvik + // Copyright (c) 2013 Arnout Kazemier and contributors + // Copyright (c) 2016 Luigi Pinca and contributors + + const channels = {} + channels.ping = diagnosticsChannel.channel('undici:websocket:ping') + channels.pong = diagnosticsChannel.channel('undici:websocket:pong') + + class ByteParser extends Writable { + #buffers = [] + #byteOffset = 0 + + #state = parserStates.INFO + + #info = {} + #fragments = [] + + constructor(ws) { + super() + + this.ws = ws + } + + /** + * @param {Buffer} chunk + * @param {() => void} callback + */ + _write(chunk, _, callback) { + this.#buffers.push(chunk) + this.#byteOffset += chunk.length + + this.run(callback) + } + + /** + * Runs whenever a new chunk is received. + * Callback is called whenever there are no more chunks buffering, + * or not enough bytes are buffered to parse. + */ + run(callback) { + while (true) { + if (this.#state === parserStates.INFO) { + // If there aren't enough bytes to parse the payload length, etc. + if (this.#byteOffset < 2) { + return callback() + } + + const buffer = this.consume(2) + + this.#info.fin = (buffer[0] & 0x80) !== 0 + this.#info.opcode = buffer[0] & 0x0f + + // If we receive a fragmented message, we use the type of the first + // frame to parse the full message as binary/text, when it's terminated + this.#info.originalOpcode ??= this.#info.opcode + + this.#info.fragmented = + !this.#info.fin && this.#info.opcode !== opcodes.CONTINUATION + + if ( + this.#info.fragmented && + this.#info.opcode !== opcodes.BINARY && + this.#info.opcode !== opcodes.TEXT + ) { + // Only text and binary frames can be fragmented + failWebsocketConnection( + this.ws, + 'Invalid frame type was fragmented.' + ) + return + } + + const payloadLength = buffer[1] & 0x7f + + if (payloadLength <= 125) { + this.#info.payloadLength = payloadLength + this.#state = parserStates.READ_DATA + } else if (payloadLength === 126) { + this.#state = parserStates.PAYLOADLENGTH_16 + } else if (payloadLength === 127) { + this.#state = parserStates.PAYLOADLENGTH_64 + } + + if (this.#info.fragmented && payloadLength > 125) { + // A fragmented frame can't be fragmented itself + failWebsocketConnection( + this.ws, + 'Fragmented frame exceeded 125 bytes.' + ) + return + } else if ( + (this.#info.opcode === opcodes.PING || + this.#info.opcode === opcodes.PONG || + this.#info.opcode === opcodes.CLOSE) && + payloadLength > 125 + ) { + // Control frames can have a payload length of 125 bytes MAX + failWebsocketConnection( + this.ws, + 'Payload length for control frame exceeded 125 bytes.' + ) + return + } else if (this.#info.opcode === opcodes.CLOSE) { + if (payloadLength === 1) { + failWebsocketConnection( + this.ws, + 'Received close frame with a 1-byte body.' + ) + return + } + + const body = this.consume(payloadLength) + + this.#info.closeInfo = this.parseCloseBody(false, body) + + if (!this.ws[kSentClose]) { + // If an endpoint receives a Close frame and did not previously send a + // Close frame, the endpoint MUST send a Close frame in response. (When + // sending a Close frame in response, the endpoint typically echos the + // status code it received.) + const body = Buffer.allocUnsafe(2) + body.writeUInt16BE(this.#info.closeInfo.code, 0) + const closeFrame = new WebsocketFrameSend(body) + + this.ws[kResponse].socket.write( + closeFrame.createFrame(opcodes.CLOSE), + (err) => { + if (!err) { + this.ws[kSentClose] = true + } + } + ) + } + + // Upon either sending or receiving a Close control frame, it is said + // that _The WebSocket Closing Handshake is Started_ and that the + // WebSocket connection is in the CLOSING state. + this.ws[kReadyState] = states.CLOSING + this.ws[kReceivedClose] = true + + this.end() + + return + } else if (this.#info.opcode === opcodes.PING) { + // Upon receipt of a Ping frame, an endpoint MUST send a Pong frame in + // response, unless it already received a Close frame. + // A Pong frame sent in response to a Ping frame must have identical + // "Application data" + + const body = this.consume(payloadLength) + + if (!this.ws[kReceivedClose]) { + const frame = new WebsocketFrameSend(body) + + this.ws[kResponse].socket.write( + frame.createFrame(opcodes.PONG) + ) + + if (channels.ping.hasSubscribers) { + channels.ping.publish({ + payload: body, + }) + } + } + + this.#state = parserStates.INFO + + if (this.#byteOffset > 0) { + continue + } else { + callback() + return + } + } else if (this.#info.opcode === opcodes.PONG) { + // A Pong frame MAY be sent unsolicited. This serves as a + // unidirectional heartbeat. A response to an unsolicited Pong frame is + // not expected. + + const body = this.consume(payloadLength) + + if (channels.pong.hasSubscribers) { + channels.pong.publish({ + payload: body, + }) + } + + if (this.#byteOffset > 0) { + continue + } else { + callback() + return + } + } + } else if (this.#state === parserStates.PAYLOADLENGTH_16) { + if (this.#byteOffset < 2) { + return callback() + } + + const buffer = this.consume(2) + + this.#info.payloadLength = buffer.readUInt16BE(0) + this.#state = parserStates.READ_DATA + } else if (this.#state === parserStates.PAYLOADLENGTH_64) { + if (this.#byteOffset < 8) { + return callback() + } + + const buffer = this.consume(8) + const upper = buffer.readUInt32BE(0) + + // 2^31 is the maxinimum bytes an arraybuffer can contain + // on 32-bit systems. Although, on 64-bit systems, this is + // 2^53-1 bytes. + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Invalid_array_length + // https://source.chromium.org/chromium/chromium/src/+/main:v8/src/common/globals.h;drc=1946212ac0100668f14eb9e2843bdd846e510a1e;bpv=1;bpt=1;l=1275 + // https://source.chromium.org/chromium/chromium/src/+/main:v8/src/objects/js-array-buffer.h;l=34;drc=1946212ac0100668f14eb9e2843bdd846e510a1e + if (upper > 2 ** 31 - 1) { + failWebsocketConnection( + this.ws, + 'Received payload length > 2^31 bytes.' + ) + return + } + + const lower = buffer.readUInt32BE(4) + + this.#info.payloadLength = (upper << 8) + lower + this.#state = parserStates.READ_DATA + } else if (this.#state === parserStates.READ_DATA) { + if (this.#byteOffset < this.#info.payloadLength) { + // If there is still more data in this chunk that needs to be read + return callback() + } else if (this.#byteOffset >= this.#info.payloadLength) { + // If the server sent multiple frames in a single chunk + + const body = this.consume(this.#info.payloadLength) + + this.#fragments.push(body) + + // If the frame is unfragmented, or a fragmented frame was terminated, + // a message was received + if ( + !this.#info.fragmented || + (this.#info.fin && this.#info.opcode === opcodes.CONTINUATION) + ) { + const fullMessage = Buffer.concat(this.#fragments) + + websocketMessageReceived( + this.ws, + this.#info.originalOpcode, + fullMessage + ) + + this.#info = {} + this.#fragments.length = 0 + } + + this.#state = parserStates.INFO + } + } + + if (this.#byteOffset > 0) { + continue + } else { + callback() + break + } + } + } + + /** + * Take n bytes from the buffered Buffers + * @param {number} n + * @returns {Buffer|null} + */ + consume(n) { + if (n > this.#byteOffset) { + return null + } else if (n === 0) { + return emptyBuffer + } + + if (this.#buffers[0].length === n) { + this.#byteOffset -= this.#buffers[0].length + return this.#buffers.shift() + } + + const buffer = Buffer.allocUnsafe(n) + let offset = 0 + + while (offset !== n) { + const next = this.#buffers[0] + const { length } = next + + if (length + offset === n) { + buffer.set(this.#buffers.shift(), offset) + break + } else if (length + offset > n) { + buffer.set(next.subarray(0, n - offset), offset) + this.#buffers[0] = next.subarray(n - offset) + break + } else { + buffer.set(this.#buffers.shift(), offset) + offset += next.length + } + } + + this.#byteOffset -= n + + return buffer + } + + parseCloseBody(onlyCode, data) { + // https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.5 + /** @type {number|undefined} */ + let code + + if (data.length >= 2) { + // _The WebSocket Connection Close Code_ is + // defined as the status code (Section 7.4) contained in the first Close + // control frame received by the application + code = data.readUInt16BE(0) + } + + if (onlyCode) { + if (!isValidStatusCode(code)) { + return null + } + + return { code } + } + + // https://datatracker.ietf.org/doc/html/rfc6455#section-7.1.6 + /** @type {Buffer} */ + let reason = data.subarray(2) + + // Remove BOM + if (reason[0] === 0xef && reason[1] === 0xbb && reason[2] === 0xbf) { + reason = reason.subarray(3) + } + + if (code !== undefined && !isValidStatusCode(code)) { + return null + } + + try { + // TODO: optimize this + reason = new TextDecoder('utf-8', { fatal: true }).decode(reason) + } catch { + return null + } + + return { code, reason } + } + + get closingInfo() { + return this.#info.closeInfo + } + } + + module.exports = { + ByteParser, + } + + /***/ + }, + + /***/ 7578: /***/ (module) => { + 'use strict' + + module.exports = { + kWebSocketURL: Symbol('url'), + kReadyState: Symbol('ready state'), + kController: Symbol('controller'), + kResponse: Symbol('response'), + kBinaryType: Symbol('binary type'), + kSentClose: Symbol('sent close'), + kReceivedClose: Symbol('received close'), + kByteParser: Symbol('byte parser'), + } + + /***/ + }, + + /***/ 5515: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const { + kReadyState, + kController, + kResponse, + kBinaryType, + kWebSocketURL, + } = __nccwpck_require__(7578) + const { states, opcodes } = __nccwpck_require__(9188) + const { MessageEvent, ErrorEvent } = __nccwpck_require__(2611) + + /* globals Blob */ + + /** + * @param {import('./websocket').WebSocket} ws + */ + function isEstablished(ws) { + // If the server's response is validated as provided for above, it is + // said that _The WebSocket Connection is Established_ and that the + // WebSocket Connection is in the OPEN state. + return ws[kReadyState] === states.OPEN + } + + /** + * @param {import('./websocket').WebSocket} ws + */ + function isClosing(ws) { + // Upon either sending or receiving a Close control frame, it is said + // that _The WebSocket Closing Handshake is Started_ and that the + // WebSocket connection is in the CLOSING state. + return ws[kReadyState] === states.CLOSING + } + + /** + * @param {import('./websocket').WebSocket} ws + */ + function isClosed(ws) { + return ws[kReadyState] === states.CLOSED + } + + /** + * @see https://dom.spec.whatwg.org/#concept-event-fire + * @param {string} e + * @param {EventTarget} target + * @param {EventInit | undefined} eventInitDict + */ + function fireEvent(e, target, eventConstructor = Event, eventInitDict) { + // 1. If eventConstructor is not given, then let eventConstructor be Event. + + // 2. Let event be the result of creating an event given eventConstructor, + // in the relevant realm of target. + // 3. Initialize event’s type attribute to e. + const event = new eventConstructor(e, eventInitDict) // eslint-disable-line new-cap + + // 4. Initialize any other IDL attributes of event as described in the + // invocation of this algorithm. + + // 5. Return the result of dispatching event at target, with legacy target + // override flag set if set. + target.dispatchEvent(event) + } + + /** + * @see https://websockets.spec.whatwg.org/#feedback-from-the-protocol + * @param {import('./websocket').WebSocket} ws + * @param {number} type Opcode + * @param {Buffer} data application data + */ + function websocketMessageReceived(ws, type, data) { + // 1. If ready state is not OPEN (1), then return. + if (ws[kReadyState] !== states.OPEN) { + return + } + + // 2. Let dataForEvent be determined by switching on type and binary type: + let dataForEvent + + if (type === opcodes.TEXT) { + // -> type indicates that the data is Text + // a new DOMString containing data + try { + dataForEvent = new TextDecoder('utf-8', { fatal: true }).decode( + data + ) + } catch { + failWebsocketConnection(ws, 'Received invalid UTF-8 in text frame.') + return + } + } else if (type === opcodes.BINARY) { + if (ws[kBinaryType] === 'blob') { + // -> type indicates that the data is Binary and binary type is "blob" + // a new Blob object, created in the relevant Realm of the WebSocket + // object, that represents data as its raw data + dataForEvent = new Blob([data]) + } else { + // -> type indicates that the data is Binary and binary type is "arraybuffer" + // a new ArrayBuffer object, created in the relevant Realm of the + // WebSocket object, whose contents are data + dataForEvent = new Uint8Array(data).buffer + } + } + + // 3. Fire an event named message at the WebSocket object, using MessageEvent, + // with the origin attribute initialized to the serialization of the WebSocket + // object’s url's origin, and the data attribute initialized to dataForEvent. + fireEvent('message', ws, MessageEvent, { + origin: ws[kWebSocketURL].origin, + data: dataForEvent, + }) + } + + /** + * @see https://datatracker.ietf.org/doc/html/rfc6455 + * @see https://datatracker.ietf.org/doc/html/rfc2616 + * @see https://bugs.chromium.org/p/chromium/issues/detail?id=398407 + * @param {string} protocol + */ + function isValidSubprotocol(protocol) { + // If present, this value indicates one + // or more comma-separated subprotocol the client wishes to speak, + // ordered by preference. The elements that comprise this value + // MUST be non-empty strings with characters in the range U+0021 to + // U+007E not including separator characters as defined in + // [RFC2616] and MUST all be unique strings. + if (protocol.length === 0) { + return false + } + + for (const char of protocol) { + const code = char.charCodeAt(0) + + if ( + code < 0x21 || + code > 0x7e || + char === '(' || + char === ')' || + char === '<' || + char === '>' || + char === '@' || + char === ',' || + char === ';' || + char === ':' || + char === '\\' || + char === '"' || + char === '/' || + char === '[' || + char === ']' || + char === '?' || + char === '=' || + char === '{' || + char === '}' || + code === 32 || // SP + code === 9 // HT + ) { + return false + } + } + + return true + } + + /** + * @see https://datatracker.ietf.org/doc/html/rfc6455#section-7-4 + * @param {number} code + */ + function isValidStatusCode(code) { + if (code >= 1000 && code < 1015) { + return ( + code !== 1004 && // reserved + code !== 1005 && // "MUST NOT be set as a status code" + code !== 1006 // "MUST NOT be set as a status code" + ) + } + + return code >= 3000 && code <= 4999 + } + + /** + * @param {import('./websocket').WebSocket} ws + * @param {string|undefined} reason + */ + function failWebsocketConnection(ws, reason) { + const { [kController]: controller, [kResponse]: response } = ws + + controller.abort() + + if (response?.socket && !response.socket.destroyed) { + response.socket.destroy() + } + + if (reason) { + fireEvent('error', ws, ErrorEvent, { + error: new Error(reason), + }) + } + } + + module.exports = { + isEstablished, + isClosing, + isClosed, + fireEvent, + isValidSubprotocol, + isValidStatusCode, + failWebsocketConnection, + websocketMessageReceived, + } + + /***/ + }, + + /***/ 4284: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const { webidl } = __nccwpck_require__(1744) + const { DOMException } = __nccwpck_require__(1037) + const { URLSerializer } = __nccwpck_require__(685) + const { getGlobalOrigin } = __nccwpck_require__(1246) + const { staticPropertyDescriptors, states, opcodes, emptyBuffer } = + __nccwpck_require__(9188) + const { + kWebSocketURL, + kReadyState, + kController, + kBinaryType, + kResponse, + kSentClose, + kByteParser, + } = __nccwpck_require__(7578) + const { + isEstablished, + isClosing, + isValidSubprotocol, + failWebsocketConnection, + fireEvent, + } = __nccwpck_require__(5515) + const { establishWebSocketConnection } = __nccwpck_require__(5354) + const { WebsocketFrameSend } = __nccwpck_require__(5444) + const { ByteParser } = __nccwpck_require__(1688) + const { kEnumerableProperty, isBlobLike } = __nccwpck_require__(3983) + const { getGlobalDispatcher } = __nccwpck_require__(1892) + const { types } = __nccwpck_require__(3837) + + let experimentalWarned = false + + // https://websockets.spec.whatwg.org/#interface-definition + class WebSocket extends EventTarget { + #events = { + open: null, + error: null, + close: null, + message: null, + } + + #bufferedAmount = 0 + #protocol = '' + #extensions = '' + + /** + * @param {string} url + * @param {string|string[]} protocols + */ + constructor(url, protocols = []) { + super() + + webidl.argumentLengthCheck(arguments, 1, { + header: 'WebSocket constructor', + }) + + if (!experimentalWarned) { + experimentalWarned = true + process.emitWarning( + 'WebSockets are experimental, expect them to change at any time.', + { + code: 'UNDICI-WS', + } + ) + } + + const options = + webidl.converters[ + 'DOMString or sequence or WebSocketInit' + ](protocols) + + url = webidl.converters.USVString(url) + protocols = options.protocols + + // 1. Let baseURL be this's relevant settings object's API base URL. + const baseURL = getGlobalOrigin() + + // 1. Let urlRecord be the result of applying the URL parser to url with baseURL. + let urlRecord + + try { + urlRecord = new URL(url, baseURL) + } catch (e) { + // 3. If urlRecord is failure, then throw a "SyntaxError" DOMException. + throw new DOMException(e, 'SyntaxError') + } + + // 4. If urlRecord’s scheme is "http", then set urlRecord’s scheme to "ws". + if (urlRecord.protocol === 'http:') { + urlRecord.protocol = 'ws:' + } else if (urlRecord.protocol === 'https:') { + // 5. Otherwise, if urlRecord’s scheme is "https", set urlRecord’s scheme to "wss". + urlRecord.protocol = 'wss:' + } + + // 6. If urlRecord’s scheme is not "ws" or "wss", then throw a "SyntaxError" DOMException. + if (urlRecord.protocol !== 'ws:' && urlRecord.protocol !== 'wss:') { + throw new DOMException( + `Expected a ws: or wss: protocol, got ${urlRecord.protocol}`, + 'SyntaxError' + ) + } + + // 7. If urlRecord’s fragment is non-null, then throw a "SyntaxError" + // DOMException. + if (urlRecord.hash || urlRecord.href.endsWith('#')) { + throw new DOMException('Got fragment', 'SyntaxError') + } + + // 8. If protocols is a string, set protocols to a sequence consisting + // of just that string. + if (typeof protocols === 'string') { + protocols = [protocols] + } + + // 9. If any of the values in protocols occur more than once or otherwise + // fail to match the requirements for elements that comprise the value + // of `Sec-WebSocket-Protocol` fields as defined by The WebSocket + // protocol, then throw a "SyntaxError" DOMException. + if ( + protocols.length !== + new Set(protocols.map((p) => p.toLowerCase())).size + ) { + throw new DOMException( + 'Invalid Sec-WebSocket-Protocol value', + 'SyntaxError' + ) + } + + if ( + protocols.length > 0 && + !protocols.every((p) => isValidSubprotocol(p)) + ) { + throw new DOMException( + 'Invalid Sec-WebSocket-Protocol value', + 'SyntaxError' + ) + } + + // 10. Set this's url to urlRecord. + this[kWebSocketURL] = new URL(urlRecord.href) + + // 11. Let client be this's relevant settings object. + + // 12. Run this step in parallel: + + // 1. Establish a WebSocket connection given urlRecord, protocols, + // and client. + this[kController] = establishWebSocketConnection( + urlRecord, + protocols, + this, + (response) => this.#onConnectionEstablished(response), + options + ) + + // Each WebSocket object has an associated ready state, which is a + // number representing the state of the connection. Initially it must + // be CONNECTING (0). + this[kReadyState] = WebSocket.CONNECTING + + // The extensions attribute must initially return the empty string. + + // The protocol attribute must initially return the empty string. + + // Each WebSocket object has an associated binary type, which is a + // BinaryType. Initially it must be "blob". + this[kBinaryType] = 'blob' + } + + /** + * @see https://websockets.spec.whatwg.org/#dom-websocket-close + * @param {number|undefined} code + * @param {string|undefined} reason + */ + close(code = undefined, reason = undefined) { + webidl.brandCheck(this, WebSocket) + + if (code !== undefined) { + code = webidl.converters['unsigned short'](code, { clamp: true }) + } + + if (reason !== undefined) { + reason = webidl.converters.USVString(reason) + } + + // 1. If code is present, but is neither an integer equal to 1000 nor an + // integer in the range 3000 to 4999, inclusive, throw an + // "InvalidAccessError" DOMException. + if (code !== undefined) { + if (code !== 1000 && (code < 3000 || code > 4999)) { + throw new DOMException('invalid code', 'InvalidAccessError') + } + } + + let reasonByteLength = 0 + + // 2. If reason is present, then run these substeps: + if (reason !== undefined) { + // 1. Let reasonBytes be the result of encoding reason. + // 2. If reasonBytes is longer than 123 bytes, then throw a + // "SyntaxError" DOMException. + reasonByteLength = Buffer.byteLength(reason) + + if (reasonByteLength > 123) { + throw new DOMException( + `Reason must be less than 123 bytes; received ${reasonByteLength}`, + 'SyntaxError' + ) + } + } + + // 3. Run the first matching steps from the following list: + if ( + this[kReadyState] === WebSocket.CLOSING || + this[kReadyState] === WebSocket.CLOSED + ) { + // If this's ready state is CLOSING (2) or CLOSED (3) + // Do nothing. + } else if (!isEstablished(this)) { + // If the WebSocket connection is not yet established + // Fail the WebSocket connection and set this's ready state + // to CLOSING (2). + failWebsocketConnection( + this, + 'Connection was closed before it was established.' + ) + this[kReadyState] = WebSocket.CLOSING + } else if (!isClosing(this)) { + // If the WebSocket closing handshake has not yet been started + // Start the WebSocket closing handshake and set this's ready + // state to CLOSING (2). + // - If neither code nor reason is present, the WebSocket Close + // message must not have a body. + // - If code is present, then the status code to use in the + // WebSocket Close message must be the integer given by code. + // - If reason is also present, then reasonBytes must be + // provided in the Close message after the status code. + + const frame = new WebsocketFrameSend() + + // If neither code nor reason is present, the WebSocket Close + // message must not have a body. + + // If code is present, then the status code to use in the + // WebSocket Close message must be the integer given by code. + if (code !== undefined && reason === undefined) { + frame.frameData = Buffer.allocUnsafe(2) + frame.frameData.writeUInt16BE(code, 0) + } else if (code !== undefined && reason !== undefined) { + // If reason is also present, then reasonBytes must be + // provided in the Close message after the status code. + frame.frameData = Buffer.allocUnsafe(2 + reasonByteLength) + frame.frameData.writeUInt16BE(code, 0) + // the body MAY contain UTF-8-encoded data with value /reason/ + frame.frameData.write(reason, 2, 'utf-8') + } else { + frame.frameData = emptyBuffer + } + + /** @type {import('stream').Duplex} */ + const socket = this[kResponse].socket + + socket.write(frame.createFrame(opcodes.CLOSE), (err) => { + if (!err) { + this[kSentClose] = true + } + }) + + // Upon either sending or receiving a Close control frame, it is said + // that _The WebSocket Closing Handshake is Started_ and that the + // WebSocket connection is in the CLOSING state. + this[kReadyState] = states.CLOSING + } else { + // Otherwise + // Set this's ready state to CLOSING (2). + this[kReadyState] = WebSocket.CLOSING + } + } + + /** + * @see https://websockets.spec.whatwg.org/#dom-websocket-send + * @param {NodeJS.TypedArray|ArrayBuffer|Blob|string} data + */ + send(data) { + webidl.brandCheck(this, WebSocket) + + webidl.argumentLengthCheck(arguments, 1, { header: 'WebSocket.send' }) + + data = webidl.converters.WebSocketSendData(data) + + // 1. If this's ready state is CONNECTING, then throw an + // "InvalidStateError" DOMException. + if (this[kReadyState] === WebSocket.CONNECTING) { + throw new DOMException( + 'Sent before connected.', + 'InvalidStateError' + ) + } + + // 2. Run the appropriate set of steps from the following list: + // https://datatracker.ietf.org/doc/html/rfc6455#section-6.1 + // https://datatracker.ietf.org/doc/html/rfc6455#section-5.2 + + if (!isEstablished(this) || isClosing(this)) { + return + } + + /** @type {import('stream').Duplex} */ + const socket = this[kResponse].socket + + // If data is a string + if (typeof data === 'string') { + // If the WebSocket connection is established and the WebSocket + // closing handshake has not yet started, then the user agent + // must send a WebSocket Message comprised of the data argument + // using a text frame opcode; if the data cannot be sent, e.g. + // because it would need to be buffered but the buffer is full, + // the user agent must flag the WebSocket as full and then close + // the WebSocket connection. Any invocation of this method with a + // string argument that does not throw an exception must increase + // the bufferedAmount attribute by the number of bytes needed to + // express the argument as UTF-8. + + const value = Buffer.from(data) + const frame = new WebsocketFrameSend(value) + const buffer = frame.createFrame(opcodes.TEXT) + + this.#bufferedAmount += value.byteLength + socket.write(buffer, () => { + this.#bufferedAmount -= value.byteLength + }) + } else if (types.isArrayBuffer(data)) { + // If the WebSocket connection is established, and the WebSocket + // closing handshake has not yet started, then the user agent must + // send a WebSocket Message comprised of data using a binary frame + // opcode; if the data cannot be sent, e.g. because it would need + // to be buffered but the buffer is full, the user agent must flag + // the WebSocket as full and then close the WebSocket connection. + // The data to be sent is the data stored in the buffer described + // by the ArrayBuffer object. Any invocation of this method with an + // ArrayBuffer argument that does not throw an exception must + // increase the bufferedAmount attribute by the length of the + // ArrayBuffer in bytes. + + const value = Buffer.from(data) + const frame = new WebsocketFrameSend(value) + const buffer = frame.createFrame(opcodes.BINARY) + + this.#bufferedAmount += value.byteLength + socket.write(buffer, () => { + this.#bufferedAmount -= value.byteLength + }) + } else if (ArrayBuffer.isView(data)) { + // If the WebSocket connection is established, and the WebSocket + // closing handshake has not yet started, then the user agent must + // send a WebSocket Message comprised of data using a binary frame + // opcode; if the data cannot be sent, e.g. because it would need to + // be buffered but the buffer is full, the user agent must flag the + // WebSocket as full and then close the WebSocket connection. The + // data to be sent is the data stored in the section of the buffer + // described by the ArrayBuffer object that data references. Any + // invocation of this method with this kind of argument that does + // not throw an exception must increase the bufferedAmount attribute + // by the length of data’s buffer in bytes. + + const ab = Buffer.from(data, data.byteOffset, data.byteLength) + + const frame = new WebsocketFrameSend(ab) + const buffer = frame.createFrame(opcodes.BINARY) + + this.#bufferedAmount += ab.byteLength + socket.write(buffer, () => { + this.#bufferedAmount -= ab.byteLength + }) + } else if (isBlobLike(data)) { + // If the WebSocket connection is established, and the WebSocket + // closing handshake has not yet started, then the user agent must + // send a WebSocket Message comprised of data using a binary frame + // opcode; if the data cannot be sent, e.g. because it would need to + // be buffered but the buffer is full, the user agent must flag the + // WebSocket as full and then close the WebSocket connection. The data + // to be sent is the raw data represented by the Blob object. Any + // invocation of this method with a Blob argument that does not throw + // an exception must increase the bufferedAmount attribute by the size + // of the Blob object’s raw data, in bytes. + + const frame = new WebsocketFrameSend() + + data.arrayBuffer().then((ab) => { + const value = Buffer.from(ab) + frame.frameData = value + const buffer = frame.createFrame(opcodes.BINARY) + + this.#bufferedAmount += value.byteLength + socket.write(buffer, () => { + this.#bufferedAmount -= value.byteLength + }) + }) + } + } + + get readyState() { + webidl.brandCheck(this, WebSocket) + + // The readyState getter steps are to return this's ready state. + return this[kReadyState] + } + + get bufferedAmount() { + webidl.brandCheck(this, WebSocket) + + return this.#bufferedAmount + } + + get url() { + webidl.brandCheck(this, WebSocket) + + // The url getter steps are to return this's url, serialized. + return URLSerializer(this[kWebSocketURL]) + } + + get extensions() { + webidl.brandCheck(this, WebSocket) + + return this.#extensions + } + + get protocol() { + webidl.brandCheck(this, WebSocket) + + return this.#protocol + } + + get onopen() { + webidl.brandCheck(this, WebSocket) + + return this.#events.open + } + + set onopen(fn) { + webidl.brandCheck(this, WebSocket) + + if (this.#events.open) { + this.removeEventListener('open', this.#events.open) + } + + if (typeof fn === 'function') { + this.#events.open = fn + this.addEventListener('open', fn) + } else { + this.#events.open = null + } + } + + get onerror() { + webidl.brandCheck(this, WebSocket) + + return this.#events.error + } + + set onerror(fn) { + webidl.brandCheck(this, WebSocket) + + if (this.#events.error) { + this.removeEventListener('error', this.#events.error) + } + + if (typeof fn === 'function') { + this.#events.error = fn + this.addEventListener('error', fn) + } else { + this.#events.error = null + } + } + + get onclose() { + webidl.brandCheck(this, WebSocket) + + return this.#events.close + } + + set onclose(fn) { + webidl.brandCheck(this, WebSocket) + + if (this.#events.close) { + this.removeEventListener('close', this.#events.close) + } + + if (typeof fn === 'function') { + this.#events.close = fn + this.addEventListener('close', fn) + } else { + this.#events.close = null + } + } + + get onmessage() { + webidl.brandCheck(this, WebSocket) + + return this.#events.message + } + + set onmessage(fn) { + webidl.brandCheck(this, WebSocket) + + if (this.#events.message) { + this.removeEventListener('message', this.#events.message) + } + + if (typeof fn === 'function') { + this.#events.message = fn + this.addEventListener('message', fn) + } else { + this.#events.message = null + } + } + + get binaryType() { + webidl.brandCheck(this, WebSocket) + + return this[kBinaryType] + } + + set binaryType(type) { + webidl.brandCheck(this, WebSocket) + + if (type !== 'blob' && type !== 'arraybuffer') { + this[kBinaryType] = 'blob' + } else { + this[kBinaryType] = type + } + } + + /** + * @see https://websockets.spec.whatwg.org/#feedback-from-the-protocol + */ + #onConnectionEstablished(response) { + // processResponse is called when the "response’s header list has been received and initialized." + // once this happens, the connection is open + this[kResponse] = response + + const parser = new ByteParser(this) + parser.on('drain', function onParserDrain() { + this.ws[kResponse].socket.resume() + }) + + response.socket.ws = this + this[kByteParser] = parser + + // 1. Change the ready state to OPEN (1). + this[kReadyState] = states.OPEN + + // 2. Change the extensions attribute’s value to the extensions in use, if + // it is not the null value. + // https://datatracker.ietf.org/doc/html/rfc6455#section-9.1 + const extensions = response.headersList.get( + 'sec-websocket-extensions' + ) + + if (extensions !== null) { + this.#extensions = extensions + } + + // 3. Change the protocol attribute’s value to the subprotocol in use, if + // it is not the null value. + // https://datatracker.ietf.org/doc/html/rfc6455#section-1.9 + const protocol = response.headersList.get('sec-websocket-protocol') + + if (protocol !== null) { + this.#protocol = protocol + } + + // 4. Fire an event named open at the WebSocket object. + fireEvent('open', this) + } + } + + // https://websockets.spec.whatwg.org/#dom-websocket-connecting + WebSocket.CONNECTING = WebSocket.prototype.CONNECTING = states.CONNECTING + // https://websockets.spec.whatwg.org/#dom-websocket-open + WebSocket.OPEN = WebSocket.prototype.OPEN = states.OPEN + // https://websockets.spec.whatwg.org/#dom-websocket-closing + WebSocket.CLOSING = WebSocket.prototype.CLOSING = states.CLOSING + // https://websockets.spec.whatwg.org/#dom-websocket-closed + WebSocket.CLOSED = WebSocket.prototype.CLOSED = states.CLOSED + + Object.defineProperties(WebSocket.prototype, { + CONNECTING: staticPropertyDescriptors, + OPEN: staticPropertyDescriptors, + CLOSING: staticPropertyDescriptors, + CLOSED: staticPropertyDescriptors, + url: kEnumerableProperty, + readyState: kEnumerableProperty, + bufferedAmount: kEnumerableProperty, + onopen: kEnumerableProperty, + onerror: kEnumerableProperty, + onclose: kEnumerableProperty, + close: kEnumerableProperty, + onmessage: kEnumerableProperty, + binaryType: kEnumerableProperty, + send: kEnumerableProperty, + extensions: kEnumerableProperty, + protocol: kEnumerableProperty, + [Symbol.toStringTag]: { + value: 'WebSocket', + writable: false, + enumerable: false, + configurable: true, + }, + }) + + Object.defineProperties(WebSocket, { + CONNECTING: staticPropertyDescriptors, + OPEN: staticPropertyDescriptors, + CLOSING: staticPropertyDescriptors, + CLOSED: staticPropertyDescriptors, + }) + + webidl.converters['sequence'] = webidl.sequenceConverter( + webidl.converters.DOMString + ) + + webidl.converters['DOMString or sequence'] = function (V) { + if (webidl.util.Type(V) === 'Object' && Symbol.iterator in V) { + return webidl.converters['sequence'](V) + } + + return webidl.converters.DOMString(V) + } + + // This implements the propsal made in https://github.com/whatwg/websockets/issues/42 + webidl.converters.WebSocketInit = webidl.dictionaryConverter([ + { + key: 'protocols', + converter: webidl.converters['DOMString or sequence'], + get defaultValue() { + return [] + }, + }, + { + key: 'dispatcher', + converter: (V) => V, + get defaultValue() { + return getGlobalDispatcher() + }, + }, + { + key: 'headers', + converter: webidl.nullableConverter(webidl.converters.HeadersInit), + }, + ]) + + webidl.converters['DOMString or sequence or WebSocketInit'] = + function (V) { + if (webidl.util.Type(V) === 'Object' && !(Symbol.iterator in V)) { + return webidl.converters.WebSocketInit(V) + } + + return { + protocols: webidl.converters['DOMString or sequence'](V), + } + } + + webidl.converters.WebSocketSendData = function (V) { + if (webidl.util.Type(V) === 'Object') { + if (isBlobLike(V)) { + return webidl.converters.Blob(V, { strict: false }) + } + + if (ArrayBuffer.isView(V) || types.isAnyArrayBuffer(V)) { + return webidl.converters.BufferSource(V) + } + } + + return webidl.converters.USVString(V) + } + + module.exports = { + WebSocket, + } + + /***/ + }, + + /***/ 5030: /***/ (__unused_webpack_module, exports) => { + 'use strict' + + Object.defineProperty(exports, '__esModule', { value: true }) + + function getUserAgent() { + if (typeof navigator === 'object' && 'userAgent' in navigator) { + return navigator.userAgent + } + + if (typeof process === 'object' && process.version !== undefined) { + return `Node.js/${process.version.substr(1)} (${process.platform}; ${ + process.arch + })` + } + + return '' + } + + exports.getUserAgent = getUserAgent + //# sourceMappingURL=index.js.map + + /***/ + }, + + /***/ 5840: /***/ ( + __unused_webpack_module, + exports, + __nccwpck_require__ + ) => { + 'use strict' + + Object.defineProperty(exports, '__esModule', { + value: true, + }) + Object.defineProperty(exports, 'v1', { + enumerable: true, + get: function () { + return _v.default + }, + }) + Object.defineProperty(exports, 'v3', { + enumerable: true, + get: function () { + return _v2.default + }, + }) + Object.defineProperty(exports, 'v4', { + enumerable: true, + get: function () { + return _v3.default + }, + }) + Object.defineProperty(exports, 'v5', { + enumerable: true, + get: function () { + return _v4.default + }, + }) + Object.defineProperty(exports, 'NIL', { + enumerable: true, + get: function () { + return _nil.default + }, + }) + Object.defineProperty(exports, 'version', { + enumerable: true, + get: function () { + return _version.default + }, + }) + Object.defineProperty(exports, 'validate', { + enumerable: true, + get: function () { + return _validate.default + }, + }) + Object.defineProperty(exports, 'stringify', { + enumerable: true, + get: function () { + return _stringify.default + }, + }) + Object.defineProperty(exports, 'parse', { + enumerable: true, + get: function () { + return _parse.default + }, + }) + + var _v = _interopRequireDefault(__nccwpck_require__(8628)) + + var _v2 = _interopRequireDefault(__nccwpck_require__(6409)) + + var _v3 = _interopRequireDefault(__nccwpck_require__(5122)) + + var _v4 = _interopRequireDefault(__nccwpck_require__(9120)) + + var _nil = _interopRequireDefault(__nccwpck_require__(5332)) + + var _version = _interopRequireDefault(__nccwpck_require__(1595)) + + var _validate = _interopRequireDefault(__nccwpck_require__(6900)) + + var _stringify = _interopRequireDefault(__nccwpck_require__(8950)) + + var _parse = _interopRequireDefault(__nccwpck_require__(2746)) + + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj } + } + + /***/ + }, + + /***/ 4569: /***/ ( + __unused_webpack_module, + exports, + __nccwpck_require__ + ) => { + 'use strict' + + Object.defineProperty(exports, '__esModule', { + value: true, + }) + exports['default'] = void 0 + + var _crypto = _interopRequireDefault(__nccwpck_require__(6113)) + + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj } + } + + function md5(bytes) { + if (Array.isArray(bytes)) { + bytes = Buffer.from(bytes) + } else if (typeof bytes === 'string') { + bytes = Buffer.from(bytes, 'utf8') + } + + return _crypto.default.createHash('md5').update(bytes).digest() + } + + var _default = md5 + exports['default'] = _default + + /***/ + }, + + /***/ 5332: /***/ (__unused_webpack_module, exports) => { + 'use strict' + + Object.defineProperty(exports, '__esModule', { + value: true, + }) + exports['default'] = void 0 + var _default = '00000000-0000-0000-0000-000000000000' + exports['default'] = _default + + /***/ + }, + + /***/ 2746: /***/ ( + __unused_webpack_module, + exports, + __nccwpck_require__ + ) => { + 'use strict' + + Object.defineProperty(exports, '__esModule', { + value: true, + }) + exports['default'] = void 0 + + var _validate = _interopRequireDefault(__nccwpck_require__(6900)) + + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj } + } + + function parse(uuid) { + if (!(0, _validate.default)(uuid)) { + throw TypeError('Invalid UUID') + } + + let v + const arr = new Uint8Array(16) // Parse ########-....-....-....-............ + + arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24 + arr[1] = (v >>> 16) & 0xff + arr[2] = (v >>> 8) & 0xff + arr[3] = v & 0xff // Parse ........-####-....-....-............ + + arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8 + arr[5] = v & 0xff // Parse ........-....-####-....-............ + + arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8 + arr[7] = v & 0xff // Parse ........-....-....-####-............ + + arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8 + arr[9] = v & 0xff // Parse ........-....-....-....-############ + // (Use "/" to avoid 32-bit truncation when bit-shifting high-order bytes) + + arr[10] = + ((v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000) & 0xff + arr[11] = (v / 0x100000000) & 0xff + arr[12] = (v >>> 24) & 0xff + arr[13] = (v >>> 16) & 0xff + arr[14] = (v >>> 8) & 0xff + arr[15] = v & 0xff + return arr + } + + var _default = parse + exports['default'] = _default + + /***/ + }, + + /***/ 814: /***/ (__unused_webpack_module, exports) => { + 'use strict' + + Object.defineProperty(exports, '__esModule', { + value: true, + }) + exports['default'] = void 0 + var _default = + /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i + exports['default'] = _default + + /***/ + }, + + /***/ 807: /***/ ( + __unused_webpack_module, + exports, + __nccwpck_require__ + ) => { + 'use strict' + + Object.defineProperty(exports, '__esModule', { + value: true, + }) + exports['default'] = rng + + var _crypto = _interopRequireDefault(__nccwpck_require__(6113)) + + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj } + } + + const rnds8Pool = new Uint8Array(256) // # of random values to pre-allocate + + let poolPtr = rnds8Pool.length + + function rng() { + if (poolPtr > rnds8Pool.length - 16) { + _crypto.default.randomFillSync(rnds8Pool) + + poolPtr = 0 + } + + return rnds8Pool.slice(poolPtr, (poolPtr += 16)) + } + + /***/ + }, + + /***/ 5274: /***/ ( + __unused_webpack_module, + exports, + __nccwpck_require__ + ) => { + 'use strict' + + Object.defineProperty(exports, '__esModule', { + value: true, + }) + exports['default'] = void 0 + + var _crypto = _interopRequireDefault(__nccwpck_require__(6113)) + + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj } + } + + function sha1(bytes) { + if (Array.isArray(bytes)) { + bytes = Buffer.from(bytes) + } else if (typeof bytes === 'string') { + bytes = Buffer.from(bytes, 'utf8') + } + + return _crypto.default.createHash('sha1').update(bytes).digest() + } + + var _default = sha1 + exports['default'] = _default + + /***/ + }, + + /***/ 8950: /***/ ( + __unused_webpack_module, + exports, + __nccwpck_require__ + ) => { + 'use strict' + + Object.defineProperty(exports, '__esModule', { + value: true, + }) + exports['default'] = void 0 + + var _validate = _interopRequireDefault(__nccwpck_require__(6900)) + + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj } + } + + /** + * Convert array of 16 byte values to UUID string format of the form: + * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX + */ + const byteToHex = [] + + for (let i = 0; i < 256; ++i) { + byteToHex.push((i + 0x100).toString(16).substr(1)) + } + + function stringify(arr, offset = 0) { + // Note: Be careful editing this code! It's been tuned for performance + // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434 + const uuid = ( + byteToHex[arr[offset + 0]] + + byteToHex[arr[offset + 1]] + + byteToHex[arr[offset + 2]] + + byteToHex[arr[offset + 3]] + + '-' + + byteToHex[arr[offset + 4]] + + byteToHex[arr[offset + 5]] + + '-' + + byteToHex[arr[offset + 6]] + + byteToHex[arr[offset + 7]] + + '-' + + byteToHex[arr[offset + 8]] + + byteToHex[arr[offset + 9]] + + '-' + + byteToHex[arr[offset + 10]] + + byteToHex[arr[offset + 11]] + + byteToHex[arr[offset + 12]] + + byteToHex[arr[offset + 13]] + + byteToHex[arr[offset + 14]] + + byteToHex[arr[offset + 15]] + ).toLowerCase() // Consistency check for valid UUID. If this throws, it's likely due to one + // of the following: + // - One or more input array values don't map to a hex octet (leading to + // "undefined" in the uuid) + // - Invalid input values for the RFC `version` or `variant` fields + + if (!(0, _validate.default)(uuid)) { + throw TypeError('Stringified UUID is invalid') + } + + return uuid + } + + var _default = stringify + exports['default'] = _default + + /***/ + }, + + /***/ 8628: /***/ ( + __unused_webpack_module, + exports, + __nccwpck_require__ + ) => { + 'use strict' + + Object.defineProperty(exports, '__esModule', { + value: true, + }) + exports['default'] = void 0 + + var _rng = _interopRequireDefault(__nccwpck_require__(807)) + + var _stringify = _interopRequireDefault(__nccwpck_require__(8950)) + + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj } + } + + // **`v1()` - Generate time-based UUID** + // + // Inspired by https://github.com/LiosK/UUID.js + // and http://docs.python.org/library/uuid.html + let _nodeId + + let _clockseq // Previous uuid creation time + + let _lastMSecs = 0 + let _lastNSecs = 0 // See https://github.com/uuidjs/uuid for API details + + function v1(options, buf, offset) { + let i = (buf && offset) || 0 + const b = buf || new Array(16) + options = options || {} + let node = options.node || _nodeId + let clockseq = + options.clockseq !== undefined ? options.clockseq : _clockseq // node and clockseq need to be initialized to random values if they're not + // specified. We do this lazily to minimize issues related to insufficient + // system entropy. See #189 + + if (node == null || clockseq == null) { + const seedBytes = options.random || (options.rng || _rng.default)() + + if (node == null) { + // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) + node = _nodeId = [ + seedBytes[0] | 0x01, + seedBytes[1], + seedBytes[2], + seedBytes[3], + seedBytes[4], + seedBytes[5], + ] + } + + if (clockseq == null) { + // Per 4.2.2, randomize (14 bit) clockseq + clockseq = _clockseq = ((seedBytes[6] << 8) | seedBytes[7]) & 0x3fff + } + } // UUID timestamps are 100 nano-second units since the Gregorian epoch, + // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so + // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' + // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. + + let msecs = options.msecs !== undefined ? options.msecs : Date.now() // Per 4.2.1.2, use count of uuid's generated during the current clock + // cycle to simulate higher resolution clock + + let nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1 // Time since last uuid creation (in msecs) + + const dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 10000 // Per 4.2.1.2, Bump clockseq on clock regression + + if (dt < 0 && options.clockseq === undefined) { + clockseq = (clockseq + 1) & 0x3fff + } // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new + // time interval + + if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { + nsecs = 0 + } // Per 4.2.1.2 Throw error if too many uuids are requested + + if (nsecs >= 10000) { + throw new Error("uuid.v1(): Can't create more than 10M uuids/sec") + } + + _lastMSecs = msecs + _lastNSecs = nsecs + _clockseq = clockseq // Per 4.1.4 - Convert from unix epoch to Gregorian epoch + + msecs += 12219292800000 // `time_low` + + const tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000 + b[i++] = (tl >>> 24) & 0xff + b[i++] = (tl >>> 16) & 0xff + b[i++] = (tl >>> 8) & 0xff + b[i++] = tl & 0xff // `time_mid` + + const tmh = ((msecs / 0x100000000) * 10000) & 0xfffffff + b[i++] = (tmh >>> 8) & 0xff + b[i++] = tmh & 0xff // `time_high_and_version` + + b[i++] = ((tmh >>> 24) & 0xf) | 0x10 // include version + + b[i++] = (tmh >>> 16) & 0xff // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) + + b[i++] = (clockseq >>> 8) | 0x80 // `clock_seq_low` + + b[i++] = clockseq & 0xff // `node` + + for (let n = 0; n < 6; ++n) { + b[i + n] = node[n] + } + + return buf || (0, _stringify.default)(b) + } + + var _default = v1 + exports['default'] = _default + + /***/ + }, + + /***/ 6409: /***/ ( + __unused_webpack_module, + exports, + __nccwpck_require__ + ) => { + 'use strict' + + Object.defineProperty(exports, '__esModule', { + value: true, + }) + exports['default'] = void 0 + + var _v = _interopRequireDefault(__nccwpck_require__(5998)) + + var _md = _interopRequireDefault(__nccwpck_require__(4569)) + + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj } + } + + const v3 = (0, _v.default)('v3', 0x30, _md.default) + var _default = v3 + exports['default'] = _default + + /***/ + }, + + /***/ 5998: /***/ ( + __unused_webpack_module, + exports, + __nccwpck_require__ + ) => { + 'use strict' + + Object.defineProperty(exports, '__esModule', { + value: true, + }) + exports['default'] = _default + exports.URL = exports.DNS = void 0 + + var _stringify = _interopRequireDefault(__nccwpck_require__(8950)) + + var _parse = _interopRequireDefault(__nccwpck_require__(2746)) + + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj } + } + + function stringToBytes(str) { + str = unescape(encodeURIComponent(str)) // UTF8 escape + + const bytes = [] + + for (let i = 0; i < str.length; ++i) { + bytes.push(str.charCodeAt(i)) + } + + return bytes + } + + const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8' + exports.DNS = DNS + const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8' + exports.URL = URL + + function _default(name, version, hashfunc) { + function generateUUID(value, namespace, buf, offset) { + if (typeof value === 'string') { + value = stringToBytes(value) + } + + if (typeof namespace === 'string') { + namespace = (0, _parse.default)(namespace) + } + + if (namespace.length !== 16) { + throw TypeError( + 'Namespace must be array-like (16 iterable integer values, 0-255)' + ) + } // Compute hash of namespace and value, Per 4.3 + // Future: Use spread syntax when supported on all platforms, e.g. `bytes = + // hashfunc([...namespace, ... value])` + + let bytes = new Uint8Array(16 + value.length) + bytes.set(namespace) + bytes.set(value, namespace.length) + bytes = hashfunc(bytes) + bytes[6] = (bytes[6] & 0x0f) | version + bytes[8] = (bytes[8] & 0x3f) | 0x80 + + if (buf) { + offset = offset || 0 + + for (let i = 0; i < 16; ++i) { + buf[offset + i] = bytes[i] + } + + return buf + } + + return (0, _stringify.default)(bytes) + } // Function#name is not settable on some platforms (#270) + + try { + generateUUID.name = name // eslint-disable-next-line no-empty + } catch (err) {} // For CommonJS default export support + + generateUUID.DNS = DNS + generateUUID.URL = URL + return generateUUID + } + + /***/ + }, + + /***/ 5122: /***/ ( + __unused_webpack_module, + exports, + __nccwpck_require__ + ) => { + 'use strict' + + Object.defineProperty(exports, '__esModule', { + value: true, + }) + exports['default'] = void 0 + + var _rng = _interopRequireDefault(__nccwpck_require__(807)) + + var _stringify = _interopRequireDefault(__nccwpck_require__(8950)) + + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj } + } + + function v4(options, buf, offset) { + options = options || {} + + const rnds = options.random || (options.rng || _rng.default)() // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` + + rnds[6] = (rnds[6] & 0x0f) | 0x40 + rnds[8] = (rnds[8] & 0x3f) | 0x80 // Copy bytes to buffer, if provided + + if (buf) { + offset = offset || 0 + + for (let i = 0; i < 16; ++i) { + buf[offset + i] = rnds[i] + } + + return buf + } + + return (0, _stringify.default)(rnds) + } + + var _default = v4 + exports['default'] = _default + + /***/ + }, + + /***/ 9120: /***/ ( + __unused_webpack_module, + exports, + __nccwpck_require__ + ) => { + 'use strict' + + Object.defineProperty(exports, '__esModule', { + value: true, + }) + exports['default'] = void 0 + + var _v = _interopRequireDefault(__nccwpck_require__(5998)) + + var _sha = _interopRequireDefault(__nccwpck_require__(5274)) + + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj } + } + + const v5 = (0, _v.default)('v5', 0x50, _sha.default) + var _default = v5 + exports['default'] = _default + + /***/ + }, + + /***/ 6900: /***/ ( + __unused_webpack_module, + exports, + __nccwpck_require__ + ) => { + 'use strict' + + Object.defineProperty(exports, '__esModule', { + value: true, + }) + exports['default'] = void 0 + + var _regex = _interopRequireDefault(__nccwpck_require__(814)) + + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj } + } + + function validate(uuid) { + return typeof uuid === 'string' && _regex.default.test(uuid) + } + + var _default = validate + exports['default'] = _default + + /***/ + }, + + /***/ 1595: /***/ ( + __unused_webpack_module, + exports, + __nccwpck_require__ + ) => { + 'use strict' + + Object.defineProperty(exports, '__esModule', { + value: true, + }) + exports['default'] = void 0 + + var _validate = _interopRequireDefault(__nccwpck_require__(6900)) + + function _interopRequireDefault(obj) { + return obj && obj.__esModule ? obj : { default: obj } + } + + function version(uuid) { + if (!(0, _validate.default)(uuid)) { + throw TypeError('Invalid UUID') + } + + return parseInt(uuid.substr(14, 1), 16) + } + + var _default = version + exports['default'] = _default + + /***/ + }, + + /***/ 4886: /***/ (module) => { + 'use strict' + + var conversions = {} + module.exports = conversions + + function sign(x) { + return x < 0 ? -1 : 1 + } + + function evenRound(x) { + // Round x to the nearest integer, choosing the even integer if it lies halfway between two. + if (x % 1 === 0.5 && (x & 1) === 0) { + // [even number].5; round down (i.e. floor) + return Math.floor(x) + } else { + return Math.round(x) + } + } + + function createNumberConversion(bitLength, typeOpts) { + if (!typeOpts.unsigned) { + --bitLength + } + const lowerBound = typeOpts.unsigned ? 0 : -Math.pow(2, bitLength) + const upperBound = Math.pow(2, bitLength) - 1 + + const moduloVal = typeOpts.moduloBitLength + ? Math.pow(2, typeOpts.moduloBitLength) + : Math.pow(2, bitLength) + const moduloBound = typeOpts.moduloBitLength + ? Math.pow(2, typeOpts.moduloBitLength - 1) + : Math.pow(2, bitLength - 1) + + return function (V, opts) { + if (!opts) opts = {} + + let x = +V + + if (opts.enforceRange) { + if (!Number.isFinite(x)) { + throw new TypeError('Argument is not a finite number') + } + + x = sign(x) * Math.floor(Math.abs(x)) + if (x < lowerBound || x > upperBound) { + throw new TypeError('Argument is not in byte range') + } + + return x + } + + if (!isNaN(x) && opts.clamp) { + x = evenRound(x) + + if (x < lowerBound) x = lowerBound + if (x > upperBound) x = upperBound + return x + } + + if (!Number.isFinite(x) || x === 0) { + return 0 + } + + x = sign(x) * Math.floor(Math.abs(x)) + x = x % moduloVal + + if (!typeOpts.unsigned && x >= moduloBound) { + return x - moduloVal + } else if (typeOpts.unsigned) { + if (x < 0) { + x += moduloVal + } else if (x === -0) { + // don't return negative zero + return 0 + } + } + + return x + } + } + + conversions['void'] = function () { + return undefined + } + + conversions['boolean'] = function (val) { + return !!val + } + + conversions['byte'] = createNumberConversion(8, { unsigned: false }) + conversions['octet'] = createNumberConversion(8, { unsigned: true }) + + conversions['short'] = createNumberConversion(16, { unsigned: false }) + conversions['unsigned short'] = createNumberConversion(16, { + unsigned: true, + }) + + conversions['long'] = createNumberConversion(32, { unsigned: false }) + conversions['unsigned long'] = createNumberConversion(32, { + unsigned: true, + }) + + conversions['long long'] = createNumberConversion(32, { + unsigned: false, + moduloBitLength: 64, + }) + conversions['unsigned long long'] = createNumberConversion(32, { + unsigned: true, + moduloBitLength: 64, + }) + + conversions['double'] = function (V) { + const x = +V + + if (!Number.isFinite(x)) { + throw new TypeError('Argument is not a finite floating-point value') + } + + return x + } + + conversions['unrestricted double'] = function (V) { + const x = +V + + if (isNaN(x)) { + throw new TypeError('Argument is NaN') + } + + return x + } + + // not quite valid, but good enough for JS + conversions['float'] = conversions['double'] + conversions['unrestricted float'] = conversions['unrestricted double'] + + conversions['DOMString'] = function (V, opts) { + if (!opts) opts = {} + + if (opts.treatNullAsEmptyString && V === null) { + return '' + } + + return String(V) + } + + conversions['ByteString'] = function (V, opts) { + const x = String(V) + let c = undefined + for (let i = 0; (c = x.codePointAt(i)) !== undefined; ++i) { + if (c > 255) { + throw new TypeError('Argument is not a valid bytestring') + } + } + + return x + } + + conversions['USVString'] = function (V) { + const S = String(V) + const n = S.length + const U = [] + for (let i = 0; i < n; ++i) { + const c = S.charCodeAt(i) + if (c < 0xd800 || c > 0xdfff) { + U.push(String.fromCodePoint(c)) + } else if (0xdc00 <= c && c <= 0xdfff) { + U.push(String.fromCodePoint(0xfffd)) + } else { + if (i === n - 1) { + U.push(String.fromCodePoint(0xfffd)) + } else { + const d = S.charCodeAt(i + 1) + if (0xdc00 <= d && d <= 0xdfff) { + const a = c & 0x3ff + const b = d & 0x3ff + U.push(String.fromCodePoint((2 << 15) + (2 << 9) * a + b)) + ++i + } else { + U.push(String.fromCodePoint(0xfffd)) + } + } + } + } + + return U.join('') + } + + conversions['Date'] = function (V, opts) { + if (!(V instanceof Date)) { + throw new TypeError('Argument is not a Date object') + } + if (isNaN(V)) { + return undefined + } + + return V + } + + conversions['RegExp'] = function (V, opts) { + if (!(V instanceof RegExp)) { + V = new RegExp(V) + } + + return V + } + + /***/ + }, + + /***/ 7537: /***/ ( + __unused_webpack_module, + exports, + __nccwpck_require__ + ) => { + 'use strict' + + const usm = __nccwpck_require__(2158) + + exports.implementation = class URLImpl { + constructor(constructorArgs) { + const url = constructorArgs[0] + const base = constructorArgs[1] + + let parsedBase = null + if (base !== undefined) { + parsedBase = usm.basicURLParse(base) + if (parsedBase === 'failure') { + throw new TypeError('Invalid base URL') + } + } + + const parsedURL = usm.basicURLParse(url, { baseURL: parsedBase }) + if (parsedURL === 'failure') { + throw new TypeError('Invalid URL') + } + + this._url = parsedURL + + // TODO: query stuff + } + + get href() { + return usm.serializeURL(this._url) + } + + set href(v) { + const parsedURL = usm.basicURLParse(v) + if (parsedURL === 'failure') { + throw new TypeError('Invalid URL') + } + + this._url = parsedURL + } + + get origin() { + return usm.serializeURLOrigin(this._url) + } + + get protocol() { + return this._url.scheme + ':' + } + + set protocol(v) { + usm.basicURLParse(v + ':', { + url: this._url, + stateOverride: 'scheme start', + }) + } + + get username() { + return this._url.username + } + + set username(v) { + if (usm.cannotHaveAUsernamePasswordPort(this._url)) { + return + } + + usm.setTheUsername(this._url, v) + } + + get password() { + return this._url.password + } + + set password(v) { + if (usm.cannotHaveAUsernamePasswordPort(this._url)) { + return + } + + usm.setThePassword(this._url, v) + } + + get host() { + const url = this._url + + if (url.host === null) { + return '' + } + + if (url.port === null) { + return usm.serializeHost(url.host) + } + + return ( + usm.serializeHost(url.host) + ':' + usm.serializeInteger(url.port) + ) + } + + set host(v) { + if (this._url.cannotBeABaseURL) { + return + } + + usm.basicURLParse(v, { url: this._url, stateOverride: 'host' }) + } + + get hostname() { + if (this._url.host === null) { + return '' + } + + return usm.serializeHost(this._url.host) + } + + set hostname(v) { + if (this._url.cannotBeABaseURL) { + return + } + + usm.basicURLParse(v, { url: this._url, stateOverride: 'hostname' }) + } + + get port() { + if (this._url.port === null) { + return '' + } + + return usm.serializeInteger(this._url.port) + } + + set port(v) { + if (usm.cannotHaveAUsernamePasswordPort(this._url)) { + return + } + + if (v === '') { + this._url.port = null + } else { + usm.basicURLParse(v, { url: this._url, stateOverride: 'port' }) + } + } + + get pathname() { + if (this._url.cannotBeABaseURL) { + return this._url.path[0] + } + + if (this._url.path.length === 0) { + return '' + } + + return '/' + this._url.path.join('/') + } + + set pathname(v) { + if (this._url.cannotBeABaseURL) { + return + } + + this._url.path = [] + usm.basicURLParse(v, { url: this._url, stateOverride: 'path start' }) + } + + get search() { + if (this._url.query === null || this._url.query === '') { + return '' + } + + return '?' + this._url.query + } + + set search(v) { + // TODO: query stuff + + const url = this._url + + if (v === '') { + url.query = null + return + } + + const input = v[0] === '?' ? v.substring(1) : v + url.query = '' + usm.basicURLParse(input, { url, stateOverride: 'query' }) + } + + get hash() { + if (this._url.fragment === null || this._url.fragment === '') { + return '' + } + + return '#' + this._url.fragment + } + + set hash(v) { + if (v === '') { + this._url.fragment = null + return + } + + const input = v[0] === '#' ? v.substring(1) : v + this._url.fragment = '' + usm.basicURLParse(input, { + url: this._url, + stateOverride: 'fragment', + }) + } + + toJSON() { + return this.href + } + } + + /***/ + }, + + /***/ 3394: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const conversions = __nccwpck_require__(4886) + const utils = __nccwpck_require__(3185) + const Impl = __nccwpck_require__(7537) + + const impl = utils.implSymbol + + function URL(url) { + if (!this || this[impl] || !(this instanceof URL)) { + throw new TypeError( + "Failed to construct 'URL': Please use the 'new' operator, this DOM object constructor cannot be called as a function." + ) + } + if (arguments.length < 1) { + throw new TypeError( + "Failed to construct 'URL': 1 argument required, but only " + + arguments.length + + ' present.' + ) + } + const args = [] + for (let i = 0; i < arguments.length && i < 2; ++i) { + args[i] = arguments[i] + } + args[0] = conversions['USVString'](args[0]) + if (args[1] !== undefined) { + args[1] = conversions['USVString'](args[1]) + } + + module.exports.setup(this, args) + } + + URL.prototype.toJSON = function toJSON() { + if (!this || !module.exports.is(this)) { + throw new TypeError('Illegal invocation') + } + const args = [] + for (let i = 0; i < arguments.length && i < 0; ++i) { + args[i] = arguments[i] + } + return this[impl].toJSON.apply(this[impl], args) + } + Object.defineProperty(URL.prototype, 'href', { + get() { + return this[impl].href + }, + set(V) { + V = conversions['USVString'](V) + this[impl].href = V + }, + enumerable: true, + configurable: true, + }) + + URL.prototype.toString = function () { + if (!this || !module.exports.is(this)) { + throw new TypeError('Illegal invocation') + } + return this.href + } + + Object.defineProperty(URL.prototype, 'origin', { + get() { + return this[impl].origin + }, + enumerable: true, + configurable: true, + }) + + Object.defineProperty(URL.prototype, 'protocol', { + get() { + return this[impl].protocol + }, + set(V) { + V = conversions['USVString'](V) + this[impl].protocol = V + }, + enumerable: true, + configurable: true, + }) + + Object.defineProperty(URL.prototype, 'username', { + get() { + return this[impl].username + }, + set(V) { + V = conversions['USVString'](V) + this[impl].username = V + }, + enumerable: true, + configurable: true, + }) + + Object.defineProperty(URL.prototype, 'password', { + get() { + return this[impl].password + }, + set(V) { + V = conversions['USVString'](V) + this[impl].password = V + }, + enumerable: true, + configurable: true, + }) + + Object.defineProperty(URL.prototype, 'host', { + get() { + return this[impl].host + }, + set(V) { + V = conversions['USVString'](V) + this[impl].host = V + }, + enumerable: true, + configurable: true, + }) + + Object.defineProperty(URL.prototype, 'hostname', { + get() { + return this[impl].hostname + }, + set(V) { + V = conversions['USVString'](V) + this[impl].hostname = V + }, + enumerable: true, + configurable: true, + }) + + Object.defineProperty(URL.prototype, 'port', { + get() { + return this[impl].port + }, + set(V) { + V = conversions['USVString'](V) + this[impl].port = V + }, + enumerable: true, + configurable: true, + }) + + Object.defineProperty(URL.prototype, 'pathname', { + get() { + return this[impl].pathname + }, + set(V) { + V = conversions['USVString'](V) + this[impl].pathname = V + }, + enumerable: true, + configurable: true, + }) + + Object.defineProperty(URL.prototype, 'search', { + get() { + return this[impl].search + }, + set(V) { + V = conversions['USVString'](V) + this[impl].search = V + }, + enumerable: true, + configurable: true, + }) + + Object.defineProperty(URL.prototype, 'hash', { + get() { + return this[impl].hash + }, + set(V) { + V = conversions['USVString'](V) + this[impl].hash = V + }, + enumerable: true, + configurable: true, + }) + + module.exports = { + is(obj) { + return !!obj && obj[impl] instanceof Impl.implementation + }, + create(constructorArgs, privateData) { + let obj = Object.create(URL.prototype) + this.setup(obj, constructorArgs, privateData) + return obj + }, + setup(obj, constructorArgs, privateData) { + if (!privateData) privateData = {} + privateData.wrapper = obj + + obj[impl] = new Impl.implementation(constructorArgs, privateData) + obj[impl][utils.wrapperSymbol] = obj + }, + interface: URL, + expose: { + Window: { URL: URL }, + Worker: { URL: URL }, + }, + } + + /***/ + }, + + /***/ 8665: /***/ ( + __unused_webpack_module, + exports, + __nccwpck_require__ + ) => { + 'use strict' + + exports.URL = __nccwpck_require__(3394)['interface'] + exports.serializeURL = __nccwpck_require__(2158).serializeURL + exports.serializeURLOrigin = __nccwpck_require__(2158).serializeURLOrigin + exports.basicURLParse = __nccwpck_require__(2158).basicURLParse + exports.setTheUsername = __nccwpck_require__(2158).setTheUsername + exports.setThePassword = __nccwpck_require__(2158).setThePassword + exports.serializeHost = __nccwpck_require__(2158).serializeHost + exports.serializeInteger = __nccwpck_require__(2158).serializeInteger + exports.parseURL = __nccwpck_require__(2158).parseURL + + /***/ + }, + + /***/ 2158: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const punycode = __nccwpck_require__(5477) + const tr46 = __nccwpck_require__(4256) + + const specialSchemes = { + ftp: 21, + file: null, + gopher: 70, + http: 80, + https: 443, + ws: 80, + wss: 443, + } + + const failure = Symbol('failure') + + function countSymbols(str) { + return punycode.ucs2.decode(str).length + } + + function at(input, idx) { + const c = input[idx] + return isNaN(c) ? undefined : String.fromCodePoint(c) + } + + function isASCIIDigit(c) { + return c >= 0x30 && c <= 0x39 + } + + function isASCIIAlpha(c) { + return (c >= 0x41 && c <= 0x5a) || (c >= 0x61 && c <= 0x7a) + } + + function isASCIIAlphanumeric(c) { + return isASCIIAlpha(c) || isASCIIDigit(c) + } + + function isASCIIHex(c) { + return ( + isASCIIDigit(c) || + (c >= 0x41 && c <= 0x46) || + (c >= 0x61 && c <= 0x66) + ) + } + + function isSingleDot(buffer) { + return buffer === '.' || buffer.toLowerCase() === '%2e' + } + + function isDoubleDot(buffer) { + buffer = buffer.toLowerCase() + return ( + buffer === '..' || + buffer === '%2e.' || + buffer === '.%2e' || + buffer === '%2e%2e' + ) + } + + function isWindowsDriveLetterCodePoints(cp1, cp2) { + return isASCIIAlpha(cp1) && (cp2 === 58 || cp2 === 124) + } + + function isWindowsDriveLetterString(string) { + return ( + string.length === 2 && + isASCIIAlpha(string.codePointAt(0)) && + (string[1] === ':' || string[1] === '|') + ) + } + + function isNormalizedWindowsDriveLetterString(string) { + return ( + string.length === 2 && + isASCIIAlpha(string.codePointAt(0)) && + string[1] === ':' + ) + } + + function containsForbiddenHostCodePoint(string) { + return ( + string.search( + /\u0000|\u0009|\u000A|\u000D|\u0020|#|%|\/|:|\?|@|\[|\\|\]/ + ) !== -1 + ) + } + + function containsForbiddenHostCodePointExcludingPercent(string) { + return ( + string.search( + /\u0000|\u0009|\u000A|\u000D|\u0020|#|\/|:|\?|@|\[|\\|\]/ + ) !== -1 + ) + } + + function isSpecialScheme(scheme) { + return specialSchemes[scheme] !== undefined + } + + function isSpecial(url) { + return isSpecialScheme(url.scheme) + } + + function defaultPort(scheme) { + return specialSchemes[scheme] + } + + function percentEncode(c) { + let hex = c.toString(16).toUpperCase() + if (hex.length === 1) { + hex = '0' + hex + } + + return '%' + hex + } + + function utf8PercentEncode(c) { + const buf = new Buffer(c) + + let str = '' + + for (let i = 0; i < buf.length; ++i) { + str += percentEncode(buf[i]) + } + + return str + } + + function utf8PercentDecode(str) { + const input = new Buffer(str) + const output = [] + for (let i = 0; i < input.length; ++i) { + if (input[i] !== 37) { + output.push(input[i]) + } else if ( + input[i] === 37 && + isASCIIHex(input[i + 1]) && + isASCIIHex(input[i + 2]) + ) { + output.push(parseInt(input.slice(i + 1, i + 3).toString(), 16)) + i += 2 + } else { + output.push(input[i]) + } + } + return new Buffer(output).toString() + } + + function isC0ControlPercentEncode(c) { + return c <= 0x1f || c > 0x7e + } + + const extraPathPercentEncodeSet = new Set([ + 32, 34, 35, 60, 62, 63, 96, 123, 125, + ]) + function isPathPercentEncode(c) { + return isC0ControlPercentEncode(c) || extraPathPercentEncodeSet.has(c) + } + + const extraUserinfoPercentEncodeSet = new Set([ + 47, 58, 59, 61, 64, 91, 92, 93, 94, 124, + ]) + function isUserinfoPercentEncode(c) { + return isPathPercentEncode(c) || extraUserinfoPercentEncodeSet.has(c) + } + + function percentEncodeChar(c, encodeSetPredicate) { + const cStr = String.fromCodePoint(c) + + if (encodeSetPredicate(c)) { + return utf8PercentEncode(cStr) + } + + return cStr + } + + function parseIPv4Number(input) { + let R = 10 + + if ( + input.length >= 2 && + input.charAt(0) === '0' && + input.charAt(1).toLowerCase() === 'x' + ) { + input = input.substring(2) + R = 16 + } else if (input.length >= 2 && input.charAt(0) === '0') { + input = input.substring(1) + R = 8 + } + + if (input === '') { + return 0 + } + + const regex = R === 10 ? /[^0-9]/ : R === 16 ? /[^0-9A-Fa-f]/ : /[^0-7]/ + if (regex.test(input)) { + return failure + } + + return parseInt(input, R) + } + + function parseIPv4(input) { + const parts = input.split('.') + if (parts[parts.length - 1] === '') { + if (parts.length > 1) { + parts.pop() + } + } + + if (parts.length > 4) { + return input + } + + const numbers = [] + for (const part of parts) { + if (part === '') { + return input + } + const n = parseIPv4Number(part) + if (n === failure) { + return input + } + + numbers.push(n) + } + + for (let i = 0; i < numbers.length - 1; ++i) { + if (numbers[i] > 255) { + return failure + } + } + if (numbers[numbers.length - 1] >= Math.pow(256, 5 - numbers.length)) { + return failure + } + + let ipv4 = numbers.pop() + let counter = 0 + + for (const n of numbers) { + ipv4 += n * Math.pow(256, 3 - counter) + ++counter + } + + return ipv4 + } + + function serializeIPv4(address) { + let output = '' + let n = address + + for (let i = 1; i <= 4; ++i) { + output = String(n % 256) + output + if (i !== 4) { + output = '.' + output + } + n = Math.floor(n / 256) + } + + return output + } + + function parseIPv6(input) { + const address = [0, 0, 0, 0, 0, 0, 0, 0] + let pieceIndex = 0 + let compress = null + let pointer = 0 + + input = punycode.ucs2.decode(input) + + if (input[pointer] === 58) { + if (input[pointer + 1] !== 58) { + return failure + } + + pointer += 2 + ++pieceIndex + compress = pieceIndex + } + + while (pointer < input.length) { + if (pieceIndex === 8) { + return failure + } + + if (input[pointer] === 58) { + if (compress !== null) { + return failure + } + ++pointer + ++pieceIndex + compress = pieceIndex + continue + } + + let value = 0 + let length = 0 + + while (length < 4 && isASCIIHex(input[pointer])) { + value = value * 0x10 + parseInt(at(input, pointer), 16) + ++pointer + ++length + } + + if (input[pointer] === 46) { + if (length === 0) { + return failure + } + + pointer -= length + + if (pieceIndex > 6) { + return failure + } + + let numbersSeen = 0 + + while (input[pointer] !== undefined) { + let ipv4Piece = null + + if (numbersSeen > 0) { + if (input[pointer] === 46 && numbersSeen < 4) { + ++pointer + } else { + return failure + } + } + + if (!isASCIIDigit(input[pointer])) { + return failure + } + + while (isASCIIDigit(input[pointer])) { + const number = parseInt(at(input, pointer)) + if (ipv4Piece === null) { + ipv4Piece = number + } else if (ipv4Piece === 0) { + return failure + } else { + ipv4Piece = ipv4Piece * 10 + number + } + if (ipv4Piece > 255) { + return failure + } + ++pointer + } + + address[pieceIndex] = address[pieceIndex] * 0x100 + ipv4Piece + + ++numbersSeen + + if (numbersSeen === 2 || numbersSeen === 4) { + ++pieceIndex + } + } + + if (numbersSeen !== 4) { + return failure + } + + break + } else if (input[pointer] === 58) { + ++pointer + if (input[pointer] === undefined) { + return failure + } + } else if (input[pointer] !== undefined) { + return failure + } + + address[pieceIndex] = value + ++pieceIndex + } + + if (compress !== null) { + let swaps = pieceIndex - compress + pieceIndex = 7 + while (pieceIndex !== 0 && swaps > 0) { + const temp = address[compress + swaps - 1] + address[compress + swaps - 1] = address[pieceIndex] + address[pieceIndex] = temp + --pieceIndex + --swaps + } + } else if (compress === null && pieceIndex !== 8) { + return failure + } + + return address + } + + function serializeIPv6(address) { + let output = '' + const seqResult = findLongestZeroSequence(address) + const compress = seqResult.idx + let ignore0 = false + + for (let pieceIndex = 0; pieceIndex <= 7; ++pieceIndex) { + if (ignore0 && address[pieceIndex] === 0) { + continue + } else if (ignore0) { + ignore0 = false + } + + if (compress === pieceIndex) { + const separator = pieceIndex === 0 ? '::' : ':' + output += separator + ignore0 = true + continue + } + + output += address[pieceIndex].toString(16) + + if (pieceIndex !== 7) { + output += ':' + } + } + + return output + } + + function parseHost(input, isSpecialArg) { + if (input[0] === '[') { + if (input[input.length - 1] !== ']') { + return failure + } + + return parseIPv6(input.substring(1, input.length - 1)) + } + + if (!isSpecialArg) { + return parseOpaqueHost(input) + } + + const domain = utf8PercentDecode(input) + const asciiDomain = tr46.toASCII( + domain, + false, + tr46.PROCESSING_OPTIONS.NONTRANSITIONAL, + false + ) + if (asciiDomain === null) { + return failure + } + + if (containsForbiddenHostCodePoint(asciiDomain)) { + return failure + } + + const ipv4Host = parseIPv4(asciiDomain) + if (typeof ipv4Host === 'number' || ipv4Host === failure) { + return ipv4Host + } + + return asciiDomain + } + + function parseOpaqueHost(input) { + if (containsForbiddenHostCodePointExcludingPercent(input)) { + return failure + } + + let output = '' + const decoded = punycode.ucs2.decode(input) + for (let i = 0; i < decoded.length; ++i) { + output += percentEncodeChar(decoded[i], isC0ControlPercentEncode) + } + return output + } + + function findLongestZeroSequence(arr) { + let maxIdx = null + let maxLen = 1 // only find elements > 1 + let currStart = null + let currLen = 0 + + for (let i = 0; i < arr.length; ++i) { + if (arr[i] !== 0) { + if (currLen > maxLen) { + maxIdx = currStart + maxLen = currLen + } + + currStart = null + currLen = 0 + } else { + if (currStart === null) { + currStart = i + } + ++currLen + } + } + + // if trailing zeros + if (currLen > maxLen) { + maxIdx = currStart + maxLen = currLen + } + + return { + idx: maxIdx, + len: maxLen, + } + } + + function serializeHost(host) { + if (typeof host === 'number') { + return serializeIPv4(host) + } + + // IPv6 serializer + if (host instanceof Array) { + return '[' + serializeIPv6(host) + ']' + } + + return host + } + + function trimControlChars(url) { + return url.replace( + /^[\u0000-\u001F\u0020]+|[\u0000-\u001F\u0020]+$/g, + '' + ) + } + + function trimTabAndNewline(url) { + return url.replace(/\u0009|\u000A|\u000D/g, '') + } + + function shortenPath(url) { + const path = url.path + if (path.length === 0) { + return + } + if ( + url.scheme === 'file' && + path.length === 1 && + isNormalizedWindowsDriveLetter(path[0]) + ) { + return + } + + path.pop() + } + + function includesCredentials(url) { + return url.username !== '' || url.password !== '' + } + + function cannotHaveAUsernamePasswordPort(url) { + return ( + url.host === null || + url.host === '' || + url.cannotBeABaseURL || + url.scheme === 'file' + ) + } + + function isNormalizedWindowsDriveLetter(string) { + return /^[A-Za-z]:$/.test(string) + } + + function URLStateMachine( + input, + base, + encodingOverride, + url, + stateOverride + ) { + this.pointer = 0 + this.input = input + this.base = base || null + this.encodingOverride = encodingOverride || 'utf-8' + this.stateOverride = stateOverride + this.url = url + this.failure = false + this.parseError = false + + if (!this.url) { + this.url = { + scheme: '', + username: '', + password: '', + host: null, + port: null, + path: [], + query: null, + fragment: null, + + cannotBeABaseURL: false, + } + + const res = trimControlChars(this.input) + if (res !== this.input) { + this.parseError = true + } + this.input = res + } + + const res = trimTabAndNewline(this.input) + if (res !== this.input) { + this.parseError = true + } + this.input = res + + this.state = stateOverride || 'scheme start' + + this.buffer = '' + this.atFlag = false + this.arrFlag = false + this.passwordTokenSeenFlag = false + + this.input = punycode.ucs2.decode(this.input) + + for (; this.pointer <= this.input.length; ++this.pointer) { + const c = this.input[this.pointer] + const cStr = isNaN(c) ? undefined : String.fromCodePoint(c) + + // exec state machine + const ret = this['parse ' + this.state](c, cStr) + if (!ret) { + break // terminate algorithm + } else if (ret === failure) { + this.failure = true + break + } + } + } + + URLStateMachine.prototype['parse scheme start'] = + function parseSchemeStart(c, cStr) { + if (isASCIIAlpha(c)) { + this.buffer += cStr.toLowerCase() + this.state = 'scheme' + } else if (!this.stateOverride) { + this.state = 'no scheme' + --this.pointer + } else { + this.parseError = true + return failure + } + + return true + } + + URLStateMachine.prototype['parse scheme'] = function parseScheme( + c, + cStr + ) { + if (isASCIIAlphanumeric(c) || c === 43 || c === 45 || c === 46) { + this.buffer += cStr.toLowerCase() + } else if (c === 58) { + if (this.stateOverride) { + if (isSpecial(this.url) && !isSpecialScheme(this.buffer)) { + return false + } + + if (!isSpecial(this.url) && isSpecialScheme(this.buffer)) { + return false + } + + if ( + (includesCredentials(this.url) || this.url.port !== null) && + this.buffer === 'file' + ) { + return false + } + + if ( + this.url.scheme === 'file' && + (this.url.host === '' || this.url.host === null) + ) { + return false + } + } + this.url.scheme = this.buffer + this.buffer = '' + if (this.stateOverride) { + return false + } + if (this.url.scheme === 'file') { + if ( + this.input[this.pointer + 1] !== 47 || + this.input[this.pointer + 2] !== 47 + ) { + this.parseError = true + } + this.state = 'file' + } else if ( + isSpecial(this.url) && + this.base !== null && + this.base.scheme === this.url.scheme + ) { + this.state = 'special relative or authority' + } else if (isSpecial(this.url)) { + this.state = 'special authority slashes' + } else if (this.input[this.pointer + 1] === 47) { + this.state = 'path or authority' + ++this.pointer + } else { + this.url.cannotBeABaseURL = true + this.url.path.push('') + this.state = 'cannot-be-a-base-URL path' + } + } else if (!this.stateOverride) { + this.buffer = '' + this.state = 'no scheme' + this.pointer = -1 + } else { + this.parseError = true + return failure + } + + return true + } + + URLStateMachine.prototype['parse no scheme'] = function parseNoScheme(c) { + if (this.base === null || (this.base.cannotBeABaseURL && c !== 35)) { + return failure + } else if (this.base.cannotBeABaseURL && c === 35) { + this.url.scheme = this.base.scheme + this.url.path = this.base.path.slice() + this.url.query = this.base.query + this.url.fragment = '' + this.url.cannotBeABaseURL = true + this.state = 'fragment' + } else if (this.base.scheme === 'file') { + this.state = 'file' + --this.pointer + } else { + this.state = 'relative' + --this.pointer + } + + return true + } + + URLStateMachine.prototype['parse special relative or authority'] = + function parseSpecialRelativeOrAuthority(c) { + if (c === 47 && this.input[this.pointer + 1] === 47) { + this.state = 'special authority ignore slashes' + ++this.pointer + } else { + this.parseError = true + this.state = 'relative' + --this.pointer + } + + return true + } + + URLStateMachine.prototype['parse path or authority'] = + function parsePathOrAuthority(c) { + if (c === 47) { + this.state = 'authority' + } else { + this.state = 'path' + --this.pointer + } + + return true + } + + URLStateMachine.prototype['parse relative'] = function parseRelative(c) { + this.url.scheme = this.base.scheme + if (isNaN(c)) { + this.url.username = this.base.username + this.url.password = this.base.password + this.url.host = this.base.host + this.url.port = this.base.port + this.url.path = this.base.path.slice() + this.url.query = this.base.query + } else if (c === 47) { + this.state = 'relative slash' + } else if (c === 63) { + this.url.username = this.base.username + this.url.password = this.base.password + this.url.host = this.base.host + this.url.port = this.base.port + this.url.path = this.base.path.slice() + this.url.query = '' + this.state = 'query' + } else if (c === 35) { + this.url.username = this.base.username + this.url.password = this.base.password + this.url.host = this.base.host + this.url.port = this.base.port + this.url.path = this.base.path.slice() + this.url.query = this.base.query + this.url.fragment = '' + this.state = 'fragment' + } else if (isSpecial(this.url) && c === 92) { + this.parseError = true + this.state = 'relative slash' + } else { + this.url.username = this.base.username + this.url.password = this.base.password + this.url.host = this.base.host + this.url.port = this.base.port + this.url.path = this.base.path.slice(0, this.base.path.length - 1) + + this.state = 'path' + --this.pointer + } + + return true + } + + URLStateMachine.prototype['parse relative slash'] = + function parseRelativeSlash(c) { + if (isSpecial(this.url) && (c === 47 || c === 92)) { + if (c === 92) { + this.parseError = true + } + this.state = 'special authority ignore slashes' + } else if (c === 47) { + this.state = 'authority' + } else { + this.url.username = this.base.username + this.url.password = this.base.password + this.url.host = this.base.host + this.url.port = this.base.port + this.state = 'path' + --this.pointer + } + + return true + } + + URLStateMachine.prototype['parse special authority slashes'] = + function parseSpecialAuthoritySlashes(c) { + if (c === 47 && this.input[this.pointer + 1] === 47) { + this.state = 'special authority ignore slashes' + ++this.pointer + } else { + this.parseError = true + this.state = 'special authority ignore slashes' + --this.pointer + } + + return true + } + + URLStateMachine.prototype['parse special authority ignore slashes'] = + function parseSpecialAuthorityIgnoreSlashes(c) { + if (c !== 47 && c !== 92) { + this.state = 'authority' + --this.pointer + } else { + this.parseError = true + } + + return true + } + + URLStateMachine.prototype['parse authority'] = function parseAuthority( + c, + cStr + ) { + if (c === 64) { + this.parseError = true + if (this.atFlag) { + this.buffer = '%40' + this.buffer + } + this.atFlag = true + + // careful, this is based on buffer and has its own pointer (this.pointer != pointer) and inner chars + const len = countSymbols(this.buffer) + for (let pointer = 0; pointer < len; ++pointer) { + const codePoint = this.buffer.codePointAt(pointer) + + if (codePoint === 58 && !this.passwordTokenSeenFlag) { + this.passwordTokenSeenFlag = true + continue + } + const encodedCodePoints = percentEncodeChar( + codePoint, + isUserinfoPercentEncode + ) + if (this.passwordTokenSeenFlag) { + this.url.password += encodedCodePoints + } else { + this.url.username += encodedCodePoints + } + } + this.buffer = '' + } else if ( + isNaN(c) || + c === 47 || + c === 63 || + c === 35 || + (isSpecial(this.url) && c === 92) + ) { + if (this.atFlag && this.buffer === '') { + this.parseError = true + return failure + } + this.pointer -= countSymbols(this.buffer) + 1 + this.buffer = '' + this.state = 'host' + } else { + this.buffer += cStr + } + + return true + } + + URLStateMachine.prototype['parse hostname'] = URLStateMachine.prototype[ + 'parse host' + ] = function parseHostName(c, cStr) { + if (this.stateOverride && this.url.scheme === 'file') { + --this.pointer + this.state = 'file host' + } else if (c === 58 && !this.arrFlag) { + if (this.buffer === '') { + this.parseError = true + return failure + } + + const host = parseHost(this.buffer, isSpecial(this.url)) + if (host === failure) { + return failure + } + + this.url.host = host + this.buffer = '' + this.state = 'port' + if (this.stateOverride === 'hostname') { + return false + } + } else if ( + isNaN(c) || + c === 47 || + c === 63 || + c === 35 || + (isSpecial(this.url) && c === 92) + ) { + --this.pointer + if (isSpecial(this.url) && this.buffer === '') { + this.parseError = true + return failure + } else if ( + this.stateOverride && + this.buffer === '' && + (includesCredentials(this.url) || this.url.port !== null) + ) { + this.parseError = true + return false + } + + const host = parseHost(this.buffer, isSpecial(this.url)) + if (host === failure) { + return failure + } + + this.url.host = host + this.buffer = '' + this.state = 'path start' + if (this.stateOverride) { + return false + } + } else { + if (c === 91) { + this.arrFlag = true + } else if (c === 93) { + this.arrFlag = false + } + this.buffer += cStr + } + + return true + } + + URLStateMachine.prototype['parse port'] = function parsePort(c, cStr) { + if (isASCIIDigit(c)) { + this.buffer += cStr + } else if ( + isNaN(c) || + c === 47 || + c === 63 || + c === 35 || + (isSpecial(this.url) && c === 92) || + this.stateOverride + ) { + if (this.buffer !== '') { + const port = parseInt(this.buffer) + if (port > Math.pow(2, 16) - 1) { + this.parseError = true + return failure + } + this.url.port = port === defaultPort(this.url.scheme) ? null : port + this.buffer = '' + } + if (this.stateOverride) { + return false + } + this.state = 'path start' + --this.pointer + } else { + this.parseError = true + return failure + } + + return true + } + + const fileOtherwiseCodePoints = new Set([47, 92, 63, 35]) + + URLStateMachine.prototype['parse file'] = function parseFile(c) { + this.url.scheme = 'file' + + if (c === 47 || c === 92) { + if (c === 92) { + this.parseError = true + } + this.state = 'file slash' + } else if (this.base !== null && this.base.scheme === 'file') { + if (isNaN(c)) { + this.url.host = this.base.host + this.url.path = this.base.path.slice() + this.url.query = this.base.query + } else if (c === 63) { + this.url.host = this.base.host + this.url.path = this.base.path.slice() + this.url.query = '' + this.state = 'query' + } else if (c === 35) { + this.url.host = this.base.host + this.url.path = this.base.path.slice() + this.url.query = this.base.query + this.url.fragment = '' + this.state = 'fragment' + } else { + if ( + this.input.length - this.pointer - 1 === 0 || // remaining consists of 0 code points + !isWindowsDriveLetterCodePoints( + c, + this.input[this.pointer + 1] + ) || + (this.input.length - this.pointer - 1 >= 2 && // remaining has at least 2 code points + !fileOtherwiseCodePoints.has(this.input[this.pointer + 2])) + ) { + this.url.host = this.base.host + this.url.path = this.base.path.slice() + shortenPath(this.url) + } else { + this.parseError = true + } + + this.state = 'path' + --this.pointer + } + } else { + this.state = 'path' + --this.pointer + } + + return true + } + + URLStateMachine.prototype['parse file slash'] = function parseFileSlash( + c + ) { + if (c === 47 || c === 92) { + if (c === 92) { + this.parseError = true + } + this.state = 'file host' + } else { + if (this.base !== null && this.base.scheme === 'file') { + if (isNormalizedWindowsDriveLetterString(this.base.path[0])) { + this.url.path.push(this.base.path[0]) + } else { + this.url.host = this.base.host + } + } + this.state = 'path' + --this.pointer + } + + return true + } + + URLStateMachine.prototype['parse file host'] = function parseFileHost( + c, + cStr + ) { + if (isNaN(c) || c === 47 || c === 92 || c === 63 || c === 35) { + --this.pointer + if (!this.stateOverride && isWindowsDriveLetterString(this.buffer)) { + this.parseError = true + this.state = 'path' + } else if (this.buffer === '') { + this.url.host = '' + if (this.stateOverride) { + return false + } + this.state = 'path start' + } else { + let host = parseHost(this.buffer, isSpecial(this.url)) + if (host === failure) { + return failure + } + if (host === 'localhost') { + host = '' + } + this.url.host = host + + if (this.stateOverride) { + return false + } + + this.buffer = '' + this.state = 'path start' + } + } else { + this.buffer += cStr + } + + return true + } + + URLStateMachine.prototype['parse path start'] = function parsePathStart( + c + ) { + if (isSpecial(this.url)) { + if (c === 92) { + this.parseError = true + } + this.state = 'path' + + if (c !== 47 && c !== 92) { + --this.pointer + } + } else if (!this.stateOverride && c === 63) { + this.url.query = '' + this.state = 'query' + } else if (!this.stateOverride && c === 35) { + this.url.fragment = '' + this.state = 'fragment' + } else if (c !== undefined) { + this.state = 'path' + if (c !== 47) { + --this.pointer + } + } + + return true + } + + URLStateMachine.prototype['parse path'] = function parsePath(c) { + if ( + isNaN(c) || + c === 47 || + (isSpecial(this.url) && c === 92) || + (!this.stateOverride && (c === 63 || c === 35)) + ) { + if (isSpecial(this.url) && c === 92) { + this.parseError = true + } + + if (isDoubleDot(this.buffer)) { + shortenPath(this.url) + if (c !== 47 && !(isSpecial(this.url) && c === 92)) { + this.url.path.push('') + } + } else if ( + isSingleDot(this.buffer) && + c !== 47 && + !(isSpecial(this.url) && c === 92) + ) { + this.url.path.push('') + } else if (!isSingleDot(this.buffer)) { + if ( + this.url.scheme === 'file' && + this.url.path.length === 0 && + isWindowsDriveLetterString(this.buffer) + ) { + if (this.url.host !== '' && this.url.host !== null) { + this.parseError = true + this.url.host = '' + } + this.buffer = this.buffer[0] + ':' + } + this.url.path.push(this.buffer) + } + this.buffer = '' + if ( + this.url.scheme === 'file' && + (c === undefined || c === 63 || c === 35) + ) { + while (this.url.path.length > 1 && this.url.path[0] === '') { + this.parseError = true + this.url.path.shift() + } + } + if (c === 63) { + this.url.query = '' + this.state = 'query' + } + if (c === 35) { + this.url.fragment = '' + this.state = 'fragment' + } + } else { + // TODO: If c is not a URL code point and not "%", parse error. + + if ( + c === 37 && + (!isASCIIHex(this.input[this.pointer + 1]) || + !isASCIIHex(this.input[this.pointer + 2])) + ) { + this.parseError = true + } + + this.buffer += percentEncodeChar(c, isPathPercentEncode) + } + + return true + } + + URLStateMachine.prototype['parse cannot-be-a-base-URL path'] = + function parseCannotBeABaseURLPath(c) { + if (c === 63) { + this.url.query = '' + this.state = 'query' + } else if (c === 35) { + this.url.fragment = '' + this.state = 'fragment' + } else { + // TODO: Add: not a URL code point + if (!isNaN(c) && c !== 37) { + this.parseError = true + } + + if ( + c === 37 && + (!isASCIIHex(this.input[this.pointer + 1]) || + !isASCIIHex(this.input[this.pointer + 2])) + ) { + this.parseError = true + } + + if (!isNaN(c)) { + this.url.path[0] = + this.url.path[0] + + percentEncodeChar(c, isC0ControlPercentEncode) + } + } + + return true + } + + URLStateMachine.prototype['parse query'] = function parseQuery(c, cStr) { + if (isNaN(c) || (!this.stateOverride && c === 35)) { + if ( + !isSpecial(this.url) || + this.url.scheme === 'ws' || + this.url.scheme === 'wss' + ) { + this.encodingOverride = 'utf-8' + } + + const buffer = new Buffer(this.buffer) // TODO: Use encoding override instead + for (let i = 0; i < buffer.length; ++i) { + if ( + buffer[i] < 0x21 || + buffer[i] > 0x7e || + buffer[i] === 0x22 || + buffer[i] === 0x23 || + buffer[i] === 0x3c || + buffer[i] === 0x3e + ) { + this.url.query += percentEncode(buffer[i]) + } else { + this.url.query += String.fromCodePoint(buffer[i]) + } + } + + this.buffer = '' + if (c === 35) { + this.url.fragment = '' + this.state = 'fragment' + } + } else { + // TODO: If c is not a URL code point and not "%", parse error. + if ( + c === 37 && + (!isASCIIHex(this.input[this.pointer + 1]) || + !isASCIIHex(this.input[this.pointer + 2])) + ) { + this.parseError = true + } + + this.buffer += cStr + } + + return true + } + + URLStateMachine.prototype['parse fragment'] = function parseFragment(c) { + if (isNaN(c)) { + // do nothing + } else if (c === 0x0) { + this.parseError = true + } else { + // TODO: If c is not a URL code point and not "%", parse error. + if ( + c === 37 && + (!isASCIIHex(this.input[this.pointer + 1]) || + !isASCIIHex(this.input[this.pointer + 2])) + ) { + this.parseError = true + } + + this.url.fragment += percentEncodeChar(c, isC0ControlPercentEncode) + } + + return true + } + + function serializeURL(url, excludeFragment) { + let output = url.scheme + ':' + if (url.host !== null) { + output += '//' + + if (url.username !== '' || url.password !== '') { + output += url.username + if (url.password !== '') { + output += ':' + url.password + } + output += '@' + } + + output += serializeHost(url.host) + + if (url.port !== null) { + output += ':' + url.port + } + } else if (url.host === null && url.scheme === 'file') { + output += '//' + } + + if (url.cannotBeABaseURL) { + output += url.path[0] + } else { + for (const string of url.path) { + output += '/' + string + } + } + + if (url.query !== null) { + output += '?' + url.query + } + + if (!excludeFragment && url.fragment !== null) { + output += '#' + url.fragment + } + + return output + } + + function serializeOrigin(tuple) { + let result = tuple.scheme + '://' + result += serializeHost(tuple.host) + + if (tuple.port !== null) { + result += ':' + tuple.port + } + + return result + } + + module.exports.serializeURL = serializeURL + + module.exports.serializeURLOrigin = function (url) { + // https://url.spec.whatwg.org/#concept-url-origin + switch (url.scheme) { + case 'blob': + try { + return module.exports.serializeURLOrigin( + module.exports.parseURL(url.path[0]) + ) + } catch (e) { + // serializing an opaque origin returns "null" + return 'null' + } + case 'ftp': + case 'gopher': + case 'http': + case 'https': + case 'ws': + case 'wss': + return serializeOrigin({ + scheme: url.scheme, + host: url.host, + port: url.port, + }) + case 'file': + // spec says "exercise to the reader", chrome says "file://" + return 'file://' + default: + // serializing an opaque origin returns "null" + return 'null' + } + } + + module.exports.basicURLParse = function (input, options) { + if (options === undefined) { + options = {} + } + + const usm = new URLStateMachine( + input, + options.baseURL, + options.encodingOverride, + options.url, + options.stateOverride + ) + if (usm.failure) { + return 'failure' + } + + return usm.url + } + + module.exports.setTheUsername = function (url, username) { + url.username = '' + const decoded = punycode.ucs2.decode(username) + for (let i = 0; i < decoded.length; ++i) { + url.username += percentEncodeChar(decoded[i], isUserinfoPercentEncode) + } + } + + module.exports.setThePassword = function (url, password) { + url.password = '' + const decoded = punycode.ucs2.decode(password) + for (let i = 0; i < decoded.length; ++i) { + url.password += percentEncodeChar(decoded[i], isUserinfoPercentEncode) + } + } + + module.exports.serializeHost = serializeHost + + module.exports.cannotHaveAUsernamePasswordPort = + cannotHaveAUsernamePasswordPort + + module.exports.serializeInteger = function (integer) { + return String(integer) + } + + module.exports.parseURL = function (input, options) { + if (options === undefined) { + options = {} + } + + // We don't handle blobs, so this just delegates: + return module.exports.basicURLParse(input, { + baseURL: options.baseURL, + encodingOverride: options.encodingOverride, + }) + } + + /***/ + }, + + /***/ 3185: /***/ (module) => { + 'use strict' + + module.exports.mixin = function mixin(target, source) { + const keys = Object.getOwnPropertyNames(source) + for (let i = 0; i < keys.length; ++i) { + Object.defineProperty( + target, + keys[i], + Object.getOwnPropertyDescriptor(source, keys[i]) + ) + } + } + + module.exports.wrapperSymbol = Symbol('wrapper') + module.exports.implSymbol = Symbol('impl') + + module.exports.wrapperForImpl = function (impl) { + return impl[module.exports.wrapperSymbol] + } + + module.exports.implForWrapper = function (wrapper) { + return wrapper[module.exports.implSymbol] + } + + /***/ + }, + + /***/ 2940: /***/ (module) => { + // Returns a wrapper function that returns a wrapped callback + // The wrapper function should do some stuff, and return a + // presumably different callback function. + // This makes sure that own properties are retained, so that + // decorations and such are not lost along the way. + module.exports = wrappy + function wrappy(fn, cb) { + if (fn && cb) return wrappy(fn)(cb) + + if (typeof fn !== 'function') + throw new TypeError('need wrapper function') + + Object.keys(fn).forEach(function (k) { + wrapper[k] = fn[k] + }) + + return wrapper + + function wrapper() { + var args = new Array(arguments.length) + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i] + } + var ret = fn.apply(this, args) + var cb = args[args.length - 1] + if (typeof ret === 'function' && ret !== cb) { + Object.keys(cb).forEach(function (k) { + ret[k] = cb[k] + }) + } + return ret + } + } + + /***/ + }, + + /***/ 4091: /***/ (module) => { + 'use strict' + + module.exports = function (Yallist) { + Yallist.prototype[Symbol.iterator] = function* () { + for (let walker = this.head; walker; walker = walker.next) { + yield walker.value + } + } + } + + /***/ + }, + + /***/ 665: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + module.exports = Yallist + + Yallist.Node = Node + Yallist.create = Yallist + + function Yallist(list) { + var self = this + if (!(self instanceof Yallist)) { + self = new Yallist() + } + + self.tail = null + self.head = null + self.length = 0 + + if (list && typeof list.forEach === 'function') { + list.forEach(function (item) { + self.push(item) + }) + } else if (arguments.length > 0) { + for (var i = 0, l = arguments.length; i < l; i++) { + self.push(arguments[i]) + } + } + + return self + } + + Yallist.prototype.removeNode = function (node) { + if (node.list !== this) { + throw new Error('removing node which does not belong to this list') + } + + var next = node.next + var prev = node.prev + + if (next) { + next.prev = prev + } + + if (prev) { + prev.next = next + } + + if (node === this.head) { + this.head = next + } + if (node === this.tail) { + this.tail = prev + } + + node.list.length-- + node.next = null + node.prev = null + node.list = null + + return next + } + + Yallist.prototype.unshiftNode = function (node) { + if (node === this.head) { + return + } + + if (node.list) { + node.list.removeNode(node) + } + + var head = this.head + node.list = this + node.next = head + if (head) { + head.prev = node + } + + this.head = node + if (!this.tail) { + this.tail = node + } + this.length++ + } + + Yallist.prototype.pushNode = function (node) { + if (node === this.tail) { + return + } + + if (node.list) { + node.list.removeNode(node) + } + + var tail = this.tail + node.list = this + node.prev = tail + if (tail) { + tail.next = node + } + + this.tail = node + if (!this.head) { + this.head = node + } + this.length++ + } + + Yallist.prototype.push = function () { + for (var i = 0, l = arguments.length; i < l; i++) { + push(this, arguments[i]) + } + return this.length + } + + Yallist.prototype.unshift = function () { + for (var i = 0, l = arguments.length; i < l; i++) { + unshift(this, arguments[i]) + } + return this.length + } + + Yallist.prototype.pop = function () { + if (!this.tail) { + return undefined + } + + var res = this.tail.value + this.tail = this.tail.prev + if (this.tail) { + this.tail.next = null + } else { + this.head = null + } + this.length-- + return res + } + + Yallist.prototype.shift = function () { + if (!this.head) { + return undefined + } + + var res = this.head.value + this.head = this.head.next + if (this.head) { + this.head.prev = null + } else { + this.tail = null + } + this.length-- + return res + } + + Yallist.prototype.forEach = function (fn, thisp) { + thisp = thisp || this + for (var walker = this.head, i = 0; walker !== null; i++) { + fn.call(thisp, walker.value, i, this) + walker = walker.next + } + } + + Yallist.prototype.forEachReverse = function (fn, thisp) { + thisp = thisp || this + for ( + var walker = this.tail, i = this.length - 1; + walker !== null; + i-- + ) { + fn.call(thisp, walker.value, i, this) + walker = walker.prev + } + } + + Yallist.prototype.get = function (n) { + for (var i = 0, walker = this.head; walker !== null && i < n; i++) { + // abort out of the list early if we hit a cycle + walker = walker.next + } + if (i === n && walker !== null) { + return walker.value + } + } + + Yallist.prototype.getReverse = function (n) { + for (var i = 0, walker = this.tail; walker !== null && i < n; i++) { + // abort out of the list early if we hit a cycle + walker = walker.prev + } + if (i === n && walker !== null) { + return walker.value + } + } + + Yallist.prototype.map = function (fn, thisp) { + thisp = thisp || this + var res = new Yallist() + for (var walker = this.head; walker !== null; ) { + res.push(fn.call(thisp, walker.value, this)) + walker = walker.next + } + return res + } + + Yallist.prototype.mapReverse = function (fn, thisp) { + thisp = thisp || this + var res = new Yallist() + for (var walker = this.tail; walker !== null; ) { + res.push(fn.call(thisp, walker.value, this)) + walker = walker.prev + } + return res + } + + Yallist.prototype.reduce = function (fn, initial) { + var acc + var walker = this.head + if (arguments.length > 1) { + acc = initial + } else if (this.head) { + walker = this.head.next + acc = this.head.value + } else { + throw new TypeError('Reduce of empty list with no initial value') + } + + for (var i = 0; walker !== null; i++) { + acc = fn(acc, walker.value, i) + walker = walker.next + } + + return acc + } + + Yallist.prototype.reduceReverse = function (fn, initial) { + var acc + var walker = this.tail + if (arguments.length > 1) { + acc = initial + } else if (this.tail) { + walker = this.tail.prev + acc = this.tail.value + } else { + throw new TypeError('Reduce of empty list with no initial value') + } + + for (var i = this.length - 1; walker !== null; i--) { + acc = fn(acc, walker.value, i) + walker = walker.prev + } + + return acc + } + + Yallist.prototype.toArray = function () { + var arr = new Array(this.length) + for (var i = 0, walker = this.head; walker !== null; i++) { + arr[i] = walker.value + walker = walker.next + } + return arr + } + + Yallist.prototype.toArrayReverse = function () { + var arr = new Array(this.length) + for (var i = 0, walker = this.tail; walker !== null; i++) { + arr[i] = walker.value + walker = walker.prev + } + return arr + } + + Yallist.prototype.slice = function (from, to) { + to = to || this.length + if (to < 0) { + to += this.length + } + from = from || 0 + if (from < 0) { + from += this.length + } + var ret = new Yallist() + if (to < from || to < 0) { + return ret + } + if (from < 0) { + from = 0 + } + if (to > this.length) { + to = this.length + } + for (var i = 0, walker = this.head; walker !== null && i < from; i++) { + walker = walker.next + } + for (; walker !== null && i < to; i++, walker = walker.next) { + ret.push(walker.value) + } + return ret + } + + Yallist.prototype.sliceReverse = function (from, to) { + to = to || this.length + if (to < 0) { + to += this.length + } + from = from || 0 + if (from < 0) { + from += this.length + } + var ret = new Yallist() + if (to < from || to < 0) { + return ret + } + if (from < 0) { + from = 0 + } + if (to > this.length) { + to = this.length + } + for ( + var i = this.length, walker = this.tail; + walker !== null && i > to; + i-- + ) { + walker = walker.prev + } + for (; walker !== null && i > from; i--, walker = walker.prev) { + ret.push(walker.value) + } + return ret + } + + Yallist.prototype.splice = function (start, deleteCount, ...nodes) { + if (start > this.length) { + start = this.length - 1 + } + if (start < 0) { + start = this.length + start + } + + for (var i = 0, walker = this.head; walker !== null && i < start; i++) { + walker = walker.next + } + + var ret = [] + for (var i = 0; walker && i < deleteCount; i++) { + ret.push(walker.value) + walker = this.removeNode(walker) + } + if (walker === null) { + walker = this.tail + } + + if (walker !== this.head && walker !== this.tail) { + walker = walker.prev + } + + for (var i = 0; i < nodes.length; i++) { + walker = insert(this, walker, nodes[i]) + } + return ret + } + + Yallist.prototype.reverse = function () { + var head = this.head + var tail = this.tail + for (var walker = head; walker !== null; walker = walker.prev) { + var p = walker.prev + walker.prev = walker.next + walker.next = p + } + this.head = tail + this.tail = head + return this + } + + function insert(self, node, value) { + var inserted = + node === self.head + ? new Node(value, null, node, self) + : new Node(value, node, node.next, self) + + if (inserted.next === null) { + self.tail = inserted + } + if (inserted.prev === null) { + self.head = inserted + } + + self.length++ + + return inserted + } + + function push(self, item) { + self.tail = new Node(item, self.tail, null, self) + if (!self.head) { + self.head = self.tail + } + self.length++ + } + + function unshift(self, item) { + self.head = new Node(item, null, self.head, self) + if (!self.tail) { + self.tail = self.head + } + self.length++ + } + + function Node(value, prev, next, list) { + if (!(this instanceof Node)) { + return new Node(value, prev, next, list) + } + + this.list = list + this.value = value + + if (prev) { + prev.next = this + this.prev = prev + } else { + this.prev = null + } + + if (next) { + next.prev = this + this.next = next + } else { + this.next = null + } + } + + try { + // add if support for Symbol.iterator is present + __nccwpck_require__(4091)(Yallist) + } catch (er) {} + + /***/ + }, + + /***/ 2877: /***/ (module) => { + module.exports = eval('require')('encoding') + + /***/ + }, + + /***/ 4978: /***/ (module) => { + module.exports = eval('require')('util/types') + + /***/ + }, + + /***/ 9491: /***/ (module) => { + 'use strict' + module.exports = require('assert') + + /***/ + }, + + /***/ 852: /***/ (module) => { + 'use strict' + module.exports = require('async_hooks') + + /***/ + }, + + /***/ 4300: /***/ (module) => { + 'use strict' + module.exports = require('buffer') + + /***/ + }, + + /***/ 6206: /***/ (module) => { + 'use strict' + module.exports = require('console') + + /***/ + }, + + /***/ 6113: /***/ (module) => { + 'use strict' + module.exports = require('crypto') + + /***/ + }, + + /***/ 7643: /***/ (module) => { + 'use strict' + module.exports = require('diagnostics_channel') + + /***/ + }, + + /***/ 2361: /***/ (module) => { + 'use strict' + module.exports = require('events') + + /***/ + }, + + /***/ 7147: /***/ (module) => { + 'use strict' + module.exports = require('fs') + + /***/ + }, + + /***/ 3685: /***/ (module) => { + 'use strict' + module.exports = require('http') + + /***/ + }, + + /***/ 5158: /***/ (module) => { + 'use strict' + module.exports = require('http2') + + /***/ + }, + + /***/ 5687: /***/ (module) => { + 'use strict' + module.exports = require('https') + + /***/ + }, + + /***/ 1808: /***/ (module) => { + 'use strict' + module.exports = require('net') + + /***/ + }, + + /***/ 5673: /***/ (module) => { + 'use strict' + module.exports = require('node:events') + + /***/ + }, + + /***/ 4492: /***/ (module) => { + 'use strict' + module.exports = require('node:stream') + + /***/ + }, + + /***/ 7261: /***/ (module) => { + 'use strict' + module.exports = require('node:util') + + /***/ + }, + + /***/ 2037: /***/ (module) => { + 'use strict' + module.exports = require('os') + + /***/ + }, - return output - } + /***/ 1017: /***/ (module) => { + 'use strict' + module.exports = require('path') - function serializeOrigin(tuple) { - let result = tuple.scheme + '://' - result += serializeHost(tuple.host) + /***/ + }, - if (tuple.port !== null) { - result += ':' + tuple.port - } + /***/ 4074: /***/ (module) => { + 'use strict' + module.exports = require('perf_hooks') - return result - } + /***/ + }, - module.exports.serializeURL = serializeURL + /***/ 5477: /***/ (module) => { + 'use strict' + module.exports = require('punycode') - module.exports.serializeURLOrigin = function (url) { - // https://url.spec.whatwg.org/#concept-url-origin - switch (url.scheme) { - case 'blob': - try { - return module.exports.serializeURLOrigin( - module.exports.parseURL(url.path[0]) - ) - } catch (e) { - // serializing an opaque origin returns "null" - return 'null' - } - case 'ftp': - case 'gopher': - case 'http': - case 'https': - case 'ws': - case 'wss': - return serializeOrigin({ - scheme: url.scheme, - host: url.host, - port: url.port, - }) - case 'file': - // spec says "exercise to the reader", chrome says "file://" - return 'file://' - default: - // serializing an opaque origin returns "null" - return 'null' - } - } + /***/ + }, - module.exports.basicURLParse = function (input, options) { - if (options === undefined) { - options = {} - } + /***/ 3477: /***/ (module) => { + 'use strict' + module.exports = require('querystring') - const usm = new URLStateMachine( - input, - options.baseURL, - options.encodingOverride, - options.url, - options.stateOverride - ) - if (usm.failure) { - return 'failure' - } + /***/ + }, - return usm.url - } + /***/ 2781: /***/ (module) => { + 'use strict' + module.exports = require('stream') - module.exports.setTheUsername = function (url, username) { - url.username = '' - const decoded = punycode.ucs2.decode(username) - for (let i = 0; i < decoded.length; ++i) { - url.username += percentEncodeChar(decoded[i], isUserinfoPercentEncode) - } - } + /***/ + }, - module.exports.setThePassword = function (url, password) { - url.password = '' - const decoded = punycode.ucs2.decode(password) - for (let i = 0; i < decoded.length; ++i) { - url.password += percentEncodeChar(decoded[i], isUserinfoPercentEncode) - } - } + /***/ 5356: /***/ (module) => { + 'use strict' + module.exports = require('stream/web') - module.exports.serializeHost = serializeHost + /***/ + }, - module.exports.cannotHaveAUsernamePasswordPort = - cannotHaveAUsernamePasswordPort + /***/ 1576: /***/ (module) => { + 'use strict' + module.exports = require('string_decoder') - module.exports.serializeInteger = function (integer) { - return String(integer) - } + /***/ + }, - module.exports.parseURL = function (input, options) { - if (options === undefined) { - options = {} - } + /***/ 4404: /***/ (module) => { + 'use strict' + module.exports = require('tls') - // We don't handle blobs, so this just delegates: - return module.exports.basicURLParse(input, { - baseURL: options.baseURL, - encodingOverride: options.encodingOverride, - }) - } + /***/ + }, + + /***/ 7310: /***/ (module) => { + 'use strict' + module.exports = require('url') /***/ }, - /***/ 3185: /***/ (module) => { + /***/ 3837: /***/ (module) => { 'use strict' + module.exports = require('util') - module.exports.mixin = function mixin(target, source) { - const keys = Object.getOwnPropertyNames(source) - for (let i = 0; i < keys.length; ++i) { - Object.defineProperty( - target, - keys[i], - Object.getOwnPropertyDescriptor(source, keys[i]) - ) - } - } + /***/ + }, - module.exports.wrapperSymbol = Symbol('wrapper') - module.exports.implSymbol = Symbol('impl') + /***/ 1267: /***/ (module) => { + 'use strict' + module.exports = require('worker_threads') - module.exports.wrapperForImpl = function (impl) { - return impl[module.exports.wrapperSymbol] - } + /***/ + }, - module.exports.implForWrapper = function (wrapper) { - return wrapper[module.exports.implSymbol] - } + /***/ 9796: /***/ (module) => { + 'use strict' + module.exports = require('zlib') /***/ }, - /***/ 2940: /***/ (module) => { - // Returns a wrapper function that returns a wrapped callback - // The wrapper function should do some stuff, and return a - // presumably different callback function. - // This makes sure that own properties are retained, so that - // decorations and such are not lost along the way. - module.exports = wrappy - function wrappy(fn, cb) { - if (fn && cb) return wrappy(fn)(cb) + /***/ 2960: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' - if (typeof fn !== 'function') - throw new TypeError('need wrapper function') + const WritableStream = __nccwpck_require__(4492).Writable + const inherits = __nccwpck_require__(7261).inherits - Object.keys(fn).forEach(function (k) { - wrapper[k] = fn[k] + const StreamSearch = __nccwpck_require__(1142) + + const PartStream = __nccwpck_require__(1620) + const HeaderParser = __nccwpck_require__(2032) + + const DASH = 45 + const B_ONEDASH = Buffer.from('-') + const B_CRLF = Buffer.from('\r\n') + const EMPTY_FN = function () {} + + function Dicer(cfg) { + if (!(this instanceof Dicer)) { + return new Dicer(cfg) + } + WritableStream.call(this, cfg) + + if (!cfg || (!cfg.headerFirst && typeof cfg.boundary !== 'string')) { + throw new TypeError('Boundary required') + } + + if (typeof cfg.boundary === 'string') { + this.setBoundary(cfg.boundary) + } else { + this._bparser = undefined + } + + this._headerFirst = cfg.headerFirst + + this._dashes = 0 + this._parts = 0 + this._finished = false + this._realFinish = false + this._isPreamble = true + this._justMatched = false + this._firstWrite = true + this._inHeader = true + this._part = undefined + this._cb = undefined + this._ignoreData = false + this._partOpts = { highWaterMark: cfg.partHwm } + this._pause = false + + const self = this + this._hparser = new HeaderParser(cfg) + this._hparser.on('header', function (header) { + self._inHeader = false + self._part.emit('header', header) }) + } + inherits(Dicer, WritableStream) + + Dicer.prototype.emit = function (ev) { + if (ev === 'finish' && !this._realFinish) { + if (!this._finished) { + const self = this + process.nextTick(function () { + self.emit('error', new Error('Unexpected end of multipart data')) + if (self._part && !self._ignoreData) { + const type = self._isPreamble ? 'Preamble' : 'Part' + self._part.emit( + 'error', + new Error( + type + + ' terminated early due to unexpected end of multipart data' + ) + ) + self._part.push(null) + process.nextTick(function () { + self._realFinish = true + self.emit('finish') + self._realFinish = false + }) + return + } + self._realFinish = true + self.emit('finish') + self._realFinish = false + }) + } + } else { + WritableStream.prototype.emit.apply(this, arguments) + } + } - return wrapper + Dicer.prototype._write = function (data, encoding, cb) { + // ignore unexpected data (e.g. extra trailer data after finished) + if (!this._hparser && !this._bparser) { + return cb() + } - function wrapper() { - var args = new Array(arguments.length) - for (var i = 0; i < args.length; i++) { - args[i] = arguments[i] + if (this._headerFirst && this._isPreamble) { + if (!this._part) { + this._part = new PartStream(this._partOpts) + if (this._events.preamble) { + this.emit('preamble', this._part) + } else { + this._ignore() + } } - var ret = fn.apply(this, args) - var cb = args[args.length - 1] - if (typeof ret === 'function' && ret !== cb) { - Object.keys(cb).forEach(function (k) { - ret[k] = cb[k] - }) + const r = this._hparser.push(data) + if (!this._inHeader && r !== undefined && r < data.length) { + data = data.slice(r) + } else { + return cb() } - return ret + } + + // allows for "easier" testing + if (this._firstWrite) { + this._bparser.push(B_CRLF) + this._firstWrite = false + } + + this._bparser.push(data) + + if (this._pause) { + this._cb = cb + } else { + cb() } } - /***/ - }, + Dicer.prototype.reset = function () { + this._part = undefined + this._bparser = undefined + this._hparser = undefined + } - /***/ 4091: /***/ (module) => { - 'use strict' + Dicer.prototype.setBoundary = function (boundary) { + const self = this + this._bparser = new StreamSearch('\r\n--' + boundary) + this._bparser.on('info', function (isMatch, data, start, end) { + self._oninfo(isMatch, data, start, end) + }) + } - module.exports = function (Yallist) { - Yallist.prototype[Symbol.iterator] = function* () { - for (let walker = this.head; walker; walker = walker.next) { - yield walker.value + Dicer.prototype._ignore = function () { + if (this._part && !this._ignoreData) { + this._ignoreData = true + this._part.on('error', EMPTY_FN) + // we must perform some kind of read on the stream even though we are + // ignoring the data, otherwise node's Readable stream will not emit 'end' + // after pushing null to the stream + this._part.resume() + } + } + + Dicer.prototype._oninfo = function (isMatch, data, start, end) { + let buf + const self = this + let i = 0 + let r + let shouldWriteMore = true + + if (!this._part && this._justMatched && data) { + while (this._dashes < 2 && start + i < end) { + if (data[start + i] === DASH) { + ++i + ++this._dashes + } else { + if (this._dashes) { + buf = B_ONEDASH + } + this._dashes = 0 + break + } + } + if (this._dashes === 2) { + if (start + i < end && this._events.trailer) { + this.emit('trailer', data.slice(start + i, end)) + } + this.reset() + this._finished = true + // no more parts will be added + if (self._parts === 0) { + self._realFinish = true + self.emit('finish') + self._realFinish = false + } + } + if (this._dashes) { + return + } + } + if (this._justMatched) { + this._justMatched = false + } + if (!this._part) { + this._part = new PartStream(this._partOpts) + this._part._read = function (n) { + self._unpause() + } + if (this._isPreamble && this._events.preamble) { + this.emit('preamble', this._part) + } else if (this._isPreamble !== true && this._events.part) { + this.emit('part', this._part) + } else { + this._ignore() + } + if (!this._isPreamble) { + this._inHeader = true + } + } + if (data && start < end && !this._ignoreData) { + if (this._isPreamble || !this._inHeader) { + if (buf) { + shouldWriteMore = this._part.push(buf) + } + shouldWriteMore = this._part.push(data.slice(start, end)) + if (!shouldWriteMore) { + this._pause = true + } + } else if (!this._isPreamble && this._inHeader) { + if (buf) { + this._hparser.push(buf) + } + r = this._hparser.push(data.slice(start, end)) + if (!this._inHeader && r !== undefined && r < end) { + this._oninfo(false, data, start + r, end) + } + } + } + if (isMatch) { + this._hparser.reset() + if (this._isPreamble) { + this._isPreamble = false + } else { + if (start !== end) { + ++this._parts + this._part.on('end', function () { + if (--self._parts === 0) { + if (self._finished) { + self._realFinish = true + self.emit('finish') + self._realFinish = false + } else { + self._unpause() + } + } + }) + } } + this._part.push(null) + this._part = undefined + this._ignoreData = false + this._justMatched = true + this._dashes = 0 } } + Dicer.prototype._unpause = function () { + if (!this._pause) { + return + } + + this._pause = false + if (this._cb) { + const cb = this._cb + this._cb = undefined + cb() + } + } + + module.exports = Dicer + /***/ }, - /***/ 665: /***/ ( + /***/ 2032: /***/ ( module, __unused_webpack_exports, __nccwpck_require__ ) => { 'use strict' - module.exports = Yallist + const EventEmitter = __nccwpck_require__(5673).EventEmitter + const inherits = __nccwpck_require__(7261).inherits + const getLimit = __nccwpck_require__(1467) - Yallist.Node = Node - Yallist.create = Yallist + const StreamSearch = __nccwpck_require__(1142) - function Yallist(list) { - var self = this - if (!(self instanceof Yallist)) { - self = new Yallist() - } + const B_DCRLF = Buffer.from('\r\n\r\n') + const RE_CRLF = /\r\n/g + const RE_HDR = /^([^:]+):[ \t]?([\x00-\xFF]+)?$/ // eslint-disable-line no-control-regex - self.tail = null - self.head = null - self.length = 0 + function HeaderParser(cfg) { + EventEmitter.call(this) - if (list && typeof list.forEach === 'function') { - list.forEach(function (item) { - self.push(item) - }) - } else if (arguments.length > 0) { - for (var i = 0, l = arguments.length; i < l; i++) { - self.push(arguments[i]) - } - } + cfg = cfg || {} + const self = this + this.nread = 0 + this.maxed = false + this.npairs = 0 + this.maxHeaderPairs = getLimit(cfg, 'maxHeaderPairs', 2000) + this.maxHeaderSize = getLimit(cfg, 'maxHeaderSize', 80 * 1024) + this.buffer = '' + this.header = {} + this.finished = false + this.ss = new StreamSearch(B_DCRLF) + this.ss.on('info', function (isMatch, data, start, end) { + if (data && !self.maxed) { + if (self.nread + end - start >= self.maxHeaderSize) { + end = self.maxHeaderSize - self.nread + start + self.nread = self.maxHeaderSize + self.maxed = true + } else { + self.nread += end - start + } - return self + self.buffer += data.toString('binary', start, end) + } + if (isMatch) { + self._finish() + } + }) } + inherits(HeaderParser, EventEmitter) - Yallist.prototype.removeNode = function (node) { - if (node.list !== this) { - throw new Error('removing node which does not belong to this list') + HeaderParser.prototype.push = function (data) { + const r = this.ss.push(data) + if (this.finished) { + return r } + } - var next = node.next - var prev = node.prev + HeaderParser.prototype.reset = function () { + this.finished = false + this.buffer = '' + this.header = {} + this.ss.reset() + } - if (next) { - next.prev = prev + HeaderParser.prototype._finish = function () { + if (this.buffer) { + this._parseHeader() } + this.ss.matches = this.ss.maxMatches + const header = this.header + this.header = {} + this.buffer = '' + this.finished = true + this.nread = this.npairs = 0 + this.maxed = false + this.emit('header', header) + } - if (prev) { - prev.next = next + HeaderParser.prototype._parseHeader = function () { + if (this.npairs === this.maxHeaderPairs) { + return } - if (node === this.head) { - this.head = next - } - if (node === this.tail) { - this.tail = prev - } + const lines = this.buffer.split(RE_CRLF) + const len = lines.length + let m, h - node.list.length-- - node.next = null - node.prev = null - node.list = null + for (var i = 0; i < len; ++i) { + // eslint-disable-line no-var + if (lines[i].length === 0) { + continue + } + if (lines[i][0] === '\t' || lines[i][0] === ' ') { + // folded header content + // RFC2822 says to just remove the CRLF and not the whitespace following + // it, so we follow the RFC and include the leading whitespace ... + if (h) { + this.header[h][this.header[h].length - 1] += lines[i] + continue + } + } - return next + const posColon = lines[i].indexOf(':') + if (posColon === -1 || posColon === 0) { + return + } + m = RE_HDR.exec(lines[i]) + h = m[1].toLowerCase() + this.header[h] = this.header[h] || [] + this.header[h].push(m[2] || '') + if (++this.npairs === this.maxHeaderPairs) { + break + } + } } - Yallist.prototype.unshiftNode = function (node) { - if (node === this.head) { - return - } + module.exports = HeaderParser - if (node.list) { - node.list.removeNode(node) - } + /***/ + }, - var head = this.head - node.list = this - node.next = head - if (head) { - head.prev = node - } + /***/ 1620: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' - this.head = node - if (!this.tail) { - this.tail = node - } - this.length++ + const inherits = __nccwpck_require__(7261).inherits + const ReadableStream = __nccwpck_require__(4492).Readable + + function PartStream(opts) { + ReadableStream.call(this, opts) } + inherits(PartStream, ReadableStream) - Yallist.prototype.pushNode = function (node) { - if (node === this.tail) { - return - } + PartStream.prototype._read = function (n) {} - if (node.list) { - node.list.removeNode(node) - } + module.exports = PartStream - var tail = this.tail - node.list = this - node.prev = tail - if (tail) { - tail.next = node - } + /***/ + }, - this.tail = node - if (!this.head) { - this.head = node - } - this.length++ - } + /***/ 1142: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' - Yallist.prototype.push = function () { - for (var i = 0, l = arguments.length; i < l; i++) { - push(this, arguments[i]) - } - return this.length - } + /** + * Copyright Brian White. All rights reserved. + * + * @see https://github.com/mscdex/streamsearch + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + * + * Based heavily on the Streaming Boyer-Moore-Horspool C++ implementation + * by Hongli Lai at: https://github.com/FooBarWidget/boyer-moore-horspool + */ + const EventEmitter = __nccwpck_require__(5673).EventEmitter + const inherits = __nccwpck_require__(7261).inherits - Yallist.prototype.unshift = function () { - for (var i = 0, l = arguments.length; i < l; i++) { - unshift(this, arguments[i]) + function SBMH(needle) { + if (typeof needle === 'string') { + needle = Buffer.from(needle) } - return this.length - } - Yallist.prototype.pop = function () { - if (!this.tail) { - return undefined + if (!Buffer.isBuffer(needle)) { + throw new TypeError('The needle has to be a String or a Buffer.') } - var res = this.tail.value - this.tail = this.tail.prev - if (this.tail) { - this.tail.next = null - } else { - this.head = null - } - this.length-- - return res - } + const needleLength = needle.length - Yallist.prototype.shift = function () { - if (!this.head) { - return undefined + if (needleLength === 0) { + throw new Error('The needle cannot be an empty String/Buffer.') } - var res = this.head.value - this.head = this.head.next - if (this.head) { - this.head.prev = null - } else { - this.tail = null + if (needleLength > 256) { + throw new Error('The needle cannot have a length bigger than 256.') } - this.length-- - return res - } - Yallist.prototype.forEach = function (fn, thisp) { - thisp = thisp || this - for (var walker = this.head, i = 0; walker !== null; i++) { - fn.call(thisp, walker.value, i, this) - walker = walker.next - } - } + this.maxMatches = Infinity + this.matches = 0 - Yallist.prototype.forEachReverse = function (fn, thisp) { - thisp = thisp || this - for ( - var walker = this.tail, i = this.length - 1; - walker !== null; - i-- - ) { - fn.call(thisp, walker.value, i, this) - walker = walker.prev + this._occ = new Array(256).fill(needleLength) // Initialize occurrence table. + this._lookbehind_size = 0 + this._needle = needle + this._bufpos = 0 + + this._lookbehind = Buffer.alloc(needleLength) + + // Populate occurrence table with analysis of the needle, + // ignoring last letter. + for (var i = 0; i < needleLength - 1; ++i) { + // eslint-disable-line no-var + this._occ[needle[i]] = needleLength - 1 - i } } + inherits(SBMH, EventEmitter) - Yallist.prototype.get = function (n) { - for (var i = 0, walker = this.head; walker !== null && i < n; i++) { - // abort out of the list early if we hit a cycle - walker = walker.next - } - if (i === n && walker !== null) { - return walker.value - } + SBMH.prototype.reset = function () { + this._lookbehind_size = 0 + this.matches = 0 + this._bufpos = 0 } - Yallist.prototype.getReverse = function (n) { - for (var i = 0, walker = this.tail; walker !== null && i < n; i++) { - // abort out of the list early if we hit a cycle - walker = walker.prev + SBMH.prototype.push = function (chunk, pos) { + if (!Buffer.isBuffer(chunk)) { + chunk = Buffer.from(chunk, 'binary') } - if (i === n && walker !== null) { - return walker.value + const chlen = chunk.length + this._bufpos = pos || 0 + let r + while (r !== chlen && this.matches < this.maxMatches) { + r = this._sbmh_feed(chunk) } + return r } - Yallist.prototype.map = function (fn, thisp) { - thisp = thisp || this - var res = new Yallist() - for (var walker = this.head; walker !== null; ) { - res.push(fn.call(thisp, walker.value, this)) - walker = walker.next - } - return res - } + SBMH.prototype._sbmh_feed = function (data) { + const len = data.length + const needle = this._needle + const needleLength = needle.length + const lastNeedleChar = needle[needleLength - 1] - Yallist.prototype.mapReverse = function (fn, thisp) { - thisp = thisp || this - var res = new Yallist() - for (var walker = this.tail; walker !== null; ) { - res.push(fn.call(thisp, walker.value, this)) - walker = walker.prev - } - return res - } + // Positive: points to a position in `data` + // pos == 3 points to data[3] + // Negative: points to a position in the lookbehind buffer + // pos == -2 points to lookbehind[lookbehind_size - 2] + let pos = -this._lookbehind_size + let ch - Yallist.prototype.reduce = function (fn, initial) { - var acc - var walker = this.head - if (arguments.length > 1) { - acc = initial - } else if (this.head) { - walker = this.head.next - acc = this.head.value - } else { - throw new TypeError('Reduce of empty list with no initial value') - } + if (pos < 0) { + // Lookbehind buffer is not empty. Perform Boyer-Moore-Horspool + // search with character lookup code that considers both the + // lookbehind buffer and the current round's haystack data. + // + // Loop until + // there is a match. + // or until + // we've moved past the position that requires the + // lookbehind buffer. In this case we switch to the + // optimized loop. + // or until + // the character to look at lies outside the haystack. + while (pos < 0 && pos <= len - needleLength) { + ch = this._sbmh_lookup_char(data, pos + needleLength - 1) - for (var i = 0; walker !== null; i++) { - acc = fn(acc, walker.value, i) - walker = walker.next - } + if ( + ch === lastNeedleChar && + this._sbmh_memcmp(data, pos, needleLength - 1) + ) { + this._lookbehind_size = 0 + ++this.matches + this.emit('info', true) - return acc - } + return (this._bufpos = pos + needleLength) + } + pos += this._occ[ch] + } + + // No match. + + if (pos < 0) { + // There's too few data for Boyer-Moore-Horspool to run, + // so let's use a different algorithm to skip as much as + // we can. + // Forward pos until + // the trailing part of lookbehind + data + // looks like the beginning of the needle + // or until + // pos == 0 + while (pos < 0 && !this._sbmh_memcmp(data, pos, len - pos)) { + ++pos + } + } - Yallist.prototype.reduceReverse = function (fn, initial) { - var acc - var walker = this.tail - if (arguments.length > 1) { - acc = initial - } else if (this.tail) { - walker = this.tail.prev - acc = this.tail.value + if (pos >= 0) { + // Discard lookbehind buffer. + this.emit('info', false, this._lookbehind, 0, this._lookbehind_size) + this._lookbehind_size = 0 + } else { + // Cut off part of the lookbehind buffer that has + // been processed and append the entire haystack + // into it. + const bytesToCutOff = this._lookbehind_size + pos + if (bytesToCutOff > 0) { + // The cut off data is guaranteed not to contain the needle. + this.emit('info', false, this._lookbehind, 0, bytesToCutOff) + } + + this._lookbehind.copy( + this._lookbehind, + 0, + bytesToCutOff, + this._lookbehind_size - bytesToCutOff + ) + this._lookbehind_size -= bytesToCutOff + + data.copy(this._lookbehind, this._lookbehind_size) + this._lookbehind_size += len + + this._bufpos = len + return len + } + } + + pos += (pos >= 0) * this._bufpos + + // Lookbehind buffer is now empty. We only need to check if the + // needle is in the haystack. + if (data.indexOf(needle, pos) !== -1) { + pos = data.indexOf(needle, pos) + ++this.matches + if (pos > 0) { + this.emit('info', true, data, this._bufpos, pos) + } else { + this.emit('info', true) + } + + return (this._bufpos = pos + needleLength) } else { - throw new TypeError('Reduce of empty list with no initial value') + pos = len - needleLength + } + + // There was no match. If there's trailing haystack data that we cannot + // match yet using the Boyer-Moore-Horspool algorithm (because the trailing + // data is less than the needle size) then match using a modified + // algorithm that starts matching from the beginning instead of the end. + // Whatever trailing data is left after running this algorithm is added to + // the lookbehind buffer. + while ( + pos < len && + (data[pos] !== needle[0] || + Buffer.compare( + data.subarray(pos, pos + len - pos), + needle.subarray(0, len - pos) + ) !== 0) + ) { + ++pos + } + if (pos < len) { + data.copy(this._lookbehind, 0, pos, pos + (len - pos)) + this._lookbehind_size = len - pos } - for (var i = this.length - 1; walker !== null; i--) { - acc = fn(acc, walker.value, i) - walker = walker.prev + // Everything until pos is guaranteed not to contain needle data. + if (pos > 0) { + this.emit('info', false, data, this._bufpos, pos < len ? pos : len) } - return acc + this._bufpos = len + return len } - Yallist.prototype.toArray = function () { - var arr = new Array(this.length) - for (var i = 0, walker = this.head; walker !== null; i++) { - arr[i] = walker.value - walker = walker.next - } - return arr + SBMH.prototype._sbmh_lookup_char = function (data, pos) { + return pos < 0 + ? this._lookbehind[this._lookbehind_size + pos] + : data[pos] } - Yallist.prototype.toArrayReverse = function () { - var arr = new Array(this.length) - for (var i = 0, walker = this.tail; walker !== null; i++) { - arr[i] = walker.value - walker = walker.prev + SBMH.prototype._sbmh_memcmp = function (data, pos, len) { + for (var i = 0; i < len; ++i) { + // eslint-disable-line no-var + if (this._sbmh_lookup_char(data, pos + i) !== this._needle[i]) { + return false + } } - return arr + return true } - Yallist.prototype.slice = function (from, to) { - to = to || this.length - if (to < 0) { - to += this.length - } - from = from || 0 - if (from < 0) { - from += this.length - } - var ret = new Yallist() - if (to < from || to < 0) { - return ret + module.exports = SBMH + + /***/ + }, + + /***/ 727: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const WritableStream = __nccwpck_require__(4492).Writable + const { inherits } = __nccwpck_require__(7261) + const Dicer = __nccwpck_require__(2960) + + const MultipartParser = __nccwpck_require__(2183) + const UrlencodedParser = __nccwpck_require__(8306) + const parseParams = __nccwpck_require__(1854) + + function Busboy(opts) { + if (!(this instanceof Busboy)) { + return new Busboy(opts) } - if (from < 0) { - from = 0 + + if (typeof opts !== 'object') { + throw new TypeError('Busboy expected an options-Object.') } - if (to > this.length) { - to = this.length + if (typeof opts.headers !== 'object') { + throw new TypeError( + 'Busboy expected an options-Object with headers-attribute.' + ) } - for (var i = 0, walker = this.head; walker !== null && i < from; i++) { - walker = walker.next + if (typeof opts.headers['content-type'] !== 'string') { + throw new TypeError('Missing Content-Type-header.') } - for (; walker !== null && i < to; i++, walker = walker.next) { - ret.push(walker.value) + + const { headers, ...streamOptions } = opts + + this.opts = { + autoDestroy: false, + ...streamOptions, } - return ret + WritableStream.call(this, this.opts) + + this._done = false + this._parser = this.getParserByHeaders(headers) + this._finished = false } + inherits(Busboy, WritableStream) - Yallist.prototype.sliceReverse = function (from, to) { - to = to || this.length - if (to < 0) { - to += this.length - } - from = from || 0 - if (from < 0) { - from += this.length - } - var ret = new Yallist() - if (to < from || to < 0) { - return ret - } - if (from < 0) { - from = 0 + Busboy.prototype.emit = function (ev) { + if (ev === 'finish') { + if (!this._done) { + this._parser?.end() + return + } else if (this._finished) { + return + } + this._finished = true } - if (to > this.length) { - to = this.length + WritableStream.prototype.emit.apply(this, arguments) + } + + Busboy.prototype.getParserByHeaders = function (headers) { + const parsed = parseParams(headers['content-type']) + + const cfg = { + defCharset: this.opts.defCharset, + fileHwm: this.opts.fileHwm, + headers, + highWaterMark: this.opts.highWaterMark, + isPartAFile: this.opts.isPartAFile, + limits: this.opts.limits, + parsedConType: parsed, + preservePath: this.opts.preservePath, } - for ( - var i = this.length, walker = this.tail; - walker !== null && i > to; - i-- - ) { - walker = walker.prev + + if (MultipartParser.detect.test(parsed[0])) { + return new MultipartParser(this, cfg) } - for (; walker !== null && i > from; i--, walker = walker.prev) { - ret.push(walker.value) + if (UrlencodedParser.detect.test(parsed[0])) { + return new UrlencodedParser(this, cfg) } - return ret + throw new Error('Unsupported Content-Type.') } - Yallist.prototype.splice = function (start, deleteCount, ...nodes) { - if (start > this.length) { - start = this.length - 1 - } - if (start < 0) { - start = this.length + start - } + Busboy.prototype._write = function (chunk, encoding, cb) { + this._parser.write(chunk, cb) + } - for (var i = 0, walker = this.head; walker !== null && i < start; i++) { - walker = walker.next - } + module.exports = Busboy + module.exports['default'] = Busboy + module.exports.Busboy = Busboy - var ret = [] - for (var i = 0; walker && i < deleteCount; i++) { - ret.push(walker.value) - walker = this.removeNode(walker) + module.exports.Dicer = Dicer + + /***/ + }, + + /***/ 2183: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + // TODO: + // * support 1 nested multipart level + // (see second multipart example here: + // http://www.w3.org/TR/html401/interact/forms.html#didx-multipartform-data) + // * support limits.fieldNameSize + // -- this will require modifications to utils.parseParams + + const { Readable } = __nccwpck_require__(4492) + const { inherits } = __nccwpck_require__(7261) + + const Dicer = __nccwpck_require__(2960) + + const parseParams = __nccwpck_require__(1854) + const decodeText = __nccwpck_require__(4619) + const basename = __nccwpck_require__(8647) + const getLimit = __nccwpck_require__(1467) + + const RE_BOUNDARY = /^boundary$/i + const RE_FIELD = /^form-data$/i + const RE_CHARSET = /^charset$/i + const RE_FILENAME = /^filename$/i + const RE_NAME = /^name$/i + + Multipart.detect = /^multipart\/form-data/i + function Multipart(boy, cfg) { + let i + let len + const self = this + let boundary + const limits = cfg.limits + const isPartAFile = + cfg.isPartAFile || + ((fieldName, contentType, fileName) => + contentType === 'application/octet-stream' || + fileName !== undefined) + const parsedConType = cfg.parsedConType || [] + const defCharset = cfg.defCharset || 'utf8' + const preservePath = cfg.preservePath + const fileOpts = { highWaterMark: cfg.fileHwm } + + for (i = 0, len = parsedConType.length; i < len; ++i) { + if ( + Array.isArray(parsedConType[i]) && + RE_BOUNDARY.test(parsedConType[i][0]) + ) { + boundary = parsedConType[i][1] + break + } } - if (walker === null) { - walker = this.tail + + function checkFinished() { + if (nends === 0 && finished && !boy._done) { + finished = false + self.end() + } } - if (walker !== this.head && walker !== this.tail) { - walker = walker.prev + if (typeof boundary !== 'string') { + throw new Error('Multipart: Boundary not found') } - for (var i = 0; i < nodes.length; i++) { - walker = insert(this, walker, nodes[i]) + const fieldSizeLimit = getLimit(limits, 'fieldSize', 1 * 1024 * 1024) + const fileSizeLimit = getLimit(limits, 'fileSize', Infinity) + const filesLimit = getLimit(limits, 'files', Infinity) + const fieldsLimit = getLimit(limits, 'fields', Infinity) + const partsLimit = getLimit(limits, 'parts', Infinity) + const headerPairsLimit = getLimit(limits, 'headerPairs', 2000) + const headerSizeLimit = getLimit(limits, 'headerSize', 80 * 1024) + + let nfiles = 0 + let nfields = 0 + let nends = 0 + let curFile + let curField + let finished = false + + this._needDrain = false + this._pause = false + this._cb = undefined + this._nparts = 0 + this._boy = boy + + const parserCfg = { + boundary, + maxHeaderPairs: headerPairsLimit, + maxHeaderSize: headerSizeLimit, + partHwm: fileOpts.highWaterMark, + highWaterMark: cfg.highWaterMark, } - return ret + + this.parser = new Dicer(parserCfg) + this.parser + .on('drain', function () { + self._needDrain = false + if (self._cb && !self._pause) { + const cb = self._cb + self._cb = undefined + cb() + } + }) + .on('part', function onPart(part) { + if (++self._nparts > partsLimit) { + self.parser.removeListener('part', onPart) + self.parser.on('part', skipPart) + boy.hitPartsLimit = true + boy.emit('partsLimit') + return skipPart(part) + } + + // hack because streams2 _always_ doesn't emit 'end' until nextTick, so let + // us emit 'end' early since we know the part has ended if we are already + // seeing the next part + if (curField) { + const field = curField + field.emit('end') + field.removeAllListeners('end') + } + + part + .on('header', function (header) { + let contype + let fieldname + let parsed + let charset + let encoding + let filename + let nsize = 0 + + if (header['content-type']) { + parsed = parseParams(header['content-type'][0]) + if (parsed[0]) { + contype = parsed[0].toLowerCase() + for (i = 0, len = parsed.length; i < len; ++i) { + if (RE_CHARSET.test(parsed[i][0])) { + charset = parsed[i][1].toLowerCase() + break + } + } + } + } + + if (contype === undefined) { + contype = 'text/plain' + } + if (charset === undefined) { + charset = defCharset + } + + if (header['content-disposition']) { + parsed = parseParams(header['content-disposition'][0]) + if (!RE_FIELD.test(parsed[0])) { + return skipPart(part) + } + for (i = 0, len = parsed.length; i < len; ++i) { + if (RE_NAME.test(parsed[i][0])) { + fieldname = parsed[i][1] + } else if (RE_FILENAME.test(parsed[i][0])) { + filename = parsed[i][1] + if (!preservePath) { + filename = basename(filename) + } + } + } + } else { + return skipPart(part) + } + + if (header['content-transfer-encoding']) { + encoding = + header['content-transfer-encoding'][0].toLowerCase() + } else { + encoding = '7bit' + } + + let onData, onEnd + + if (isPartAFile(fieldname, contype, filename)) { + // file/binary field + if (nfiles === filesLimit) { + if (!boy.hitFilesLimit) { + boy.hitFilesLimit = true + boy.emit('filesLimit') + } + return skipPart(part) + } + + ++nfiles + + if (!boy._events.file) { + self.parser._ignore() + return + } + + ++nends + const file = new FileStream(fileOpts) + curFile = file + file.on('end', function () { + --nends + self._pause = false + checkFinished() + if (self._cb && !self._needDrain) { + const cb = self._cb + self._cb = undefined + cb() + } + }) + file._read = function (n) { + if (!self._pause) { + return + } + self._pause = false + if (self._cb && !self._needDrain) { + const cb = self._cb + self._cb = undefined + cb() + } + } + boy.emit('file', fieldname, file, filename, encoding, contype) + + onData = function (data) { + if ((nsize += data.length) > fileSizeLimit) { + const extralen = fileSizeLimit - nsize + data.length + if (extralen > 0) { + file.push(data.slice(0, extralen)) + } + file.truncated = true + file.bytesRead = fileSizeLimit + part.removeAllListeners('data') + file.emit('limit') + return + } else if (!file.push(data)) { + self._pause = true + } + + file.bytesRead = nsize + } + + onEnd = function () { + curFile = undefined + file.push(null) + } + } else { + // non-file field + if (nfields === fieldsLimit) { + if (!boy.hitFieldsLimit) { + boy.hitFieldsLimit = true + boy.emit('fieldsLimit') + } + return skipPart(part) + } + + ++nfields + ++nends + let buffer = '' + let truncated = false + curField = part + + onData = function (data) { + if ((nsize += data.length) > fieldSizeLimit) { + const extralen = fieldSizeLimit - (nsize - data.length) + buffer += data.toString('binary', 0, extralen) + truncated = true + part.removeAllListeners('data') + } else { + buffer += data.toString('binary') + } + } + + onEnd = function () { + curField = undefined + if (buffer.length) { + buffer = decodeText(buffer, 'binary', charset) + } + boy.emit( + 'field', + fieldname, + buffer, + false, + truncated, + encoding, + contype + ) + --nends + checkFinished() + } + } + + /* As of node@2efe4ab761666 (v0.10.29+/v0.11.14+), busboy had become + broken. Streams2/streams3 is a huge black box of confusion, but + somehow overriding the sync state seems to fix things again (and still + seems to work for previous node versions). + */ + part._readableState.sync = false + + part.on('data', onData) + part.on('end', onEnd) + }) + .on('error', function (err) { + if (curFile) { + curFile.emit('error', err) + } + }) + }) + .on('error', function (err) { + boy.emit('error', err) + }) + .on('finish', function () { + finished = true + checkFinished() + }) } - Yallist.prototype.reverse = function () { - var head = this.head - var tail = this.tail - for (var walker = head; walker !== null; walker = walker.prev) { - var p = walker.prev - walker.prev = walker.next - walker.next = p + Multipart.prototype.write = function (chunk, cb) { + const r = this.parser.write(chunk) + if (r && !this._pause) { + cb() + } else { + this._needDrain = !r + this._cb = cb } - this.head = tail - this.tail = head - return this } - function insert(self, node, value) { - var inserted = - node === self.head - ? new Node(value, null, node, self) - : new Node(value, node, node.next, self) + Multipart.prototype.end = function () { + const self = this - if (inserted.next === null) { - self.tail = inserted + if (self.parser.writable) { + self.parser.end() + } else if (!self._boy._done) { + process.nextTick(function () { + self._boy._done = true + self._boy.emit('finish') + }) } - if (inserted.prev === null) { - self.head = inserted + } + + function skipPart(part) { + part.resume() + } + + function FileStream(opts) { + Readable.call(this, opts) + + this.bytesRead = 0 + + this.truncated = false + } + + inherits(FileStream, Readable) + + FileStream.prototype._read = function (n) {} + + module.exports = Multipart + + /***/ + }, + + /***/ 8306: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { + 'use strict' + + const Decoder = __nccwpck_require__(7100) + const decodeText = __nccwpck_require__(4619) + const getLimit = __nccwpck_require__(1467) + + const RE_CHARSET = /^charset$/i + + UrlEncoded.detect = /^application\/x-www-form-urlencoded/i + function UrlEncoded(boy, cfg) { + const limits = cfg.limits + const parsedConType = cfg.parsedConType + this.boy = boy + + this.fieldSizeLimit = getLimit(limits, 'fieldSize', 1 * 1024 * 1024) + this.fieldNameSizeLimit = getLimit(limits, 'fieldNameSize', 100) + this.fieldsLimit = getLimit(limits, 'fields', Infinity) + + let charset + for (var i = 0, len = parsedConType.length; i < len; ++i) { + // eslint-disable-line no-var + if ( + Array.isArray(parsedConType[i]) && + RE_CHARSET.test(parsedConType[i][0]) + ) { + charset = parsedConType[i][1].toLowerCase() + break + } } - self.length++ + if (charset === undefined) { + charset = cfg.defCharset || 'utf8' + } - return inserted + this.decoder = new Decoder() + this.charset = charset + this._fields = 0 + this._state = 'key' + this._checkingBytes = true + this._bytesKey = 0 + this._bytesVal = 0 + this._key = '' + this._val = '' + this._keyTrunc = false + this._valTrunc = false + this._hitLimit = false } - function push(self, item) { - self.tail = new Node(item, self.tail, null, self) - if (!self.head) { - self.head = self.tail + UrlEncoded.prototype.write = function (data, cb) { + if (this._fields === this.fieldsLimit) { + if (!this.boy.hitFieldsLimit) { + this.boy.hitFieldsLimit = true + this.boy.emit('fieldsLimit') + } + return cb() } - self.length++ - } - function unshift(self, item) { - self.head = new Node(item, null, self.head, self) - if (!self.tail) { - self.tail = self.head - } - self.length++ - } + let idxeq + let idxamp + let i + let p = 0 + const len = data.length - function Node(value, prev, next, list) { - if (!(this instanceof Node)) { - return new Node(value, prev, next, list) - } + while (p < len) { + if (this._state === 'key') { + idxeq = idxamp = undefined + for (i = p; i < len; ++i) { + if (!this._checkingBytes) { + ++p + } + if (data[i] === 0x3d /* = */) { + idxeq = i + break + } else if (data[i] === 0x26 /* & */) { + idxamp = i + break + } + if ( + this._checkingBytes && + this._bytesKey === this.fieldNameSizeLimit + ) { + this._hitLimit = true + break + } else if (this._checkingBytes) { + ++this._bytesKey + } + } - this.list = list - this.value = value + if (idxeq !== undefined) { + // key with assignment + if (idxeq > p) { + this._key += this.decoder.write( + data.toString('binary', p, idxeq) + ) + } + this._state = 'val' + + this._hitLimit = false + this._checkingBytes = true + this._val = '' + this._bytesVal = 0 + this._valTrunc = false + this.decoder.reset() + + p = idxeq + 1 + } else if (idxamp !== undefined) { + // key with no assignment + ++this._fields + let key + const keyTrunc = this._keyTrunc + if (idxamp > p) { + key = this._key += this.decoder.write( + data.toString('binary', p, idxamp) + ) + } else { + key = this._key + } - if (prev) { - prev.next = this - this.prev = prev - } else { - this.prev = null - } + this._hitLimit = false + this._checkingBytes = true + this._key = '' + this._bytesKey = 0 + this._keyTrunc = false + this.decoder.reset() + + if (key.length) { + this.boy.emit( + 'field', + decodeText(key, 'binary', this.charset), + '', + keyTrunc, + false + ) + } - if (next) { - next.prev = this - this.next = next - } else { - this.next = null + p = idxamp + 1 + if (this._fields === this.fieldsLimit) { + return cb() + } + } else if (this._hitLimit) { + // we may not have hit the actual limit if there are encoded bytes... + if (i > p) { + this._key += this.decoder.write(data.toString('binary', p, i)) + } + p = i + if ( + (this._bytesKey = this._key.length) === this.fieldNameSizeLimit + ) { + // yep, we actually did hit the limit + this._checkingBytes = false + this._keyTrunc = true + } + } else { + if (p < len) { + this._key += this.decoder.write(data.toString('binary', p)) + } + p = len + } + } else { + idxamp = undefined + for (i = p; i < len; ++i) { + if (!this._checkingBytes) { + ++p + } + if (data[i] === 0x26 /* & */) { + idxamp = i + break + } + if ( + this._checkingBytes && + this._bytesVal === this.fieldSizeLimit + ) { + this._hitLimit = true + break + } else if (this._checkingBytes) { + ++this._bytesVal + } + } + + if (idxamp !== undefined) { + ++this._fields + if (idxamp > p) { + this._val += this.decoder.write( + data.toString('binary', p, idxamp) + ) + } + this.boy.emit( + 'field', + decodeText(this._key, 'binary', this.charset), + decodeText(this._val, 'binary', this.charset), + this._keyTrunc, + this._valTrunc + ) + this._state = 'key' + + this._hitLimit = false + this._checkingBytes = true + this._key = '' + this._bytesKey = 0 + this._keyTrunc = false + this.decoder.reset() + + p = idxamp + 1 + if (this._fields === this.fieldsLimit) { + return cb() + } + } else if (this._hitLimit) { + // we may not have hit the actual limit if there are encoded bytes... + if (i > p) { + this._val += this.decoder.write(data.toString('binary', p, i)) + } + p = i + if ( + (this._val === '' && this.fieldSizeLimit === 0) || + (this._bytesVal = this._val.length) === this.fieldSizeLimit + ) { + // yep, we actually did hit the limit + this._checkingBytes = false + this._valTrunc = true + } + } else { + if (p < len) { + this._val += this.decoder.write(data.toString('binary', p)) + } + p = len + } + } } + cb() } - try { - // add if support for Symbol.iterator is present - __nccwpck_require__(4091)(Yallist) - } catch (er) {} + UrlEncoded.prototype.end = function () { + if (this.boy._done) { + return + } - /***/ - }, + if (this._state === 'key' && this._key.length > 0) { + this.boy.emit( + 'field', + decodeText(this._key, 'binary', this.charset), + '', + this._keyTrunc, + false + ) + } else if (this._state === 'val') { + this.boy.emit( + 'field', + decodeText(this._key, 'binary', this.charset), + decodeText(this._val, 'binary', this.charset), + this._keyTrunc, + this._valTrunc + ) + } + this.boy._done = true + this.boy.emit('finish') + } - /***/ 2877: /***/ (module) => { - module.exports = eval('require')('encoding') + module.exports = UrlEncoded /***/ }, - /***/ 9491: /***/ (module) => { + /***/ 7100: /***/ (module) => { 'use strict' - module.exports = require('assert') - /***/ - }, + const RE_PLUS = /\+/g - /***/ 6113: /***/ (module) => { - 'use strict' - module.exports = require('crypto') + const HEX = [ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + ] - /***/ - }, + function Decoder() { + this.buffer = undefined + } + Decoder.prototype.write = function (str) { + // Replace '+' with ' ' before decoding + str = str.replace(RE_PLUS, ' ') + let res = '' + let i = 0 + let p = 0 + const len = str.length + for (; i < len; ++i) { + if (this.buffer !== undefined) { + if (!HEX[str.charCodeAt(i)]) { + res += '%' + this.buffer + this.buffer = undefined + --i // retry character + } else { + this.buffer += str[i] + ++p + if (this.buffer.length === 2) { + res += String.fromCharCode(parseInt(this.buffer, 16)) + this.buffer = undefined + } + } + } else if (str[i] === '%') { + if (i > p) { + res += str.substring(p, i) + p = i + } + this.buffer = '' + ++p + } + } + if (p < len && this.buffer === undefined) { + res += str.substring(p) + } + return res + } + Decoder.prototype.reset = function () { + this.buffer = undefined + } - /***/ 2361: /***/ (module) => { - 'use strict' - module.exports = require('events') + module.exports = Decoder /***/ }, - /***/ 7147: /***/ (module) => { + /***/ 8647: /***/ (module) => { 'use strict' - module.exports = require('fs') + + module.exports = function basename(path) { + if (typeof path !== 'string') { + return '' + } + for (var i = path.length - 1; i >= 0; --i) { + // eslint-disable-line no-var + switch (path.charCodeAt(i)) { + case 0x2f: // '/' + case 0x5c: // '\' + path = path.slice(i + 1) + return path === '..' || path === '.' ? '' : path + } + } + return path === '..' || path === '.' ? '' : path + } /***/ }, - /***/ 3685: /***/ (module) => { + /***/ 4619: /***/ function (module) { 'use strict' - module.exports = require('http') - /***/ - }, + // Node has always utf-8 + const utf8Decoder = new TextDecoder('utf-8') + const textDecoders = new Map([ + ['utf-8', utf8Decoder], + ['utf8', utf8Decoder], + ]) - /***/ 5687: /***/ (module) => { - 'use strict' - module.exports = require('https') + function getDecoder(charset) { + let lc + while (true) { + switch (charset) { + case 'utf-8': + case 'utf8': + return decoders.utf8 + case 'latin1': + case 'ascii': // TODO: Make these a separate, strict decoder? + case 'us-ascii': + case 'iso-8859-1': + case 'iso8859-1': + case 'iso88591': + case 'iso_8859-1': + case 'windows-1252': + case 'iso_8859-1:1987': + case 'cp1252': + case 'x-cp1252': + return decoders.latin1 + case 'utf16le': + case 'utf-16le': + case 'ucs2': + case 'ucs-2': + return decoders.utf16le + case 'base64': + return decoders.base64 + default: + if (lc === undefined) { + lc = true + charset = charset.toLowerCase() + continue + } + return decoders.other.bind(charset) + } + } + } - /***/ - }, + const decoders = { + utf8: (data, sourceEncoding) => { + if (data.length === 0) { + return '' + } + if (typeof data === 'string') { + data = Buffer.from(data, sourceEncoding) + } + return data.utf8Slice(0, data.length) + }, - /***/ 1808: /***/ (module) => { - 'use strict' - module.exports = require('net') + latin1: (data, sourceEncoding) => { + if (data.length === 0) { + return '' + } + if (typeof data === 'string') { + return data + } + return data.latin1Slice(0, data.length) + }, - /***/ - }, + utf16le: (data, sourceEncoding) => { + if (data.length === 0) { + return '' + } + if (typeof data === 'string') { + data = Buffer.from(data, sourceEncoding) + } + return data.ucs2Slice(0, data.length) + }, - /***/ 2037: /***/ (module) => { - 'use strict' - module.exports = require('os') + base64: (data, sourceEncoding) => { + if (data.length === 0) { + return '' + } + if (typeof data === 'string') { + data = Buffer.from(data, sourceEncoding) + } + return data.base64Slice(0, data.length) + }, - /***/ - }, + other: (data, sourceEncoding) => { + if (data.length === 0) { + return '' + } + if (typeof data === 'string') { + data = Buffer.from(data, sourceEncoding) + } - /***/ 1017: /***/ (module) => { - 'use strict' - module.exports = require('path') + if (textDecoders.has(this.toString())) { + try { + return textDecoders.get(this).decode(data) + } catch (e) {} + } + return typeof data === 'string' ? data : data.toString() + }, + } - /***/ - }, + function decodeText(text, sourceEncoding, destEncoding) { + if (text) { + return getDecoder(destEncoding)(text, sourceEncoding) + } + return text + } - /***/ 5477: /***/ (module) => { - 'use strict' - module.exports = require('punycode') + module.exports = decodeText /***/ }, - /***/ 2781: /***/ (module) => { + /***/ 1467: /***/ (module) => { 'use strict' - module.exports = require('stream') - /***/ - }, + module.exports = function getLimit(limits, name, defaultLimit) { + if (!limits || limits[name] === undefined || limits[name] === null) { + return defaultLimit + } - /***/ 4404: /***/ (module) => { - 'use strict' - module.exports = require('tls') + if (typeof limits[name] !== 'number' || isNaN(limits[name])) { + throw new TypeError('Limit ' + name + ' is not a valid number') + } + + return limits[name] + } /***/ }, - /***/ 7310: /***/ (module) => { + /***/ 1854: /***/ ( + module, + __unused_webpack_exports, + __nccwpck_require__ + ) => { 'use strict' - module.exports = require('url') + /* eslint-disable object-property-newline */ + + const decodeText = __nccwpck_require__(4619) + + const RE_ENCODED = /%[a-fA-F0-9][a-fA-F0-9]/g + + const EncodedLookup = { + '%00': '\x00', + '%01': '\x01', + '%02': '\x02', + '%03': '\x03', + '%04': '\x04', + '%05': '\x05', + '%06': '\x06', + '%07': '\x07', + '%08': '\x08', + '%09': '\x09', + '%0a': '\x0a', + '%0A': '\x0a', + '%0b': '\x0b', + '%0B': '\x0b', + '%0c': '\x0c', + '%0C': '\x0c', + '%0d': '\x0d', + '%0D': '\x0d', + '%0e': '\x0e', + '%0E': '\x0e', + '%0f': '\x0f', + '%0F': '\x0f', + '%10': '\x10', + '%11': '\x11', + '%12': '\x12', + '%13': '\x13', + '%14': '\x14', + '%15': '\x15', + '%16': '\x16', + '%17': '\x17', + '%18': '\x18', + '%19': '\x19', + '%1a': '\x1a', + '%1A': '\x1a', + '%1b': '\x1b', + '%1B': '\x1b', + '%1c': '\x1c', + '%1C': '\x1c', + '%1d': '\x1d', + '%1D': '\x1d', + '%1e': '\x1e', + '%1E': '\x1e', + '%1f': '\x1f', + '%1F': '\x1f', + '%20': '\x20', + '%21': '\x21', + '%22': '\x22', + '%23': '\x23', + '%24': '\x24', + '%25': '\x25', + '%26': '\x26', + '%27': '\x27', + '%28': '\x28', + '%29': '\x29', + '%2a': '\x2a', + '%2A': '\x2a', + '%2b': '\x2b', + '%2B': '\x2b', + '%2c': '\x2c', + '%2C': '\x2c', + '%2d': '\x2d', + '%2D': '\x2d', + '%2e': '\x2e', + '%2E': '\x2e', + '%2f': '\x2f', + '%2F': '\x2f', + '%30': '\x30', + '%31': '\x31', + '%32': '\x32', + '%33': '\x33', + '%34': '\x34', + '%35': '\x35', + '%36': '\x36', + '%37': '\x37', + '%38': '\x38', + '%39': '\x39', + '%3a': '\x3a', + '%3A': '\x3a', + '%3b': '\x3b', + '%3B': '\x3b', + '%3c': '\x3c', + '%3C': '\x3c', + '%3d': '\x3d', + '%3D': '\x3d', + '%3e': '\x3e', + '%3E': '\x3e', + '%3f': '\x3f', + '%3F': '\x3f', + '%40': '\x40', + '%41': '\x41', + '%42': '\x42', + '%43': '\x43', + '%44': '\x44', + '%45': '\x45', + '%46': '\x46', + '%47': '\x47', + '%48': '\x48', + '%49': '\x49', + '%4a': '\x4a', + '%4A': '\x4a', + '%4b': '\x4b', + '%4B': '\x4b', + '%4c': '\x4c', + '%4C': '\x4c', + '%4d': '\x4d', + '%4D': '\x4d', + '%4e': '\x4e', + '%4E': '\x4e', + '%4f': '\x4f', + '%4F': '\x4f', + '%50': '\x50', + '%51': '\x51', + '%52': '\x52', + '%53': '\x53', + '%54': '\x54', + '%55': '\x55', + '%56': '\x56', + '%57': '\x57', + '%58': '\x58', + '%59': '\x59', + '%5a': '\x5a', + '%5A': '\x5a', + '%5b': '\x5b', + '%5B': '\x5b', + '%5c': '\x5c', + '%5C': '\x5c', + '%5d': '\x5d', + '%5D': '\x5d', + '%5e': '\x5e', + '%5E': '\x5e', + '%5f': '\x5f', + '%5F': '\x5f', + '%60': '\x60', + '%61': '\x61', + '%62': '\x62', + '%63': '\x63', + '%64': '\x64', + '%65': '\x65', + '%66': '\x66', + '%67': '\x67', + '%68': '\x68', + '%69': '\x69', + '%6a': '\x6a', + '%6A': '\x6a', + '%6b': '\x6b', + '%6B': '\x6b', + '%6c': '\x6c', + '%6C': '\x6c', + '%6d': '\x6d', + '%6D': '\x6d', + '%6e': '\x6e', + '%6E': '\x6e', + '%6f': '\x6f', + '%6F': '\x6f', + '%70': '\x70', + '%71': '\x71', + '%72': '\x72', + '%73': '\x73', + '%74': '\x74', + '%75': '\x75', + '%76': '\x76', + '%77': '\x77', + '%78': '\x78', + '%79': '\x79', + '%7a': '\x7a', + '%7A': '\x7a', + '%7b': '\x7b', + '%7B': '\x7b', + '%7c': '\x7c', + '%7C': '\x7c', + '%7d': '\x7d', + '%7D': '\x7d', + '%7e': '\x7e', + '%7E': '\x7e', + '%7f': '\x7f', + '%7F': '\x7f', + '%80': '\x80', + '%81': '\x81', + '%82': '\x82', + '%83': '\x83', + '%84': '\x84', + '%85': '\x85', + '%86': '\x86', + '%87': '\x87', + '%88': '\x88', + '%89': '\x89', + '%8a': '\x8a', + '%8A': '\x8a', + '%8b': '\x8b', + '%8B': '\x8b', + '%8c': '\x8c', + '%8C': '\x8c', + '%8d': '\x8d', + '%8D': '\x8d', + '%8e': '\x8e', + '%8E': '\x8e', + '%8f': '\x8f', + '%8F': '\x8f', + '%90': '\x90', + '%91': '\x91', + '%92': '\x92', + '%93': '\x93', + '%94': '\x94', + '%95': '\x95', + '%96': '\x96', + '%97': '\x97', + '%98': '\x98', + '%99': '\x99', + '%9a': '\x9a', + '%9A': '\x9a', + '%9b': '\x9b', + '%9B': '\x9b', + '%9c': '\x9c', + '%9C': '\x9c', + '%9d': '\x9d', + '%9D': '\x9d', + '%9e': '\x9e', + '%9E': '\x9e', + '%9f': '\x9f', + '%9F': '\x9f', + '%a0': '\xa0', + '%A0': '\xa0', + '%a1': '\xa1', + '%A1': '\xa1', + '%a2': '\xa2', + '%A2': '\xa2', + '%a3': '\xa3', + '%A3': '\xa3', + '%a4': '\xa4', + '%A4': '\xa4', + '%a5': '\xa5', + '%A5': '\xa5', + '%a6': '\xa6', + '%A6': '\xa6', + '%a7': '\xa7', + '%A7': '\xa7', + '%a8': '\xa8', + '%A8': '\xa8', + '%a9': '\xa9', + '%A9': '\xa9', + '%aa': '\xaa', + '%Aa': '\xaa', + '%aA': '\xaa', + '%AA': '\xaa', + '%ab': '\xab', + '%Ab': '\xab', + '%aB': '\xab', + '%AB': '\xab', + '%ac': '\xac', + '%Ac': '\xac', + '%aC': '\xac', + '%AC': '\xac', + '%ad': '\xad', + '%Ad': '\xad', + '%aD': '\xad', + '%AD': '\xad', + '%ae': '\xae', + '%Ae': '\xae', + '%aE': '\xae', + '%AE': '\xae', + '%af': '\xaf', + '%Af': '\xaf', + '%aF': '\xaf', + '%AF': '\xaf', + '%b0': '\xb0', + '%B0': '\xb0', + '%b1': '\xb1', + '%B1': '\xb1', + '%b2': '\xb2', + '%B2': '\xb2', + '%b3': '\xb3', + '%B3': '\xb3', + '%b4': '\xb4', + '%B4': '\xb4', + '%b5': '\xb5', + '%B5': '\xb5', + '%b6': '\xb6', + '%B6': '\xb6', + '%b7': '\xb7', + '%B7': '\xb7', + '%b8': '\xb8', + '%B8': '\xb8', + '%b9': '\xb9', + '%B9': '\xb9', + '%ba': '\xba', + '%Ba': '\xba', + '%bA': '\xba', + '%BA': '\xba', + '%bb': '\xbb', + '%Bb': '\xbb', + '%bB': '\xbb', + '%BB': '\xbb', + '%bc': '\xbc', + '%Bc': '\xbc', + '%bC': '\xbc', + '%BC': '\xbc', + '%bd': '\xbd', + '%Bd': '\xbd', + '%bD': '\xbd', + '%BD': '\xbd', + '%be': '\xbe', + '%Be': '\xbe', + '%bE': '\xbe', + '%BE': '\xbe', + '%bf': '\xbf', + '%Bf': '\xbf', + '%bF': '\xbf', + '%BF': '\xbf', + '%c0': '\xc0', + '%C0': '\xc0', + '%c1': '\xc1', + '%C1': '\xc1', + '%c2': '\xc2', + '%C2': '\xc2', + '%c3': '\xc3', + '%C3': '\xc3', + '%c4': '\xc4', + '%C4': '\xc4', + '%c5': '\xc5', + '%C5': '\xc5', + '%c6': '\xc6', + '%C6': '\xc6', + '%c7': '\xc7', + '%C7': '\xc7', + '%c8': '\xc8', + '%C8': '\xc8', + '%c9': '\xc9', + '%C9': '\xc9', + '%ca': '\xca', + '%Ca': '\xca', + '%cA': '\xca', + '%CA': '\xca', + '%cb': '\xcb', + '%Cb': '\xcb', + '%cB': '\xcb', + '%CB': '\xcb', + '%cc': '\xcc', + '%Cc': '\xcc', + '%cC': '\xcc', + '%CC': '\xcc', + '%cd': '\xcd', + '%Cd': '\xcd', + '%cD': '\xcd', + '%CD': '\xcd', + '%ce': '\xce', + '%Ce': '\xce', + '%cE': '\xce', + '%CE': '\xce', + '%cf': '\xcf', + '%Cf': '\xcf', + '%cF': '\xcf', + '%CF': '\xcf', + '%d0': '\xd0', + '%D0': '\xd0', + '%d1': '\xd1', + '%D1': '\xd1', + '%d2': '\xd2', + '%D2': '\xd2', + '%d3': '\xd3', + '%D3': '\xd3', + '%d4': '\xd4', + '%D4': '\xd4', + '%d5': '\xd5', + '%D5': '\xd5', + '%d6': '\xd6', + '%D6': '\xd6', + '%d7': '\xd7', + '%D7': '\xd7', + '%d8': '\xd8', + '%D8': '\xd8', + '%d9': '\xd9', + '%D9': '\xd9', + '%da': '\xda', + '%Da': '\xda', + '%dA': '\xda', + '%DA': '\xda', + '%db': '\xdb', + '%Db': '\xdb', + '%dB': '\xdb', + '%DB': '\xdb', + '%dc': '\xdc', + '%Dc': '\xdc', + '%dC': '\xdc', + '%DC': '\xdc', + '%dd': '\xdd', + '%Dd': '\xdd', + '%dD': '\xdd', + '%DD': '\xdd', + '%de': '\xde', + '%De': '\xde', + '%dE': '\xde', + '%DE': '\xde', + '%df': '\xdf', + '%Df': '\xdf', + '%dF': '\xdf', + '%DF': '\xdf', + '%e0': '\xe0', + '%E0': '\xe0', + '%e1': '\xe1', + '%E1': '\xe1', + '%e2': '\xe2', + '%E2': '\xe2', + '%e3': '\xe3', + '%E3': '\xe3', + '%e4': '\xe4', + '%E4': '\xe4', + '%e5': '\xe5', + '%E5': '\xe5', + '%e6': '\xe6', + '%E6': '\xe6', + '%e7': '\xe7', + '%E7': '\xe7', + '%e8': '\xe8', + '%E8': '\xe8', + '%e9': '\xe9', + '%E9': '\xe9', + '%ea': '\xea', + '%Ea': '\xea', + '%eA': '\xea', + '%EA': '\xea', + '%eb': '\xeb', + '%Eb': '\xeb', + '%eB': '\xeb', + '%EB': '\xeb', + '%ec': '\xec', + '%Ec': '\xec', + '%eC': '\xec', + '%EC': '\xec', + '%ed': '\xed', + '%Ed': '\xed', + '%eD': '\xed', + '%ED': '\xed', + '%ee': '\xee', + '%Ee': '\xee', + '%eE': '\xee', + '%EE': '\xee', + '%ef': '\xef', + '%Ef': '\xef', + '%eF': '\xef', + '%EF': '\xef', + '%f0': '\xf0', + '%F0': '\xf0', + '%f1': '\xf1', + '%F1': '\xf1', + '%f2': '\xf2', + '%F2': '\xf2', + '%f3': '\xf3', + '%F3': '\xf3', + '%f4': '\xf4', + '%F4': '\xf4', + '%f5': '\xf5', + '%F5': '\xf5', + '%f6': '\xf6', + '%F6': '\xf6', + '%f7': '\xf7', + '%F7': '\xf7', + '%f8': '\xf8', + '%F8': '\xf8', + '%f9': '\xf9', + '%F9': '\xf9', + '%fa': '\xfa', + '%Fa': '\xfa', + '%fA': '\xfa', + '%FA': '\xfa', + '%fb': '\xfb', + '%Fb': '\xfb', + '%fB': '\xfb', + '%FB': '\xfb', + '%fc': '\xfc', + '%Fc': '\xfc', + '%fC': '\xfc', + '%FC': '\xfc', + '%fd': '\xfd', + '%Fd': '\xfd', + '%fD': '\xfd', + '%FD': '\xfd', + '%fe': '\xfe', + '%Fe': '\xfe', + '%fE': '\xfe', + '%FE': '\xfe', + '%ff': '\xff', + '%Ff': '\xff', + '%fF': '\xff', + '%FF': '\xff', + } + + function encodedReplacer(match) { + return EncodedLookup[match] + } + + const STATE_KEY = 0 + const STATE_VALUE = 1 + const STATE_CHARSET = 2 + const STATE_LANG = 3 + + function parseParams(str) { + const res = [] + let state = STATE_KEY + let charset = '' + let inquote = false + let escaping = false + let p = 0 + let tmp = '' + const len = str.length - /***/ - }, + for (var i = 0; i < len; ++i) { + // eslint-disable-line no-var + const char = str[i] + if (char === '\\' && inquote) { + if (escaping) { + escaping = false + } else { + escaping = true + continue + } + } else if (char === '"') { + if (!escaping) { + if (inquote) { + inquote = false + state = STATE_KEY + } else { + inquote = true + } + continue + } else { + escaping = false + } + } else { + if (escaping && inquote) { + tmp += '\\' + } + escaping = false + if ( + (state === STATE_CHARSET || state === STATE_LANG) && + char === "'" + ) { + if (state === STATE_CHARSET) { + state = STATE_LANG + charset = tmp.substring(1) + } else { + state = STATE_VALUE + } + tmp = '' + continue + } else if ( + state === STATE_KEY && + (char === '*' || char === '=') && + res.length + ) { + state = char === '*' ? STATE_CHARSET : STATE_VALUE + res[p] = [tmp, undefined] + tmp = '' + continue + } else if (!inquote && char === ';') { + state = STATE_KEY + if (charset) { + if (tmp.length) { + tmp = decodeText( + tmp.replace(RE_ENCODED, encodedReplacer), + 'binary', + charset + ) + } + charset = '' + } else if (tmp.length) { + tmp = decodeText(tmp, 'binary', 'utf8') + } + if (res[p] === undefined) { + res[p] = tmp + } else { + res[p][1] = tmp + } + tmp = '' + ++p + continue + } else if (!inquote && (char === ' ' || char === '\t')) { + continue + } + } + tmp += char + } + if (charset && tmp.length) { + tmp = decodeText( + tmp.replace(RE_ENCODED, encodedReplacer), + 'binary', + charset + ) + } else if (tmp) { + tmp = decodeText(tmp, 'binary', 'utf8') + } - /***/ 3837: /***/ (module) => { - 'use strict' - module.exports = require('util') + if (res[p] === undefined) { + if (tmp) { + res[p] = tmp + } + } else { + res[p][1] = tmp + } - /***/ - }, + return res + } - /***/ 9796: /***/ (module) => { - 'use strict' - module.exports = require('zlib') + module.exports = parseParams /***/ }, @@ -15699,12 +41496,17 @@ return new RegExp(pattern, onlyFirst ? undefined : 'g') } // CONCATENATED MODULE: ./node_modules/strip-ansi/index.js + const regex = ansiRegex() + function stripAnsi(string) { if (typeof string !== 'string') { throw new TypeError(`Expected a \`string\`, got \`${typeof string}\``) } - return string.replace(ansiRegex(), '') + // Even though the regex is global, we don't need to reset the `.lastIndex` + // because unlike `.exec()` and `.test()`, `.replace()` does it automatically + // and doing it manually has a performance penalty. + return string.replace(regex, '') } /***/ @@ -16064,7 +41866,7 @@ 2 ) console.log( - 'Storing slack payload to ./slack-paylod.json to report into Slack channel.', + 'Storing slack payload to ./slack-payload.json to report into Slack channel.', slackPayloadJson ) fs.writeFileSync('./slack-payload.json', slackPayloadJson) @@ -16343,9 +42145,7 @@ }, [[], []] ) - console.log(`Flakyness test subset results`, { - flakyMonitorJobResults, - }) + console.log(`Flakyness test subset results`, { flakyMonitorJobResults }) testResultManifest.flakyMonitorJobResults = flakyMonitorJobResults testResultManifest.result = jobResults // Collect all test results into single manifest to store into file. This'll allow to upload / compare test results diff --git a/.github/actions/next-integration-stat/package.json b/.github/actions/next-integration-stat/package.json index db173fb9cfb6b..cef82ad0b4ea7 100644 --- a/.github/actions/next-integration-stat/package.json +++ b/.github/actions/next-integration-stat/package.json @@ -8,7 +8,6 @@ "lint:prettier": "prettier -c . --cache --ignore-path=../../../.prettierignore" }, "devDependencies": { - "@turbo/eslint-config": "workspace:*", "@types/node": "^18.11.18", "@vercel/ncc": "0.34.0", "typescript": "^4.4.4" diff --git a/.github/actions/next-integration-stat/src/index.ts b/.github/actions/next-integration-stat/src/index.ts index eb0d1204095f9..fb229262317d4 100644 --- a/.github/actions/next-integration-stat/src/index.ts +++ b/.github/actions/next-integration-stat/src/index.ts @@ -6,41 +6,7 @@ const fs = require('fs') const path = require('path') const semver = require('semver') -/** - * Models parsed test results output from next.js integration test. - * This is a subset of the full test result output from jest, partially compatible. - */ -interface TestResult { - numFailedTestSuites: number - numFailedTests: number - numPassedTestSuites: number - numPassedTests: number - numPendingTestSuites: number - numPendingTests: number - numRuntimeErrorTestSuites: number - numTodoTests: number - numTotalTestSuites: number - numTotalTests: number - startTime: number - success: boolean - testResults?: Array<{ - assertionResults?: Array<{ - ancestorTitles?: Array | null - failureMessages?: Array | null - fullName: string - location?: null - status: string - title: string - }> | null - endTime: number - message: string - name: string - startTime: number - status: string - summary: string - }> | null - wasInterrupted: boolean -} +/// type Octokit = ReturnType @@ -53,18 +19,6 @@ type ExistingComment = ReturnType >['data'][number] | undefined -interface JobResult { - job: string - data: TestResult -} -interface TestResultManifest { - nextjsVersion: string - ref: string - buildTime?: string - buildSize?: string - result: Array - flakyMonitorJobResults: Array -} // A comment marker to identify the comment created by this action. const BOT_COMMENT_MARKER = `` diff --git a/.github/actions/next-integration-stat/src/manifest.d.ts b/.github/actions/next-integration-stat/src/manifest.d.ts new file mode 100644 index 0000000000000..4c8d724ab2703 --- /dev/null +++ b/.github/actions/next-integration-stat/src/manifest.d.ts @@ -0,0 +1,49 @@ +interface JobResult { + job: string + data: TestResult +} + +interface TestResultManifest { + nextjsVersion: string + ref: string + buildTime?: string + buildSize?: string + result: Array + flakyMonitorJobResults: Array +} + +/** + * Models parsed test results output from next.js integration test. + * This is a subset of the full test result output from jest, partially compatible. + */ +interface TestResult { + numFailedTestSuites: number + numFailedTests: number + numPassedTestSuites: number + numPassedTests: number + numPendingTestSuites: number + numPendingTests: number + numRuntimeErrorTestSuites: number + numTodoTests: number + numTotalTestSuites: number + numTotalTests: number + startTime: number + success: boolean + testResults?: Array<{ + assertionResults?: Array<{ + ancestorTitles?: Array | null + failureMessages?: Array | null + fullName: string + location?: null + status: string + title: string + }> | null + endTime: number + message: string + name: string + startTime: number + status: string + summary: string + }> | null + wasInterrupted: boolean +} diff --git a/package.json b/package.json index 3cc3f9e89dfa4..8df96c207df80 100644 --- a/package.json +++ b/package.json @@ -162,6 +162,7 @@ "jest-extended": "4.0.2", "jest-junit": "16.0.0", "json5": "2.2.3", + "kleur": "^4.1.0", "ky": "0.19.1", "ky-universal": "0.6.0", "lerna": "4.0.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ffeaa6ab48110..9bd496a4c8a26 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -332,6 +332,9 @@ importers: json5: specifier: 2.2.3 version: 2.2.3 + kleur: + specifier: ^4.1.0 + version: 4.1.3 ky: specifier: 0.19.1 version: 0.19.1 diff --git a/test/build-turbopack-tests-manifest.d.ts b/test/build-turbopack-tests-manifest.d.ts new file mode 100644 index 0000000000000..e5d3ad09fafa5 --- /dev/null +++ b/test/build-turbopack-tests-manifest.d.ts @@ -0,0 +1,28 @@ +/// + +type ListArtifactsResponse = { + total_count: number + artifacts: Artifact[] +} + +type Artifact = { + id: number + node_id: string + name: string + size_in_bytes: number + url: string + archive_download_url: string + expired: false + created_at: string + expires_at: string + updated_at: string + workflow_run: WorkflowRun +} + +type WorkflowRun = { + id: number + repository_id: number + head_repository_id: number + head_branch: string + head_sha: string +} diff --git a/test/build-turbopack-tests-manifest.js b/test/build-turbopack-tests-manifest.js index 534edd7f7c75b..fbbc4b5d24b35 100644 --- a/test/build-turbopack-tests-manifest.js +++ b/test/build-turbopack-tests-manifest.js @@ -1,6 +1,10 @@ -const fetch = require('node-fetch') const fs = require('fs') +const os = require('os') +const path = require('path') + const prettier = require('prettier') +const execa = require('execa') +const { bold } = require('kleur') async function format(text) { const options = await prettier.resolveConfig(__filename) @@ -9,10 +13,8 @@ async function format(text) { const override = process.argv.includes('--override') -const RESULT_URL = - 'https://raw.githubusercontent.com/vercel/turbo/nextjs-integration-test-data/test-results/main/nextjs-test-results.json' const PASSING_JSON_PATH = `${__dirname}/turbopack-tests-manifest.json` -const WORKING_PATH = '/home/runner/work/turbo/turbo/' +const WORKING_PATH = '/root/actions-runner/_work/next.js/next.js/' const INITIALIZING_TEST_CASES = [ 'compile successfully', @@ -106,11 +108,93 @@ const SKIPPED_TEST_SUITES = { ], } +/** + * @param title {string} + * @param file {string} + * @param args {readonly string[]} + * @returns {execa.ExecaChildProcess} + */ +function exec(title, file, args) { + logCommand(title, `${file} ${args.join(' ')}`) + + return execa(file, args, { + stderr: 'inherit', + }) +} + +/** + * @param {string} title + * @param {string} [command] + */ +function logCommand(title, command) { + let message = `\n${bold().underline(title)}\n` + + if (command) { + message += `> ${bold(command)}\n` + } + + console.log(message) +} + +/** + * @returns {Promise} + */ +async function fetchLatestTestArtifact() { + const { stdout } = await exec( + 'Getting latest test artifacts from GitHub actions', + 'gh', + ['api', '/repos/vercel/next.js/actions/artifacts?name=test-results'] + ) + + /** @type {ListArtifactsResponse} */ + const res = JSON.parse(stdout) + + for (const artifact of res.artifacts) { + if (artifact.expired || artifact.workflow_run.head_branch !== 'canary') { + continue + } + + return artifact + } + + throw new Error('no valid test-results artifact was found for branch canary') +} + +/** + * @returns {Promise} + */ +async function fetchTestResults() { + const artifact = await fetchLatestTestArtifact() + + const subprocess = exec('Downloading artifact archive', 'gh', [ + 'api', + `/repos/vercel/next.js/actions/artifacts/${artifact.id}/zip`, + ]) + + const filePath = path.join( + os.tmpdir(), + `next-test-results.${Math.floor(Math.random() * 1000).toString(16)}.zip` + ) + + subprocess.stdout.pipe(fs.createWriteStream(filePath)) + + await subprocess + + const { stdout } = await exec('Extracting test results manifest', 'unzip', [ + '-pj', + filePath, + 'nextjs-test-results.json', + ]) + + return JSON.parse(stdout) +} + async function updatePassingTests() { - const passing = { __proto__: null } - const res = await fetch(RESULT_URL) - const results = await res.json() + const results = await fetchTestResults() + logCommand('Processing results...') + + const passing = { __proto__: null } for (const result of results.result) { const runtimeError = result.data.numRuntimeErrorTestSuites > 0 for (const testResult of result.data.testResults) { @@ -153,13 +237,11 @@ async function updatePassingTests() { if (skippedPassingNames.length > 0) { console.log( - `${filepath} has ${ + `${bold().red(filepath)} has ${ skippedPassingNames.length - } passing tests that are marked as skipped: ${JSON.stringify( - skippedPassingNames, - 0, - 2 - )}` + } passing tests that are marked as skipped:\n${skippedPassingNames + .map((name) => ` - ${name}`) + .join('\n')}\n` ) } } @@ -190,9 +272,12 @@ async function updatePassingTests() { oldData.passed.filter((name) => newData.failed.includes(name)) ) if (shouldPass.size > 0) { - const list = JSON.stringify([...shouldPass], 0, 2) console.log( - `${file} has ${shouldPass.size} test(s) that should pass but failed: ${list}` + `${bold().red(file)} has ${ + shouldPass.size + } test(s) that should pass but failed:\n${Array.from(shouldPass) + .map((name) => ` - ${name}`) + .join('\n')}\n` ) } // Merge the old passing tests with the new ones @@ -203,7 +288,9 @@ async function updatePassingTests() { .sort() if (!oldData.runtimeError && newData.runtimeError) { - console.log(`${file} has a runtime error that is shouldn't have`) + console.log( + `${bold().red(file)} has a runtime error that is shouldn't have\n` + ) newData.runtimeError = false } } @@ -246,4 +333,7 @@ function stripWorkingPath(path) { return path.slice(WORKING_PATH.length) } -updatePassingTests() +updatePassingTests().catch((e) => { + console.error(e) + process.exit(1) +}) From 4465b1856f44f9d5368cd404f9c05786b07b2000 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Fri, 24 Nov 2023 17:53:28 +0100 Subject: [PATCH 042/481] fix uniqueness of layers (#58872) ### What? * rename `ssr` in app to `app-ssr` * rename `_` to `-` in layer names ### Why? `ssr` layer name was used twice, but it must be unique to avoid hanging compilation Closes PACK-2036 --- packages/next-swc/crates/next-api/src/app.rs | 8 ++++---- packages/next-swc/crates/next-api/src/pages.rs | 8 ++++---- .../crates/next-build/src/next_app/app_entries.rs | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/next-swc/crates/next-api/src/app.rs b/packages/next-swc/crates/next-api/src/app.rs index 7e01aeb11d555..5c4255063b809 100644 --- a/packages/next-swc/crates/next-api/src/app.rs +++ b/packages/next-swc/crates/next-api/src/app.rs @@ -232,7 +232,7 @@ impl AppProject { self.project().server_compile_time_info(), self.rsc_module_options_context(), self.rsc_resolve_options_context(), - Vc::cell("rsc".to_string()), + Vc::cell("app-rsc".to_string()), ) } @@ -262,7 +262,7 @@ impl AppProject { self.project().edge_compile_time_info(), self.rsc_module_options_context(), self.edge_rsc_resolve_options_context(), - Vc::cell("edge_rsc".to_string()), + Vc::cell("app-edge-rsc".to_string()), ) } @@ -319,7 +319,7 @@ impl AppProject { self.project().server_compile_time_info(), self.ssr_module_options_context(), self.ssr_resolve_options_context(), - Vc::cell("ssr".to_string()), + Vc::cell("app-ssr".to_string()), ) } @@ -329,7 +329,7 @@ impl AppProject { self.project().edge_compile_time_info(), self.ssr_module_options_context(), self.edge_ssr_resolve_options_context(), - Vc::cell("edge_ssr".to_string()), + Vc::cell("app-edge-ssr".to_string()), ) } diff --git a/packages/next-swc/crates/next-api/src/pages.rs b/packages/next-swc/crates/next-api/src/pages.rs index 070e8fc08c70c..35bb83441799c 100644 --- a/packages/next-swc/crates/next-api/src/pages.rs +++ b/packages/next-swc/crates/next-api/src/pages.rs @@ -340,7 +340,7 @@ impl PagesProject { self.project().server_compile_time_info(), self.ssr_data_module_options_context(), self.ssr_resolve_options_context(), - Vc::cell("ssr_data".to_string()), + Vc::cell("ssr-data".to_string()), ) } @@ -351,7 +351,7 @@ impl PagesProject { self.project().edge_compile_time_info(), self.ssr_module_options_context(), self.edge_ssr_resolve_options_context(), - Vc::cell("edge_ssr".to_string()), + Vc::cell("edge-ssr".to_string()), ) } @@ -362,7 +362,7 @@ impl PagesProject { self.project().edge_compile_time_info(), self.api_module_options_context(), self.edge_ssr_resolve_options_context(), - Vc::cell("edge_api".to_string()), + Vc::cell("edge-api".to_string()), ) } @@ -373,7 +373,7 @@ impl PagesProject { self.project().edge_compile_time_info(), self.ssr_data_module_options_context(), self.edge_ssr_resolve_options_context(), - Vc::cell("edge_ssr_data".to_string()), + Vc::cell("edge-ssr-data".to_string()), ) } diff --git a/packages/next-swc/crates/next-build/src/next_app/app_entries.rs b/packages/next-swc/crates/next-build/src/next_app/app_entries.rs index fad536024f284..e21ff0c6d7b83 100644 --- a/packages/next-swc/crates/next-build/src/next_app/app_entries.rs +++ b/packages/next-swc/crates/next-build/src/next_app/app_entries.rs @@ -137,7 +137,7 @@ pub async fn get_app_entries( server_compile_time_info, ssr_module_options_context, ssr_resolve_options_context, - Vc::cell("ssr".to_string()), + Vc::cell("app-ssr".to_string()), ); transitions.insert("next-ssr".to_string(), Vc::upcast(ssr_transition)); @@ -184,7 +184,7 @@ pub async fn get_app_entries( server_compile_time_info, rsc_module_options_context, rsc_resolve_options_context, - Vc::cell("rsc".to_string()), + Vc::cell("app-rsc".to_string()), ); let entries = entrypoints From e1cb3f5483184043aa4b65d510f50a3b9ce788cd Mon Sep 17 00:00:00 2001 From: Zack Tanner Date: Fri, 24 Nov 2023 10:43:37 -0800 Subject: [PATCH 043/481] disable flushToDisk during `generateStaticParams` (#58871) Follow-up to #58516 where a few spots where missed. This is only disabled in minimal mode. [Slack context](https://vercel.slack.com/archives/C042LHPJ1NX/p1700756778718459) --- packages/next/src/build/index.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/next/src/build/index.ts b/packages/next/src/build/index.ts index 9fd50672283ed..917bb161a4efa 100644 --- a/packages/next/src/build/index.ts +++ b/packages/next/src/build/index.ts @@ -1318,7 +1318,9 @@ export default async function build( pagesDir: true, appDir: true, fetchCache: true, - flushToDisk: config.experimental.isrFlushToDisk, + flushToDisk: ciEnvironment.hasNextSupport + ? false + : config.experimental.isrFlushToDisk, serverDistDir: path.join(distDir, 'server'), fetchCacheKeyPrefix: config.experimental.fetchCacheKeyPrefix, maxMemoryCacheSize: config.experimental.isrMemoryCacheSize, @@ -1611,7 +1613,9 @@ export default async function build( pageType, incrementalCacheHandlerPath: config.experimental.incrementalCacheHandlerPath, - isrFlushToDisk: config.experimental.isrFlushToDisk, + isrFlushToDisk: ciEnvironment.hasNextSupport + ? false + : config.experimental.isrFlushToDisk, maxMemoryCacheSize: config.experimental.isrMemoryCacheSize, nextConfigOutput: config.output, From 1496d50f68b75d9325364658ad1f59fe687d445f Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Fri, 24 Nov 2023 19:37:49 +0000 Subject: [PATCH 044/481] v14.0.4-canary.15 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 16 ++++++++-------- 18 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lerna.json b/lerna.json index c44596a511b8b..600f4da477c5d 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.14" + "version": "14.0.4-canary.15" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index acca66ea84cae..85ae7004047bf 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.14", + "version": "14.0.4-canary.15", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index d8a9518c9740a..567725f388f6c 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.14", + "version": "14.0.4-canary.15", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.14", + "@next/eslint-plugin-next": "14.0.4-canary.15", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 6afcb69c71dbf..8c1241684e049 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.14", + "version": "14.0.4-canary.15", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index 6549eb45ad989..c95547ce5a1ba 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.14", + "version": "14.0.4-canary.15", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 069b384d2f094..e8f5764484bb7 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.14", + "version": "14.0.4-canary.15", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index cfff7093f2a43..af13f67be6fa7 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.14", + "version": "14.0.4-canary.15", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 58f5f1b761688..0b8747e3baee1 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.14", + "version": "14.0.4-canary.15", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 4ce0219a929ed..9fce1280237c5 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.14", + "version": "14.0.4-canary.15", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 53e1dad1a2442..6aec29b88d82a 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.14", + "version": "14.0.4-canary.15", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index 59d97998934d0..32038f7b0f570 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.14", + "version": "14.0.4-canary.15", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index 6822914db8d9b..243e1545eebcd 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.14", + "version": "14.0.4-canary.15", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index d973d5606c7e8..587e590322dc1 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.14", + "version": "14.0.4-canary.15", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index 1c1fe91be66a3..ec28b000c367f 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.14", + "version": "14.0.4-canary.15", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.14", + "@next/env": "14.0.4-canary.15", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -146,11 +146,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.14", - "@next/polyfill-nomodule": "14.0.4-canary.14", - "@next/react-dev-overlay": "14.0.4-canary.14", - "@next/react-refresh-utils": "14.0.4-canary.14", - "@next/swc": "14.0.4-canary.14", + "@next/polyfill-module": "14.0.4-canary.15", + "@next/polyfill-nomodule": "14.0.4-canary.15", + "@next/react-dev-overlay": "14.0.4-canary.15", + "@next/react-refresh-utils": "14.0.4-canary.15", + "@next/swc": "14.0.4-canary.15", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index c0833ffdb19ac..e60cb95bf1af1 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.14", + "version": "14.0.4-canary.15", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index 71af12f5d9a5a..e5b470e1300b1 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.14", + "version": "14.0.4-canary.15", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index a31962fd20f55..8502e4f314592 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.14", + "version": "14.0.4-canary.15", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -23,7 +23,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.14", + "next": "14.0.4-canary.15", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9bd496a4c8a26..291f3ff9b265a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -738,7 +738,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.14 + specifier: 14.0.4-canary.15 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -803,7 +803,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.14 + specifier: 14.0.4-canary.15 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -927,19 +927,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.14 + specifier: 14.0.4-canary.15 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.14 + specifier: 14.0.4-canary.15 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.14 + specifier: 14.0.4-canary.15 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.14 + specifier: 14.0.4-canary.15 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.14 + specifier: 14.0.4-canary.15 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1590,7 +1590,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.14 + specifier: 14.0.4-canary.15 version: link:../next outdent: specifier: 0.8.0 From f6070c807b3af262a66f9562ac5f9b1bab318c02 Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Fri, 24 Nov 2023 23:21:37 +0000 Subject: [PATCH 045/481] v14.0.4-canary.16 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 16 ++++++++-------- 18 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lerna.json b/lerna.json index 600f4da477c5d..dd1f6fb516cac 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.15" + "version": "14.0.4-canary.16" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 85ae7004047bf..cf10038077ba8 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.15", + "version": "14.0.4-canary.16", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 567725f388f6c..c21feabc879b8 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.15", + "version": "14.0.4-canary.16", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.15", + "@next/eslint-plugin-next": "14.0.4-canary.16", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 8c1241684e049..84abdc7fe4f3b 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.15", + "version": "14.0.4-canary.16", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index c95547ce5a1ba..4ddc6160c96f0 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.15", + "version": "14.0.4-canary.16", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index e8f5764484bb7..5eccc51bc0c0f 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.15", + "version": "14.0.4-canary.16", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index af13f67be6fa7..95e543033dbfd 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.15", + "version": "14.0.4-canary.16", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 0b8747e3baee1..c47f44eb07153 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.15", + "version": "14.0.4-canary.16", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 9fce1280237c5..225b70e65ba10 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.15", + "version": "14.0.4-canary.16", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 6aec29b88d82a..a3968ecba86ac 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.15", + "version": "14.0.4-canary.16", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index 32038f7b0f570..c16a7905cb056 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.15", + "version": "14.0.4-canary.16", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index 243e1545eebcd..21d8e5e9805aa 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.15", + "version": "14.0.4-canary.16", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index 587e590322dc1..b5720a579cb6a 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.15", + "version": "14.0.4-canary.16", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index ec28b000c367f..2ec7c19f331bf 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.15", + "version": "14.0.4-canary.16", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.15", + "@next/env": "14.0.4-canary.16", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -146,11 +146,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.15", - "@next/polyfill-nomodule": "14.0.4-canary.15", - "@next/react-dev-overlay": "14.0.4-canary.15", - "@next/react-refresh-utils": "14.0.4-canary.15", - "@next/swc": "14.0.4-canary.15", + "@next/polyfill-module": "14.0.4-canary.16", + "@next/polyfill-nomodule": "14.0.4-canary.16", + "@next/react-dev-overlay": "14.0.4-canary.16", + "@next/react-refresh-utils": "14.0.4-canary.16", + "@next/swc": "14.0.4-canary.16", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index e60cb95bf1af1..65a41d4f91476 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.15", + "version": "14.0.4-canary.16", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index e5b470e1300b1..2960d7c7d9659 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.15", + "version": "14.0.4-canary.16", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index 8502e4f314592..bfe4c2bc8b99e 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.15", + "version": "14.0.4-canary.16", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -23,7 +23,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.15", + "next": "14.0.4-canary.16", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 291f3ff9b265a..19426aa8be6e2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -738,7 +738,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.15 + specifier: 14.0.4-canary.16 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -803,7 +803,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.15 + specifier: 14.0.4-canary.16 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -927,19 +927,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.15 + specifier: 14.0.4-canary.16 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.15 + specifier: 14.0.4-canary.16 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.15 + specifier: 14.0.4-canary.16 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.15 + specifier: 14.0.4-canary.16 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.15 + specifier: 14.0.4-canary.16 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1590,7 +1590,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.15 + specifier: 14.0.4-canary.16 version: link:../next outdent: specifier: 0.8.0 From 12a683b925efba8e770490db8b83645daa029ee9 Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Sat, 25 Nov 2023 23:21:36 +0000 Subject: [PATCH 046/481] v14.0.4-canary.17 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 16 ++++++++-------- 18 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lerna.json b/lerna.json index dd1f6fb516cac..1af4c8e867a7a 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.16" + "version": "14.0.4-canary.17" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index cf10038077ba8..6d02148a1511b 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.16", + "version": "14.0.4-canary.17", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index c21feabc879b8..db6a5d0a62cbd 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.16", + "version": "14.0.4-canary.17", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.16", + "@next/eslint-plugin-next": "14.0.4-canary.17", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 84abdc7fe4f3b..67502f34f5326 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.16", + "version": "14.0.4-canary.17", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index 4ddc6160c96f0..36b2de01ca8d1 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.16", + "version": "14.0.4-canary.17", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 5eccc51bc0c0f..4a101fbcb7983 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.16", + "version": "14.0.4-canary.17", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 95e543033dbfd..b50be48e9a2db 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.16", + "version": "14.0.4-canary.17", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index c47f44eb07153..e924c354b455e 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.16", + "version": "14.0.4-canary.17", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 225b70e65ba10..2dc40be47ba45 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.16", + "version": "14.0.4-canary.17", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index a3968ecba86ac..b2651d7ae2564 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.16", + "version": "14.0.4-canary.17", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index c16a7905cb056..906b7476bfb59 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.16", + "version": "14.0.4-canary.17", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index 21d8e5e9805aa..124887993fbf1 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.16", + "version": "14.0.4-canary.17", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index b5720a579cb6a..e238998e00340 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.16", + "version": "14.0.4-canary.17", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index 2ec7c19f331bf..6403c9bd5d620 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.16", + "version": "14.0.4-canary.17", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.16", + "@next/env": "14.0.4-canary.17", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -146,11 +146,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.16", - "@next/polyfill-nomodule": "14.0.4-canary.16", - "@next/react-dev-overlay": "14.0.4-canary.16", - "@next/react-refresh-utils": "14.0.4-canary.16", - "@next/swc": "14.0.4-canary.16", + "@next/polyfill-module": "14.0.4-canary.17", + "@next/polyfill-nomodule": "14.0.4-canary.17", + "@next/react-dev-overlay": "14.0.4-canary.17", + "@next/react-refresh-utils": "14.0.4-canary.17", + "@next/swc": "14.0.4-canary.17", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index 65a41d4f91476..61a1da5c3e4ce 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.16", + "version": "14.0.4-canary.17", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index 2960d7c7d9659..ff7dada5d8864 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.16", + "version": "14.0.4-canary.17", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index bfe4c2bc8b99e..f6fa0a79971c2 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.16", + "version": "14.0.4-canary.17", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -23,7 +23,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.16", + "next": "14.0.4-canary.17", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 19426aa8be6e2..522bde94ce1ca 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -738,7 +738,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.16 + specifier: 14.0.4-canary.17 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -803,7 +803,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.16 + specifier: 14.0.4-canary.17 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -927,19 +927,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.16 + specifier: 14.0.4-canary.17 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.16 + specifier: 14.0.4-canary.17 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.16 + specifier: 14.0.4-canary.17 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.16 + specifier: 14.0.4-canary.17 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.16 + specifier: 14.0.4-canary.17 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1590,7 +1590,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.16 + specifier: 14.0.4-canary.17 version: link:../next outdent: specifier: 0.8.0 From 9f69766cfa3234ac7a343abdd81f41315cf33891 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Sun, 26 Nov 2023 19:55:23 +0100 Subject: [PATCH 047/481] Turbopack: enable some node.js builtin in edge runtime (#58850) ### What? Edge runtime allow additional node.js builtins see https://github.com/vercel/turbo/pull/6562 Closes PACK-2031 --------- Co-authored-by: Tim Neutkens --- Cargo.lock | 66 +++++++++---------- Cargo.toml | 6 +- .../crates/next-core/src/next_edge/context.rs | 1 + packages/next/package.json | 2 +- pnpm-lock.yaml | 10 +-- 5 files changed, 43 insertions(+), 42 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f808972adf6aa..0a0f1f010f4e6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -322,7 +322,7 @@ dependencies = [ [[package]] name = "auto-hash-map" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" dependencies = [ "serde", "smallvec", @@ -3549,7 +3549,7 @@ dependencies = [ [[package]] name = "node-file-trace" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" dependencies = [ "anyhow", "serde", @@ -7695,7 +7695,7 @@ dependencies = [ [[package]] name = "turbo-tasks" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" dependencies = [ "anyhow", "async-trait", @@ -7727,7 +7727,7 @@ dependencies = [ [[package]] name = "turbo-tasks-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" dependencies = [ "anyhow", "cargo-lock", @@ -7739,7 +7739,7 @@ dependencies = [ [[package]] name = "turbo-tasks-bytes" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" dependencies = [ "anyhow", "bytes", @@ -7754,7 +7754,7 @@ dependencies = [ [[package]] name = "turbo-tasks-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" dependencies = [ "anyhow", "dotenvs", @@ -7768,7 +7768,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fetch" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7785,7 +7785,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fs" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" dependencies = [ "anyhow", "auto-hash-map", @@ -7815,7 +7815,7 @@ dependencies = [ [[package]] name = "turbo-tasks-hash" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" dependencies = [ "base16", "hex", @@ -7827,7 +7827,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" dependencies = [ "anyhow", "convert_case 0.6.0", @@ -7841,7 +7841,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros-shared" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" dependencies = [ "proc-macro2", "quote", @@ -7851,7 +7851,7 @@ dependencies = [ [[package]] name = "turbo-tasks-malloc" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" dependencies = [ "mimalloc", ] @@ -7859,7 +7859,7 @@ dependencies = [ [[package]] name = "turbo-tasks-memory" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" dependencies = [ "anyhow", "auto-hash-map", @@ -7884,7 +7884,7 @@ dependencies = [ [[package]] name = "turbopack" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" dependencies = [ "anyhow", "async-recursion", @@ -7915,7 +7915,7 @@ dependencies = [ [[package]] name = "turbopack-binding" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" dependencies = [ "auto-hash-map", "mdxjs", @@ -7955,7 +7955,7 @@ dependencies = [ [[package]] name = "turbopack-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7978,7 +7978,7 @@ dependencies = [ [[package]] name = "turbopack-cli-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" dependencies = [ "anyhow", "clap 4.4.2", @@ -8002,7 +8002,7 @@ dependencies = [ [[package]] name = "turbopack-core" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" dependencies = [ "anyhow", "async-recursion", @@ -8032,7 +8032,7 @@ dependencies = [ [[package]] name = "turbopack-css" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" dependencies = [ "anyhow", "async-trait", @@ -8058,7 +8058,7 @@ dependencies = [ [[package]] name = "turbopack-dev" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -8082,7 +8082,7 @@ dependencies = [ [[package]] name = "turbopack-dev-server" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" dependencies = [ "anyhow", "async-compression", @@ -8119,7 +8119,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" dependencies = [ "anyhow", "async-trait", @@ -8153,7 +8153,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-hmr-protocol" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" dependencies = [ "serde", "serde_json", @@ -8164,7 +8164,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-plugins" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" dependencies = [ "anyhow", "async-trait", @@ -8187,7 +8187,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-runtime" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" dependencies = [ "anyhow", "indoc", @@ -8204,7 +8204,7 @@ dependencies = [ [[package]] name = "turbopack-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -8220,7 +8220,7 @@ dependencies = [ [[package]] name = "turbopack-image" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" dependencies = [ "anyhow", "base64 0.21.4", @@ -8240,7 +8240,7 @@ dependencies = [ [[package]] name = "turbopack-json" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" dependencies = [ "anyhow", "serde", @@ -8255,7 +8255,7 @@ dependencies = [ [[package]] name = "turbopack-mdx" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" dependencies = [ "anyhow", "mdxjs", @@ -8270,7 +8270,7 @@ dependencies = [ [[package]] name = "turbopack-node" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" dependencies = [ "anyhow", "async-stream", @@ -8305,7 +8305,7 @@ dependencies = [ [[package]] name = "turbopack-static" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" dependencies = [ "anyhow", "serde", @@ -8321,7 +8321,7 @@ dependencies = [ [[package]] name = "turbopack-swc-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" dependencies = [ "swc_core", "turbo-tasks", @@ -8332,7 +8332,7 @@ dependencies = [ [[package]] name = "turbopack-wasm" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231124.2#b0d2798675a0dcf26176496491c0790502dcbe7b" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" dependencies = [ "anyhow", "indexmap 1.9.3", diff --git a/Cargo.toml b/Cargo.toml index a14ce800042f2..a6ed3bd05af4e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,11 +43,11 @@ next-transform-strip-page-exports = { path = "packages/next-swc/crates/next-tran testing = { version = "0.35.10" } # Turbo crates -turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231124.2" } +turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231126.2" } # [TODO]: need to refactor embed_directory! macro usages, as well as resolving turbo_tasks::function, macros.. -turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231124.2" } +turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231126.2" } # [TODO]: need to refactor embed_directory! macro usage in next-core -turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231124.2" } +turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231126.2" } # General Deps diff --git a/packages/next-swc/crates/next-core/src/next_edge/context.rs b/packages/next-swc/crates/next-core/src/next_edge/context.rs index f632b9f43cc6c..3566acf915ae6 100644 --- a/packages/next-swc/crates/next-core/src/next_edge/context.rs +++ b/packages/next-swc/crates/next-core/src/next_edge/context.rs @@ -138,6 +138,7 @@ pub async fn get_edge_resolve_options_context( enable_typescript: true, enable_react: true, enable_mjs_extension: true, + enable_edge_node_externals: true, rules: vec![( foreign_code_context_condition(next_config, project_path).await?, resolve_options_context.clone().cell(), diff --git a/packages/next/package.json b/packages/next/package.json index 6403c9bd5d620..9e2ffbe1a5011 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -193,7 +193,7 @@ "@types/ws": "8.2.0", "@vercel/ncc": "0.34.0", "@vercel/nft": "0.22.6", - "@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231124.2", + "@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231126.2", "acorn": "8.5.0", "amphtml-validator": "1.0.35", "anser": "1.4.9", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 522bde94ce1ca..521c25a4dcd65 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1068,8 +1068,8 @@ importers: specifier: 0.22.6 version: 0.22.6 '@vercel/turbopack-ecmascript-runtime': - specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231124.2 - version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231124.2(react-refresh@0.12.0)(webpack@5.86.0)' + specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231126.2 + version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231126.2(react-refresh@0.12.0)(webpack@5.86.0)' acorn: specifier: 8.5.0 version: 8.5.0 @@ -24649,9 +24649,9 @@ packages: /zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} - '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231124.2(react-refresh@0.12.0)(webpack@5.86.0)': - resolution: {registry: https://registry.npmjs.org/, tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231124.2} - id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231124.2' + '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231126.2(react-refresh@0.12.0)(webpack@5.86.0)': + resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231126.2} + id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231126.2' name: '@vercel/turbopack-ecmascript-runtime' version: 0.0.0 dependencies: From 7874ad265962dd1659497cbd8f5c71ddceee207b Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Sun, 26 Nov 2023 23:21:26 +0000 Subject: [PATCH 048/481] v14.0.4-canary.18 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 18 +++++++++--------- 18 files changed, 34 insertions(+), 34 deletions(-) diff --git a/lerna.json b/lerna.json index 1af4c8e867a7a..f4d4b84da3585 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.17" + "version": "14.0.4-canary.18" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 6d02148a1511b..b3706d547c451 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.17", + "version": "14.0.4-canary.18", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index db6a5d0a62cbd..6e5608b2ec000 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.17", + "version": "14.0.4-canary.18", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.17", + "@next/eslint-plugin-next": "14.0.4-canary.18", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 67502f34f5326..26cf52da66b7d 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.17", + "version": "14.0.4-canary.18", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index 36b2de01ca8d1..05f6b90b5adc2 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.17", + "version": "14.0.4-canary.18", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 4a101fbcb7983..325108c03e0bc 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.17", + "version": "14.0.4-canary.18", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index b50be48e9a2db..c3d0cb55edcf0 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.17", + "version": "14.0.4-canary.18", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index e924c354b455e..32c94ca88eac0 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.17", + "version": "14.0.4-canary.18", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 2dc40be47ba45..ac4190e01a399 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.17", + "version": "14.0.4-canary.18", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index b2651d7ae2564..0e33aee20b72e 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.17", + "version": "14.0.4-canary.18", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index 906b7476bfb59..29f3d6fb4a1c0 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.17", + "version": "14.0.4-canary.18", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index 124887993fbf1..87c87e80c1bed 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.17", + "version": "14.0.4-canary.18", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index e238998e00340..b04f24d7b1284 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.17", + "version": "14.0.4-canary.18", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index 9e2ffbe1a5011..aad9bd07330c6 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.17", + "version": "14.0.4-canary.18", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.17", + "@next/env": "14.0.4-canary.18", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -146,11 +146,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.17", - "@next/polyfill-nomodule": "14.0.4-canary.17", - "@next/react-dev-overlay": "14.0.4-canary.17", - "@next/react-refresh-utils": "14.0.4-canary.17", - "@next/swc": "14.0.4-canary.17", + "@next/polyfill-module": "14.0.4-canary.18", + "@next/polyfill-nomodule": "14.0.4-canary.18", + "@next/react-dev-overlay": "14.0.4-canary.18", + "@next/react-refresh-utils": "14.0.4-canary.18", + "@next/swc": "14.0.4-canary.18", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index 61a1da5c3e4ce..f10537ee23980 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.17", + "version": "14.0.4-canary.18", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index ff7dada5d8864..3cfbd74ea6192 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.17", + "version": "14.0.4-canary.18", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index f6fa0a79971c2..ba4cfa004fd3d 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.17", + "version": "14.0.4-canary.18", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -23,7 +23,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.17", + "next": "14.0.4-canary.18", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 521c25a4dcd65..98ef2ea66e30c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -738,7 +738,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.17 + specifier: 14.0.4-canary.18 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -803,7 +803,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.17 + specifier: 14.0.4-canary.18 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -927,19 +927,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.17 + specifier: 14.0.4-canary.18 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.17 + specifier: 14.0.4-canary.18 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.17 + specifier: 14.0.4-canary.18 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.17 + specifier: 14.0.4-canary.18 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.17 + specifier: 14.0.4-canary.18 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1590,7 +1590,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.17 + specifier: 14.0.4-canary.18 version: link:../next outdent: specifier: 0.8.0 @@ -24650,7 +24650,7 @@ packages: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231126.2(react-refresh@0.12.0)(webpack@5.86.0)': - resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231126.2} + resolution: {registry: https://registry.npmjs.org/, tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231126.2} id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231126.2' name: '@vercel/turbopack-ecmascript-runtime' version: 0.0.0 From 4d330a850062e844226c0c53cecf3fec410a8de1 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Mon, 27 Nov 2023 09:14:20 +0100 Subject: [PATCH 049/481] add `NEXT_TRIGGER_URL` env var to show request triggering a compilation (#58762) ### What? Shows the actual request url that triggered a compilation in the console message ### Why? makes it easier to find accidental compilation ### How? Closes PACK-2017 --- packages/next/src/build/output/index.ts | 11 ++++++-- packages/next/src/build/output/store.ts | 13 ++++++++- packages/next/src/server/base-server.ts | 13 +++++++-- .../next/src/server/dev/hot-reloader-types.ts | 2 ++ .../src/server/dev/hot-reloader-webpack.ts | 5 +++- .../next/src/server/dev/next-dev-server.ts | 20 ++++++++++--- .../src/server/dev/on-demand-entry-handler.ts | 7 ++++- .../dev-route-matcher-manager.ts | 4 +-- .../src/server/lib/dev-bundler-service.ts | 3 +- .../server/lib/router-utils/resolve-routes.ts | 4 +-- .../lib/router-utils/setup-dev-bundler.ts | 28 +++++++++++++------ packages/next/src/server/next-server.ts | 24 ++++++++++++---- packages/next/src/server/web-server.ts | 6 +++- 13 files changed, 110 insertions(+), 30 deletions(-) diff --git a/packages/next/src/build/output/index.ts b/packages/next/src/build/output/index.ts index ef773a18a1964..a304daa454b46 100644 --- a/packages/next/src/build/output/index.ts +++ b/packages/next/src/build/output/index.ts @@ -40,6 +40,7 @@ type BuildStatusStore = { server: WebpackStatus edgeServer: WebpackStatus trigger: string | undefined + url: string | undefined amp: AmpPageStatus } @@ -111,7 +112,7 @@ let serverWasLoading = true let edgeServerWasLoading = false buildStore.subscribe((state) => { - const { amp, client, server, edgeServer, trigger } = state + const { amp, client, server, edgeServer, trigger, url } = state const { appUrl } = consoleStore.getState() @@ -123,6 +124,7 @@ buildStore.subscribe((state) => { // If it takes more than 3 seconds to compile, mark it as loading status loading: true, trigger, + url, } as OutputState, true ) @@ -230,6 +232,7 @@ export function watchCompilers( server: { loading: true }, edgeServer: { loading: true }, trigger: 'initial', + url: undefined, }) function tapCompiler( @@ -273,6 +276,7 @@ export function watchCompilers( buildStore.setState({ client: status, trigger: undefined, + url: undefined, }) } else { buildStore.setState({ @@ -290,6 +294,7 @@ export function watchCompilers( buildStore.setState({ server: status, trigger: undefined, + url: undefined, }) } else { buildStore.setState({ @@ -307,6 +312,7 @@ export function watchCompilers( buildStore.setState({ edgeServer: status, trigger: undefined, + url: undefined, }) } else { buildStore.setState({ @@ -317,7 +323,7 @@ export function watchCompilers( } const internalSegments = ['[[...__metadata_id__]]', '[__metadata_id__]'] -export function reportTrigger(trigger: string) { +export function reportTrigger(trigger: string, url?: string) { for (const segment of internalSegments) { if (trigger.includes(segment)) { trigger = trigger.replace(segment, '') @@ -330,5 +336,6 @@ export function reportTrigger(trigger: string) { buildStore.setState({ trigger, + url, }) } diff --git a/packages/next/src/build/output/store.ts b/packages/next/src/build/output/store.ts index 0599ccf7157b1..e15d566c5e8de 100644 --- a/packages/next/src/build/output/store.ts +++ b/packages/next/src/build/output/store.ts @@ -16,6 +16,7 @@ export type OutputState = | { loading: true trigger: string | undefined + url: string | undefined } | { loading: false @@ -51,6 +52,7 @@ function hasStoreChanged(nextStore: OutputState) { let startTime = 0 let trigger = '' // default, use empty string for trigger +let triggerUrl: string | undefined = undefined let loadingLogTimer: NodeJS.Timeout | null = null let traceSpan: Span | null = null @@ -66,6 +68,7 @@ store.subscribe((state) => { if (state.loading) { if (state.trigger) { trigger = state.trigger + triggerUrl = state.url if (trigger !== 'initial') { traceSpan = trace('compile-path', undefined, { trigger: trigger, @@ -73,7 +76,15 @@ store.subscribe((state) => { if (!loadingLogTimer) { // Only log compiling if compiled is not finished in 3 seconds loadingLogTimer = setTimeout(() => { - Log.wait(`Compiling ${trigger} ...`) + if ( + triggerUrl && + triggerUrl !== trigger && + process.env.NEXT_TRIGGER_URL + ) { + Log.wait(`Compiling ${trigger} (${triggerUrl}) ...`) + } else { + Log.wait(`Compiling ${trigger} ...`) + } }, MAX_LOG_SKIP_DURATION) } } diff --git a/packages/next/src/server/base-server.ts b/packages/next/src/server/base-server.ts index 093fc3c8ef464..4bd8258598318 100644 --- a/packages/next/src/server/base-server.ts +++ b/packages/next/src/server/base-server.ts @@ -343,6 +343,7 @@ export default abstract class Server { sriEnabled?: boolean appPaths?: ReadonlyArray | null shouldEnsure?: boolean + url?: string }): Promise protected abstract getFontManifest(): FontManifest | undefined protected abstract getPrerenderManifest(): PrerenderManifest @@ -3006,7 +3007,9 @@ export default abstract class Server { } protected abstract getMiddleware(): MiddlewareRoutingItem | undefined - protected abstract getFallbackErrorComponents(): Promise + protected abstract getFallbackErrorComponents( + url?: string + ): Promise protected abstract getRoutesManifest(): NormalizedRouteManifest | undefined private async renderToResponseImpl( @@ -3249,6 +3252,7 @@ export default abstract class Server { params: {}, isAppPath: true, shouldEnsure: true, + url: ctx.req.url, }) using404Page = result !== null } @@ -3261,6 +3265,7 @@ export default abstract class Server { isAppPath: false, // Ensuring can't be done here because you never "match" a 404 route. shouldEnsure: true, + url: ctx.req.url, }) using404Page = result !== null } @@ -3283,6 +3288,7 @@ export default abstract class Server { // Ensuring can't be done here because you never "match" a 500 // route. shouldEnsure: true, + url: ctx.req.url, }) } } @@ -3296,6 +3302,7 @@ export default abstract class Server { // Ensuring can't be done here because you never "match" an error // route. shouldEnsure: true, + url: ctx.req.url, }) statusPage = '/_error' } @@ -3376,7 +3383,9 @@ export default abstract class Server { this.logError(renderToHtmlError) } res.statusCode = 500 - const fallbackComponents = await this.getFallbackErrorComponents() + const fallbackComponents = await this.getFallbackErrorComponents( + ctx.req.url + ) if (fallbackComponents) { // There was an error, so use it's definition from the route module diff --git a/packages/next/src/server/dev/hot-reloader-types.ts b/packages/next/src/server/dev/hot-reloader-types.ts index 44262520ee2e7..0e6a49c660e54 100644 --- a/packages/next/src/server/dev/hot-reloader-types.ts +++ b/packages/next/src/server/dev/hot-reloader-types.ts @@ -148,11 +148,13 @@ export interface NextJsHotReloaderInterface { appPaths, definition, isApp, + url, }: { page: string clientOnly: boolean appPaths?: ReadonlyArray | null isApp?: boolean definition: RouteDefinition | undefined + url?: string }): Promise } diff --git a/packages/next/src/server/dev/hot-reloader-webpack.ts b/packages/next/src/server/dev/hot-reloader-webpack.ts index e7348cbcf4bcb..63da5b34f75ce 100644 --- a/packages/next/src/server/dev/hot-reloader-webpack.ts +++ b/packages/next/src/server/dev/hot-reloader-webpack.ts @@ -313,7 +313,7 @@ export default class HotReloader implements NextJsHotReloaderInterface { if (page === '/_error' || BLOCKED_PAGES.indexOf(page) === -1) { try { - await this.ensurePage({ page, clientOnly: true }) + await this.ensurePage({ page, clientOnly: true, url: req.url }) } catch (error) { return await renderScriptError(pageBundleRes, getProperError(error)) } @@ -1471,12 +1471,14 @@ export default class HotReloader implements NextJsHotReloaderInterface { appPaths, definition, isApp, + url, }: { page: string clientOnly: boolean appPaths?: ReadonlyArray | null isApp?: boolean definition?: RouteDefinition + url?: string }): Promise { // Make sure we don't re-build or dispose prebuilt pages if (page !== '/_error' && BLOCKED_PAGES.indexOf(page) !== -1) { @@ -1494,6 +1496,7 @@ export default class HotReloader implements NextJsHotReloaderInterface { appPaths, definition, isApp, + url, }) } } diff --git a/packages/next/src/server/dev/next-dev-server.ts b/packages/next/src/server/dev/next-dev-server.ts index 05d428360212c..23aac6c89002c 100644 --- a/packages/next/src/server/dev/next-dev-server.ts +++ b/packages/next/src/server/dev/next-dev-server.ts @@ -198,11 +198,12 @@ export default class DevServer extends Server { const { pagesDir, appDir } = findPagesDir(this.dir) const ensurer: RouteEnsurer = { - ensure: async (match) => { + ensure: async (match, pathname) => { await this.ensurePage({ definition: match.definition, page: match.definition.page, clientOnly: false, + url: pathname, }) }, } @@ -559,11 +560,12 @@ export default class DevServer extends Server { return this.hasPage(this.actualMiddlewareFile!) } - protected async ensureMiddleware() { + protected async ensureMiddleware(url: string) { return this.ensurePage({ page: this.actualMiddlewareFile!, clientOnly: false, definition: undefined, + url, }) } @@ -597,15 +599,18 @@ export default class DevServer extends Server { protected async ensureEdgeFunction({ page, appPaths, + url, }: { page: string appPaths: string[] | null + url: string }) { return this.ensurePage({ page, appPaths, clientOnly: false, definition: undefined, + url, }) } @@ -762,6 +767,7 @@ export default class DevServer extends Server { clientOnly: boolean appPaths?: ReadonlyArray | null definition: RouteDefinition | undefined + url?: string }): Promise { await this.bundlerService.ensurePage(opts) } @@ -773,6 +779,7 @@ export default class DevServer extends Server { isAppPath, appPaths = null, shouldEnsure, + url, }: { page: string query: NextParsedUrlQuery @@ -781,6 +788,7 @@ export default class DevServer extends Server { sriEnabled?: boolean appPaths?: ReadonlyArray | null shouldEnsure: boolean + url?: string }): Promise { await this.ready?.promise @@ -796,6 +804,7 @@ export default class DevServer extends Server { appPaths, clientOnly: false, definition: undefined, + url, }) } @@ -812,6 +821,7 @@ export default class DevServer extends Server { params, isAppPath, shouldEnsure, + url, }) } catch (err) { if ((err as any).code !== 'ENOENT') { @@ -821,8 +831,10 @@ export default class DevServer extends Server { } } - protected async getFallbackErrorComponents(): Promise { - await this.bundlerService.getFallbackErrorComponents() + protected async getFallbackErrorComponents( + url?: string + ): Promise { + await this.bundlerService.getFallbackErrorComponents(url) return await loadDefaultErrorComponents(this.distDir) } diff --git a/packages/next/src/server/dev/on-demand-entry-handler.ts b/packages/next/src/server/dev/on-demand-entry-handler.ts index a7213abb2400f..4c3c6738ae6e5 100644 --- a/packages/next/src/server/dev/on-demand-entry-handler.ts +++ b/packages/next/src/server/dev/on-demand-entry-handler.ts @@ -678,11 +678,13 @@ export function onDemandEntryHandler({ appPaths, definition, isApp, + url, }: { page: string appPaths: ReadonlyArray | null definition: RouteDefinition | undefined isApp: boolean | undefined + url?: string }): Promise { const stalledTime = 60 const stalledEnsureTimeout = setTimeout(() => { @@ -834,7 +836,7 @@ export function onDemandEntryHandler({ if (hasNewEntry) { const routePage = isApp ? route.page : normalizeAppPath(route.page) - reportTrigger(routePage) + reportTrigger(routePage, url) } if (entriesThatShouldBeInvalidated.length > 0) { @@ -877,6 +879,7 @@ export function onDemandEntryHandler({ appPaths?: ReadonlyArray | null definition?: RouteDefinition isApp?: boolean + url?: string } // Make sure that we won't have multiple invalidations ongoing concurrently. @@ -900,6 +903,7 @@ export function onDemandEntryHandler({ appPaths = null, definition, isApp, + url, }: EnsurePageOptions) { // If the route is actually an app page route, then we should have access // to the app route definition, and therefore, the appPaths from it. @@ -916,6 +920,7 @@ export function onDemandEntryHandler({ appPaths, definition, isApp, + url, }) }) }, diff --git a/packages/next/src/server/future/route-matcher-managers/dev-route-matcher-manager.ts b/packages/next/src/server/future/route-matcher-managers/dev-route-matcher-manager.ts index 78d69b95a698a..6b73a5da189c4 100644 --- a/packages/next/src/server/future/route-matcher-managers/dev-route-matcher-manager.ts +++ b/packages/next/src/server/future/route-matcher-managers/dev-route-matcher-manager.ts @@ -9,7 +9,7 @@ import { cyan } from '../../../lib/picocolors' import type { RouteMatcher } from '../route-matchers/route-matcher' export interface RouteEnsurer { - ensure(match: RouteMatch): Promise + ensure(match: RouteMatch, pathname: string): Promise } export class DevRouteMatcherManager extends DefaultRouteMatcherManager { @@ -74,7 +74,7 @@ export class DevRouteMatcherManager extends DefaultRouteMatcherManager { for await (const development of super.matchAll(pathname, options)) { // We're here, which means that we haven't seen this match yet, so we // should try to ensure it and recompile the production matcher. - await this.ensurer.ensure(development) + await this.ensurer.ensure(development, pathname) await this.production.reload() // Iterate over the production matches again, this time we should be able diff --git a/packages/next/src/server/lib/dev-bundler-service.ts b/packages/next/src/server/lib/dev-bundler-service.ts index 99ca47415bcf6..f847b220e1d53 100644 --- a/packages/next/src/server/lib/dev-bundler-service.ts +++ b/packages/next/src/server/lib/dev-bundler-service.ts @@ -26,7 +26,7 @@ export class DevBundlerService { return await this.bundler.logErrorWithOriginalStack(...args) } - public async getFallbackErrorComponents() { + public async getFallbackErrorComponents(url?: string) { await this.bundler.hotReloader.buildFallbackError() // Build the error page to ensure the fallback is built too. // TODO: See if this can be moved into hotReloader or removed. @@ -34,6 +34,7 @@ export class DevBundlerService { page: '/_error', clientOnly: false, definition: undefined, + url, }) } diff --git a/packages/next/src/server/lib/router-utils/resolve-routes.ts b/packages/next/src/server/lib/router-utils/resolve-routes.ts index 3780c90321276..98276d71a6478 100644 --- a/packages/next/src/server/lib/router-utils/resolve-routes.ts +++ b/packages/next/src/server/lib/router-utils/resolve-routes.ts @@ -49,7 +49,7 @@ export function getResolveRoutes( opts: Parameters[0], renderServer: RenderServer, renderServerOpts: Parameters[0], - ensureMiddleware?: () => Promise + ensureMiddleware?: (url?: string) => Promise ) { type Route = { /** @@ -446,7 +446,7 @@ export function getResolveRoutes( // @ts-expect-error BaseNextRequest stuff match?.(parsedUrl.pathname, req, parsedUrl.query) && (!ensureMiddleware || - (await ensureMiddleware?.() + (await ensureMiddleware?.(req.url) .then(() => true) .catch(() => false))) ) { diff --git a/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts b/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts index 783632028b896..af3a417c2a462 100644 --- a/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts +++ b/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts @@ -452,7 +452,11 @@ async function startWatcher(opts: SetupOpts) { const buildingIds = new Set() const readyIds = new Set() - function startBuilding(id: string, forceRebuild: boolean = false) { + function startBuilding( + id: string, + requestUrl: string | undefined, + forceRebuild: boolean = false + ) { if (!forceRebuild && readyIds.has(id)) { return () => {} } @@ -461,6 +465,7 @@ async function startWatcher(opts: SetupOpts) { { loading: true, trigger: id, + url: requestUrl, } as OutputState, true ) @@ -1144,7 +1149,11 @@ async function startWatcher(opts: SetupOpts) { false, middleware.endpoint, async () => { - const finishBuilding = startBuilding('middleware', true) + const finishBuilding = startBuilding( + 'middleware', + undefined, + true + ) await processMiddleware() await propagateServerField( 'actualMiddlewareFile', @@ -1248,6 +1257,7 @@ async function startWatcher(opts: SetupOpts) { page: denormalizedPagePath, clientOnly: false, definition: undefined, + url: req.url, }) .catch(console.error) } @@ -1355,11 +1365,12 @@ async function startWatcher(opts: SetupOpts) { // appPaths, definition, isApp, + url: requestUrl, }) { let page = definition?.pathname ?? inputPage if (page === '/_error') { - let finishBuilding = startBuilding(page) + let finishBuilding = startBuilding(page, requestUrl) try { if (globalEntries.app) { const writtenEndpoint = await processResult( @@ -1458,7 +1469,7 @@ async function startWatcher(opts: SetupOpts) { ) } - finishBuilding = startBuilding(buildingKey) + finishBuilding = startBuilding(buildingKey, requestUrl) try { if (globalEntries.app) { const writtenEndpoint = await processResult( @@ -1546,7 +1557,7 @@ async function startWatcher(opts: SetupOpts) { // since this can happen when app pages make // api requests to page API routes. - finishBuilding = startBuilding(buildingKey) + finishBuilding = startBuilding(buildingKey, requestUrl) const writtenEndpoint = await processResult( page, await route.endpoint.writeToDisk() @@ -1571,7 +1582,7 @@ async function startWatcher(opts: SetupOpts) { break } case 'app-page': { - finishBuilding = startBuilding(buildingKey) + finishBuilding = startBuilding(buildingKey, requestUrl) const writtenEndpoint = await processResult( page, await route.htmlEndpoint.writeToDisk() @@ -1622,7 +1633,7 @@ async function startWatcher(opts: SetupOpts) { break } case 'app-route': { - finishBuilding = startBuilding(buildingKey) + finishBuilding = startBuilding(buildingKey, requestUrl) const writtenEndpoint = await processResult( page, await route.endpoint.writeToDisk() @@ -2479,12 +2490,13 @@ async function startWatcher(opts: SetupOpts) { requestHandler, logErrorWithOriginalStack, - async ensureMiddleware() { + async ensureMiddleware(requestUrl?: string) { if (!serverFields.actualMiddlewareFile) return return hotReloader.ensurePage({ page: serverFields.actualMiddlewareFile, clientOnly: false, definition: undefined, + url: requestUrl, }) }, } diff --git a/packages/next/src/server/next-server.ts b/packages/next/src/server/next-server.ts index 32e03d94369ed..7495f46aa0b9d 100644 --- a/packages/next/src/server/next-server.ts +++ b/packages/next/src/server/next-server.ts @@ -626,6 +626,7 @@ export default class NextNodeServer extends BaseServer { query, params, isAppPath, + url, }: { page: string query: NextParsedUrlQuery @@ -636,6 +637,7 @@ export default class NextNodeServer extends BaseServer { sriEnabled?: boolean appPaths?: ReadonlyArray | null shouldEnsure: boolean + url?: string }): Promise { return getTracer().trace( NextNodeServerSpan.findPageComponents, @@ -651,6 +653,7 @@ export default class NextNodeServer extends BaseServer { query, params, isAppPath, + url, }) ) } @@ -660,11 +663,13 @@ export default class NextNodeServer extends BaseServer { query, params, isAppPath, + url: _url, }: { page: string query: NextParsedUrlQuery params: Params isAppPath: boolean + url?: string }): Promise { const pagePaths: string[] = [page] if (query.amp) { @@ -977,6 +982,7 @@ export default class NextNodeServer extends BaseServer { clientOnly: boolean appPaths?: ReadonlyArray | null match?: RouteMatch + url?: string }): Promise { throw new Error( 'Invariant: ensurePage can only be called on the development server' @@ -1288,6 +1294,7 @@ export default class NextNodeServer extends BaseServer { await this.ensurePage({ page: notFoundPathname, clientOnly: false, + url: req.url, }).catch(() => {}) } @@ -1453,10 +1460,11 @@ export default class NextNodeServer extends BaseServer { * It will make sure that the root middleware or an edge function has been compiled * so that we can run it. */ - protected async ensureMiddleware() {} + protected async ensureMiddleware(_url?: string) {} protected async ensureEdgeFunction(_params: { page: string appPaths: string[] | null + url?: string }) {} /** @@ -1523,7 +1531,7 @@ export default class NextNodeServer extends BaseServer { return { finished: false } } - await this.ensureMiddleware() + await this.ensureMiddleware(params.request.url) const middlewareInfo = this.getEdgeFunctionInfo({ page: middleware.page, middleware: true, @@ -1634,7 +1642,7 @@ export default class NextNodeServer extends BaseServer { this.stripInternalHeaders(req) try { - await this.ensureMiddleware() + await this.ensureMiddleware(req.url) result = await this.runMiddleware({ request: req, @@ -1796,7 +1804,11 @@ export default class NextNodeServer extends BaseServer { const { query, page, match } = params if (!match) - await this.ensureEdgeFunction({ page, appPaths: params.appPaths }) + await this.ensureEdgeFunction({ + page, + appPaths: params.appPaths, + url: params.req.url, + }) edgeInfo = this.getEdgeFunctionInfo({ page, middleware: false, @@ -1903,7 +1915,9 @@ export default class NextNodeServer extends BaseServer { return serverDistDir } - protected async getFallbackErrorComponents(): Promise { + protected async getFallbackErrorComponents( + _url?: string + ): Promise { // Not implemented for production use cases, this is implemented on the // development server. return null diff --git a/packages/next/src/server/web-server.ts b/packages/next/src/server/web-server.ts index 463599a3065b7..52a3edfc1ea04 100644 --- a/packages/next/src/server/web-server.ts +++ b/packages/next/src/server/web-server.ts @@ -280,11 +280,13 @@ export default class NextWebServer extends BaseServer { page, query, params, + url: _url, }: { page: string query: NextParsedUrlQuery params: Params | null isAppPath: boolean + url?: string }) { const result = await this.serverOptions.webServerConfig.loadComponent(page) if (!result) return null @@ -342,7 +344,9 @@ export default class NextWebServer extends BaseServer { // The web server does not support web sockets. } - protected async getFallbackErrorComponents(): Promise { + protected async getFallbackErrorComponents( + _url?: string + ): Promise { // The web server does not need to handle fallback errors in production. return null } From 8e6d51f4fa9aa015552f1dc1722540c986a71c06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Donny/=EA=B0=95=EB=8F=99=EC=9C=A4?= Date: Mon, 27 Nov 2023 19:02:25 +0900 Subject: [PATCH 050/481] Update `swc_core` to `v0.86.81` (#58517) ### What? Update swc crates. Diff: https://github.com/swc-project/swc/compare/09b3003e589409e1fffe32cf5e3328d946bd270e...c566b73bfbcd24fc34eedc2baf62d0afb8609636 ### Why? To fix bugs, and improve minification. ### How? turbopack counterpart: https://github.com/vercel/turbo/pull/6472 - Closes PACK-1972 - Closes #30802 --------- Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- Cargo.lock | 371 +++++++++++------------ Cargo.toml | 10 +- packages/next-swc/crates/core/Cargo.toml | 4 +- packages/next-swc/crates/core/src/lib.rs | 7 +- packages/next/package.json | 2 +- pnpm-lock.yaml | 10 +- 6 files changed, 200 insertions(+), 204 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0a0f1f010f4e6..67ab55f16dc71 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -322,7 +322,7 @@ dependencies = [ [[package]] name = "auto-hash-map" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" dependencies = [ "serde", "smallvec", @@ -522,9 +522,9 @@ dependencies = [ [[package]] name = "binding_macros" -version = "0.60.59" +version = "0.60.80" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fdde7535e3cb901527bb60f69b10958215f8dafde044f2c57fd9fd7cb02e49b" +checksum = "fad347930aa10cdc234781028009ccb8ebf4ee5055463fe473c055fc6e92ca90" dependencies = [ "anyhow", "console_error_panic_hook", @@ -2874,9 +2874,9 @@ dependencies = [ [[package]] name = "lightningcss" -version = "1.0.0-alpha.50" +version = "1.0.0-alpha.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2999490cc10a59ad8a87d731791a5d438d2d025e3f137aa7d4c23e1827985b0" +checksum = "99d6ad516c08b24c246b339159dc2ee2144c012e8ebdf4db4bddefb8734b2b69" dependencies = [ "ahash 0.7.6", "bitflags 2.4.0", @@ -2981,9 +2981,9 @@ dependencies = [ [[package]] name = "markdown" -version = "1.0.0-alpha.14" +version = "1.0.0-alpha.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d2a51befc5a2b4a052c473ffbc9ad462e358de59dcc2fde4997fd2a16403dcbd" +checksum = "ff9c0d28952698a9accc957767f2bcad203ec10251601f89b9ddc82661c3a15a" dependencies = [ "unicode-id", ] @@ -3036,9 +3036,9 @@ dependencies = [ [[package]] name = "mdxjs" -version = "0.1.19" +version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7572e57307a72a93fed80bf5aaa0a81cca3a47d7faaf65af4f0d3ac4d84a1715" +checksum = "76dd8c39a187154daf394ac55f155f6c411ac0c9f8c0dda7a00e80879610d994" dependencies = [ "markdown", "serde", @@ -3235,9 +3235,9 @@ dependencies = [ [[package]] name = "modularize_imports" -version = "0.56.0" +version = "0.61.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b938c4ffaa1180f64186fd52f51dac5998e68c8c29f3ce4a0da952b873ebe021" +checksum = "75b4169048f6d77763229901de98307369bd96e901ec496eb095bf9c82943608" dependencies = [ "convert_case 0.5.0", "handlebars", @@ -3423,7 +3423,7 @@ dependencies = [ "tracing-subscriber", "turbo-tasks", "turbopack-binding", - "vergen", + "vergen 7.5.1", ] [[package]] @@ -3549,7 +3549,7 @@ dependencies = [ [[package]] name = "node-file-trace" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" dependencies = [ "anyhow", "serde", @@ -4019,9 +4019,7 @@ version = "0.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fabbf1ead8a5bcbc20f5f8b939ee3f5b0f6f281b6ad3468b84656b658b455259" dependencies = [ - "phf_macros 0.10.0", "phf_shared 0.10.0", - "proc-macro-hack", ] [[package]] @@ -4030,7 +4028,7 @@ version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" dependencies = [ - "phf_macros 0.11.2", + "phf_macros", "phf_shared 0.11.2", ] @@ -4064,20 +4062,6 @@ dependencies = [ "rand", ] -[[package]] -name = "phf_macros" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58fdf3184dd560f160dd73922bea2d5cd6e8f064bf4b13110abd81b03697b4e0" -dependencies = [ - "phf_generator 0.10.0", - "phf_shared 0.10.0", - "proc-macro-hack", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "phf_macros" version = "0.11.2" @@ -4513,9 +4497,9 @@ dependencies = [ [[package]] name = "react_remove_properties" -version = "0.11.0" +version = "0.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c179dadcf9e31539e9af8a709153adafa4cf9f907c4df20a4b52a80718bd884d" +checksum = "cca2278d333c3a8172c77876b33c5f48115a9e36f59204b922b0b60d6d92281c" dependencies = [ "serde", "swc_atoms", @@ -4656,9 +4640,9 @@ checksum = "c707298afce11da2efef2f600116fa93ffa7a032b5d7b628aa17711ec81383ca" [[package]] name = "remove_console" -version = "0.12.0" +version = "0.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bb68d00d948a7ffa1dc16aee64cc45640ca8ed9afe14e109d5a1f1d8e4db65e" +checksum = "90a94a77158b6033a4cb7491e701477e6636ad3e764885dacd9088a6c887ab67" dependencies = [ "serde", "swc_atoms", @@ -5667,9 +5651,9 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "styled_components" -version = "0.83.0" +version = "0.89.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97aa75a37e4afde897446c920d4569ff18fbf32d2f8f3d9d0f109da674a9cb15" +checksum = "98db15f396dabd0f53988952ad682b957b5d310ebb0a0106f8d93f20303c378d" dependencies = [ "Inflector", "once_cell", @@ -5685,9 +5669,9 @@ dependencies = [ [[package]] name = "styled_jsx" -version = "0.60.0" +version = "0.66.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d5d705b3f746558b25d9badb4e2af0d106688880a7a7efd7cc41b4af7d42fd4" +checksum = "b8d4222bde4e3ee9d454b8e8e7585ddd9ff8f5a7c98e960b434b9c9822e625e2" dependencies = [ "easy-error", "lightningcss", @@ -5746,9 +5730,9 @@ dependencies = [ [[package]] name = "swc" -version = "0.269.54" +version = "0.269.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05849a2ce200bb82aec323cb672d9ecb9e9029316e3d44a0a7d510572d5e5501" +checksum = "a08210450ab29ec98733f71ac457d45d4355ef166a4a21d669bf79f7d1cfe5ab" dependencies = [ "anyhow", "base64 0.13.1", @@ -5812,9 +5796,9 @@ dependencies = [ [[package]] name = "swc_bundler" -version = "0.222.48" +version = "0.222.68" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdab096f62e461d4524ddf65978e69393db703356a97f4b558f2a4f212a1b7dd" +checksum = "a26ee0a3735b686dbf5819f739d969fc51932db5dbf766dd845b114d0da0aaa6" dependencies = [ "anyhow", "crc", @@ -5858,9 +5842,9 @@ dependencies = [ [[package]] name = "swc_common" -version = "0.33.8" +version = "0.33.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49fba1ce1d44f142b9e8212a6360fc7818e2c99c7f5ebe8b4fa4061c5764e48e" +checksum = "5ccb656cd57c93614e4e8b33a60e75ca095383565c1a8d2bbe6a1103942831e0" dependencies = [ "ahash 0.8.6", "anyhow", @@ -5880,7 +5864,6 @@ dependencies = [ "serde", "siphasher", "sourcemap", - "string_cache", "swc_atoms", "swc_eq_ignore_macros", "swc_visit", @@ -5892,9 +5875,9 @@ dependencies = [ [[package]] name = "swc_compiler_base" -version = "0.3.54" +version = "0.3.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ccb251385a0ab21b4470b2e9088c3d992f4cb3c9a3a80a46ee802e4f6b22dbb" +checksum = "febebd8b41806960c8ac3e00f6702eb4cecfa4c60e8cc38ce94fa1e5d8b87269" dependencies = [ "anyhow", "base64 0.13.1", @@ -5941,9 +5924,9 @@ dependencies = [ [[package]] name = "swc_core" -version = "0.86.60" +version = "0.86.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f718c699aac95c69bad3ba5e81e554407c4195ff339e61b96686abab4bfed40c" +checksum = "862dfc1749e2b0ddfba5431a9001c9727c7349606b4aaa571f784232b122ff0d" dependencies = [ "binding_macros", "swc", @@ -5977,14 +5960,14 @@ dependencies = [ "swc_plugin_proxy", "swc_plugin_runner", "testing", - "vergen", + "vergen 8.2.6", ] [[package]] name = "swc_css_ast" -version = "0.140.9" +version = "0.140.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24e33aed6900a6478ec9bffa7cdf5249ea79b55fcc86b34872212800086504fa" +checksum = "8f17c30ef639db1d8ad3df3a23391f0ede477cd7f51cfa7bc9d4e6d8e0429849" dependencies = [ "is-macro", "string_enum", @@ -5994,9 +5977,9 @@ dependencies = [ [[package]] name = "swc_css_codegen" -version = "0.151.15" +version = "0.151.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71a04ac7b5672d740340ae09a6bcedad753d45ae9d4ec3b935617c20dce90094" +checksum = "268ca93260524544652a53c61120c2d08bfd8e61868219cc7a2d4a16e2ad96de" dependencies = [ "auto_impl", "bitflags 2.4.0", @@ -6024,9 +6007,9 @@ dependencies = [ [[package]] name = "swc_css_compat" -version = "0.27.15" +version = "0.27.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f82fd2fc69fb5898111ef25a2dd74f68dc4f043a25b4a4ceca7db67322e4a83" +checksum = "7c7f172cd29cffebad877373d6d8e0978a195371940e84afb1e95d70dc3780d3" dependencies = [ "bitflags 2.4.0", "once_cell", @@ -6041,9 +6024,9 @@ dependencies = [ [[package]] name = "swc_css_minifier" -version = "0.116.15" +version = "0.116.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f758a030c634a2dfd78c44ebefbb64c9155e086a72d15784ad3ee91c1fa66485" +checksum = "efcc0624eeb73b6312d0646d608a089ce3370d61f7eef030372d7dd0a65a49bf" dependencies = [ "serde", "swc_atoms", @@ -6055,9 +6038,9 @@ dependencies = [ [[package]] name = "swc_css_modules" -version = "0.29.16" +version = "0.29.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fcf9dc1c339724167d9bbeec6176e4785d0996babc9def04786c724626dee69" +checksum = "0cb16b1bf99683064b366434bd1ece6880829b01af8c77b38f2f0f06e21805b2" dependencies = [ "rustc-hash", "serde", @@ -6071,9 +6054,9 @@ dependencies = [ [[package]] name = "swc_css_parser" -version = "0.150.15" +version = "0.150.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a3a21dc7405cbb2f7c923e0759bc3ab4a561780b638e9e79c96675341fd89d0" +checksum = "258304ed3eab3fc7bae96158eb51cd32900bac706413604de13cb9483b9e259a" dependencies = [ "lexical", "serde", @@ -6084,9 +6067,9 @@ dependencies = [ [[package]] name = "swc_css_prefixer" -version = "0.153.17" +version = "0.153.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18ee513d43dca0debd04de9f2df55292778f982ec27d02bc503203bb644e409d" +checksum = "270792f8684826e41221b1b12d1f73afb5ba631d7389b839e36f3b1a3a860b29" dependencies = [ "once_cell", "preset_env_base", @@ -6101,9 +6084,9 @@ dependencies = [ [[package]] name = "swc_css_utils" -version = "0.137.9" +version = "0.137.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24fec9a00252d393ca43383109f38a68d64c326ca967b40ec35499ef0c57a7dc" +checksum = "577c187c251c81f8b9f45b4b58d5eaec24a31dfac66c4cd196e4dd7330a71b44" dependencies = [ "once_cell", "serde", @@ -6116,9 +6099,9 @@ dependencies = [ [[package]] name = "swc_css_visit" -version = "0.139.9" +version = "0.139.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f4827e116e4e417a5f7f995ef3e2ef83ddef034418667c5e1ed169f072053c2" +checksum = "f6a65238a42e8cb07dbfff82211867dd868b1ff4ce310209eb9d4b8c63807944" dependencies = [ "serde", "swc_atoms", @@ -6129,9 +6112,9 @@ dependencies = [ [[package]] name = "swc_ecma_ast" -version = "0.110.9" +version = "0.110.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cefcc1c71bf00e48da7b65801d1fccf7eed2b7fa1fc5c4848ed09801bfe2403" +checksum = "2c3d416121da2d56bcbd1b1623725a68890af4552fef0c6d1e4bfa92776ccd6a" dependencies = [ "bitflags 2.4.0", "bytecheck", @@ -6149,9 +6132,9 @@ dependencies = [ [[package]] name = "swc_ecma_codegen" -version = "0.146.26" +version = "0.146.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c45a0beb1293372354b57bbafa06bf5ca6c3fab4bfd157b54d65db96612232eb" +checksum = "4f6b9e2e703bab3cc0f484eaf32c8081792460beb64860c2950fb7e56ff67ed8" dependencies = [ "memchr", "num-bigint", @@ -6181,9 +6164,9 @@ dependencies = [ [[package]] name = "swc_ecma_compat_bugfixes" -version = "0.1.35" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5521b96f87e13fd10f2a7c3bf4f8f80ed2cc3a532a4c9b6625a724d8e3083e85" +checksum = "b23c256c5729096df0635bd1fc727e6e34c804882478805ab3820c824060017c" dependencies = [ "swc_atoms", "swc_common", @@ -6198,9 +6181,9 @@ dependencies = [ [[package]] name = "swc_ecma_compat_common" -version = "0.1.25" +version = "0.1.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1889c73fde0612659b59359a0f4e42be73b623cba895fd88957b60471559d04" +checksum = "5abed404c9425bf0d1f44da426f9fec6fe1833b696275ed4dff85550376a32d4" dependencies = [ "swc_common", "swc_ecma_ast", @@ -6211,9 +6194,9 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es2015" -version = "0.1.35" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea1c8835b35efa6b3264cf3330e5ecd3abde691e3037fac724fe73cf26fb4a9f" +checksum = "139b44e5de713a690003040c1068d52f4cc400fa623887d84e29fc7a5cf01b23" dependencies = [ "arrayvec", "indexmap 1.9.3", @@ -6237,9 +6220,9 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es2016" -version = "0.1.33" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58265ca3e2bbeefe595c3a77cbca10d44d877cf006429529ee6a7245122a7f84" +checksum = "4130f981d7f216116feb9b01a878fea161b19494834e7fc9ddf4ab550839ec97" dependencies = [ "swc_atoms", "swc_common", @@ -6254,9 +6237,9 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es2017" -version = "0.1.33" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "590e3ea46d074bd8ebd57d0f45d3c8dcbafacf18e58704abd034ebcf73f120ad" +checksum = "27b25eb792480f28c5ef7d37cf3db3a4d6241a7b64e068435586d806922eac84" dependencies = [ "serde", "swc_atoms", @@ -6272,9 +6255,9 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es2018" -version = "0.1.33" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8ba03ae7d980a7a09c425b8be7ef56775f7ee703cceee82cf6f6712899cfe6" +checksum = "24abad70f29e945544994e4977cd986f5fc6579cd8b0dc16230faff2c7b14f0e" dependencies = [ "serde", "swc_atoms", @@ -6291,9 +6274,9 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es2019" -version = "0.1.33" +version = "0.1.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c034b8ea66e47552fafdef3d904c53597761c91ca51174c2576c04706e38687" +checksum = "27d7d78648bc37adc80f24941a6b84027d78aa6916638633e2f271a611d6bf0f" dependencies = [ "swc_atoms", "swc_common", @@ -6307,9 +6290,9 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es2020" -version = "0.1.32" +version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d43af0631e13dbfccf67c42105b3e07dfc620d43226128c3a0cd478b57e87de" +checksum = "10e70a88c91a60cae3ccc9513db46e83ee05dcadbe06e41fbddf72f66537e7d0" dependencies = [ "serde", "swc_atoms", @@ -6325,9 +6308,9 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es2021" -version = "0.1.31" +version = "0.1.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4623f933fea8df5e8d8be0d511b9c441c30f0601f9161b6a6660fc0f6a54aea9" +checksum = "6c7e5dbd76ce0ef560086aa5a34a8c2901095724c6d3cf4e1bc193c91d40ed25" dependencies = [ "swc_atoms", "swc_common", @@ -6341,9 +6324,9 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es2022" -version = "0.1.33" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e041d062041ca30fea5cb0f9c590edff6e99f3fc117c0470f12dbe5abe5412d" +checksum = "b2bc635b5029c48b92723e10af44e4710e5c42963bfd52b1d1fd8e78835b4601" dependencies = [ "swc_atoms", "swc_common", @@ -6360,9 +6343,9 @@ dependencies = [ [[package]] name = "swc_ecma_compat_es3" -version = "0.1.32" +version = "0.1.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6102f7c0c339ed21d5be4a197332ec9b4886d0b28fd4ca15905a9ce6eec4ea83" +checksum = "a5e9dcb092ae019ee6cb54abcab7659ea8469e3f0808916895cebc465c79adb1" dependencies = [ "swc_common", "swc_ecma_ast", @@ -6375,11 +6358,11 @@ dependencies = [ [[package]] name = "swc_ecma_ext_transforms" -version = "0.110.28" +version = "0.110.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04c4614dca2e8561024be8906f9a095777ad1f39a3b2b426111b96c03465af8d" +checksum = "3cc0000e38d2c67772c632f3e0fe1d8c2a63479bcb9d2746b8042af6f65f42c7" dependencies = [ - "phf 0.10.1", + "phf 0.11.2", "swc_atoms", "swc_common", "swc_ecma_ast", @@ -6389,9 +6372,9 @@ dependencies = [ [[package]] name = "swc_ecma_lints" -version = "0.89.33" +version = "0.89.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c783cf4cf1a5887de0e7b5fc25fab6f7bdcf7268eca671fe2fb4ff654e6b1006" +checksum = "ac15ed364f2a72ba02f7ecd5add9745c7713b919c8826d147b549ffea1554196" dependencies = [ "auto_impl", "dashmap", @@ -6409,9 +6392,9 @@ dependencies = [ [[package]] name = "swc_ecma_loader" -version = "0.45.9" +version = "0.45.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc83806e30310943718eef1209c388f375417bcc3e499df8820c189d92ecf05f" +checksum = "31cf7549feec3698d0110a0a71ae547f31ae272dc92db3285ce126d6dcbdadf3" dependencies = [ "anyhow", "dashmap", @@ -6430,9 +6413,9 @@ dependencies = [ [[package]] name = "swc_ecma_minifier" -version = "0.189.49" +version = "0.189.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d50fedc759df341016d49a100b389cb6c1b7574e4cc65367487d5d3afc22e9e" +checksum = "5adc7f226679e7371d794b54155bf0b4afe095486c5316ed3760897e1e56045c" dependencies = [ "arrayvec", "indexmap 1.9.3", @@ -6465,9 +6448,9 @@ dependencies = [ [[package]] name = "swc_ecma_parser" -version = "0.141.22" +version = "0.141.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acfad502c2e0579e09e216da1c627d583fdbc6c8a08f2c8bd0160f9119d4246d" +checksum = "0b8436a58ac9f31068e9bf871e2ce7f3a18fe1d7e3fe8d54abe4896673eae20c" dependencies = [ "either", "new_debug_unreachable", @@ -6487,9 +6470,9 @@ dependencies = [ [[package]] name = "swc_ecma_preset_env" -version = "0.203.42" +version = "0.203.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "652c066e316cd2acf9bc39a151456188925a5f01e5bb00018b9bf468ee0fd734" +checksum = "fdd1f8c17f6231387150aa69d62c1ebba3e1d55dc2a858e9bdf40f9f6e2adef8" dependencies = [ "anyhow", "dashmap", @@ -6512,9 +6495,9 @@ dependencies = [ [[package]] name = "swc_ecma_quote_macros" -version = "0.52.22" +version = "0.52.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51c6de18105523ee7c930178406cd324c272ae21bc549e53593105b345969e18" +checksum = "28b017bb7d94219d36c2647f927a3937c5d578ee90630aff74f4fbc0e345341e" dependencies = [ "anyhow", "pmutil", @@ -6530,9 +6513,9 @@ dependencies = [ [[package]] name = "swc_ecma_testing" -version = "0.22.10" +version = "0.22.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62dc3d273ef4f7fe39b670b7f1fdd2dd33518f5de987e7f7fe9d1b44e650e891" +checksum = "40ae9e4a7deca72765c1d63fa6b0b3b41919187e4dd4ce99d57e348a2411b57f" dependencies = [ "anyhow", "hex", @@ -6543,9 +6526,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms" -version = "0.226.41" +version = "0.226.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b020aef371703583047e8e41468c17790e5f3caf9cf1cb53b7fb91d7a8d8a70" +checksum = "c5bfa68b9931abbf582fa08aa427e74089036ffdfb1efa5624059fb3caecd9b3" dependencies = [ "swc_atoms", "swc_common", @@ -6563,15 +6546,15 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_base" -version = "0.134.33" +version = "0.134.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cea2778aaa7152bacc2877ce900a78f815c64630102ec8d824a8ec543ac5ef5" +checksum = "3e3b8393c86d0ea8ccc7aab30696fae48b8ec7edd69b450318bb7930ca448817" dependencies = [ "better_scoped_tls", "bitflags 2.4.0", "indexmap 1.9.3", "once_cell", - "phf 0.10.1", + "phf 0.11.2", "rayon", "rustc-hash", "serde", @@ -6587,9 +6570,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_classes" -version = "0.123.34" +version = "0.123.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75a2a98541dffaffbfecb6aaccf8d910c8e9e54576a785e431d8eb2d2c56b80a" +checksum = "0b718100ae10d0790bb867197e648d505a1f849f830edf25e0f0f30cdbafae0d" dependencies = [ "swc_atoms", "swc_common", @@ -6601,9 +6584,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_compat" -version = "0.160.39" +version = "0.160.51" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2be5f5f7b7e62cd94ae24f51bf42fc33a25a3ea5a401e3da313538bfa682bdf7" +checksum = "b1e9596160b85bd29a0ad12294add8436555b35a1624fb294931e61378c4059b" dependencies = [ "arrayvec", "indexmap 1.9.3", @@ -6651,9 +6634,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_module" -version = "0.177.41" +version = "0.177.54" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee2323576600e67365ba75f6db9fa38d18d2227921cd5cec907a2bc5f3e8a51b" +checksum = "d2326820487674180acee95ed55f3386e6555fe39b0ac25df13097f57c4a6bb2" dependencies = [ "Inflector", "anyhow", @@ -6678,9 +6661,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_optimization" -version = "0.195.41" +version = "0.195.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb488266e2ed474b1315fee62396217fc62a505adfe4a29a65aa9985026e9d24" +checksum = "baaf94134146830012488f6bee2b89f0675fd742611c326c2b2c1bb49f59714e" dependencies = [ "dashmap", "indexmap 1.9.3", @@ -6703,9 +6686,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_proposal" -version = "0.168.42" +version = "0.168.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa5d747160aca89b0496d0f3e5a3c7961e6f31d3b4f75a1ab52e050d894d0e12" +checksum = "6abb14f7198481c85bd1cf69ece8ed9a72c49d77260b107d0fcfdf0a12717885" dependencies = [ "either", "rustc-hash", @@ -6723,9 +6706,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_react" -version = "0.180.42" +version = "0.180.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21876e623cb894ca2d020c29003c8e5f619e7d345f6188eb53e39c2ce6dea783" +checksum = "02424cc787df6f5a37cc0c45fc159141a78f4a713dd1f394ef787f3147c4edbf" dependencies = [ "base64 0.13.1", "dashmap", @@ -6748,9 +6731,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_testing" -version = "0.137.35" +version = "0.137.47" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1633020e7f46dd994e1f39c9365b852f25384cab56e527cbde645ba6742dba65" +checksum = "a7b282c0fe89bc6bc2ce0c76211fcaf89e2472edc2b87e8f8353278be625bec7" dependencies = [ "ansi_term", "anyhow", @@ -6774,9 +6757,9 @@ dependencies = [ [[package]] name = "swc_ecma_transforms_typescript" -version = "0.185.40" +version = "0.185.56" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e64b6cf5505e05f4a3a9ef2fcb13bcd5147e16ce642a8a06f76270eb5a240434" +checksum = "401d899c11ca688f62a0b28bfd5c129d58d7cb838e22072aa86a54f03d8cac73" dependencies = [ "ryu-js", "serde", @@ -6791,9 +6774,9 @@ dependencies = [ [[package]] name = "swc_ecma_usage_analyzer" -version = "0.20.29" +version = "0.20.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5fd3bb4cdb8813a7045eb569388386ab9a13317f5bef4a334cfe2e7018bbc29" +checksum = "dfa8d5dc775d4bf35967a0216783058b13ffe5423b807927aa5dbc92251f6839" dependencies = [ "indexmap 1.9.3", "rustc-hash", @@ -6808,9 +6791,9 @@ dependencies = [ [[package]] name = "swc_ecma_utils" -version = "0.124.28" +version = "0.124.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10584648054df1b174b0ce48070f1567996141c2549906eebd12467019752c00" +checksum = "ad013c92a6e05a850db088ae7a17dc667209780b2a1a313544540111f33b5233" dependencies = [ "indexmap 1.9.3", "num_cpus", @@ -6827,9 +6810,9 @@ dependencies = [ [[package]] name = "swc_ecma_visit" -version = "0.96.9" +version = "0.96.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21305b130986e771206c9f447c8040f9b3be47c9fbbb1f659904e223b8e1c007" +checksum = "ba962f0becf83bab12a17365dface5a4f636c9e1743d479e292b96910a753743" dependencies = [ "num-bigint", "serde", @@ -6842,9 +6825,9 @@ dependencies = [ [[package]] name = "swc_emotion" -version = "0.59.0" +version = "0.65.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "708a605ff7a722d169e800dbbb0328a82db38811d3b07cbb8ca87db27d7b3e9c" +checksum = "e658f35b695f0dc8152088a03c7678dcf6702bf7a0bacc4b7727499f7d5db454" dependencies = [ "base64 0.13.1", "byteorder", @@ -6878,9 +6861,9 @@ dependencies = [ [[package]] name = "swc_error_reporters" -version = "0.17.8" +version = "0.17.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a80f674bef7baf65c979f684bbe9fa8f4e275e3b61589b62d6dc260331a102b" +checksum = "d29add35412af288be50e1012bbb825a66871bb2b4d960d1c456917ec3ccea32" dependencies = [ "anyhow", "miette", @@ -6891,9 +6874,9 @@ dependencies = [ [[package]] name = "swc_fast_graph" -version = "0.21.8" +version = "0.21.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "392047ce047ab6f9c02ef17e7e19627c0050fe6dbb0bccd2350a92664a859c62" +checksum = "8117f6d10bbcb30cb3e549d6fa7637cb6d7c713cb71b2ce1808105a6825c788d" dependencies = [ "indexmap 1.9.3", "petgraph", @@ -6903,9 +6886,9 @@ dependencies = [ [[package]] name = "swc_graph_analyzer" -version = "0.22.10" +version = "0.22.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebb1843242b0ee38517116da75576e13bcdcc8e08af288537e8745d480c31cfc" +checksum = "de8f0ac33ef7486723a3acdd9c4541dac79f0433bf878b9075826bca1163d83e" dependencies = [ "auto_impl", "petgraph", @@ -6928,9 +6911,9 @@ dependencies = [ [[package]] name = "swc_node_comments" -version = "0.20.8" +version = "0.20.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "249c6c5935bcea54025c5c767f33d89d650293288837b50113ac9c437e546450" +checksum = "282ef548f602694c4eaa36a1d704282fd9713b9725b58bce7fb41630feefc4f7" dependencies = [ "dashmap", "swc_atoms", @@ -6964,9 +6947,9 @@ dependencies = [ [[package]] name = "swc_plugin_proxy" -version = "0.39.9" +version = "0.39.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e73aa3453e0026b009f35462b77f7dbc2e1b9a91cd92fae6f517802f3b6f4561" +checksum = "f10904ed792a38bae2810ed9ca781a2e5d62c369b2f83843255bde1141a32502" dependencies = [ "better_scoped_tls", "rkyv", @@ -6978,9 +6961,9 @@ dependencies = [ [[package]] name = "swc_plugin_runner" -version = "0.104.24" +version = "0.104.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1ef2eb955ba87377bda7b17b7bb511b62d3c8e7b56c9481598f7821438df5e0" +checksum = "650a138a519e67dd9b85c37bf807c311be009f68267d767da6989f428d715037" dependencies = [ "anyhow", "enumset", @@ -7002,9 +6985,9 @@ dependencies = [ [[package]] name = "swc_relay" -version = "0.31.0" +version = "0.37.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a144781f2f2de3e7ccc22f7381a7f24383ac36168a4afefdbb029f78c1aa973" +checksum = "faede0a001c4f29cd912954334b9940b57f89bc844f46aafb8d6c304f6acc211" dependencies = [ "once_cell", "regex", @@ -7020,9 +7003,9 @@ dependencies = [ [[package]] name = "swc_timer" -version = "0.21.10" +version = "0.21.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "388d9d8a67d907c9a5f69250a32134b80fa01c2c03b7fbfcdbb9e8d4ed18b3ed" +checksum = "5a200243f3c296f74f52a562342ec0e972376377f4c202b0fa84a0e860a3bff7" dependencies = [ "tracing", ] @@ -7188,9 +7171,9 @@ dependencies = [ [[package]] name = "testing" -version = "0.35.10" +version = "0.35.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fa85c2c4605cd16c3b358b125a23b36e01fe04a0ef687d22df97baa4b25fa8" +checksum = "528fe2b00056f8a214476c599708f70a09c8b6634d4f6e2f9d78e0d1d37f4057" dependencies = [ "ansi_term", "cargo_metadata", @@ -7695,7 +7678,7 @@ dependencies = [ [[package]] name = "turbo-tasks" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" dependencies = [ "anyhow", "async-trait", @@ -7727,7 +7710,7 @@ dependencies = [ [[package]] name = "turbo-tasks-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" dependencies = [ "anyhow", "cargo-lock", @@ -7739,7 +7722,7 @@ dependencies = [ [[package]] name = "turbo-tasks-bytes" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" dependencies = [ "anyhow", "bytes", @@ -7754,7 +7737,7 @@ dependencies = [ [[package]] name = "turbo-tasks-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" dependencies = [ "anyhow", "dotenvs", @@ -7768,7 +7751,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fetch" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7785,7 +7768,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fs" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" dependencies = [ "anyhow", "auto-hash-map", @@ -7815,7 +7798,7 @@ dependencies = [ [[package]] name = "turbo-tasks-hash" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" dependencies = [ "base16", "hex", @@ -7827,7 +7810,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" dependencies = [ "anyhow", "convert_case 0.6.0", @@ -7841,7 +7824,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros-shared" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" dependencies = [ "proc-macro2", "quote", @@ -7851,7 +7834,7 @@ dependencies = [ [[package]] name = "turbo-tasks-malloc" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" dependencies = [ "mimalloc", ] @@ -7859,7 +7842,7 @@ dependencies = [ [[package]] name = "turbo-tasks-memory" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" dependencies = [ "anyhow", "auto-hash-map", @@ -7884,7 +7867,7 @@ dependencies = [ [[package]] name = "turbopack" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" dependencies = [ "anyhow", "async-recursion", @@ -7915,7 +7898,7 @@ dependencies = [ [[package]] name = "turbopack-binding" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" dependencies = [ "auto-hash-map", "mdxjs", @@ -7955,7 +7938,7 @@ dependencies = [ [[package]] name = "turbopack-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7978,7 +7961,7 @@ dependencies = [ [[package]] name = "turbopack-cli-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" dependencies = [ "anyhow", "clap 4.4.2", @@ -8002,7 +7985,7 @@ dependencies = [ [[package]] name = "turbopack-core" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" dependencies = [ "anyhow", "async-recursion", @@ -8032,7 +8015,7 @@ dependencies = [ [[package]] name = "turbopack-css" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" dependencies = [ "anyhow", "async-trait", @@ -8058,7 +8041,7 @@ dependencies = [ [[package]] name = "turbopack-dev" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -8082,7 +8065,7 @@ dependencies = [ [[package]] name = "turbopack-dev-server" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" dependencies = [ "anyhow", "async-compression", @@ -8119,7 +8102,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" dependencies = [ "anyhow", "async-trait", @@ -8153,7 +8136,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-hmr-protocol" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" dependencies = [ "serde", "serde_json", @@ -8164,7 +8147,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-plugins" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" dependencies = [ "anyhow", "async-trait", @@ -8187,7 +8170,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-runtime" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" dependencies = [ "anyhow", "indoc", @@ -8204,7 +8187,7 @@ dependencies = [ [[package]] name = "turbopack-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -8220,7 +8203,7 @@ dependencies = [ [[package]] name = "turbopack-image" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" dependencies = [ "anyhow", "base64 0.21.4", @@ -8240,7 +8223,7 @@ dependencies = [ [[package]] name = "turbopack-json" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" dependencies = [ "anyhow", "serde", @@ -8255,7 +8238,7 @@ dependencies = [ [[package]] name = "turbopack-mdx" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" dependencies = [ "anyhow", "mdxjs", @@ -8270,7 +8253,7 @@ dependencies = [ [[package]] name = "turbopack-node" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" dependencies = [ "anyhow", "async-stream", @@ -8305,7 +8288,7 @@ dependencies = [ [[package]] name = "turbopack-static" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" dependencies = [ "anyhow", "serde", @@ -8321,7 +8304,7 @@ dependencies = [ [[package]] name = "turbopack-swc-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" dependencies = [ "swc_core", "turbo-tasks", @@ -8332,7 +8315,7 @@ dependencies = [ [[package]] name = "turbopack-wasm" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231126.2#12cdfed2cf3467d1cd87e12d092813d12ae3c3b8" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -8575,6 +8558,16 @@ dependencies = [ "time 0.3.30", ] +[[package]] +name = "vergen" +version = "8.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1290fd64cc4e7d3c9b07d7f333ce0ce0007253e32870e632624835cc80b83939" +dependencies = [ + "anyhow", + "rustversion", +] + [[package]] name = "version-compare" version = "0.1.1" diff --git a/Cargo.toml b/Cargo.toml index a6ed3bd05af4e..afefeae346758 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,18 +36,18 @@ next-transform-dynamic = { path = "packages/next-swc/crates/next-transform-dynam next-transform-strip-page-exports = { path = "packages/next-swc/crates/next-transform-strip-page-exports" } # SWC crates - swc_core = { version = "0.86.60", features = [ + swc_core = { version = "0.86.81", features = [ "ecma_loader_lru", "ecma_loader_parking_lot", ] } -testing = { version = "0.35.10" } +testing = { version = "0.35.11" } # Turbo crates -turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231126.2" } +turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231127.1" } # [TODO]: need to refactor embed_directory! macro usages, as well as resolving turbo_tasks::function, macros.. -turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231126.2" } +turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231127.1" } # [TODO]: need to refactor embed_directory! macro usage in next-core -turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231126.2" } +turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231127.1" } # General Deps diff --git a/packages/next-swc/crates/core/Cargo.toml b/packages/next-swc/crates/core/Cargo.toml index a58d780a18d9d..91499457977f5 100644 --- a/packages/next-swc/crates/core/Cargo.toml +++ b/packages/next-swc/crates/core/Cargo.toml @@ -38,8 +38,8 @@ turbopack-binding = { workspace = true, features = [ "__swc_transform_modularize_imports", "__swc_transform_relay", ] } -react_remove_properties = "0.11.0" -remove_console = "0.12.0" +react_remove_properties = "0.17.0" +remove_console = "0.18.0" [dev-dependencies] turbopack-binding = { workspace = true, features = [ diff --git a/packages/next-swc/crates/core/src/lib.rs b/packages/next-swc/crates/core/src/lib.rs index 56385f74b737b..90971748105b2 100644 --- a/packages/next-swc/crates/core/src/lib.rs +++ b/packages/next-swc/crates/core/src/lib.rs @@ -43,8 +43,10 @@ use serde::Deserialize; use turbopack_binding::swc::{ core::{ common::{ - chain, comments::Comments, pass::Optional, FileName, Mark, SourceFile, SourceMap, - SyntaxContext, + chain, + comments::{Comments, NoopComments}, + pass::Optional, + FileName, Mark, SourceFile, SourceMap, SyntaxContext, }, ecma::{ ast::EsVersion, parser::parse_file_as_module, transforms::base::pass::noop, visit::Fold, @@ -214,6 +216,7 @@ where file.name.clone(), file.src_hash, config.clone(), + NoopComments ) ), None => Either::Right(noop()), diff --git a/packages/next/package.json b/packages/next/package.json index aad9bd07330c6..54e36fcf662cf 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -193,7 +193,7 @@ "@types/ws": "8.2.0", "@vercel/ncc": "0.34.0", "@vercel/nft": "0.22.6", - "@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231126.2", + "@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.1", "acorn": "8.5.0", "amphtml-validator": "1.0.35", "anser": "1.4.9", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 98ef2ea66e30c..bd0f581b3af4a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1068,8 +1068,8 @@ importers: specifier: 0.22.6 version: 0.22.6 '@vercel/turbopack-ecmascript-runtime': - specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231126.2 - version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231126.2(react-refresh@0.12.0)(webpack@5.86.0)' + specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.1 + version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.1(react-refresh@0.12.0)(webpack@5.86.0)' acorn: specifier: 8.5.0 version: 8.5.0 @@ -24649,9 +24649,9 @@ packages: /zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} - '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231126.2(react-refresh@0.12.0)(webpack@5.86.0)': - resolution: {registry: https://registry.npmjs.org/, tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231126.2} - id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231126.2' + '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.1(react-refresh@0.12.0)(webpack@5.86.0)': + resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.1} + id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.1' name: '@vercel/turbopack-ecmascript-runtime' version: 0.0.0 dependencies: From f1511515fdf33bc30ce5436f5ec555ec71c528d3 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Mon, 27 Nov 2023 15:29:41 +0100 Subject: [PATCH 051/481] Trace server updates (#58694) ### What? some refactoring updates Closes PACK-1994 --- Cargo.lock | 88 +++++++++++-------- Cargo.toml | 8 +- .../crates/napi/src/next_api/project.rs | 12 +-- packages/next-swc/crates/next-core/Cargo.toml | 1 + .../crates/next-core/src/tracing_presets.rs | 2 +- packages/next/package.json | 2 +- pnpm-lock.yaml | 10 +-- 7 files changed, 67 insertions(+), 56 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 67ab55f16dc71..9387dd7d74c70 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -322,7 +322,7 @@ dependencies = [ [[package]] name = "auto-hash-map" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" dependencies = [ "serde", "smallvec", @@ -3549,7 +3549,7 @@ dependencies = [ [[package]] name = "node-file-trace" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" dependencies = [ "anyhow", "serde", @@ -7678,7 +7678,7 @@ dependencies = [ [[package]] name = "turbo-tasks" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" dependencies = [ "anyhow", "async-trait", @@ -7710,7 +7710,7 @@ dependencies = [ [[package]] name = "turbo-tasks-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" dependencies = [ "anyhow", "cargo-lock", @@ -7722,7 +7722,7 @@ dependencies = [ [[package]] name = "turbo-tasks-bytes" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" dependencies = [ "anyhow", "bytes", @@ -7737,7 +7737,7 @@ dependencies = [ [[package]] name = "turbo-tasks-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" dependencies = [ "anyhow", "dotenvs", @@ -7751,7 +7751,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fetch" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7768,7 +7768,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fs" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" dependencies = [ "anyhow", "auto-hash-map", @@ -7798,7 +7798,7 @@ dependencies = [ [[package]] name = "turbo-tasks-hash" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" dependencies = [ "base16", "hex", @@ -7810,7 +7810,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" dependencies = [ "anyhow", "convert_case 0.6.0", @@ -7824,7 +7824,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros-shared" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" dependencies = [ "proc-macro2", "quote", @@ -7834,7 +7834,7 @@ dependencies = [ [[package]] name = "turbo-tasks-malloc" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" dependencies = [ "mimalloc", ] @@ -7842,7 +7842,7 @@ dependencies = [ [[package]] name = "turbo-tasks-memory" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" dependencies = [ "anyhow", "auto-hash-map", @@ -7867,7 +7867,7 @@ dependencies = [ [[package]] name = "turbopack" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" dependencies = [ "anyhow", "async-recursion", @@ -7898,7 +7898,7 @@ dependencies = [ [[package]] name = "turbopack-binding" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" dependencies = [ "auto-hash-map", "mdxjs", @@ -7933,12 +7933,13 @@ dependencies = [ "turbopack-image", "turbopack-node", "turbopack-static", + "turbopack-trace-utils", ] [[package]] name = "turbopack-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7961,20 +7962,14 @@ dependencies = [ [[package]] name = "turbopack-cli-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" dependencies = [ "anyhow", "clap 4.4.2", - "crossbeam-channel", "crossterm", "once_cell", "owo-colors", - "postcard", "serde", - "serde_json", - "tokio", - "tracing", - "tracing-subscriber", "turbo-tasks", "turbo-tasks-build", "turbo-tasks-fs", @@ -7985,7 +7980,7 @@ dependencies = [ [[package]] name = "turbopack-core" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" dependencies = [ "anyhow", "async-recursion", @@ -8015,7 +8010,7 @@ dependencies = [ [[package]] name = "turbopack-css" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" dependencies = [ "anyhow", "async-trait", @@ -8041,7 +8036,7 @@ dependencies = [ [[package]] name = "turbopack-dev" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -8065,7 +8060,7 @@ dependencies = [ [[package]] name = "turbopack-dev-server" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" dependencies = [ "anyhow", "async-compression", @@ -8102,7 +8097,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" dependencies = [ "anyhow", "async-trait", @@ -8136,7 +8131,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-hmr-protocol" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" dependencies = [ "serde", "serde_json", @@ -8147,7 +8142,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-plugins" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" dependencies = [ "anyhow", "async-trait", @@ -8170,7 +8165,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-runtime" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" dependencies = [ "anyhow", "indoc", @@ -8187,7 +8182,7 @@ dependencies = [ [[package]] name = "turbopack-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -8203,7 +8198,7 @@ dependencies = [ [[package]] name = "turbopack-image" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" dependencies = [ "anyhow", "base64 0.21.4", @@ -8223,7 +8218,7 @@ dependencies = [ [[package]] name = "turbopack-json" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" dependencies = [ "anyhow", "serde", @@ -8238,7 +8233,7 @@ dependencies = [ [[package]] name = "turbopack-mdx" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" dependencies = [ "anyhow", "mdxjs", @@ -8253,7 +8248,7 @@ dependencies = [ [[package]] name = "turbopack-node" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" dependencies = [ "anyhow", "async-stream", @@ -8288,7 +8283,7 @@ dependencies = [ [[package]] name = "turbopack-static" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" dependencies = [ "anyhow", "serde", @@ -8304,7 +8299,7 @@ dependencies = [ [[package]] name = "turbopack-swc-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" dependencies = [ "swc_core", "turbo-tasks", @@ -8312,10 +8307,25 @@ dependencies = [ "turbopack-core", ] +[[package]] +name = "turbopack-trace-utils" +version = "0.1.0" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" +dependencies = [ + "anyhow", + "crossbeam-channel", + "once_cell", + "postcard", + "serde", + "tokio", + "tracing", + "tracing-subscriber", +] + [[package]] name = "turbopack-wasm" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.1#790f111bec30557369da6935ccae6d7782560edd" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" dependencies = [ "anyhow", "indexmap 1.9.3", diff --git a/Cargo.toml b/Cargo.toml index afefeae346758..4c7e71f5b53d9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -36,18 +36,18 @@ next-transform-dynamic = { path = "packages/next-swc/crates/next-transform-dynam next-transform-strip-page-exports = { path = "packages/next-swc/crates/next-transform-strip-page-exports" } # SWC crates - swc_core = { version = "0.86.81", features = [ +swc_core = { version = "0.86.81", features = [ "ecma_loader_lru", "ecma_loader_parking_lot", ] } testing = { version = "0.35.11" } # Turbo crates -turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231127.1" } +turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231127.3" } # [TODO]: need to refactor embed_directory! macro usages, as well as resolving turbo_tasks::function, macros.. -turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231127.1" } +turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231127.3" } # [TODO]: need to refactor embed_directory! macro usage in next-core -turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231127.1" } +turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231127.3" } # General Deps diff --git a/packages/next-swc/crates/napi/src/next_api/project.rs b/packages/next-swc/crates/napi/src/next_api/project.rs index 387e8f40a79fe..80ef449ec1b77 100644 --- a/packages/next-swc/crates/napi/src/next_api/project.rs +++ b/packages/next-swc/crates/napi/src/next_api/project.rs @@ -23,18 +23,18 @@ use turbopack_binding::{ tasks_memory::MemoryBackend, }, turbopack::{ - cli_utils::{ - exit::ExitGuard, - raw_trace::RawTraceLayer, - trace_writer::{TraceWriter, TraceWriterGuard}, - tracing_presets::TRACING_OVERVIEW_TARGETS, - }, core::{ error::PrettyPrintError, source_map::{GenerateSourceMap, Token}, version::{PartialUpdate, TotalUpdate, Update}, }, ecmascript_hmr_protocol::{ClientUpdateInstruction, ResourceIdentifier}, + trace_utils::{ + exit::ExitGuard, + raw_trace::RawTraceLayer, + trace_writer::{TraceWriter, TraceWriterGuard}, + tracing_presets::TRACING_OVERVIEW_TARGETS, + }, }, }; use url::Url; diff --git a/packages/next-swc/crates/next-core/Cargo.toml b/packages/next-swc/crates/next-core/Cargo.toml index 17bb9cbd20011..44e79c77f79bf 100644 --- a/packages/next-swc/crates/next-core/Cargo.toml +++ b/packages/next-swc/crates/next-core/Cargo.toml @@ -56,6 +56,7 @@ turbopack-binding = { workspace = true, features = [ "__turbopack_static", "__turbopack_image", "__turbopack_node", + "__turbopack_trace_utils", ] } turbo-tasks = { workspace = true } turbo-tasks-fs = { workspace = true } diff --git a/packages/next-swc/crates/next-core/src/tracing_presets.rs b/packages/next-swc/crates/next-core/src/tracing_presets.rs index 726a84380e764..c1dc35586fa79 100644 --- a/packages/next-swc/crates/next-core/src/tracing_presets.rs +++ b/packages/next-swc/crates/next-core/src/tracing_presets.rs @@ -1,5 +1,5 @@ use once_cell::sync::Lazy; -use turbopack_binding::turbopack::cli_utils::tracing_presets::{ +use turbopack_binding::turbopack::trace_utils::tracing_presets::{ TRACING_OVERVIEW_TARGETS, TRACING_TURBOPACK_TARGETS, TRACING_TURBO_TASKS_TARGETS, }; diff --git a/packages/next/package.json b/packages/next/package.json index 54e36fcf662cf..6ae8285a58f3d 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -193,7 +193,7 @@ "@types/ws": "8.2.0", "@vercel/ncc": "0.34.0", "@vercel/nft": "0.22.6", - "@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.1", + "@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.3", "acorn": "8.5.0", "amphtml-validator": "1.0.35", "anser": "1.4.9", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bd0f581b3af4a..be1463742f0fd 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1068,8 +1068,8 @@ importers: specifier: 0.22.6 version: 0.22.6 '@vercel/turbopack-ecmascript-runtime': - specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.1 - version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.1(react-refresh@0.12.0)(webpack@5.86.0)' + specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.3 + version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.3(react-refresh@0.12.0)(webpack@5.86.0)' acorn: specifier: 8.5.0 version: 8.5.0 @@ -24649,9 +24649,9 @@ packages: /zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} - '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.1(react-refresh@0.12.0)(webpack@5.86.0)': - resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.1} - id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.1' + '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.3(react-refresh@0.12.0)(webpack@5.86.0)': + resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.3} + id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.3' name: '@vercel/turbopack-ecmascript-runtime' version: 0.0.0 dependencies: From e62c18b89d26f6b52ba092bcac4ecdff3f71776b Mon Sep 17 00:00:00 2001 From: Zack Tanner Date: Mon, 27 Nov 2023 06:58:05 -0800 Subject: [PATCH 052/481] remove duplicate util file for redirect status (#58878) No change in behavior, this just moves a util that performs the same error digest parsing into the other file that performs similar behavior & validation. Since splitting & parsing the digest string is a strange operation, this keeps it close to where that happens & where it's validated so it's easier to follow. Since this file is imported in the same spots that we're importing the other redirect utils, there doesn't seem to be a reason to keep them separated. --- .../components/get-redirect-status-code-from-error.ts | 11 ----------- packages/next/src/client/components/redirect.ts | 10 ++++++++++ packages/next/src/server/app-render/app-render.tsx | 2 +- .../app-render/make-get-server-inserted-html.tsx | 2 +- .../app-route/helpers/resolve-handler-error.ts | 2 +- 5 files changed, 13 insertions(+), 14 deletions(-) delete mode 100644 packages/next/src/client/components/get-redirect-status-code-from-error.ts diff --git a/packages/next/src/client/components/get-redirect-status-code-from-error.ts b/packages/next/src/client/components/get-redirect-status-code-from-error.ts deleted file mode 100644 index 44e89ea751570..0000000000000 --- a/packages/next/src/client/components/get-redirect-status-code-from-error.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { type RedirectError, isRedirectError } from './redirect' - -export function getRedirectStatusCodeFromError( - error: RedirectError -): number { - if (!isRedirectError(error)) { - throw new Error('Not a redirect error') - } - - return error.digest.split(';', 4)[3] === 'true' ? 308 : 307 -} diff --git a/packages/next/src/client/components/redirect.ts b/packages/next/src/client/components/redirect.ts index cce1c01d67b63..d21deecb7754a 100644 --- a/packages/next/src/client/components/redirect.ts +++ b/packages/next/src/client/components/redirect.ts @@ -106,3 +106,13 @@ export function getRedirectTypeFromError( return error.digest.split(';', 2)[1] as RedirectType } + +export function getRedirectStatusCodeFromError( + error: RedirectError +): number { + if (!isRedirectError(error)) { + throw new Error('Not a redirect error') + } + + return error.digest.split(';', 4)[3] === 'true' ? 308 : 307 +} diff --git a/packages/next/src/server/app-render/app-render.tsx b/packages/next/src/server/app-render/app-render.tsx index d8a6e2662b871..252bb68d83ab4 100644 --- a/packages/next/src/server/app-render/app-render.tsx +++ b/packages/next/src/server/app-render/app-render.tsx @@ -44,8 +44,8 @@ import { isNotFoundError } from '../../client/components/not-found' import { getURLFromRedirectError, isRedirectError, + getRedirectStatusCodeFromError, } from '../../client/components/redirect' -import { getRedirectStatusCodeFromError } from '../../client/components/get-redirect-status-code-from-error' import { addImplicitTags } from '../lib/patch-fetch' import { AppRenderSpan } from '../lib/trace/constants' import { getTracer } from '../lib/trace/tracer' diff --git a/packages/next/src/server/app-render/make-get-server-inserted-html.tsx b/packages/next/src/server/app-render/make-get-server-inserted-html.tsx index d5b74353c84f4..7e4505823105e 100644 --- a/packages/next/src/server/app-render/make-get-server-inserted-html.tsx +++ b/packages/next/src/server/app-render/make-get-server-inserted-html.tsx @@ -3,8 +3,8 @@ import { isNotFoundError } from '../../client/components/not-found' import { getURLFromRedirectError, isRedirectError, + getRedirectStatusCodeFromError, } from '../../client/components/redirect' -import { getRedirectStatusCodeFromError } from '../../client/components/get-redirect-status-code-from-error' import { renderToReadableStream } from 'react-dom/server.edge' import { streamToString } from '../stream-utils/node-web-streams-helper' diff --git a/packages/next/src/server/future/route-modules/app-route/helpers/resolve-handler-error.ts b/packages/next/src/server/future/route-modules/app-route/helpers/resolve-handler-error.ts index 99f93376f3461..89045058e6172 100644 --- a/packages/next/src/server/future/route-modules/app-route/helpers/resolve-handler-error.ts +++ b/packages/next/src/server/future/route-modules/app-route/helpers/resolve-handler-error.ts @@ -1,8 +1,8 @@ -import { getRedirectStatusCodeFromError } from '../../../../../client/components/get-redirect-status-code-from-error' import { isNotFoundError } from '../../../../../client/components/not-found' import { getURLFromRedirectError, isRedirectError, + getRedirectStatusCodeFromError, } from '../../../../../client/components/redirect' import { handleNotFoundResponse, From 40a6e613fe700cf7de0797f6f1afcfdf6b10a4e6 Mon Sep 17 00:00:00 2001 From: Leah Date: Mon, 27 Nov 2023 16:19:45 +0100 Subject: [PATCH 053/481] fix(windows): workaround for intermittent locks on windows when renaming files (#58835) ### What? See: https://github.com/libuv/libuv/pull/1981 Closes PACK-1956 Fixes #57581 --- packages/next/package.json | 2 + .../next/src/compiled/@vercel/nft/index.js | 4 +- packages/next/src/lib/fs/rename.ts | 107 ++++++++++++++++++ packages/next/src/lib/fs/write-atomic.ts | 20 ++++ .../lib/router-utils/setup-dev-bundler.ts | 21 +--- pnpm-lock.yaml | 29 +++-- 6 files changed, 147 insertions(+), 36 deletions(-) create mode 100644 packages/next/src/lib/fs/rename.ts create mode 100644 packages/next/src/lib/fs/write-atomic.ts diff --git a/packages/next/package.json b/packages/next/package.json index 6ae8285a58f3d..a82113d24de6a 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -96,6 +96,7 @@ "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", + "graceful-fs": "^4.2.11", "postcss": "8.4.31", "styled-jsx": "5.1.1", "watchpack": "2.4.0" @@ -172,6 +173,7 @@ "@types/express-serve-static-core": "4.17.33", "@types/fresh": "0.5.0", "@types/glob": "7.1.1", + "@types/graceful-fs": "4.1.9", "@types/jsonwebtoken": "9.0.0", "@types/lodash": "4.14.198", "@types/lodash.curry": "4.1.6", diff --git a/packages/next/src/compiled/@vercel/nft/index.js b/packages/next/src/compiled/@vercel/nft/index.js index c95185aa3d22a..7b330e0edbc8c 100644 --- a/packages/next/src/compiled/@vercel/nft/index.js +++ b/packages/next/src/compiled/@vercel/nft/index.js @@ -1,6 +1,6 @@ -(()=>{var __webpack_modules__={5841:(e,t,r)=>{"use strict";e.exports=t;t.mockS3Http=r(9361).get_mockS3Http();t.mockS3Http("on");const s=t.mockS3Http("get");const a=r(7147);const o=r(1017);const u=r(1758);const c=r(9544);c.disableProgress();const f=r(5977);const d=r(2361).EventEmitter;const p=r(3837).inherits;const h=["clean","install","reinstall","build","rebuild","package","testpackage","publish","unpublish","info","testbinary","reveal","configure"];const v={};c.heading="node-pre-gyp";if(s){c.warn(`mocking s3 to ${process.env.node_pre_gyp_mock_s3}`)}Object.defineProperty(t,"find",{get:function(){return r(5921).find},enumerable:true});function Run({package_json_path:e="./package.json",argv:t}){this.package_json_path=e;this.commands={};const r=this;h.forEach((e=>{r.commands[e]=function(t,s){c.verbose("command",e,t);return require("./"+e)(r,t,s)}}));this.parseArgv(t);this.binaryHostSet=false}p(Run,d);t.Run=Run;const D=Run.prototype;D.package=r(7399);D.configDefs={help:Boolean,arch:String,debug:Boolean,directory:String,proxy:String,loglevel:String};D.shorthands={release:"--no-debug",C:"--directory",debug:"--debug",j:"--jobs",silent:"--loglevel=silent",silly:"--loglevel=silly",verbose:"--loglevel=verbose"};D.aliases=v;D.parseArgv=function parseOpts(e){this.opts=u(this.configDefs,this.shorthands,e);this.argv=this.opts.argv.remain.slice();const t=this.todo=[];e=this.argv.map((e=>{if(e in this.aliases){e=this.aliases[e]}return e}));e.slice().forEach((r=>{if(r in this.commands){const s=e.splice(0,e.indexOf(r));e.shift();if(t.length>0){t[t.length-1].args=s}t.push({name:r,args:[]})}}));if(t.length>0){t[t.length-1].args=e.splice(0)}let r=this.package_json_path;if(this.opts.directory){r=o.join(this.opts.directory,r)}this.package_json=JSON.parse(a.readFileSync(r));this.todo=f.expand_commands(this.package_json,this.opts,t);const s="npm_config_";Object.keys(process.env).forEach((e=>{if(e.indexOf(s)!==0)return;const t=process.env[e];if(e===s+"loglevel"){c.level=t}else{e=e.substring(s.length);if(e==="argv"){if(this.opts.argv&&this.opts.argv.remain&&this.opts.argv.remain.length){}else{this.opts[e]=t}}else{this.opts[e]=t}}}));if(this.opts.loglevel){c.level=this.opts.loglevel}c.resume()};D.setBinaryHostProperty=function(e){if(this.binaryHostSet){return this.package_json.binary.host}const t=this.package_json;if(!t||!t.binary||t.binary.host){return""}if(!t.binary.staging_host||!t.binary.production_host){return""}let r="production_host";if(e==="publish"){r="staging_host"}const s=process.env.node_pre_gyp_s3_host;if(s==="staging"||s==="production"){r=`${s}_host`}else if(this.opts["s3_host"]==="staging"||this.opts["s3_host"]==="production"){r=`${this.opts["s3_host"]}_host`}else if(this.opts["s3_host"]||s){throw new Error(`invalid s3_host ${this.opts["s3_host"]||s}`)}t.binary.host=t.binary[r];this.binaryHostSet=true;return t.binary.host};D.usage=function usage(){const e=[""," Usage: node-pre-gyp [options]",""," where is one of:",h.map((e=>" - "+e+" - "+require("./"+e).usage)).join("\n"),"","node-pre-gyp@"+this.version+" "+o.resolve(__dirname,".."),"node@"+process.versions.node].join("\n");return e};Object.defineProperty(D,"version",{get:function(){return this.package.version},enumerable:true})},5921:(e,t,r)=>{"use strict";const s=r(5841);const a=r(2821);const o=r(5977);const u=r(7147).existsSync||r(1017).existsSync;const c=r(1017);e.exports=t;t.usage="Finds the require path for the node-pre-gyp installed module";t.validate=function(e,t){a.validate_config(e,t)};t.find=function(e,t){if(!u(e)){throw new Error(e+"does not exist")}const r=new s.Run({package_json_path:e,argv:process.argv});r.setBinaryHostProperty();const f=r.package_json;a.validate_config(f,t);let d;if(o.get_napi_build_versions(f,t)){d=o.get_best_napi_build_version(f,t)}t=t||{};if(!t.module_root)t.module_root=c.dirname(e);const p=a.evaluate(f,t,d);return p.module}},5977:(e,t,r)=>{"use strict";const s=r(7147);e.exports=t;const a=process.version.substr(1).replace(/-.*$/,"").split(".").map((e=>+e));const o=["build","clean","configure","package","publish","reveal","testbinary","testpackage","unpublish"];const u="napi_build_version=";e.exports.get_napi_version=function(){let e=process.versions.napi;if(!e){if(a[0]===9&&a[1]>=3)e=2;else if(a[0]===8)e=1}return e};e.exports.get_napi_version_as_string=function(t){const r=e.exports.get_napi_version(t);return r?""+r:""};e.exports.validate_package_json=function(t,r){const s=t.binary;const a=pathOK(s.module_path);const o=pathOK(s.remote_path);const u=pathOK(s.package_name);const c=e.exports.get_napi_build_versions(t,r,true);const f=e.exports.get_napi_build_versions_raw(t);if(c){c.forEach((e=>{if(!(parseInt(e,10)===e&&e>0)){throw new Error("All values specified in napi_versions must be positive integers.")}}))}if(c&&(!a||!o&&!u)){throw new Error("When napi_versions is specified; module_path and either remote_path or "+"package_name must contain the substitution string '{napi_build_version}`.")}if((a||o||u)&&!f){throw new Error("When the substitution string '{napi_build_version}` is specified in "+"module_path, remote_path, or package_name; napi_versions must also be specified.")}if(c&&!e.exports.get_best_napi_build_version(t,r)&&e.exports.build_napi_only(t)){throw new Error("The Node-API version of this Node instance is "+e.exports.get_napi_version(r?r.target:undefined)+". "+"This module supports Node-API version(s) "+e.exports.get_napi_build_versions_raw(t)+". "+"This Node instance cannot run this module.")}if(f&&!c&&e.exports.build_napi_only(t)){throw new Error("The Node-API version of this Node instance is "+e.exports.get_napi_version(r?r.target:undefined)+". "+"This module supports Node-API version(s) "+e.exports.get_napi_build_versions_raw(t)+". "+"This Node instance cannot run this module.")}};function pathOK(e){return e&&(e.indexOf("{napi_build_version}")!==-1||e.indexOf("{node_napi_label}")!==-1)}e.exports.expand_commands=function(t,r,s){const a=[];const c=e.exports.get_napi_build_versions(t,r);s.forEach((s=>{if(c&&s.name==="install"){const o=e.exports.get_best_napi_build_version(t,r);const c=o?[u+o]:[];a.push({name:s.name,args:c})}else if(c&&o.indexOf(s.name)!==-1){c.forEach((e=>{const t=s.args.slice();t.push(u+e);a.push({name:s.name,args:t})}))}else{a.push(s)}}));return a};e.exports.get_napi_build_versions=function(t,s,a){const o=r(9544);let u=[];const c=e.exports.get_napi_version(s?s.target:undefined);if(t.binary&&t.binary.napi_versions){t.binary.napi_versions.forEach((e=>{const t=u.indexOf(e)!==-1;if(!t&&c&&e<=c){u.push(e)}else if(a&&!t&&c){o.info("This Node instance does not support builds for Node-API version",e)}}))}if(s&&s["build-latest-napi-version-only"]){let e=0;u.forEach((t=>{if(t>e)e=t}));u=e?[e]:[]}return u.length?u:undefined};e.exports.get_napi_build_versions_raw=function(e){const t=[];if(e.binary&&e.binary.napi_versions){e.binary.napi_versions.forEach((e=>{if(t.indexOf(e)===-1){t.push(e)}}))}return t.length?t:undefined};e.exports.get_command_arg=function(e){return u+e};e.exports.get_napi_build_version_from_command_args=function(e){for(let t=0;t{if(e>s&&e<=t){s=e}}))}return s===0?undefined:s};e.exports.build_napi_only=function(e){return e.binary&&e.binary.package_name&&e.binary.package_name.indexOf("{node_napi_label}")===-1}},9361:(e,t,r)=>{"use strict";e.exports=t;const s=r(7310);const a=r(7147);const o=r(1017);e.exports.detect=function(e,t){const r=e.hosted_path;const a=s.parse(r);t.prefix=!a.pathname||a.pathname==="/"?"":a.pathname.replace("/","");if(e.bucket&&e.region){t.bucket=e.bucket;t.region=e.region;t.endpoint=e.host;t.s3ForcePathStyle=e.s3ForcePathStyle}else{const e=a.hostname.split(".s3");const r=e[0];if(!r){return}if(!t.bucket){t.bucket=r}if(!t.region){const r=e[1].slice(1).split(".")[0];if(r==="amazonaws"){t.region="us-east-1"}else{t.region=r}}}};e.exports.get_s3=function(e){if(process.env.node_pre_gyp_mock_s3){const e=r(3930);const t=r(2037);e.config.basePath=`${t.tmpdir()}/mock`;const s=e.S3();const wcb=e=>(t,...r)=>{if(t&&t.code==="ENOENT"){t.code="NotFound"}return e(t,...r)};return{listObjects(e,t){return s.listObjects(e,wcb(t))},headObject(e,t){return s.headObject(e,wcb(t))},deleteObject(e,t){return s.deleteObject(e,wcb(t))},putObject(e,t){return s.putObject(e,wcb(t))}}}const t=r(2355);t.config.update(e);const s=new t.S3;return{listObjects(e,t){return s.listObjects(e,t)},headObject(e,t){return s.headObject(e,t)},deleteObject(e,t){return s.deleteObject(e,t)},putObject(e,t){return s.putObject(e,t)}}};e.exports.get_mockS3Http=function(){let e=false;if(!process.env.node_pre_gyp_mock_s3){return()=>e}const t=r(4997);const s="https://mapbox-node-pre-gyp-public-testing-bucket.s3.us-east-1.amazonaws.com";const u=process.env.node_pre_gyp_mock_s3+"/mapbox-node-pre-gyp-public-testing-bucket";const mock_http=()=>{function get(e,t){const r=o.join(u,e.replace("%2B","+"));try{a.accessSync(r,a.constants.R_OK)}catch(e){return[404,"not found\n"]}return[200,a.createReadStream(r)]}return t(s).persist().get((()=>e)).reply(get)};mock_http(t,s,u);const mockS3Http=t=>{const r=e;if(t==="off"){e=false}else if(t==="on"){e=true}else if(t!=="get"){throw new Error(`illegal action for setMockHttp ${t}`)}return r};return mockS3Http}},2821:(e,t,r)=>{"use strict";e.exports=t;const s=r(1017);const a=r(7849);const o=r(7310);const u=r(5104);const c=r(5977);let f;if(process.env.NODE_PRE_GYP_ABI_CROSSWALK){f=require(process.env.NODE_PRE_GYP_ABI_CROSSWALK)}else{f=r(9448)}const d={};Object.keys(f).forEach((e=>{const t=e.split(".")[0];if(!d[t]){d[t]=e}}));function get_electron_abi(e,t){if(!e){throw new Error("get_electron_abi requires valid runtime arg")}if(typeof t==="undefined"){throw new Error("Empty target version is not supported if electron is the target.")}const r=a.parse(t);return e+"-v"+r.major+"."+r.minor}e.exports.get_electron_abi=get_electron_abi;function get_node_webkit_abi(e,t){if(!e){throw new Error("get_node_webkit_abi requires valid runtime arg")}if(typeof t==="undefined"){throw new Error("Empty target version is not supported if node-webkit is the target.")}return e+"-v"+t}e.exports.get_node_webkit_abi=get_node_webkit_abi;function get_node_abi(e,t){if(!e){throw new Error("get_node_abi requires valid runtime arg")}if(!t){throw new Error("get_node_abi requires valid process.versions object")}const r=a.parse(t.node);if(r.major===0&&r.minor%2){return e+"-v"+t.node}else{return t.modules?e+"-v"+ +t.modules:"v8-"+t.v8.split(".").slice(0,2).join(".")}}e.exports.get_node_abi=get_node_abi;function get_runtime_abi(e,t){if(!e){throw new Error("get_runtime_abi requires valid runtime arg")}if(e==="node-webkit"){return get_node_webkit_abi(e,t||process.versions["node-webkit"])}else if(e==="electron"){return get_electron_abi(e,t||process.versions.electron)}else{if(e!=="node"){throw new Error("Unknown Runtime: '"+e+"'")}if(!t){return get_node_abi(e,process.versions)}else{let r;if(f[t]){r=f[t]}else{const e=t.split(".").map((e=>+e));if(e.length!==3){throw new Error("Unknown target version: "+t)}const s=e[0];let a=e[1];let o=e[2];if(s===1){while(true){if(a>0)--a;if(o>0)--o;const e=""+s+"."+a+"."+o;if(f[e]){r=f[e];console.log("Warning: node-pre-gyp could not find exact match for "+t);console.log("Warning: but node-pre-gyp successfully choose "+e+" as ABI compatible target");break}if(a===0&&o===0){break}}}else if(s>=2){if(d[s]){r=f[d[s]];console.log("Warning: node-pre-gyp could not find exact match for "+t);console.log("Warning: but node-pre-gyp successfully choose "+d[s]+" as ABI compatible target")}}else if(s===0){if(e[1]%2===0){while(--o>0){const e=""+s+"."+a+"."+o;if(f[e]){r=f[e];console.log("Warning: node-pre-gyp could not find exact match for "+t);console.log("Warning: but node-pre-gyp successfully choose "+e+" as ABI compatible target");break}}}}}if(!r){throw new Error("Unsupported target version: "+t)}const s={node:t,v8:r.v8+".0",modules:r.node_abi>1?r.node_abi:undefined};return get_node_abi(e,s)}}}e.exports.get_runtime_abi=get_runtime_abi;const p=["module_name","module_path","host"];function validate_config(e,t){const r=e.name+" package.json is not node-pre-gyp ready:\n";const s=[];if(!e.main){s.push("main")}if(!e.version){s.push("version")}if(!e.name){s.push("name")}if(!e.binary){s.push("binary")}const a=e.binary;if(a){p.forEach((e=>{if(!a[e]||typeof a[e]!=="string"){s.push("binary."+e)}}))}if(s.length>=1){throw new Error(r+"package.json must declare these properties: \n"+s.join("\n"))}if(a){const e=o.parse(a.host).protocol;if(e==="http:"){throw new Error("'host' protocol ("+e+") is invalid - only 'https:' is accepted")}}c.validate_package_json(e,t)}e.exports.validate_config=validate_config;function eval_template(e,t){Object.keys(t).forEach((r=>{const s="{"+r+"}";while(e.indexOf(s)>-1){e=e.replace(s,t[r])}}));return e}function fix_slashes(e){if(e.slice(-1)!=="/"){return e+"/"}return e}function drop_double_slashes(e){return e.replace(/\/\//g,"/")}function get_process_runtime(e){let t="node";if(e["node-webkit"]){t="node-webkit"}else if(e.electron){t="electron"}return t}e.exports.get_process_runtime=get_process_runtime;const h="{module_name}-v{version}-{node_abi}-{platform}-{arch}.tar.gz";const v="";e.exports.evaluate=function(e,t,r){t=t||{};validate_config(e,t);const f=e.version;const d=a.parse(f);const p=t.runtime||get_process_runtime(process.versions);const D={name:e.name,configuration:t.debug?"Debug":"Release",debug:t.debug,module_name:e.binary.module_name,version:d.version,prerelease:d.prerelease.length?d.prerelease.join("."):"",build:d.build.length?d.build.join("."):"",major:d.major,minor:d.minor,patch:d.patch,runtime:p,node_abi:get_runtime_abi(p,t.target),node_abi_napi:c.get_napi_version(t.target)?"napi":get_runtime_abi(p,t.target),napi_version:c.get_napi_version(t.target),napi_build_version:r||"",node_napi_label:r?"napi-v"+r:get_runtime_abi(p,t.target),target:t.target||"",platform:t.target_platform||process.platform,target_platform:t.target_platform||process.platform,arch:t.target_arch||process.arch,target_arch:t.target_arch||process.arch,libc:t.target_libc||u.family||"unknown",module_main:e.main,toolset:t.toolset||"",bucket:e.binary.bucket,region:e.binary.region,s3ForcePathStyle:e.binary.s3ForcePathStyle||false};const g=D.module_name.replace("-","_");const y=process.env["npm_config_"+g+"_binary_host_mirror"]||e.binary.host;D.host=fix_slashes(eval_template(y,D));D.module_path=eval_template(e.binary.module_path,D);if(t.module_root){D.module_path=s.join(t.module_root,D.module_path)}else{D.module_path=s.resolve(D.module_path)}D.module=s.join(D.module_path,D.module_name+".node");D.remote_path=e.binary.remote_path?drop_double_slashes(fix_slashes(eval_template(e.binary.remote_path,D))):v;const m=e.binary.package_name?e.binary.package_name:h;D.package_name=eval_template(m,D);D.staged_tarball=s.join("build/stage",D.remote_path,D.package_name);D.hosted_path=o.resolve(D.host,D.remote_path);D.hosted_tarball=o.resolve(D.hosted_path,D.package_name);return D}},7498:function(e,t,r){"use strict";var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:true});const a=s(r(1017));const o=r(3982);const u=r(9663);const c=r(4370);const f=r(1988);const d=s(r(3331));const p=r(9336);const h=s(r(3535));const v=r(1226);const D=r(2100);const g=r(7393);const y=s(r(1415));const m=s(r(1));const _=s(r(7663));const E=s(r(5841));const w=r(7310);const x=f.Parser.extend();const F=s(r(2037));const C=r(3791);const S=s(r(2382));const k={cwd:()=>K,env:{NODE_ENV:c.UNKNOWN,[c.UNKNOWN]:true},[c.UNKNOWN]:true};const A=Symbol();const R=Symbol();const O=Symbol();const T=Symbol();const j=Symbol();const B=Symbol();const L=Symbol();const N=Symbol();const I=Symbol();const P={access:B,accessSync:B,createReadStream:B,exists:B,existsSync:B,fstat:B,fstatSync:B,lstat:B,lstatSync:B,open:B,readdir:L,readdirSync:L,readFile:B,readFileSync:B,stat:B,statSync:B};const W={...P,pathExists:B,pathExistsSync:B,readJson:B,readJSON:B,readJsonSync:B,readJSONSync:B};const M=Object.assign(Object.create(null),{bindings:{default:N},express:{default:function(){return{[c.UNKNOWN]:true,set:A,engine:R}}},fs:{default:P,...P},"fs-extra":{default:W,...W},"graceful-fs":{default:P,...P},process:{default:k,...k},path:{default:{}},os:{default:F.default,...F.default},"@mapbox/node-pre-gyp":{default:E.default,...E.default},"node-pre-gyp":D.pregyp,"node-pre-gyp/lib/pre-binding":D.pregyp,"node-pre-gyp/lib/pre-binding.js":D.pregyp,"node-gyp-build":{default:I},nbind:{init:O,default:{init:O}},"resolve-from":{default:S.default},"strong-globalize":{default:{SetRootDir:T},SetRootDir:T},pkginfo:{default:j}});const $={_interopRequireDefault:g.normalizeDefaultRequire,_interopRequireWildcard:g.normalizeWildcardRequire,__importDefault:g.normalizeDefaultRequire,__importStar:g.normalizeWildcardRequire,MONGOOSE_DRIVER_PATH:undefined,URL:w.URL,Object:{assign:Object.assign}};$.global=$.GLOBAL=$.globalThis=$;const q=Symbol();D.pregyp.find[q]=true;const U=M.path;Object.keys(a.default).forEach((e=>{const t=a.default[e];if(typeof t==="function"){const r=function mockPath(){return t.apply(mockPath,arguments)};r[q]=true;U[e]=U.default[e]=r}else{U[e]=U.default[e]=t}}));U.resolve=U.default.resolve=function(...e){return a.default.resolve.apply(this,[K,...e])};U.resolve[q]=true;const G=new Set([".h",".cmake",".c",".cpp"]);const H=new Set(["CHANGELOG.md","README.md","readme.md","changelog.md"]);let K;const z=/^\/[^\/]+|^[a-z]:[\\/][^\\/]+/i;function isAbsolutePathOrUrl(e){if(e instanceof w.URL)return e.protocol==="file:";if(typeof e==="string"){if(e.startsWith("file:")){try{new w.URL(e);return true}catch{return false}}return z.test(e)}return false}const V=Symbol();const Y=/([\/\\]\*\*[\/\\]\*)+/g;async function analyze(e,t,r){const s=new Set;const f=new Set;const g=new Set;const E=a.default.dirname(e);K=r.cwd;const F=(0,v.getPackageBase)(e);const emitAssetDirectory=e=>{if(!r.analysis.emitGlobs)return;const t=e.indexOf(c.WILDCARD);const o=t===-1?e.length:e.lastIndexOf(a.default.sep,t);const u=e.substring(0,o);const f=e.slice(o);const d=f.replace(c.wildcardRegEx,((e,t)=>f[t-1]===a.default.sep?"**/*":"*")).replace(Y,"/**/*")||"/**/*";if(r.ignoreFn(a.default.relative(r.base,u+d)))return;P=P.then((async()=>{if(r.log)console.log("Globbing "+u+d);const e=await new Promise(((e,t)=>(0,h.default)(u+d,{mark:true,ignore:u+"/**/node_modules/**/*"},((r,s)=>r?t(r):e(s)))));e.filter((e=>!G.has(a.default.extname(e))&&!H.has(a.default.basename(e))&&!e.endsWith("/"))).forEach((e=>s.add(e)))}))};let P=Promise.resolve();t=t.replace(/^#![^\n\r]*[\r\n]/,"");let W;let U=false;try{W=x.parse(t,{ecmaVersion:"latest",allowReturnOutsideFunction:true});U=false}catch(t){const s=t&&t.message&&t.message.includes("sourceType: module");if(!s){r.warnings.add(new Error(`Failed to parse ${e} as script:\n${t&&t.message}`))}}if(!W){try{W=x.parse(t,{ecmaVersion:"latest",sourceType:"module",allowAwaitOutsideFunction:true});U=true}catch(t){r.warnings.add(new Error(`Failed to parse ${e} as module:\n${t&&t.message}`));return{assets:s,deps:f,imports:g,isESM:false}}}const Q=(0,w.pathToFileURL)(e).href;const J=Object.assign(Object.create(null),{__dirname:{shadowDepth:0,value:{value:a.default.resolve(e,"..")}},__filename:{shadowDepth:0,value:{value:e}},process:{shadowDepth:0,value:{value:k}}});if(!U||r.mixedModules){J.require={shadowDepth:0,value:{value:{[c.FUNCTION](e){f.add(e);const t=M[e.startsWith("node:")?e.slice(5):e];return t.default},resolve(t){return(0,m.default)(t,e,r)}}}};J.require.value.value.resolve[q]=true}function setKnownBinding(e,t){if(e==="require")return;J[e]={shadowDepth:0,value:t}}function getKnownBinding(e){const t=J[e];if(t){if(t.shadowDepth===0){return t.value}}return undefined}function hasKnownBindingValue(e){const t=J[e];return t&&t.shadowDepth===0}if((U||r.mixedModules)&&isAst(W)){for(const e of W.body){if(e.type==="ImportDeclaration"){const t=String(e.source.value);f.add(t);const r=M[t.startsWith("node:")?t.slice(5):t];if(r){for(const t of e.specifiers){if(t.type==="ImportNamespaceSpecifier")setKnownBinding(t.local.name,{value:r});else if(t.type==="ImportDefaultSpecifier"&&"default"in r)setKnownBinding(t.local.name,{value:r.default});else if(t.type==="ImportSpecifier"&&t.imported.name in r)setKnownBinding(t.local.name,{value:r[t.imported.name]})}}}else if(e.type==="ExportNamedDeclaration"||e.type==="ExportAllDeclaration"){if(e.source)f.add(String(e.source.value))}}}async function computePureStaticValue(e,t=true){const r=Object.create(null);Object.keys($).forEach((e=>{r[e]={value:$[e]}}));Object.keys(J).forEach((e=>{r[e]=getKnownBinding(e)}));r["import.meta"]={url:Q};const s=await(0,c.evaluate)(e,r,t);return s}let X;let Z;let ee=false;function emitWildcardRequire(e){if(!r.analysis.emitGlobs||!e.startsWith("./")&&!e.startsWith("../"))return;e=a.default.resolve(E,e);const t=e.indexOf(c.WILDCARD);const s=t===-1?e.length:e.lastIndexOf(a.default.sep,t);const o=e.substring(0,s);const u=e.slice(s);let d=u.replace(c.wildcardRegEx,((e,t)=>u[t-1]===a.default.sep?"**/*":"*"))||"/**/*";if(!d.endsWith("*"))d+="?("+(r.ts?".ts|.tsx|":"")+".js|.json|.node)";if(r.ignoreFn(a.default.relative(r.base,o+d)))return;P=P.then((async()=>{if(r.log)console.log("Globbing "+o+d);const e=await new Promise(((e,t)=>(0,h.default)(o+d,{mark:true,ignore:o+"/**/node_modules/**/*"},((r,s)=>r?t(r):e(s)))));e.filter((e=>!G.has(a.default.extname(e))&&!H.has(a.default.basename(e))&&!e.endsWith("/"))).forEach((e=>f.add(e)))}))}async function processRequireArg(e,t=false){if(e.type==="ConditionalExpression"){await processRequireArg(e.consequent,t);await processRequireArg(e.alternate,t);return}if(e.type==="LogicalExpression"){await processRequireArg(e.left,t);await processRequireArg(e.right,t);return}let r=await computePureStaticValue(e,true);if(!r)return;if("value"in r&&typeof r.value==="string"){if(!r.wildcards)(t?g:f).add(r.value);else if(r.wildcards.length>=1)emitWildcardRequire(r.value)}else{if("then"in r&&typeof r.then==="string")(t?g:f).add(r.then);if("else"in r&&typeof r.else==="string")(t?g:f).add(r.else)}}let te=(0,u.attachScopes)(W,"scope");if(isAst(W)){(0,C.handleWrappers)(W);await(0,y.default)({id:e,ast:W,emitDependency:e=>f.add(e),emitAsset:e=>s.add(e),emitAssetDirectory:emitAssetDirectory,job:r})}async function backtrack(e,t){if(!X)throw new Error("Internal error: No staticChildNode for backtrack.");const r=await computePureStaticValue(e,true);if(r){if("value"in r&&typeof r.value!=="symbol"||"then"in r&&typeof r.then!=="symbol"&&typeof r.else!=="symbol"){Z=r;X=e;if(t)t.skip();return}}await emitStaticChildAsset()}await(0,o.asyncWalk)(W,{async enter(t,o){const u=t;const c=o;if(u.scope){te=u.scope;for(const e in u.scope.declarations){if(e in J)J[e].shadowDepth++}}if(X)return;if(!c)return;if(u.type==="Identifier"){if((0,p.isIdentifierRead)(u,c)&&r.analysis.computeFileReferences){let e;if(typeof(e=getKnownBinding(u.name)?.value)==="string"&&e.match(z)||e&&(typeof e==="function"||typeof e==="object")&&e[q]){Z={value:typeof e==="string"?e:undefined};X=u;await backtrack(c,this)}}}else if(r.analysis.computeFileReferences&&u.type==="MemberExpression"&&u.object.type==="MetaProperty"&&u.object.meta.name==="import"&&u.object.property.name==="meta"&&(u.property.computed?u.property.value:u.property.name)==="url"){Z={value:Q};X=u;await backtrack(c,this)}else if(u.type==="ImportExpression"){await processRequireArg(u.source,true);return}else if(u.type==="CallExpression"){if((!U||r.mixedModules)&&u.callee.type==="Identifier"&&u.arguments.length){if(u.callee.name==="require"&&J.require.shadowDepth===0){await processRequireArg(u.arguments[0]);return}}else if((!U||r.mixedModules)&&u.callee.type==="MemberExpression"&&u.callee.object.type==="Identifier"&&u.callee.object.name==="module"&&"module"in J===false&&u.callee.property.type==="Identifier"&&!u.callee.computed&&u.callee.property.name==="require"&&u.arguments.length){await processRequireArg(u.arguments[0]);return}else if((!U||r.mixedModules)&&u.callee.type==="MemberExpression"&&u.callee.object.type==="Identifier"&&u.callee.object.name==="require"&&J.require.shadowDepth===0&&u.callee.property.type==="Identifier"&&!u.callee.computed&&u.callee.property.name==="resolve"&&u.arguments.length){await processRequireArg(u.arguments[0]);return}const t=r.analysis.evaluatePureExpressions&&await computePureStaticValue(u.callee,false);if(t&&"value"in t&&typeof t.value==="function"&&t.value[q]&&r.analysis.computeFileReferences){Z=await computePureStaticValue(u,true);if(Z&&c){X=u;await backtrack(c,this)}}else if(t&&"value"in t&&typeof t.value==="symbol"){switch(t.value){case V:if(u.arguments.length===1&&u.arguments[0].type==="Literal"&&u.callee.type==="Identifier"&&J.require.shadowDepth===0){await processRequireArg(u.arguments[0])}break;case N:if(u.arguments.length){const e=await computePureStaticValue(u.arguments[0],false);if(e&&"value"in e&&e.value){let t;if(typeof e.value==="object")t=e.value;else if(typeof e.value==="string")t={bindings:e.value};if(!t.path){t.path=true}t.module_root=F;let r;try{r=(0,d.default)(t)}catch(e){}if(r){Z={value:r};X=u;await emitStaticChildAsset()}}}break;case I:if(u.arguments.length===1&&u.arguments[0].type==="Identifier"&&u.arguments[0].name==="__dirname"&&J.__dirname.shadowDepth===0){let e;try{const t=(0,S.default)(E,"node-gyp-build");e=require(t).path(E)}catch(t){try{e=_.default.path(E)}catch(e){}}if(e){Z={value:e};X=u;await emitStaticChildAsset()}}break;case O:if(u.arguments.length){const e=await computePureStaticValue(u.arguments[0],false);if(e&&"value"in e&&(typeof e.value==="string"||typeof e.value==="undefined")){const t=(0,D.nbind)(e.value);if(t&&t.path){f.add(a.default.relative(E,t.path).replace(/\\/g,"/"));return this.skip()}}}break;case A:if(u.arguments.length===2&&u.arguments[0].type==="Literal"&&u.arguments[0].value==="view engine"&&!ee){await processRequireArg(u.arguments[1]);return this.skip()}break;case R:ee=true;break;case B:case L:if(u.arguments[0]&&r.analysis.computeFileReferences){Z=await computePureStaticValue(u.arguments[0],true);if(Z){X=u.arguments[0];if(t.value===L&&u.arguments[0].type==="Identifier"&&u.arguments[0].name==="__dirname"){emitAssetDirectory(E)}else{await backtrack(c,this)}return this.skip()}}break;case T:if(u.arguments[0]){const e=await computePureStaticValue(u.arguments[0],false);if(e&&"value"in e&&e.value)emitAssetDirectory(e.value+"/intl");return this.skip()}break;case j:let o=a.default.resolve(e,"../package.json");const p=a.default.resolve("/package.json");while(o!==p&&await r.stat(o)===null)o=a.default.resolve(o,"../../package.json");if(o!==p)s.add(o);break}}}else if(u.type==="VariableDeclaration"&&c&&!(0,p.isVarLoop)(c)&&r.analysis.evaluatePureExpressions){for(const e of u.declarations){if(!e.init)continue;const t=await computePureStaticValue(e.init,true);if(t){if(e.id.type==="Identifier"){setKnownBinding(e.id.name,t)}else if(e.id.type==="ObjectPattern"&&"value"in t){for(const r of e.id.properties){if(r.type!=="Property"||r.key.type!=="Identifier"||r.value.type!=="Identifier"||typeof t.value!=="object"||t.value===null||!(r.key.name in t.value))continue;setKnownBinding(r.value.name,{value:t.value[r.key.name]})}}if(!("value"in t)&&isAbsolutePathOrUrl(t.then)&&isAbsolutePathOrUrl(t.else)){Z=t;X=e.init;await emitStaticChildAsset()}}}}else if(u.type==="AssignmentExpression"&&c&&!(0,p.isLoop)(c)&&r.analysis.evaluatePureExpressions){if(!hasKnownBindingValue(u.left.name)){const e=await computePureStaticValue(u.right,false);if(e&&"value"in e){if(u.left.type==="Identifier"){setKnownBinding(u.left.name,e)}else if(u.left.type==="ObjectPattern"){for(const t of u.left.properties){if(t.type!=="Property"||t.key.type!=="Identifier"||t.value.type!=="Identifier"||typeof e.value!=="object"||e.value===null||!(t.key.name in e.value))continue;setKnownBinding(t.value.name,{value:e.value[t.key.name]})}}if(isAbsolutePathOrUrl(e.value)){Z=e;X=u.right;await emitStaticChildAsset()}}}}else if((!U||r.mixedModules)&&(u.type==="FunctionDeclaration"||u.type==="FunctionExpression"||u.type==="ArrowFunctionExpression")&&(u.arguments||u.params)[0]&&(u.arguments||u.params)[0].type==="Identifier"){let e;let t;if((u.type==="ArrowFunctionExpression"||u.type==="FunctionExpression")&&c&&c.type==="VariableDeclarator"&&c.id.type==="Identifier"){e=c.id;t=u.arguments||u.params}else if(u.id){e=u.id;t=u.arguments||u.params}if(e&&u.body.body){let r,s=false;for(let e=0;ee&&e.id&&e.id.type==="Identifier"&&e.init&&e.init.type==="CallExpression"&&e.init.callee.type==="Identifier"&&e.init.callee.name==="require"&&J.require.shadowDepth===0&&e.init.arguments[0]&&e.init.arguments[0].type==="Identifier"&&e.init.arguments[0].name===t[0].name))}if(r&&u.body.body[e].type==="ReturnStatement"&&u.body.body[e].argument&&u.body.body[e].argument.type==="Identifier"&&u.body.body[e].argument.name===r.id.name){s=true;break}}if(s)setKnownBinding(e.name,{value:V})}}},async leave(e,t){const r=e;const s=t;if(r.scope){if(te.parent){te=te.parent}for(const e in r.scope.declarations){if(e in J){if(J[e].shadowDepth>0)J[e].shadowDepth--;else delete J[e]}}}if(X&&s)await backtrack(s,this)}});await P;return{assets:s,deps:f,imports:g,isESM:U};async function emitAssetPath(e){const t=e.indexOf(c.WILDCARD);const o=t===-1?e.length:e.lastIndexOf(a.default.sep,t);const u=e.substring(0,o);try{var f=await r.stat(u);if(f===null){throw new Error("file not found")}}catch(e){return}if(t!==-1&&f.isFile())return;if(f.isFile()){s.add(e)}else if(f.isDirectory()){if(validWildcard(e))emitAssetDirectory(e)}}function validWildcard(t){let s="";if(t.endsWith(a.default.sep))s=a.default.sep;else if(t.endsWith(a.default.sep+c.WILDCARD))s=a.default.sep+c.WILDCARD;else if(t.endsWith(c.WILDCARD))s=c.WILDCARD;if(t===E+s)return false;if(t===K+s)return false;if(t.endsWith(a.default.sep+"node_modules"+s))return false;if(E.startsWith(t.slice(0,t.length-s.length)+a.default.sep))return false;if(F){const s=e.substring(0,e.indexOf(a.default.sep+"node_modules"))+a.default.sep+"node_modules"+a.default.sep;if(!t.startsWith(s)){if(r.log)console.log("Skipping asset emission of "+t.replace(c.wildcardRegEx,"*")+" for "+e+" as it is outside the package base "+F);return false}}return true}function resolveAbsolutePathOrUrl(e){return e instanceof w.URL?(0,w.fileURLToPath)(e):e.startsWith("file:")?(0,w.fileURLToPath)(new w.URL(e)):a.default.resolve(e)}async function emitStaticChildAsset(){if(!Z){return}if("value"in Z&&isAbsolutePathOrUrl(Z.value)){try{const e=resolveAbsolutePathOrUrl(Z.value);await emitAssetPath(e)}catch(e){}}else if("then"in Z&&"else"in Z&&isAbsolutePathOrUrl(Z.then)&&isAbsolutePathOrUrl(Z.else)){let e;try{e=resolveAbsolutePathOrUrl(Z.then)}catch(e){}let t;try{t=resolveAbsolutePathOrUrl(Z.else)}catch(e){}if(e)await emitAssetPath(e);if(t)await emitAssetPath(t)}else if(X&&X.type==="ArrayExpression"&&"value"in Z&&Z.value instanceof Array){for(const e of Z.value){try{const t=resolveAbsolutePathOrUrl(e);await emitAssetPath(t)}catch(e){}}}X=Z=undefined}}t["default"]=analyze;function isAst(e){return"body"in e}},529:function(e,t,r){"use strict";var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:true});t.CachedFileSystem=void 0;const a=r(1017);const o=s(r(9165));const u=r(5749);const c=o.default.promises.readFile;const f=o.default.promises.readlink;const d=o.default.promises.stat;class CachedFileSystem{constructor({cache:e,fileIOConcurrency:t}){this.fileIOQueue=new u.Sema(t);this.fileCache=e?.fileCache??new Map;this.statCache=e?.statCache??new Map;this.symlinkCache=e?.symlinkCache??new Map;if(e){e.fileCache=this.fileCache;e.statCache=this.statCache;e.symlinkCache=this.symlinkCache}}async readlink(e){const t=this.symlinkCache.get(e);if(t!==undefined)return t;const r=this.executeFileIO(e,this._internalReadlink);this.symlinkCache.set(e,r);return r}async readFile(e){const t=this.fileCache.get(e);if(t!==undefined)return t;const r=this.executeFileIO(e,this._internalReadFile);this.fileCache.set(e,r);return r}async stat(e){const t=this.statCache.get(e);if(t!==undefined)return t;const r=this.executeFileIO(e,this._internalStat);this.statCache.set(e,r);return r}async _internalReadlink(e){try{const t=await f(e);const r=this.statCache.get(e);if(r)this.statCache.set((0,a.resolve)(e,t),r);return t}catch(e){if(e.code!=="EINVAL"&&e.code!=="ENOENT"&&e.code!=="UNKNOWN")throw e;return null}}async _internalReadFile(e){try{return(await c(e)).toString()}catch(e){if(e.code==="ENOENT"||e.code==="EISDIR"){return null}throw e}}async _internalStat(e){try{return await d(e)}catch(e){if(e.code==="ENOENT"){return null}throw e}}async executeFileIO(e,t){await this.fileIOQueue.acquire();try{return t.call(this,e)}finally{this.fileIOQueue.release()}}}t.CachedFileSystem=CachedFileSystem},6223:function(e,t,r){"use strict";var s=this&&this.__createBinding||(Object.create?function(e,t,r,s){if(s===undefined)s=r;var a=Object.getOwnPropertyDescriptor(t,r);if(!a||("get"in a?!t.__esModule:a.writable||a.configurable)){a={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,s,a)}:function(e,t,r,s){if(s===undefined)s=r;e[s]=t[r]});var a=this&&this.__exportStar||function(e,t){for(var r in e)if(r!=="default"&&!Object.prototype.hasOwnProperty.call(t,r))s(t,e,r)};Object.defineProperty(t,"__esModule",{value:true});t.nodeFileTrace=void 0;a(r(8470),t);var o=r(2411);Object.defineProperty(t,"nodeFileTrace",{enumerable:true,get:function(){return o.nodeFileTrace}})},2411:function(e,t,r){"use strict";var s=this&&this.__createBinding||(Object.create?function(e,t,r,s){if(s===undefined)s=r;var a=Object.getOwnPropertyDescriptor(t,r);if(!a||("get"in a?!t.__esModule:a.writable||a.configurable)){a={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,s,a)}:function(e,t,r,s){if(s===undefined)s=r;e[s]=t[r]});var a=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var o=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r in e)if(r!=="default"&&Object.prototype.hasOwnProperty.call(e,r))s(t,e,r);a(t,e);return t};var u=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:true});t.Job=t.nodeFileTrace=void 0;const c=r(1017);const f=u(r(7498));const d=o(r(1));const p=r(2540);const h=r(8908);const v=r(1017);const D=r(529);function inPath(e,t){const r=(0,v.join)(t,c.sep);return e.startsWith(r)&&e!==r}async function nodeFileTrace(e,t={}){const r=new Job(t);if(t.readFile)r.readFile=t.readFile;if(t.stat)r.stat=t.stat;if(t.readlink)r.readlink=t.readlink;if(t.resolve)r.resolve=t.resolve;r.ts=true;await Promise.all(e.map((async e=>{const t=(0,c.resolve)(e);await r.emitFile(t,"initial");return r.emitDependency(t)})));const s={fileList:r.fileList,esmFileList:r.esmFileList,reasons:r.reasons,warnings:r.warnings};return s}t.nodeFileTrace=nodeFileTrace;class Job{constructor({base:e=process.cwd(),processCwd:t,exports:r,conditions:s=r||["node"],exportsOnly:a=false,paths:o={},ignore:u,log:f=false,mixedModules:h=false,ts:v=true,analysis:g={},cache:y,fileIOConcurrency:m=1024}){this.reasons=new Map;this.maybeEmitDep=async(e,t,r)=>{let s="";let a;try{s=await this.resolve(e,t,this,r)}catch(o){a=o;try{if(this.ts&&e.endsWith(".js")&&o instanceof d.NotFoundError){const o=e.slice(0,-3)+".ts";s=await this.resolve(o,t,this,r);a=undefined}}catch(e){a=e}}if(a){this.warnings.add(new Error(`Failed to resolve dependency "${e}":\n${a?.message}`));return}if(Array.isArray(s)){for(const e of s){if(e.startsWith("node:"))return;await this.emitDependency(e,t)}}else{if(s.startsWith("node:"))return;await this.emitDependency(s,t)}};this.ts=v;e=(0,c.resolve)(e);this.ignoreFn=e=>{if(e.startsWith(".."+c.sep))return true;return false};if(typeof u==="string")u=[u];if(typeof u==="function"){const e=u;this.ignoreFn=t=>{if(t.startsWith(".."+c.sep))return true;if(e(t))return true;return false}}else if(Array.isArray(u)){const t=u.map((t=>(0,c.relative)(e,(0,c.resolve)(e||process.cwd(),t))));this.ignoreFn=e=>{if(e.startsWith(".."+c.sep))return true;if((0,p.isMatch)(e,t))return true;return false}}this.base=e;this.cwd=(0,c.resolve)(t||e);this.conditions=s;this.exportsOnly=a;const _={};for(const t of Object.keys(o)){const r=o[t].endsWith("/");const s=(0,c.resolve)(e,o[t]);_[t]=s+(r?"/":"")}this.paths=_;this.log=f;this.mixedModules=h;this.cachedFileSystem=new D.CachedFileSystem({cache:y,fileIOConcurrency:m});this.analysis={};if(g!==false){Object.assign(this.analysis,{emitGlobs:true,computeFileReferences:true,evaluatePureExpressions:true},g===true?{}:g)}this.analysisCache=y&&y.analysisCache||new Map;if(y){y.analysisCache=this.analysisCache}this.fileList=new Set;this.esmFileList=new Set;this.processed=new Set;this.warnings=new Set}async readlink(e){return this.cachedFileSystem.readlink(e)}async isFile(e){const t=await this.stat(e);if(t)return t.isFile();return false}async isDir(e){const t=await this.stat(e);if(t)return t.isDirectory();return false}async stat(e){return this.cachedFileSystem.stat(e)}async resolve(e,t,r,s){return(0,d.default)(e,t,r,s)}async readFile(e){return this.cachedFileSystem.readFile(e)}async realpath(e,t,r=new Set){if(r.has(e))throw new Error("Recursive symlink detected resolving "+e);r.add(e);const s=await this.readlink(e);if(s){const a=(0,c.dirname)(e);const o=(0,c.resolve)(a,s);const u=await this.realpath(a,t);if(inPath(e,u))await this.emitFile(e,"resolve",t,true);return this.realpath(o,t,r)}if(!inPath(e,this.base))return e;return(0,v.join)(await this.realpath((0,c.dirname)(e),t,r),(0,c.basename)(e))}async emitFile(e,t,r,s=false){if(!s){e=await this.realpath(e,r)}e=(0,c.relative)(this.base,e);if(r){r=(0,c.relative)(this.base,r)}let a=this.reasons.get(e);if(!a){a={type:[t],ignored:false,parents:new Set};this.reasons.set(e,a)}else if(!a.type.includes(t)){a.type.push(t)}if(r&&this.ignoreFn(e,r)){if(!this.fileList.has(e)&&a){a.ignored=true}return false}if(r){a.parents.add(r)}this.fileList.add(e);return true}async getPjsonBoundary(e){const t=e.indexOf(c.sep);let r;while((r=e.lastIndexOf(c.sep))>t){e=e.slice(0,r);if(await this.isFile(e+c.sep+"package.json"))return e}return undefined}async emitDependency(e,t){if(this.processed.has(e)){if(t){await this.emitFile(e,"dependency",t)}return}this.processed.add(e);const r=await this.emitFile(e,"dependency",t);if(!r)return;if(e.endsWith(".json"))return;if(e.endsWith(".node"))return await(0,h.sharedLibEmit)(e,this);if(e.endsWith(".js")||e.endsWith(".ts")){const t=await this.getPjsonBoundary(e);if(t)await this.emitFile(t+c.sep+"package.json","resolve",e)}let s;const a=this.analysisCache.get(e);if(a){s=a}else{const t=await this.readFile(e);if(t===null)throw new Error("File "+e+" does not exist.");s=await(0,f.default)(e,t.toString(),this);this.analysisCache.set(e,s)}const{deps:o,imports:u,assets:d,isESM:p}=s;if(p){this.esmFileList.add((0,c.relative)(this.base,e))}await Promise.all([...[...d].map((async t=>{const r=(0,c.extname)(t);if(r===".js"||r===".mjs"||r===".node"||r===""||this.ts&&(r===".ts"||r===".tsx")&&t.startsWith(this.base)&&t.slice(this.base.length).indexOf(c.sep+"node_modules"+c.sep)===-1)await this.emitDependency(t,e);else await this.emitFile(t,"asset",e)})),...[...o].map((async t=>this.maybeEmitDep(t,e,!p))),...[...u].map((async t=>this.maybeEmitDep(t,e,false)))])}}t.Job=Job},1:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.NotFoundError=void 0;const s=r(1017);async function resolveDependency(e,t,r,a=true){let o;if((0,s.isAbsolute)(e)||e==="."||e===".."||e.startsWith("./")||e.startsWith("../")){const a=e.endsWith("/");o=await resolvePath((0,s.resolve)(t,"..",e)+(a?"/":""),t,r)}else if(e[0]==="#"){o=await packageImportsResolve(e,t,r,a)}else{o=await resolvePackage(e,t,r,a)}if(Array.isArray(o)){return Promise.all(o.map((e=>r.realpath(e,t))))}else if(o.startsWith("node:")){return o}else{return r.realpath(o,t)}}t["default"]=resolveDependency;async function resolvePath(e,t,r){const s=await resolveFile(e,t,r)||await resolveDir(e,t,r);if(!s){throw new NotFoundError(e,t)}return s}async function resolveFile(e,t,r){if(e.endsWith("/"))return undefined;e=await r.realpath(e,t);if(await r.isFile(e))return e;if(r.ts&&e.startsWith(r.base)&&e.slice(r.base.length).indexOf(s.sep+"node_modules"+s.sep)===-1&&await r.isFile(e+".ts"))return e+".ts";if(r.ts&&e.startsWith(r.base)&&e.slice(r.base.length).indexOf(s.sep+"node_modules"+s.sep)===-1&&await r.isFile(e+".tsx"))return e+".tsx";if(await r.isFile(e+".js"))return e+".js";if(await r.isFile(e+".json"))return e+".json";if(await r.isFile(e+".node"))return e+".node";return undefined}async function resolveDir(e,t,r){if(e.endsWith("/"))e=e.slice(0,-1);if(!await r.isDir(e))return;const a=await getPkgCfg(e,r);if(a&&typeof a.main==="string"){const o=await resolveFile((0,s.resolve)(e,a.main),t,r)||await resolveFile((0,s.resolve)(e,a.main,"index"),t,r);if(o){await r.emitFile(e+s.sep+"package.json","resolve",t);return o}}return resolveFile((0,s.resolve)(e,"index"),t,r)}class NotFoundError extends Error{constructor(e,t){super("Cannot find module '"+e+"' loaded from "+t);this.code="MODULE_NOT_FOUND"}}t.NotFoundError=NotFoundError;const a=new Set([...r(8102)._builtinLibs,"constants","module","timers","console","_stream_writable","_stream_readable","_stream_duplex","process","sys"]);function getPkgName(e){const t=e.split("/");if(e[0]==="@"&&t.length>1)return t.length>1?t.slice(0,2).join("/"):null;return t.length?t[0]:null}async function getPkgCfg(e,t){const r=await t.readFile(e+s.sep+"package.json");if(r){try{return JSON.parse(r.toString())}catch(e){}}return undefined}function getExportsTarget(e,t,r){if(typeof e==="string"){return e}else if(e===null){return e}else if(Array.isArray(e)){for(const s of e){const e=getExportsTarget(s,t,r);if(e===null||typeof e==="string"&&e.startsWith("./"))return e}}else if(typeof e==="object"){for(const s of Object.keys(e)){if(s==="default"||s==="require"&&r||s==="import"&&!r||t.includes(s)){const a=getExportsTarget(e[s],t,r);if(a!==undefined)return a}}}return undefined}function resolveExportsImports(e,t,r,s,a,o){let u;if(a){if(!(typeof t==="object"&&!Array.isArray(t)&&t!==null))return undefined;u=t}else if(typeof t==="string"||Array.isArray(t)||t===null||typeof t==="object"&&Object.keys(t).length&&Object.keys(t)[0][0]!=="."){u={".":t}}else{u=t}if(r in u){const t=getExportsTarget(u[r],s.conditions,o);if(typeof t==="string"&&t.startsWith("./"))return e+t.slice(1)}for(const t of Object.keys(u).sort(((e,t)=>t.length-e.length))){if(t.endsWith("*")&&r.startsWith(t.slice(0,-1))){const a=getExportsTarget(u[t],s.conditions,o);if(typeof a==="string"&&a.startsWith("./"))return e+a.slice(1).replace(/\*/g,r.slice(t.length-1))}if(!t.endsWith("/"))continue;if(r.startsWith(t)){const a=getExportsTarget(u[t],s.conditions,o);if(typeof a==="string"&&a.endsWith("/")&&a.startsWith("./"))return e+a.slice(1)+r.slice(t.length)}}return undefined}async function packageImportsResolve(e,t,r,a){if(e!=="#"&&!e.startsWith("#/")&&r.conditions){const o=await r.getPjsonBoundary(t);if(o){const u=await getPkgCfg(o,r);const{imports:c}=u||{};if(u&&c!==null&&c!==undefined){let u=resolveExportsImports(o,c,e,r,true,a);if(u){if(a)u=await resolveFile(u,t,r)||await resolveDir(u,t,r);else if(!await r.isFile(u))throw new NotFoundError(u,t);if(u){await r.emitFile(o+s.sep+"package.json","resolve",t);return u}}}}}throw new NotFoundError(e,t)}async function resolvePackage(e,t,r,o){let u=t;if(a.has(e))return"node:"+e;if(e.startsWith("node:"))return e;const c=getPkgName(e)||"";let f;if(r.conditions){const a=await r.getPjsonBoundary(t);if(a){const u=await getPkgCfg(a,r);const{exports:d}=u||{};if(u&&u.name&&u.name===c&&d!==null&&d!==undefined){f=resolveExportsImports(a,d,"."+e.slice(c.length),r,false,o);if(f){if(o)f=await resolveFile(f,t,r)||await resolveDir(f,t,r);else if(!await r.isFile(f))throw new NotFoundError(f,t)}if(f)await r.emitFile(a+s.sep+"package.json","resolve",t)}}}let d;const p=u.indexOf(s.sep);while((d=u.lastIndexOf(s.sep))>p){u=u.slice(0,d);const a=u+s.sep+"node_modules";const p=await r.stat(a);if(!p||!p.isDirectory())continue;const h=await getPkgCfg(a+s.sep+c,r);const{exports:v}=h||{};if(r.conditions&&v!==undefined&&v!==null&&!f){let u;if(!r.exportsOnly)u=await resolveFile(a+s.sep+e,t,r)||await resolveDir(a+s.sep+e,t,r);let f=resolveExportsImports(a+s.sep+c,v,"."+e.slice(c.length),r,false,o);if(f){if(o)f=await resolveFile(f,t,r)||await resolveDir(f,t,r);else if(!await r.isFile(f))throw new NotFoundError(f,t)}if(f){await r.emitFile(a+s.sep+c+s.sep+"package.json","resolve",t);if(u&&u!==f)return[f,u];return f}if(u)return u}else{const o=await resolveFile(a+s.sep+e,t,r)||await resolveDir(a+s.sep+e,t,r);if(o){if(f&&f!==o)return[o,f];return o}}}if(f)return f;if(Object.hasOwnProperty.call(r.paths,e)){return r.paths[e]}for(const s of Object.keys(r.paths)){if(s.endsWith("/")&&e.startsWith(s)){const a=r.paths[s]+e.slice(s.length);const o=await resolveFile(a,t,r)||await resolveDir(a,t,r);if(!o){throw new NotFoundError(e,t)}return o}}throw new NotFoundError(e,t)}},8470:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true})},9336:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.isLoop=t.isVarLoop=t.isIdentifierRead=void 0;function isIdentifierRead(e,t){switch(t.type){case"ObjectPattern":case"ArrayPattern":return false;case"AssignmentExpression":return t.right===e;case"MemberExpression":return t.computed||e===t.object;case"Property":return e===t.value;case"MethodDefinition":return false;case"VariableDeclarator":return t.id!==e;case"ExportSpecifier":return false;case"FunctionExpression":case"FunctionDeclaration":case"ArrowFunctionExpression":return false;default:return true}}t.isIdentifierRead=isIdentifierRead;function isVarLoop(e){return e.type==="ForStatement"||e.type==="ForInStatement"||e.type==="ForOfStatement"}t.isVarLoop=isVarLoop;function isLoop(e){return e.type==="ForStatement"||e.type==="ForInStatement"||e.type==="ForOfStatement"||e.type==="WhileStatement"||e.type==="DoWhileStatement"}t.isLoop=isLoop},2100:function(__unused_webpack_module,exports,__nccwpck_require__){"use strict";var __importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:true});exports.nbind=exports.pregyp=void 0;const path_1=__importDefault(__nccwpck_require__(1017));const graceful_fs_1=__importDefault(__nccwpck_require__(9165));const versioning=__nccwpck_require__(2821);const napi=__nccwpck_require__(5977);const pregypFind=(e,t)=>{const r=JSON.parse(graceful_fs_1.default.readFileSync(e).toString());versioning.validate_config(r,t);var s;if(napi.get_napi_build_versions(r,t)){s=napi.get_best_napi_build_version(r,t)}t=t||{};if(!t.module_root)t.module_root=path_1.default.dirname(e);var a=versioning.evaluate(r,t,s);return a.module};exports.pregyp={default:{find:pregypFind},find:pregypFind};function makeModulePathList(e,t){return[[e,t],[e,"build",t],[e,"build","Debug",t],[e,"build","Release",t],[e,"out","Debug",t],[e,"Debug",t],[e,"out","Release",t],[e,"Release",t],[e,"build","default",t],[e,process.env["NODE_BINDINGS_COMPILED_DIR"]||"compiled",process.versions.node,process.platform,process.arch,t]]}function findCompiledModule(basePath,specList){var resolvedList=[];var ext=path_1.default.extname(basePath);for(var _i=0,specList_1=specList;_i{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.getPackageName=t.getPackageBase=void 0;const r=/^(@[^\\\/]+[\\\/])?[^\\\/]+/;function getPackageBase(e){const t=e.lastIndexOf("node_modules");if(t!==-1&&(e[t-1]==="/"||e[t-1]==="\\")&&(e[t+12]==="/"||e[t+12]==="\\")){const s=e.slice(t+13).match(r);if(s)return e.slice(0,t+13+s[0].length)}return undefined}t.getPackageBase=getPackageBase;function getPackageName(e){const t=e.lastIndexOf("node_modules");if(t!==-1&&(e[t-1]==="/"||e[t-1]==="\\")&&(e[t+12]==="/"||e[t+12]==="\\")){const s=e.slice(t+13).match(r);if(s&&s.length>0){return s[0].replace(/\\/g,"/")}}return undefined}t.getPackageName=getPackageName},7393:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.normalizeWildcardRequire=t.normalizeDefaultRequire=void 0;function normalizeDefaultRequire(e){if(e&&e.__esModule)return e;return{default:e}}t.normalizeDefaultRequire=normalizeDefaultRequire;const r=Object.prototype.hasOwnProperty;function normalizeWildcardRequire(e){if(e&&e.__esModule)return e;const t={};for(const s in e){if(!r.call(e,s))continue;t[s]=e[s]}t["default"]=e;return t}t.normalizeWildcardRequire=normalizeWildcardRequire},8908:function(e,t,r){"use strict";var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:true});t.sharedLibEmit=void 0;const a=s(r(2037));const o=s(r(3535));const u=r(1226);let c="";switch(a.default.platform()){case"darwin":c="/**/*.@(dylib|so?(.*))";break;case"win32":c="/**/*.dll";break;default:c="/**/*.so?(.*)"}async function sharedLibEmit(e,t){const r=(0,u.getPackageBase)(e);if(!r)return;const s=await new Promise(((e,t)=>(0,o.default)(r+c,{ignore:r+"/**/node_modules/**/*"},((r,s)=>r?t(r):e(s)))));await Promise.all(s.map((r=>t.emitFile(r,"sharedlib",e))))}t.sharedLibEmit=sharedLibEmit},1415:function(e,t,r){"use strict";var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:true});const a=r(1017);const o=s(r(1));const u=r(1226);const c=r(9165);const f={"@generated/photon"({id:e,emitAssetDirectory:t}){if(e.endsWith("@generated/photon/index.js")){t((0,a.resolve)((0,a.dirname)(e),"runtime/"))}},argon2({id:e,emitAssetDirectory:t}){if(e.endsWith("argon2/argon2.js")){t((0,a.resolve)((0,a.dirname)(e),"build","Release"));t((0,a.resolve)((0,a.dirname)(e),"prebuilds"));t((0,a.resolve)((0,a.dirname)(e),"lib","binding"))}},bull({id:e,emitAssetDirectory:t}){if(e.endsWith("bull/lib/commands/index.js")){t((0,a.resolve)((0,a.dirname)(e)))}},camaro({id:e,emitAsset:t}){if(e.endsWith("camaro/dist/camaro.js")){t((0,a.resolve)((0,a.dirname)(e),"camaro.wasm"))}},esbuild({id:e,emitAssetDirectory:t}){if(e.endsWith("esbuild/lib/main.js")){const r=(0,a.resolve)(e,"..","..","package.json");const s=JSON.parse((0,c.readFileSync)(r,"utf8"));for(const r of Object.keys(s.optionalDependencies||{})){const s=(0,a.resolve)(e,"..","..","..",r);t(s)}}},"google-gax"({id:e,ast:t,emitAssetDirectory:r}){if(e.endsWith("google-gax/build/src/grpc.js")){for(const s of t.body){if(s.type==="VariableDeclaration"&&s.declarations[0].id.type==="Identifier"&&s.declarations[0].id.name==="googleProtoFilesDir"){r((0,a.resolve)((0,a.dirname)(e),"../../../google-proto-files"))}}}},oracledb({id:e,ast:t,emitAsset:r}){if(e.endsWith("oracledb/lib/oracledb.js")){for(const s of t.body){if(s.type==="ForStatement"&&"body"in s.body&&s.body.body&&Array.isArray(s.body.body)&&s.body.body[0]&&s.body.body[0].type==="TryStatement"&&s.body.body[0].block.body[0]&&s.body.body[0].block.body[0].type==="ExpressionStatement"&&s.body.body[0].block.body[0].expression.type==="AssignmentExpression"&&s.body.body[0].block.body[0].expression.operator==="="&&s.body.body[0].block.body[0].expression.left.type==="Identifier"&&s.body.body[0].block.body[0].expression.left.name==="oracledbCLib"&&s.body.body[0].block.body[0].expression.right.type==="CallExpression"&&s.body.body[0].block.body[0].expression.right.callee.type==="Identifier"&&s.body.body[0].block.body[0].expression.right.callee.name==="require"&&s.body.body[0].block.body[0].expression.right.arguments.length===1&&s.body.body[0].block.body[0].expression.right.arguments[0].type==="MemberExpression"&&s.body.body[0].block.body[0].expression.right.arguments[0].computed===true&&s.body.body[0].block.body[0].expression.right.arguments[0].object.type==="Identifier"&&s.body.body[0].block.body[0].expression.right.arguments[0].object.name==="binaryLocations"&&s.body.body[0].block.body[0].expression.right.arguments[0].property.type==="Identifier"&&s.body.body[0].block.body[0].expression.right.arguments[0].property.name==="i"){s.body.body[0].block.body[0].expression.right.arguments=[{type:"Literal",value:"_"}];const t=global._unit?"3.0.0":JSON.parse((0,c.readFileSync)(e.slice(0,-15)+"package.json","utf8")).version;const o=Number(t.slice(0,t.indexOf(".")))>=4;const u="oracledb-"+(o?t:"abi"+process.versions.modules)+"-"+process.platform+"-"+process.arch+".node";r((0,a.resolve)(e,"../../build/Release/"+u))}}}},"phantomjs-prebuilt"({id:e,emitAssetDirectory:t}){if(e.endsWith("phantomjs-prebuilt/lib/phantomjs.js")){t((0,a.resolve)((0,a.dirname)(e),"..","bin"))}},"remark-prism"({id:e,emitAssetDirectory:t}){const r="remark-prism/src/highlight.js";if(e.endsWith(r)){try{const s=e.slice(0,-r.length);t((0,a.resolve)(s,"prismjs","components"))}catch(e){}}},semver({id:e,emitAsset:t}){if(e.endsWith("semver/index.js")){t((0,a.resolve)(e.replace("index.js","preload.js")))}},"socket.io":async function({id:e,ast:t,job:r}){if(e.endsWith("socket.io/lib/index.js")){async function replaceResolvePathStatement(t){if(t.type==="ExpressionStatement"&&t.expression.type==="AssignmentExpression"&&t.expression.operator==="="&&t.expression.right.type==="CallExpression"&&t.expression.right.callee.type==="Identifier"&&t.expression.right.callee.name==="read"&&t.expression.right.arguments.length>=1&&t.expression.right.arguments[0].type==="CallExpression"&&t.expression.right.arguments[0].callee.type==="Identifier"&&t.expression.right.arguments[0].callee.name==="resolvePath"&&t.expression.right.arguments[0].arguments.length===1&&t.expression.right.arguments[0].arguments[0].type==="Literal"){const s=t.expression.right.arguments[0].arguments[0].value;let u;try{const t=await(0,o.default)(String(s),e,r);if(typeof t==="string"){u=t}else{return undefined}}catch(e){return undefined}const c="/"+(0,a.relative)((0,a.dirname)(e),u);t.expression.right.arguments[0]={type:"BinaryExpression",start:t.expression.right.arguments[0].start,end:t.expression.right.arguments[0].end,operator:"+",left:{type:"Identifier",name:"__dirname"},right:{type:"Literal",value:c,raw:JSON.stringify(c)}}}return undefined}for(const e of t.body){if(e.type==="ExpressionStatement"&&e.expression.type==="AssignmentExpression"&&e.expression.operator==="="&&e.expression.left.type==="MemberExpression"&&e.expression.left.object.type==="MemberExpression"&&e.expression.left.object.object.type==="Identifier"&&e.expression.left.object.object.name==="Server"&&e.expression.left.object.property.type==="Identifier"&&e.expression.left.object.property.name==="prototype"&&e.expression.left.property.type==="Identifier"&&e.expression.left.property.name==="serveClient"&&e.expression.right.type==="FunctionExpression"){for(const t of e.expression.right.body.body){if(t.type==="IfStatement"&&t.consequent&&"body"in t.consequent&&t.consequent.body){const e=t.consequent.body;let r=false;if(Array.isArray(e)&&e[0]&&e[0].type==="ExpressionStatement"){r=await replaceResolvePathStatement(e[0])}if(Array.isArray(e)&&e[1]&&e[1].type==="TryStatement"&&e[1].block.body&&e[1].block.body[0]){r=await replaceResolvePathStatement(e[1].block.body[0])||r}return}}}}}},typescript({id:e,emitAssetDirectory:t}){if(e.endsWith("typescript/lib/tsc.js")){t((0,a.resolve)(e,"../"))}},"uglify-es"({id:e,emitAsset:t}){if(e.endsWith("uglify-es/tools/node.js")){t((0,a.resolve)(e,"../../lib/utils.js"));t((0,a.resolve)(e,"../../lib/ast.js"));t((0,a.resolve)(e,"../../lib/parse.js"));t((0,a.resolve)(e,"../../lib/transform.js"));t((0,a.resolve)(e,"../../lib/scope.js"));t((0,a.resolve)(e,"../../lib/output.js"));t((0,a.resolve)(e,"../../lib/compress.js"));t((0,a.resolve)(e,"../../lib/sourcemap.js"));t((0,a.resolve)(e,"../../lib/mozilla-ast.js"));t((0,a.resolve)(e,"../../lib/propmangle.js"));t((0,a.resolve)(e,"../../lib/minify.js"));t((0,a.resolve)(e,"../exports.js"))}},"uglify-js"({id:e,emitAsset:t,emitAssetDirectory:r}){if(e.endsWith("uglify-js/tools/node.js")){r((0,a.resolve)(e,"../../lib"));t((0,a.resolve)(e,"../exports.js"))}},"playwright-core"({id:e,emitAsset:t}){if(e.endsWith("playwright-core/index.js")){t((0,a.resolve)((0,a.dirname)(e),"browsers.json"))}},"geo-tz"({id:e,emitAsset:t}){if(e.endsWith("geo-tz/dist/geo-tz.js")){t((0,a.resolve)((0,a.dirname)(e),"../data/geo.dat"))}},pixelmatch({id:e,emitDependency:t}){if(e.endsWith("pixelmatch/index.js")){t((0,a.resolve)((0,a.dirname)(e),"bin/pixelmatch"))}}};async function handleSpecialCases({id:e,ast:t,emitDependency:r,emitAsset:s,emitAssetDirectory:a,job:o}){const c=(0,u.getPackageName)(e);const d=f[c||""];e=e.replace(/\\/g,"/");if(d)await d({id:e,ast:t,emitDependency:r,emitAsset:s,emitAssetDirectory:a,job:o})}t["default"]=handleSpecialCases},4370:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.wildcardRegEx=t.WILDCARD=t.FUNCTION=t.UNKNOWN=t.evaluate=void 0;const s=r(7310);async function evaluate(e,t={},r=true){const s={computeBranches:r,vars:t};return walk(e);function walk(e){const t=a[e.type];if(t){return t.call(s,e,walk)}return undefined}}t.evaluate=evaluate;t.UNKNOWN=Symbol();t.FUNCTION=Symbol();t.WILDCARD="";t.wildcardRegEx=/\x1a/g;function countWildcards(e){t.wildcardRegEx.lastIndex=0;let r=0;while(t.wildcardRegEx.exec(e))r++;return r}const a={ArrayExpression:async function ArrayExpression(e,t){const r=[];for(let s=0,a=e.elements.length;ss.value}}}return undefined},BinaryExpression:async function BinaryExpression(e,r){const s=e.operator;let a=await r(e.left);if(!a&&s!=="+")return;let o=await r(e.right);if(!a&&!o)return;if(!a){if(this.computeBranches&&o&&"value"in o&&typeof o.value==="string")return{value:t.WILDCARD+o.value,wildcards:[e.left,...o.wildcards||[]]};return}if(!o){if(this.computeBranches&&s==="+"){if(a&&"value"in a&&typeof a.value==="string")return{value:a.value+t.WILDCARD,wildcards:[...a.wildcards||[],e.right]}}if(!("test"in a)&&s==="||"&&a.value)return a;return}if("test"in a&&"value"in o){const e=o.value;if(s==="==")return{test:a.test,then:a.then==e,else:a.else==e};if(s==="===")return{test:a.test,then:a.then===e,else:a.else===e};if(s==="!=")return{test:a.test,then:a.then!=e,else:a.else!=e};if(s==="!==")return{test:a.test,then:a.then!==e,else:a.else!==e};if(s==="+")return{test:a.test,then:a.then+e,else:a.else+e};if(s==="-")return{test:a.test,then:a.then-e,else:a.else-e};if(s==="*")return{test:a.test,then:a.then*e,else:a.else*e};if(s==="/")return{test:a.test,then:a.then/e,else:a.else/e};if(s==="%")return{test:a.test,then:a.then%e,else:a.else%e};if(s==="<")return{test:a.test,then:a.then")return{test:a.test,then:a.then>e,else:a.else>e};if(s===">=")return{test:a.test,then:a.then>=e,else:a.else>=e};if(s==="|")return{test:a.test,then:a.then|e,else:a.else|e};if(s==="&")return{test:a.test,then:a.then&e,else:a.else&e};if(s==="^")return{test:a.test,then:a.then^e,else:a.else^e};if(s==="&&")return{test:a.test,then:a.then&&e,else:a.else&&e};if(s==="||")return{test:a.test,then:a.then||e,else:a.else||e}}else if("test"in o&&"value"in a){const e=a.value;if(s==="==")return{test:o.test,then:e==o.then,else:e==o.else};if(s==="===")return{test:o.test,then:e===o.then,else:e===o.else};if(s==="!=")return{test:o.test,then:e!=o.then,else:e!=o.else};if(s==="!==")return{test:o.test,then:e!==o.then,else:e!==o.else};if(s==="+")return{test:o.test,then:e+o.then,else:e+o.else};if(s==="-")return{test:o.test,then:e-o.then,else:e-o.else};if(s==="*")return{test:o.test,then:e*o.then,else:e*o.else};if(s==="/")return{test:o.test,then:e/o.then,else:e/o.else};if(s==="%")return{test:o.test,then:e%o.then,else:e%o.else};if(s==="<")return{test:o.test,then:e")return{test:o.test,then:e>o.then,else:e>o.else};if(s===">=")return{test:o.test,then:e>=o.then,else:e>=o.else};if(s==="|")return{test:o.test,then:e|o.then,else:e|o.else};if(s==="&")return{test:o.test,then:e&o.then,else:e&o.else};if(s==="^")return{test:o.test,then:e^o.then,else:e^o.else};if(s==="&&")return{test:o.test,then:e&&o.then,else:a&&o.else};if(s==="||")return{test:o.test,then:e||o.then,else:a||o.else}}else if("value"in a&&"value"in o){if(s==="==")return{value:a.value==o.value};if(s==="===")return{value:a.value===o.value};if(s==="!=")return{value:a.value!=o.value};if(s==="!==")return{value:a.value!==o.value};if(s==="+"){const e={value:a.value+o.value};let t=[];if("wildcards"in a&&a.wildcards){t=t.concat(a.wildcards)}if("wildcards"in o&&o.wildcards){t=t.concat(o.wildcards)}if(t.length>0){e.wildcards=t}return e}if(s==="-")return{value:a.value-o.value};if(s==="*")return{value:a.value*o.value};if(s==="/")return{value:a.value/o.value};if(s==="%")return{value:a.value%o.value};if(s==="<")return{value:a.value")return{value:a.value>o.value};if(s===">=")return{value:a.value>=o.value};if(s==="|")return{value:a.value|o.value};if(s==="&")return{value:a.value&o.value};if(s==="^")return{value:a.value^o.value};if(s==="&&")return{value:a.value&&o.value};if(s==="||")return{value:a.value||o.value}}return},CallExpression:async function CallExpression(e,r){const s=await r(e.callee);if(!s||"test"in s)return;let a=s.value;if(typeof a==="object"&&a!==null)a=a[t.FUNCTION];if(typeof a!=="function")return;let o=null;if(e.callee.object){o=await r(e.callee.object);o=o&&"value"in o&&o.value?o.value:null}let u;let c=[];let f;let d=e.arguments.length>0&&e.callee.property?.name!=="concat";const p=[];for(let s=0,a=e.arguments.length;sp.push(e)))}else{if(!this.computeBranches)return;a={value:t.WILDCARD};p.push(e.arguments[s])}if("test"in a){if(p.length)return;if(u)return;u=a.test;f=c.concat([]);c.push(a.then);f.push(a.else)}else{c.push(a.value);if(f)f.push(a.value)}}if(d)return;try{const e=await a.apply(o,c);if(e===t.UNKNOWN)return;if(!u){if(p.length){if(typeof e!=="string"||countWildcards(e)!==p.length)return;return{value:e,wildcards:p}}return{value:e}}const r=await a.apply(o,f);if(e===t.UNKNOWN)return;return{test:u,then:e,else:r}}catch(e){return}},ConditionalExpression:async function ConditionalExpression(e,t){const r=await t(e.test);if(r&&"value"in r)return r.value?t(e.consequent):t(e.alternate);if(!this.computeBranches)return;const s=await t(e.consequent);if(!s||"wildcards"in s||"test"in s)return;const a=await t(e.alternate);if(!a||"wildcards"in a||"test"in a)return;return{test:e.test,then:s.value,else:a.value}},ExpressionStatement:async function ExpressionStatement(e,t){return t(e.expression)},Identifier:async function Identifier(e,t){if(Object.hasOwnProperty.call(this.vars,e.name))return this.vars[e.name];return undefined},Literal:async function Literal(e,t){return{value:e.value}},MemberExpression:async function MemberExpression(e,r){const s=await r(e.object);if(!s||"test"in s||typeof s.value==="function"){return undefined}if(e.property.type==="Identifier"){if(typeof s.value==="string"&&e.property.name==="concat"){return{value:{[t.FUNCTION]:(...e)=>s.value.concat(e)}}}if(typeof s.value==="object"&&s.value!==null){const a=s.value;if(e.computed){const o=await r(e.property);if(o&&"value"in o&&o.value){const e=a[o.value];if(e===t.UNKNOWN)return undefined;return{value:e}}if(!a[t.UNKNOWN]&&Object.keys(s).length===0){return{value:undefined}}}else if(e.property.name in a){const r=a[e.property.name];if(r===t.UNKNOWN)return undefined;return{value:r}}else if(a[t.UNKNOWN])return undefined}else{return{value:undefined}}}const a=await r(e.property);if(!a||"test"in a)return undefined;if(typeof s.value==="object"&&s.value!==null){if(a.value in s.value){const e=s.value[a.value];if(e===t.UNKNOWN)return undefined;return{value:e}}else if(s.value[t.UNKNOWN]){return undefined}}else{return{value:undefined}}return undefined},MetaProperty:async function MetaProperty(e){if(e.meta.name==="import"&&e.property.name==="meta")return{value:this.vars["import.meta"]};return undefined},NewExpression:async function NewExpression(e,t){const r=await t(e.callee);if(r&&"value"in r&&r.value===s.URL&&e.arguments.length){const r=await t(e.arguments[0]);if(!r)return undefined;let a=null;if(e.arguments[1]){a=await t(e.arguments[1]);if(!a||!("value"in a))return undefined}if("value"in r){if(a){try{return{value:new s.URL(r.value,a.value)}}catch{return undefined}}try{return{value:new s.URL(r.value)}}catch{return undefined}}else{const e=r.test;if(a){try{return{test:e,then:new s.URL(r.then,a.value),else:new s.URL(r.else,a.value)}}catch{return undefined}}try{return{test:e,then:new s.URL(r.then),else:new s.URL(r.else)}}catch{return undefined}}}return undefined},ObjectExpression:async function ObjectExpression(e,r){const s={};for(let a=0;a{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.handleWrappers=void 0;const s=r(3982);function isUndefinedOrVoid(e){return e.type==="Identifier"&&e.name==="undefined"||e.type==="UnaryExpression"&&e.operator==="void"&&e.argument.type==="Literal"&&e.argument.value===0}function handleWrappers(e){let t;if(e.body.length===1&&e.body[0].type==="ExpressionStatement"&&e.body[0].expression.type==="UnaryExpression"&&e.body[0].expression.operator==="!"&&e.body[0].expression.argument.type==="CallExpression"&&e.body[0].expression.argument.callee.type==="FunctionExpression"&&e.body[0].expression.argument.arguments.length===1)t=e.body[0].expression.argument;else if(e.body.length===1&&e.body[0].type==="ExpressionStatement"&&e.body[0].expression.type==="CallExpression"&&e.body[0].expression.callee.type==="FunctionExpression"&&(e.body[0].expression.arguments.length===1||e.body[0].expression.arguments.length===0))t=e.body[0].expression;else if(e.body.length===1&&e.body[0].type==="ExpressionStatement"&&e.body[0].expression.type==="AssignmentExpression"&&e.body[0].expression.left.type==="MemberExpression"&&e.body[0].expression.left.object.type==="Identifier"&&e.body[0].expression.left.object.name==="module"&&e.body[0].expression.left.property.type==="Identifier"&&e.body[0].expression.left.property.name==="exports"&&e.body[0].expression.right.type==="CallExpression"&&e.body[0].expression.right.callee.type==="FunctionExpression"&&e.body[0].expression.right.arguments.length===1)t=e.body[0].expression.right;if(t){let e;let r;if(t.arguments[0]&&t.arguments[0].type==="ConditionalExpression"&&t.arguments[0].test.type==="LogicalExpression"&&t.arguments[0].test.operator==="&&"&&t.arguments[0].test.left.type==="BinaryExpression"&&t.arguments[0].test.left.operator==="==="&&t.arguments[0].test.left.left.type==="UnaryExpression"&&t.arguments[0].test.left.left.operator==="typeof"&&"name"in t.arguments[0].test.left.left.argument&&t.arguments[0].test.left.left.argument.name==="define"&&t.arguments[0].test.left.right.type==="Literal"&&t.arguments[0].test.left.right.value==="function"&&t.arguments[0].test.right.type==="MemberExpression"&&t.arguments[0].test.right.object.type==="Identifier"&&t.arguments[0].test.right.property.type==="Identifier"&&t.arguments[0].test.right.property.name==="amd"&&t.arguments[0].test.right.computed===false&&t.arguments[0].alternate.type==="FunctionExpression"&&t.arguments[0].alternate.params.length===1&&t.arguments[0].alternate.params[0].type==="Identifier"&&t.arguments[0].alternate.body.body.length===1&&t.arguments[0].alternate.body.body[0].type==="ExpressionStatement"&&t.arguments[0].alternate.body.body[0].expression.type==="AssignmentExpression"&&t.arguments[0].alternate.body.body[0].expression.left.type==="MemberExpression"&&t.arguments[0].alternate.body.body[0].expression.left.object.type==="Identifier"&&t.arguments[0].alternate.body.body[0].expression.left.object.name==="module"&&t.arguments[0].alternate.body.body[0].expression.left.property.type==="Identifier"&&t.arguments[0].alternate.body.body[0].expression.left.property.name==="exports"&&t.arguments[0].alternate.body.body[0].expression.left.computed===false&&t.arguments[0].alternate.body.body[0].expression.right.type==="CallExpression"&&t.arguments[0].alternate.body.body[0].expression.right.callee.type==="Identifier"&&t.arguments[0].alternate.body.body[0].expression.right.callee.name===t.arguments[0].alternate.params[0].name&&"body"in t.callee&&"body"in t.callee.body&&Array.isArray(t.callee.body.body)&&t.arguments[0].alternate.body.body[0].expression.right.arguments.length===1&&t.arguments[0].alternate.body.body[0].expression.right.arguments[0].type==="Identifier"&&t.arguments[0].alternate.body.body[0].expression.right.arguments[0].name==="require"){let e=t.callee.body.body;if(e[0].type==="ExpressionStatement"&&e[0].expression.type==="Literal"&&e[0].expression.value==="use strict"){e=e.slice(1)}if(e.length===1&&e[0].type==="ExpressionStatement"&&e[0].expression.type==="CallExpression"&&e[0].expression.callee.type==="Identifier"&&e[0].expression.callee.name===t.arguments[0].test.right.object.name&&e[0].expression.arguments.length===1&&e[0].expression.arguments[0].type==="FunctionExpression"&&e[0].expression.arguments[0].params.length===1&&e[0].expression.arguments[0].params[0].type==="Identifier"&&e[0].expression.arguments[0].params[0].name==="require"){const t=e[0].expression.arguments[0];t.params=[];try{delete t.scope.declarations.require}catch(e){}}}else if(t.arguments[0]&&t.arguments[0].type==="FunctionExpression"&&t.arguments[0].params.length===0&&(t.arguments[0].body.body.length===1||t.arguments[0].body.body.length===2&&t.arguments[0].body.body[0].type==="VariableDeclaration"&&t.arguments[0].body.body[0].declarations.length===3&&t.arguments[0].body.body[0].declarations.every((e=>e.init===null&&e.id.type==="Identifier")))&&t.arguments[0].body.body[t.arguments[0].body.body.length-1].type==="ReturnStatement"&&(e=t.arguments[0].body.body[t.arguments[0].body.body.length-1])&&e.argument?.type==="CallExpression"&&e.argument.arguments.length&&e.argument.arguments.every((e=>e&&e.type==="Literal"&&typeof e.value==="number"))&&e.argument.callee.type==="CallExpression"&&(e.argument.callee.callee.type==="FunctionExpression"||e.argument.callee.callee.type==="CallExpression"&&e.argument.callee.callee.callee.type==="FunctionExpression"&&e.argument.callee.callee.arguments.length===0)&&e.argument.callee.arguments.length===3&&e.argument.callee.arguments[0].type==="ObjectExpression"&&e.argument.callee.arguments[1].type==="ObjectExpression"&&e.argument.callee.arguments[2].type==="ArrayExpression"){const t=e.argument.callee.arguments[0].properties;const r={};if(t.every((e=>{if(e.type!=="Property"||e.computed!==false||e.key.type!=="Literal"||typeof e.key.value!=="number"||e.value.type!=="ArrayExpression"||e.value.elements.length!==2||!e.value.elements[0]||!e.value.elements[1]||e.value.elements[0].type!=="FunctionExpression"||e.value.elements[1].type!=="ObjectExpression"){return false}const t=e.value.elements[1].properties;for(const e of t){if(e.type!=="Property"||e.value.type!=="Identifier"&&e.value.type!=="Literal"&&!isUndefinedOrVoid(e.value)||!(e.key.type==="Literal"&&typeof e.key.value==="string"||e.key.type==="Identifier")||e.computed){return false}if(isUndefinedOrVoid(e.value)){if(e.key.type==="Identifier"){r[e.key.name]={type:"Literal",start:e.key.start,end:e.key.end,value:e.key.name,raw:JSON.stringify(e.key.name)}}else if(e.key.type==="Literal"){r[String(e.key.value)]=e.key}}}return true}))){const t=Object.keys(r);const s=e.argument.callee.arguments[1];s.properties=t.map((e=>({type:"Property",method:false,shorthand:false,computed:false,kind:"init",key:r[e],value:{type:"ObjectExpression",properties:[{type:"Property",kind:"init",method:false,shorthand:false,computed:false,key:{type:"Identifier",name:"exports"},value:{type:"CallExpression",optional:false,callee:{type:"Identifier",name:"require"},arguments:[r[e]]}}]}})))}}else if(t.arguments[0]&&t.arguments[0].type==="FunctionExpression"&&t.arguments[0].params.length===2&&t.arguments[0].params[0].type==="Identifier"&&t.arguments[0].params[1].type==="Identifier"&&"body"in t.callee&&"body"in t.callee.body&&Array.isArray(t.callee.body.body)&&t.callee.body.body.length===1){const e=t.callee.body.body[0];if(e.type==="IfStatement"&&e.test.type==="LogicalExpression"&&e.test.operator==="&&"&&e.test.left.type==="BinaryExpression"&&e.test.left.left.type==="UnaryExpression"&&e.test.left.left.operator==="typeof"&&e.test.left.left.argument.type==="Identifier"&&e.test.left.left.argument.name==="module"&&e.test.left.right.type==="Literal"&&e.test.left.right.value==="object"&&e.test.right.type==="BinaryExpression"&&e.test.right.left.type==="UnaryExpression"&&e.test.right.left.operator==="typeof"&&e.test.right.left.argument.type==="MemberExpression"&&e.test.right.left.argument.object.type==="Identifier"&&e.test.right.left.argument.object.name==="module"&&e.test.right.left.argument.property.type==="Identifier"&&e.test.right.left.argument.property.name==="exports"&&e.test.right.right.type==="Literal"&&e.test.right.right.value==="object"&&e.consequent.type==="BlockStatement"&&e.consequent.body.length>0){let r;if(e.consequent.body[0].type==="VariableDeclaration"&&e.consequent.body[0].declarations[0].init&&e.consequent.body[0].declarations[0].init.type==="CallExpression")r=e.consequent.body[0].declarations[0].init;else if(e.consequent.body[0].type==="ExpressionStatement"&&e.consequent.body[0].expression.type==="CallExpression")r=e.consequent.body[0].expression;else if(e.consequent.body[0].type==="ExpressionStatement"&&e.consequent.body[0].expression.type==="AssignmentExpression"&&e.consequent.body[0].expression.operator==="="&&e.consequent.body[0].expression.right.type==="CallExpression")r=e.consequent.body[0].expression.right;if(r&&r.callee.type==="Identifier"&&"params"in t.callee&&t.callee.params.length>0&&"name"in t.callee.params[0]&&r.callee.name===t.callee.params[0].name&&r.arguments.length===2&&r.arguments[0].type==="Identifier"&&r.arguments[0].name==="require"&&r.arguments[1].type==="Identifier"&&r.arguments[1].name==="exports"){const e=t.arguments[0];e.params=[];try{const t=e.scope;delete t.declarations.require;delete t.declarations.exports}catch(e){}}}}else if(t.callee.type==="FunctionExpression"&&t.callee.body.body.length>2&&t.callee.body.body[0].type==="VariableDeclaration"&&t.callee.body.body[0].declarations.length===1&&t.callee.body.body[0].declarations[0].type==="VariableDeclarator"&&t.callee.body.body[0].declarations[0].id.type==="Identifier"&&t.callee.body.body[0].declarations[0].init&&(t.callee.body.body[0].declarations[0].init.type==="ObjectExpression"&&t.callee.body.body[0].declarations[0].init.properties.length===0||t.callee.body.body[0].declarations[0].init.type==="CallExpression"&&t.callee.body.body[0].declarations[0].init.arguments.length===1)&&(t.callee.body.body[1]&&t.callee.body.body[1].type==="FunctionDeclaration"&&t.callee.body.body[1].params.length===1&&t.callee.body.body[1].body.body.length>=3||t.callee.body.body[2]&&t.callee.body.body[2].type==="FunctionDeclaration"&&t.callee.body.body[2].params.length===1&&t.callee.body.body[2].body.body.length>=3)&&(t.arguments[0]&&(t.arguments[0].type==="ArrayExpression"&&(r=t.arguments[0])&&t.arguments[0].elements.length>0&&t.arguments[0].elements.every((e=>e&&e.type==="FunctionExpression"))||t.arguments[0].type==="ObjectExpression"&&(r=t.arguments[0])&&t.arguments[0].properties&&t.arguments[0].properties.length>0&&t.arguments[0].properties.every((e=>e&&e.type==="Property"&&!e.computed&&e.key&&e.key.type==="Literal"&&(typeof e.key.value==="string"||typeof e.key.value==="number")&&e.value&&e.value.type==="FunctionExpression"))))||t.arguments.length===0&&t.callee.type==="FunctionExpression"&&t.callee.params.length===0&&t.callee.body.type==="BlockStatement"&&t.callee.body.body.length>5&&t.callee.body.body[0].type==="VariableDeclaration"&&t.callee.body.body[0].declarations.length===1&&t.callee.body.body[0].declarations[0].id.type==="Identifier"&&t.callee.body.body[1].type==="ExpressionStatement"&&t.callee.body.body[1].expression.type==="AssignmentExpression"&&t.callee.body.body[2].type==="ExpressionStatement"&&t.callee.body.body[2].expression.type==="AssignmentExpression"&&t.callee.body.body[3].type==="ExpressionStatement"&&t.callee.body.body[3].expression.type==="AssignmentExpression"&&t.callee.body.body[3].expression.left.type==="MemberExpression"&&t.callee.body.body[3].expression.left.object.type==="Identifier"&&t.callee.body.body[3].expression.left.object.name===t.callee.body.body[0].declarations[0].id.name&&t.callee.body.body[3].expression.left.property.type==="Identifier"&&t.callee.body.body[3].expression.left.property.name==="modules"&&t.callee.body.body[3].expression.right.type==="ObjectExpression"&&t.callee.body.body[3].expression.right.properties.every((e=>e&&e.type==="Property"&&!e.computed&&e.key&&e.key.type==="Literal"&&(typeof e.key.value==="string"||typeof e.key.value==="number")&&e.value&&e.value.type==="FunctionExpression"))&&(r=t.callee.body.body[3].expression.right)&&(t.callee.body.body[4].type==="VariableDeclaration"&&t.callee.body.body[4].declarations.length===1&&t.callee.body.body[4].declarations[0].init&&t.callee.body.body[4].declarations[0].init.type==="CallExpression"&&t.callee.body.body[4].declarations[0].init.callee.type==="Identifier"&&t.callee.body.body[4].declarations[0].init.callee.name==="require"||t.callee.body.body[5].type==="VariableDeclaration"&&t.callee.body.body[5].declarations.length===1&&t.callee.body.body[5].declarations[0].init&&t.callee.body.body[5].declarations[0].init.type==="CallExpression"&&t.callee.body.body[5].declarations[0].init.callee.type==="Identifier"&&t.callee.body.body[5].declarations[0].init.callee.name==="require")){const e=new Map;let t;if(r.type==="ArrayExpression")t=r.elements.filter((e=>e?.type==="FunctionExpression")).map(((e,t)=>[String(t),e]));else t=r.properties.map((e=>[String(e.key.value),e.value]));for(const[r,s]of t){const t=s.body.body.length===1?s.body.body[0]:(s.body.body.length===2||s.body.body.length===3&&s.body.body[2].type==="EmptyStatement")&&s.body.body[0].type==="ExpressionStatement"&&s.body.body[0].expression.type==="Literal"&&s.body.body[0].expression.value==="use strict"?s.body.body[1]:null;if(t&&t.type==="ExpressionStatement"&&t.expression.type==="AssignmentExpression"&&t.expression.operator==="="&&t.expression.left.type==="MemberExpression"&&t.expression.left.object.type==="Identifier"&&"params"in s&&s.params.length>0&&"name"in s.params[0]&&t.expression.left.object.name===s.params[0].name&&t.expression.left.property.type==="Identifier"&&t.expression.left.property.name==="exports"&&t.expression.right.type==="CallExpression"&&t.expression.right.callee.type==="Identifier"&&t.expression.right.callee.name==="require"&&t.expression.right.arguments.length===1&&t.expression.right.arguments[0].type==="Literal"){e.set(r,t.expression.right.arguments[0].value)}}for(const[,r]of t){if("params"in r&&r.params.length===3&&r.params[2].type==="Identifier"){const t=new Map;(0,s.walk)(r.body,{enter(s,a){const o=s;const u=a;if(o.type==="CallExpression"&&o.callee.type==="Identifier"&&"name"in r.params[2]&&o.callee.name===r.params[2].name&&o.arguments.length===1&&o.arguments[0].type==="Literal"){const r=e.get(String(o.arguments[0].value));if(r){const e={type:"CallExpression",optional:false,callee:{type:"Identifier",name:"require"},arguments:[{type:"Literal",value:r}]};const s=u;if("right"in s&&s.right===o){s.right=e}else if("left"in s&&s.left===o){s.left=e}else if("object"in s&&s.object===o){s.object=e}else if("callee"in s&&s.callee===o){s.callee=e}else if("arguments"in s&&s.arguments.some((e=>e===o))){s.arguments=s.arguments.map((t=>t===o?e:t))}else if("init"in s&&s.init===o){if(s.type==="VariableDeclarator"&&s.id.type==="Identifier")t.set(s.id.name,r);s.init=e}}}else if(o.type==="CallExpression"&&o.callee.type==="MemberExpression"&&o.callee.object.type==="Identifier"&&"name"in r.params[2]&&o.callee.object.name===r.params[2].name&&o.callee.property.type==="Identifier"&&o.callee.property.name==="n"&&o.arguments.length===1&&o.arguments[0].type==="Identifier"){if(u&&"init"in u&&u.init===o){const e=o.arguments[0];const t={type:"CallExpression",optional:false,callee:{type:"MemberExpression",computed:false,optional:false,object:{type:"Identifier",name:"Object"},property:{type:"Identifier",name:"assign"}},arguments:[{type:"ArrowFunctionExpression",expression:true,params:[],body:e},{type:"ObjectExpression",properties:[{type:"Property",kind:"init",method:false,computed:false,shorthand:false,key:{type:"Identifier",name:"a"},value:e}]}]};u.init=t}}}})}}}}}t.handleWrappers=handleWrappers},351:(e,t)=>{e.exports=t=abbrev.abbrev=abbrev;abbrev.monkeyPatch=monkeyPatch;function monkeyPatch(){Object.defineProperty(Array.prototype,"abbrev",{value:function(){return abbrev(this)},enumerable:false,configurable:true,writable:true});Object.defineProperty(Object.prototype,"abbrev",{value:function(){return abbrev(Object.keys(this))},enumerable:false,configurable:true,writable:true})}function abbrev(e){if(arguments.length!==1||!Array.isArray(e)){e=Array.prototype.slice.call(arguments,0)}for(var t=0,r=e.length,s=[];tt?1:-1}},878:e=>{"use strict";function isArguments(e){return e!=null&&typeof e==="object"&&e.hasOwnProperty("callee")}var t={"*":{label:"any",check:function(){return true}},A:{label:"array",check:function(e){return Array.isArray(e)||isArguments(e)}},S:{label:"string",check:function(e){return typeof e==="string"}},N:{label:"number",check:function(e){return typeof e==="number"}},F:{label:"function",check:function(e){return typeof e==="function"}},O:{label:"object",check:function(e){return typeof e==="object"&&e!=null&&!t.A.check(e)&&!t.E.check(e)}},B:{label:"boolean",check:function(e){return typeof e==="boolean"}},E:{label:"error",check:function(e){return e instanceof Error}},Z:{label:"null",check:function(e){return e==null}}};function addSchema(e,t){var r=t[e.length]=t[e.length]||[];if(r.indexOf(e)===-1)r.push(e)}var r=e.exports=function(e,r){if(arguments.length!==2)throw wrongNumberOfArgs(["SA"],arguments.length);if(!e)throw missingRequiredArg(0,"rawSchemas");if(!r)throw missingRequiredArg(1,"args");if(!t.S.check(e))throw invalidType(0,["string"],e);if(!t.A.check(r))throw invalidType(1,["array"],r);var s=e.split("|");var a={};s.forEach((function(e){for(var r=0;r{"use strict";t.TrackerGroup=r(308);t.Tracker=r(7605);t.TrackerStream=r(374)},5299:(e,t,r)=>{"use strict";var s=r(2361).EventEmitter;var a=r(3837);var o=0;var u=e.exports=function(e){s.call(this);this.id=++o;this.name=e};a.inherits(u,s)},308:(e,t,r)=>{"use strict";var s=r(3837);var a=r(5299);var o=r(7605);var u=r(374);var c=e.exports=function(e){a.call(this,e);this.parentGroup=null;this.trackers=[];this.completion={};this.weight={};this.totalWeight=0;this.finished=false;this.bubbleChange=bubbleChange(this)};s.inherits(c,a);function bubbleChange(e){return function(t,r,s){e.completion[s.id]=r;if(e.finished)return;e.emit("change",t||e.name,e.completed(),e)}}c.prototype.nameInTree=function(){var e=[];var t=this;while(t){e.unshift(t.name);t=t.parentGroup}return e.join("/")};c.prototype.addUnit=function(e,t){if(e.addUnit){var r=this;while(r){if(e===r){throw new Error("Attempted to add tracker group "+e.name+" to tree that already includes it "+this.nameInTree(this))}r=r.parentGroup}e.parentGroup=this}this.weight[e.id]=t||1;this.totalWeight+=this.weight[e.id];this.trackers.push(e);this.completion[e.id]=e.completed();e.on("change",this.bubbleChange);if(!this.finished)this.emit("change",e.name,this.completion[e.id],e);return e};c.prototype.completed=function(){if(this.trackers.length===0)return 0;var e=1/this.totalWeight;var t=0;for(var r=0;r{"use strict";var s=r(3837);var a=r(8511);var o=r(857);var u=r(7605);var c=e.exports=function(e,t,r){a.Transform.call(this,r);this.tracker=new u(e,t);this.name=e;this.id=this.tracker.id;this.tracker.on("change",delegateChange(this))};s.inherits(c,a.Transform);function delegateChange(e){return function(t,r,s){e.emit("change",t,r,e)}}c.prototype._transform=function(e,t,r){this.tracker.completeWork(e.length?e.length:1);this.push(e);r()};c.prototype._flush=function(e){this.tracker.finish();e()};o(c.prototype,"tracker").method("completed").method("addWork").method("finish")},7605:(e,t,r)=>{"use strict";var s=r(3837);var a=r(5299);var o=e.exports=function(e,t){a.call(this,e);this.workDone=0;this.workTodo=t||0};s.inherits(o,a);o.prototype.completed=function(){return this.workTodo===0?0:this.workDone/this.workTodo};o.prototype.addWork=function(e){this.workTodo+=e;this.emit("change",this.name,this.completed(),this)};o.prototype.completeWork=function(e){this.workDone+=e;if(this.workDone>this.workTodo)this.workDone=this.workTodo;this.emit("change",this.name,this.completed(),this)};o.prototype.finish=function(){this.workTodo=this.workDone=1;this.emit("change",this.name,1,this)}},3331:(module,exports,__nccwpck_require__)=>{var fs=__nccwpck_require__(7147),path=__nccwpck_require__(1017),fileURLToPath=__nccwpck_require__(7121),join=path.join,dirname=path.dirname,exists=fs.accessSync&&function(e){try{fs.accessSync(e)}catch(e){return false}return true}||fs.existsSync||path.existsSync,defaults={arrow:process.env.NODE_BINDINGS_ARROW||" → ",compiled:process.env.NODE_BINDINGS_COMPILED_DIR||"compiled",platform:process.platform,arch:process.arch,nodePreGyp:"node-v"+process.versions.modules+"-"+process.platform+"-"+process.arch,version:process.versions.node,bindings:"bindings.node",try:[["module_root","build","bindings"],["module_root","build","Debug","bindings"],["module_root","build","Release","bindings"],["module_root","out","Debug","bindings"],["module_root","Debug","bindings"],["module_root","out","Release","bindings"],["module_root","Release","bindings"],["module_root","build","default","bindings"],["module_root","compiled","version","platform","arch","bindings"],["module_root","addon-build","release","install-root","bindings"],["module_root","addon-build","debug","install-root","bindings"],["module_root","addon-build","default","install-root","bindings"],["module_root","lib","binding","nodePreGyp","bindings"]]};function bindings(opts){if(typeof opts=="string"){opts={bindings:opts}}else if(!opts){opts={}}Object.keys(defaults).map((function(e){if(!(e in opts))opts[e]=defaults[e]}));if(!opts.module_root){opts.module_root=exports.getRoot(exports.getFileName())}if(path.extname(opts.bindings)!=".node"){opts.bindings+=".node"}var requireFunc=true?eval("require"):0;var tries=[],i=0,l=opts.try.length,n,b,err;for(;i{"use strict";e.exports=function(e,t){if(e===null||e===undefined){throw TypeError()}e=String(e);var r=e.length;var s=t?Number(t):0;if(Number.isNaN(s)){s=0}if(s<0||s>=r){return undefined}var a=e.charCodeAt(s);if(a>=55296&&a<=56319&&r>s+1){var o=e.charCodeAt(s+1);if(o>=56320&&o<=57343){return(a-55296)*1024+o-56320+65536}}return a}},3844:(e,t)=>{"use strict";var r="[";t.up=function up(e){return r+(e||"")+"A"};t.down=function down(e){return r+(e||"")+"B"};t.forward=function forward(e){return r+(e||"")+"C"};t.back=function back(e){return r+(e||"")+"D"};t.nextLine=function nextLine(e){return r+(e||"")+"E"};t.previousLine=function previousLine(e){return r+(e||"")+"F"};t.horizontalAbsolute=function horizontalAbsolute(e){if(e==null)throw new Error("horizontalAboslute requires a column to position to");return r+e+"G"};t.eraseData=function eraseData(){return r+"J"};t.eraseLine=function eraseLine(){return r+"K"};t.goto=function(e,t){return r+t+";"+e+"H"};t.gotoSOL=function(){return"\r"};t.beep=function(){return""};t.hideCursor=function hideCursor(){return r+"?25l"};t.showCursor=function showCursor(){return r+"?25h"};var s={reset:0,bold:1,italic:3,underline:4,inverse:7,stopBold:22,stopItalic:23,stopUnderline:24,stopInverse:27,white:37,black:30,blue:34,cyan:36,green:32,magenta:35,red:31,yellow:33,bgWhite:47,bgBlack:40,bgBlue:44,bgCyan:46,bgGreen:42,bgMagenta:45,bgRed:41,bgYellow:43,grey:90,brightBlack:90,brightRed:91,brightGreen:92,brightYellow:93,brightBlue:94,brightMagenta:95,brightCyan:96,brightWhite:97,bgGrey:100,bgBrightBlack:100,bgBrightRed:101,bgBrightGreen:102,bgBrightYellow:103,bgBrightBlue:104,bgBrightMagenta:105,bgBrightCyan:106,bgBrightWhite:107};t.color=function color(e){if(arguments.length!==1||!Array.isArray(e)){e=Array.prototype.slice.call(arguments)}return r+e.map(colorNameToCode).join(";")+"m"};function colorNameToCode(e){if(s[e]!=null)return s[e];throw new Error("Unknown color or style name: "+e)}},1504:(e,t)=>{function isArray(e){if(Array.isArray){return Array.isArray(e)}return objectToString(e)==="[object Array]"}t.isArray=isArray;function isBoolean(e){return typeof e==="boolean"}t.isBoolean=isBoolean;function isNull(e){return e===null}t.isNull=isNull;function isNullOrUndefined(e){return e==null}t.isNullOrUndefined=isNullOrUndefined;function isNumber(e){return typeof e==="number"}t.isNumber=isNumber;function isString(e){return typeof e==="string"}t.isString=isString;function isSymbol(e){return typeof e==="symbol"}t.isSymbol=isSymbol;function isUndefined(e){return e===void 0}t.isUndefined=isUndefined;function isRegExp(e){return objectToString(e)==="[object RegExp]"}t.isRegExp=isRegExp;function isObject(e){return typeof e==="object"&&e!==null}t.isObject=isObject;function isDate(e){return objectToString(e)==="[object Date]"}t.isDate=isDate;function isError(e){return objectToString(e)==="[object Error]"||e instanceof Error}t.isError=isError;function isFunction(e){return typeof e==="function"}t.isFunction=isFunction;function isPrimitive(e){return e===null||typeof e==="boolean"||typeof e==="number"||typeof e==="string"||typeof e==="symbol"||typeof e==="undefined"}t.isPrimitive=isPrimitive;t.isBuffer=Buffer.isBuffer;function objectToString(e){return Object.prototype.toString.call(e)}},857:e=>{e.exports=Delegator;function Delegator(e,t){if(!(this instanceof Delegator))return new Delegator(e,t);this.proto=e;this.target=t;this.methods=[];this.getters=[];this.setters=[];this.fluents=[]}Delegator.prototype.method=function(e){var t=this.proto;var r=this.target;this.methods.push(e);t[e]=function(){return this[r][e].apply(this[r],arguments)};return this};Delegator.prototype.access=function(e){return this.getter(e).setter(e)};Delegator.prototype.getter=function(e){var t=this.proto;var r=this.target;this.getters.push(e);t.__defineGetter__(e,(function(){return this[r][e]}));return this};Delegator.prototype.setter=function(e){var t=this.proto;var r=this.target;this.setters.push(e);t.__defineSetter__(e,(function(t){return this[r][e]=t}));return this};Delegator.prototype.fluent=function(e){var t=this.proto;var r=this.target;this.fluents.push(e);t[e]=function(t){if("undefined"!=typeof t){this[r][e]=t;return this}else{return this[r][e]}};return this}},5104:(e,t,r)=>{"use strict";var s=r(2037).platform();var a=r(2081).spawnSync;var o=r(7147).readdirSync;var u="glibc";var c="musl";var f={encoding:"utf8",env:process.env};if(!a){a=function(){return{status:126,stdout:"",stderr:""}}}function contains(e){return function(t){return t.indexOf(e)!==-1}}function versionFromMuslLdd(e){return e.split(/[\r\n]+/)[1].trim().split(/\s/)[1]}function safeReaddirSync(e){try{return o(e)}catch(e){}return[]}var d="";var p="";var h="";if(s==="linux"){var v=a("getconf",["GNU_LIBC_VERSION"],f);if(v.status===0){d=u;p=v.stdout.trim().split(" ")[1];h="getconf"}else{var D=a("ldd",["--version"],f);if(D.status===0&&D.stdout.indexOf(c)!==-1){d=c;p=versionFromMuslLdd(D.stdout);h="ldd"}else if(D.status===1&&D.stderr.indexOf(c)!==-1){d=c;p=versionFromMuslLdd(D.stderr);h="ldd"}else{var g=safeReaddirSync("/lib");if(g.some(contains("-linux-gnu"))){d=u;h="filesystem"}else if(g.some(contains("libc.musl-"))){d=c;h="filesystem"}else if(g.some(contains("ld-musl-"))){d=c;h="filesystem"}else{var y=safeReaddirSync("/usr/sbin");if(y.some(contains("glibc"))){d=u;h="filesystem"}}}}}var m=d!==""&&d!==u;e.exports={GLIBC:u,MUSL:c,family:d,version:p,method:h,isNonGlibcLinux:m}},3876:e=>{"use strict";e.exports=function(){return/\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F|\uD83D\uDC68(?:\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68\uD83C\uDFFB|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|[\u2695\u2696\u2708]\uFE0F|\uD83D[\uDC66\uDC67]|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708])\uFE0F|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C[\uDFFB-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)\uD83C\uDFFB|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB\uDFFC])|\uD83D\uDC69(?:\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB-\uDFFD])|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|(?:(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)\uFE0F|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\u200D[\u2640\u2642])|\uD83C\uDFF4\u200D\u2620)\uFE0F|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF4\uD83C\uDDF2|\uD83C\uDDF6\uD83C\uDDE6|[#\*0-9]\uFE0F\u20E3|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83D\uDC69(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270A-\u270D]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC70\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDCAA\uDD74\uDD7A\uDD90\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD36\uDDB5\uDDB6\uDDBB\uDDD2-\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5\uDEEB\uDEEC\uDEF4-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g}},7121:(e,t,r)=>{var s=r(1017).sep||"/";e.exports=fileUriToPath;function fileUriToPath(e){if("string"!=typeof e||e.length<=7||"file://"!=e.substring(0,7)){throw new TypeError("must pass in a file:// URI to convert to a file path")}var t=decodeURI(e.substring(7));var r=t.indexOf("/");var a=t.substring(0,r);var o=t.substring(r+1);if("localhost"==a)a="";if(a){a=s+s+a}o=o.replace(/^(.+)\|/,"$1:");if(s=="\\"){o=o.replace(/\//g,"\\")}if(/^.+\:/.test(o)){}else{o=s+o}return a+o}},8862:(e,t,r)=>{"use strict";var s=r(5154);var a=r(4044);e.exports={activityIndicator:function(e,t,r){if(e.spun==null)return;return s(t,e.spun)},progressbar:function(e,t,r){if(e.completed==null)return;return a(t,r,e.completed)}}},2905:(e,t,r)=>{"use strict";var s=r(3837);var a=t.User=function User(e){var t=new Error(e);Error.captureStackTrace(t,User);t.code="EGAUGE";return t};t.MissingTemplateValue=function MissingTemplateValue(e,t){var r=new a(s.format('Missing template value "%s"',e.type));Error.captureStackTrace(r,MissingTemplateValue);r.template=e;r.values=t;return r};t.Internal=function Internal(e){var t=new Error(e);Error.captureStackTrace(t,Internal);t.code="EGAUGEINTERNAL";return t}},1191:e=>{"use strict";e.exports=isWin32()||isColorTerm();function isWin32(){return process.platform==="win32"}function isColorTerm(){var e=/^screen|^xterm|^vt100|color|ansi|cygwin|linux/i;return!!process.env.COLORTERM||e.test(process.env.TERM)}},287:(e,t,r)=>{"use strict";var s=r(4052);var a=r(5214);var o=r(1191);var u=r(7234);var c=r(9986);var f=r(7131);var d=r(5751);var p=r(5498);e.exports=Gauge;function callWith(e,t){return function(){return t.call(e)}}function Gauge(e,t){var r,a;if(e&&e.write){a=e;r=t||{}}else if(t&&t.write){a=t;r=e||{}}else{a=d.stderr;r=e||t||{}}this._status={spun:0,section:"",subsection:""};this._paused=false;this._disabled=true;this._showing=false;this._onScreen=false;this._needsRedraw=false;this._hideCursor=r.hideCursor==null?true:r.hideCursor;this._fixedFramerate=r.fixedFramerate==null?!/^v0\.8\./.test(d.version):r.fixedFramerate;this._lastUpdateAt=null;this._updateInterval=r.updateInterval==null?50:r.updateInterval;this._themes=r.themes||c;this._theme=r.theme;var o=this._computeTheme(r.theme);var u=r.template||[{type:"progressbar",length:20},{type:"activityIndicator",kerning:1,length:1},{type:"section",kerning:1,default:""},{type:"subsection",kerning:1,default:""}];this.setWriteTo(a,r.tty);var f=r.Plumbing||s;this._gauge=new f(o,u,this.getWidth());this._$$doRedraw=callWith(this,this._doRedraw);this._$$handleSizeChange=callWith(this,this._handleSizeChange);this._cleanupOnExit=r.cleanupOnExit==null||r.cleanupOnExit;this._removeOnExit=null;if(r.enabled||r.enabled==null&&this._tty&&this._tty.isTTY){this.enable()}else{this.disable()}}Gauge.prototype={};Gauge.prototype.isEnabled=function(){return!this._disabled};Gauge.prototype.setTemplate=function(e){this._gauge.setTemplate(e);if(this._showing)this._requestRedraw()};Gauge.prototype._computeTheme=function(e){if(!e)e={};if(typeof e==="string"){e=this._themes.getTheme(e)}else if(e&&(Object.keys(e).length===0||e.hasUnicode!=null||e.hasColor!=null)){var t=e.hasUnicode==null?a():e.hasUnicode;var r=e.hasColor==null?o:e.hasColor;e=this._themes.getDefault({hasUnicode:t,hasColor:r,platform:e.platform})}return e};Gauge.prototype.setThemeset=function(e){this._themes=e;this.setTheme(this._theme)};Gauge.prototype.setTheme=function(e){this._gauge.setTheme(this._computeTheme(e));if(this._showing)this._requestRedraw();this._theme=e};Gauge.prototype._requestRedraw=function(){this._needsRedraw=true;if(!this._fixedFramerate)this._doRedraw()};Gauge.prototype.getWidth=function(){return(this._tty&&this._tty.columns||80)-1};Gauge.prototype.setWriteTo=function(e,t){var r=!this._disabled;if(r)this.disable();this._writeTo=e;this._tty=t||e===d.stderr&&d.stdout.isTTY&&d.stdout||e.isTTY&&e||this._tty;if(this._gauge)this._gauge.setWidth(this.getWidth());if(r)this.enable()};Gauge.prototype.enable=function(){if(!this._disabled)return;this._disabled=false;if(this._tty)this._enableEvents();if(this._showing)this.show()};Gauge.prototype.disable=function(){if(this._disabled)return;if(this._showing){this._lastUpdateAt=null;this._showing=false;this._doRedraw();this._showing=true}this._disabled=true;if(this._tty)this._disableEvents()};Gauge.prototype._enableEvents=function(){if(this._cleanupOnExit){this._removeOnExit=u(callWith(this,this.disable))}this._tty.on("resize",this._$$handleSizeChange);if(this._fixedFramerate){this.redrawTracker=f(this._$$doRedraw,this._updateInterval);if(this.redrawTracker.unref)this.redrawTracker.unref()}};Gauge.prototype._disableEvents=function(){this._tty.removeListener("resize",this._$$handleSizeChange);if(this._fixedFramerate)clearInterval(this.redrawTracker);if(this._removeOnExit)this._removeOnExit()};Gauge.prototype.hide=function(e){if(this._disabled)return e&&d.nextTick(e);if(!this._showing)return e&&d.nextTick(e);this._showing=false;this._doRedraw();e&&p(e)};Gauge.prototype.show=function(e,t){this._showing=true;if(typeof e==="string"){this._status.section=e}else if(typeof e==="object"){var r=Object.keys(e);for(var s=0;s{"use strict";var s=r(3844);var a=r(7238);var o=r(878);var u=e.exports=function(e,t,r){if(!r)r=80;o("OAN",[e,t,r]);this.showing=false;this.theme=e;this.width=r;this.template=t};u.prototype={};u.prototype.setTheme=function(e){o("O",[e]);this.theme=e};u.prototype.setTemplate=function(e){o("A",[e]);this.template=e};u.prototype.setWidth=function(e){o("N",[e]);this.width=e};u.prototype.hide=function(){return s.gotoSOL()+s.eraseLine()};u.prototype.hideCursor=s.hideCursor;u.prototype.showCursor=s.showCursor;u.prototype.show=function(e){var t=Object.create(this.theme);for(var r in e){t[r]=e[r]}return a(this.width,this.template,t).trim()+s.color("reset")+s.eraseLine()+s.gotoSOL()}},5751:e=>{"use strict";e.exports=process},4044:(e,t,r)=>{"use strict";var s=r(878);var a=r(7238);var o=r(5791);var u=r(8321);e.exports=function(e,t,r){s("ONN",[e,t,r]);if(r<0)r=0;if(r>1)r=1;if(t<=0)return"";var o=Math.round(t*r);var u=t-o;var c=[{type:"complete",value:repeat(e.complete,o),length:o},{type:"remaining",value:repeat(e.remaining,u),length:u}];return a(t,c,e)};function repeat(e,t){var r="";var s=t;do{if(s%2){r+=e}s=Math.floor(s/2);e+=e}while(s&&u(r){"use strict";var s=r(1365);var a=r(878);var o=r(3540);var u=r(5791);var c=r(2905);var f=r(8855);function renderValueWithValues(e){return function(t){return renderValue(t,e)}}var d=e.exports=function(e,t,r){var a=prepareItems(e,t,r);var o=a.map(renderValueWithValues(r)).join("");return s.left(u(o,e),e)};function preType(e){var t=e.type[0].toUpperCase()+e.type.slice(1);return"pre"+t}function postType(e){var t=e.type[0].toUpperCase()+e.type.slice(1);return"post"+t}function hasPreOrPost(e,t){if(!e.type)return;return t[preType(e)]||t[postType(e)]}function generatePreAndPost(e,t){var r=o({},e);var s=Object.create(t);var a=[];var u=preType(r);var c=postType(r);if(s[u]){a.push({value:s[u]});s[u]=null}r.minLength=null;r.length=null;r.maxLength=null;a.push(r);s[r.type]=s[r.type];if(s[c]){a.push({value:s[c]});s[c]=null}return function(e,t,r){return d(r,a,s)}}function prepareItems(e,t,r){function cloneAndObjectify(t,s,a){var o=new f(t,e);var u=o.type;if(o.value==null){if(!(u in r)){if(o.default==null){throw new c.MissingTemplateValue(o,r)}else{o.value=o.default}}else{o.value=r[u]}}if(o.value==null||o.value==="")return null;o.index=s;o.first=s===0;o.last=s===a.length-1;if(hasPreOrPost(o,r))o.value=generatePreAndPost(o,r);return o}var s=t.map(cloneAndObjectify).filter((function(e){return e!=null}));var a=0;var o=e;var u=s.length;function consumeSpace(e){if(e>o)e=o;a+=e;o-=e}function finishSizing(e,t){if(e.finished)throw new c.Internal("Tried to finish template item that was already finished");if(t===Infinity)throw new c.Internal("Length of template item cannot be infinity");if(t!=null)e.length=t;e.minLength=null;e.maxLength=null;--u;e.finished=true;if(e.length==null)e.length=e.getBaseLength();if(e.length==null)throw new c.Internal("Finished template items must have a length");consumeSpace(e.getLength())}s.forEach((function(e){if(!e.kerning)return;var t=e.first?0:s[e.index-1].padRight;if(!e.first&&t=h){finishSizing(e,e.minLength);p=true}}))}while(p&&d++{"use strict";var s=r(5751);try{e.exports=setImmediate}catch(t){e.exports=s.nextTick}},7131:e=>{"use strict";e.exports=setInterval},5154:e=>{"use strict";e.exports=function spin(e,t){return e[t%e.length]}},8855:(e,t,r)=>{"use strict";var s=r(8321);e.exports=TemplateItem;function isPercent(e){if(typeof e!=="string")return false;return e.slice(-1)==="%"}function percent(e){return Number(e.slice(0,-1))/100}function TemplateItem(e,t){this.overallOutputLength=t;this.finished=false;this.type=null;this.value=null;this.length=null;this.maxLength=null;this.minLength=null;this.kerning=null;this.align="left";this.padLeft=0;this.padRight=0;this.index=null;this.first=null;this.last=null;if(typeof e==="string"){this.value=e}else{for(var r in e)this[r]=e[r]}if(isPercent(this.length)){this.length=Math.round(this.overallOutputLength*percent(this.length))}if(isPercent(this.minLength)){this.minLength=Math.round(this.overallOutputLength*percent(this.minLength))}if(isPercent(this.maxLength)){this.maxLength=Math.round(this.overallOutputLength*percent(this.maxLength))}return this}TemplateItem.prototype={};TemplateItem.prototype.getBaseLength=function(){var e=this.length;if(e==null&&typeof this.value==="string"&&this.maxLength==null&&this.minLength==null){e=s(this.value)}return e};TemplateItem.prototype.getLength=function(){var e=this.getBaseLength();if(e==null)return null;return e+this.padLeft+this.padRight};TemplateItem.prototype.getMaxLength=function(){if(this.maxLength==null)return null;return this.maxLength+this.padLeft+this.padRight};TemplateItem.prototype.getMinLength=function(){if(this.minLength==null)return null;return this.minLength+this.padLeft+this.padRight}},8469:(e,t,r)=>{"use strict";var s=r(3540);e.exports=function(){return a.newThemeSet()};var a={};a.baseTheme=r(8862);a.newTheme=function(e,t){if(!t){t=e;e=this.baseTheme}return s({},e,t)};a.getThemeNames=function(){return Object.keys(this.themes)};a.addTheme=function(e,t,r){this.themes[e]=this.newTheme(t,r)};a.addToAllThemes=function(e){var t=this.themes;Object.keys(t).forEach((function(r){s(t[r],e)}));s(this.baseTheme,e)};a.getTheme=function(e){if(!this.themes[e])throw this.newMissingThemeError(e);return this.themes[e]};a.setDefault=function(e,t){if(t==null){t=e;e={}}var r=e.platform==null?"fallback":e.platform;var s=!!e.hasUnicode;var a=!!e.hasColor;if(!this.defaults[r])this.defaults[r]={true:{},false:{}};this.defaults[r][s][a]=t};a.getDefault=function(e){if(!e)e={};var t=e.platform||process.platform;var r=this.defaults[t]||this.defaults.fallback;var a=!!e.hasUnicode;var o=!!e.hasColor;if(!r)throw this.newMissingDefaultThemeError(t,a,o);if(!r[a][o]){if(a&&o&&r[!a][o]){a=false}else if(a&&o&&r[a][!o]){o=false}else if(a&&o&&r[!a][!o]){a=false;o=false}else if(a&&!o&&r[!a][o]){a=false}else if(!a&&o&&r[a][!o]){o=false}else if(r===this.defaults.fallback){throw this.newMissingDefaultThemeError(t,a,o)}}if(r[a][o]){return this.getTheme(r[a][o])}else{return this.getDefault(s({},e,{platform:"fallback"}))}};a.newMissingThemeError=function newMissingThemeError(e){var t=new Error('Could not find a gauge theme named "'+e+'"');Error.captureStackTrace.call(t,newMissingThemeError);t.theme=e;t.code="EMISSINGTHEME";return t};a.newMissingDefaultThemeError=function newMissingDefaultThemeError(e,t,r){var s=new Error("Could not find a gauge theme for your platform/unicode/color use combo:\n"+" platform = "+e+"\n"+" hasUnicode = "+t+"\n"+" hasColor = "+r);Error.captureStackTrace.call(s,newMissingDefaultThemeError);s.platform=e;s.hasUnicode=t;s.hasColor=r;s.code="EMISSINGTHEME";return s};a.newThemeSet=function(){var themeset=function(e){return themeset.getDefault(e)};return s(themeset,a,{themes:s({},this.themes),baseTheme:s({},this.baseTheme),defaults:JSON.parse(JSON.stringify(this.defaults||{}))})}},9986:(e,t,r)=>{"use strict";var s=r(3844);var a=r(8469);var o=e.exports=new a;o.addTheme("ASCII",{preProgressbar:"[",postProgressbar:"]",progressbarTheme:{complete:"#",remaining:"."},activityIndicatorTheme:"-\\|/",preSubsection:">"});o.addTheme("colorASCII",o.getTheme("ASCII"),{progressbarTheme:{preComplete:s.color("inverse"),complete:" ",postComplete:s.color("stopInverse"),preRemaining:s.color("brightBlack"),remaining:".",postRemaining:s.color("reset")}});o.addTheme("brailleSpinner",{preProgressbar:"⸨",postProgressbar:"⸩",progressbarTheme:{complete:"░",remaining:"⠂"},activityIndicatorTheme:"⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏",preSubsection:">"});o.addTheme("colorBrailleSpinner",o.getTheme("brailleSpinner"),{progressbarTheme:{preComplete:s.color("inverse"),complete:" ",postComplete:s.color("stopInverse"),preRemaining:s.color("brightBlack"),remaining:"░",postRemaining:s.color("reset")}});o.setDefault({},"ASCII");o.setDefault({hasColor:true},"colorASCII");o.setDefault({platform:"darwin",hasUnicode:true},"brailleSpinner");o.setDefault({platform:"darwin",hasUnicode:true,hasColor:true},"colorBrailleSpinner")},5791:(e,t,r)=>{"use strict";var s=r(8321);var a=r(7518);e.exports=wideTruncate;function wideTruncate(e,t){if(s(e)===0)return e;if(t<=0)return"";if(s(e)<=t)return e;var r=a(e);var o=e.length+r.length;var u=e.slice(0,t+o);while(s(u)>t){u=u.slice(0,-1)}return u}},4444:e=>{"use strict";e.exports=clone;var t=Object.getPrototypeOf||function(e){return e.__proto__};function clone(e){if(e===null||typeof e!=="object")return e;if(e instanceof Object)var r={__proto__:t(e)};else var r=Object.create(null);Object.getOwnPropertyNames(e).forEach((function(t){Object.defineProperty(r,t,Object.getOwnPropertyDescriptor(e,t))}));return r}},9165:(e,t,r)=>{var s=r(7147);var a=r(8986);var o=r(7078);var u=r(4444);var c=r(3837);var f;var d;if(typeof Symbol==="function"&&typeof Symbol.for==="function"){f=Symbol.for("graceful-fs.queue");d=Symbol.for("graceful-fs.previous")}else{f="___graceful-fs.queue";d="___graceful-fs.previous"}function noop(){}function publishQueue(e,t){Object.defineProperty(e,f,{get:function(){return t}})}var p=noop;if(c.debuglog)p=c.debuglog("gfs4");else if(/\bgfs4\b/i.test(process.env.NODE_DEBUG||""))p=function(){var e=c.format.apply(c,arguments);e="GFS4: "+e.split(/\n/).join("\nGFS4: ");console.error(e)};if(!s[f]){var h=global[f]||[];publishQueue(s,h);s.close=function(e){function close(t,r){return e.call(s,t,(function(e){if(!e){resetQueue()}if(typeof r==="function")r.apply(this,arguments)}))}Object.defineProperty(close,d,{value:e});return close}(s.close);s.closeSync=function(e){function closeSync(t){e.apply(s,arguments);resetQueue()}Object.defineProperty(closeSync,d,{value:e});return closeSync}(s.closeSync);if(/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")){process.on("exit",(function(){p(s[f]);r(9491).equal(s[f].length,0)}))}}if(!global[f]){publishQueue(global,s[f])}e.exports=patch(u(s));if(process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH&&!s.__patched){e.exports=patch(s);s.__patched=true}function patch(e){a(e);e.gracefulify=patch;e.createReadStream=createReadStream;e.createWriteStream=createWriteStream;var t=e.readFile;e.readFile=readFile;function readFile(e,r,s){if(typeof r==="function")s=r,r=null;return go$readFile(e,r,s);function go$readFile(e,r,s,a){return t(e,r,(function(t){if(t&&(t.code==="EMFILE"||t.code==="ENFILE"))enqueue([go$readFile,[e,r,s],t,a||Date.now(),Date.now()]);else{if(typeof s==="function")s.apply(this,arguments)}}))}}var r=e.writeFile;e.writeFile=writeFile;function writeFile(e,t,s,a){if(typeof s==="function")a=s,s=null;return go$writeFile(e,t,s,a);function go$writeFile(e,t,s,a,o){return r(e,t,s,(function(r){if(r&&(r.code==="EMFILE"||r.code==="ENFILE"))enqueue([go$writeFile,[e,t,s,a],r,o||Date.now(),Date.now()]);else{if(typeof a==="function")a.apply(this,arguments)}}))}}var s=e.appendFile;if(s)e.appendFile=appendFile;function appendFile(e,t,r,a){if(typeof r==="function")a=r,r=null;return go$appendFile(e,t,r,a);function go$appendFile(e,t,r,a,o){return s(e,t,r,(function(s){if(s&&(s.code==="EMFILE"||s.code==="ENFILE"))enqueue([go$appendFile,[e,t,r,a],s,o||Date.now(),Date.now()]);else{if(typeof a==="function")a.apply(this,arguments)}}))}}var u=e.copyFile;if(u)e.copyFile=copyFile;function copyFile(e,t,r,s){if(typeof r==="function"){s=r;r=0}return go$copyFile(e,t,r,s);function go$copyFile(e,t,r,s,a){return u(e,t,r,(function(o){if(o&&(o.code==="EMFILE"||o.code==="ENFILE"))enqueue([go$copyFile,[e,t,r,s],o,a||Date.now(),Date.now()]);else{if(typeof s==="function")s.apply(this,arguments)}}))}}var c=e.readdir;e.readdir=readdir;var f=/^v[0-5]\./;function readdir(e,t,r){if(typeof t==="function")r=t,t=null;var s=f.test(process.version)?function go$readdir(e,t,r,s){return c(e,fs$readdirCallback(e,t,r,s))}:function go$readdir(e,t,r,s){return c(e,t,fs$readdirCallback(e,t,r,s))};return s(e,t,r);function fs$readdirCallback(e,t,r,a){return function(o,u){if(o&&(o.code==="EMFILE"||o.code==="ENFILE"))enqueue([s,[e,t,r],o,a||Date.now(),Date.now()]);else{if(u&&u.sort)u.sort();if(typeof r==="function")r.call(this,o,u)}}}}if(process.version.substr(0,4)==="v0.8"){var d=o(e);ReadStream=d.ReadStream;WriteStream=d.WriteStream}var p=e.ReadStream;if(p){ReadStream.prototype=Object.create(p.prototype);ReadStream.prototype.open=ReadStream$open}var h=e.WriteStream;if(h){WriteStream.prototype=Object.create(h.prototype);WriteStream.prototype.open=WriteStream$open}Object.defineProperty(e,"ReadStream",{get:function(){return ReadStream},set:function(e){ReadStream=e},enumerable:true,configurable:true});Object.defineProperty(e,"WriteStream",{get:function(){return WriteStream},set:function(e){WriteStream=e},enumerable:true,configurable:true});var v=ReadStream;Object.defineProperty(e,"FileReadStream",{get:function(){return v},set:function(e){v=e},enumerable:true,configurable:true});var D=WriteStream;Object.defineProperty(e,"FileWriteStream",{get:function(){return D},set:function(e){D=e},enumerable:true,configurable:true});function ReadStream(e,t){if(this instanceof ReadStream)return p.apply(this,arguments),this;else return ReadStream.apply(Object.create(ReadStream.prototype),arguments)}function ReadStream$open(){var e=this;open(e.path,e.flags,e.mode,(function(t,r){if(t){if(e.autoClose)e.destroy();e.emit("error",t)}else{e.fd=r;e.emit("open",r);e.read()}}))}function WriteStream(e,t){if(this instanceof WriteStream)return h.apply(this,arguments),this;else return WriteStream.apply(Object.create(WriteStream.prototype),arguments)}function WriteStream$open(){var e=this;open(e.path,e.flags,e.mode,(function(t,r){if(t){e.destroy();e.emit("error",t)}else{e.fd=r;e.emit("open",r)}}))}function createReadStream(t,r){return new e.ReadStream(t,r)}function createWriteStream(t,r){return new e.WriteStream(t,r)}var g=e.open;e.open=open;function open(e,t,r,s){if(typeof r==="function")s=r,r=null;return go$open(e,t,r,s);function go$open(e,t,r,s,a){return g(e,t,r,(function(o,u){if(o&&(o.code==="EMFILE"||o.code==="ENFILE"))enqueue([go$open,[e,t,r,s],o,a||Date.now(),Date.now()]);else{if(typeof s==="function")s.apply(this,arguments)}}))}}return e}function enqueue(e){p("ENQUEUE",e[0].name,e[1]);s[f].push(e);retry()}var v;function resetQueue(){var e=Date.now();for(var t=0;t2){s[f][t][3]=e;s[f][t][4]=e}}retry()}function retry(){clearTimeout(v);v=undefined;if(s[f].length===0)return;var e=s[f].shift();var t=e[0];var r=e[1];var a=e[2];var o=e[3];var u=e[4];if(o===undefined){p("RETRY",t.name,r);t.apply(null,r)}else if(Date.now()-o>=6e4){p("TIMEOUT",t.name,r);var c=r.pop();if(typeof c==="function")c.call(null,a)}else{var d=Date.now()-u;var h=Math.max(u-o,1);var D=Math.min(h*1.2,100);if(d>=D){p("RETRY",t.name,r);t.apply(null,r.concat([o]))}else{s[f].push(e)}}if(v===undefined){v=setTimeout(retry,0)}}},7078:(e,t,r)=>{var s=r(2781).Stream;e.exports=legacy;function legacy(e){return{ReadStream:ReadStream,WriteStream:WriteStream};function ReadStream(t,r){if(!(this instanceof ReadStream))return new ReadStream(t,r);s.call(this);var a=this;this.path=t;this.fd=null;this.readable=true;this.paused=false;this.flags="r";this.mode=438;this.bufferSize=64*1024;r=r||{};var o=Object.keys(r);for(var u=0,c=o.length;uthis.end){throw new Error("start must be <= end")}this.pos=this.start}if(this.fd!==null){process.nextTick((function(){a._read()}));return}e.open(this.path,this.flags,this.mode,(function(e,t){if(e){a.emit("error",e);a.readable=false;return}a.fd=t;a.emit("open",t);a._read()}))}function WriteStream(t,r){if(!(this instanceof WriteStream))return new WriteStream(t,r);s.call(this);this.path=t;this.fd=null;this.writable=true;this.flags="w";this.encoding="binary";this.mode=438;this.bytesWritten=0;r=r||{};var a=Object.keys(r);for(var o=0,u=a.length;o= zero")}this.pos=this.start}this.busy=false;this._queue=[];if(this.fd===null){this._open=e.open;this._queue.push([this._open,this.path,this.flags,this.mode,undefined]);this.flush()}}}},8986:(e,t,r)=>{var s=r(2057);var a=process.cwd;var o=null;var u=process.env.GRACEFUL_FS_PLATFORM||process.platform;process.cwd=function(){if(!o)o=a.call(process);return o};try{process.cwd()}catch(e){}if(typeof process.chdir==="function"){var c=process.chdir;process.chdir=function(e){o=null;c.call(process,e)};if(Object.setPrototypeOf)Object.setPrototypeOf(process.chdir,c)}e.exports=patch;function patch(e){if(s.hasOwnProperty("O_SYMLINK")&&process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)){patchLchmod(e)}if(!e.lutimes){patchLutimes(e)}e.chown=chownFix(e.chown);e.fchown=chownFix(e.fchown);e.lchown=chownFix(e.lchown);e.chmod=chmodFix(e.chmod);e.fchmod=chmodFix(e.fchmod);e.lchmod=chmodFix(e.lchmod);e.chownSync=chownFixSync(e.chownSync);e.fchownSync=chownFixSync(e.fchownSync);e.lchownSync=chownFixSync(e.lchownSync);e.chmodSync=chmodFixSync(e.chmodSync);e.fchmodSync=chmodFixSync(e.fchmodSync);e.lchmodSync=chmodFixSync(e.lchmodSync);e.stat=statFix(e.stat);e.fstat=statFix(e.fstat);e.lstat=statFix(e.lstat);e.statSync=statFixSync(e.statSync);e.fstatSync=statFixSync(e.fstatSync);e.lstatSync=statFixSync(e.lstatSync);if(e.chmod&&!e.lchmod){e.lchmod=function(e,t,r){if(r)process.nextTick(r)};e.lchmodSync=function(){}}if(e.chown&&!e.lchown){e.lchown=function(e,t,r,s){if(s)process.nextTick(s)};e.lchownSync=function(){}}if(u==="win32"){e.rename=typeof e.rename!=="function"?e.rename:function(t){function rename(r,s,a){var o=Date.now();var u=0;t(r,s,(function CB(c){if(c&&(c.code==="EACCES"||c.code==="EPERM")&&Date.now()-o<6e4){setTimeout((function(){e.stat(s,(function(e,o){if(e&&e.code==="ENOENT")t(r,s,CB);else a(c)}))}),u);if(u<100)u+=10;return}if(a)a(c)}))}if(Object.setPrototypeOf)Object.setPrototypeOf(rename,t);return rename}(e.rename)}e.read=typeof e.read!=="function"?e.read:function(t){function read(r,s,a,o,u,c){var f;if(c&&typeof c==="function"){var d=0;f=function(p,h,v){if(p&&p.code==="EAGAIN"&&d<10){d++;return t.call(e,r,s,a,o,u,f)}c.apply(this,arguments)}}return t.call(e,r,s,a,o,u,f)}if(Object.setPrototypeOf)Object.setPrototypeOf(read,t);return read}(e.read);e.readSync=typeof e.readSync!=="function"?e.readSync:function(t){return function(r,s,a,o,u){var c=0;while(true){try{return t.call(e,r,s,a,o,u)}catch(e){if(e.code==="EAGAIN"&&c<10){c++;continue}throw e}}}}(e.readSync);function patchLchmod(e){e.lchmod=function(t,r,a){e.open(t,s.O_WRONLY|s.O_SYMLINK,r,(function(t,s){if(t){if(a)a(t);return}e.fchmod(s,r,(function(t){e.close(s,(function(e){if(a)a(t||e)}))}))}))};e.lchmodSync=function(t,r){var a=e.openSync(t,s.O_WRONLY|s.O_SYMLINK,r);var o=true;var u;try{u=e.fchmodSync(a,r);o=false}finally{if(o){try{e.closeSync(a)}catch(e){}}else{e.closeSync(a)}}return u}}function patchLutimes(e){if(s.hasOwnProperty("O_SYMLINK")&&e.futimes){e.lutimes=function(t,r,a,o){e.open(t,s.O_SYMLINK,(function(t,s){if(t){if(o)o(t);return}e.futimes(s,r,a,(function(t){e.close(s,(function(e){if(o)o(t||e)}))}))}))};e.lutimesSync=function(t,r,a){var o=e.openSync(t,s.O_SYMLINK);var u;var c=true;try{u=e.futimesSync(o,r,a);c=false}finally{if(c){try{e.closeSync(o)}catch(e){}}else{e.closeSync(o)}}return u}}else if(e.futimes){e.lutimes=function(e,t,r,s){if(s)process.nextTick(s)};e.lutimesSync=function(){}}}function chmodFix(t){if(!t)return t;return function(r,s,a){return t.call(e,r,s,(function(e){if(chownErOk(e))e=null;if(a)a.apply(this,arguments)}))}}function chmodFixSync(t){if(!t)return t;return function(r,s){try{return t.call(e,r,s)}catch(e){if(!chownErOk(e))throw e}}}function chownFix(t){if(!t)return t;return function(r,s,a,o){return t.call(e,r,s,a,(function(e){if(chownErOk(e))e=null;if(o)o.apply(this,arguments)}))}}function chownFixSync(t){if(!t)return t;return function(r,s,a){try{return t.call(e,r,s,a)}catch(e){if(!chownErOk(e))throw e}}}function statFix(t){if(!t)return t;return function(r,s,a){if(typeof s==="function"){a=s;s=null}function callback(e,t){if(t){if(t.uid<0)t.uid+=4294967296;if(t.gid<0)t.gid+=4294967296}if(a)a.apply(this,arguments)}return s?t.call(e,r,s,callback):t.call(e,r,callback)}}function statFixSync(t){if(!t)return t;return function(r,s){var a=s?t.call(e,r,s):t.call(e,r);if(a){if(a.uid<0)a.uid+=4294967296;if(a.gid<0)a.gid+=4294967296}return a}}function chownErOk(e){if(!e)return true;if(e.code==="ENOSYS")return true;var t=!process.getuid||process.getuid()!==0;if(t){if(e.code==="EINVAL"||e.code==="EPERM")return true}return false}}},5214:(e,t,r)=>{"use strict";var s=r(2037);var a=e.exports=function(){if(s.type()=="Windows_NT"){return false}var e=/UTF-?8$/i;var t=process.env.LC_ALL||process.env.LC_CTYPE||process.env.LANG;return e.test(t)}},2842:(e,t,r)=>{try{var s=r(3837);if(typeof s.inherits!=="function")throw"";e.exports=s.inherits}catch(t){e.exports=r(3782)}},3782:e=>{if(typeof Object.create==="function"){e.exports=function inherits(e,t){if(t){e.super_=t;e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:false,writable:true,configurable:true}})}}}else{e.exports=function inherits(e,t){if(t){e.super_=t;var TempCtor=function(){};TempCtor.prototype=t.prototype;e.prototype=new TempCtor;e.prototype.constructor=e}}}},3279:(e,t,r)=>{"use strict";var s=r(3979);e.exports=function(e){if(s(e)){return false}if(e>=4352&&(e<=4447||9001===e||9002===e||11904<=e&&e<=12871&&e!==12351||12880<=e&&e<=19903||19968<=e&&e<=42182||43360<=e&&e<=43388||44032<=e&&e<=55203||63744<=e&&e<=64255||65040<=e&&e<=65049||65072<=e&&e<=65131||65281<=e&&e<=65376||65504<=e&&e<=65510||110592<=e&&e<=110593||127488<=e&&e<=127569||131072<=e&&e<=262141)){return true}return false}},8502:e=>{"use strict";const isFullwidthCodePoint=e=>{if(Number.isNaN(e)){return false}if(e>=4352&&(e<=4447||e===9001||e===9002||11904<=e&&e<=12871&&e!==12351||12880<=e&&e<=19903||19968<=e&&e<=42182||43360<=e&&e<=43388||44032<=e&&e<=55203||63744<=e&&e<=64255||65040<=e&&e<=65049||65072<=e&&e<=65131||65281<=e&&e<=65376||65504<=e&&e<=65510||110592<=e&&e<=110593||127488<=e&&e<=127569||131072<=e&&e<=262141)){return true}return false};e.exports=isFullwidthCodePoint;e.exports["default"]=isFullwidthCodePoint},1551:e=>{var t={}.toString;e.exports=Array.isArray||function(e){return t.call(e)=="[object Array]"}},7663:(module,__unused_webpack_exports,__nccwpck_require__)=>{var fs=__nccwpck_require__(7147);var path=__nccwpck_require__(1017);var os=__nccwpck_require__(2037);var runtimeRequire=true?eval("require"):0;var vars=process.config&&process.config.variables||{};var prebuildsOnly=!!process.env.PREBUILDS_ONLY;var abi=process.versions.modules;var runtime=isElectron()?"electron":"node";var arch=os.arch();var platform=os.platform();var libc=process.env.LIBC||(isAlpine(platform)?"musl":"glibc");var armv=process.env.ARM_VERSION||(arch==="arm64"?"8":vars.arm_version)||"";var uv=(process.versions.uv||"").split(".")[0];module.exports=load;function load(e){return runtimeRequire(load.path(e))}load.path=function(e){e=path.resolve(e||".");try{var t=runtimeRequire(path.join(e,"package.json")).name.toUpperCase().replace(/-/g,"_");if(process.env[t+"_PREBUILD"])e=process.env[t+"_PREBUILD"]}catch(e){}if(!prebuildsOnly){var r=getFirst(path.join(e,"build/Release"),matchBuild);if(r)return r;var s=getFirst(path.join(e,"build/Debug"),matchBuild);if(s)return s}var a=resolve(e);if(a)return a;var o=resolve(path.dirname(process.execPath));if(o)return o;var u=["platform="+platform,"arch="+arch,"runtime="+runtime,"abi="+abi,"uv="+uv,armv?"armv="+armv:"","libc="+libc,"node="+process.versions.node,process.versions&&process.versions.electron?"electron="+process.versions.electron:"",true?"webpack=true":0].filter(Boolean).join(" ");throw new Error("No native build was found for "+u+"\n loaded from: "+e+"\n");function resolve(e){var t=path.join(e,"prebuilds",platform+"-"+arch);var r=readdirSync(t).map(parseTags);var s=r.filter(matchTags(runtime,abi));var a=s.sort(compareTags(runtime))[0];if(a)return path.join(t,a.file)}};function readdirSync(e){try{return fs.readdirSync(e)}catch(e){return[]}}function getFirst(e,t){var r=readdirSync(e).filter(t);return r[0]&&path.join(e,r[0])}function matchBuild(e){return/\.node$/.test(e)}function parseTags(e){var t=e.split(".");var r=t.pop();var s={file:e,specificity:0};if(r!=="node")return;for(var a=0;ar.specificity?-1:1}else{return 0}}}function isElectron(){if(process.versions&&process.versions.electron)return true;if(process.env.ELECTRON_RUN_AS_NODE)return true;return typeof window!=="undefined"&&window.process&&window.process.type==="renderer"}function isAlpine(e){return e==="linux"&&fs.existsSync("/etc/alpine-release")}load.parseTags=parseTags;load.matchTags=matchTags;load.compareTags=compareTags},1758:(e,t,r)=>{var s=process.env.DEBUG_NOPT||process.env.NOPT_DEBUG?function(){console.error.apply(console,arguments)}:function(){};var a=r(7310),o=r(1017),u=r(2781).Stream,c=r(351),f=r(2037);e.exports=t=nopt;t.clean=clean;t.typeDefs={String:{type:String,validate:validateString},Boolean:{type:Boolean,validate:validateBoolean},url:{type:a,validate:validateUrl},Number:{type:Number,validate:validateNumber},path:{type:o,validate:validatePath},Stream:{type:u,validate:validateStream},Date:{type:Date,validate:validateDate}};function nopt(e,r,a,o){a=a||process.argv;e=e||{};r=r||{};if(typeof o!=="number")o=2;s(e,r,a,o);a=a.slice(o);var u={},c,f={remain:[],cooked:a,original:a.slice(0)};parse(a,u,f.remain,e,r);clean(u,e,t.typeDefs);u.argv=f;Object.defineProperty(u.argv,"toString",{value:function(){return this.original.map(JSON.stringify).join(" ")},enumerable:false});return u}function clean(e,r,a){a=a||t.typeDefs;var o={},u=[false,true,null,String,Array];Object.keys(e).forEach((function(c){if(c==="argv")return;var f=e[c],d=Array.isArray(f),p=r[c];if(!d)f=[f];if(!p)p=u;if(p===Array)p=u.concat(Array);if(!Array.isArray(p))p=[p];s("val=%j",f);s("types=",p);f=f.map((function(u){if(typeof u==="string"){s("string %j",u);u=u.trim();if(u==="null"&&~p.indexOf(null)||u==="true"&&(~p.indexOf(true)||~p.indexOf(Boolean))||u==="false"&&(~p.indexOf(false)||~p.indexOf(Boolean))){u=JSON.parse(u);s("jsonable %j",u)}else if(~p.indexOf(Number)&&!isNaN(u)){s("convert to number",u);u=+u}else if(~p.indexOf(Date)&&!isNaN(Date.parse(u))){s("convert to date",u);u=new Date(u)}}if(!r.hasOwnProperty(c)){return u}if(u===false&&~p.indexOf(null)&&!(~p.indexOf(false)||~p.indexOf(Boolean))){u=null}var f={};f[c]=u;s("prevalidated val",f,u,r[c]);if(!validate(f,c,u,r[c],a)){if(t.invalidHandler){t.invalidHandler(c,u,r[c],e)}else if(t.invalidHandler!==false){s("invalid: "+c+"="+u,r[c])}return o}s("validated val",f,u,r[c]);return f[c]})).filter((function(e){return e!==o}));if(!f.length&&p.indexOf(Array)===-1){s("VAL HAS NO LENGTH, DELETE IT",f,c,p.indexOf(Array));delete e[c]}else if(d){s(d,e[c],f);e[c]=f}else e[c]=f[0];s("k=%s val=%j",c,f,e[c])}))}function validateString(e,t,r){e[t]=String(r)}function validatePath(e,t,r){if(r===true)return false;if(r===null)return true;r=String(r);var s=process.platform==="win32",a=s?/^~(\/|\\)/:/^~\//,u=f.homedir();if(u&&r.match(a)){e[t]=o.resolve(u,r.substr(2))}else{e[t]=o.resolve(r)}return true}function validateNumber(e,t,r){s("validate Number %j %j %j",t,r,isNaN(r));if(isNaN(r))return false;e[t]=+r}function validateDate(e,t,r){var a=Date.parse(r);s("validate Date %j %j %j",t,r,a);if(isNaN(a))return false;e[t]=new Date(r)}function validateBoolean(e,t,r){if(r instanceof Boolean)r=r.valueOf();else if(typeof r==="string"){if(!isNaN(r))r=!!+r;else if(r==="null"||r==="false")r=false;else r=true}else r=!!r;e[t]=r}function validateUrl(e,t,r){r=a.parse(String(r));if(!r.host)return false;e[t]=r.href}function validateStream(e,t,r){if(!(r instanceof u))return false;e[t]=r}function validate(e,t,r,a,o){if(Array.isArray(a)){for(var u=0,c=a.length;u1){var D=h.indexOf("=");if(D>-1){v=true;var g=h.substr(D+1);h=h.substr(0,D);e.splice(p,1,h,g)}var y=resolveShort(h,o,d,f);s("arg=%j shRes=%j",h,y);if(y){s(h,y);e.splice.apply(e,[p,1].concat(y));if(h!==y[0]){p--;continue}}h=h.replace(/^-+/,"");var m=null;while(h.toLowerCase().indexOf("no-")===0){m=!m;h=h.substr(3)}if(f[h])h=f[h];var _=a[h];var E=Array.isArray(_);if(E&&_.length===1){E=false;_=_[0]}var w=_===Array||E&&_.indexOf(Array)!==-1;if(!a.hasOwnProperty(h)&&t.hasOwnProperty(h)){if(!Array.isArray(t[h]))t[h]=[t[h]];w=true}var x,F=e[p+1];var C=typeof m==="boolean"||_===Boolean||E&&_.indexOf(Boolean)!==-1||typeof _==="undefined"&&!v||F==="false"&&(_===null||E&&~_.indexOf(null));if(C){x=!m;if(F==="true"||F==="false"){x=JSON.parse(F);F=null;if(m)x=!x;p++}if(E&&F){if(~_.indexOf(F)){x=F;p++}else if(F==="null"&&~_.indexOf(null)){x=null;p++}else if(!F.match(/^-{2,}[^-]/)&&!isNaN(F)&&~_.indexOf(Number)){x=+F;p++}else if(!F.match(/^-[^-]/)&&~_.indexOf(String)){x=F;p++}}if(w)(t[h]=t[h]||[]).push(x);else t[h]=x;continue}if(_===String){if(F===undefined){F=""}else if(F.match(/^-{1,2}[^-]+/)){F="";p--}}if(F&&F.match(/^-{2,}$/)){F=undefined;p--}x=F===undefined?true:F;if(w)(t[h]=t[h]||[]).push(x);else t[h]=x;p++;continue}r.push(h)}}function resolveShort(e,t,r,a){e=e.replace(/^-+/,"");if(a[e]===e)return null;if(t[e]){if(t[e]&&!Array.isArray(t[e]))t[e]=t[e].split(/\s+/);return t[e]}var o=t.___singles;if(!o){o=Object.keys(t).filter((function(e){return e.length===1})).reduce((function(e,t){e[t]=true;return e}),{});t.___singles=o;s("shorthand singles",o)}var u=e.split("").filter((function(e){return o[e]}));if(u.join("")===e)return u.map((function(e){return t[e]})).reduce((function(e,t){return e.concat(t)}),[]);if(a[e]&&!t[e])return null;if(r[e])e=r[e];if(t[e]&&!Array.isArray(t[e]))t[e]=t[e].split(/\s+/);return t[e]}},9544:(e,t,r)=>{"use strict";var s=r(4906);var a=r(287);var o=r(2361).EventEmitter;var u=t=e.exports=new o;var c=r(3837);var f=r(2656);var d=r(3844);f(true);var p=process.stderr;Object.defineProperty(u,"stream",{set:function(e){p=e;if(this.gauge)this.gauge.setWriteTo(p,p)},get:function(){return p}});var h;u.useColor=function(){return h!=null?h:p.isTTY};u.enableColor=function(){h=true;this.gauge.setTheme({hasColor:h,hasUnicode:v})};u.disableColor=function(){h=false;this.gauge.setTheme({hasColor:h,hasUnicode:v})};u.level="info";u.gauge=new a(p,{enabled:false,theme:{hasColor:u.useColor()},template:[{type:"progressbar",length:20},{type:"activityIndicator",kerning:1,length:1},{type:"section",default:""},":",{type:"logline",kerning:1,default:""}]});u.tracker=new s.TrackerGroup;u.progressEnabled=u.gauge.isEnabled();var v;u.enableUnicode=function(){v=true;this.gauge.setTheme({hasColor:this.useColor(),hasUnicode:v})};u.disableUnicode=function(){v=false;this.gauge.setTheme({hasColor:this.useColor(),hasUnicode:v})};u.setGaugeThemeset=function(e){this.gauge.setThemeset(e)};u.setGaugeTemplate=function(e){this.gauge.setTemplate(e)};u.enableProgress=function(){if(this.progressEnabled)return;this.progressEnabled=true;this.tracker.on("change",this.showProgress);if(this._pause)return;this.gauge.enable()};u.disableProgress=function(){if(!this.progressEnabled)return;this.progressEnabled=false;this.tracker.removeListener("change",this.showProgress);this.gauge.disable()};var D=["newGroup","newItem","newStream"];var mixinLog=function(e){Object.keys(u).forEach((function(t){if(t[0]==="_")return;if(D.filter((function(e){return e===t})).length)return;if(e[t])return;if(typeof u[t]!=="function")return;var r=u[t];e[t]=function(){return r.apply(u,arguments)}}));if(e instanceof s.TrackerGroup){D.forEach((function(t){var r=e[t];e[t]=function(){return mixinLog(r.apply(e,arguments))}}))}return e};D.forEach((function(e){u[e]=function(){return mixinLog(this.tracker[e].apply(this.tracker,arguments))}}));u.clearProgress=function(e){if(!this.progressEnabled)return e&&process.nextTick(e);this.gauge.hide(e)};u.showProgress=function(e,t){if(!this.progressEnabled)return;var r={};if(e)r.section=e;var s=u.record[u.record.length-1];if(s){r.subsection=s.prefix;var a=u.disp[s.level]||s.level;var o=this._format(a,u.style[s.level]);if(s.prefix)o+=" "+this._format(s.prefix,this.prefixStyle);o+=" "+s.message.split(/\r?\n/)[0];r.logline=o}r.completed=t||this.tracker.completed();this.gauge.show(r)}.bind(u);u.pause=function(){this._paused=true;if(this.progressEnabled)this.gauge.disable()};u.resume=function(){if(!this._paused)return;this._paused=false;var e=this._buffer;this._buffer=[];e.forEach((function(e){this.emitLog(e)}),this);if(this.progressEnabled)this.gauge.enable()};u._buffer=[];var g=0;u.record=[];u.maxRecordSize=1e4;u.log=function(e,t,r){var s=this.levels[e];if(s===undefined){return this.emit("error",new Error(c.format("Undefined log level: %j",e)))}var a=new Array(arguments.length-2);var o=null;for(var u=2;up/10){var v=Math.floor(p*.9);this.record=this.record.slice(-1*v)}this.emitLog(d)}.bind(u);u.emitLog=function(e){if(this._paused){this._buffer.push(e);return}if(this.progressEnabled)this.gauge.pulse(e.prefix);var t=this.levels[e.level];if(t===undefined)return;if(t0&&!isFinite(t))return;var r=u.disp[e.level]!=null?u.disp[e.level]:e.level;this.clearProgress();e.message.split(/\r?\n/).forEach((function(t){if(this.heading){this.write(this.heading,this.headingStyle);this.write(" ")}this.write(r,u.style[e.level]);var s=e.prefix||"";if(s)this.write(" ");this.write(s,this.prefixStyle);this.write(" "+t+"\n")}),this);this.showProgress()};u._format=function(e,t){if(!p)return;var r="";if(this.useColor()){t=t||{};var s=[];if(t.fg)s.push(t.fg);if(t.bg)s.push("bg"+t.bg[0].toUpperCase()+t.bg.slice(1));if(t.bold)s.push("bold");if(t.underline)s.push("underline");if(t.inverse)s.push("inverse");if(s.length)r+=d.color(s);if(t.beep)r+=d.beep()}r+=e;if(this.useColor()){r+=d.color("reset")}return r};u.write=function(e,t){if(!p)return;p.write(this._format(e,t))};u.addLevel=function(e,t,r,s){if(s==null)s=e;this.levels[e]=t;this.style[e]=r;if(!this[e]){this[e]=function(){var t=new Array(arguments.length+1);t[0]=e;for(var r=0;r{"use strict";e.exports=Number.isNaN||function(e){return e!==e}},3540:e=>{"use strict"; +(()=>{var __webpack_modules__={5841:(e,t,r)=>{"use strict";e.exports=t;t.mockS3Http=r(9361).get_mockS3Http();t.mockS3Http("on");const s=t.mockS3Http("get");const a=r(7147);const o=r(1017);const u=r(1758);const c=r(9544);c.disableProgress();const f=r(5977);const d=r(2361).EventEmitter;const p=r(3837).inherits;const h=["clean","install","reinstall","build","rebuild","package","testpackage","publish","unpublish","info","testbinary","reveal","configure"];const v={};c.heading="node-pre-gyp";if(s){c.warn(`mocking s3 to ${process.env.node_pre_gyp_mock_s3}`)}Object.defineProperty(t,"find",{get:function(){return r(5921).find},enumerable:true});function Run({package_json_path:e="./package.json",argv:t}){this.package_json_path=e;this.commands={};const r=this;h.forEach((e=>{r.commands[e]=function(t,s){c.verbose("command",e,t);return require("./"+e)(r,t,s)}}));this.parseArgv(t);this.binaryHostSet=false}p(Run,d);t.Run=Run;const D=Run.prototype;D.package=r(7399);D.configDefs={help:Boolean,arch:String,debug:Boolean,directory:String,proxy:String,loglevel:String};D.shorthands={release:"--no-debug",C:"--directory",debug:"--debug",j:"--jobs",silent:"--loglevel=silent",silly:"--loglevel=silly",verbose:"--loglevel=verbose"};D.aliases=v;D.parseArgv=function parseOpts(e){this.opts=u(this.configDefs,this.shorthands,e);this.argv=this.opts.argv.remain.slice();const t=this.todo=[];e=this.argv.map((e=>{if(e in this.aliases){e=this.aliases[e]}return e}));e.slice().forEach((r=>{if(r in this.commands){const s=e.splice(0,e.indexOf(r));e.shift();if(t.length>0){t[t.length-1].args=s}t.push({name:r,args:[]})}}));if(t.length>0){t[t.length-1].args=e.splice(0)}let r=this.package_json_path;if(this.opts.directory){r=o.join(this.opts.directory,r)}this.package_json=JSON.parse(a.readFileSync(r));this.todo=f.expand_commands(this.package_json,this.opts,t);const s="npm_config_";Object.keys(process.env).forEach((e=>{if(e.indexOf(s)!==0)return;const t=process.env[e];if(e===s+"loglevel"){c.level=t}else{e=e.substring(s.length);if(e==="argv"){if(this.opts.argv&&this.opts.argv.remain&&this.opts.argv.remain.length){}else{this.opts[e]=t}}else{this.opts[e]=t}}}));if(this.opts.loglevel){c.level=this.opts.loglevel}c.resume()};D.setBinaryHostProperty=function(e){if(this.binaryHostSet){return this.package_json.binary.host}const t=this.package_json;if(!t||!t.binary||t.binary.host){return""}if(!t.binary.staging_host||!t.binary.production_host){return""}let r="production_host";if(e==="publish"){r="staging_host"}const s=process.env.node_pre_gyp_s3_host;if(s==="staging"||s==="production"){r=`${s}_host`}else if(this.opts["s3_host"]==="staging"||this.opts["s3_host"]==="production"){r=`${this.opts["s3_host"]}_host`}else if(this.opts["s3_host"]||s){throw new Error(`invalid s3_host ${this.opts["s3_host"]||s}`)}t.binary.host=t.binary[r];this.binaryHostSet=true;return t.binary.host};D.usage=function usage(){const e=[""," Usage: node-pre-gyp [options]",""," where is one of:",h.map((e=>" - "+e+" - "+require("./"+e).usage)).join("\n"),"","node-pre-gyp@"+this.version+" "+o.resolve(__dirname,".."),"node@"+process.versions.node].join("\n");return e};Object.defineProperty(D,"version",{get:function(){return this.package.version},enumerable:true})},5921:(e,t,r)=>{"use strict";const s=r(5841);const a=r(2821);const o=r(5977);const u=r(7147).existsSync||r(1017).existsSync;const c=r(1017);e.exports=t;t.usage="Finds the require path for the node-pre-gyp installed module";t.validate=function(e,t){a.validate_config(e,t)};t.find=function(e,t){if(!u(e)){throw new Error(e+"does not exist")}const r=new s.Run({package_json_path:e,argv:process.argv});r.setBinaryHostProperty();const f=r.package_json;a.validate_config(f,t);let d;if(o.get_napi_build_versions(f,t)){d=o.get_best_napi_build_version(f,t)}t=t||{};if(!t.module_root)t.module_root=c.dirname(e);const p=a.evaluate(f,t,d);return p.module}},5977:(e,t,r)=>{"use strict";const s=r(7147);e.exports=t;const a=process.version.substr(1).replace(/-.*$/,"").split(".").map((e=>+e));const o=["build","clean","configure","package","publish","reveal","testbinary","testpackage","unpublish"];const u="napi_build_version=";e.exports.get_napi_version=function(){let e=process.versions.napi;if(!e){if(a[0]===9&&a[1]>=3)e=2;else if(a[0]===8)e=1}return e};e.exports.get_napi_version_as_string=function(t){const r=e.exports.get_napi_version(t);return r?""+r:""};e.exports.validate_package_json=function(t,r){const s=t.binary;const a=pathOK(s.module_path);const o=pathOK(s.remote_path);const u=pathOK(s.package_name);const c=e.exports.get_napi_build_versions(t,r,true);const f=e.exports.get_napi_build_versions_raw(t);if(c){c.forEach((e=>{if(!(parseInt(e,10)===e&&e>0)){throw new Error("All values specified in napi_versions must be positive integers.")}}))}if(c&&(!a||!o&&!u)){throw new Error("When napi_versions is specified; module_path and either remote_path or "+"package_name must contain the substitution string '{napi_build_version}`.")}if((a||o||u)&&!f){throw new Error("When the substitution string '{napi_build_version}` is specified in "+"module_path, remote_path, or package_name; napi_versions must also be specified.")}if(c&&!e.exports.get_best_napi_build_version(t,r)&&e.exports.build_napi_only(t)){throw new Error("The Node-API version of this Node instance is "+e.exports.get_napi_version(r?r.target:undefined)+". "+"This module supports Node-API version(s) "+e.exports.get_napi_build_versions_raw(t)+". "+"This Node instance cannot run this module.")}if(f&&!c&&e.exports.build_napi_only(t)){throw new Error("The Node-API version of this Node instance is "+e.exports.get_napi_version(r?r.target:undefined)+". "+"This module supports Node-API version(s) "+e.exports.get_napi_build_versions_raw(t)+". "+"This Node instance cannot run this module.")}};function pathOK(e){return e&&(e.indexOf("{napi_build_version}")!==-1||e.indexOf("{node_napi_label}")!==-1)}e.exports.expand_commands=function(t,r,s){const a=[];const c=e.exports.get_napi_build_versions(t,r);s.forEach((s=>{if(c&&s.name==="install"){const o=e.exports.get_best_napi_build_version(t,r);const c=o?[u+o]:[];a.push({name:s.name,args:c})}else if(c&&o.indexOf(s.name)!==-1){c.forEach((e=>{const t=s.args.slice();t.push(u+e);a.push({name:s.name,args:t})}))}else{a.push(s)}}));return a};e.exports.get_napi_build_versions=function(t,s,a){const o=r(9544);let u=[];const c=e.exports.get_napi_version(s?s.target:undefined);if(t.binary&&t.binary.napi_versions){t.binary.napi_versions.forEach((e=>{const t=u.indexOf(e)!==-1;if(!t&&c&&e<=c){u.push(e)}else if(a&&!t&&c){o.info("This Node instance does not support builds for Node-API version",e)}}))}if(s&&s["build-latest-napi-version-only"]){let e=0;u.forEach((t=>{if(t>e)e=t}));u=e?[e]:[]}return u.length?u:undefined};e.exports.get_napi_build_versions_raw=function(e){const t=[];if(e.binary&&e.binary.napi_versions){e.binary.napi_versions.forEach((e=>{if(t.indexOf(e)===-1){t.push(e)}}))}return t.length?t:undefined};e.exports.get_command_arg=function(e){return u+e};e.exports.get_napi_build_version_from_command_args=function(e){for(let t=0;t{if(e>s&&e<=t){s=e}}))}return s===0?undefined:s};e.exports.build_napi_only=function(e){return e.binary&&e.binary.package_name&&e.binary.package_name.indexOf("{node_napi_label}")===-1}},9361:(e,t,r)=>{"use strict";e.exports=t;const s=r(7310);const a=r(7147);const o=r(1017);e.exports.detect=function(e,t){const r=e.hosted_path;const a=s.parse(r);t.prefix=!a.pathname||a.pathname==="/"?"":a.pathname.replace("/","");if(e.bucket&&e.region){t.bucket=e.bucket;t.region=e.region;t.endpoint=e.host;t.s3ForcePathStyle=e.s3ForcePathStyle}else{const e=a.hostname.split(".s3");const r=e[0];if(!r){return}if(!t.bucket){t.bucket=r}if(!t.region){const r=e[1].slice(1).split(".")[0];if(r==="amazonaws"){t.region="us-east-1"}else{t.region=r}}}};e.exports.get_s3=function(e){if(process.env.node_pre_gyp_mock_s3){const e=r(3930);const t=r(2037);e.config.basePath=`${t.tmpdir()}/mock`;const s=e.S3();const wcb=e=>(t,...r)=>{if(t&&t.code==="ENOENT"){t.code="NotFound"}return e(t,...r)};return{listObjects(e,t){return s.listObjects(e,wcb(t))},headObject(e,t){return s.headObject(e,wcb(t))},deleteObject(e,t){return s.deleteObject(e,wcb(t))},putObject(e,t){return s.putObject(e,wcb(t))}}}const t=r(2355);t.config.update(e);const s=new t.S3;return{listObjects(e,t){return s.listObjects(e,t)},headObject(e,t){return s.headObject(e,t)},deleteObject(e,t){return s.deleteObject(e,t)},putObject(e,t){return s.putObject(e,t)}}};e.exports.get_mockS3Http=function(){let e=false;if(!process.env.node_pre_gyp_mock_s3){return()=>e}const t=r(4997);const s="https://mapbox-node-pre-gyp-public-testing-bucket.s3.us-east-1.amazonaws.com";const u=process.env.node_pre_gyp_mock_s3+"/mapbox-node-pre-gyp-public-testing-bucket";const mock_http=()=>{function get(e,t){const r=o.join(u,e.replace("%2B","+"));try{a.accessSync(r,a.constants.R_OK)}catch(e){return[404,"not found\n"]}return[200,a.createReadStream(r)]}return t(s).persist().get((()=>e)).reply(get)};mock_http(t,s,u);const mockS3Http=t=>{const r=e;if(t==="off"){e=false}else if(t==="on"){e=true}else if(t!=="get"){throw new Error(`illegal action for setMockHttp ${t}`)}return r};return mockS3Http}},2821:(e,t,r)=>{"use strict";e.exports=t;const s=r(1017);const a=r(7849);const o=r(7310);const u=r(5104);const c=r(5977);let f;if(process.env.NODE_PRE_GYP_ABI_CROSSWALK){f=require(process.env.NODE_PRE_GYP_ABI_CROSSWALK)}else{f=r(9448)}const d={};Object.keys(f).forEach((e=>{const t=e.split(".")[0];if(!d[t]){d[t]=e}}));function get_electron_abi(e,t){if(!e){throw new Error("get_electron_abi requires valid runtime arg")}if(typeof t==="undefined"){throw new Error("Empty target version is not supported if electron is the target.")}const r=a.parse(t);return e+"-v"+r.major+"."+r.minor}e.exports.get_electron_abi=get_electron_abi;function get_node_webkit_abi(e,t){if(!e){throw new Error("get_node_webkit_abi requires valid runtime arg")}if(typeof t==="undefined"){throw new Error("Empty target version is not supported if node-webkit is the target.")}return e+"-v"+t}e.exports.get_node_webkit_abi=get_node_webkit_abi;function get_node_abi(e,t){if(!e){throw new Error("get_node_abi requires valid runtime arg")}if(!t){throw new Error("get_node_abi requires valid process.versions object")}const r=a.parse(t.node);if(r.major===0&&r.minor%2){return e+"-v"+t.node}else{return t.modules?e+"-v"+ +t.modules:"v8-"+t.v8.split(".").slice(0,2).join(".")}}e.exports.get_node_abi=get_node_abi;function get_runtime_abi(e,t){if(!e){throw new Error("get_runtime_abi requires valid runtime arg")}if(e==="node-webkit"){return get_node_webkit_abi(e,t||process.versions["node-webkit"])}else if(e==="electron"){return get_electron_abi(e,t||process.versions.electron)}else{if(e!=="node"){throw new Error("Unknown Runtime: '"+e+"'")}if(!t){return get_node_abi(e,process.versions)}else{let r;if(f[t]){r=f[t]}else{const e=t.split(".").map((e=>+e));if(e.length!==3){throw new Error("Unknown target version: "+t)}const s=e[0];let a=e[1];let o=e[2];if(s===1){while(true){if(a>0)--a;if(o>0)--o;const e=""+s+"."+a+"."+o;if(f[e]){r=f[e];console.log("Warning: node-pre-gyp could not find exact match for "+t);console.log("Warning: but node-pre-gyp successfully choose "+e+" as ABI compatible target");break}if(a===0&&o===0){break}}}else if(s>=2){if(d[s]){r=f[d[s]];console.log("Warning: node-pre-gyp could not find exact match for "+t);console.log("Warning: but node-pre-gyp successfully choose "+d[s]+" as ABI compatible target")}}else if(s===0){if(e[1]%2===0){while(--o>0){const e=""+s+"."+a+"."+o;if(f[e]){r=f[e];console.log("Warning: node-pre-gyp could not find exact match for "+t);console.log("Warning: but node-pre-gyp successfully choose "+e+" as ABI compatible target");break}}}}}if(!r){throw new Error("Unsupported target version: "+t)}const s={node:t,v8:r.v8+".0",modules:r.node_abi>1?r.node_abi:undefined};return get_node_abi(e,s)}}}e.exports.get_runtime_abi=get_runtime_abi;const p=["module_name","module_path","host"];function validate_config(e,t){const r=e.name+" package.json is not node-pre-gyp ready:\n";const s=[];if(!e.main){s.push("main")}if(!e.version){s.push("version")}if(!e.name){s.push("name")}if(!e.binary){s.push("binary")}const a=e.binary;if(a){p.forEach((e=>{if(!a[e]||typeof a[e]!=="string"){s.push("binary."+e)}}))}if(s.length>=1){throw new Error(r+"package.json must declare these properties: \n"+s.join("\n"))}if(a){const e=o.parse(a.host).protocol;if(e==="http:"){throw new Error("'host' protocol ("+e+") is invalid - only 'https:' is accepted")}}c.validate_package_json(e,t)}e.exports.validate_config=validate_config;function eval_template(e,t){Object.keys(t).forEach((r=>{const s="{"+r+"}";while(e.indexOf(s)>-1){e=e.replace(s,t[r])}}));return e}function fix_slashes(e){if(e.slice(-1)!=="/"){return e+"/"}return e}function drop_double_slashes(e){return e.replace(/\/\//g,"/")}function get_process_runtime(e){let t="node";if(e["node-webkit"]){t="node-webkit"}else if(e.electron){t="electron"}return t}e.exports.get_process_runtime=get_process_runtime;const h="{module_name}-v{version}-{node_abi}-{platform}-{arch}.tar.gz";const v="";e.exports.evaluate=function(e,t,r){t=t||{};validate_config(e,t);const f=e.version;const d=a.parse(f);const p=t.runtime||get_process_runtime(process.versions);const D={name:e.name,configuration:t.debug?"Debug":"Release",debug:t.debug,module_name:e.binary.module_name,version:d.version,prerelease:d.prerelease.length?d.prerelease.join("."):"",build:d.build.length?d.build.join("."):"",major:d.major,minor:d.minor,patch:d.patch,runtime:p,node_abi:get_runtime_abi(p,t.target),node_abi_napi:c.get_napi_version(t.target)?"napi":get_runtime_abi(p,t.target),napi_version:c.get_napi_version(t.target),napi_build_version:r||"",node_napi_label:r?"napi-v"+r:get_runtime_abi(p,t.target),target:t.target||"",platform:t.target_platform||process.platform,target_platform:t.target_platform||process.platform,arch:t.target_arch||process.arch,target_arch:t.target_arch||process.arch,libc:t.target_libc||u.family||"unknown",module_main:e.main,toolset:t.toolset||"",bucket:e.binary.bucket,region:e.binary.region,s3ForcePathStyle:e.binary.s3ForcePathStyle||false};const g=D.module_name.replace("-","_");const y=process.env["npm_config_"+g+"_binary_host_mirror"]||e.binary.host;D.host=fix_slashes(eval_template(y,D));D.module_path=eval_template(e.binary.module_path,D);if(t.module_root){D.module_path=s.join(t.module_root,D.module_path)}else{D.module_path=s.resolve(D.module_path)}D.module=s.join(D.module_path,D.module_name+".node");D.remote_path=e.binary.remote_path?drop_double_slashes(fix_slashes(eval_template(e.binary.remote_path,D))):v;const m=e.binary.package_name?e.binary.package_name:h;D.package_name=eval_template(m,D);D.staged_tarball=s.join("build/stage",D.remote_path,D.package_name);D.hosted_path=o.resolve(D.host,D.remote_path);D.hosted_tarball=o.resolve(D.hosted_path,D.package_name);return D}},7498:function(e,t,r){"use strict";var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:true});const a=s(r(1017));const o=r(3982);const u=r(9663);const c=r(4370);const f=r(1988);const d=s(r(3331));const p=r(9336);const h=s(r(3535));const v=r(1226);const D=r(2100);const g=r(7393);const y=s(r(1415));const m=s(r(1));const _=s(r(7663));const E=s(r(5841));const w=r(7310);const x=f.Parser.extend();const F=s(r(2037));const C=r(3791);const S=s(r(2382));const k={cwd:()=>K,env:{NODE_ENV:c.UNKNOWN,[c.UNKNOWN]:true},[c.UNKNOWN]:true};const A=Symbol();const R=Symbol();const O=Symbol();const T=Symbol();const j=Symbol();const B=Symbol();const L=Symbol();const N=Symbol();const I=Symbol();const P={access:B,accessSync:B,createReadStream:B,exists:B,existsSync:B,fstat:B,fstatSync:B,lstat:B,lstatSync:B,open:B,readdir:L,readdirSync:L,readFile:B,readFileSync:B,stat:B,statSync:B};const W={...P,pathExists:B,pathExistsSync:B,readJson:B,readJSON:B,readJsonSync:B,readJSONSync:B};const M=Object.assign(Object.create(null),{bindings:{default:N},express:{default:function(){return{[c.UNKNOWN]:true,set:A,engine:R}}},fs:{default:P,...P},"fs-extra":{default:W,...W},"graceful-fs":{default:P,...P},process:{default:k,...k},path:{default:{}},os:{default:F.default,...F.default},"@mapbox/node-pre-gyp":{default:E.default,...E.default},"node-pre-gyp":D.pregyp,"node-pre-gyp/lib/pre-binding":D.pregyp,"node-pre-gyp/lib/pre-binding.js":D.pregyp,"node-gyp-build":{default:I},nbind:{init:O,default:{init:O}},"resolve-from":{default:S.default},"strong-globalize":{default:{SetRootDir:T},SetRootDir:T},pkginfo:{default:j}});const $={_interopRequireDefault:g.normalizeDefaultRequire,_interopRequireWildcard:g.normalizeWildcardRequire,__importDefault:g.normalizeDefaultRequire,__importStar:g.normalizeWildcardRequire,MONGOOSE_DRIVER_PATH:undefined,URL:w.URL,Object:{assign:Object.assign}};$.global=$.GLOBAL=$.globalThis=$;const q=Symbol();D.pregyp.find[q]=true;const U=M.path;Object.keys(a.default).forEach((e=>{const t=a.default[e];if(typeof t==="function"){const r=function mockPath(){return t.apply(mockPath,arguments)};r[q]=true;U[e]=U.default[e]=r}else{U[e]=U.default[e]=t}}));U.resolve=U.default.resolve=function(...e){return a.default.resolve.apply(this,[K,...e])};U.resolve[q]=true;const G=new Set([".h",".cmake",".c",".cpp"]);const H=new Set(["CHANGELOG.md","README.md","readme.md","changelog.md"]);let K;const z=/^\/[^\/]+|^[a-z]:[\\/][^\\/]+/i;function isAbsolutePathOrUrl(e){if(e instanceof w.URL)return e.protocol==="file:";if(typeof e==="string"){if(e.startsWith("file:")){try{new w.URL(e);return true}catch{return false}}return z.test(e)}return false}const V=Symbol();const Y=/([\/\\]\*\*[\/\\]\*)+/g;async function analyze(e,t,r){const s=new Set;const f=new Set;const g=new Set;const E=a.default.dirname(e);K=r.cwd;const F=(0,v.getPackageBase)(e);const emitAssetDirectory=e=>{if(!r.analysis.emitGlobs)return;const t=e.indexOf(c.WILDCARD);const o=t===-1?e.length:e.lastIndexOf(a.default.sep,t);const u=e.substring(0,o);const f=e.slice(o);const d=f.replace(c.wildcardRegEx,((e,t)=>f[t-1]===a.default.sep?"**/*":"*")).replace(Y,"/**/*")||"/**/*";if(r.ignoreFn(a.default.relative(r.base,u+d)))return;P=P.then((async()=>{if(r.log)console.log("Globbing "+u+d);const e=await new Promise(((e,t)=>(0,h.default)(u+d,{mark:true,ignore:u+"/**/node_modules/**/*"},((r,s)=>r?t(r):e(s)))));e.filter((e=>!G.has(a.default.extname(e))&&!H.has(a.default.basename(e))&&!e.endsWith("/"))).forEach((e=>s.add(e)))}))};let P=Promise.resolve();t=t.replace(/^#![^\n\r]*[\r\n]/,"");let W;let U=false;try{W=x.parse(t,{ecmaVersion:"latest",allowReturnOutsideFunction:true});U=false}catch(t){const s=t&&t.message&&t.message.includes("sourceType: module");if(!s){r.warnings.add(new Error(`Failed to parse ${e} as script:\n${t&&t.message}`))}}if(!W){try{W=x.parse(t,{ecmaVersion:"latest",sourceType:"module",allowAwaitOutsideFunction:true});U=true}catch(t){r.warnings.add(new Error(`Failed to parse ${e} as module:\n${t&&t.message}`));return{assets:s,deps:f,imports:g,isESM:false}}}const Q=(0,w.pathToFileURL)(e).href;const J=Object.assign(Object.create(null),{__dirname:{shadowDepth:0,value:{value:a.default.resolve(e,"..")}},__filename:{shadowDepth:0,value:{value:e}},process:{shadowDepth:0,value:{value:k}}});if(!U||r.mixedModules){J.require={shadowDepth:0,value:{value:{[c.FUNCTION](e){f.add(e);const t=M[e.startsWith("node:")?e.slice(5):e];return t.default},resolve(t){return(0,m.default)(t,e,r)}}}};J.require.value.value.resolve[q]=true}function setKnownBinding(e,t){if(e==="require")return;J[e]={shadowDepth:0,value:t}}function getKnownBinding(e){const t=J[e];if(t){if(t.shadowDepth===0){return t.value}}return undefined}function hasKnownBindingValue(e){const t=J[e];return t&&t.shadowDepth===0}if((U||r.mixedModules)&&isAst(W)){for(const e of W.body){if(e.type==="ImportDeclaration"){const t=String(e.source.value);f.add(t);const r=M[t.startsWith("node:")?t.slice(5):t];if(r){for(const t of e.specifiers){if(t.type==="ImportNamespaceSpecifier")setKnownBinding(t.local.name,{value:r});else if(t.type==="ImportDefaultSpecifier"&&"default"in r)setKnownBinding(t.local.name,{value:r.default});else if(t.type==="ImportSpecifier"&&t.imported.name in r)setKnownBinding(t.local.name,{value:r[t.imported.name]})}}}else if(e.type==="ExportNamedDeclaration"||e.type==="ExportAllDeclaration"){if(e.source)f.add(String(e.source.value))}}}async function computePureStaticValue(e,t=true){const r=Object.create(null);Object.keys($).forEach((e=>{r[e]={value:$[e]}}));Object.keys(J).forEach((e=>{r[e]=getKnownBinding(e)}));r["import.meta"]={url:Q};const s=await(0,c.evaluate)(e,r,t);return s}let X;let Z;let ee=false;function emitWildcardRequire(e){if(!r.analysis.emitGlobs||!e.startsWith("./")&&!e.startsWith("../"))return;e=a.default.resolve(E,e);const t=e.indexOf(c.WILDCARD);const s=t===-1?e.length:e.lastIndexOf(a.default.sep,t);const o=e.substring(0,s);const u=e.slice(s);let d=u.replace(c.wildcardRegEx,((e,t)=>u[t-1]===a.default.sep?"**/*":"*"))||"/**/*";if(!d.endsWith("*"))d+="?("+(r.ts?".ts|.tsx|":"")+".js|.json|.node)";if(r.ignoreFn(a.default.relative(r.base,o+d)))return;P=P.then((async()=>{if(r.log)console.log("Globbing "+o+d);const e=await new Promise(((e,t)=>(0,h.default)(o+d,{mark:true,ignore:o+"/**/node_modules/**/*"},((r,s)=>r?t(r):e(s)))));e.filter((e=>!G.has(a.default.extname(e))&&!H.has(a.default.basename(e))&&!e.endsWith("/"))).forEach((e=>f.add(e)))}))}async function processRequireArg(e,t=false){if(e.type==="ConditionalExpression"){await processRequireArg(e.consequent,t);await processRequireArg(e.alternate,t);return}if(e.type==="LogicalExpression"){await processRequireArg(e.left,t);await processRequireArg(e.right,t);return}let r=await computePureStaticValue(e,true);if(!r)return;if("value"in r&&typeof r.value==="string"){if(!r.wildcards)(t?g:f).add(r.value);else if(r.wildcards.length>=1)emitWildcardRequire(r.value)}else{if("then"in r&&typeof r.then==="string")(t?g:f).add(r.then);if("else"in r&&typeof r.else==="string")(t?g:f).add(r.else)}}let te=(0,u.attachScopes)(W,"scope");if(isAst(W)){(0,C.handleWrappers)(W);await(0,y.default)({id:e,ast:W,emitDependency:e=>f.add(e),emitAsset:e=>s.add(e),emitAssetDirectory:emitAssetDirectory,job:r})}async function backtrack(e,t){if(!X)throw new Error("Internal error: No staticChildNode for backtrack.");const r=await computePureStaticValue(e,true);if(r){if("value"in r&&typeof r.value!=="symbol"||"then"in r&&typeof r.then!=="symbol"&&typeof r.else!=="symbol"){Z=r;X=e;if(t)t.skip();return}}await emitStaticChildAsset()}await(0,o.asyncWalk)(W,{async enter(t,o){const u=t;const c=o;if(u.scope){te=u.scope;for(const e in u.scope.declarations){if(e in J)J[e].shadowDepth++}}if(X)return;if(!c)return;if(u.type==="Identifier"){if((0,p.isIdentifierRead)(u,c)&&r.analysis.computeFileReferences){let e;if(typeof(e=getKnownBinding(u.name)?.value)==="string"&&e.match(z)||e&&(typeof e==="function"||typeof e==="object")&&e[q]){Z={value:typeof e==="string"?e:undefined};X=u;await backtrack(c,this)}}}else if(r.analysis.computeFileReferences&&u.type==="MemberExpression"&&u.object.type==="MetaProperty"&&u.object.meta.name==="import"&&u.object.property.name==="meta"&&(u.property.computed?u.property.value:u.property.name)==="url"){Z={value:Q};X=u;await backtrack(c,this)}else if(u.type==="ImportExpression"){await processRequireArg(u.source,true);return}else if(u.type==="CallExpression"){if((!U||r.mixedModules)&&u.callee.type==="Identifier"&&u.arguments.length){if(u.callee.name==="require"&&J.require.shadowDepth===0){await processRequireArg(u.arguments[0]);return}}else if((!U||r.mixedModules)&&u.callee.type==="MemberExpression"&&u.callee.object.type==="Identifier"&&u.callee.object.name==="module"&&"module"in J===false&&u.callee.property.type==="Identifier"&&!u.callee.computed&&u.callee.property.name==="require"&&u.arguments.length){await processRequireArg(u.arguments[0]);return}else if((!U||r.mixedModules)&&u.callee.type==="MemberExpression"&&u.callee.object.type==="Identifier"&&u.callee.object.name==="require"&&J.require.shadowDepth===0&&u.callee.property.type==="Identifier"&&!u.callee.computed&&u.callee.property.name==="resolve"&&u.arguments.length){await processRequireArg(u.arguments[0]);return}const t=r.analysis.evaluatePureExpressions&&await computePureStaticValue(u.callee,false);if(t&&"value"in t&&typeof t.value==="function"&&t.value[q]&&r.analysis.computeFileReferences){Z=await computePureStaticValue(u,true);if(Z&&c){X=u;await backtrack(c,this)}}else if(t&&"value"in t&&typeof t.value==="symbol"){switch(t.value){case V:if(u.arguments.length===1&&u.arguments[0].type==="Literal"&&u.callee.type==="Identifier"&&J.require.shadowDepth===0){await processRequireArg(u.arguments[0])}break;case N:if(u.arguments.length){const e=await computePureStaticValue(u.arguments[0],false);if(e&&"value"in e&&e.value){let t;if(typeof e.value==="object")t=e.value;else if(typeof e.value==="string")t={bindings:e.value};if(!t.path){t.path=true}t.module_root=F;let r;try{r=(0,d.default)(t)}catch(e){}if(r){Z={value:r};X=u;await emitStaticChildAsset()}}}break;case I:if(u.arguments.length===1&&u.arguments[0].type==="Identifier"&&u.arguments[0].name==="__dirname"&&J.__dirname.shadowDepth===0){let e;try{const t=(0,S.default)(E,"node-gyp-build");e=require(t).path(E)}catch(t){try{e=_.default.path(E)}catch(e){}}if(e){Z={value:e};X=u;await emitStaticChildAsset()}}break;case O:if(u.arguments.length){const e=await computePureStaticValue(u.arguments[0],false);if(e&&"value"in e&&(typeof e.value==="string"||typeof e.value==="undefined")){const t=(0,D.nbind)(e.value);if(t&&t.path){f.add(a.default.relative(E,t.path).replace(/\\/g,"/"));return this.skip()}}}break;case A:if(u.arguments.length===2&&u.arguments[0].type==="Literal"&&u.arguments[0].value==="view engine"&&!ee){await processRequireArg(u.arguments[1]);return this.skip()}break;case R:ee=true;break;case B:case L:if(u.arguments[0]&&r.analysis.computeFileReferences){Z=await computePureStaticValue(u.arguments[0],true);if(Z){X=u.arguments[0];if(t.value===L&&u.arguments[0].type==="Identifier"&&u.arguments[0].name==="__dirname"){emitAssetDirectory(E)}else{await backtrack(c,this)}return this.skip()}}break;case T:if(u.arguments[0]){const e=await computePureStaticValue(u.arguments[0],false);if(e&&"value"in e&&e.value)emitAssetDirectory(e.value+"/intl");return this.skip()}break;case j:let o=a.default.resolve(e,"../package.json");const p=a.default.resolve("/package.json");while(o!==p&&await r.stat(o)===null)o=a.default.resolve(o,"../../package.json");if(o!==p)s.add(o);break}}}else if(u.type==="VariableDeclaration"&&c&&!(0,p.isVarLoop)(c)&&r.analysis.evaluatePureExpressions){for(const e of u.declarations){if(!e.init)continue;const t=await computePureStaticValue(e.init,true);if(t){if(e.id.type==="Identifier"){setKnownBinding(e.id.name,t)}else if(e.id.type==="ObjectPattern"&&"value"in t){for(const r of e.id.properties){if(r.type!=="Property"||r.key.type!=="Identifier"||r.value.type!=="Identifier"||typeof t.value!=="object"||t.value===null||!(r.key.name in t.value))continue;setKnownBinding(r.value.name,{value:t.value[r.key.name]})}}if(!("value"in t)&&isAbsolutePathOrUrl(t.then)&&isAbsolutePathOrUrl(t.else)){Z=t;X=e.init;await emitStaticChildAsset()}}}}else if(u.type==="AssignmentExpression"&&c&&!(0,p.isLoop)(c)&&r.analysis.evaluatePureExpressions){if(!hasKnownBindingValue(u.left.name)){const e=await computePureStaticValue(u.right,false);if(e&&"value"in e){if(u.left.type==="Identifier"){setKnownBinding(u.left.name,e)}else if(u.left.type==="ObjectPattern"){for(const t of u.left.properties){if(t.type!=="Property"||t.key.type!=="Identifier"||t.value.type!=="Identifier"||typeof e.value!=="object"||e.value===null||!(t.key.name in e.value))continue;setKnownBinding(t.value.name,{value:e.value[t.key.name]})}}if(isAbsolutePathOrUrl(e.value)){Z=e;X=u.right;await emitStaticChildAsset()}}}}else if((!U||r.mixedModules)&&(u.type==="FunctionDeclaration"||u.type==="FunctionExpression"||u.type==="ArrowFunctionExpression")&&(u.arguments||u.params)[0]&&(u.arguments||u.params)[0].type==="Identifier"){let e;let t;if((u.type==="ArrowFunctionExpression"||u.type==="FunctionExpression")&&c&&c.type==="VariableDeclarator"&&c.id.type==="Identifier"){e=c.id;t=u.arguments||u.params}else if(u.id){e=u.id;t=u.arguments||u.params}if(e&&u.body.body){let r,s=false;for(let e=0;ee&&e.id&&e.id.type==="Identifier"&&e.init&&e.init.type==="CallExpression"&&e.init.callee.type==="Identifier"&&e.init.callee.name==="require"&&J.require.shadowDepth===0&&e.init.arguments[0]&&e.init.arguments[0].type==="Identifier"&&e.init.arguments[0].name===t[0].name))}if(r&&u.body.body[e].type==="ReturnStatement"&&u.body.body[e].argument&&u.body.body[e].argument.type==="Identifier"&&u.body.body[e].argument.name===r.id.name){s=true;break}}if(s)setKnownBinding(e.name,{value:V})}}},async leave(e,t){const r=e;const s=t;if(r.scope){if(te.parent){te=te.parent}for(const e in r.scope.declarations){if(e in J){if(J[e].shadowDepth>0)J[e].shadowDepth--;else delete J[e]}}}if(X&&s)await backtrack(s,this)}});await P;return{assets:s,deps:f,imports:g,isESM:U};async function emitAssetPath(e){const t=e.indexOf(c.WILDCARD);const o=t===-1?e.length:e.lastIndexOf(a.default.sep,t);const u=e.substring(0,o);try{var f=await r.stat(u);if(f===null){throw new Error("file not found")}}catch(e){return}if(t!==-1&&f.isFile())return;if(f.isFile()){s.add(e)}else if(f.isDirectory()){if(validWildcard(e))emitAssetDirectory(e)}}function validWildcard(t){let s="";if(t.endsWith(a.default.sep))s=a.default.sep;else if(t.endsWith(a.default.sep+c.WILDCARD))s=a.default.sep+c.WILDCARD;else if(t.endsWith(c.WILDCARD))s=c.WILDCARD;if(t===E+s)return false;if(t===K+s)return false;if(t.endsWith(a.default.sep+"node_modules"+s))return false;if(E.startsWith(t.slice(0,t.length-s.length)+a.default.sep))return false;if(F){const s=e.substring(0,e.indexOf(a.default.sep+"node_modules"))+a.default.sep+"node_modules"+a.default.sep;if(!t.startsWith(s)){if(r.log)console.log("Skipping asset emission of "+t.replace(c.wildcardRegEx,"*")+" for "+e+" as it is outside the package base "+F);return false}}return true}function resolveAbsolutePathOrUrl(e){return e instanceof w.URL?(0,w.fileURLToPath)(e):e.startsWith("file:")?(0,w.fileURLToPath)(new w.URL(e)):a.default.resolve(e)}async function emitStaticChildAsset(){if(!Z){return}if("value"in Z&&isAbsolutePathOrUrl(Z.value)){try{const e=resolveAbsolutePathOrUrl(Z.value);await emitAssetPath(e)}catch(e){}}else if("then"in Z&&"else"in Z&&isAbsolutePathOrUrl(Z.then)&&isAbsolutePathOrUrl(Z.else)){let e;try{e=resolveAbsolutePathOrUrl(Z.then)}catch(e){}let t;try{t=resolveAbsolutePathOrUrl(Z.else)}catch(e){}if(e)await emitAssetPath(e);if(t)await emitAssetPath(t)}else if(X&&X.type==="ArrayExpression"&&"value"in Z&&Z.value instanceof Array){for(const e of Z.value){try{const t=resolveAbsolutePathOrUrl(e);await emitAssetPath(t)}catch(e){}}}X=Z=undefined}}t["default"]=analyze;function isAst(e){return"body"in e}},529:function(e,t,r){"use strict";var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:true});t.CachedFileSystem=void 0;const a=r(1017);const o=s(r(6450));const u=r(5749);const c=o.default.promises.readFile;const f=o.default.promises.readlink;const d=o.default.promises.stat;class CachedFileSystem{constructor({cache:e,fileIOConcurrency:t}){this.fileIOQueue=new u.Sema(t);this.fileCache=e?.fileCache??new Map;this.statCache=e?.statCache??new Map;this.symlinkCache=e?.symlinkCache??new Map;if(e){e.fileCache=this.fileCache;e.statCache=this.statCache;e.symlinkCache=this.symlinkCache}}async readlink(e){const t=this.symlinkCache.get(e);if(t!==undefined)return t;const r=this.executeFileIO(e,this._internalReadlink);this.symlinkCache.set(e,r);return r}async readFile(e){const t=this.fileCache.get(e);if(t!==undefined)return t;const r=this.executeFileIO(e,this._internalReadFile);this.fileCache.set(e,r);return r}async stat(e){const t=this.statCache.get(e);if(t!==undefined)return t;const r=this.executeFileIO(e,this._internalStat);this.statCache.set(e,r);return r}async _internalReadlink(e){try{const t=await f(e);const r=this.statCache.get(e);if(r)this.statCache.set((0,a.resolve)(e,t),r);return t}catch(e){if(e.code!=="EINVAL"&&e.code!=="ENOENT"&&e.code!=="UNKNOWN")throw e;return null}}async _internalReadFile(e){try{return(await c(e)).toString()}catch(e){if(e.code==="ENOENT"||e.code==="EISDIR"){return null}throw e}}async _internalStat(e){try{return await d(e)}catch(e){if(e.code==="ENOENT"){return null}throw e}}async executeFileIO(e,t){await this.fileIOQueue.acquire();try{return t.call(this,e)}finally{this.fileIOQueue.release()}}}t.CachedFileSystem=CachedFileSystem},6223:function(e,t,r){"use strict";var s=this&&this.__createBinding||(Object.create?function(e,t,r,s){if(s===undefined)s=r;var a=Object.getOwnPropertyDescriptor(t,r);if(!a||("get"in a?!t.__esModule:a.writable||a.configurable)){a={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,s,a)}:function(e,t,r,s){if(s===undefined)s=r;e[s]=t[r]});var a=this&&this.__exportStar||function(e,t){for(var r in e)if(r!=="default"&&!Object.prototype.hasOwnProperty.call(t,r))s(t,e,r)};Object.defineProperty(t,"__esModule",{value:true});t.nodeFileTrace=void 0;a(r(8470),t);var o=r(2411);Object.defineProperty(t,"nodeFileTrace",{enumerable:true,get:function(){return o.nodeFileTrace}})},2411:function(e,t,r){"use strict";var s=this&&this.__createBinding||(Object.create?function(e,t,r,s){if(s===undefined)s=r;var a=Object.getOwnPropertyDescriptor(t,r);if(!a||("get"in a?!t.__esModule:a.writable||a.configurable)){a={enumerable:true,get:function(){return t[r]}}}Object.defineProperty(e,s,a)}:function(e,t,r,s){if(s===undefined)s=r;e[s]=t[r]});var a=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:true,value:t})}:function(e,t){e["default"]=t});var o=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(e!=null)for(var r in e)if(r!=="default"&&Object.prototype.hasOwnProperty.call(e,r))s(t,e,r);a(t,e);return t};var u=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:true});t.Job=t.nodeFileTrace=void 0;const c=r(1017);const f=u(r(7498));const d=o(r(1));const p=r(2540);const h=r(8908);const v=r(1017);const D=r(529);function inPath(e,t){const r=(0,v.join)(t,c.sep);return e.startsWith(r)&&e!==r}async function nodeFileTrace(e,t={}){const r=new Job(t);if(t.readFile)r.readFile=t.readFile;if(t.stat)r.stat=t.stat;if(t.readlink)r.readlink=t.readlink;if(t.resolve)r.resolve=t.resolve;r.ts=true;await Promise.all(e.map((async e=>{const t=(0,c.resolve)(e);await r.emitFile(t,"initial");return r.emitDependency(t)})));const s={fileList:r.fileList,esmFileList:r.esmFileList,reasons:r.reasons,warnings:r.warnings};return s}t.nodeFileTrace=nodeFileTrace;class Job{constructor({base:e=process.cwd(),processCwd:t,exports:r,conditions:s=r||["node"],exportsOnly:a=false,paths:o={},ignore:u,log:f=false,mixedModules:h=false,ts:v=true,analysis:g={},cache:y,fileIOConcurrency:m=1024}){this.reasons=new Map;this.maybeEmitDep=async(e,t,r)=>{let s="";let a;try{s=await this.resolve(e,t,this,r)}catch(o){a=o;try{if(this.ts&&e.endsWith(".js")&&o instanceof d.NotFoundError){const o=e.slice(0,-3)+".ts";s=await this.resolve(o,t,this,r);a=undefined}}catch(e){a=e}}if(a){this.warnings.add(new Error(`Failed to resolve dependency "${e}":\n${a?.message}`));return}if(Array.isArray(s)){for(const e of s){if(e.startsWith("node:"))return;await this.emitDependency(e,t)}}else{if(s.startsWith("node:"))return;await this.emitDependency(s,t)}};this.ts=v;e=(0,c.resolve)(e);this.ignoreFn=e=>{if(e.startsWith(".."+c.sep))return true;return false};if(typeof u==="string")u=[u];if(typeof u==="function"){const e=u;this.ignoreFn=t=>{if(t.startsWith(".."+c.sep))return true;if(e(t))return true;return false}}else if(Array.isArray(u)){const t=u.map((t=>(0,c.relative)(e,(0,c.resolve)(e||process.cwd(),t))));this.ignoreFn=e=>{if(e.startsWith(".."+c.sep))return true;if((0,p.isMatch)(e,t))return true;return false}}this.base=e;this.cwd=(0,c.resolve)(t||e);this.conditions=s;this.exportsOnly=a;const _={};for(const t of Object.keys(o)){const r=o[t].endsWith("/");const s=(0,c.resolve)(e,o[t]);_[t]=s+(r?"/":"")}this.paths=_;this.log=f;this.mixedModules=h;this.cachedFileSystem=new D.CachedFileSystem({cache:y,fileIOConcurrency:m});this.analysis={};if(g!==false){Object.assign(this.analysis,{emitGlobs:true,computeFileReferences:true,evaluatePureExpressions:true},g===true?{}:g)}this.analysisCache=y&&y.analysisCache||new Map;if(y){y.analysisCache=this.analysisCache}this.fileList=new Set;this.esmFileList=new Set;this.processed=new Set;this.warnings=new Set}async readlink(e){return this.cachedFileSystem.readlink(e)}async isFile(e){const t=await this.stat(e);if(t)return t.isFile();return false}async isDir(e){const t=await this.stat(e);if(t)return t.isDirectory();return false}async stat(e){return this.cachedFileSystem.stat(e)}async resolve(e,t,r,s){return(0,d.default)(e,t,r,s)}async readFile(e){return this.cachedFileSystem.readFile(e)}async realpath(e,t,r=new Set){if(r.has(e))throw new Error("Recursive symlink detected resolving "+e);r.add(e);const s=await this.readlink(e);if(s){const a=(0,c.dirname)(e);const o=(0,c.resolve)(a,s);const u=await this.realpath(a,t);if(inPath(e,u))await this.emitFile(e,"resolve",t,true);return this.realpath(o,t,r)}if(!inPath(e,this.base))return e;return(0,v.join)(await this.realpath((0,c.dirname)(e),t,r),(0,c.basename)(e))}async emitFile(e,t,r,s=false){if(!s){e=await this.realpath(e,r)}e=(0,c.relative)(this.base,e);if(r){r=(0,c.relative)(this.base,r)}let a=this.reasons.get(e);if(!a){a={type:[t],ignored:false,parents:new Set};this.reasons.set(e,a)}else if(!a.type.includes(t)){a.type.push(t)}if(r&&this.ignoreFn(e,r)){if(!this.fileList.has(e)&&a){a.ignored=true}return false}if(r){a.parents.add(r)}this.fileList.add(e);return true}async getPjsonBoundary(e){const t=e.indexOf(c.sep);let r;while((r=e.lastIndexOf(c.sep))>t){e=e.slice(0,r);if(await this.isFile(e+c.sep+"package.json"))return e}return undefined}async emitDependency(e,t){if(this.processed.has(e)){if(t){await this.emitFile(e,"dependency",t)}return}this.processed.add(e);const r=await this.emitFile(e,"dependency",t);if(!r)return;if(e.endsWith(".json"))return;if(e.endsWith(".node"))return await(0,h.sharedLibEmit)(e,this);if(e.endsWith(".js")||e.endsWith(".ts")){const t=await this.getPjsonBoundary(e);if(t)await this.emitFile(t+c.sep+"package.json","resolve",e)}let s;const a=this.analysisCache.get(e);if(a){s=a}else{const t=await this.readFile(e);if(t===null)throw new Error("File "+e+" does not exist.");s=await(0,f.default)(e,t.toString(),this);this.analysisCache.set(e,s)}const{deps:o,imports:u,assets:d,isESM:p}=s;if(p){this.esmFileList.add((0,c.relative)(this.base,e))}await Promise.all([...[...d].map((async t=>{const r=(0,c.extname)(t);if(r===".js"||r===".mjs"||r===".node"||r===""||this.ts&&(r===".ts"||r===".tsx")&&t.startsWith(this.base)&&t.slice(this.base.length).indexOf(c.sep+"node_modules"+c.sep)===-1)await this.emitDependency(t,e);else await this.emitFile(t,"asset",e)})),...[...o].map((async t=>this.maybeEmitDep(t,e,!p))),...[...u].map((async t=>this.maybeEmitDep(t,e,false)))])}}t.Job=Job},1:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.NotFoundError=void 0;const s=r(1017);async function resolveDependency(e,t,r,a=true){let o;if((0,s.isAbsolute)(e)||e==="."||e===".."||e.startsWith("./")||e.startsWith("../")){const a=e.endsWith("/");o=await resolvePath((0,s.resolve)(t,"..",e)+(a?"/":""),t,r)}else if(e[0]==="#"){o=await packageImportsResolve(e,t,r,a)}else{o=await resolvePackage(e,t,r,a)}if(Array.isArray(o)){return Promise.all(o.map((e=>r.realpath(e,t))))}else if(o.startsWith("node:")){return o}else{return r.realpath(o,t)}}t["default"]=resolveDependency;async function resolvePath(e,t,r){const s=await resolveFile(e,t,r)||await resolveDir(e,t,r);if(!s){throw new NotFoundError(e,t)}return s}async function resolveFile(e,t,r){if(e.endsWith("/"))return undefined;e=await r.realpath(e,t);if(await r.isFile(e))return e;if(r.ts&&e.startsWith(r.base)&&e.slice(r.base.length).indexOf(s.sep+"node_modules"+s.sep)===-1&&await r.isFile(e+".ts"))return e+".ts";if(r.ts&&e.startsWith(r.base)&&e.slice(r.base.length).indexOf(s.sep+"node_modules"+s.sep)===-1&&await r.isFile(e+".tsx"))return e+".tsx";if(await r.isFile(e+".js"))return e+".js";if(await r.isFile(e+".json"))return e+".json";if(await r.isFile(e+".node"))return e+".node";return undefined}async function resolveDir(e,t,r){if(e.endsWith("/"))e=e.slice(0,-1);if(!await r.isDir(e))return;const a=await getPkgCfg(e,r);if(a&&typeof a.main==="string"){const o=await resolveFile((0,s.resolve)(e,a.main),t,r)||await resolveFile((0,s.resolve)(e,a.main,"index"),t,r);if(o){await r.emitFile(e+s.sep+"package.json","resolve",t);return o}}return resolveFile((0,s.resolve)(e,"index"),t,r)}class NotFoundError extends Error{constructor(e,t){super("Cannot find module '"+e+"' loaded from "+t);this.code="MODULE_NOT_FOUND"}}t.NotFoundError=NotFoundError;const a=new Set([...r(8102)._builtinLibs,"constants","module","timers","console","_stream_writable","_stream_readable","_stream_duplex","process","sys"]);function getPkgName(e){const t=e.split("/");if(e[0]==="@"&&t.length>1)return t.length>1?t.slice(0,2).join("/"):null;return t.length?t[0]:null}async function getPkgCfg(e,t){const r=await t.readFile(e+s.sep+"package.json");if(r){try{return JSON.parse(r.toString())}catch(e){}}return undefined}function getExportsTarget(e,t,r){if(typeof e==="string"){return e}else if(e===null){return e}else if(Array.isArray(e)){for(const s of e){const e=getExportsTarget(s,t,r);if(e===null||typeof e==="string"&&e.startsWith("./"))return e}}else if(typeof e==="object"){for(const s of Object.keys(e)){if(s==="default"||s==="require"&&r||s==="import"&&!r||t.includes(s)){const a=getExportsTarget(e[s],t,r);if(a!==undefined)return a}}}return undefined}function resolveExportsImports(e,t,r,s,a,o){let u;if(a){if(!(typeof t==="object"&&!Array.isArray(t)&&t!==null))return undefined;u=t}else if(typeof t==="string"||Array.isArray(t)||t===null||typeof t==="object"&&Object.keys(t).length&&Object.keys(t)[0][0]!=="."){u={".":t}}else{u=t}if(r in u){const t=getExportsTarget(u[r],s.conditions,o);if(typeof t==="string"&&t.startsWith("./"))return e+t.slice(1)}for(const t of Object.keys(u).sort(((e,t)=>t.length-e.length))){if(t.endsWith("*")&&r.startsWith(t.slice(0,-1))){const a=getExportsTarget(u[t],s.conditions,o);if(typeof a==="string"&&a.startsWith("./"))return e+a.slice(1).replace(/\*/g,r.slice(t.length-1))}if(!t.endsWith("/"))continue;if(r.startsWith(t)){const a=getExportsTarget(u[t],s.conditions,o);if(typeof a==="string"&&a.endsWith("/")&&a.startsWith("./"))return e+a.slice(1)+r.slice(t.length)}}return undefined}async function packageImportsResolve(e,t,r,a){if(e!=="#"&&!e.startsWith("#/")&&r.conditions){const o=await r.getPjsonBoundary(t);if(o){const u=await getPkgCfg(o,r);const{imports:c}=u||{};if(u&&c!==null&&c!==undefined){let u=resolveExportsImports(o,c,e,r,true,a);if(u){if(a)u=await resolveFile(u,t,r)||await resolveDir(u,t,r);else if(!await r.isFile(u))throw new NotFoundError(u,t);if(u){await r.emitFile(o+s.sep+"package.json","resolve",t);return u}}}}}throw new NotFoundError(e,t)}async function resolvePackage(e,t,r,o){let u=t;if(a.has(e))return"node:"+e;if(e.startsWith("node:"))return e;const c=getPkgName(e)||"";let f;if(r.conditions){const a=await r.getPjsonBoundary(t);if(a){const u=await getPkgCfg(a,r);const{exports:d}=u||{};if(u&&u.name&&u.name===c&&d!==null&&d!==undefined){f=resolveExportsImports(a,d,"."+e.slice(c.length),r,false,o);if(f){if(o)f=await resolveFile(f,t,r)||await resolveDir(f,t,r);else if(!await r.isFile(f))throw new NotFoundError(f,t)}if(f)await r.emitFile(a+s.sep+"package.json","resolve",t)}}}let d;const p=u.indexOf(s.sep);while((d=u.lastIndexOf(s.sep))>p){u=u.slice(0,d);const a=u+s.sep+"node_modules";const p=await r.stat(a);if(!p||!p.isDirectory())continue;const h=await getPkgCfg(a+s.sep+c,r);const{exports:v}=h||{};if(r.conditions&&v!==undefined&&v!==null&&!f){let u;if(!r.exportsOnly)u=await resolveFile(a+s.sep+e,t,r)||await resolveDir(a+s.sep+e,t,r);let f=resolveExportsImports(a+s.sep+c,v,"."+e.slice(c.length),r,false,o);if(f){if(o)f=await resolveFile(f,t,r)||await resolveDir(f,t,r);else if(!await r.isFile(f))throw new NotFoundError(f,t)}if(f){await r.emitFile(a+s.sep+c+s.sep+"package.json","resolve",t);if(u&&u!==f)return[f,u];return f}if(u)return u}else{const o=await resolveFile(a+s.sep+e,t,r)||await resolveDir(a+s.sep+e,t,r);if(o){if(f&&f!==o)return[o,f];return o}}}if(f)return f;if(Object.hasOwnProperty.call(r.paths,e)){return r.paths[e]}for(const s of Object.keys(r.paths)){if(s.endsWith("/")&&e.startsWith(s)){const a=r.paths[s]+e.slice(s.length);const o=await resolveFile(a,t,r)||await resolveDir(a,t,r);if(!o){throw new NotFoundError(e,t)}return o}}throw new NotFoundError(e,t)}},8470:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true})},9336:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.isLoop=t.isVarLoop=t.isIdentifierRead=void 0;function isIdentifierRead(e,t){switch(t.type){case"ObjectPattern":case"ArrayPattern":return false;case"AssignmentExpression":return t.right===e;case"MemberExpression":return t.computed||e===t.object;case"Property":return e===t.value;case"MethodDefinition":return false;case"VariableDeclarator":return t.id!==e;case"ExportSpecifier":return false;case"FunctionExpression":case"FunctionDeclaration":case"ArrowFunctionExpression":return false;default:return true}}t.isIdentifierRead=isIdentifierRead;function isVarLoop(e){return e.type==="ForStatement"||e.type==="ForInStatement"||e.type==="ForOfStatement"}t.isVarLoop=isVarLoop;function isLoop(e){return e.type==="ForStatement"||e.type==="ForInStatement"||e.type==="ForOfStatement"||e.type==="WhileStatement"||e.type==="DoWhileStatement"}t.isLoop=isLoop},2100:function(__unused_webpack_module,exports,__nccwpck_require__){"use strict";var __importDefault=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(exports,"__esModule",{value:true});exports.nbind=exports.pregyp=void 0;const path_1=__importDefault(__nccwpck_require__(1017));const graceful_fs_1=__importDefault(__nccwpck_require__(6450));const versioning=__nccwpck_require__(2821);const napi=__nccwpck_require__(5977);const pregypFind=(e,t)=>{const r=JSON.parse(graceful_fs_1.default.readFileSync(e).toString());versioning.validate_config(r,t);var s;if(napi.get_napi_build_versions(r,t)){s=napi.get_best_napi_build_version(r,t)}t=t||{};if(!t.module_root)t.module_root=path_1.default.dirname(e);var a=versioning.evaluate(r,t,s);return a.module};exports.pregyp={default:{find:pregypFind},find:pregypFind};function makeModulePathList(e,t){return[[e,t],[e,"build",t],[e,"build","Debug",t],[e,"build","Release",t],[e,"out","Debug",t],[e,"Debug",t],[e,"out","Release",t],[e,"Release",t],[e,"build","default",t],[e,process.env["NODE_BINDINGS_COMPILED_DIR"]||"compiled",process.versions.node,process.platform,process.arch,t]]}function findCompiledModule(basePath,specList){var resolvedList=[];var ext=path_1.default.extname(basePath);for(var _i=0,specList_1=specList;_i{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.getPackageName=t.getPackageBase=void 0;const r=/^(@[^\\\/]+[\\\/])?[^\\\/]+/;function getPackageBase(e){const t=e.lastIndexOf("node_modules");if(t!==-1&&(e[t-1]==="/"||e[t-1]==="\\")&&(e[t+12]==="/"||e[t+12]==="\\")){const s=e.slice(t+13).match(r);if(s)return e.slice(0,t+13+s[0].length)}return undefined}t.getPackageBase=getPackageBase;function getPackageName(e){const t=e.lastIndexOf("node_modules");if(t!==-1&&(e[t-1]==="/"||e[t-1]==="\\")&&(e[t+12]==="/"||e[t+12]==="\\")){const s=e.slice(t+13).match(r);if(s&&s.length>0){return s[0].replace(/\\/g,"/")}}return undefined}t.getPackageName=getPackageName},7393:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.normalizeWildcardRequire=t.normalizeDefaultRequire=void 0;function normalizeDefaultRequire(e){if(e&&e.__esModule)return e;return{default:e}}t.normalizeDefaultRequire=normalizeDefaultRequire;const r=Object.prototype.hasOwnProperty;function normalizeWildcardRequire(e){if(e&&e.__esModule)return e;const t={};for(const s in e){if(!r.call(e,s))continue;t[s]=e[s]}t["default"]=e;return t}t.normalizeWildcardRequire=normalizeWildcardRequire},8908:function(e,t,r){"use strict";var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:true});t.sharedLibEmit=void 0;const a=s(r(2037));const o=s(r(3535));const u=r(1226);let c="";switch(a.default.platform()){case"darwin":c="/**/*.@(dylib|so?(.*))";break;case"win32":c="/**/*.dll";break;default:c="/**/*.so?(.*)"}async function sharedLibEmit(e,t){const r=(0,u.getPackageBase)(e);if(!r)return;const s=await new Promise(((e,t)=>(0,o.default)(r+c,{ignore:r+"/**/node_modules/**/*"},((r,s)=>r?t(r):e(s)))));await Promise.all(s.map((r=>t.emitFile(r,"sharedlib",e))))}t.sharedLibEmit=sharedLibEmit},1415:function(e,t,r){"use strict";var s=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:true});const a=r(1017);const o=s(r(1));const u=r(1226);const c=r(6450);const f={"@generated/photon"({id:e,emitAssetDirectory:t}){if(e.endsWith("@generated/photon/index.js")){t((0,a.resolve)((0,a.dirname)(e),"runtime/"))}},argon2({id:e,emitAssetDirectory:t}){if(e.endsWith("argon2/argon2.js")){t((0,a.resolve)((0,a.dirname)(e),"build","Release"));t((0,a.resolve)((0,a.dirname)(e),"prebuilds"));t((0,a.resolve)((0,a.dirname)(e),"lib","binding"))}},bull({id:e,emitAssetDirectory:t}){if(e.endsWith("bull/lib/commands/index.js")){t((0,a.resolve)((0,a.dirname)(e)))}},camaro({id:e,emitAsset:t}){if(e.endsWith("camaro/dist/camaro.js")){t((0,a.resolve)((0,a.dirname)(e),"camaro.wasm"))}},esbuild({id:e,emitAssetDirectory:t}){if(e.endsWith("esbuild/lib/main.js")){const r=(0,a.resolve)(e,"..","..","package.json");const s=JSON.parse((0,c.readFileSync)(r,"utf8"));for(const r of Object.keys(s.optionalDependencies||{})){const s=(0,a.resolve)(e,"..","..","..",r);t(s)}}},"google-gax"({id:e,ast:t,emitAssetDirectory:r}){if(e.endsWith("google-gax/build/src/grpc.js")){for(const s of t.body){if(s.type==="VariableDeclaration"&&s.declarations[0].id.type==="Identifier"&&s.declarations[0].id.name==="googleProtoFilesDir"){r((0,a.resolve)((0,a.dirname)(e),"../../../google-proto-files"))}}}},oracledb({id:e,ast:t,emitAsset:r}){if(e.endsWith("oracledb/lib/oracledb.js")){for(const s of t.body){if(s.type==="ForStatement"&&"body"in s.body&&s.body.body&&Array.isArray(s.body.body)&&s.body.body[0]&&s.body.body[0].type==="TryStatement"&&s.body.body[0].block.body[0]&&s.body.body[0].block.body[0].type==="ExpressionStatement"&&s.body.body[0].block.body[0].expression.type==="AssignmentExpression"&&s.body.body[0].block.body[0].expression.operator==="="&&s.body.body[0].block.body[0].expression.left.type==="Identifier"&&s.body.body[0].block.body[0].expression.left.name==="oracledbCLib"&&s.body.body[0].block.body[0].expression.right.type==="CallExpression"&&s.body.body[0].block.body[0].expression.right.callee.type==="Identifier"&&s.body.body[0].block.body[0].expression.right.callee.name==="require"&&s.body.body[0].block.body[0].expression.right.arguments.length===1&&s.body.body[0].block.body[0].expression.right.arguments[0].type==="MemberExpression"&&s.body.body[0].block.body[0].expression.right.arguments[0].computed===true&&s.body.body[0].block.body[0].expression.right.arguments[0].object.type==="Identifier"&&s.body.body[0].block.body[0].expression.right.arguments[0].object.name==="binaryLocations"&&s.body.body[0].block.body[0].expression.right.arguments[0].property.type==="Identifier"&&s.body.body[0].block.body[0].expression.right.arguments[0].property.name==="i"){s.body.body[0].block.body[0].expression.right.arguments=[{type:"Literal",value:"_"}];const t=global._unit?"3.0.0":JSON.parse((0,c.readFileSync)(e.slice(0,-15)+"package.json","utf8")).version;const o=Number(t.slice(0,t.indexOf(".")))>=4;const u="oracledb-"+(o?t:"abi"+process.versions.modules)+"-"+process.platform+"-"+process.arch+".node";r((0,a.resolve)(e,"../../build/Release/"+u))}}}},"phantomjs-prebuilt"({id:e,emitAssetDirectory:t}){if(e.endsWith("phantomjs-prebuilt/lib/phantomjs.js")){t((0,a.resolve)((0,a.dirname)(e),"..","bin"))}},"remark-prism"({id:e,emitAssetDirectory:t}){const r="remark-prism/src/highlight.js";if(e.endsWith(r)){try{const s=e.slice(0,-r.length);t((0,a.resolve)(s,"prismjs","components"))}catch(e){}}},semver({id:e,emitAsset:t}){if(e.endsWith("semver/index.js")){t((0,a.resolve)(e.replace("index.js","preload.js")))}},"socket.io":async function({id:e,ast:t,job:r}){if(e.endsWith("socket.io/lib/index.js")){async function replaceResolvePathStatement(t){if(t.type==="ExpressionStatement"&&t.expression.type==="AssignmentExpression"&&t.expression.operator==="="&&t.expression.right.type==="CallExpression"&&t.expression.right.callee.type==="Identifier"&&t.expression.right.callee.name==="read"&&t.expression.right.arguments.length>=1&&t.expression.right.arguments[0].type==="CallExpression"&&t.expression.right.arguments[0].callee.type==="Identifier"&&t.expression.right.arguments[0].callee.name==="resolvePath"&&t.expression.right.arguments[0].arguments.length===1&&t.expression.right.arguments[0].arguments[0].type==="Literal"){const s=t.expression.right.arguments[0].arguments[0].value;let u;try{const t=await(0,o.default)(String(s),e,r);if(typeof t==="string"){u=t}else{return undefined}}catch(e){return undefined}const c="/"+(0,a.relative)((0,a.dirname)(e),u);t.expression.right.arguments[0]={type:"BinaryExpression",start:t.expression.right.arguments[0].start,end:t.expression.right.arguments[0].end,operator:"+",left:{type:"Identifier",name:"__dirname"},right:{type:"Literal",value:c,raw:JSON.stringify(c)}}}return undefined}for(const e of t.body){if(e.type==="ExpressionStatement"&&e.expression.type==="AssignmentExpression"&&e.expression.operator==="="&&e.expression.left.type==="MemberExpression"&&e.expression.left.object.type==="MemberExpression"&&e.expression.left.object.object.type==="Identifier"&&e.expression.left.object.object.name==="Server"&&e.expression.left.object.property.type==="Identifier"&&e.expression.left.object.property.name==="prototype"&&e.expression.left.property.type==="Identifier"&&e.expression.left.property.name==="serveClient"&&e.expression.right.type==="FunctionExpression"){for(const t of e.expression.right.body.body){if(t.type==="IfStatement"&&t.consequent&&"body"in t.consequent&&t.consequent.body){const e=t.consequent.body;let r=false;if(Array.isArray(e)&&e[0]&&e[0].type==="ExpressionStatement"){r=await replaceResolvePathStatement(e[0])}if(Array.isArray(e)&&e[1]&&e[1].type==="TryStatement"&&e[1].block.body&&e[1].block.body[0]){r=await replaceResolvePathStatement(e[1].block.body[0])||r}return}}}}}},typescript({id:e,emitAssetDirectory:t}){if(e.endsWith("typescript/lib/tsc.js")){t((0,a.resolve)(e,"../"))}},"uglify-es"({id:e,emitAsset:t}){if(e.endsWith("uglify-es/tools/node.js")){t((0,a.resolve)(e,"../../lib/utils.js"));t((0,a.resolve)(e,"../../lib/ast.js"));t((0,a.resolve)(e,"../../lib/parse.js"));t((0,a.resolve)(e,"../../lib/transform.js"));t((0,a.resolve)(e,"../../lib/scope.js"));t((0,a.resolve)(e,"../../lib/output.js"));t((0,a.resolve)(e,"../../lib/compress.js"));t((0,a.resolve)(e,"../../lib/sourcemap.js"));t((0,a.resolve)(e,"../../lib/mozilla-ast.js"));t((0,a.resolve)(e,"../../lib/propmangle.js"));t((0,a.resolve)(e,"../../lib/minify.js"));t((0,a.resolve)(e,"../exports.js"))}},"uglify-js"({id:e,emitAsset:t,emitAssetDirectory:r}){if(e.endsWith("uglify-js/tools/node.js")){r((0,a.resolve)(e,"../../lib"));t((0,a.resolve)(e,"../exports.js"))}},"playwright-core"({id:e,emitAsset:t}){if(e.endsWith("playwright-core/index.js")){t((0,a.resolve)((0,a.dirname)(e),"browsers.json"))}},"geo-tz"({id:e,emitAsset:t}){if(e.endsWith("geo-tz/dist/geo-tz.js")){t((0,a.resolve)((0,a.dirname)(e),"../data/geo.dat"))}},pixelmatch({id:e,emitDependency:t}){if(e.endsWith("pixelmatch/index.js")){t((0,a.resolve)((0,a.dirname)(e),"bin/pixelmatch"))}}};async function handleSpecialCases({id:e,ast:t,emitDependency:r,emitAsset:s,emitAssetDirectory:a,job:o}){const c=(0,u.getPackageName)(e);const d=f[c||""];e=e.replace(/\\/g,"/");if(d)await d({id:e,ast:t,emitDependency:r,emitAsset:s,emitAssetDirectory:a,job:o})}t["default"]=handleSpecialCases},4370:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.wildcardRegEx=t.WILDCARD=t.FUNCTION=t.UNKNOWN=t.evaluate=void 0;const s=r(7310);async function evaluate(e,t={},r=true){const s={computeBranches:r,vars:t};return walk(e);function walk(e){const t=a[e.type];if(t){return t.call(s,e,walk)}return undefined}}t.evaluate=evaluate;t.UNKNOWN=Symbol();t.FUNCTION=Symbol();t.WILDCARD="";t.wildcardRegEx=/\x1a/g;function countWildcards(e){t.wildcardRegEx.lastIndex=0;let r=0;while(t.wildcardRegEx.exec(e))r++;return r}const a={ArrayExpression:async function ArrayExpression(e,t){const r=[];for(let s=0,a=e.elements.length;ss.value}}}return undefined},BinaryExpression:async function BinaryExpression(e,r){const s=e.operator;let a=await r(e.left);if(!a&&s!=="+")return;let o=await r(e.right);if(!a&&!o)return;if(!a){if(this.computeBranches&&o&&"value"in o&&typeof o.value==="string")return{value:t.WILDCARD+o.value,wildcards:[e.left,...o.wildcards||[]]};return}if(!o){if(this.computeBranches&&s==="+"){if(a&&"value"in a&&typeof a.value==="string")return{value:a.value+t.WILDCARD,wildcards:[...a.wildcards||[],e.right]}}if(!("test"in a)&&s==="||"&&a.value)return a;return}if("test"in a&&"value"in o){const e=o.value;if(s==="==")return{test:a.test,then:a.then==e,else:a.else==e};if(s==="===")return{test:a.test,then:a.then===e,else:a.else===e};if(s==="!=")return{test:a.test,then:a.then!=e,else:a.else!=e};if(s==="!==")return{test:a.test,then:a.then!==e,else:a.else!==e};if(s==="+")return{test:a.test,then:a.then+e,else:a.else+e};if(s==="-")return{test:a.test,then:a.then-e,else:a.else-e};if(s==="*")return{test:a.test,then:a.then*e,else:a.else*e};if(s==="/")return{test:a.test,then:a.then/e,else:a.else/e};if(s==="%")return{test:a.test,then:a.then%e,else:a.else%e};if(s==="<")return{test:a.test,then:a.then")return{test:a.test,then:a.then>e,else:a.else>e};if(s===">=")return{test:a.test,then:a.then>=e,else:a.else>=e};if(s==="|")return{test:a.test,then:a.then|e,else:a.else|e};if(s==="&")return{test:a.test,then:a.then&e,else:a.else&e};if(s==="^")return{test:a.test,then:a.then^e,else:a.else^e};if(s==="&&")return{test:a.test,then:a.then&&e,else:a.else&&e};if(s==="||")return{test:a.test,then:a.then||e,else:a.else||e}}else if("test"in o&&"value"in a){const e=a.value;if(s==="==")return{test:o.test,then:e==o.then,else:e==o.else};if(s==="===")return{test:o.test,then:e===o.then,else:e===o.else};if(s==="!=")return{test:o.test,then:e!=o.then,else:e!=o.else};if(s==="!==")return{test:o.test,then:e!==o.then,else:e!==o.else};if(s==="+")return{test:o.test,then:e+o.then,else:e+o.else};if(s==="-")return{test:o.test,then:e-o.then,else:e-o.else};if(s==="*")return{test:o.test,then:e*o.then,else:e*o.else};if(s==="/")return{test:o.test,then:e/o.then,else:e/o.else};if(s==="%")return{test:o.test,then:e%o.then,else:e%o.else};if(s==="<")return{test:o.test,then:e")return{test:o.test,then:e>o.then,else:e>o.else};if(s===">=")return{test:o.test,then:e>=o.then,else:e>=o.else};if(s==="|")return{test:o.test,then:e|o.then,else:e|o.else};if(s==="&")return{test:o.test,then:e&o.then,else:e&o.else};if(s==="^")return{test:o.test,then:e^o.then,else:e^o.else};if(s==="&&")return{test:o.test,then:e&&o.then,else:a&&o.else};if(s==="||")return{test:o.test,then:e||o.then,else:a||o.else}}else if("value"in a&&"value"in o){if(s==="==")return{value:a.value==o.value};if(s==="===")return{value:a.value===o.value};if(s==="!=")return{value:a.value!=o.value};if(s==="!==")return{value:a.value!==o.value};if(s==="+"){const e={value:a.value+o.value};let t=[];if("wildcards"in a&&a.wildcards){t=t.concat(a.wildcards)}if("wildcards"in o&&o.wildcards){t=t.concat(o.wildcards)}if(t.length>0){e.wildcards=t}return e}if(s==="-")return{value:a.value-o.value};if(s==="*")return{value:a.value*o.value};if(s==="/")return{value:a.value/o.value};if(s==="%")return{value:a.value%o.value};if(s==="<")return{value:a.value")return{value:a.value>o.value};if(s===">=")return{value:a.value>=o.value};if(s==="|")return{value:a.value|o.value};if(s==="&")return{value:a.value&o.value};if(s==="^")return{value:a.value^o.value};if(s==="&&")return{value:a.value&&o.value};if(s==="||")return{value:a.value||o.value}}return},CallExpression:async function CallExpression(e,r){const s=await r(e.callee);if(!s||"test"in s)return;let a=s.value;if(typeof a==="object"&&a!==null)a=a[t.FUNCTION];if(typeof a!=="function")return;let o=null;if(e.callee.object){o=await r(e.callee.object);o=o&&"value"in o&&o.value?o.value:null}let u;let c=[];let f;let d=e.arguments.length>0&&e.callee.property?.name!=="concat";const p=[];for(let s=0,a=e.arguments.length;sp.push(e)))}else{if(!this.computeBranches)return;a={value:t.WILDCARD};p.push(e.arguments[s])}if("test"in a){if(p.length)return;if(u)return;u=a.test;f=c.concat([]);c.push(a.then);f.push(a.else)}else{c.push(a.value);if(f)f.push(a.value)}}if(d)return;try{const e=await a.apply(o,c);if(e===t.UNKNOWN)return;if(!u){if(p.length){if(typeof e!=="string"||countWildcards(e)!==p.length)return;return{value:e,wildcards:p}}return{value:e}}const r=await a.apply(o,f);if(e===t.UNKNOWN)return;return{test:u,then:e,else:r}}catch(e){return}},ConditionalExpression:async function ConditionalExpression(e,t){const r=await t(e.test);if(r&&"value"in r)return r.value?t(e.consequent):t(e.alternate);if(!this.computeBranches)return;const s=await t(e.consequent);if(!s||"wildcards"in s||"test"in s)return;const a=await t(e.alternate);if(!a||"wildcards"in a||"test"in a)return;return{test:e.test,then:s.value,else:a.value}},ExpressionStatement:async function ExpressionStatement(e,t){return t(e.expression)},Identifier:async function Identifier(e,t){if(Object.hasOwnProperty.call(this.vars,e.name))return this.vars[e.name];return undefined},Literal:async function Literal(e,t){return{value:e.value}},MemberExpression:async function MemberExpression(e,r){const s=await r(e.object);if(!s||"test"in s||typeof s.value==="function"){return undefined}if(e.property.type==="Identifier"){if(typeof s.value==="string"&&e.property.name==="concat"){return{value:{[t.FUNCTION]:(...e)=>s.value.concat(e)}}}if(typeof s.value==="object"&&s.value!==null){const a=s.value;if(e.computed){const o=await r(e.property);if(o&&"value"in o&&o.value){const e=a[o.value];if(e===t.UNKNOWN)return undefined;return{value:e}}if(!a[t.UNKNOWN]&&Object.keys(s).length===0){return{value:undefined}}}else if(e.property.name in a){const r=a[e.property.name];if(r===t.UNKNOWN)return undefined;return{value:r}}else if(a[t.UNKNOWN])return undefined}else{return{value:undefined}}}const a=await r(e.property);if(!a||"test"in a)return undefined;if(typeof s.value==="object"&&s.value!==null){if(a.value in s.value){const e=s.value[a.value];if(e===t.UNKNOWN)return undefined;return{value:e}}else if(s.value[t.UNKNOWN]){return undefined}}else{return{value:undefined}}return undefined},MetaProperty:async function MetaProperty(e){if(e.meta.name==="import"&&e.property.name==="meta")return{value:this.vars["import.meta"]};return undefined},NewExpression:async function NewExpression(e,t){const r=await t(e.callee);if(r&&"value"in r&&r.value===s.URL&&e.arguments.length){const r=await t(e.arguments[0]);if(!r)return undefined;let a=null;if(e.arguments[1]){a=await t(e.arguments[1]);if(!a||!("value"in a))return undefined}if("value"in r){if(a){try{return{value:new s.URL(r.value,a.value)}}catch{return undefined}}try{return{value:new s.URL(r.value)}}catch{return undefined}}else{const e=r.test;if(a){try{return{test:e,then:new s.URL(r.then,a.value),else:new s.URL(r.else,a.value)}}catch{return undefined}}try{return{test:e,then:new s.URL(r.then),else:new s.URL(r.else)}}catch{return undefined}}}return undefined},ObjectExpression:async function ObjectExpression(e,r){const s={};for(let a=0;a{"use strict";Object.defineProperty(t,"__esModule",{value:true});t.handleWrappers=void 0;const s=r(3982);function isUndefinedOrVoid(e){return e.type==="Identifier"&&e.name==="undefined"||e.type==="UnaryExpression"&&e.operator==="void"&&e.argument.type==="Literal"&&e.argument.value===0}function handleWrappers(e){let t;if(e.body.length===1&&e.body[0].type==="ExpressionStatement"&&e.body[0].expression.type==="UnaryExpression"&&e.body[0].expression.operator==="!"&&e.body[0].expression.argument.type==="CallExpression"&&e.body[0].expression.argument.callee.type==="FunctionExpression"&&e.body[0].expression.argument.arguments.length===1)t=e.body[0].expression.argument;else if(e.body.length===1&&e.body[0].type==="ExpressionStatement"&&e.body[0].expression.type==="CallExpression"&&e.body[0].expression.callee.type==="FunctionExpression"&&(e.body[0].expression.arguments.length===1||e.body[0].expression.arguments.length===0))t=e.body[0].expression;else if(e.body.length===1&&e.body[0].type==="ExpressionStatement"&&e.body[0].expression.type==="AssignmentExpression"&&e.body[0].expression.left.type==="MemberExpression"&&e.body[0].expression.left.object.type==="Identifier"&&e.body[0].expression.left.object.name==="module"&&e.body[0].expression.left.property.type==="Identifier"&&e.body[0].expression.left.property.name==="exports"&&e.body[0].expression.right.type==="CallExpression"&&e.body[0].expression.right.callee.type==="FunctionExpression"&&e.body[0].expression.right.arguments.length===1)t=e.body[0].expression.right;if(t){let e;let r;if(t.arguments[0]&&t.arguments[0].type==="ConditionalExpression"&&t.arguments[0].test.type==="LogicalExpression"&&t.arguments[0].test.operator==="&&"&&t.arguments[0].test.left.type==="BinaryExpression"&&t.arguments[0].test.left.operator==="==="&&t.arguments[0].test.left.left.type==="UnaryExpression"&&t.arguments[0].test.left.left.operator==="typeof"&&"name"in t.arguments[0].test.left.left.argument&&t.arguments[0].test.left.left.argument.name==="define"&&t.arguments[0].test.left.right.type==="Literal"&&t.arguments[0].test.left.right.value==="function"&&t.arguments[0].test.right.type==="MemberExpression"&&t.arguments[0].test.right.object.type==="Identifier"&&t.arguments[0].test.right.property.type==="Identifier"&&t.arguments[0].test.right.property.name==="amd"&&t.arguments[0].test.right.computed===false&&t.arguments[0].alternate.type==="FunctionExpression"&&t.arguments[0].alternate.params.length===1&&t.arguments[0].alternate.params[0].type==="Identifier"&&t.arguments[0].alternate.body.body.length===1&&t.arguments[0].alternate.body.body[0].type==="ExpressionStatement"&&t.arguments[0].alternate.body.body[0].expression.type==="AssignmentExpression"&&t.arguments[0].alternate.body.body[0].expression.left.type==="MemberExpression"&&t.arguments[0].alternate.body.body[0].expression.left.object.type==="Identifier"&&t.arguments[0].alternate.body.body[0].expression.left.object.name==="module"&&t.arguments[0].alternate.body.body[0].expression.left.property.type==="Identifier"&&t.arguments[0].alternate.body.body[0].expression.left.property.name==="exports"&&t.arguments[0].alternate.body.body[0].expression.left.computed===false&&t.arguments[0].alternate.body.body[0].expression.right.type==="CallExpression"&&t.arguments[0].alternate.body.body[0].expression.right.callee.type==="Identifier"&&t.arguments[0].alternate.body.body[0].expression.right.callee.name===t.arguments[0].alternate.params[0].name&&"body"in t.callee&&"body"in t.callee.body&&Array.isArray(t.callee.body.body)&&t.arguments[0].alternate.body.body[0].expression.right.arguments.length===1&&t.arguments[0].alternate.body.body[0].expression.right.arguments[0].type==="Identifier"&&t.arguments[0].alternate.body.body[0].expression.right.arguments[0].name==="require"){let e=t.callee.body.body;if(e[0].type==="ExpressionStatement"&&e[0].expression.type==="Literal"&&e[0].expression.value==="use strict"){e=e.slice(1)}if(e.length===1&&e[0].type==="ExpressionStatement"&&e[0].expression.type==="CallExpression"&&e[0].expression.callee.type==="Identifier"&&e[0].expression.callee.name===t.arguments[0].test.right.object.name&&e[0].expression.arguments.length===1&&e[0].expression.arguments[0].type==="FunctionExpression"&&e[0].expression.arguments[0].params.length===1&&e[0].expression.arguments[0].params[0].type==="Identifier"&&e[0].expression.arguments[0].params[0].name==="require"){const t=e[0].expression.arguments[0];t.params=[];try{delete t.scope.declarations.require}catch(e){}}}else if(t.arguments[0]&&t.arguments[0].type==="FunctionExpression"&&t.arguments[0].params.length===0&&(t.arguments[0].body.body.length===1||t.arguments[0].body.body.length===2&&t.arguments[0].body.body[0].type==="VariableDeclaration"&&t.arguments[0].body.body[0].declarations.length===3&&t.arguments[0].body.body[0].declarations.every((e=>e.init===null&&e.id.type==="Identifier")))&&t.arguments[0].body.body[t.arguments[0].body.body.length-1].type==="ReturnStatement"&&(e=t.arguments[0].body.body[t.arguments[0].body.body.length-1])&&e.argument?.type==="CallExpression"&&e.argument.arguments.length&&e.argument.arguments.every((e=>e&&e.type==="Literal"&&typeof e.value==="number"))&&e.argument.callee.type==="CallExpression"&&(e.argument.callee.callee.type==="FunctionExpression"||e.argument.callee.callee.type==="CallExpression"&&e.argument.callee.callee.callee.type==="FunctionExpression"&&e.argument.callee.callee.arguments.length===0)&&e.argument.callee.arguments.length===3&&e.argument.callee.arguments[0].type==="ObjectExpression"&&e.argument.callee.arguments[1].type==="ObjectExpression"&&e.argument.callee.arguments[2].type==="ArrayExpression"){const t=e.argument.callee.arguments[0].properties;const r={};if(t.every((e=>{if(e.type!=="Property"||e.computed!==false||e.key.type!=="Literal"||typeof e.key.value!=="number"||e.value.type!=="ArrayExpression"||e.value.elements.length!==2||!e.value.elements[0]||!e.value.elements[1]||e.value.elements[0].type!=="FunctionExpression"||e.value.elements[1].type!=="ObjectExpression"){return false}const t=e.value.elements[1].properties;for(const e of t){if(e.type!=="Property"||e.value.type!=="Identifier"&&e.value.type!=="Literal"&&!isUndefinedOrVoid(e.value)||!(e.key.type==="Literal"&&typeof e.key.value==="string"||e.key.type==="Identifier")||e.computed){return false}if(isUndefinedOrVoid(e.value)){if(e.key.type==="Identifier"){r[e.key.name]={type:"Literal",start:e.key.start,end:e.key.end,value:e.key.name,raw:JSON.stringify(e.key.name)}}else if(e.key.type==="Literal"){r[String(e.key.value)]=e.key}}}return true}))){const t=Object.keys(r);const s=e.argument.callee.arguments[1];s.properties=t.map((e=>({type:"Property",method:false,shorthand:false,computed:false,kind:"init",key:r[e],value:{type:"ObjectExpression",properties:[{type:"Property",kind:"init",method:false,shorthand:false,computed:false,key:{type:"Identifier",name:"exports"},value:{type:"CallExpression",optional:false,callee:{type:"Identifier",name:"require"},arguments:[r[e]]}}]}})))}}else if(t.arguments[0]&&t.arguments[0].type==="FunctionExpression"&&t.arguments[0].params.length===2&&t.arguments[0].params[0].type==="Identifier"&&t.arguments[0].params[1].type==="Identifier"&&"body"in t.callee&&"body"in t.callee.body&&Array.isArray(t.callee.body.body)&&t.callee.body.body.length===1){const e=t.callee.body.body[0];if(e.type==="IfStatement"&&e.test.type==="LogicalExpression"&&e.test.operator==="&&"&&e.test.left.type==="BinaryExpression"&&e.test.left.left.type==="UnaryExpression"&&e.test.left.left.operator==="typeof"&&e.test.left.left.argument.type==="Identifier"&&e.test.left.left.argument.name==="module"&&e.test.left.right.type==="Literal"&&e.test.left.right.value==="object"&&e.test.right.type==="BinaryExpression"&&e.test.right.left.type==="UnaryExpression"&&e.test.right.left.operator==="typeof"&&e.test.right.left.argument.type==="MemberExpression"&&e.test.right.left.argument.object.type==="Identifier"&&e.test.right.left.argument.object.name==="module"&&e.test.right.left.argument.property.type==="Identifier"&&e.test.right.left.argument.property.name==="exports"&&e.test.right.right.type==="Literal"&&e.test.right.right.value==="object"&&e.consequent.type==="BlockStatement"&&e.consequent.body.length>0){let r;if(e.consequent.body[0].type==="VariableDeclaration"&&e.consequent.body[0].declarations[0].init&&e.consequent.body[0].declarations[0].init.type==="CallExpression")r=e.consequent.body[0].declarations[0].init;else if(e.consequent.body[0].type==="ExpressionStatement"&&e.consequent.body[0].expression.type==="CallExpression")r=e.consequent.body[0].expression;else if(e.consequent.body[0].type==="ExpressionStatement"&&e.consequent.body[0].expression.type==="AssignmentExpression"&&e.consequent.body[0].expression.operator==="="&&e.consequent.body[0].expression.right.type==="CallExpression")r=e.consequent.body[0].expression.right;if(r&&r.callee.type==="Identifier"&&"params"in t.callee&&t.callee.params.length>0&&"name"in t.callee.params[0]&&r.callee.name===t.callee.params[0].name&&r.arguments.length===2&&r.arguments[0].type==="Identifier"&&r.arguments[0].name==="require"&&r.arguments[1].type==="Identifier"&&r.arguments[1].name==="exports"){const e=t.arguments[0];e.params=[];try{const t=e.scope;delete t.declarations.require;delete t.declarations.exports}catch(e){}}}}else if(t.callee.type==="FunctionExpression"&&t.callee.body.body.length>2&&t.callee.body.body[0].type==="VariableDeclaration"&&t.callee.body.body[0].declarations.length===1&&t.callee.body.body[0].declarations[0].type==="VariableDeclarator"&&t.callee.body.body[0].declarations[0].id.type==="Identifier"&&t.callee.body.body[0].declarations[0].init&&(t.callee.body.body[0].declarations[0].init.type==="ObjectExpression"&&t.callee.body.body[0].declarations[0].init.properties.length===0||t.callee.body.body[0].declarations[0].init.type==="CallExpression"&&t.callee.body.body[0].declarations[0].init.arguments.length===1)&&(t.callee.body.body[1]&&t.callee.body.body[1].type==="FunctionDeclaration"&&t.callee.body.body[1].params.length===1&&t.callee.body.body[1].body.body.length>=3||t.callee.body.body[2]&&t.callee.body.body[2].type==="FunctionDeclaration"&&t.callee.body.body[2].params.length===1&&t.callee.body.body[2].body.body.length>=3)&&(t.arguments[0]&&(t.arguments[0].type==="ArrayExpression"&&(r=t.arguments[0])&&t.arguments[0].elements.length>0&&t.arguments[0].elements.every((e=>e&&e.type==="FunctionExpression"))||t.arguments[0].type==="ObjectExpression"&&(r=t.arguments[0])&&t.arguments[0].properties&&t.arguments[0].properties.length>0&&t.arguments[0].properties.every((e=>e&&e.type==="Property"&&!e.computed&&e.key&&e.key.type==="Literal"&&(typeof e.key.value==="string"||typeof e.key.value==="number")&&e.value&&e.value.type==="FunctionExpression"))))||t.arguments.length===0&&t.callee.type==="FunctionExpression"&&t.callee.params.length===0&&t.callee.body.type==="BlockStatement"&&t.callee.body.body.length>5&&t.callee.body.body[0].type==="VariableDeclaration"&&t.callee.body.body[0].declarations.length===1&&t.callee.body.body[0].declarations[0].id.type==="Identifier"&&t.callee.body.body[1].type==="ExpressionStatement"&&t.callee.body.body[1].expression.type==="AssignmentExpression"&&t.callee.body.body[2].type==="ExpressionStatement"&&t.callee.body.body[2].expression.type==="AssignmentExpression"&&t.callee.body.body[3].type==="ExpressionStatement"&&t.callee.body.body[3].expression.type==="AssignmentExpression"&&t.callee.body.body[3].expression.left.type==="MemberExpression"&&t.callee.body.body[3].expression.left.object.type==="Identifier"&&t.callee.body.body[3].expression.left.object.name===t.callee.body.body[0].declarations[0].id.name&&t.callee.body.body[3].expression.left.property.type==="Identifier"&&t.callee.body.body[3].expression.left.property.name==="modules"&&t.callee.body.body[3].expression.right.type==="ObjectExpression"&&t.callee.body.body[3].expression.right.properties.every((e=>e&&e.type==="Property"&&!e.computed&&e.key&&e.key.type==="Literal"&&(typeof e.key.value==="string"||typeof e.key.value==="number")&&e.value&&e.value.type==="FunctionExpression"))&&(r=t.callee.body.body[3].expression.right)&&(t.callee.body.body[4].type==="VariableDeclaration"&&t.callee.body.body[4].declarations.length===1&&t.callee.body.body[4].declarations[0].init&&t.callee.body.body[4].declarations[0].init.type==="CallExpression"&&t.callee.body.body[4].declarations[0].init.callee.type==="Identifier"&&t.callee.body.body[4].declarations[0].init.callee.name==="require"||t.callee.body.body[5].type==="VariableDeclaration"&&t.callee.body.body[5].declarations.length===1&&t.callee.body.body[5].declarations[0].init&&t.callee.body.body[5].declarations[0].init.type==="CallExpression"&&t.callee.body.body[5].declarations[0].init.callee.type==="Identifier"&&t.callee.body.body[5].declarations[0].init.callee.name==="require")){const e=new Map;let t;if(r.type==="ArrayExpression")t=r.elements.filter((e=>e?.type==="FunctionExpression")).map(((e,t)=>[String(t),e]));else t=r.properties.map((e=>[String(e.key.value),e.value]));for(const[r,s]of t){const t=s.body.body.length===1?s.body.body[0]:(s.body.body.length===2||s.body.body.length===3&&s.body.body[2].type==="EmptyStatement")&&s.body.body[0].type==="ExpressionStatement"&&s.body.body[0].expression.type==="Literal"&&s.body.body[0].expression.value==="use strict"?s.body.body[1]:null;if(t&&t.type==="ExpressionStatement"&&t.expression.type==="AssignmentExpression"&&t.expression.operator==="="&&t.expression.left.type==="MemberExpression"&&t.expression.left.object.type==="Identifier"&&"params"in s&&s.params.length>0&&"name"in s.params[0]&&t.expression.left.object.name===s.params[0].name&&t.expression.left.property.type==="Identifier"&&t.expression.left.property.name==="exports"&&t.expression.right.type==="CallExpression"&&t.expression.right.callee.type==="Identifier"&&t.expression.right.callee.name==="require"&&t.expression.right.arguments.length===1&&t.expression.right.arguments[0].type==="Literal"){e.set(r,t.expression.right.arguments[0].value)}}for(const[,r]of t){if("params"in r&&r.params.length===3&&r.params[2].type==="Identifier"){const t=new Map;(0,s.walk)(r.body,{enter(s,a){const o=s;const u=a;if(o.type==="CallExpression"&&o.callee.type==="Identifier"&&"name"in r.params[2]&&o.callee.name===r.params[2].name&&o.arguments.length===1&&o.arguments[0].type==="Literal"){const r=e.get(String(o.arguments[0].value));if(r){const e={type:"CallExpression",optional:false,callee:{type:"Identifier",name:"require"},arguments:[{type:"Literal",value:r}]};const s=u;if("right"in s&&s.right===o){s.right=e}else if("left"in s&&s.left===o){s.left=e}else if("object"in s&&s.object===o){s.object=e}else if("callee"in s&&s.callee===o){s.callee=e}else if("arguments"in s&&s.arguments.some((e=>e===o))){s.arguments=s.arguments.map((t=>t===o?e:t))}else if("init"in s&&s.init===o){if(s.type==="VariableDeclarator"&&s.id.type==="Identifier")t.set(s.id.name,r);s.init=e}}}else if(o.type==="CallExpression"&&o.callee.type==="MemberExpression"&&o.callee.object.type==="Identifier"&&"name"in r.params[2]&&o.callee.object.name===r.params[2].name&&o.callee.property.type==="Identifier"&&o.callee.property.name==="n"&&o.arguments.length===1&&o.arguments[0].type==="Identifier"){if(u&&"init"in u&&u.init===o){const e=o.arguments[0];const t={type:"CallExpression",optional:false,callee:{type:"MemberExpression",computed:false,optional:false,object:{type:"Identifier",name:"Object"},property:{type:"Identifier",name:"assign"}},arguments:[{type:"ArrowFunctionExpression",expression:true,params:[],body:e},{type:"ObjectExpression",properties:[{type:"Property",kind:"init",method:false,computed:false,shorthand:false,key:{type:"Identifier",name:"a"},value:e}]}]};u.init=t}}}})}}}}}t.handleWrappers=handleWrappers},351:(e,t)=>{e.exports=t=abbrev.abbrev=abbrev;abbrev.monkeyPatch=monkeyPatch;function monkeyPatch(){Object.defineProperty(Array.prototype,"abbrev",{value:function(){return abbrev(this)},enumerable:false,configurable:true,writable:true});Object.defineProperty(Object.prototype,"abbrev",{value:function(){return abbrev(Object.keys(this))},enumerable:false,configurable:true,writable:true})}function abbrev(e){if(arguments.length!==1||!Array.isArray(e)){e=Array.prototype.slice.call(arguments,0)}for(var t=0,r=e.length,s=[];tt?1:-1}},878:e=>{"use strict";function isArguments(e){return e!=null&&typeof e==="object"&&e.hasOwnProperty("callee")}var t={"*":{label:"any",check:function(){return true}},A:{label:"array",check:function(e){return Array.isArray(e)||isArguments(e)}},S:{label:"string",check:function(e){return typeof e==="string"}},N:{label:"number",check:function(e){return typeof e==="number"}},F:{label:"function",check:function(e){return typeof e==="function"}},O:{label:"object",check:function(e){return typeof e==="object"&&e!=null&&!t.A.check(e)&&!t.E.check(e)}},B:{label:"boolean",check:function(e){return typeof e==="boolean"}},E:{label:"error",check:function(e){return e instanceof Error}},Z:{label:"null",check:function(e){return e==null}}};function addSchema(e,t){var r=t[e.length]=t[e.length]||[];if(r.indexOf(e)===-1)r.push(e)}var r=e.exports=function(e,r){if(arguments.length!==2)throw wrongNumberOfArgs(["SA"],arguments.length);if(!e)throw missingRequiredArg(0,"rawSchemas");if(!r)throw missingRequiredArg(1,"args");if(!t.S.check(e))throw invalidType(0,["string"],e);if(!t.A.check(r))throw invalidType(1,["array"],r);var s=e.split("|");var a={};s.forEach((function(e){for(var r=0;r{"use strict";t.TrackerGroup=r(308);t.Tracker=r(7605);t.TrackerStream=r(374)},5299:(e,t,r)=>{"use strict";var s=r(2361).EventEmitter;var a=r(3837);var o=0;var u=e.exports=function(e){s.call(this);this.id=++o;this.name=e};a.inherits(u,s)},308:(e,t,r)=>{"use strict";var s=r(3837);var a=r(5299);var o=r(7605);var u=r(374);var c=e.exports=function(e){a.call(this,e);this.parentGroup=null;this.trackers=[];this.completion={};this.weight={};this.totalWeight=0;this.finished=false;this.bubbleChange=bubbleChange(this)};s.inherits(c,a);function bubbleChange(e){return function(t,r,s){e.completion[s.id]=r;if(e.finished)return;e.emit("change",t||e.name,e.completed(),e)}}c.prototype.nameInTree=function(){var e=[];var t=this;while(t){e.unshift(t.name);t=t.parentGroup}return e.join("/")};c.prototype.addUnit=function(e,t){if(e.addUnit){var r=this;while(r){if(e===r){throw new Error("Attempted to add tracker group "+e.name+" to tree that already includes it "+this.nameInTree(this))}r=r.parentGroup}e.parentGroup=this}this.weight[e.id]=t||1;this.totalWeight+=this.weight[e.id];this.trackers.push(e);this.completion[e.id]=e.completed();e.on("change",this.bubbleChange);if(!this.finished)this.emit("change",e.name,this.completion[e.id],e);return e};c.prototype.completed=function(){if(this.trackers.length===0)return 0;var e=1/this.totalWeight;var t=0;for(var r=0;r{"use strict";var s=r(3837);var a=r(8511);var o=r(857);var u=r(7605);var c=e.exports=function(e,t,r){a.Transform.call(this,r);this.tracker=new u(e,t);this.name=e;this.id=this.tracker.id;this.tracker.on("change",delegateChange(this))};s.inherits(c,a.Transform);function delegateChange(e){return function(t,r,s){e.emit("change",t,r,e)}}c.prototype._transform=function(e,t,r){this.tracker.completeWork(e.length?e.length:1);this.push(e);r()};c.prototype._flush=function(e){this.tracker.finish();e()};o(c.prototype,"tracker").method("completed").method("addWork").method("finish")},7605:(e,t,r)=>{"use strict";var s=r(3837);var a=r(5299);var o=e.exports=function(e,t){a.call(this,e);this.workDone=0;this.workTodo=t||0};s.inherits(o,a);o.prototype.completed=function(){return this.workTodo===0?0:this.workDone/this.workTodo};o.prototype.addWork=function(e){this.workTodo+=e;this.emit("change",this.name,this.completed(),this)};o.prototype.completeWork=function(e){this.workDone+=e;if(this.workDone>this.workTodo)this.workDone=this.workTodo;this.emit("change",this.name,this.completed(),this)};o.prototype.finish=function(){this.workTodo=this.workDone=1;this.emit("change",this.name,1,this)}},3331:(module,exports,__nccwpck_require__)=>{var fs=__nccwpck_require__(7147),path=__nccwpck_require__(1017),fileURLToPath=__nccwpck_require__(7121),join=path.join,dirname=path.dirname,exists=fs.accessSync&&function(e){try{fs.accessSync(e)}catch(e){return false}return true}||fs.existsSync||path.existsSync,defaults={arrow:process.env.NODE_BINDINGS_ARROW||" → ",compiled:process.env.NODE_BINDINGS_COMPILED_DIR||"compiled",platform:process.platform,arch:process.arch,nodePreGyp:"node-v"+process.versions.modules+"-"+process.platform+"-"+process.arch,version:process.versions.node,bindings:"bindings.node",try:[["module_root","build","bindings"],["module_root","build","Debug","bindings"],["module_root","build","Release","bindings"],["module_root","out","Debug","bindings"],["module_root","Debug","bindings"],["module_root","out","Release","bindings"],["module_root","Release","bindings"],["module_root","build","default","bindings"],["module_root","compiled","version","platform","arch","bindings"],["module_root","addon-build","release","install-root","bindings"],["module_root","addon-build","debug","install-root","bindings"],["module_root","addon-build","default","install-root","bindings"],["module_root","lib","binding","nodePreGyp","bindings"]]};function bindings(opts){if(typeof opts=="string"){opts={bindings:opts}}else if(!opts){opts={}}Object.keys(defaults).map((function(e){if(!(e in opts))opts[e]=defaults[e]}));if(!opts.module_root){opts.module_root=exports.getRoot(exports.getFileName())}if(path.extname(opts.bindings)!=".node"){opts.bindings+=".node"}var requireFunc=true?eval("require"):0;var tries=[],i=0,l=opts.try.length,n,b,err;for(;i{"use strict";e.exports=function(e,t){if(e===null||e===undefined){throw TypeError()}e=String(e);var r=e.length;var s=t?Number(t):0;if(Number.isNaN(s)){s=0}if(s<0||s>=r){return undefined}var a=e.charCodeAt(s);if(a>=55296&&a<=56319&&r>s+1){var o=e.charCodeAt(s+1);if(o>=56320&&o<=57343){return(a-55296)*1024+o-56320+65536}}return a}},3844:(e,t)=>{"use strict";var r="[";t.up=function up(e){return r+(e||"")+"A"};t.down=function down(e){return r+(e||"")+"B"};t.forward=function forward(e){return r+(e||"")+"C"};t.back=function back(e){return r+(e||"")+"D"};t.nextLine=function nextLine(e){return r+(e||"")+"E"};t.previousLine=function previousLine(e){return r+(e||"")+"F"};t.horizontalAbsolute=function horizontalAbsolute(e){if(e==null)throw new Error("horizontalAboslute requires a column to position to");return r+e+"G"};t.eraseData=function eraseData(){return r+"J"};t.eraseLine=function eraseLine(){return r+"K"};t.goto=function(e,t){return r+t+";"+e+"H"};t.gotoSOL=function(){return"\r"};t.beep=function(){return""};t.hideCursor=function hideCursor(){return r+"?25l"};t.showCursor=function showCursor(){return r+"?25h"};var s={reset:0,bold:1,italic:3,underline:4,inverse:7,stopBold:22,stopItalic:23,stopUnderline:24,stopInverse:27,white:37,black:30,blue:34,cyan:36,green:32,magenta:35,red:31,yellow:33,bgWhite:47,bgBlack:40,bgBlue:44,bgCyan:46,bgGreen:42,bgMagenta:45,bgRed:41,bgYellow:43,grey:90,brightBlack:90,brightRed:91,brightGreen:92,brightYellow:93,brightBlue:94,brightMagenta:95,brightCyan:96,brightWhite:97,bgGrey:100,bgBrightBlack:100,bgBrightRed:101,bgBrightGreen:102,bgBrightYellow:103,bgBrightBlue:104,bgBrightMagenta:105,bgBrightCyan:106,bgBrightWhite:107};t.color=function color(e){if(arguments.length!==1||!Array.isArray(e)){e=Array.prototype.slice.call(arguments)}return r+e.map(colorNameToCode).join(";")+"m"};function colorNameToCode(e){if(s[e]!=null)return s[e];throw new Error("Unknown color or style name: "+e)}},1504:(e,t)=>{function isArray(e){if(Array.isArray){return Array.isArray(e)}return objectToString(e)==="[object Array]"}t.isArray=isArray;function isBoolean(e){return typeof e==="boolean"}t.isBoolean=isBoolean;function isNull(e){return e===null}t.isNull=isNull;function isNullOrUndefined(e){return e==null}t.isNullOrUndefined=isNullOrUndefined;function isNumber(e){return typeof e==="number"}t.isNumber=isNumber;function isString(e){return typeof e==="string"}t.isString=isString;function isSymbol(e){return typeof e==="symbol"}t.isSymbol=isSymbol;function isUndefined(e){return e===void 0}t.isUndefined=isUndefined;function isRegExp(e){return objectToString(e)==="[object RegExp]"}t.isRegExp=isRegExp;function isObject(e){return typeof e==="object"&&e!==null}t.isObject=isObject;function isDate(e){return objectToString(e)==="[object Date]"}t.isDate=isDate;function isError(e){return objectToString(e)==="[object Error]"||e instanceof Error}t.isError=isError;function isFunction(e){return typeof e==="function"}t.isFunction=isFunction;function isPrimitive(e){return e===null||typeof e==="boolean"||typeof e==="number"||typeof e==="string"||typeof e==="symbol"||typeof e==="undefined"}t.isPrimitive=isPrimitive;t.isBuffer=Buffer.isBuffer;function objectToString(e){return Object.prototype.toString.call(e)}},857:e=>{e.exports=Delegator;function Delegator(e,t){if(!(this instanceof Delegator))return new Delegator(e,t);this.proto=e;this.target=t;this.methods=[];this.getters=[];this.setters=[];this.fluents=[]}Delegator.prototype.method=function(e){var t=this.proto;var r=this.target;this.methods.push(e);t[e]=function(){return this[r][e].apply(this[r],arguments)};return this};Delegator.prototype.access=function(e){return this.getter(e).setter(e)};Delegator.prototype.getter=function(e){var t=this.proto;var r=this.target;this.getters.push(e);t.__defineGetter__(e,(function(){return this[r][e]}));return this};Delegator.prototype.setter=function(e){var t=this.proto;var r=this.target;this.setters.push(e);t.__defineSetter__(e,(function(t){return this[r][e]=t}));return this};Delegator.prototype.fluent=function(e){var t=this.proto;var r=this.target;this.fluents.push(e);t[e]=function(t){if("undefined"!=typeof t){this[r][e]=t;return this}else{return this[r][e]}};return this}},5104:(e,t,r)=>{"use strict";var s=r(2037).platform();var a=r(2081).spawnSync;var o=r(7147).readdirSync;var u="glibc";var c="musl";var f={encoding:"utf8",env:process.env};if(!a){a=function(){return{status:126,stdout:"",stderr:""}}}function contains(e){return function(t){return t.indexOf(e)!==-1}}function versionFromMuslLdd(e){return e.split(/[\r\n]+/)[1].trim().split(/\s/)[1]}function safeReaddirSync(e){try{return o(e)}catch(e){}return[]}var d="";var p="";var h="";if(s==="linux"){var v=a("getconf",["GNU_LIBC_VERSION"],f);if(v.status===0){d=u;p=v.stdout.trim().split(" ")[1];h="getconf"}else{var D=a("ldd",["--version"],f);if(D.status===0&&D.stdout.indexOf(c)!==-1){d=c;p=versionFromMuslLdd(D.stdout);h="ldd"}else if(D.status===1&&D.stderr.indexOf(c)!==-1){d=c;p=versionFromMuslLdd(D.stderr);h="ldd"}else{var g=safeReaddirSync("/lib");if(g.some(contains("-linux-gnu"))){d=u;h="filesystem"}else if(g.some(contains("libc.musl-"))){d=c;h="filesystem"}else if(g.some(contains("ld-musl-"))){d=c;h="filesystem"}else{var y=safeReaddirSync("/usr/sbin");if(y.some(contains("glibc"))){d=u;h="filesystem"}}}}}var m=d!==""&&d!==u;e.exports={GLIBC:u,MUSL:c,family:d,version:p,method:h,isNonGlibcLinux:m}},3876:e=>{"use strict";e.exports=function(){return/\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73)\uDB40\uDC7F|\uD83D\uDC68(?:\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68\uD83C\uDFFB|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|[\u2695\u2696\u2708]\uFE0F|\uD83D[\uDC66\uDC67]|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708])\uFE0F|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C[\uDFFB-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)\uD83C\uDFFB|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB\uDFFC])|\uD83D\uDC69(?:\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D\uD83D\uDC69)(?:\uD83C[\uDFFB-\uDFFD])|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|(?:(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)\uFE0F|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:(?:\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\u200D[\u2640\u2642])|\uD83C\uDFF4\u200D\u2620)\uFE0F|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF4\uD83C\uDDF2|\uD83C\uDDF6\uD83C\uDDE6|[#\*0-9]\uFE0F\u20E3|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83D\uDC69(?:\uD83C[\uDFFB-\uDFFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270A-\u270D]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC70\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDCAA\uDD74\uDD7A\uDD90\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD36\uDDB5\uDDB6\uDDBB\uDDD2-\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5\uDEEB\uDEEC\uDEF4-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFA\uDFE0-\uDFEB]|\uD83E[\uDD0D-\uDD3A\uDD3C-\uDD45\uDD47-\uDD71\uDD73-\uDD76\uDD7A-\uDDA2\uDDA5-\uDDAA\uDDAE-\uDDCA\uDDCD-\uDDFF\uDE70-\uDE73\uDE78-\uDE7A\uDE80-\uDE82\uDE90-\uDE95])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g}},7121:(e,t,r)=>{var s=r(1017).sep||"/";e.exports=fileUriToPath;function fileUriToPath(e){if("string"!=typeof e||e.length<=7||"file://"!=e.substring(0,7)){throw new TypeError("must pass in a file:// URI to convert to a file path")}var t=decodeURI(e.substring(7));var r=t.indexOf("/");var a=t.substring(0,r);var o=t.substring(r+1);if("localhost"==a)a="";if(a){a=s+s+a}o=o.replace(/^(.+)\|/,"$1:");if(s=="\\"){o=o.replace(/\//g,"\\")}if(/^.+\:/.test(o)){}else{o=s+o}return a+o}},8862:(e,t,r)=>{"use strict";var s=r(5154);var a=r(4044);e.exports={activityIndicator:function(e,t,r){if(e.spun==null)return;return s(t,e.spun)},progressbar:function(e,t,r){if(e.completed==null)return;return a(t,r,e.completed)}}},2905:(e,t,r)=>{"use strict";var s=r(3837);var a=t.User=function User(e){var t=new Error(e);Error.captureStackTrace(t,User);t.code="EGAUGE";return t};t.MissingTemplateValue=function MissingTemplateValue(e,t){var r=new a(s.format('Missing template value "%s"',e.type));Error.captureStackTrace(r,MissingTemplateValue);r.template=e;r.values=t;return r};t.Internal=function Internal(e){var t=new Error(e);Error.captureStackTrace(t,Internal);t.code="EGAUGEINTERNAL";return t}},1191:e=>{"use strict";e.exports=isWin32()||isColorTerm();function isWin32(){return process.platform==="win32"}function isColorTerm(){var e=/^screen|^xterm|^vt100|color|ansi|cygwin|linux/i;return!!process.env.COLORTERM||e.test(process.env.TERM)}},287:(e,t,r)=>{"use strict";var s=r(4052);var a=r(5214);var o=r(1191);var u=r(7234);var c=r(9986);var f=r(7131);var d=r(5751);var p=r(5498);e.exports=Gauge;function callWith(e,t){return function(){return t.call(e)}}function Gauge(e,t){var r,a;if(e&&e.write){a=e;r=t||{}}else if(t&&t.write){a=t;r=e||{}}else{a=d.stderr;r=e||t||{}}this._status={spun:0,section:"",subsection:""};this._paused=false;this._disabled=true;this._showing=false;this._onScreen=false;this._needsRedraw=false;this._hideCursor=r.hideCursor==null?true:r.hideCursor;this._fixedFramerate=r.fixedFramerate==null?!/^v0\.8\./.test(d.version):r.fixedFramerate;this._lastUpdateAt=null;this._updateInterval=r.updateInterval==null?50:r.updateInterval;this._themes=r.themes||c;this._theme=r.theme;var o=this._computeTheme(r.theme);var u=r.template||[{type:"progressbar",length:20},{type:"activityIndicator",kerning:1,length:1},{type:"section",kerning:1,default:""},{type:"subsection",kerning:1,default:""}];this.setWriteTo(a,r.tty);var f=r.Plumbing||s;this._gauge=new f(o,u,this.getWidth());this._$$doRedraw=callWith(this,this._doRedraw);this._$$handleSizeChange=callWith(this,this._handleSizeChange);this._cleanupOnExit=r.cleanupOnExit==null||r.cleanupOnExit;this._removeOnExit=null;if(r.enabled||r.enabled==null&&this._tty&&this._tty.isTTY){this.enable()}else{this.disable()}}Gauge.prototype={};Gauge.prototype.isEnabled=function(){return!this._disabled};Gauge.prototype.setTemplate=function(e){this._gauge.setTemplate(e);if(this._showing)this._requestRedraw()};Gauge.prototype._computeTheme=function(e){if(!e)e={};if(typeof e==="string"){e=this._themes.getTheme(e)}else if(e&&(Object.keys(e).length===0||e.hasUnicode!=null||e.hasColor!=null)){var t=e.hasUnicode==null?a():e.hasUnicode;var r=e.hasColor==null?o:e.hasColor;e=this._themes.getDefault({hasUnicode:t,hasColor:r,platform:e.platform})}return e};Gauge.prototype.setThemeset=function(e){this._themes=e;this.setTheme(this._theme)};Gauge.prototype.setTheme=function(e){this._gauge.setTheme(this._computeTheme(e));if(this._showing)this._requestRedraw();this._theme=e};Gauge.prototype._requestRedraw=function(){this._needsRedraw=true;if(!this._fixedFramerate)this._doRedraw()};Gauge.prototype.getWidth=function(){return(this._tty&&this._tty.columns||80)-1};Gauge.prototype.setWriteTo=function(e,t){var r=!this._disabled;if(r)this.disable();this._writeTo=e;this._tty=t||e===d.stderr&&d.stdout.isTTY&&d.stdout||e.isTTY&&e||this._tty;if(this._gauge)this._gauge.setWidth(this.getWidth());if(r)this.enable()};Gauge.prototype.enable=function(){if(!this._disabled)return;this._disabled=false;if(this._tty)this._enableEvents();if(this._showing)this.show()};Gauge.prototype.disable=function(){if(this._disabled)return;if(this._showing){this._lastUpdateAt=null;this._showing=false;this._doRedraw();this._showing=true}this._disabled=true;if(this._tty)this._disableEvents()};Gauge.prototype._enableEvents=function(){if(this._cleanupOnExit){this._removeOnExit=u(callWith(this,this.disable))}this._tty.on("resize",this._$$handleSizeChange);if(this._fixedFramerate){this.redrawTracker=f(this._$$doRedraw,this._updateInterval);if(this.redrawTracker.unref)this.redrawTracker.unref()}};Gauge.prototype._disableEvents=function(){this._tty.removeListener("resize",this._$$handleSizeChange);if(this._fixedFramerate)clearInterval(this.redrawTracker);if(this._removeOnExit)this._removeOnExit()};Gauge.prototype.hide=function(e){if(this._disabled)return e&&d.nextTick(e);if(!this._showing)return e&&d.nextTick(e);this._showing=false;this._doRedraw();e&&p(e)};Gauge.prototype.show=function(e,t){this._showing=true;if(typeof e==="string"){this._status.section=e}else if(typeof e==="object"){var r=Object.keys(e);for(var s=0;s{"use strict";var s=r(3844);var a=r(7238);var o=r(878);var u=e.exports=function(e,t,r){if(!r)r=80;o("OAN",[e,t,r]);this.showing=false;this.theme=e;this.width=r;this.template=t};u.prototype={};u.prototype.setTheme=function(e){o("O",[e]);this.theme=e};u.prototype.setTemplate=function(e){o("A",[e]);this.template=e};u.prototype.setWidth=function(e){o("N",[e]);this.width=e};u.prototype.hide=function(){return s.gotoSOL()+s.eraseLine()};u.prototype.hideCursor=s.hideCursor;u.prototype.showCursor=s.showCursor;u.prototype.show=function(e){var t=Object.create(this.theme);for(var r in e){t[r]=e[r]}return a(this.width,this.template,t).trim()+s.color("reset")+s.eraseLine()+s.gotoSOL()}},5751:e=>{"use strict";e.exports=process},4044:(e,t,r)=>{"use strict";var s=r(878);var a=r(7238);var o=r(5791);var u=r(8321);e.exports=function(e,t,r){s("ONN",[e,t,r]);if(r<0)r=0;if(r>1)r=1;if(t<=0)return"";var o=Math.round(t*r);var u=t-o;var c=[{type:"complete",value:repeat(e.complete,o),length:o},{type:"remaining",value:repeat(e.remaining,u),length:u}];return a(t,c,e)};function repeat(e,t){var r="";var s=t;do{if(s%2){r+=e}s=Math.floor(s/2);e+=e}while(s&&u(r){"use strict";var s=r(1365);var a=r(878);var o=r(3540);var u=r(5791);var c=r(2905);var f=r(8855);function renderValueWithValues(e){return function(t){return renderValue(t,e)}}var d=e.exports=function(e,t,r){var a=prepareItems(e,t,r);var o=a.map(renderValueWithValues(r)).join("");return s.left(u(o,e),e)};function preType(e){var t=e.type[0].toUpperCase()+e.type.slice(1);return"pre"+t}function postType(e){var t=e.type[0].toUpperCase()+e.type.slice(1);return"post"+t}function hasPreOrPost(e,t){if(!e.type)return;return t[preType(e)]||t[postType(e)]}function generatePreAndPost(e,t){var r=o({},e);var s=Object.create(t);var a=[];var u=preType(r);var c=postType(r);if(s[u]){a.push({value:s[u]});s[u]=null}r.minLength=null;r.length=null;r.maxLength=null;a.push(r);s[r.type]=s[r.type];if(s[c]){a.push({value:s[c]});s[c]=null}return function(e,t,r){return d(r,a,s)}}function prepareItems(e,t,r){function cloneAndObjectify(t,s,a){var o=new f(t,e);var u=o.type;if(o.value==null){if(!(u in r)){if(o.default==null){throw new c.MissingTemplateValue(o,r)}else{o.value=o.default}}else{o.value=r[u]}}if(o.value==null||o.value==="")return null;o.index=s;o.first=s===0;o.last=s===a.length-1;if(hasPreOrPost(o,r))o.value=generatePreAndPost(o,r);return o}var s=t.map(cloneAndObjectify).filter((function(e){return e!=null}));var a=0;var o=e;var u=s.length;function consumeSpace(e){if(e>o)e=o;a+=e;o-=e}function finishSizing(e,t){if(e.finished)throw new c.Internal("Tried to finish template item that was already finished");if(t===Infinity)throw new c.Internal("Length of template item cannot be infinity");if(t!=null)e.length=t;e.minLength=null;e.maxLength=null;--u;e.finished=true;if(e.length==null)e.length=e.getBaseLength();if(e.length==null)throw new c.Internal("Finished template items must have a length");consumeSpace(e.getLength())}s.forEach((function(e){if(!e.kerning)return;var t=e.first?0:s[e.index-1].padRight;if(!e.first&&t=h){finishSizing(e,e.minLength);p=true}}))}while(p&&d++{"use strict";var s=r(5751);try{e.exports=setImmediate}catch(t){e.exports=s.nextTick}},7131:e=>{"use strict";e.exports=setInterval},5154:e=>{"use strict";e.exports=function spin(e,t){return e[t%e.length]}},8855:(e,t,r)=>{"use strict";var s=r(8321);e.exports=TemplateItem;function isPercent(e){if(typeof e!=="string")return false;return e.slice(-1)==="%"}function percent(e){return Number(e.slice(0,-1))/100}function TemplateItem(e,t){this.overallOutputLength=t;this.finished=false;this.type=null;this.value=null;this.length=null;this.maxLength=null;this.minLength=null;this.kerning=null;this.align="left";this.padLeft=0;this.padRight=0;this.index=null;this.first=null;this.last=null;if(typeof e==="string"){this.value=e}else{for(var r in e)this[r]=e[r]}if(isPercent(this.length)){this.length=Math.round(this.overallOutputLength*percent(this.length))}if(isPercent(this.minLength)){this.minLength=Math.round(this.overallOutputLength*percent(this.minLength))}if(isPercent(this.maxLength)){this.maxLength=Math.round(this.overallOutputLength*percent(this.maxLength))}return this}TemplateItem.prototype={};TemplateItem.prototype.getBaseLength=function(){var e=this.length;if(e==null&&typeof this.value==="string"&&this.maxLength==null&&this.minLength==null){e=s(this.value)}return e};TemplateItem.prototype.getLength=function(){var e=this.getBaseLength();if(e==null)return null;return e+this.padLeft+this.padRight};TemplateItem.prototype.getMaxLength=function(){if(this.maxLength==null)return null;return this.maxLength+this.padLeft+this.padRight};TemplateItem.prototype.getMinLength=function(){if(this.minLength==null)return null;return this.minLength+this.padLeft+this.padRight}},8469:(e,t,r)=>{"use strict";var s=r(3540);e.exports=function(){return a.newThemeSet()};var a={};a.baseTheme=r(8862);a.newTheme=function(e,t){if(!t){t=e;e=this.baseTheme}return s({},e,t)};a.getThemeNames=function(){return Object.keys(this.themes)};a.addTheme=function(e,t,r){this.themes[e]=this.newTheme(t,r)};a.addToAllThemes=function(e){var t=this.themes;Object.keys(t).forEach((function(r){s(t[r],e)}));s(this.baseTheme,e)};a.getTheme=function(e){if(!this.themes[e])throw this.newMissingThemeError(e);return this.themes[e]};a.setDefault=function(e,t){if(t==null){t=e;e={}}var r=e.platform==null?"fallback":e.platform;var s=!!e.hasUnicode;var a=!!e.hasColor;if(!this.defaults[r])this.defaults[r]={true:{},false:{}};this.defaults[r][s][a]=t};a.getDefault=function(e){if(!e)e={};var t=e.platform||process.platform;var r=this.defaults[t]||this.defaults.fallback;var a=!!e.hasUnicode;var o=!!e.hasColor;if(!r)throw this.newMissingDefaultThemeError(t,a,o);if(!r[a][o]){if(a&&o&&r[!a][o]){a=false}else if(a&&o&&r[a][!o]){o=false}else if(a&&o&&r[!a][!o]){a=false;o=false}else if(a&&!o&&r[!a][o]){a=false}else if(!a&&o&&r[a][!o]){o=false}else if(r===this.defaults.fallback){throw this.newMissingDefaultThemeError(t,a,o)}}if(r[a][o]){return this.getTheme(r[a][o])}else{return this.getDefault(s({},e,{platform:"fallback"}))}};a.newMissingThemeError=function newMissingThemeError(e){var t=new Error('Could not find a gauge theme named "'+e+'"');Error.captureStackTrace.call(t,newMissingThemeError);t.theme=e;t.code="EMISSINGTHEME";return t};a.newMissingDefaultThemeError=function newMissingDefaultThemeError(e,t,r){var s=new Error("Could not find a gauge theme for your platform/unicode/color use combo:\n"+" platform = "+e+"\n"+" hasUnicode = "+t+"\n"+" hasColor = "+r);Error.captureStackTrace.call(s,newMissingDefaultThemeError);s.platform=e;s.hasUnicode=t;s.hasColor=r;s.code="EMISSINGTHEME";return s};a.newThemeSet=function(){var themeset=function(e){return themeset.getDefault(e)};return s(themeset,a,{themes:s({},this.themes),baseTheme:s({},this.baseTheme),defaults:JSON.parse(JSON.stringify(this.defaults||{}))})}},9986:(e,t,r)=>{"use strict";var s=r(3844);var a=r(8469);var o=e.exports=new a;o.addTheme("ASCII",{preProgressbar:"[",postProgressbar:"]",progressbarTheme:{complete:"#",remaining:"."},activityIndicatorTheme:"-\\|/",preSubsection:">"});o.addTheme("colorASCII",o.getTheme("ASCII"),{progressbarTheme:{preComplete:s.color("inverse"),complete:" ",postComplete:s.color("stopInverse"),preRemaining:s.color("brightBlack"),remaining:".",postRemaining:s.color("reset")}});o.addTheme("brailleSpinner",{preProgressbar:"⸨",postProgressbar:"⸩",progressbarTheme:{complete:"░",remaining:"⠂"},activityIndicatorTheme:"⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏",preSubsection:">"});o.addTheme("colorBrailleSpinner",o.getTheme("brailleSpinner"),{progressbarTheme:{preComplete:s.color("inverse"),complete:" ",postComplete:s.color("stopInverse"),preRemaining:s.color("brightBlack"),remaining:"░",postRemaining:s.color("reset")}});o.setDefault({},"ASCII");o.setDefault({hasColor:true},"colorASCII");o.setDefault({platform:"darwin",hasUnicode:true},"brailleSpinner");o.setDefault({platform:"darwin",hasUnicode:true,hasColor:true},"colorBrailleSpinner")},5791:(e,t,r)=>{"use strict";var s=r(8321);var a=r(7518);e.exports=wideTruncate;function wideTruncate(e,t){if(s(e)===0)return e;if(t<=0)return"";if(s(e)<=t)return e;var r=a(e);var o=e.length+r.length;var u=e.slice(0,t+o);while(s(u)>t){u=u.slice(0,-1)}return u}},8567:e=>{"use strict";e.exports=clone;var t=Object.getPrototypeOf||function(e){return e.__proto__};function clone(e){if(e===null||typeof e!=="object")return e;if(e instanceof Object)var r={__proto__:t(e)};else var r=Object.create(null);Object.getOwnPropertyNames(e).forEach((function(t){Object.defineProperty(r,t,Object.getOwnPropertyDescriptor(e,t))}));return r}},6450:(e,t,r)=>{var s=r(7147);var a=r(2164);var o=r(5653);var u=r(8567);var c=r(3837);var f;var d;if(typeof Symbol==="function"&&typeof Symbol.for==="function"){f=Symbol.for("graceful-fs.queue");d=Symbol.for("graceful-fs.previous")}else{f="___graceful-fs.queue";d="___graceful-fs.previous"}function noop(){}function publishQueue(e,t){Object.defineProperty(e,f,{get:function(){return t}})}var p=noop;if(c.debuglog)p=c.debuglog("gfs4");else if(/\bgfs4\b/i.test(process.env.NODE_DEBUG||""))p=function(){var e=c.format.apply(c,arguments);e="GFS4: "+e.split(/\n/).join("\nGFS4: ");console.error(e)};if(!s[f]){var h=global[f]||[];publishQueue(s,h);s.close=function(e){function close(t,r){return e.call(s,t,(function(e){if(!e){resetQueue()}if(typeof r==="function")r.apply(this,arguments)}))}Object.defineProperty(close,d,{value:e});return close}(s.close);s.closeSync=function(e){function closeSync(t){e.apply(s,arguments);resetQueue()}Object.defineProperty(closeSync,d,{value:e});return closeSync}(s.closeSync);if(/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")){process.on("exit",(function(){p(s[f]);r(9491).equal(s[f].length,0)}))}}if(!global[f]){publishQueue(global,s[f])}e.exports=patch(u(s));if(process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH&&!s.__patched){e.exports=patch(s);s.__patched=true}function patch(e){a(e);e.gracefulify=patch;e.createReadStream=createReadStream;e.createWriteStream=createWriteStream;var t=e.readFile;e.readFile=readFile;function readFile(e,r,s){if(typeof r==="function")s=r,r=null;return go$readFile(e,r,s);function go$readFile(e,r,s,a){return t(e,r,(function(t){if(t&&(t.code==="EMFILE"||t.code==="ENFILE"))enqueue([go$readFile,[e,r,s],t,a||Date.now(),Date.now()]);else{if(typeof s==="function")s.apply(this,arguments)}}))}}var r=e.writeFile;e.writeFile=writeFile;function writeFile(e,t,s,a){if(typeof s==="function")a=s,s=null;return go$writeFile(e,t,s,a);function go$writeFile(e,t,s,a,o){return r(e,t,s,(function(r){if(r&&(r.code==="EMFILE"||r.code==="ENFILE"))enqueue([go$writeFile,[e,t,s,a],r,o||Date.now(),Date.now()]);else{if(typeof a==="function")a.apply(this,arguments)}}))}}var s=e.appendFile;if(s)e.appendFile=appendFile;function appendFile(e,t,r,a){if(typeof r==="function")a=r,r=null;return go$appendFile(e,t,r,a);function go$appendFile(e,t,r,a,o){return s(e,t,r,(function(s){if(s&&(s.code==="EMFILE"||s.code==="ENFILE"))enqueue([go$appendFile,[e,t,r,a],s,o||Date.now(),Date.now()]);else{if(typeof a==="function")a.apply(this,arguments)}}))}}var u=e.copyFile;if(u)e.copyFile=copyFile;function copyFile(e,t,r,s){if(typeof r==="function"){s=r;r=0}return go$copyFile(e,t,r,s);function go$copyFile(e,t,r,s,a){return u(e,t,r,(function(o){if(o&&(o.code==="EMFILE"||o.code==="ENFILE"))enqueue([go$copyFile,[e,t,r,s],o,a||Date.now(),Date.now()]);else{if(typeof s==="function")s.apply(this,arguments)}}))}}var c=e.readdir;e.readdir=readdir;var f=/^v[0-5]\./;function readdir(e,t,r){if(typeof t==="function")r=t,t=null;var s=f.test(process.version)?function go$readdir(e,t,r,s){return c(e,fs$readdirCallback(e,t,r,s))}:function go$readdir(e,t,r,s){return c(e,t,fs$readdirCallback(e,t,r,s))};return s(e,t,r);function fs$readdirCallback(e,t,r,a){return function(o,u){if(o&&(o.code==="EMFILE"||o.code==="ENFILE"))enqueue([s,[e,t,r],o,a||Date.now(),Date.now()]);else{if(u&&u.sort)u.sort();if(typeof r==="function")r.call(this,o,u)}}}}if(process.version.substr(0,4)==="v0.8"){var d=o(e);ReadStream=d.ReadStream;WriteStream=d.WriteStream}var p=e.ReadStream;if(p){ReadStream.prototype=Object.create(p.prototype);ReadStream.prototype.open=ReadStream$open}var h=e.WriteStream;if(h){WriteStream.prototype=Object.create(h.prototype);WriteStream.prototype.open=WriteStream$open}Object.defineProperty(e,"ReadStream",{get:function(){return ReadStream},set:function(e){ReadStream=e},enumerable:true,configurable:true});Object.defineProperty(e,"WriteStream",{get:function(){return WriteStream},set:function(e){WriteStream=e},enumerable:true,configurable:true});var v=ReadStream;Object.defineProperty(e,"FileReadStream",{get:function(){return v},set:function(e){v=e},enumerable:true,configurable:true});var D=WriteStream;Object.defineProperty(e,"FileWriteStream",{get:function(){return D},set:function(e){D=e},enumerable:true,configurable:true});function ReadStream(e,t){if(this instanceof ReadStream)return p.apply(this,arguments),this;else return ReadStream.apply(Object.create(ReadStream.prototype),arguments)}function ReadStream$open(){var e=this;open(e.path,e.flags,e.mode,(function(t,r){if(t){if(e.autoClose)e.destroy();e.emit("error",t)}else{e.fd=r;e.emit("open",r);e.read()}}))}function WriteStream(e,t){if(this instanceof WriteStream)return h.apply(this,arguments),this;else return WriteStream.apply(Object.create(WriteStream.prototype),arguments)}function WriteStream$open(){var e=this;open(e.path,e.flags,e.mode,(function(t,r){if(t){e.destroy();e.emit("error",t)}else{e.fd=r;e.emit("open",r)}}))}function createReadStream(t,r){return new e.ReadStream(t,r)}function createWriteStream(t,r){return new e.WriteStream(t,r)}var g=e.open;e.open=open;function open(e,t,r,s){if(typeof r==="function")s=r,r=null;return go$open(e,t,r,s);function go$open(e,t,r,s,a){return g(e,t,r,(function(o,u){if(o&&(o.code==="EMFILE"||o.code==="ENFILE"))enqueue([go$open,[e,t,r,s],o,a||Date.now(),Date.now()]);else{if(typeof s==="function")s.apply(this,arguments)}}))}}return e}function enqueue(e){p("ENQUEUE",e[0].name,e[1]);s[f].push(e);retry()}var v;function resetQueue(){var e=Date.now();for(var t=0;t2){s[f][t][3]=e;s[f][t][4]=e}}retry()}function retry(){clearTimeout(v);v=undefined;if(s[f].length===0)return;var e=s[f].shift();var t=e[0];var r=e[1];var a=e[2];var o=e[3];var u=e[4];if(o===undefined){p("RETRY",t.name,r);t.apply(null,r)}else if(Date.now()-o>=6e4){p("TIMEOUT",t.name,r);var c=r.pop();if(typeof c==="function")c.call(null,a)}else{var d=Date.now()-u;var h=Math.max(u-o,1);var D=Math.min(h*1.2,100);if(d>=D){p("RETRY",t.name,r);t.apply(null,r.concat([o]))}else{s[f].push(e)}}if(v===undefined){v=setTimeout(retry,0)}}},5653:(e,t,r)=>{var s=r(2781).Stream;e.exports=legacy;function legacy(e){return{ReadStream:ReadStream,WriteStream:WriteStream};function ReadStream(t,r){if(!(this instanceof ReadStream))return new ReadStream(t,r);s.call(this);var a=this;this.path=t;this.fd=null;this.readable=true;this.paused=false;this.flags="r";this.mode=438;this.bufferSize=64*1024;r=r||{};var o=Object.keys(r);for(var u=0,c=o.length;uthis.end){throw new Error("start must be <= end")}this.pos=this.start}if(this.fd!==null){process.nextTick((function(){a._read()}));return}e.open(this.path,this.flags,this.mode,(function(e,t){if(e){a.emit("error",e);a.readable=false;return}a.fd=t;a.emit("open",t);a._read()}))}function WriteStream(t,r){if(!(this instanceof WriteStream))return new WriteStream(t,r);s.call(this);this.path=t;this.fd=null;this.writable=true;this.flags="w";this.encoding="binary";this.mode=438;this.bytesWritten=0;r=r||{};var a=Object.keys(r);for(var o=0,u=a.length;o= zero")}this.pos=this.start}this.busy=false;this._queue=[];if(this.fd===null){this._open=e.open;this._queue.push([this._open,this.path,this.flags,this.mode,undefined]);this.flush()}}}},2164:(e,t,r)=>{var s=r(2057);var a=process.cwd;var o=null;var u=process.env.GRACEFUL_FS_PLATFORM||process.platform;process.cwd=function(){if(!o)o=a.call(process);return o};try{process.cwd()}catch(e){}if(typeof process.chdir==="function"){var c=process.chdir;process.chdir=function(e){o=null;c.call(process,e)};if(Object.setPrototypeOf)Object.setPrototypeOf(process.chdir,c)}e.exports=patch;function patch(e){if(s.hasOwnProperty("O_SYMLINK")&&process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)){patchLchmod(e)}if(!e.lutimes){patchLutimes(e)}e.chown=chownFix(e.chown);e.fchown=chownFix(e.fchown);e.lchown=chownFix(e.lchown);e.chmod=chmodFix(e.chmod);e.fchmod=chmodFix(e.fchmod);e.lchmod=chmodFix(e.lchmod);e.chownSync=chownFixSync(e.chownSync);e.fchownSync=chownFixSync(e.fchownSync);e.lchownSync=chownFixSync(e.lchownSync);e.chmodSync=chmodFixSync(e.chmodSync);e.fchmodSync=chmodFixSync(e.fchmodSync);e.lchmodSync=chmodFixSync(e.lchmodSync);e.stat=statFix(e.stat);e.fstat=statFix(e.fstat);e.lstat=statFix(e.lstat);e.statSync=statFixSync(e.statSync);e.fstatSync=statFixSync(e.fstatSync);e.lstatSync=statFixSync(e.lstatSync);if(e.chmod&&!e.lchmod){e.lchmod=function(e,t,r){if(r)process.nextTick(r)};e.lchmodSync=function(){}}if(e.chown&&!e.lchown){e.lchown=function(e,t,r,s){if(s)process.nextTick(s)};e.lchownSync=function(){}}if(u==="win32"){e.rename=typeof e.rename!=="function"?e.rename:function(t){function rename(r,s,a){var o=Date.now();var u=0;t(r,s,(function CB(c){if(c&&(c.code==="EACCES"||c.code==="EPERM"||c.code==="EBUSY")&&Date.now()-o<6e4){setTimeout((function(){e.stat(s,(function(e,o){if(e&&e.code==="ENOENT")t(r,s,CB);else a(c)}))}),u);if(u<100)u+=10;return}if(a)a(c)}))}if(Object.setPrototypeOf)Object.setPrototypeOf(rename,t);return rename}(e.rename)}e.read=typeof e.read!=="function"?e.read:function(t){function read(r,s,a,o,u,c){var f;if(c&&typeof c==="function"){var d=0;f=function(p,h,v){if(p&&p.code==="EAGAIN"&&d<10){d++;return t.call(e,r,s,a,o,u,f)}c.apply(this,arguments)}}return t.call(e,r,s,a,o,u,f)}if(Object.setPrototypeOf)Object.setPrototypeOf(read,t);return read}(e.read);e.readSync=typeof e.readSync!=="function"?e.readSync:function(t){return function(r,s,a,o,u){var c=0;while(true){try{return t.call(e,r,s,a,o,u)}catch(e){if(e.code==="EAGAIN"&&c<10){c++;continue}throw e}}}}(e.readSync);function patchLchmod(e){e.lchmod=function(t,r,a){e.open(t,s.O_WRONLY|s.O_SYMLINK,r,(function(t,s){if(t){if(a)a(t);return}e.fchmod(s,r,(function(t){e.close(s,(function(e){if(a)a(t||e)}))}))}))};e.lchmodSync=function(t,r){var a=e.openSync(t,s.O_WRONLY|s.O_SYMLINK,r);var o=true;var u;try{u=e.fchmodSync(a,r);o=false}finally{if(o){try{e.closeSync(a)}catch(e){}}else{e.closeSync(a)}}return u}}function patchLutimes(e){if(s.hasOwnProperty("O_SYMLINK")&&e.futimes){e.lutimes=function(t,r,a,o){e.open(t,s.O_SYMLINK,(function(t,s){if(t){if(o)o(t);return}e.futimes(s,r,a,(function(t){e.close(s,(function(e){if(o)o(t||e)}))}))}))};e.lutimesSync=function(t,r,a){var o=e.openSync(t,s.O_SYMLINK);var u;var c=true;try{u=e.futimesSync(o,r,a);c=false}finally{if(c){try{e.closeSync(o)}catch(e){}}else{e.closeSync(o)}}return u}}else if(e.futimes){e.lutimes=function(e,t,r,s){if(s)process.nextTick(s)};e.lutimesSync=function(){}}}function chmodFix(t){if(!t)return t;return function(r,s,a){return t.call(e,r,s,(function(e){if(chownErOk(e))e=null;if(a)a.apply(this,arguments)}))}}function chmodFixSync(t){if(!t)return t;return function(r,s){try{return t.call(e,r,s)}catch(e){if(!chownErOk(e))throw e}}}function chownFix(t){if(!t)return t;return function(r,s,a,o){return t.call(e,r,s,a,(function(e){if(chownErOk(e))e=null;if(o)o.apply(this,arguments)}))}}function chownFixSync(t){if(!t)return t;return function(r,s,a){try{return t.call(e,r,s,a)}catch(e){if(!chownErOk(e))throw e}}}function statFix(t){if(!t)return t;return function(r,s,a){if(typeof s==="function"){a=s;s=null}function callback(e,t){if(t){if(t.uid<0)t.uid+=4294967296;if(t.gid<0)t.gid+=4294967296}if(a)a.apply(this,arguments)}return s?t.call(e,r,s,callback):t.call(e,r,callback)}}function statFixSync(t){if(!t)return t;return function(r,s){var a=s?t.call(e,r,s):t.call(e,r);if(a){if(a.uid<0)a.uid+=4294967296;if(a.gid<0)a.gid+=4294967296}return a}}function chownErOk(e){if(!e)return true;if(e.code==="ENOSYS")return true;var t=!process.getuid||process.getuid()!==0;if(t){if(e.code==="EINVAL"||e.code==="EPERM")return true}return false}}},5214:(e,t,r)=>{"use strict";var s=r(2037);var a=e.exports=function(){if(s.type()=="Windows_NT"){return false}var e=/UTF-?8$/i;var t=process.env.LC_ALL||process.env.LC_CTYPE||process.env.LANG;return e.test(t)}},2842:(e,t,r)=>{try{var s=r(3837);if(typeof s.inherits!=="function")throw"";e.exports=s.inherits}catch(t){e.exports=r(3782)}},3782:e=>{if(typeof Object.create==="function"){e.exports=function inherits(e,t){if(t){e.super_=t;e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:false,writable:true,configurable:true}})}}}else{e.exports=function inherits(e,t){if(t){e.super_=t;var TempCtor=function(){};TempCtor.prototype=t.prototype;e.prototype=new TempCtor;e.prototype.constructor=e}}}},3279:(e,t,r)=>{"use strict";var s=r(3979);e.exports=function(e){if(s(e)){return false}if(e>=4352&&(e<=4447||9001===e||9002===e||11904<=e&&e<=12871&&e!==12351||12880<=e&&e<=19903||19968<=e&&e<=42182||43360<=e&&e<=43388||44032<=e&&e<=55203||63744<=e&&e<=64255||65040<=e&&e<=65049||65072<=e&&e<=65131||65281<=e&&e<=65376||65504<=e&&e<=65510||110592<=e&&e<=110593||127488<=e&&e<=127569||131072<=e&&e<=262141)){return true}return false}},8502:e=>{"use strict";const isFullwidthCodePoint=e=>{if(Number.isNaN(e)){return false}if(e>=4352&&(e<=4447||e===9001||e===9002||11904<=e&&e<=12871&&e!==12351||12880<=e&&e<=19903||19968<=e&&e<=42182||43360<=e&&e<=43388||44032<=e&&e<=55203||63744<=e&&e<=64255||65040<=e&&e<=65049||65072<=e&&e<=65131||65281<=e&&e<=65376||65504<=e&&e<=65510||110592<=e&&e<=110593||127488<=e&&e<=127569||131072<=e&&e<=262141)){return true}return false};e.exports=isFullwidthCodePoint;e.exports["default"]=isFullwidthCodePoint},1551:e=>{var t={}.toString;e.exports=Array.isArray||function(e){return t.call(e)=="[object Array]"}},7663:(module,__unused_webpack_exports,__nccwpck_require__)=>{var fs=__nccwpck_require__(7147);var path=__nccwpck_require__(1017);var os=__nccwpck_require__(2037);var runtimeRequire=true?eval("require"):0;var vars=process.config&&process.config.variables||{};var prebuildsOnly=!!process.env.PREBUILDS_ONLY;var abi=process.versions.modules;var runtime=isElectron()?"electron":"node";var arch=os.arch();var platform=os.platform();var libc=process.env.LIBC||(isAlpine(platform)?"musl":"glibc");var armv=process.env.ARM_VERSION||(arch==="arm64"?"8":vars.arm_version)||"";var uv=(process.versions.uv||"").split(".")[0];module.exports=load;function load(e){return runtimeRequire(load.path(e))}load.path=function(e){e=path.resolve(e||".");try{var t=runtimeRequire(path.join(e,"package.json")).name.toUpperCase().replace(/-/g,"_");if(process.env[t+"_PREBUILD"])e=process.env[t+"_PREBUILD"]}catch(e){}if(!prebuildsOnly){var r=getFirst(path.join(e,"build/Release"),matchBuild);if(r)return r;var s=getFirst(path.join(e,"build/Debug"),matchBuild);if(s)return s}var a=resolve(e);if(a)return a;var o=resolve(path.dirname(process.execPath));if(o)return o;var u=["platform="+platform,"arch="+arch,"runtime="+runtime,"abi="+abi,"uv="+uv,armv?"armv="+armv:"","libc="+libc,"node="+process.versions.node,process.versions&&process.versions.electron?"electron="+process.versions.electron:"",true?"webpack=true":0].filter(Boolean).join(" ");throw new Error("No native build was found for "+u+"\n loaded from: "+e+"\n");function resolve(e){var t=path.join(e,"prebuilds",platform+"-"+arch);var r=readdirSync(t).map(parseTags);var s=r.filter(matchTags(runtime,abi));var a=s.sort(compareTags(runtime))[0];if(a)return path.join(t,a.file)}};function readdirSync(e){try{return fs.readdirSync(e)}catch(e){return[]}}function getFirst(e,t){var r=readdirSync(e).filter(t);return r[0]&&path.join(e,r[0])}function matchBuild(e){return/\.node$/.test(e)}function parseTags(e){var t=e.split(".");var r=t.pop();var s={file:e,specificity:0};if(r!=="node")return;for(var a=0;ar.specificity?-1:1}else{return 0}}}function isElectron(){if(process.versions&&process.versions.electron)return true;if(process.env.ELECTRON_RUN_AS_NODE)return true;return typeof window!=="undefined"&&window.process&&window.process.type==="renderer"}function isAlpine(e){return e==="linux"&&fs.existsSync("/etc/alpine-release")}load.parseTags=parseTags;load.matchTags=matchTags;load.compareTags=compareTags},1758:(e,t,r)=>{var s=process.env.DEBUG_NOPT||process.env.NOPT_DEBUG?function(){console.error.apply(console,arguments)}:function(){};var a=r(7310),o=r(1017),u=r(2781).Stream,c=r(351),f=r(2037);e.exports=t=nopt;t.clean=clean;t.typeDefs={String:{type:String,validate:validateString},Boolean:{type:Boolean,validate:validateBoolean},url:{type:a,validate:validateUrl},Number:{type:Number,validate:validateNumber},path:{type:o,validate:validatePath},Stream:{type:u,validate:validateStream},Date:{type:Date,validate:validateDate}};function nopt(e,r,a,o){a=a||process.argv;e=e||{};r=r||{};if(typeof o!=="number")o=2;s(e,r,a,o);a=a.slice(o);var u={},c,f={remain:[],cooked:a,original:a.slice(0)};parse(a,u,f.remain,e,r);clean(u,e,t.typeDefs);u.argv=f;Object.defineProperty(u.argv,"toString",{value:function(){return this.original.map(JSON.stringify).join(" ")},enumerable:false});return u}function clean(e,r,a){a=a||t.typeDefs;var o={},u=[false,true,null,String,Array];Object.keys(e).forEach((function(c){if(c==="argv")return;var f=e[c],d=Array.isArray(f),p=r[c];if(!d)f=[f];if(!p)p=u;if(p===Array)p=u.concat(Array);if(!Array.isArray(p))p=[p];s("val=%j",f);s("types=",p);f=f.map((function(u){if(typeof u==="string"){s("string %j",u);u=u.trim();if(u==="null"&&~p.indexOf(null)||u==="true"&&(~p.indexOf(true)||~p.indexOf(Boolean))||u==="false"&&(~p.indexOf(false)||~p.indexOf(Boolean))){u=JSON.parse(u);s("jsonable %j",u)}else if(~p.indexOf(Number)&&!isNaN(u)){s("convert to number",u);u=+u}else if(~p.indexOf(Date)&&!isNaN(Date.parse(u))){s("convert to date",u);u=new Date(u)}}if(!r.hasOwnProperty(c)){return u}if(u===false&&~p.indexOf(null)&&!(~p.indexOf(false)||~p.indexOf(Boolean))){u=null}var f={};f[c]=u;s("prevalidated val",f,u,r[c]);if(!validate(f,c,u,r[c],a)){if(t.invalidHandler){t.invalidHandler(c,u,r[c],e)}else if(t.invalidHandler!==false){s("invalid: "+c+"="+u,r[c])}return o}s("validated val",f,u,r[c]);return f[c]})).filter((function(e){return e!==o}));if(!f.length&&p.indexOf(Array)===-1){s("VAL HAS NO LENGTH, DELETE IT",f,c,p.indexOf(Array));delete e[c]}else if(d){s(d,e[c],f);e[c]=f}else e[c]=f[0];s("k=%s val=%j",c,f,e[c])}))}function validateString(e,t,r){e[t]=String(r)}function validatePath(e,t,r){if(r===true)return false;if(r===null)return true;r=String(r);var s=process.platform==="win32",a=s?/^~(\/|\\)/:/^~\//,u=f.homedir();if(u&&r.match(a)){e[t]=o.resolve(u,r.substr(2))}else{e[t]=o.resolve(r)}return true}function validateNumber(e,t,r){s("validate Number %j %j %j",t,r,isNaN(r));if(isNaN(r))return false;e[t]=+r}function validateDate(e,t,r){var a=Date.parse(r);s("validate Date %j %j %j",t,r,a);if(isNaN(a))return false;e[t]=new Date(r)}function validateBoolean(e,t,r){if(r instanceof Boolean)r=r.valueOf();else if(typeof r==="string"){if(!isNaN(r))r=!!+r;else if(r==="null"||r==="false")r=false;else r=true}else r=!!r;e[t]=r}function validateUrl(e,t,r){r=a.parse(String(r));if(!r.host)return false;e[t]=r.href}function validateStream(e,t,r){if(!(r instanceof u))return false;e[t]=r}function validate(e,t,r,a,o){if(Array.isArray(a)){for(var u=0,c=a.length;u1){var D=h.indexOf("=");if(D>-1){v=true;var g=h.substr(D+1);h=h.substr(0,D);e.splice(p,1,h,g)}var y=resolveShort(h,o,d,f);s("arg=%j shRes=%j",h,y);if(y){s(h,y);e.splice.apply(e,[p,1].concat(y));if(h!==y[0]){p--;continue}}h=h.replace(/^-+/,"");var m=null;while(h.toLowerCase().indexOf("no-")===0){m=!m;h=h.substr(3)}if(f[h])h=f[h];var _=a[h];var E=Array.isArray(_);if(E&&_.length===1){E=false;_=_[0]}var w=_===Array||E&&_.indexOf(Array)!==-1;if(!a.hasOwnProperty(h)&&t.hasOwnProperty(h)){if(!Array.isArray(t[h]))t[h]=[t[h]];w=true}var x,F=e[p+1];var C=typeof m==="boolean"||_===Boolean||E&&_.indexOf(Boolean)!==-1||typeof _==="undefined"&&!v||F==="false"&&(_===null||E&&~_.indexOf(null));if(C){x=!m;if(F==="true"||F==="false"){x=JSON.parse(F);F=null;if(m)x=!x;p++}if(E&&F){if(~_.indexOf(F)){x=F;p++}else if(F==="null"&&~_.indexOf(null)){x=null;p++}else if(!F.match(/^-{2,}[^-]/)&&!isNaN(F)&&~_.indexOf(Number)){x=+F;p++}else if(!F.match(/^-[^-]/)&&~_.indexOf(String)){x=F;p++}}if(w)(t[h]=t[h]||[]).push(x);else t[h]=x;continue}if(_===String){if(F===undefined){F=""}else if(F.match(/^-{1,2}[^-]+/)){F="";p--}}if(F&&F.match(/^-{2,}$/)){F=undefined;p--}x=F===undefined?true:F;if(w)(t[h]=t[h]||[]).push(x);else t[h]=x;p++;continue}r.push(h)}}function resolveShort(e,t,r,a){e=e.replace(/^-+/,"");if(a[e]===e)return null;if(t[e]){if(t[e]&&!Array.isArray(t[e]))t[e]=t[e].split(/\s+/);return t[e]}var o=t.___singles;if(!o){o=Object.keys(t).filter((function(e){return e.length===1})).reduce((function(e,t){e[t]=true;return e}),{});t.___singles=o;s("shorthand singles",o)}var u=e.split("").filter((function(e){return o[e]}));if(u.join("")===e)return u.map((function(e){return t[e]})).reduce((function(e,t){return e.concat(t)}),[]);if(a[e]&&!t[e])return null;if(r[e])e=r[e];if(t[e]&&!Array.isArray(t[e]))t[e]=t[e].split(/\s+/);return t[e]}},9544:(e,t,r)=>{"use strict";var s=r(4906);var a=r(287);var o=r(2361).EventEmitter;var u=t=e.exports=new o;var c=r(3837);var f=r(2656);var d=r(3844);f(true);var p=process.stderr;Object.defineProperty(u,"stream",{set:function(e){p=e;if(this.gauge)this.gauge.setWriteTo(p,p)},get:function(){return p}});var h;u.useColor=function(){return h!=null?h:p.isTTY};u.enableColor=function(){h=true;this.gauge.setTheme({hasColor:h,hasUnicode:v})};u.disableColor=function(){h=false;this.gauge.setTheme({hasColor:h,hasUnicode:v})};u.level="info";u.gauge=new a(p,{enabled:false,theme:{hasColor:u.useColor()},template:[{type:"progressbar",length:20},{type:"activityIndicator",kerning:1,length:1},{type:"section",default:""},":",{type:"logline",kerning:1,default:""}]});u.tracker=new s.TrackerGroup;u.progressEnabled=u.gauge.isEnabled();var v;u.enableUnicode=function(){v=true;this.gauge.setTheme({hasColor:this.useColor(),hasUnicode:v})};u.disableUnicode=function(){v=false;this.gauge.setTheme({hasColor:this.useColor(),hasUnicode:v})};u.setGaugeThemeset=function(e){this.gauge.setThemeset(e)};u.setGaugeTemplate=function(e){this.gauge.setTemplate(e)};u.enableProgress=function(){if(this.progressEnabled)return;this.progressEnabled=true;this.tracker.on("change",this.showProgress);if(this._pause)return;this.gauge.enable()};u.disableProgress=function(){if(!this.progressEnabled)return;this.progressEnabled=false;this.tracker.removeListener("change",this.showProgress);this.gauge.disable()};var D=["newGroup","newItem","newStream"];var mixinLog=function(e){Object.keys(u).forEach((function(t){if(t[0]==="_")return;if(D.filter((function(e){return e===t})).length)return;if(e[t])return;if(typeof u[t]!=="function")return;var r=u[t];e[t]=function(){return r.apply(u,arguments)}}));if(e instanceof s.TrackerGroup){D.forEach((function(t){var r=e[t];e[t]=function(){return mixinLog(r.apply(e,arguments))}}))}return e};D.forEach((function(e){u[e]=function(){return mixinLog(this.tracker[e].apply(this.tracker,arguments))}}));u.clearProgress=function(e){if(!this.progressEnabled)return e&&process.nextTick(e);this.gauge.hide(e)};u.showProgress=function(e,t){if(!this.progressEnabled)return;var r={};if(e)r.section=e;var s=u.record[u.record.length-1];if(s){r.subsection=s.prefix;var a=u.disp[s.level]||s.level;var o=this._format(a,u.style[s.level]);if(s.prefix)o+=" "+this._format(s.prefix,this.prefixStyle);o+=" "+s.message.split(/\r?\n/)[0];r.logline=o}r.completed=t||this.tracker.completed();this.gauge.show(r)}.bind(u);u.pause=function(){this._paused=true;if(this.progressEnabled)this.gauge.disable()};u.resume=function(){if(!this._paused)return;this._paused=false;var e=this._buffer;this._buffer=[];e.forEach((function(e){this.emitLog(e)}),this);if(this.progressEnabled)this.gauge.enable()};u._buffer=[];var g=0;u.record=[];u.maxRecordSize=1e4;u.log=function(e,t,r){var s=this.levels[e];if(s===undefined){return this.emit("error",new Error(c.format("Undefined log level: %j",e)))}var a=new Array(arguments.length-2);var o=null;for(var u=2;up/10){var v=Math.floor(p*.9);this.record=this.record.slice(-1*v)}this.emitLog(d)}.bind(u);u.emitLog=function(e){if(this._paused){this._buffer.push(e);return}if(this.progressEnabled)this.gauge.pulse(e.prefix);var t=this.levels[e.level];if(t===undefined)return;if(t0&&!isFinite(t))return;var r=u.disp[e.level]!=null?u.disp[e.level]:e.level;this.clearProgress();e.message.split(/\r?\n/).forEach((function(t){if(this.heading){this.write(this.heading,this.headingStyle);this.write(" ")}this.write(r,u.style[e.level]);var s=e.prefix||"";if(s)this.write(" ");this.write(s,this.prefixStyle);this.write(" "+t+"\n")}),this);this.showProgress()};u._format=function(e,t){if(!p)return;var r="";if(this.useColor()){t=t||{};var s=[];if(t.fg)s.push(t.fg);if(t.bg)s.push("bg"+t.bg[0].toUpperCase()+t.bg.slice(1));if(t.bold)s.push("bold");if(t.underline)s.push("underline");if(t.inverse)s.push("inverse");if(s.length)r+=d.color(s);if(t.beep)r+=d.beep()}r+=e;if(this.useColor()){r+=d.color("reset")}return r};u.write=function(e,t){if(!p)return;p.write(this._format(e,t))};u.addLevel=function(e,t,r,s){if(s==null)s=e;this.levels[e]=t;this.style[e]=r;if(!this[e]){this[e]=function(){var t=new Array(arguments.length+1);t[0]=e;for(var r=0;r{"use strict";e.exports=Number.isNaN||function(e){return e!==e}},3540:e=>{"use strict"; /* object-assign (c) Sindre Sorhus @license MIT -*/var t=Object.getOwnPropertySymbols;var r=Object.prototype.hasOwnProperty;var s=Object.prototype.propertyIsEnumerable;function toObject(e){if(e===null||e===undefined){throw new TypeError("Object.assign cannot be called with null or undefined")}return Object(e)}function shouldUseNative(){try{if(!Object.assign){return false}var e=new String("abc");e[5]="de";if(Object.getOwnPropertyNames(e)[0]==="5"){return false}var t={};for(var r=0;r<10;r++){t["_"+String.fromCharCode(r)]=r}var s=Object.getOwnPropertyNames(t).map((function(e){return t[e]}));if(s.join("")!=="0123456789"){return false}var a={};"abcdefghijklmnopqrst".split("").forEach((function(e){a[e]=e}));if(Object.keys(Object.assign({},a)).join("")!=="abcdefghijklmnopqrst"){return false}return true}catch(e){return false}}e.exports=shouldUseNative()?Object.assign:function(e,a){var o;var u=toObject(e);var c;for(var f=1;f{"use strict";e.exports=r(7250)},7798:(e,t,r)=>{"use strict";const s=r(1017);const a="\\\\/";const o=`[^${a}]`;const u="\\.";const c="\\+";const f="\\?";const d="\\/";const p="(?=.)";const h="[^/]";const v=`(?:${d}|$)`;const D=`(?:^|${d})`;const g=`${u}{1,2}${v}`;const y=`(?!${u})`;const m=`(?!${D}${g})`;const _=`(?!${u}{0,1}${v})`;const E=`(?!${g})`;const w=`[^.${d}]`;const x=`${h}*?`;const F={DOT_LITERAL:u,PLUS_LITERAL:c,QMARK_LITERAL:f,SLASH_LITERAL:d,ONE_CHAR:p,QMARK:h,END_ANCHOR:v,DOTS_SLASH:g,NO_DOT:y,NO_DOTS:m,NO_DOT_SLASH:_,NO_DOTS_SLASH:E,QMARK_NO_DOT:w,STAR:x,START_ANCHOR:D};const C={...F,SLASH_LITERAL:`[${a}]`,QMARK:o,STAR:`${o}*?`,DOTS_SLASH:`${u}{1,2}(?:[${a}]|$)`,NO_DOT:`(?!${u})`,NO_DOTS:`(?!(?:^|[${a}])${u}{1,2}(?:[${a}]|$))`,NO_DOT_SLASH:`(?!${u}{0,1}(?:[${a}]|$))`,NO_DOTS_SLASH:`(?!${u}{1,2}(?:[${a}]|$))`,QMARK_NO_DOT:`[^.${a}]`,START_ANCHOR:`(?:^|[${a}])`,END_ANCHOR:`(?:[${a}]|$)`};const S={alnum:"a-zA-Z0-9",alpha:"a-zA-Z",ascii:"\\x00-\\x7F",blank:" \\t",cntrl:"\\x00-\\x1F\\x7F",digit:"0-9",graph:"\\x21-\\x7E",lower:"a-z",print:"\\x20-\\x7E ",punct:"\\-!\"#$%&'()\\*+,./:;<=>?@[\\]^_`{|}~",space:" \\t\\r\\n\\v\\f",upper:"A-Z",word:"A-Za-z0-9_",xdigit:"A-Fa-f0-9"};e.exports={MAX_LENGTH:1024*64,POSIX_REGEX_SOURCE:S,REGEX_BACKSLASH:/\\(?![*+?^${}(|)[\]])/g,REGEX_NON_SPECIAL_CHARS:/^[^@![\].,$*+?^{}()|\\/]+/,REGEX_SPECIAL_CHARS:/[-*+?.^${}(|)[\]]/,REGEX_SPECIAL_CHARS_BACKREF:/(\\?)((\W)(\3*))/g,REGEX_SPECIAL_CHARS_GLOBAL:/([-*+?.^${}(|)[\]])/g,REGEX_REMOVE_BACKSLASH:/(?:\[.*?[^\\]\]|\\(?=.))/g,REPLACEMENTS:{"***":"*","**/**":"**","**/**/**":"**"},CHAR_0:48,CHAR_9:57,CHAR_UPPERCASE_A:65,CHAR_LOWERCASE_A:97,CHAR_UPPERCASE_Z:90,CHAR_LOWERCASE_Z:122,CHAR_LEFT_PARENTHESES:40,CHAR_RIGHT_PARENTHESES:41,CHAR_ASTERISK:42,CHAR_AMPERSAND:38,CHAR_AT:64,CHAR_BACKWARD_SLASH:92,CHAR_CARRIAGE_RETURN:13,CHAR_CIRCUMFLEX_ACCENT:94,CHAR_COLON:58,CHAR_COMMA:44,CHAR_DOT:46,CHAR_DOUBLE_QUOTE:34,CHAR_EQUAL:61,CHAR_EXCLAMATION_MARK:33,CHAR_FORM_FEED:12,CHAR_FORWARD_SLASH:47,CHAR_GRAVE_ACCENT:96,CHAR_HASH:35,CHAR_HYPHEN_MINUS:45,CHAR_LEFT_ANGLE_BRACKET:60,CHAR_LEFT_CURLY_BRACE:123,CHAR_LEFT_SQUARE_BRACKET:91,CHAR_LINE_FEED:10,CHAR_NO_BREAK_SPACE:160,CHAR_PERCENT:37,CHAR_PLUS:43,CHAR_QUESTION_MARK:63,CHAR_RIGHT_ANGLE_BRACKET:62,CHAR_RIGHT_CURLY_BRACE:125,CHAR_RIGHT_SQUARE_BRACKET:93,CHAR_SEMICOLON:59,CHAR_SINGLE_QUOTE:39,CHAR_SPACE:32,CHAR_TAB:9,CHAR_UNDERSCORE:95,CHAR_VERTICAL_LINE:124,CHAR_ZERO_WIDTH_NOBREAK_SPACE:65279,SEP:s.sep,extglobChars(e){return{"!":{type:"negate",open:"(?:(?!(?:",close:`))${e.STAR})`},"?":{type:"qmark",open:"(?:",close:")?"},"+":{type:"plus",open:"(?:",close:")+"},"*":{type:"star",open:"(?:",close:")*"},"@":{type:"at",open:"(?:",close:")"}}},globChars(e){return e===true?C:F}}},3632:(e,t,r)=>{"use strict";const s=r(7798);const a=r(5502);const{MAX_LENGTH:o,POSIX_REGEX_SOURCE:u,REGEX_NON_SPECIAL_CHARS:c,REGEX_SPECIAL_CHARS_BACKREF:f,REPLACEMENTS:d}=s;const expandRange=(e,t)=>{if(typeof t.expandRange==="function"){return t.expandRange(...e,t)}e.sort();const r=`[${e.join("-")}]`;try{new RegExp(r)}catch(t){return e.map((e=>a.escapeRegex(e))).join("..")}return r};const syntaxError=(e,t)=>`Missing ${e}: "${t}" - use "\\\\${t}" to match literal characters`;const parse=(e,t)=>{if(typeof e!=="string"){throw new TypeError("Expected a string")}e=d[e]||e;const r={...t};const p=typeof r.maxLength==="number"?Math.min(o,r.maxLength):o;let h=e.length;if(h>p){throw new SyntaxError(`Input length: ${h}, exceeds maximum allowed length: ${p}`)}const v={type:"bos",value:"",output:r.prepend||""};const D=[v];const g=r.capture?"":"?:";const y=a.isWindows(t);const m=s.globChars(y);const _=s.extglobChars(m);const{DOT_LITERAL:E,PLUS_LITERAL:w,SLASH_LITERAL:x,ONE_CHAR:F,DOTS_SLASH:C,NO_DOT:S,NO_DOT_SLASH:k,NO_DOTS_SLASH:A,QMARK:R,QMARK_NO_DOT:O,STAR:T,START_ANCHOR:j}=m;const globstar=e=>`(${g}(?:(?!${j}${e.dot?C:E}).)*?)`;const B=r.dot?"":S;const L=r.dot?R:O;let N=r.bash===true?globstar(r):T;if(r.capture){N=`(${N})`}if(typeof r.noext==="boolean"){r.noextglob=r.noext}const I={input:e,index:-1,start:0,dot:r.dot===true,consumed:"",output:"",prefix:"",backtrack:false,negated:false,brackets:0,braces:0,parens:0,quotes:0,globstar:false,tokens:D};e=a.removePrefix(e,I);h=e.length;const P=[];const W=[];const M=[];let $=v;let q;const eos=()=>I.index===h-1;const U=I.peek=(t=1)=>e[I.index+t];const G=I.advance=()=>e[++I.index]||"";const remaining=()=>e.slice(I.index+1);const consume=(e="",t=0)=>{I.consumed+=e;I.index+=t};const append=e=>{I.output+=e.output!=null?e.output:e.value;consume(e.value)};const negate=()=>{let e=1;while(U()==="!"&&(U(2)!=="("||U(3)==="?")){G();I.start++;e++}if(e%2===0){return false}I.negated=true;I.start++;return true};const increment=e=>{I[e]++;M.push(e)};const decrement=e=>{I[e]--;M.pop()};const push=e=>{if($.type==="globstar"){const t=I.braces>0&&(e.type==="comma"||e.type==="brace");const r=e.extglob===true||P.length&&(e.type==="pipe"||e.type==="paren");if(e.type!=="slash"&&e.type!=="paren"&&!t&&!r){I.output=I.output.slice(0,-$.output.length);$.type="star";$.value="*";$.output=N;I.output+=$.output}}if(P.length&&e.type!=="paren"){P[P.length-1].inner+=e.value}if(e.value||e.output)append(e);if($&&$.type==="text"&&e.type==="text"){$.value+=e.value;$.output=($.output||"")+e.value;return}e.prev=$;D.push(e);$=e};const extglobOpen=(e,t)=>{const s={..._[t],conditions:1,inner:""};s.prev=$;s.parens=I.parens;s.output=I.output;const a=(r.capture?"(":"")+s.open;increment("parens");push({type:e,value:t,output:I.output?"":F});push({type:"paren",extglob:true,value:G(),output:a});P.push(s)};const extglobClose=e=>{let s=e.close+(r.capture?")":"");let a;if(e.type==="negate"){let o=N;if(e.inner&&e.inner.length>1&&e.inner.includes("/")){o=globstar(r)}if(o!==N||eos()||/^\)+$/.test(remaining())){s=e.close=`)$))${o}`}if(e.inner.includes("*")&&(a=remaining())&&/^\.[^\\/.]+$/.test(a)){const r=parse(a,{...t,fastpaths:false}).output;s=e.close=`)${r})${o})`}if(e.prev.type==="bos"){I.negatedExtglob=true}}push({type:"paren",extglob:true,value:q,output:s});decrement("parens")};if(r.fastpaths!==false&&!/(^[*!]|[/()[\]{}"])/.test(e)){let s=false;let o=e.replace(f,((e,t,r,a,o,u)=>{if(a==="\\"){s=true;return e}if(a==="?"){if(t){return t+a+(o?R.repeat(o.length):"")}if(u===0){return L+(o?R.repeat(o.length):"")}return R.repeat(r.length)}if(a==="."){return E.repeat(r.length)}if(a==="*"){if(t){return t+a+(o?N:"")}return N}return t?e:`\\${e}`}));if(s===true){if(r.unescape===true){o=o.replace(/\\/g,"")}else{o=o.replace(/\\+/g,(e=>e.length%2===0?"\\\\":e?"\\":""))}}if(o===e&&r.contains===true){I.output=e;return I}I.output=a.wrapOutput(o,I,t);return I}while(!eos()){q=G();if(q==="\0"){continue}if(q==="\\"){const e=U();if(e==="/"&&r.bash!==true){continue}if(e==="."||e===";"){continue}if(!e){q+="\\";push({type:"text",value:q});continue}const t=/^\\+/.exec(remaining());let s=0;if(t&&t[0].length>2){s=t[0].length;I.index+=s;if(s%2!==0){q+="\\"}}if(r.unescape===true){q=G()}else{q+=G()}if(I.brackets===0){push({type:"text",value:q});continue}}if(I.brackets>0&&(q!=="]"||$.value==="["||$.value==="[^")){if(r.posix!==false&&q===":"){const e=$.value.slice(1);if(e.includes("[")){$.posix=true;if(e.includes(":")){const e=$.value.lastIndexOf("[");const t=$.value.slice(0,e);const r=$.value.slice(e+2);const s=u[r];if(s){$.value=t+s;I.backtrack=true;G();if(!v.output&&D.indexOf($)===1){v.output=F}continue}}}}if(q==="["&&U()!==":"||q==="-"&&U()==="]"){q=`\\${q}`}if(q==="]"&&($.value==="["||$.value==="[^")){q=`\\${q}`}if(r.posix===true&&q==="!"&&$.value==="["){q="^"}$.value+=q;append({value:q});continue}if(I.quotes===1&&q!=='"'){q=a.escapeRegex(q);$.value+=q;append({value:q});continue}if(q==='"'){I.quotes=I.quotes===1?0:1;if(r.keepQuotes===true){push({type:"text",value:q})}continue}if(q==="("){increment("parens");push({type:"paren",value:q});continue}if(q===")"){if(I.parens===0&&r.strictBrackets===true){throw new SyntaxError(syntaxError("opening","("))}const e=P[P.length-1];if(e&&I.parens===e.parens+1){extglobClose(P.pop());continue}push({type:"paren",value:q,output:I.parens?")":"\\)"});decrement("parens");continue}if(q==="["){if(r.nobracket===true||!remaining().includes("]")){if(r.nobracket!==true&&r.strictBrackets===true){throw new SyntaxError(syntaxError("closing","]"))}q=`\\${q}`}else{increment("brackets")}push({type:"bracket",value:q});continue}if(q==="]"){if(r.nobracket===true||$&&$.type==="bracket"&&$.value.length===1){push({type:"text",value:q,output:`\\${q}`});continue}if(I.brackets===0){if(r.strictBrackets===true){throw new SyntaxError(syntaxError("opening","["))}push({type:"text",value:q,output:`\\${q}`});continue}decrement("brackets");const e=$.value.slice(1);if($.posix!==true&&e[0]==="^"&&!e.includes("/")){q=`/${q}`}$.value+=q;append({value:q});if(r.literalBrackets===false||a.hasRegexChars(e)){continue}const t=a.escapeRegex($.value);I.output=I.output.slice(0,-$.value.length);if(r.literalBrackets===true){I.output+=t;$.value=t;continue}$.value=`(${g}${t}|${$.value})`;I.output+=$.value;continue}if(q==="{"&&r.nobrace!==true){increment("braces");const e={type:"brace",value:q,output:"(",outputIndex:I.output.length,tokensIndex:I.tokens.length};W.push(e);push(e);continue}if(q==="}"){const e=W[W.length-1];if(r.nobrace===true||!e){push({type:"text",value:q,output:q});continue}let t=")";if(e.dots===true){const e=D.slice();const s=[];for(let t=e.length-1;t>=0;t--){D.pop();if(e[t].type==="brace"){break}if(e[t].type!=="dots"){s.unshift(e[t].value)}}t=expandRange(s,r);I.backtrack=true}if(e.comma!==true&&e.dots!==true){const r=I.output.slice(0,e.outputIndex);const s=I.tokens.slice(e.tokensIndex);e.value=e.output="\\{";q=t="\\}";I.output=r;for(const e of s){I.output+=e.output||e.value}}push({type:"brace",value:q,output:t});decrement("braces");W.pop();continue}if(q==="|"){if(P.length>0){P[P.length-1].conditions++}push({type:"text",value:q});continue}if(q===","){let e=q;const t=W[W.length-1];if(t&&M[M.length-1]==="braces"){t.comma=true;e="|"}push({type:"comma",value:q,output:e});continue}if(q==="/"){if($.type==="dot"&&I.index===I.start+1){I.start=I.index+1;I.consumed="";I.output="";D.pop();$=v;continue}push({type:"slash",value:q,output:x});continue}if(q==="."){if(I.braces>0&&$.type==="dot"){if($.value===".")$.output=E;const e=W[W.length-1];$.type="dots";$.output+=q;$.value+=q;e.dots=true;continue}if(I.braces+I.parens===0&&$.type!=="bos"&&$.type!=="slash"){push({type:"text",value:q,output:E});continue}push({type:"dot",value:q,output:E});continue}if(q==="?"){const e=$&&$.value==="(";if(!e&&r.noextglob!==true&&U()==="("&&U(2)!=="?"){extglobOpen("qmark",q);continue}if($&&$.type==="paren"){const e=U();let t=q;if(e==="<"&&!a.supportsLookbehinds()){throw new Error("Node.js v10 or higher is required for regex lookbehinds")}if($.value==="("&&!/[!=<:]/.test(e)||e==="<"&&!/<([!=]|\w+>)/.test(remaining())){t=`\\${q}`}push({type:"text",value:q,output:t});continue}if(r.dot!==true&&($.type==="slash"||$.type==="bos")){push({type:"qmark",value:q,output:O});continue}push({type:"qmark",value:q,output:R});continue}if(q==="!"){if(r.noextglob!==true&&U()==="("){if(U(2)!=="?"||!/[!=<:]/.test(U(3))){extglobOpen("negate",q);continue}}if(r.nonegate!==true&&I.index===0){negate();continue}}if(q==="+"){if(r.noextglob!==true&&U()==="("&&U(2)!=="?"){extglobOpen("plus",q);continue}if($&&$.value==="("||r.regex===false){push({type:"plus",value:q,output:w});continue}if($&&($.type==="bracket"||$.type==="paren"||$.type==="brace")||I.parens>0){push({type:"plus",value:q});continue}push({type:"plus",value:w});continue}if(q==="@"){if(r.noextglob!==true&&U()==="("&&U(2)!=="?"){push({type:"at",extglob:true,value:q,output:""});continue}push({type:"text",value:q});continue}if(q!=="*"){if(q==="$"||q==="^"){q=`\\${q}`}const e=c.exec(remaining());if(e){q+=e[0];I.index+=e[0].length}push({type:"text",value:q});continue}if($&&($.type==="globstar"||$.star===true)){$.type="star";$.star=true;$.value+=q;$.output=N;I.backtrack=true;I.globstar=true;consume(q);continue}let t=remaining();if(r.noextglob!==true&&/^\([^?]/.test(t)){extglobOpen("star",q);continue}if($.type==="star"){if(r.noglobstar===true){consume(q);continue}const s=$.prev;const a=s.prev;const o=s.type==="slash"||s.type==="bos";const u=a&&(a.type==="star"||a.type==="globstar");if(r.bash===true&&(!o||t[0]&&t[0]!=="/")){push({type:"star",value:q,output:""});continue}const c=I.braces>0&&(s.type==="comma"||s.type==="brace");const f=P.length&&(s.type==="pipe"||s.type==="paren");if(!o&&s.type!=="paren"&&!c&&!f){push({type:"star",value:q,output:""});continue}while(t.slice(0,3)==="/**"){const r=e[I.index+4];if(r&&r!=="/"){break}t=t.slice(3);consume("/**",3)}if(s.type==="bos"&&eos()){$.type="globstar";$.value+=q;$.output=globstar(r);I.output=$.output;I.globstar=true;consume(q);continue}if(s.type==="slash"&&s.prev.type!=="bos"&&!u&&eos()){I.output=I.output.slice(0,-(s.output+$.output).length);s.output=`(?:${s.output}`;$.type="globstar";$.output=globstar(r)+(r.strictSlashes?")":"|$)");$.value+=q;I.globstar=true;I.output+=s.output+$.output;consume(q);continue}if(s.type==="slash"&&s.prev.type!=="bos"&&t[0]==="/"){const e=t[1]!==void 0?"|$":"";I.output=I.output.slice(0,-(s.output+$.output).length);s.output=`(?:${s.output}`;$.type="globstar";$.output=`${globstar(r)}${x}|${x}${e})`;$.value+=q;I.output+=s.output+$.output;I.globstar=true;consume(q+G());push({type:"slash",value:"/",output:""});continue}if(s.type==="bos"&&t[0]==="/"){$.type="globstar";$.value+=q;$.output=`(?:^|${x}|${globstar(r)}${x})`;I.output=$.output;I.globstar=true;consume(q+G());push({type:"slash",value:"/",output:""});continue}I.output=I.output.slice(0,-$.output.length);$.type="globstar";$.output=globstar(r);$.value+=q;I.output+=$.output;I.globstar=true;consume(q);continue}const s={type:"star",value:q,output:N};if(r.bash===true){s.output=".*?";if($.type==="bos"||$.type==="slash"){s.output=B+s.output}push(s);continue}if($&&($.type==="bracket"||$.type==="paren")&&r.regex===true){s.output=q;push(s);continue}if(I.index===I.start||$.type==="slash"||$.type==="dot"){if($.type==="dot"){I.output+=k;$.output+=k}else if(r.dot===true){I.output+=A;$.output+=A}else{I.output+=B;$.output+=B}if(U()!=="*"){I.output+=F;$.output+=F}}push(s)}while(I.brackets>0){if(r.strictBrackets===true)throw new SyntaxError(syntaxError("closing","]"));I.output=a.escapeLast(I.output,"[");decrement("brackets")}while(I.parens>0){if(r.strictBrackets===true)throw new SyntaxError(syntaxError("closing",")"));I.output=a.escapeLast(I.output,"(");decrement("parens")}while(I.braces>0){if(r.strictBrackets===true)throw new SyntaxError(syntaxError("closing","}"));I.output=a.escapeLast(I.output,"{");decrement("braces")}if(r.strictSlashes!==true&&($.type==="star"||$.type==="bracket")){push({type:"maybe_slash",value:"",output:`${x}?`})}if(I.backtrack===true){I.output="";for(const e of I.tokens){I.output+=e.output!=null?e.output:e.value;if(e.suffix){I.output+=e.suffix}}}return I};parse.fastpaths=(e,t)=>{const r={...t};const u=typeof r.maxLength==="number"?Math.min(o,r.maxLength):o;const c=e.length;if(c>u){throw new SyntaxError(`Input length: ${c}, exceeds maximum allowed length: ${u}`)}e=d[e]||e;const f=a.isWindows(t);const{DOT_LITERAL:p,SLASH_LITERAL:h,ONE_CHAR:v,DOTS_SLASH:D,NO_DOT:g,NO_DOTS:y,NO_DOTS_SLASH:m,STAR:_,START_ANCHOR:E}=s.globChars(f);const w=r.dot?y:g;const x=r.dot?m:g;const F=r.capture?"":"?:";const C={negated:false,prefix:""};let S=r.bash===true?".*?":_;if(r.capture){S=`(${S})`}const globstar=e=>{if(e.noglobstar===true)return S;return`(${F}(?:(?!${E}${e.dot?D:p}).)*?)`};const create=e=>{switch(e){case"*":return`${w}${v}${S}`;case".*":return`${p}${v}${S}`;case"*.*":return`${w}${S}${p}${v}${S}`;case"*/*":return`${w}${S}${h}${v}${x}${S}`;case"**":return w+globstar(r);case"**/*":return`(?:${w}${globstar(r)}${h})?${x}${v}${S}`;case"**/*.*":return`(?:${w}${globstar(r)}${h})?${x}${S}${p}${v}${S}`;case"**/.*":return`(?:${w}${globstar(r)}${h})?${p}${v}${S}`;default:{const t=/^(.*?)\.(\w+)$/.exec(e);if(!t)return;const r=create(t[1]);if(!r)return;return r+p+t[2]}}};const k=a.removePrefix(e,C);let A=create(k);if(A&&r.strictSlashes!==true){A+=`${h}?`}return A};e.exports=parse},7250:(e,t,r)=>{"use strict";const s=r(1017);const a=r(2964);const o=r(3632);const u=r(5502);const c=r(7798);const isObject=e=>e&&typeof e==="object"&&!Array.isArray(e);const picomatch=(e,t,r=false)=>{if(Array.isArray(e)){const s=e.map((e=>picomatch(e,t,r)));const arrayMatcher=e=>{for(const t of s){const r=t(e);if(r)return r}return false};return arrayMatcher}const s=isObject(e)&&e.tokens&&e.input;if(e===""||typeof e!=="string"&&!s){throw new TypeError("Expected pattern to be a non-empty string")}const a=t||{};const o=u.isWindows(t);const c=s?picomatch.compileRe(e,t):picomatch.makeRe(e,t,false,true);const f=c.state;delete c.state;let isIgnored=()=>false;if(a.ignore){const e={...t,ignore:null,onMatch:null,onResult:null};isIgnored=picomatch(a.ignore,e,r)}const matcher=(r,s=false)=>{const{isMatch:u,match:d,output:p}=picomatch.test(r,c,t,{glob:e,posix:o});const h={glob:e,state:f,regex:c,posix:o,input:r,output:p,match:d,isMatch:u};if(typeof a.onResult==="function"){a.onResult(h)}if(u===false){h.isMatch=false;return s?h:false}if(isIgnored(r)){if(typeof a.onIgnore==="function"){a.onIgnore(h)}h.isMatch=false;return s?h:false}if(typeof a.onMatch==="function"){a.onMatch(h)}return s?h:true};if(r){matcher.state=f}return matcher};picomatch.test=(e,t,r,{glob:s,posix:a}={})=>{if(typeof e!=="string"){throw new TypeError("Expected input to be a string")}if(e===""){return{isMatch:false,output:""}}const o=r||{};const c=o.format||(a?u.toPosixSlashes:null);let f=e===s;let d=f&&c?c(e):e;if(f===false){d=c?c(e):e;f=d===s}if(f===false||o.capture===true){if(o.matchBase===true||o.basename===true){f=picomatch.matchBase(e,t,r,a)}else{f=t.exec(d)}}return{isMatch:Boolean(f),match:f,output:d}};picomatch.matchBase=(e,t,r,a=u.isWindows(r))=>{const o=t instanceof RegExp?t:picomatch.makeRe(t,r);return o.test(s.basename(e))};picomatch.isMatch=(e,t,r)=>picomatch(t,r)(e);picomatch.parse=(e,t)=>{if(Array.isArray(e))return e.map((e=>picomatch.parse(e,t)));return o(e,{...t,fastpaths:false})};picomatch.scan=(e,t)=>a(e,t);picomatch.compileRe=(e,t,r=false,s=false)=>{if(r===true){return e.output}const a=t||{};const o=a.contains?"":"^";const u=a.contains?"":"$";let c=`${o}(?:${e.output})${u}`;if(e&&e.negated===true){c=`^(?!${c}).*$`}const f=picomatch.toRegex(c,t);if(s===true){f.state=e}return f};picomatch.makeRe=(e,t={},r=false,s=false)=>{if(!e||typeof e!=="string"){throw new TypeError("Expected a non-empty string")}let a={negated:false,fastpaths:true};if(t.fastpaths!==false&&(e[0]==="."||e[0]==="*")){a.output=o.fastpaths(e,t)}if(!a.output){a=o(e,t)}return picomatch.compileRe(a,t,r,s)};picomatch.toRegex=(e,t)=>{try{const r=t||{};return new RegExp(e,r.flags||(r.nocase?"i":""))}catch(e){if(t&&t.debug===true)throw e;return/$^/}};picomatch.constants=c;e.exports=picomatch},2964:(e,t,r)=>{"use strict";const s=r(5502);const{CHAR_ASTERISK:a,CHAR_AT:o,CHAR_BACKWARD_SLASH:u,CHAR_COMMA:c,CHAR_DOT:f,CHAR_EXCLAMATION_MARK:d,CHAR_FORWARD_SLASH:p,CHAR_LEFT_CURLY_BRACE:h,CHAR_LEFT_PARENTHESES:v,CHAR_LEFT_SQUARE_BRACKET:D,CHAR_PLUS:g,CHAR_QUESTION_MARK:y,CHAR_RIGHT_CURLY_BRACE:m,CHAR_RIGHT_PARENTHESES:_,CHAR_RIGHT_SQUARE_BRACKET:E}=r(7798);const isPathSeparator=e=>e===p||e===u;const depth=e=>{if(e.isPrefix!==true){e.depth=e.isGlobstar?Infinity:1}};const scan=(e,t)=>{const r=t||{};const w=e.length-1;const x=r.parts===true||r.scanToEnd===true;const F=[];const C=[];const S=[];let k=e;let A=-1;let R=0;let O=0;let T=false;let j=false;let B=false;let L=false;let N=false;let I=false;let P=false;let W=false;let M=false;let $=false;let q=0;let U;let G;let H={value:"",depth:0,isGlob:false};const eos=()=>A>=w;const peek=()=>k.charCodeAt(A+1);const advance=()=>{U=G;return k.charCodeAt(++A)};while(A0){z=k.slice(0,R);k=k.slice(R);O-=R}if(K&&B===true&&O>0){K=k.slice(0,O);V=k.slice(O)}else if(B===true){K="";V=k}else{K=k}if(K&&K!==""&&K!=="/"&&K!==k){if(isPathSeparator(K.charCodeAt(K.length-1))){K=K.slice(0,-1)}}if(r.unescape===true){if(V)V=s.removeBackslashes(V);if(K&&P===true){K=s.removeBackslashes(K)}}const Y={prefix:z,input:e,start:R,base:K,glob:V,isBrace:T,isBracket:j,isGlob:B,isExtglob:L,isGlobstar:N,negated:W,negatedExtglob:M};if(r.tokens===true){Y.maxDepth=0;if(!isPathSeparator(G)){C.push(H)}Y.tokens=C}if(r.parts===true||r.tokens===true){let t;for(let s=0;s{"use strict";const s=r(1017);const a=process.platform==="win32";const{REGEX_BACKSLASH:o,REGEX_REMOVE_BACKSLASH:u,REGEX_SPECIAL_CHARS:c,REGEX_SPECIAL_CHARS_GLOBAL:f}=r(7798);t.isObject=e=>e!==null&&typeof e==="object"&&!Array.isArray(e);t.hasRegexChars=e=>c.test(e);t.isRegexChar=e=>e.length===1&&t.hasRegexChars(e);t.escapeRegex=e=>e.replace(f,"\\$1");t.toPosixSlashes=e=>e.replace(o,"/");t.removeBackslashes=e=>e.replace(u,(e=>e==="\\"?"":e));t.supportsLookbehinds=()=>{const e=process.version.slice(1).split(".").map(Number);if(e.length===3&&e[0]>=9||e[0]===8&&e[1]>=10){return true}return false};t.isWindows=e=>{if(e&&typeof e.windows==="boolean"){return e.windows}return a===true||s.sep==="\\"};t.escapeLast=(e,r,s)=>{const a=e.lastIndexOf(r,s);if(a===-1)return e;if(e[a-1]==="\\")return t.escapeLast(e,r,a-1);return`${e.slice(0,a)}\\${e.slice(a)}`};t.removePrefix=(e,t={})=>{let r=e;if(r.startsWith("./")){r=r.slice(2);t.prefix="./"}return r};t.wrapOutput=(e,t={},r={})=>{const s=r.contains?"":"^";const a=r.contains?"":"$";let o=`${s}(?:${e})${a}`;if(t.negated===true){o=`(?:^(?!${o}).*$)`}return o}},9182:e=>{"use strict";if(typeof process==="undefined"||!process.version||process.version.indexOf("v0.")===0||process.version.indexOf("v1.")===0&&process.version.indexOf("v1.8.")!==0){e.exports={nextTick:nextTick}}else{e.exports=process}function nextTick(e,t,r,s){if(typeof e!=="function"){throw new TypeError('"callback" argument must be a function')}var a=arguments.length;var o,u;switch(a){case 0:case 1:return process.nextTick(e);case 2:return process.nextTick((function afterTickOne(){e.call(null,t)}));case 3:return process.nextTick((function afterTickTwo(){e.call(null,t,r)}));case 4:return process.nextTick((function afterTickThree(){e.call(null,t,r,s)}));default:o=new Array(a-1);u=0;while(u{"use strict";var s=r(9182);var a=Object.keys||function(e){var t=[];for(var r in e){t.push(r)}return t};e.exports=Duplex;var o=Object.create(r(1504));o.inherits=r(2842);var u=r(7355);var c=r(3517);o.inherits(Duplex,u);{var f=a(c.prototype);for(var d=0;d{"use strict";e.exports=PassThrough;var s=r(2162);var a=Object.create(r(1504));a.inherits=r(2842);a.inherits(PassThrough,s);function PassThrough(e){if(!(this instanceof PassThrough))return new PassThrough(e);s.call(this,e)}PassThrough.prototype._transform=function(e,t,r){r(null,e)}},7355:(e,t,r)=>{"use strict";var s=r(9182);e.exports=Readable;var a=r(1551);var o;Readable.ReadableState=ReadableState;var u=r(2361).EventEmitter;var EElistenerCount=function(e,t){return e.listeners(t).length};var c=r(2641);var f=r(291).Buffer;var d=global.Uint8Array||function(){};function _uint8ArrayToBuffer(e){return f.from(e)}function _isUint8Array(e){return f.isBuffer(e)||e instanceof d}var p=Object.create(r(1504));p.inherits=r(2842);var h=r(3837);var v=void 0;if(h&&h.debuglog){v=h.debuglog("stream")}else{v=function(){}}var D=r(4865);var g=r(2604);var y;p.inherits(Readable,c);var m=["error","close","destroy","pause","resume"];function prependListener(e,t,r){if(typeof e.prependListener==="function")return e.prependListener(t,r);if(!e._events||!e._events[t])e.on(t,r);else if(a(e._events[t]))e._events[t].unshift(r);else e._events[t]=[r,e._events[t]]}function ReadableState(e,t){o=o||r(4928);e=e||{};var s=t instanceof o;this.objectMode=!!e.objectMode;if(s)this.objectMode=this.objectMode||!!e.readableObjectMode;var a=e.highWaterMark;var u=e.readableHighWaterMark;var c=this.objectMode?16:16*1024;if(a||a===0)this.highWaterMark=a;else if(s&&(u||u===0))this.highWaterMark=u;else this.highWaterMark=c;this.highWaterMark=Math.floor(this.highWaterMark);this.buffer=new D;this.length=0;this.pipes=null;this.pipesCount=0;this.flowing=null;this.ended=false;this.endEmitted=false;this.reading=false;this.sync=true;this.needReadable=false;this.emittedReadable=false;this.readableListening=false;this.resumeScheduled=false;this.destroyed=false;this.defaultEncoding=e.defaultEncoding||"utf8";this.awaitDrain=0;this.readingMore=false;this.decoder=null;this.encoding=null;if(e.encoding){if(!y)y=r(4426).s;this.decoder=new y(e.encoding);this.encoding=e.encoding}}function Readable(e){o=o||r(4928);if(!(this instanceof Readable))return new Readable(e);this._readableState=new ReadableState(e,this);this.readable=true;if(e){if(typeof e.read==="function")this._read=e.read;if(typeof e.destroy==="function")this._destroy=e.destroy}c.call(this)}Object.defineProperty(Readable.prototype,"destroyed",{get:function(){if(this._readableState===undefined){return false}return this._readableState.destroyed},set:function(e){if(!this._readableState){return}this._readableState.destroyed=e}});Readable.prototype.destroy=g.destroy;Readable.prototype._undestroy=g.undestroy;Readable.prototype._destroy=function(e,t){this.push(null);t(e)};Readable.prototype.push=function(e,t){var r=this._readableState;var s;if(!r.objectMode){if(typeof e==="string"){t=t||r.defaultEncoding;if(t!==r.encoding){e=f.from(e,t);t=""}s=true}}else{s=true}return readableAddChunk(this,e,t,false,s)};Readable.prototype.unshift=function(e){return readableAddChunk(this,e,null,true,false)};function readableAddChunk(e,t,r,s,a){var o=e._readableState;if(t===null){o.reading=false;onEofChunk(e,o)}else{var u;if(!a)u=chunkInvalid(o,t);if(u){e.emit("error",u)}else if(o.objectMode||t&&t.length>0){if(typeof t!=="string"&&!o.objectMode&&Object.getPrototypeOf(t)!==f.prototype){t=_uint8ArrayToBuffer(t)}if(s){if(o.endEmitted)e.emit("error",new Error("stream.unshift() after end event"));else addChunk(e,o,t,true)}else if(o.ended){e.emit("error",new Error("stream.push() after EOF"))}else{o.reading=false;if(o.decoder&&!r){t=o.decoder.write(t);if(o.objectMode||t.length!==0)addChunk(e,o,t,false);else maybeReadMore(e,o)}else{addChunk(e,o,t,false)}}}else if(!s){o.reading=false}}return needMoreData(o)}function addChunk(e,t,r,s){if(t.flowing&&t.length===0&&!t.sync){e.emit("data",r);e.read(0)}else{t.length+=t.objectMode?1:r.length;if(s)t.buffer.unshift(r);else t.buffer.push(r);if(t.needReadable)emitReadable(e)}maybeReadMore(e,t)}function chunkInvalid(e,t){var r;if(!_isUint8Array(t)&&typeof t!=="string"&&t!==undefined&&!e.objectMode){r=new TypeError("Invalid non-string/buffer chunk")}return r}function needMoreData(e){return!e.ended&&(e.needReadable||e.length=_){e=_}else{e--;e|=e>>>1;e|=e>>>2;e|=e>>>4;e|=e>>>8;e|=e>>>16;e++}return e}function howMuchToRead(e,t){if(e<=0||t.length===0&&t.ended)return 0;if(t.objectMode)return 1;if(e!==e){if(t.flowing&&t.length)return t.buffer.head.data.length;else return t.length}if(e>t.highWaterMark)t.highWaterMark=computeNewHighWaterMark(e);if(e<=t.length)return e;if(!t.ended){t.needReadable=true;return 0}return t.length}Readable.prototype.read=function(e){v("read",e);e=parseInt(e,10);var t=this._readableState;var r=e;if(e!==0)t.emittedReadable=false;if(e===0&&t.needReadable&&(t.length>=t.highWaterMark||t.ended)){v("read: emitReadable",t.length,t.ended);if(t.length===0&&t.ended)endReadable(this);else emitReadable(this);return null}e=howMuchToRead(e,t);if(e===0&&t.ended){if(t.length===0)endReadable(this);return null}var s=t.needReadable;v("need readable",s);if(t.length===0||t.length-e0)a=fromList(e,t);else a=null;if(a===null){t.needReadable=true;e=0}else{t.length-=e}if(t.length===0){if(!t.ended)t.needReadable=true;if(r!==e&&t.ended)endReadable(this)}if(a!==null)this.emit("data",a);return a};function onEofChunk(e,t){if(t.ended)return;if(t.decoder){var r=t.decoder.end();if(r&&r.length){t.buffer.push(r);t.length+=t.objectMode?1:r.length}}t.ended=true;emitReadable(e)}function emitReadable(e){var t=e._readableState;t.needReadable=false;if(!t.emittedReadable){v("emitReadable",t.flowing);t.emittedReadable=true;if(t.sync)s.nextTick(emitReadable_,e);else emitReadable_(e)}}function emitReadable_(e){v("emit readable");e.emit("readable");flow(e)}function maybeReadMore(e,t){if(!t.readingMore){t.readingMore=true;s.nextTick(maybeReadMore_,e,t)}}function maybeReadMore_(e,t){var r=t.length;while(!t.reading&&!t.flowing&&!t.ended&&t.length1&&indexOf(a.pipes,e)!==-1)&&!f){v("false write response, pause",r._readableState.awaitDrain);r._readableState.awaitDrain++;d=true}r.pause()}}function onerror(t){v("onerror",t);unpipe();e.removeListener("error",onerror);if(EElistenerCount(e,"error")===0)e.emit("error",t)}prependListener(e,"error",onerror);function onclose(){e.removeListener("finish",onfinish);unpipe()}e.once("close",onclose);function onfinish(){v("onfinish");e.removeListener("close",onclose);unpipe()}e.once("finish",onfinish);function unpipe(){v("unpipe");r.unpipe(e)}e.emit("pipe",r);if(!a.flowing){v("pipe resume");r.resume()}return e};function pipeOnDrain(e){return function(){var t=e._readableState;v("pipeOnDrain",t.awaitDrain);if(t.awaitDrain)t.awaitDrain--;if(t.awaitDrain===0&&EElistenerCount(e,"data")){t.flowing=true;flow(e)}}}Readable.prototype.unpipe=function(e){var t=this._readableState;var r={hasUnpiped:false};if(t.pipesCount===0)return this;if(t.pipesCount===1){if(e&&e!==t.pipes)return this;if(!e)e=t.pipes;t.pipes=null;t.pipesCount=0;t.flowing=false;if(e)e.emit("unpipe",this,r);return this}if(!e){var s=t.pipes;var a=t.pipesCount;t.pipes=null;t.pipesCount=0;t.flowing=false;for(var o=0;o=t.length){if(t.decoder)r=t.buffer.join("");else if(t.buffer.length===1)r=t.buffer.head.data;else r=t.buffer.concat(t.length);t.buffer.clear()}else{r=fromListPartial(e,t.buffer,t.decoder)}return r}function fromListPartial(e,t,r){var s;if(eo.length?o.length:e;if(u===o.length)a+=o;else a+=o.slice(0,e);e-=u;if(e===0){if(u===o.length){++s;if(r.next)t.head=r.next;else t.head=t.tail=null}else{t.head=r;r.data=o.slice(u)}break}++s}t.length-=s;return a}function copyFromBuffer(e,t){var r=f.allocUnsafe(e);var s=t.head;var a=1;s.data.copy(r);e-=s.data.length;while(s=s.next){var o=s.data;var u=e>o.length?o.length:e;o.copy(r,r.length-e,0,u);e-=u;if(e===0){if(u===o.length){++a;if(s.next)t.head=s.next;else t.head=t.tail=null}else{t.head=s;s.data=o.slice(u)}break}++a}t.length-=a;return r}function endReadable(e){var t=e._readableState;if(t.length>0)throw new Error('"endReadable()" called on non-empty stream');if(!t.endEmitted){t.ended=true;s.nextTick(endReadableNT,t,e)}}function endReadableNT(e,t){if(!e.endEmitted&&e.length===0){e.endEmitted=true;t.readable=false;t.emit("end")}}function indexOf(e,t){for(var r=0,s=e.length;r{"use strict";e.exports=Transform;var s=r(4928);var a=Object.create(r(1504));a.inherits=r(2842);a.inherits(Transform,s);function afterTransform(e,t){var r=this._transformState;r.transforming=false;var s=r.writecb;if(!s){return this.emit("error",new Error("write callback called multiple times"))}r.writechunk=null;r.writecb=null;if(t!=null)this.push(t);s(e);var a=this._readableState;a.reading=false;if(a.needReadable||a.length{"use strict";var s=r(9182);e.exports=Writable;function WriteReq(e,t,r){this.chunk=e;this.encoding=t;this.callback=r;this.next=null}function CorkedRequest(e){var t=this;this.next=null;this.entry=null;this.finish=function(){onCorkedFinish(t,e)}}var a=!process.browser&&["v0.10","v0.9."].indexOf(process.version.slice(0,5))>-1?setImmediate:s.nextTick;var o;Writable.WritableState=WritableState;var u=Object.create(r(1504));u.inherits=r(2842);var c={deprecate:r(6124)};var f=r(2641);var d=r(291).Buffer;var p=global.Uint8Array||function(){};function _uint8ArrayToBuffer(e){return d.from(e)}function _isUint8Array(e){return d.isBuffer(e)||e instanceof p}var h=r(2604);u.inherits(Writable,f);function nop(){}function WritableState(e,t){o=o||r(4928);e=e||{};var s=t instanceof o;this.objectMode=!!e.objectMode;if(s)this.objectMode=this.objectMode||!!e.writableObjectMode;var a=e.highWaterMark;var u=e.writableHighWaterMark;var c=this.objectMode?16:16*1024;if(a||a===0)this.highWaterMark=a;else if(s&&(u||u===0))this.highWaterMark=u;else this.highWaterMark=c;this.highWaterMark=Math.floor(this.highWaterMark);this.finalCalled=false;this.needDrain=false;this.ending=false;this.ended=false;this.finished=false;this.destroyed=false;var f=e.decodeStrings===false;this.decodeStrings=!f;this.defaultEncoding=e.defaultEncoding||"utf8";this.length=0;this.writing=false;this.corked=0;this.sync=true;this.bufferProcessing=false;this.onwrite=function(e){onwrite(t,e)};this.writecb=null;this.writelen=0;this.bufferedRequest=null;this.lastBufferedRequest=null;this.pendingcb=0;this.prefinished=false;this.errorEmitted=false;this.bufferedRequestCount=0;this.corkedRequestsFree=new CorkedRequest(this)}WritableState.prototype.getBuffer=function getBuffer(){var e=this.bufferedRequest;var t=[];while(e){t.push(e);e=e.next}return t};(function(){try{Object.defineProperty(WritableState.prototype,"buffer",{get:c.deprecate((function(){return this.getBuffer()}),"_writableState.buffer is deprecated. Use _writableState.getBuffer "+"instead.","DEP0003")})}catch(e){}})();var v;if(typeof Symbol==="function"&&Symbol.hasInstance&&typeof Function.prototype[Symbol.hasInstance]==="function"){v=Function.prototype[Symbol.hasInstance];Object.defineProperty(Writable,Symbol.hasInstance,{value:function(e){if(v.call(this,e))return true;if(this!==Writable)return false;return e&&e._writableState instanceof WritableState}})}else{v=function(e){return e instanceof this}}function Writable(e){o=o||r(4928);if(!v.call(Writable,this)&&!(this instanceof o)){return new Writable(e)}this._writableState=new WritableState(e,this);this.writable=true;if(e){if(typeof e.write==="function")this._write=e.write;if(typeof e.writev==="function")this._writev=e.writev;if(typeof e.destroy==="function")this._destroy=e.destroy;if(typeof e.final==="function")this._final=e.final}f.call(this)}Writable.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe, not readable"))};function writeAfterEnd(e,t){var r=new Error("write after end");e.emit("error",r);s.nextTick(t,r)}function validChunk(e,t,r,a){var o=true;var u=false;if(r===null){u=new TypeError("May not write null values to stream")}else if(typeof r!=="string"&&r!==undefined&&!t.objectMode){u=new TypeError("Invalid non-string/buffer chunk")}if(u){e.emit("error",u);s.nextTick(a,u);o=false}return o}Writable.prototype.write=function(e,t,r){var s=this._writableState;var a=false;var o=!s.objectMode&&_isUint8Array(e);if(o&&!d.isBuffer(e)){e=_uint8ArrayToBuffer(e)}if(typeof t==="function"){r=t;t=null}if(o)t="buffer";else if(!t)t=s.defaultEncoding;if(typeof r!=="function")r=nop;if(s.ended)writeAfterEnd(this,r);else if(o||validChunk(this,s,e,r)){s.pendingcb++;a=writeOrBuffer(this,s,o,e,t,r)}return a};Writable.prototype.cork=function(){var e=this._writableState;e.corked++};Writable.prototype.uncork=function(){var e=this._writableState;if(e.corked){e.corked--;if(!e.writing&&!e.corked&&!e.finished&&!e.bufferProcessing&&e.bufferedRequest)clearBuffer(this,e)}};Writable.prototype.setDefaultEncoding=function setDefaultEncoding(e){if(typeof e==="string")e=e.toLowerCase();if(!(["hex","utf8","utf-8","ascii","binary","base64","ucs2","ucs-2","utf16le","utf-16le","raw"].indexOf((e+"").toLowerCase())>-1))throw new TypeError("Unknown encoding: "+e);this._writableState.defaultEncoding=e;return this};function decodeChunk(e,t,r){if(!e.objectMode&&e.decodeStrings!==false&&typeof t==="string"){t=d.from(t,r)}return t}Object.defineProperty(Writable.prototype,"writableHighWaterMark",{enumerable:false,get:function(){return this._writableState.highWaterMark}});function writeOrBuffer(e,t,r,s,a,o){if(!r){var u=decodeChunk(t,s,a);if(s!==u){r=true;a="buffer";s=u}}var c=t.objectMode?1:s.length;t.length+=c;var f=t.length{"use strict";function _classCallCheck(e,t){if(!(e instanceof t)){throw new TypeError("Cannot call a class as a function")}}var s=r(291).Buffer;var a=r(3837);function copyBuffer(e,t,r){e.copy(t,r)}e.exports=function(){function BufferList(){_classCallCheck(this,BufferList);this.head=null;this.tail=null;this.length=0}BufferList.prototype.push=function push(e){var t={data:e,next:null};if(this.length>0)this.tail.next=t;else this.head=t;this.tail=t;++this.length};BufferList.prototype.unshift=function unshift(e){var t={data:e,next:this.head};if(this.length===0)this.tail=t;this.head=t;++this.length};BufferList.prototype.shift=function shift(){if(this.length===0)return;var e=this.head.data;if(this.length===1)this.head=this.tail=null;else this.head=this.head.next;--this.length;return e};BufferList.prototype.clear=function clear(){this.head=this.tail=null;this.length=0};BufferList.prototype.join=function join(e){if(this.length===0)return"";var t=this.head;var r=""+t.data;while(t=t.next){r+=e+t.data}return r};BufferList.prototype.concat=function concat(e){if(this.length===0)return s.alloc(0);if(this.length===1)return this.head.data;var t=s.allocUnsafe(e>>>0);var r=this.head;var a=0;while(r){copyBuffer(r.data,t,a);a+=r.data.length;r=r.next}return t};return BufferList}();if(a&&a.inspect&&a.inspect.custom){e.exports.prototype[a.inspect.custom]=function(){var e=a.inspect({length:this.length});return this.constructor.name+" "+e}}},2604:(e,t,r)=>{"use strict";var s=r(9182);function destroy(e,t){var r=this;var a=this._readableState&&this._readableState.destroyed;var o=this._writableState&&this._writableState.destroyed;if(a||o){if(t){t(e)}else if(e&&(!this._writableState||!this._writableState.errorEmitted)){s.nextTick(emitErrorNT,this,e)}return this}if(this._readableState){this._readableState.destroyed=true}if(this._writableState){this._writableState.destroyed=true}this._destroy(e||null,(function(e){if(!t&&e){s.nextTick(emitErrorNT,r,e);if(r._writableState){r._writableState.errorEmitted=true}}else if(t){t(e)}}));return this}function undestroy(){if(this._readableState){this._readableState.destroyed=false;this._readableState.reading=false;this._readableState.ended=false;this._readableState.endEmitted=false}if(this._writableState){this._writableState.destroyed=false;this._writableState.ended=false;this._writableState.ending=false;this._writableState.finished=false;this._writableState.errorEmitted=false}}function emitErrorNT(e,t){e.emit("error",t)}e.exports={destroy:destroy,undestroy:undestroy}},2641:(e,t,r)=>{e.exports=r(2781)},8511:(e,t,r)=>{var s=r(2781);if(process.env.READABLE_STREAM==="disable"&&s){e.exports=s;t=e.exports=s.Readable;t.Readable=s.Readable;t.Writable=s.Writable;t.Duplex=s.Duplex;t.Transform=s.Transform;t.PassThrough=s.PassThrough;t.Stream=s}else{t=e.exports=r(7355);t.Stream=s||t;t.Readable=t;t.Writable=r(3517);t.Duplex=r(4928);t.Transform=r(2162);t.PassThrough=r(9924)}},2382:(e,t,r)=>{"use strict";const s=r(1017);const a=r(8188);const o=r(7147);const resolveFrom=(e,t,r)=>{if(typeof e!=="string"){throw new TypeError(`Expected \`fromDir\` to be of type \`string\`, got \`${typeof e}\``)}if(typeof t!=="string"){throw new TypeError(`Expected \`moduleId\` to be of type \`string\`, got \`${typeof t}\``)}try{e=o.realpathSync(e)}catch(t){if(t.code==="ENOENT"){e=s.resolve(e)}else if(r){return}else{throw t}}const u=s.join(e,"noop.js");const resolveFileName=()=>a._resolveFilename(t,{id:u,filename:u,paths:a._nodeModulePaths(e)});if(r){try{return resolveFileName()}catch(e){return}}return resolveFileName()};e.exports=(e,t)=>resolveFrom(e,t);e.exports.silent=(e,t)=>resolveFrom(e,t,true)},4700:(e,t,r)=>{const s=r(9491);const a=r(1017);const o=r(7147);let u=undefined;try{u=r(3535)}catch(e){}const c={nosort:true,silent:true};let f=0;const d=process.platform==="win32";const defaults=e=>{const t=["unlink","chmod","stat","lstat","rmdir","readdir"];t.forEach((t=>{e[t]=e[t]||o[t];t=t+"Sync";e[t]=e[t]||o[t]}));e.maxBusyTries=e.maxBusyTries||3;e.emfileWait=e.emfileWait||1e3;if(e.glob===false){e.disableGlob=true}if(e.disableGlob!==true&&u===undefined){throw Error("glob dependency not found, set `options.disableGlob = true` if intentional")}e.disableGlob=e.disableGlob||false;e.glob=e.glob||c};const rimraf=(e,t,r)=>{if(typeof t==="function"){r=t;t={}}s(e,"rimraf: missing path");s.equal(typeof e,"string","rimraf: path should be a string");s.equal(typeof r,"function","rimraf: callback function required");s(t,"rimraf: invalid options argument provided");s.equal(typeof t,"object","rimraf: options should be object");defaults(t);let a=0;let o=null;let c=0;const next=e=>{o=o||e;if(--c===0)r(o)};const afterGlob=(e,s)=>{if(e)return r(e);c=s.length;if(c===0)return r();s.forEach((e=>{const CB=r=>{if(r){if((r.code==="EBUSY"||r.code==="ENOTEMPTY"||r.code==="EPERM")&&arimraf_(e,t,CB)),a*100)}if(r.code==="EMFILE"&&frimraf_(e,t,CB)),f++)}if(r.code==="ENOENT")r=null}f=0;next(r)};rimraf_(e,t,CB)}))};if(t.disableGlob||!u.hasMagic(e))return afterGlob(null,[e]);t.lstat(e,((r,s)=>{if(!r)return afterGlob(null,[e]);u(e,t.glob,afterGlob)}))};const rimraf_=(e,t,r)=>{s(e);s(t);s(typeof r==="function");t.lstat(e,((s,a)=>{if(s&&s.code==="ENOENT")return r(null);if(s&&s.code==="EPERM"&&d)fixWinEPERM(e,t,s,r);if(a&&a.isDirectory())return rmdir(e,t,s,r);t.unlink(e,(s=>{if(s){if(s.code==="ENOENT")return r(null);if(s.code==="EPERM")return d?fixWinEPERM(e,t,s,r):rmdir(e,t,s,r);if(s.code==="EISDIR")return rmdir(e,t,s,r)}return r(s)}))}))};const fixWinEPERM=(e,t,r,a)=>{s(e);s(t);s(typeof a==="function");t.chmod(e,438,(s=>{if(s)a(s.code==="ENOENT"?null:r);else t.stat(e,((s,o)=>{if(s)a(s.code==="ENOENT"?null:r);else if(o.isDirectory())rmdir(e,t,r,a);else t.unlink(e,a)}))}))};const fixWinEPERMSync=(e,t,r)=>{s(e);s(t);try{t.chmodSync(e,438)}catch(e){if(e.code==="ENOENT")return;else throw r}let a;try{a=t.statSync(e)}catch(e){if(e.code==="ENOENT")return;else throw r}if(a.isDirectory())rmdirSync(e,t,r);else t.unlinkSync(e)};const rmdir=(e,t,r,a)=>{s(e);s(t);s(typeof a==="function");t.rmdir(e,(s=>{if(s&&(s.code==="ENOTEMPTY"||s.code==="EEXIST"||s.code==="EPERM"))rmkids(e,t,a);else if(s&&s.code==="ENOTDIR")a(r);else a(s)}))};const rmkids=(e,t,r)=>{s(e);s(t);s(typeof r==="function");t.readdir(e,((s,o)=>{if(s)return r(s);let u=o.length;if(u===0)return t.rmdir(e,r);let c;o.forEach((s=>{rimraf(a.join(e,s),t,(s=>{if(c)return;if(s)return r(c=s);if(--u===0)t.rmdir(e,r)}))}))}))};const rimrafSync=(e,t)=>{t=t||{};defaults(t);s(e,"rimraf: missing path");s.equal(typeof e,"string","rimraf: path should be a string");s(t,"rimraf: missing options");s.equal(typeof t,"object","rimraf: options should be object");let r;if(t.disableGlob||!u.hasMagic(e)){r=[e]}else{try{t.lstatSync(e);r=[e]}catch(s){r=u.sync(e,t.glob)}}if(!r.length)return;for(let e=0;e{s(e);s(t);try{t.rmdirSync(e)}catch(s){if(s.code==="ENOENT")return;if(s.code==="ENOTDIR")throw r;if(s.code==="ENOTEMPTY"||s.code==="EEXIST"||s.code==="EPERM")rmkidsSync(e,t)}};const rmkidsSync=(e,t)=>{s(e);s(t);t.readdirSync(e).forEach((r=>rimrafSync(a.join(e,r),t)));const r=d?100:1;let o=0;do{let s=true;try{const a=t.rmdirSync(e,t);s=false;return a}finally{if(++o{var s=r(4300);var a=s.Buffer;function copyProps(e,t){for(var r in e){t[r]=e[r]}}if(a.from&&a.alloc&&a.allocUnsafe&&a.allocUnsafeSlow){e.exports=s}else{copyProps(s,t);t.Buffer=SafeBuffer}function SafeBuffer(e,t,r){return a(e,t,r)}copyProps(a,SafeBuffer);SafeBuffer.from=function(e,t,r){if(typeof e==="number"){throw new TypeError("Argument must not be a number")}return a(e,t,r)};SafeBuffer.alloc=function(e,t,r){if(typeof e!=="number"){throw new TypeError("Argument must be a number")}var s=a(e);if(t!==undefined){if(typeof r==="string"){s.fill(t,r)}else{s.fill(t)}}else{s.fill(0)}return s};SafeBuffer.allocUnsafe=function(e){if(typeof e!=="number"){throw new TypeError("Argument must be a number")}return a(e)};SafeBuffer.allocUnsafeSlow=function(e){if(typeof e!=="number"){throw new TypeError("Argument must be a number")}return s.SlowBuffer(e)}},2656:e=>{e.exports=function(e){[process.stdout,process.stderr].forEach((function(t){if(t._handle&&t.isTTY&&typeof t._handle.setBlocking==="function"){t._handle.setBlocking(e)}}))}},7234:(e,t,r)=>{var s=global.process;const processOk=function(e){return e&&typeof e==="object"&&typeof e.removeListener==="function"&&typeof e.emit==="function"&&typeof e.reallyExit==="function"&&typeof e.listeners==="function"&&typeof e.kill==="function"&&typeof e.pid==="number"&&typeof e.on==="function"};if(!processOk(s)){e.exports=function(){return function(){}}}else{var a=r(9491);var o=r(6462);var u=/^win/i.test(s.platform);var c=r(2361);if(typeof c!=="function"){c=c.EventEmitter}var f;if(s.__signal_exit_emitter__){f=s.__signal_exit_emitter__}else{f=s.__signal_exit_emitter__=new c;f.count=0;f.emitted={}}if(!f.infinite){f.setMaxListeners(Infinity);f.infinite=true}e.exports=function(e,t){if(!processOk(global.process)){return function(){}}a.equal(typeof e,"function","a callback must be provided for exit handler");if(v===false){D()}var r="exit";if(t&&t.alwaysLast){r="afterexit"}var remove=function(){f.removeListener(r,e);if(f.listeners("exit").length===0&&f.listeners("afterexit").length===0){d()}};f.on(r,e);return remove};var d=function unload(){if(!v||!processOk(global.process)){return}v=false;o.forEach((function(e){try{s.removeListener(e,h[e])}catch(e){}}));s.emit=m;s.reallyExit=g;f.count-=1};e.exports.unload=d;var p=function emit(e,t,r){if(f.emitted[e]){return}f.emitted[e]=true;f.emit(e,t,r)};var h={};o.forEach((function(e){h[e]=function listener(){if(!processOk(global.process)){return}var t=s.listeners(e);if(t.length===f.count){d();p("exit",null,e);p("afterexit",null,e);if(u&&e==="SIGHUP"){e="SIGINT"}s.kill(s.pid,e)}}}));e.exports.signals=function(){return o};var v=false;var D=function load(){if(v||!processOk(global.process)){return}v=true;f.count+=1;o=o.filter((function(e){try{s.on(e,h[e]);return true}catch(e){return false}}));s.emit=_;s.reallyExit=y};e.exports.load=D;var g=s.reallyExit;var y=function processReallyExit(e){if(!processOk(global.process)){return}s.exitCode=e||0;p("exit",s.exitCode,null);p("afterexit",s.exitCode,null);g.call(s,s.exitCode)};var m=s.emit;var _=function processEmit(e,t){if(e==="exit"&&processOk(global.process)){if(t!==undefined){s.exitCode=t}var r=m.apply(this,arguments);p("exit",s.exitCode,null);p("afterexit",s.exitCode,null);return r}else{return m.apply(this,arguments)}}}},6462:e=>{e.exports=["SIGABRT","SIGALRM","SIGHUP","SIGINT","SIGTERM"];if(process.platform!=="win32"){e.exports.push("SIGVTALRM","SIGXCPU","SIGXFSZ","SIGUSR2","SIGTRAP","SIGSYS","SIGQUIT","SIGIOT")}if(process.platform==="linux"){e.exports.push("SIGIO","SIGPOLL","SIGPWR","SIGSTKFLT","SIGUNUSED")}},8321:(e,t,r)=>{"use strict";var s=r(7518);var a=r(8589);var o=r(3279);e.exports=function(e){if(typeof e!=="string"||e.length===0){return 0}var t=0;e=s(e);for(var r=0;r=127&&u<=159){continue}if(u>=65536){r++}if(o(u)){t+=2}else{t++}}return t}},5663:(e,t,r)=>{"use strict";const s=r(7518);const a=r(8502);const o=r(3876);const stringWidth=e=>{if(typeof e!=="string"||e.length===0){return 0}e=s(e);if(e.length===0){return 0}e=e.replace(o()," ");let t=0;for(let r=0;r=127&&s<=159){continue}if(s>=768&&s<=879){continue}if(s>65535){r++}t+=a(s)?2:1}return t};e.exports=stringWidth;e.exports["default"]=stringWidth},4426:(e,t,r)=>{"use strict";var s=r(291).Buffer;var a=s.isEncoding||function(e){e=""+e;switch(e&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return true;default:return false}};function _normalizeEncoding(e){if(!e)return"utf8";var t;while(true){switch(e){case"utf8":case"utf-8":return"utf8";case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return"utf16le";case"latin1":case"binary":return"latin1";case"base64":case"ascii":case"hex":return e;default:if(t)return;e=(""+e).toLowerCase();t=true}}}function normalizeEncoding(e){var t=_normalizeEncoding(e);if(typeof t!=="string"&&(s.isEncoding===a||!a(e)))throw new Error("Unknown encoding: "+e);return t||e}t.s=StringDecoder;function StringDecoder(e){this.encoding=normalizeEncoding(e);var t;switch(this.encoding){case"utf16le":this.text=utf16Text;this.end=utf16End;t=4;break;case"utf8":this.fillLast=utf8FillLast;t=4;break;case"base64":this.text=base64Text;this.end=base64End;t=3;break;default:this.write=simpleWrite;this.end=simpleEnd;return}this.lastNeed=0;this.lastTotal=0;this.lastChar=s.allocUnsafe(t)}StringDecoder.prototype.write=function(e){if(e.length===0)return"";var t;var r;if(this.lastNeed){t=this.fillLast(e);if(t===undefined)return"";r=this.lastNeed;this.lastNeed=0}else{r=0}if(r>5===6)return 2;else if(e>>4===14)return 3;else if(e>>3===30)return 4;return e>>6===2?-1:-2}function utf8CheckIncomplete(e,t,r){var s=t.length-1;if(s=0){if(a>0)e.lastNeed=a-1;return a}if(--s=0){if(a>0)e.lastNeed=a-2;return a}if(--s=0){if(a>0){if(a===2)a=0;else e.lastNeed=a-3}return a}return 0}function utf8CheckExtraBytes(e,t,r){if((t[0]&192)!==128){e.lastNeed=0;return"�"}if(e.lastNeed>1&&t.length>1){if((t[1]&192)!==128){e.lastNeed=1;return"�"}if(e.lastNeed>2&&t.length>2){if((t[2]&192)!==128){e.lastNeed=2;return"�"}}}}function utf8FillLast(e){var t=this.lastTotal-this.lastNeed;var r=utf8CheckExtraBytes(this,e,t);if(r!==undefined)return r;if(this.lastNeed<=e.length){e.copy(this.lastChar,t,0,this.lastNeed);return this.lastChar.toString(this.encoding,0,this.lastTotal)}e.copy(this.lastChar,t,0,e.length);this.lastNeed-=e.length}function utf8Text(e,t){var r=utf8CheckIncomplete(this,e,t);if(!this.lastNeed)return e.toString("utf8",t);this.lastTotal=r;var s=e.length-(r-this.lastNeed);e.copy(this.lastChar,0,s);return e.toString("utf8",t,s)}function utf8End(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed)return t+"�";return t}function utf16Text(e,t){if((e.length-t)%2===0){var r=e.toString("utf16le",t);if(r){var s=r.charCodeAt(r.length-1);if(s>=55296&&s<=56319){this.lastNeed=2;this.lastTotal=4;this.lastChar[0]=e[e.length-2];this.lastChar[1]=e[e.length-1];return r.slice(0,-1)}}return r}this.lastNeed=1;this.lastTotal=2;this.lastChar[0]=e[e.length-1];return e.toString("utf16le",t,e.length-1)}function utf16End(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed){var r=this.lastTotal-this.lastNeed;return t+this.lastChar.toString("utf16le",0,r)}return t}function base64Text(e,t){var r=(e.length-t)%3;if(r===0)return e.toString("base64",t);this.lastNeed=3-r;this.lastTotal=3;if(r===1){this.lastChar[0]=e[e.length-1]}else{this.lastChar[0]=e[e.length-2];this.lastChar[1]=e[e.length-1]}return e.toString("base64",t,e.length-r)}function base64End(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed)return t+this.lastChar.toString("base64",0,3-this.lastNeed);return t}function simpleWrite(e){return e.toString(this.encoding)}function simpleEnd(e){return e&&e.length?this.write(e):""}},6124:(e,t,r)=>{e.exports=r(3837).deprecate},1365:(e,t,r)=>{"use strict";var s=r(5663);t.center=alignCenter;t.left=alignLeft;t.right=alignRight;function createPadding(e){var t="";var r=" ";var s=e;do{if(s%2){t+=r}s=Math.floor(s/2);r+=r}while(s);return t}function alignLeft(e,t){var r=e.trimRight();if(r.length===0&&e.length>=t)return e;var a="";var o=s(r);if(o=t)return e;var a="";var o=s(r);if(o=t)return e;var a="";var o="";var u=s(r);if(u{module.exports=eval("require")("aws-sdk")},3930:module=>{module.exports=eval("require")("mock-aws-s3")},4997:module=>{module.exports=eval("require")("nock")},9491:e=>{"use strict";e.exports=require("assert")},4300:e=>{"use strict";e.exports=require("buffer")},2081:e=>{"use strict";e.exports=require("child_process")},2057:e=>{"use strict";e.exports=require("constants")},2361:e=>{"use strict";e.exports=require("events")},7147:e=>{"use strict";e.exports=require("fs")},8188:e=>{"use strict";e.exports=require("module")},1988:e=>{"use strict";e.exports=require("next/dist/compiled/acorn")},5749:e=>{"use strict";e.exports=require("next/dist/compiled/async-sema")},3535:e=>{"use strict";e.exports=require("next/dist/compiled/glob")},2540:e=>{"use strict";e.exports=require("next/dist/compiled/micromatch")},7849:e=>{"use strict";e.exports=require("next/dist/compiled/semver")},7518:e=>{"use strict";e.exports=require("next/dist/compiled/strip-ansi")},2037:e=>{"use strict";e.exports=require("os")},1017:e=>{"use strict";e.exports=require("path")},8102:e=>{"use strict";e.exports=require("repl")},2781:e=>{"use strict";e.exports=require("stream")},7310:e=>{"use strict";e.exports=require("url")},3837:e=>{"use strict";e.exports=require("util")},9663:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});var s=r(1017);var a=r(3846);function _interopDefaultLegacy(e){return e&&typeof e==="object"&&"default"in e?e:{default:e}}var o=_interopDefaultLegacy(a);const u=function addExtension(e,t=".js"){let r=`${e}`;if(!s.extname(e))r+=t;return r};class WalkerBase{constructor(){WalkerBase.prototype.__init.call(this);WalkerBase.prototype.__init2.call(this);WalkerBase.prototype.__init3.call(this);WalkerBase.prototype.__init4.call(this)}__init(){this.should_skip=false}__init2(){this.should_remove=false}__init3(){this.replacement=null}__init4(){this.context={skip:()=>this.should_skip=true,remove:()=>this.should_remove=true,replace:e=>this.replacement=e}}replace(e,t,r,s){if(e){if(r!==null){e[t][r]=s}else{e[t]=s}}}remove(e,t,r){if(e){if(r!==null){e[t].splice(r,1)}else{delete e[t]}}}}class SyncWalkerClass extends WalkerBase{constructor(e){super();this.enter=e.enter;this.leave=e.leave}visit(e,t,r,s,a,o){if(e){if(r){const s=this.should_skip;const u=this.should_remove;const c=this.replacement;this.should_skip=false;this.should_remove=false;this.replacement=null;r.call(this.context,e,t,a,o);if(this.replacement){e=this.replacement;this.replace(t,a,o,e)}if(this.should_remove){this.remove(t,a,o)}const f=this.should_skip;const d=this.should_remove;this.should_skip=s;this.should_remove=u;this.replacement=c;if(f)return e;if(d)return null}for(const t in e){const a=e[t];if(typeof a!=="object"){continue}else if(Array.isArray(a)){for(let o=0;o{f(e).forEach((e=>{this.declarations[e]=true}))}))}}addDeclaration(e,t,r){if(!t&&this.isBlockScope){this.parent.addDeclaration(e,t,r)}else if(e.id){f(e.id).forEach((e=>{this.declarations[e]=true}))}}contains(e){return this.declarations[e]||(this.parent?this.parent.contains(e):false)}}const p=function attachScopes(e,t="scope"){let r=new Scope;walk(e,{enter(e,s){const a=e;if(/(Function|Class)Declaration/.test(a.type)){r.addDeclaration(a,false,false)}if(a.type==="VariableDeclaration"){const{kind:e}=a;const t=d[e];a.declarations.forEach((e=>{r.addDeclaration(e,t,true)}))}let o;if(/Function/.test(a.type)){const e=a;o=new Scope({parent:r,block:false,params:e.params});if(e.type==="FunctionExpression"&&e.id){o.addDeclaration(e,false,false)}}if(/For(In|Of)?Statement/.test(a.type)){o=new Scope({parent:r,block:true})}if(a.type==="BlockStatement"&&!/Function/.test(s.type)){o=new Scope({parent:r,block:true})}if(a.type==="CatchClause"){o=new Scope({parent:r,params:a.param?[a.param]:[],block:true})}if(o){Object.defineProperty(a,t,{value:o,configurable:true});r=o}},leave(e){const s=e;if(s[t])r=r.parent}});return r};function isArray(e){return Array.isArray(e)}function ensureArray(e){if(isArray(e))return e;if(e==null)return[];return[e]}const h=function normalizePath(e){return e.split(s.win32.sep).join(s.posix.sep)};function getMatcherString(e,t){if(t===false||s.isAbsolute(e)||e.startsWith("*")){return h(e)}const r=h(s.resolve(t||"")).replace(/[-^$*+?.()|[\]{}]/g,"\\$&");return s.posix.join(r,h(e))}const v=function createFilter(e,t,r){const s=r&&r.resolve;const getMatcher=e=>e instanceof RegExp?e:{test:t=>{const r=getMatcherString(e,s);const a=o["default"](r,{dot:true});const u=a(t);return u}};const a=ensureArray(e).map(getMatcher);const u=ensureArray(t).map(getMatcher);return function result(e){if(typeof e!=="string")return false;if(/\0/.test(e))return false;const t=h(e);for(let e=0;et.toUpperCase())).replace(/[^$_a-zA-Z0-9]/g,"_");if(/\d/.test(t[0])||y.has(t)){t=`_${t}`}return t||"_"};function stringify(e){return(JSON.stringify(e)||"undefined").replace(/[\u2028\u2029]/g,(e=>`\\u${`000${e.charCodeAt(0).toString(16)}`.slice(-4)}`))}function serializeArray(e,t,r){let s="[";const a=t?`\n${r}${t}`:"";for(let o=0;o0?",":""}${a}${serialize(u,t,r+t)}`}return`${s}${t?`\n${r}`:""}]`}function serializeObject(e,t,r){let s="{";const a=t?`\n${r}${t}`:"";const o=Object.entries(e);for(let e=0;e0?",":""}${a}${f}:${t?" ":""}${serialize(c,t,r+t)}`}return`${s}${t?`\n${r}`:""}}`}function serialize(e,t,r){if(typeof e==="object"&&e!==null){if(Array.isArray(e))return serializeArray(e,t,r);if(e instanceof Date)return`new Date(${e.getTime()})`;if(e instanceof RegExp)return e.toString();return serializeObject(e,t,r)}if(typeof e==="number"){if(e===Infinity)return"Infinity";if(e===-Infinity)return"-Infinity";if(e===0)return 1/e===Infinity?"0":"-0";if(e!==e)return"NaN"}if(typeof e==="symbol"){const t=Symbol.keyFor(e);if(t!==undefined)return`Symbol.for(${stringify(t)})`}if(typeof e==="bigint")return`${e}n`;return stringify(e)}const _=function dataToEsm(e,t={}){const r=t.compact?"":"indent"in t?t.indent:"\t";const s=t.compact?"":" ";const a=t.compact?"":"\n";const o=t.preferConst?"const":"var";if(t.namedExports===false||typeof e!=="object"||Array.isArray(e)||e instanceof Date||e instanceof RegExp||e===null){const a=serialize(e,t.compact?null:r,"");const o=s||(/^[{[\-\/]/.test(a)?"":" ");return`export default${o}${a};`}let u="";const c=[];for(const[f,d]of Object.entries(e)){if(f===m(f)){if(t.objectShorthand)c.push(f);else c.push(`${f}:${s}${f}`);u+=`export ${o} ${f}${s}=${s}${serialize(d,t.compact?null:r,"")};${a}`}else{c.push(`${stringify(f)}:${s}${serialize(d,t.compact?null:r,"")}`)}}return`${u}export default${s}{${a}${r}${c.join(`,${a}${r}`)}${a}};${a}`};var E={addExtension:u,attachScopes:p,createFilter:v,dataToEsm:_,extractAssignedNames:f,makeLegalIdentifier:m,normalizePath:h};t.addExtension=u;t.attachScopes=p;t.createFilter=v;t.dataToEsm=_;t["default"]=E;t.extractAssignedNames=f;t.makeLegalIdentifier=m;t.normalizePath=h},3982:function(e,t){(function(e,r){true?r(t):0})(this,(function(e){"use strict";class WalkerBase{constructor(){this.should_skip=false;this.should_remove=false;this.replacement=null;this.context={skip:()=>this.should_skip=true,remove:()=>this.should_remove=true,replace:e=>this.replacement=e}}replace(e,t,r,s){if(e){if(r!==null){e[t][r]=s}else{e[t]=s}}}remove(e,t,r){if(e){if(r!==null){e[t].splice(r,1)}else{delete e[t]}}}}class SyncWalker extends WalkerBase{constructor(e,t){super();this.enter=e;this.leave=t}visit(e,t,r,s){if(e){if(this.enter){const a=this.should_skip;const o=this.should_remove;const u=this.replacement;this.should_skip=false;this.should_remove=false;this.replacement=null;this.enter.call(this.context,e,t,r,s);if(this.replacement){e=this.replacement;this.replace(t,r,s,e)}if(this.should_remove){this.remove(t,r,s)}const c=this.should_skip;const f=this.should_remove;this.should_skip=a;this.should_remove=o;this.replacement=u;if(c)return e;if(f)return null}for(const t in e){const r=e[t];if(typeof r!=="object"){continue}else if(Array.isArray(r)){for(let s=0;s{"use strict";e.exports=JSON.parse('{"0.1.14":{"node_abi":null,"v8":"1.3"},"0.1.15":{"node_abi":null,"v8":"1.3"},"0.1.16":{"node_abi":null,"v8":"1.3"},"0.1.17":{"node_abi":null,"v8":"1.3"},"0.1.18":{"node_abi":null,"v8":"1.3"},"0.1.19":{"node_abi":null,"v8":"2.0"},"0.1.20":{"node_abi":null,"v8":"2.0"},"0.1.21":{"node_abi":null,"v8":"2.0"},"0.1.22":{"node_abi":null,"v8":"2.0"},"0.1.23":{"node_abi":null,"v8":"2.0"},"0.1.24":{"node_abi":null,"v8":"2.0"},"0.1.25":{"node_abi":null,"v8":"2.0"},"0.1.26":{"node_abi":null,"v8":"2.0"},"0.1.27":{"node_abi":null,"v8":"2.1"},"0.1.28":{"node_abi":null,"v8":"2.1"},"0.1.29":{"node_abi":null,"v8":"2.1"},"0.1.30":{"node_abi":null,"v8":"2.1"},"0.1.31":{"node_abi":null,"v8":"2.1"},"0.1.32":{"node_abi":null,"v8":"2.1"},"0.1.33":{"node_abi":null,"v8":"2.1"},"0.1.90":{"node_abi":null,"v8":"2.2"},"0.1.91":{"node_abi":null,"v8":"2.2"},"0.1.92":{"node_abi":null,"v8":"2.2"},"0.1.93":{"node_abi":null,"v8":"2.2"},"0.1.94":{"node_abi":null,"v8":"2.2"},"0.1.95":{"node_abi":null,"v8":"2.2"},"0.1.96":{"node_abi":null,"v8":"2.2"},"0.1.97":{"node_abi":null,"v8":"2.2"},"0.1.98":{"node_abi":null,"v8":"2.2"},"0.1.99":{"node_abi":null,"v8":"2.2"},"0.1.100":{"node_abi":null,"v8":"2.2"},"0.1.101":{"node_abi":null,"v8":"2.3"},"0.1.102":{"node_abi":null,"v8":"2.3"},"0.1.103":{"node_abi":null,"v8":"2.3"},"0.1.104":{"node_abi":null,"v8":"2.3"},"0.2.0":{"node_abi":1,"v8":"2.3"},"0.2.1":{"node_abi":1,"v8":"2.3"},"0.2.2":{"node_abi":1,"v8":"2.3"},"0.2.3":{"node_abi":1,"v8":"2.3"},"0.2.4":{"node_abi":1,"v8":"2.3"},"0.2.5":{"node_abi":1,"v8":"2.3"},"0.2.6":{"node_abi":1,"v8":"2.3"},"0.3.0":{"node_abi":1,"v8":"2.5"},"0.3.1":{"node_abi":1,"v8":"2.5"},"0.3.2":{"node_abi":1,"v8":"3.0"},"0.3.3":{"node_abi":1,"v8":"3.0"},"0.3.4":{"node_abi":1,"v8":"3.0"},"0.3.5":{"node_abi":1,"v8":"3.0"},"0.3.6":{"node_abi":1,"v8":"3.0"},"0.3.7":{"node_abi":1,"v8":"3.0"},"0.3.8":{"node_abi":1,"v8":"3.1"},"0.4.0":{"node_abi":1,"v8":"3.1"},"0.4.1":{"node_abi":1,"v8":"3.1"},"0.4.2":{"node_abi":1,"v8":"3.1"},"0.4.3":{"node_abi":1,"v8":"3.1"},"0.4.4":{"node_abi":1,"v8":"3.1"},"0.4.5":{"node_abi":1,"v8":"3.1"},"0.4.6":{"node_abi":1,"v8":"3.1"},"0.4.7":{"node_abi":1,"v8":"3.1"},"0.4.8":{"node_abi":1,"v8":"3.1"},"0.4.9":{"node_abi":1,"v8":"3.1"},"0.4.10":{"node_abi":1,"v8":"3.1"},"0.4.11":{"node_abi":1,"v8":"3.1"},"0.4.12":{"node_abi":1,"v8":"3.1"},"0.5.0":{"node_abi":1,"v8":"3.1"},"0.5.1":{"node_abi":1,"v8":"3.4"},"0.5.2":{"node_abi":1,"v8":"3.4"},"0.5.3":{"node_abi":1,"v8":"3.4"},"0.5.4":{"node_abi":1,"v8":"3.5"},"0.5.5":{"node_abi":1,"v8":"3.5"},"0.5.6":{"node_abi":1,"v8":"3.6"},"0.5.7":{"node_abi":1,"v8":"3.6"},"0.5.8":{"node_abi":1,"v8":"3.6"},"0.5.9":{"node_abi":1,"v8":"3.6"},"0.5.10":{"node_abi":1,"v8":"3.7"},"0.6.0":{"node_abi":1,"v8":"3.6"},"0.6.1":{"node_abi":1,"v8":"3.6"},"0.6.2":{"node_abi":1,"v8":"3.6"},"0.6.3":{"node_abi":1,"v8":"3.6"},"0.6.4":{"node_abi":1,"v8":"3.6"},"0.6.5":{"node_abi":1,"v8":"3.6"},"0.6.6":{"node_abi":1,"v8":"3.6"},"0.6.7":{"node_abi":1,"v8":"3.6"},"0.6.8":{"node_abi":1,"v8":"3.6"},"0.6.9":{"node_abi":1,"v8":"3.6"},"0.6.10":{"node_abi":1,"v8":"3.6"},"0.6.11":{"node_abi":1,"v8":"3.6"},"0.6.12":{"node_abi":1,"v8":"3.6"},"0.6.13":{"node_abi":1,"v8":"3.6"},"0.6.14":{"node_abi":1,"v8":"3.6"},"0.6.15":{"node_abi":1,"v8":"3.6"},"0.6.16":{"node_abi":1,"v8":"3.6"},"0.6.17":{"node_abi":1,"v8":"3.6"},"0.6.18":{"node_abi":1,"v8":"3.6"},"0.6.19":{"node_abi":1,"v8":"3.6"},"0.6.20":{"node_abi":1,"v8":"3.6"},"0.6.21":{"node_abi":1,"v8":"3.6"},"0.7.0":{"node_abi":1,"v8":"3.8"},"0.7.1":{"node_abi":1,"v8":"3.8"},"0.7.2":{"node_abi":1,"v8":"3.8"},"0.7.3":{"node_abi":1,"v8":"3.9"},"0.7.4":{"node_abi":1,"v8":"3.9"},"0.7.5":{"node_abi":1,"v8":"3.9"},"0.7.6":{"node_abi":1,"v8":"3.9"},"0.7.7":{"node_abi":1,"v8":"3.9"},"0.7.8":{"node_abi":1,"v8":"3.9"},"0.7.9":{"node_abi":1,"v8":"3.11"},"0.7.10":{"node_abi":1,"v8":"3.9"},"0.7.11":{"node_abi":1,"v8":"3.11"},"0.7.12":{"node_abi":1,"v8":"3.11"},"0.8.0":{"node_abi":1,"v8":"3.11"},"0.8.1":{"node_abi":1,"v8":"3.11"},"0.8.2":{"node_abi":1,"v8":"3.11"},"0.8.3":{"node_abi":1,"v8":"3.11"},"0.8.4":{"node_abi":1,"v8":"3.11"},"0.8.5":{"node_abi":1,"v8":"3.11"},"0.8.6":{"node_abi":1,"v8":"3.11"},"0.8.7":{"node_abi":1,"v8":"3.11"},"0.8.8":{"node_abi":1,"v8":"3.11"},"0.8.9":{"node_abi":1,"v8":"3.11"},"0.8.10":{"node_abi":1,"v8":"3.11"},"0.8.11":{"node_abi":1,"v8":"3.11"},"0.8.12":{"node_abi":1,"v8":"3.11"},"0.8.13":{"node_abi":1,"v8":"3.11"},"0.8.14":{"node_abi":1,"v8":"3.11"},"0.8.15":{"node_abi":1,"v8":"3.11"},"0.8.16":{"node_abi":1,"v8":"3.11"},"0.8.17":{"node_abi":1,"v8":"3.11"},"0.8.18":{"node_abi":1,"v8":"3.11"},"0.8.19":{"node_abi":1,"v8":"3.11"},"0.8.20":{"node_abi":1,"v8":"3.11"},"0.8.21":{"node_abi":1,"v8":"3.11"},"0.8.22":{"node_abi":1,"v8":"3.11"},"0.8.23":{"node_abi":1,"v8":"3.11"},"0.8.24":{"node_abi":1,"v8":"3.11"},"0.8.25":{"node_abi":1,"v8":"3.11"},"0.8.26":{"node_abi":1,"v8":"3.11"},"0.8.27":{"node_abi":1,"v8":"3.11"},"0.8.28":{"node_abi":1,"v8":"3.11"},"0.9.0":{"node_abi":1,"v8":"3.11"},"0.9.1":{"node_abi":10,"v8":"3.11"},"0.9.2":{"node_abi":10,"v8":"3.11"},"0.9.3":{"node_abi":10,"v8":"3.13"},"0.9.4":{"node_abi":10,"v8":"3.13"},"0.9.5":{"node_abi":10,"v8":"3.13"},"0.9.6":{"node_abi":10,"v8":"3.15"},"0.9.7":{"node_abi":10,"v8":"3.15"},"0.9.8":{"node_abi":10,"v8":"3.15"},"0.9.9":{"node_abi":11,"v8":"3.15"},"0.9.10":{"node_abi":11,"v8":"3.15"},"0.9.11":{"node_abi":11,"v8":"3.14"},"0.9.12":{"node_abi":11,"v8":"3.14"},"0.10.0":{"node_abi":11,"v8":"3.14"},"0.10.1":{"node_abi":11,"v8":"3.14"},"0.10.2":{"node_abi":11,"v8":"3.14"},"0.10.3":{"node_abi":11,"v8":"3.14"},"0.10.4":{"node_abi":11,"v8":"3.14"},"0.10.5":{"node_abi":11,"v8":"3.14"},"0.10.6":{"node_abi":11,"v8":"3.14"},"0.10.7":{"node_abi":11,"v8":"3.14"},"0.10.8":{"node_abi":11,"v8":"3.14"},"0.10.9":{"node_abi":11,"v8":"3.14"},"0.10.10":{"node_abi":11,"v8":"3.14"},"0.10.11":{"node_abi":11,"v8":"3.14"},"0.10.12":{"node_abi":11,"v8":"3.14"},"0.10.13":{"node_abi":11,"v8":"3.14"},"0.10.14":{"node_abi":11,"v8":"3.14"},"0.10.15":{"node_abi":11,"v8":"3.14"},"0.10.16":{"node_abi":11,"v8":"3.14"},"0.10.17":{"node_abi":11,"v8":"3.14"},"0.10.18":{"node_abi":11,"v8":"3.14"},"0.10.19":{"node_abi":11,"v8":"3.14"},"0.10.20":{"node_abi":11,"v8":"3.14"},"0.10.21":{"node_abi":11,"v8":"3.14"},"0.10.22":{"node_abi":11,"v8":"3.14"},"0.10.23":{"node_abi":11,"v8":"3.14"},"0.10.24":{"node_abi":11,"v8":"3.14"},"0.10.25":{"node_abi":11,"v8":"3.14"},"0.10.26":{"node_abi":11,"v8":"3.14"},"0.10.27":{"node_abi":11,"v8":"3.14"},"0.10.28":{"node_abi":11,"v8":"3.14"},"0.10.29":{"node_abi":11,"v8":"3.14"},"0.10.30":{"node_abi":11,"v8":"3.14"},"0.10.31":{"node_abi":11,"v8":"3.14"},"0.10.32":{"node_abi":11,"v8":"3.14"},"0.10.33":{"node_abi":11,"v8":"3.14"},"0.10.34":{"node_abi":11,"v8":"3.14"},"0.10.35":{"node_abi":11,"v8":"3.14"},"0.10.36":{"node_abi":11,"v8":"3.14"},"0.10.37":{"node_abi":11,"v8":"3.14"},"0.10.38":{"node_abi":11,"v8":"3.14"},"0.10.39":{"node_abi":11,"v8":"3.14"},"0.10.40":{"node_abi":11,"v8":"3.14"},"0.10.41":{"node_abi":11,"v8":"3.14"},"0.10.42":{"node_abi":11,"v8":"3.14"},"0.10.43":{"node_abi":11,"v8":"3.14"},"0.10.44":{"node_abi":11,"v8":"3.14"},"0.10.45":{"node_abi":11,"v8":"3.14"},"0.10.46":{"node_abi":11,"v8":"3.14"},"0.10.47":{"node_abi":11,"v8":"3.14"},"0.10.48":{"node_abi":11,"v8":"3.14"},"0.11.0":{"node_abi":12,"v8":"3.17"},"0.11.1":{"node_abi":12,"v8":"3.18"},"0.11.2":{"node_abi":12,"v8":"3.19"},"0.11.3":{"node_abi":12,"v8":"3.19"},"0.11.4":{"node_abi":12,"v8":"3.20"},"0.11.5":{"node_abi":12,"v8":"3.20"},"0.11.6":{"node_abi":12,"v8":"3.20"},"0.11.7":{"node_abi":12,"v8":"3.20"},"0.11.8":{"node_abi":13,"v8":"3.21"},"0.11.9":{"node_abi":13,"v8":"3.22"},"0.11.10":{"node_abi":13,"v8":"3.22"},"0.11.11":{"node_abi":14,"v8":"3.22"},"0.11.12":{"node_abi":14,"v8":"3.22"},"0.11.13":{"node_abi":14,"v8":"3.25"},"0.11.14":{"node_abi":14,"v8":"3.26"},"0.11.15":{"node_abi":14,"v8":"3.28"},"0.11.16":{"node_abi":14,"v8":"3.28"},"0.12.0":{"node_abi":14,"v8":"3.28"},"0.12.1":{"node_abi":14,"v8":"3.28"},"0.12.2":{"node_abi":14,"v8":"3.28"},"0.12.3":{"node_abi":14,"v8":"3.28"},"0.12.4":{"node_abi":14,"v8":"3.28"},"0.12.5":{"node_abi":14,"v8":"3.28"},"0.12.6":{"node_abi":14,"v8":"3.28"},"0.12.7":{"node_abi":14,"v8":"3.28"},"0.12.8":{"node_abi":14,"v8":"3.28"},"0.12.9":{"node_abi":14,"v8":"3.28"},"0.12.10":{"node_abi":14,"v8":"3.28"},"0.12.11":{"node_abi":14,"v8":"3.28"},"0.12.12":{"node_abi":14,"v8":"3.28"},"0.12.13":{"node_abi":14,"v8":"3.28"},"0.12.14":{"node_abi":14,"v8":"3.28"},"0.12.15":{"node_abi":14,"v8":"3.28"},"0.12.16":{"node_abi":14,"v8":"3.28"},"0.12.17":{"node_abi":14,"v8":"3.28"},"0.12.18":{"node_abi":14,"v8":"3.28"},"1.0.0":{"node_abi":42,"v8":"3.31"},"1.0.1":{"node_abi":42,"v8":"3.31"},"1.0.2":{"node_abi":42,"v8":"3.31"},"1.0.3":{"node_abi":42,"v8":"4.1"},"1.0.4":{"node_abi":42,"v8":"4.1"},"1.1.0":{"node_abi":43,"v8":"4.1"},"1.2.0":{"node_abi":43,"v8":"4.1"},"1.3.0":{"node_abi":43,"v8":"4.1"},"1.4.1":{"node_abi":43,"v8":"4.1"},"1.4.2":{"node_abi":43,"v8":"4.1"},"1.4.3":{"node_abi":43,"v8":"4.1"},"1.5.0":{"node_abi":43,"v8":"4.1"},"1.5.1":{"node_abi":43,"v8":"4.1"},"1.6.0":{"node_abi":43,"v8":"4.1"},"1.6.1":{"node_abi":43,"v8":"4.1"},"1.6.2":{"node_abi":43,"v8":"4.1"},"1.6.3":{"node_abi":43,"v8":"4.1"},"1.6.4":{"node_abi":43,"v8":"4.1"},"1.7.1":{"node_abi":43,"v8":"4.1"},"1.8.1":{"node_abi":43,"v8":"4.1"},"1.8.2":{"node_abi":43,"v8":"4.1"},"1.8.3":{"node_abi":43,"v8":"4.1"},"1.8.4":{"node_abi":43,"v8":"4.1"},"2.0.0":{"node_abi":44,"v8":"4.2"},"2.0.1":{"node_abi":44,"v8":"4.2"},"2.0.2":{"node_abi":44,"v8":"4.2"},"2.1.0":{"node_abi":44,"v8":"4.2"},"2.2.0":{"node_abi":44,"v8":"4.2"},"2.2.1":{"node_abi":44,"v8":"4.2"},"2.3.0":{"node_abi":44,"v8":"4.2"},"2.3.1":{"node_abi":44,"v8":"4.2"},"2.3.2":{"node_abi":44,"v8":"4.2"},"2.3.3":{"node_abi":44,"v8":"4.2"},"2.3.4":{"node_abi":44,"v8":"4.2"},"2.4.0":{"node_abi":44,"v8":"4.2"},"2.5.0":{"node_abi":44,"v8":"4.2"},"3.0.0":{"node_abi":45,"v8":"4.4"},"3.1.0":{"node_abi":45,"v8":"4.4"},"3.2.0":{"node_abi":45,"v8":"4.4"},"3.3.0":{"node_abi":45,"v8":"4.4"},"3.3.1":{"node_abi":45,"v8":"4.4"},"4.0.0":{"node_abi":46,"v8":"4.5"},"4.1.0":{"node_abi":46,"v8":"4.5"},"4.1.1":{"node_abi":46,"v8":"4.5"},"4.1.2":{"node_abi":46,"v8":"4.5"},"4.2.0":{"node_abi":46,"v8":"4.5"},"4.2.1":{"node_abi":46,"v8":"4.5"},"4.2.2":{"node_abi":46,"v8":"4.5"},"4.2.3":{"node_abi":46,"v8":"4.5"},"4.2.4":{"node_abi":46,"v8":"4.5"},"4.2.5":{"node_abi":46,"v8":"4.5"},"4.2.6":{"node_abi":46,"v8":"4.5"},"4.3.0":{"node_abi":46,"v8":"4.5"},"4.3.1":{"node_abi":46,"v8":"4.5"},"4.3.2":{"node_abi":46,"v8":"4.5"},"4.4.0":{"node_abi":46,"v8":"4.5"},"4.4.1":{"node_abi":46,"v8":"4.5"},"4.4.2":{"node_abi":46,"v8":"4.5"},"4.4.3":{"node_abi":46,"v8":"4.5"},"4.4.4":{"node_abi":46,"v8":"4.5"},"4.4.5":{"node_abi":46,"v8":"4.5"},"4.4.6":{"node_abi":46,"v8":"4.5"},"4.4.7":{"node_abi":46,"v8":"4.5"},"4.5.0":{"node_abi":46,"v8":"4.5"},"4.6.0":{"node_abi":46,"v8":"4.5"},"4.6.1":{"node_abi":46,"v8":"4.5"},"4.6.2":{"node_abi":46,"v8":"4.5"},"4.7.0":{"node_abi":46,"v8":"4.5"},"4.7.1":{"node_abi":46,"v8":"4.5"},"4.7.2":{"node_abi":46,"v8":"4.5"},"4.7.3":{"node_abi":46,"v8":"4.5"},"4.8.0":{"node_abi":46,"v8":"4.5"},"4.8.1":{"node_abi":46,"v8":"4.5"},"4.8.2":{"node_abi":46,"v8":"4.5"},"4.8.3":{"node_abi":46,"v8":"4.5"},"4.8.4":{"node_abi":46,"v8":"4.5"},"4.8.5":{"node_abi":46,"v8":"4.5"},"4.8.6":{"node_abi":46,"v8":"4.5"},"4.8.7":{"node_abi":46,"v8":"4.5"},"4.9.0":{"node_abi":46,"v8":"4.5"},"4.9.1":{"node_abi":46,"v8":"4.5"},"5.0.0":{"node_abi":47,"v8":"4.6"},"5.1.0":{"node_abi":47,"v8":"4.6"},"5.1.1":{"node_abi":47,"v8":"4.6"},"5.2.0":{"node_abi":47,"v8":"4.6"},"5.3.0":{"node_abi":47,"v8":"4.6"},"5.4.0":{"node_abi":47,"v8":"4.6"},"5.4.1":{"node_abi":47,"v8":"4.6"},"5.5.0":{"node_abi":47,"v8":"4.6"},"5.6.0":{"node_abi":47,"v8":"4.6"},"5.7.0":{"node_abi":47,"v8":"4.6"},"5.7.1":{"node_abi":47,"v8":"4.6"},"5.8.0":{"node_abi":47,"v8":"4.6"},"5.9.0":{"node_abi":47,"v8":"4.6"},"5.9.1":{"node_abi":47,"v8":"4.6"},"5.10.0":{"node_abi":47,"v8":"4.6"},"5.10.1":{"node_abi":47,"v8":"4.6"},"5.11.0":{"node_abi":47,"v8":"4.6"},"5.11.1":{"node_abi":47,"v8":"4.6"},"5.12.0":{"node_abi":47,"v8":"4.6"},"6.0.0":{"node_abi":48,"v8":"5.0"},"6.1.0":{"node_abi":48,"v8":"5.0"},"6.2.0":{"node_abi":48,"v8":"5.0"},"6.2.1":{"node_abi":48,"v8":"5.0"},"6.2.2":{"node_abi":48,"v8":"5.0"},"6.3.0":{"node_abi":48,"v8":"5.0"},"6.3.1":{"node_abi":48,"v8":"5.0"},"6.4.0":{"node_abi":48,"v8":"5.0"},"6.5.0":{"node_abi":48,"v8":"5.1"},"6.6.0":{"node_abi":48,"v8":"5.1"},"6.7.0":{"node_abi":48,"v8":"5.1"},"6.8.0":{"node_abi":48,"v8":"5.1"},"6.8.1":{"node_abi":48,"v8":"5.1"},"6.9.0":{"node_abi":48,"v8":"5.1"},"6.9.1":{"node_abi":48,"v8":"5.1"},"6.9.2":{"node_abi":48,"v8":"5.1"},"6.9.3":{"node_abi":48,"v8":"5.1"},"6.9.4":{"node_abi":48,"v8":"5.1"},"6.9.5":{"node_abi":48,"v8":"5.1"},"6.10.0":{"node_abi":48,"v8":"5.1"},"6.10.1":{"node_abi":48,"v8":"5.1"},"6.10.2":{"node_abi":48,"v8":"5.1"},"6.10.3":{"node_abi":48,"v8":"5.1"},"6.11.0":{"node_abi":48,"v8":"5.1"},"6.11.1":{"node_abi":48,"v8":"5.1"},"6.11.2":{"node_abi":48,"v8":"5.1"},"6.11.3":{"node_abi":48,"v8":"5.1"},"6.11.4":{"node_abi":48,"v8":"5.1"},"6.11.5":{"node_abi":48,"v8":"5.1"},"6.12.0":{"node_abi":48,"v8":"5.1"},"6.12.1":{"node_abi":48,"v8":"5.1"},"6.12.2":{"node_abi":48,"v8":"5.1"},"6.12.3":{"node_abi":48,"v8":"5.1"},"6.13.0":{"node_abi":48,"v8":"5.1"},"6.13.1":{"node_abi":48,"v8":"5.1"},"6.14.0":{"node_abi":48,"v8":"5.1"},"6.14.1":{"node_abi":48,"v8":"5.1"},"6.14.2":{"node_abi":48,"v8":"5.1"},"6.14.3":{"node_abi":48,"v8":"5.1"},"6.14.4":{"node_abi":48,"v8":"5.1"},"6.15.0":{"node_abi":48,"v8":"5.1"},"6.15.1":{"node_abi":48,"v8":"5.1"},"6.16.0":{"node_abi":48,"v8":"5.1"},"6.17.0":{"node_abi":48,"v8":"5.1"},"6.17.1":{"node_abi":48,"v8":"5.1"},"7.0.0":{"node_abi":51,"v8":"5.4"},"7.1.0":{"node_abi":51,"v8":"5.4"},"7.2.0":{"node_abi":51,"v8":"5.4"},"7.2.1":{"node_abi":51,"v8":"5.4"},"7.3.0":{"node_abi":51,"v8":"5.4"},"7.4.0":{"node_abi":51,"v8":"5.4"},"7.5.0":{"node_abi":51,"v8":"5.4"},"7.6.0":{"node_abi":51,"v8":"5.5"},"7.7.0":{"node_abi":51,"v8":"5.5"},"7.7.1":{"node_abi":51,"v8":"5.5"},"7.7.2":{"node_abi":51,"v8":"5.5"},"7.7.3":{"node_abi":51,"v8":"5.5"},"7.7.4":{"node_abi":51,"v8":"5.5"},"7.8.0":{"node_abi":51,"v8":"5.5"},"7.9.0":{"node_abi":51,"v8":"5.5"},"7.10.0":{"node_abi":51,"v8":"5.5"},"7.10.1":{"node_abi":51,"v8":"5.5"},"8.0.0":{"node_abi":57,"v8":"5.8"},"8.1.0":{"node_abi":57,"v8":"5.8"},"8.1.1":{"node_abi":57,"v8":"5.8"},"8.1.2":{"node_abi":57,"v8":"5.8"},"8.1.3":{"node_abi":57,"v8":"5.8"},"8.1.4":{"node_abi":57,"v8":"5.8"},"8.2.0":{"node_abi":57,"v8":"5.8"},"8.2.1":{"node_abi":57,"v8":"5.8"},"8.3.0":{"node_abi":57,"v8":"6.0"},"8.4.0":{"node_abi":57,"v8":"6.0"},"8.5.0":{"node_abi":57,"v8":"6.0"},"8.6.0":{"node_abi":57,"v8":"6.0"},"8.7.0":{"node_abi":57,"v8":"6.1"},"8.8.0":{"node_abi":57,"v8":"6.1"},"8.8.1":{"node_abi":57,"v8":"6.1"},"8.9.0":{"node_abi":57,"v8":"6.1"},"8.9.1":{"node_abi":57,"v8":"6.1"},"8.9.2":{"node_abi":57,"v8":"6.1"},"8.9.3":{"node_abi":57,"v8":"6.1"},"8.9.4":{"node_abi":57,"v8":"6.1"},"8.10.0":{"node_abi":57,"v8":"6.2"},"8.11.0":{"node_abi":57,"v8":"6.2"},"8.11.1":{"node_abi":57,"v8":"6.2"},"8.11.2":{"node_abi":57,"v8":"6.2"},"8.11.3":{"node_abi":57,"v8":"6.2"},"8.11.4":{"node_abi":57,"v8":"6.2"},"8.12.0":{"node_abi":57,"v8":"6.2"},"8.13.0":{"node_abi":57,"v8":"6.2"},"8.14.0":{"node_abi":57,"v8":"6.2"},"8.14.1":{"node_abi":57,"v8":"6.2"},"8.15.0":{"node_abi":57,"v8":"6.2"},"8.15.1":{"node_abi":57,"v8":"6.2"},"8.16.0":{"node_abi":57,"v8":"6.2"},"8.16.1":{"node_abi":57,"v8":"6.2"},"8.16.2":{"node_abi":57,"v8":"6.2"},"8.17.0":{"node_abi":57,"v8":"6.2"},"9.0.0":{"node_abi":59,"v8":"6.2"},"9.1.0":{"node_abi":59,"v8":"6.2"},"9.2.0":{"node_abi":59,"v8":"6.2"},"9.2.1":{"node_abi":59,"v8":"6.2"},"9.3.0":{"node_abi":59,"v8":"6.2"},"9.4.0":{"node_abi":59,"v8":"6.2"},"9.5.0":{"node_abi":59,"v8":"6.2"},"9.6.0":{"node_abi":59,"v8":"6.2"},"9.6.1":{"node_abi":59,"v8":"6.2"},"9.7.0":{"node_abi":59,"v8":"6.2"},"9.7.1":{"node_abi":59,"v8":"6.2"},"9.8.0":{"node_abi":59,"v8":"6.2"},"9.9.0":{"node_abi":59,"v8":"6.2"},"9.10.0":{"node_abi":59,"v8":"6.2"},"9.10.1":{"node_abi":59,"v8":"6.2"},"9.11.0":{"node_abi":59,"v8":"6.2"},"9.11.1":{"node_abi":59,"v8":"6.2"},"9.11.2":{"node_abi":59,"v8":"6.2"},"10.0.0":{"node_abi":64,"v8":"6.6"},"10.1.0":{"node_abi":64,"v8":"6.6"},"10.2.0":{"node_abi":64,"v8":"6.6"},"10.2.1":{"node_abi":64,"v8":"6.6"},"10.3.0":{"node_abi":64,"v8":"6.6"},"10.4.0":{"node_abi":64,"v8":"6.7"},"10.4.1":{"node_abi":64,"v8":"6.7"},"10.5.0":{"node_abi":64,"v8":"6.7"},"10.6.0":{"node_abi":64,"v8":"6.7"},"10.7.0":{"node_abi":64,"v8":"6.7"},"10.8.0":{"node_abi":64,"v8":"6.7"},"10.9.0":{"node_abi":64,"v8":"6.8"},"10.10.0":{"node_abi":64,"v8":"6.8"},"10.11.0":{"node_abi":64,"v8":"6.8"},"10.12.0":{"node_abi":64,"v8":"6.8"},"10.13.0":{"node_abi":64,"v8":"6.8"},"10.14.0":{"node_abi":64,"v8":"6.8"},"10.14.1":{"node_abi":64,"v8":"6.8"},"10.14.2":{"node_abi":64,"v8":"6.8"},"10.15.0":{"node_abi":64,"v8":"6.8"},"10.15.1":{"node_abi":64,"v8":"6.8"},"10.15.2":{"node_abi":64,"v8":"6.8"},"10.15.3":{"node_abi":64,"v8":"6.8"},"10.16.0":{"node_abi":64,"v8":"6.8"},"10.16.1":{"node_abi":64,"v8":"6.8"},"10.16.2":{"node_abi":64,"v8":"6.8"},"10.16.3":{"node_abi":64,"v8":"6.8"},"10.17.0":{"node_abi":64,"v8":"6.8"},"10.18.0":{"node_abi":64,"v8":"6.8"},"10.18.1":{"node_abi":64,"v8":"6.8"},"10.19.0":{"node_abi":64,"v8":"6.8"},"10.20.0":{"node_abi":64,"v8":"6.8"},"10.20.1":{"node_abi":64,"v8":"6.8"},"10.21.0":{"node_abi":64,"v8":"6.8"},"10.22.0":{"node_abi":64,"v8":"6.8"},"10.22.1":{"node_abi":64,"v8":"6.8"},"10.23.0":{"node_abi":64,"v8":"6.8"},"10.23.1":{"node_abi":64,"v8":"6.8"},"10.23.2":{"node_abi":64,"v8":"6.8"},"10.23.3":{"node_abi":64,"v8":"6.8"},"10.24.0":{"node_abi":64,"v8":"6.8"},"10.24.1":{"node_abi":64,"v8":"6.8"},"11.0.0":{"node_abi":67,"v8":"7.0"},"11.1.0":{"node_abi":67,"v8":"7.0"},"11.2.0":{"node_abi":67,"v8":"7.0"},"11.3.0":{"node_abi":67,"v8":"7.0"},"11.4.0":{"node_abi":67,"v8":"7.0"},"11.5.0":{"node_abi":67,"v8":"7.0"},"11.6.0":{"node_abi":67,"v8":"7.0"},"11.7.0":{"node_abi":67,"v8":"7.0"},"11.8.0":{"node_abi":67,"v8":"7.0"},"11.9.0":{"node_abi":67,"v8":"7.0"},"11.10.0":{"node_abi":67,"v8":"7.0"},"11.10.1":{"node_abi":67,"v8":"7.0"},"11.11.0":{"node_abi":67,"v8":"7.0"},"11.12.0":{"node_abi":67,"v8":"7.0"},"11.13.0":{"node_abi":67,"v8":"7.0"},"11.14.0":{"node_abi":67,"v8":"7.0"},"11.15.0":{"node_abi":67,"v8":"7.0"},"12.0.0":{"node_abi":72,"v8":"7.4"},"12.1.0":{"node_abi":72,"v8":"7.4"},"12.2.0":{"node_abi":72,"v8":"7.4"},"12.3.0":{"node_abi":72,"v8":"7.4"},"12.3.1":{"node_abi":72,"v8":"7.4"},"12.4.0":{"node_abi":72,"v8":"7.4"},"12.5.0":{"node_abi":72,"v8":"7.5"},"12.6.0":{"node_abi":72,"v8":"7.5"},"12.7.0":{"node_abi":72,"v8":"7.5"},"12.8.0":{"node_abi":72,"v8":"7.5"},"12.8.1":{"node_abi":72,"v8":"7.5"},"12.9.0":{"node_abi":72,"v8":"7.6"},"12.9.1":{"node_abi":72,"v8":"7.6"},"12.10.0":{"node_abi":72,"v8":"7.6"},"12.11.0":{"node_abi":72,"v8":"7.7"},"12.11.1":{"node_abi":72,"v8":"7.7"},"12.12.0":{"node_abi":72,"v8":"7.7"},"12.13.0":{"node_abi":72,"v8":"7.7"},"12.13.1":{"node_abi":72,"v8":"7.7"},"12.14.0":{"node_abi":72,"v8":"7.7"},"12.14.1":{"node_abi":72,"v8":"7.7"},"12.15.0":{"node_abi":72,"v8":"7.7"},"12.16.0":{"node_abi":72,"v8":"7.8"},"12.16.1":{"node_abi":72,"v8":"7.8"},"12.16.2":{"node_abi":72,"v8":"7.8"},"12.16.3":{"node_abi":72,"v8":"7.8"},"12.17.0":{"node_abi":72,"v8":"7.8"},"12.18.0":{"node_abi":72,"v8":"7.8"},"12.18.1":{"node_abi":72,"v8":"7.8"},"12.18.2":{"node_abi":72,"v8":"7.8"},"12.18.3":{"node_abi":72,"v8":"7.8"},"12.18.4":{"node_abi":72,"v8":"7.8"},"12.19.0":{"node_abi":72,"v8":"7.8"},"12.19.1":{"node_abi":72,"v8":"7.8"},"12.20.0":{"node_abi":72,"v8":"7.8"},"12.20.1":{"node_abi":72,"v8":"7.8"},"12.20.2":{"node_abi":72,"v8":"7.8"},"12.21.0":{"node_abi":72,"v8":"7.8"},"12.22.0":{"node_abi":72,"v8":"7.8"},"12.22.1":{"node_abi":72,"v8":"7.8"},"13.0.0":{"node_abi":79,"v8":"7.8"},"13.0.1":{"node_abi":79,"v8":"7.8"},"13.1.0":{"node_abi":79,"v8":"7.8"},"13.2.0":{"node_abi":79,"v8":"7.9"},"13.3.0":{"node_abi":79,"v8":"7.9"},"13.4.0":{"node_abi":79,"v8":"7.9"},"13.5.0":{"node_abi":79,"v8":"7.9"},"13.6.0":{"node_abi":79,"v8":"7.9"},"13.7.0":{"node_abi":79,"v8":"7.9"},"13.8.0":{"node_abi":79,"v8":"7.9"},"13.9.0":{"node_abi":79,"v8":"7.9"},"13.10.0":{"node_abi":79,"v8":"7.9"},"13.10.1":{"node_abi":79,"v8":"7.9"},"13.11.0":{"node_abi":79,"v8":"7.9"},"13.12.0":{"node_abi":79,"v8":"7.9"},"13.13.0":{"node_abi":79,"v8":"7.9"},"13.14.0":{"node_abi":79,"v8":"7.9"},"14.0.0":{"node_abi":83,"v8":"8.1"},"14.1.0":{"node_abi":83,"v8":"8.1"},"14.2.0":{"node_abi":83,"v8":"8.1"},"14.3.0":{"node_abi":83,"v8":"8.1"},"14.4.0":{"node_abi":83,"v8":"8.1"},"14.5.0":{"node_abi":83,"v8":"8.3"},"14.6.0":{"node_abi":83,"v8":"8.4"},"14.7.0":{"node_abi":83,"v8":"8.4"},"14.8.0":{"node_abi":83,"v8":"8.4"},"14.9.0":{"node_abi":83,"v8":"8.4"},"14.10.0":{"node_abi":83,"v8":"8.4"},"14.10.1":{"node_abi":83,"v8":"8.4"},"14.11.0":{"node_abi":83,"v8":"8.4"},"14.12.0":{"node_abi":83,"v8":"8.4"},"14.13.0":{"node_abi":83,"v8":"8.4"},"14.13.1":{"node_abi":83,"v8":"8.4"},"14.14.0":{"node_abi":83,"v8":"8.4"},"14.15.0":{"node_abi":83,"v8":"8.4"},"14.15.1":{"node_abi":83,"v8":"8.4"},"14.15.2":{"node_abi":83,"v8":"8.4"},"14.15.3":{"node_abi":83,"v8":"8.4"},"14.15.4":{"node_abi":83,"v8":"8.4"},"14.15.5":{"node_abi":83,"v8":"8.4"},"14.16.0":{"node_abi":83,"v8":"8.4"},"14.16.1":{"node_abi":83,"v8":"8.4"},"15.0.0":{"node_abi":88,"v8":"8.6"},"15.0.1":{"node_abi":88,"v8":"8.6"},"15.1.0":{"node_abi":88,"v8":"8.6"},"15.2.0":{"node_abi":88,"v8":"8.6"},"15.2.1":{"node_abi":88,"v8":"8.6"},"15.3.0":{"node_abi":88,"v8":"8.6"},"15.4.0":{"node_abi":88,"v8":"8.6"},"15.5.0":{"node_abi":88,"v8":"8.6"},"15.5.1":{"node_abi":88,"v8":"8.6"},"15.6.0":{"node_abi":88,"v8":"8.6"},"15.7.0":{"node_abi":88,"v8":"8.6"},"15.8.0":{"node_abi":88,"v8":"8.6"},"15.9.0":{"node_abi":88,"v8":"8.6"},"15.10.0":{"node_abi":88,"v8":"8.6"},"15.11.0":{"node_abi":88,"v8":"8.6"},"15.12.0":{"node_abi":88,"v8":"8.6"},"15.13.0":{"node_abi":88,"v8":"8.6"},"15.14.0":{"node_abi":88,"v8":"8.6"},"16.0.0":{"node_abi":93,"v8":"9.0"}}')},7399:e=>{"use strict";e.exports=JSON.parse('{"name":"@mapbox/node-pre-gyp","description":"Node.js native addon binary install tool","version":"1.0.5","keywords":["native","addon","module","c","c++","bindings","binary"],"license":"BSD-3-Clause","author":"Dane Springmeyer ","repository":{"type":"git","url":"git://github.com/mapbox/node-pre-gyp.git"},"bin":"./bin/node-pre-gyp","main":"./lib/node-pre-gyp.js","dependencies":{"detect-libc":"^1.0.3","https-proxy-agent":"^5.0.0","make-dir":"^3.1.0","node-fetch":"^2.6.1","nopt":"^5.0.0","npmlog":"^4.1.2","rimraf":"^3.0.2","semver":"^7.3.4","tar":"^6.1.0"},"devDependencies":{"@mapbox/cloudfriend":"^4.6.0","@mapbox/eslint-config-mapbox":"^3.0.0","action-walk":"^2.2.0","aws-sdk":"^2.840.0","codecov":"^3.8.1","eslint":"^7.18.0","eslint-plugin-node":"^11.1.0","mock-aws-s3":"^4.0.1","nock":"^12.0.3","node-addon-api":"^3.1.0","nyc":"^15.1.0","tape":"^5.2.2","tar-fs":"^2.1.1"},"nyc":{"all":true,"skip-full":false,"exclude":["test/**"]},"scripts":{"coverage":"nyc --all --include index.js --include lib/ npm test","upload-coverage":"nyc report --reporter json && codecov --clear --flags=unit --file=./coverage/coverage-final.json","lint":"eslint bin/node-pre-gyp lib/*js lib/util/*js test/*js scripts/*js","fix":"npm run lint -- --fix","update-crosswalk":"node scripts/abi_crosswalk.js","test":"tape test/*test.js"}}')}};var __webpack_module_cache__={};function __nccwpck_require__(e){var t=__webpack_module_cache__[e];if(t!==undefined){return t.exports}var r=__webpack_module_cache__[e]={exports:{}};var s=true;try{__webpack_modules__[e].call(r.exports,r,r.exports,__nccwpck_require__);s=false}finally{if(s)delete __webpack_module_cache__[e]}return r.exports}if(typeof __nccwpck_require__!=="undefined")__nccwpck_require__.ab=__dirname+"/";var __webpack_exports__=__nccwpck_require__(6223);module.exports=__webpack_exports__})(); \ No newline at end of file +*/var t=Object.getOwnPropertySymbols;var r=Object.prototype.hasOwnProperty;var s=Object.prototype.propertyIsEnumerable;function toObject(e){if(e===null||e===undefined){throw new TypeError("Object.assign cannot be called with null or undefined")}return Object(e)}function shouldUseNative(){try{if(!Object.assign){return false}var e=new String("abc");e[5]="de";if(Object.getOwnPropertyNames(e)[0]==="5"){return false}var t={};for(var r=0;r<10;r++){t["_"+String.fromCharCode(r)]=r}var s=Object.getOwnPropertyNames(t).map((function(e){return t[e]}));if(s.join("")!=="0123456789"){return false}var a={};"abcdefghijklmnopqrst".split("").forEach((function(e){a[e]=e}));if(Object.keys(Object.assign({},a)).join("")!=="abcdefghijklmnopqrst"){return false}return true}catch(e){return false}}e.exports=shouldUseNative()?Object.assign:function(e,a){var o;var u=toObject(e);var c;for(var f=1;f{"use strict";e.exports=r(7250)},7798:(e,t,r)=>{"use strict";const s=r(1017);const a="\\\\/";const o=`[^${a}]`;const u="\\.";const c="\\+";const f="\\?";const d="\\/";const p="(?=.)";const h="[^/]";const v=`(?:${d}|$)`;const D=`(?:^|${d})`;const g=`${u}{1,2}${v}`;const y=`(?!${u})`;const m=`(?!${D}${g})`;const _=`(?!${u}{0,1}${v})`;const E=`(?!${g})`;const w=`[^.${d}]`;const x=`${h}*?`;const F={DOT_LITERAL:u,PLUS_LITERAL:c,QMARK_LITERAL:f,SLASH_LITERAL:d,ONE_CHAR:p,QMARK:h,END_ANCHOR:v,DOTS_SLASH:g,NO_DOT:y,NO_DOTS:m,NO_DOT_SLASH:_,NO_DOTS_SLASH:E,QMARK_NO_DOT:w,STAR:x,START_ANCHOR:D};const C={...F,SLASH_LITERAL:`[${a}]`,QMARK:o,STAR:`${o}*?`,DOTS_SLASH:`${u}{1,2}(?:[${a}]|$)`,NO_DOT:`(?!${u})`,NO_DOTS:`(?!(?:^|[${a}])${u}{1,2}(?:[${a}]|$))`,NO_DOT_SLASH:`(?!${u}{0,1}(?:[${a}]|$))`,NO_DOTS_SLASH:`(?!${u}{1,2}(?:[${a}]|$))`,QMARK_NO_DOT:`[^.${a}]`,START_ANCHOR:`(?:^|[${a}])`,END_ANCHOR:`(?:[${a}]|$)`};const S={alnum:"a-zA-Z0-9",alpha:"a-zA-Z",ascii:"\\x00-\\x7F",blank:" \\t",cntrl:"\\x00-\\x1F\\x7F",digit:"0-9",graph:"\\x21-\\x7E",lower:"a-z",print:"\\x20-\\x7E ",punct:"\\-!\"#$%&'()\\*+,./:;<=>?@[\\]^_`{|}~",space:" \\t\\r\\n\\v\\f",upper:"A-Z",word:"A-Za-z0-9_",xdigit:"A-Fa-f0-9"};e.exports={MAX_LENGTH:1024*64,POSIX_REGEX_SOURCE:S,REGEX_BACKSLASH:/\\(?![*+?^${}(|)[\]])/g,REGEX_NON_SPECIAL_CHARS:/^[^@![\].,$*+?^{}()|\\/]+/,REGEX_SPECIAL_CHARS:/[-*+?.^${}(|)[\]]/,REGEX_SPECIAL_CHARS_BACKREF:/(\\?)((\W)(\3*))/g,REGEX_SPECIAL_CHARS_GLOBAL:/([-*+?.^${}(|)[\]])/g,REGEX_REMOVE_BACKSLASH:/(?:\[.*?[^\\]\]|\\(?=.))/g,REPLACEMENTS:{"***":"*","**/**":"**","**/**/**":"**"},CHAR_0:48,CHAR_9:57,CHAR_UPPERCASE_A:65,CHAR_LOWERCASE_A:97,CHAR_UPPERCASE_Z:90,CHAR_LOWERCASE_Z:122,CHAR_LEFT_PARENTHESES:40,CHAR_RIGHT_PARENTHESES:41,CHAR_ASTERISK:42,CHAR_AMPERSAND:38,CHAR_AT:64,CHAR_BACKWARD_SLASH:92,CHAR_CARRIAGE_RETURN:13,CHAR_CIRCUMFLEX_ACCENT:94,CHAR_COLON:58,CHAR_COMMA:44,CHAR_DOT:46,CHAR_DOUBLE_QUOTE:34,CHAR_EQUAL:61,CHAR_EXCLAMATION_MARK:33,CHAR_FORM_FEED:12,CHAR_FORWARD_SLASH:47,CHAR_GRAVE_ACCENT:96,CHAR_HASH:35,CHAR_HYPHEN_MINUS:45,CHAR_LEFT_ANGLE_BRACKET:60,CHAR_LEFT_CURLY_BRACE:123,CHAR_LEFT_SQUARE_BRACKET:91,CHAR_LINE_FEED:10,CHAR_NO_BREAK_SPACE:160,CHAR_PERCENT:37,CHAR_PLUS:43,CHAR_QUESTION_MARK:63,CHAR_RIGHT_ANGLE_BRACKET:62,CHAR_RIGHT_CURLY_BRACE:125,CHAR_RIGHT_SQUARE_BRACKET:93,CHAR_SEMICOLON:59,CHAR_SINGLE_QUOTE:39,CHAR_SPACE:32,CHAR_TAB:9,CHAR_UNDERSCORE:95,CHAR_VERTICAL_LINE:124,CHAR_ZERO_WIDTH_NOBREAK_SPACE:65279,SEP:s.sep,extglobChars(e){return{"!":{type:"negate",open:"(?:(?!(?:",close:`))${e.STAR})`},"?":{type:"qmark",open:"(?:",close:")?"},"+":{type:"plus",open:"(?:",close:")+"},"*":{type:"star",open:"(?:",close:")*"},"@":{type:"at",open:"(?:",close:")"}}},globChars(e){return e===true?C:F}}},3632:(e,t,r)=>{"use strict";const s=r(7798);const a=r(5502);const{MAX_LENGTH:o,POSIX_REGEX_SOURCE:u,REGEX_NON_SPECIAL_CHARS:c,REGEX_SPECIAL_CHARS_BACKREF:f,REPLACEMENTS:d}=s;const expandRange=(e,t)=>{if(typeof t.expandRange==="function"){return t.expandRange(...e,t)}e.sort();const r=`[${e.join("-")}]`;try{new RegExp(r)}catch(t){return e.map((e=>a.escapeRegex(e))).join("..")}return r};const syntaxError=(e,t)=>`Missing ${e}: "${t}" - use "\\\\${t}" to match literal characters`;const parse=(e,t)=>{if(typeof e!=="string"){throw new TypeError("Expected a string")}e=d[e]||e;const r={...t};const p=typeof r.maxLength==="number"?Math.min(o,r.maxLength):o;let h=e.length;if(h>p){throw new SyntaxError(`Input length: ${h}, exceeds maximum allowed length: ${p}`)}const v={type:"bos",value:"",output:r.prepend||""};const D=[v];const g=r.capture?"":"?:";const y=a.isWindows(t);const m=s.globChars(y);const _=s.extglobChars(m);const{DOT_LITERAL:E,PLUS_LITERAL:w,SLASH_LITERAL:x,ONE_CHAR:F,DOTS_SLASH:C,NO_DOT:S,NO_DOT_SLASH:k,NO_DOTS_SLASH:A,QMARK:R,QMARK_NO_DOT:O,STAR:T,START_ANCHOR:j}=m;const globstar=e=>`(${g}(?:(?!${j}${e.dot?C:E}).)*?)`;const B=r.dot?"":S;const L=r.dot?R:O;let N=r.bash===true?globstar(r):T;if(r.capture){N=`(${N})`}if(typeof r.noext==="boolean"){r.noextglob=r.noext}const I={input:e,index:-1,start:0,dot:r.dot===true,consumed:"",output:"",prefix:"",backtrack:false,negated:false,brackets:0,braces:0,parens:0,quotes:0,globstar:false,tokens:D};e=a.removePrefix(e,I);h=e.length;const P=[];const W=[];const M=[];let $=v;let q;const eos=()=>I.index===h-1;const U=I.peek=(t=1)=>e[I.index+t];const G=I.advance=()=>e[++I.index]||"";const remaining=()=>e.slice(I.index+1);const consume=(e="",t=0)=>{I.consumed+=e;I.index+=t};const append=e=>{I.output+=e.output!=null?e.output:e.value;consume(e.value)};const negate=()=>{let e=1;while(U()==="!"&&(U(2)!=="("||U(3)==="?")){G();I.start++;e++}if(e%2===0){return false}I.negated=true;I.start++;return true};const increment=e=>{I[e]++;M.push(e)};const decrement=e=>{I[e]--;M.pop()};const push=e=>{if($.type==="globstar"){const t=I.braces>0&&(e.type==="comma"||e.type==="brace");const r=e.extglob===true||P.length&&(e.type==="pipe"||e.type==="paren");if(e.type!=="slash"&&e.type!=="paren"&&!t&&!r){I.output=I.output.slice(0,-$.output.length);$.type="star";$.value="*";$.output=N;I.output+=$.output}}if(P.length&&e.type!=="paren"){P[P.length-1].inner+=e.value}if(e.value||e.output)append(e);if($&&$.type==="text"&&e.type==="text"){$.value+=e.value;$.output=($.output||"")+e.value;return}e.prev=$;D.push(e);$=e};const extglobOpen=(e,t)=>{const s={..._[t],conditions:1,inner:""};s.prev=$;s.parens=I.parens;s.output=I.output;const a=(r.capture?"(":"")+s.open;increment("parens");push({type:e,value:t,output:I.output?"":F});push({type:"paren",extglob:true,value:G(),output:a});P.push(s)};const extglobClose=e=>{let s=e.close+(r.capture?")":"");let a;if(e.type==="negate"){let o=N;if(e.inner&&e.inner.length>1&&e.inner.includes("/")){o=globstar(r)}if(o!==N||eos()||/^\)+$/.test(remaining())){s=e.close=`)$))${o}`}if(e.inner.includes("*")&&(a=remaining())&&/^\.[^\\/.]+$/.test(a)){const r=parse(a,{...t,fastpaths:false}).output;s=e.close=`)${r})${o})`}if(e.prev.type==="bos"){I.negatedExtglob=true}}push({type:"paren",extglob:true,value:q,output:s});decrement("parens")};if(r.fastpaths!==false&&!/(^[*!]|[/()[\]{}"])/.test(e)){let s=false;let o=e.replace(f,((e,t,r,a,o,u)=>{if(a==="\\"){s=true;return e}if(a==="?"){if(t){return t+a+(o?R.repeat(o.length):"")}if(u===0){return L+(o?R.repeat(o.length):"")}return R.repeat(r.length)}if(a==="."){return E.repeat(r.length)}if(a==="*"){if(t){return t+a+(o?N:"")}return N}return t?e:`\\${e}`}));if(s===true){if(r.unescape===true){o=o.replace(/\\/g,"")}else{o=o.replace(/\\+/g,(e=>e.length%2===0?"\\\\":e?"\\":""))}}if(o===e&&r.contains===true){I.output=e;return I}I.output=a.wrapOutput(o,I,t);return I}while(!eos()){q=G();if(q==="\0"){continue}if(q==="\\"){const e=U();if(e==="/"&&r.bash!==true){continue}if(e==="."||e===";"){continue}if(!e){q+="\\";push({type:"text",value:q});continue}const t=/^\\+/.exec(remaining());let s=0;if(t&&t[0].length>2){s=t[0].length;I.index+=s;if(s%2!==0){q+="\\"}}if(r.unescape===true){q=G()}else{q+=G()}if(I.brackets===0){push({type:"text",value:q});continue}}if(I.brackets>0&&(q!=="]"||$.value==="["||$.value==="[^")){if(r.posix!==false&&q===":"){const e=$.value.slice(1);if(e.includes("[")){$.posix=true;if(e.includes(":")){const e=$.value.lastIndexOf("[");const t=$.value.slice(0,e);const r=$.value.slice(e+2);const s=u[r];if(s){$.value=t+s;I.backtrack=true;G();if(!v.output&&D.indexOf($)===1){v.output=F}continue}}}}if(q==="["&&U()!==":"||q==="-"&&U()==="]"){q=`\\${q}`}if(q==="]"&&($.value==="["||$.value==="[^")){q=`\\${q}`}if(r.posix===true&&q==="!"&&$.value==="["){q="^"}$.value+=q;append({value:q});continue}if(I.quotes===1&&q!=='"'){q=a.escapeRegex(q);$.value+=q;append({value:q});continue}if(q==='"'){I.quotes=I.quotes===1?0:1;if(r.keepQuotes===true){push({type:"text",value:q})}continue}if(q==="("){increment("parens");push({type:"paren",value:q});continue}if(q===")"){if(I.parens===0&&r.strictBrackets===true){throw new SyntaxError(syntaxError("opening","("))}const e=P[P.length-1];if(e&&I.parens===e.parens+1){extglobClose(P.pop());continue}push({type:"paren",value:q,output:I.parens?")":"\\)"});decrement("parens");continue}if(q==="["){if(r.nobracket===true||!remaining().includes("]")){if(r.nobracket!==true&&r.strictBrackets===true){throw new SyntaxError(syntaxError("closing","]"))}q=`\\${q}`}else{increment("brackets")}push({type:"bracket",value:q});continue}if(q==="]"){if(r.nobracket===true||$&&$.type==="bracket"&&$.value.length===1){push({type:"text",value:q,output:`\\${q}`});continue}if(I.brackets===0){if(r.strictBrackets===true){throw new SyntaxError(syntaxError("opening","["))}push({type:"text",value:q,output:`\\${q}`});continue}decrement("brackets");const e=$.value.slice(1);if($.posix!==true&&e[0]==="^"&&!e.includes("/")){q=`/${q}`}$.value+=q;append({value:q});if(r.literalBrackets===false||a.hasRegexChars(e)){continue}const t=a.escapeRegex($.value);I.output=I.output.slice(0,-$.value.length);if(r.literalBrackets===true){I.output+=t;$.value=t;continue}$.value=`(${g}${t}|${$.value})`;I.output+=$.value;continue}if(q==="{"&&r.nobrace!==true){increment("braces");const e={type:"brace",value:q,output:"(",outputIndex:I.output.length,tokensIndex:I.tokens.length};W.push(e);push(e);continue}if(q==="}"){const e=W[W.length-1];if(r.nobrace===true||!e){push({type:"text",value:q,output:q});continue}let t=")";if(e.dots===true){const e=D.slice();const s=[];for(let t=e.length-1;t>=0;t--){D.pop();if(e[t].type==="brace"){break}if(e[t].type!=="dots"){s.unshift(e[t].value)}}t=expandRange(s,r);I.backtrack=true}if(e.comma!==true&&e.dots!==true){const r=I.output.slice(0,e.outputIndex);const s=I.tokens.slice(e.tokensIndex);e.value=e.output="\\{";q=t="\\}";I.output=r;for(const e of s){I.output+=e.output||e.value}}push({type:"brace",value:q,output:t});decrement("braces");W.pop();continue}if(q==="|"){if(P.length>0){P[P.length-1].conditions++}push({type:"text",value:q});continue}if(q===","){let e=q;const t=W[W.length-1];if(t&&M[M.length-1]==="braces"){t.comma=true;e="|"}push({type:"comma",value:q,output:e});continue}if(q==="/"){if($.type==="dot"&&I.index===I.start+1){I.start=I.index+1;I.consumed="";I.output="";D.pop();$=v;continue}push({type:"slash",value:q,output:x});continue}if(q==="."){if(I.braces>0&&$.type==="dot"){if($.value===".")$.output=E;const e=W[W.length-1];$.type="dots";$.output+=q;$.value+=q;e.dots=true;continue}if(I.braces+I.parens===0&&$.type!=="bos"&&$.type!=="slash"){push({type:"text",value:q,output:E});continue}push({type:"dot",value:q,output:E});continue}if(q==="?"){const e=$&&$.value==="(";if(!e&&r.noextglob!==true&&U()==="("&&U(2)!=="?"){extglobOpen("qmark",q);continue}if($&&$.type==="paren"){const e=U();let t=q;if(e==="<"&&!a.supportsLookbehinds()){throw new Error("Node.js v10 or higher is required for regex lookbehinds")}if($.value==="("&&!/[!=<:]/.test(e)||e==="<"&&!/<([!=]|\w+>)/.test(remaining())){t=`\\${q}`}push({type:"text",value:q,output:t});continue}if(r.dot!==true&&($.type==="slash"||$.type==="bos")){push({type:"qmark",value:q,output:O});continue}push({type:"qmark",value:q,output:R});continue}if(q==="!"){if(r.noextglob!==true&&U()==="("){if(U(2)!=="?"||!/[!=<:]/.test(U(3))){extglobOpen("negate",q);continue}}if(r.nonegate!==true&&I.index===0){negate();continue}}if(q==="+"){if(r.noextglob!==true&&U()==="("&&U(2)!=="?"){extglobOpen("plus",q);continue}if($&&$.value==="("||r.regex===false){push({type:"plus",value:q,output:w});continue}if($&&($.type==="bracket"||$.type==="paren"||$.type==="brace")||I.parens>0){push({type:"plus",value:q});continue}push({type:"plus",value:w});continue}if(q==="@"){if(r.noextglob!==true&&U()==="("&&U(2)!=="?"){push({type:"at",extglob:true,value:q,output:""});continue}push({type:"text",value:q});continue}if(q!=="*"){if(q==="$"||q==="^"){q=`\\${q}`}const e=c.exec(remaining());if(e){q+=e[0];I.index+=e[0].length}push({type:"text",value:q});continue}if($&&($.type==="globstar"||$.star===true)){$.type="star";$.star=true;$.value+=q;$.output=N;I.backtrack=true;I.globstar=true;consume(q);continue}let t=remaining();if(r.noextglob!==true&&/^\([^?]/.test(t)){extglobOpen("star",q);continue}if($.type==="star"){if(r.noglobstar===true){consume(q);continue}const s=$.prev;const a=s.prev;const o=s.type==="slash"||s.type==="bos";const u=a&&(a.type==="star"||a.type==="globstar");if(r.bash===true&&(!o||t[0]&&t[0]!=="/")){push({type:"star",value:q,output:""});continue}const c=I.braces>0&&(s.type==="comma"||s.type==="brace");const f=P.length&&(s.type==="pipe"||s.type==="paren");if(!o&&s.type!=="paren"&&!c&&!f){push({type:"star",value:q,output:""});continue}while(t.slice(0,3)==="/**"){const r=e[I.index+4];if(r&&r!=="/"){break}t=t.slice(3);consume("/**",3)}if(s.type==="bos"&&eos()){$.type="globstar";$.value+=q;$.output=globstar(r);I.output=$.output;I.globstar=true;consume(q);continue}if(s.type==="slash"&&s.prev.type!=="bos"&&!u&&eos()){I.output=I.output.slice(0,-(s.output+$.output).length);s.output=`(?:${s.output}`;$.type="globstar";$.output=globstar(r)+(r.strictSlashes?")":"|$)");$.value+=q;I.globstar=true;I.output+=s.output+$.output;consume(q);continue}if(s.type==="slash"&&s.prev.type!=="bos"&&t[0]==="/"){const e=t[1]!==void 0?"|$":"";I.output=I.output.slice(0,-(s.output+$.output).length);s.output=`(?:${s.output}`;$.type="globstar";$.output=`${globstar(r)}${x}|${x}${e})`;$.value+=q;I.output+=s.output+$.output;I.globstar=true;consume(q+G());push({type:"slash",value:"/",output:""});continue}if(s.type==="bos"&&t[0]==="/"){$.type="globstar";$.value+=q;$.output=`(?:^|${x}|${globstar(r)}${x})`;I.output=$.output;I.globstar=true;consume(q+G());push({type:"slash",value:"/",output:""});continue}I.output=I.output.slice(0,-$.output.length);$.type="globstar";$.output=globstar(r);$.value+=q;I.output+=$.output;I.globstar=true;consume(q);continue}const s={type:"star",value:q,output:N};if(r.bash===true){s.output=".*?";if($.type==="bos"||$.type==="slash"){s.output=B+s.output}push(s);continue}if($&&($.type==="bracket"||$.type==="paren")&&r.regex===true){s.output=q;push(s);continue}if(I.index===I.start||$.type==="slash"||$.type==="dot"){if($.type==="dot"){I.output+=k;$.output+=k}else if(r.dot===true){I.output+=A;$.output+=A}else{I.output+=B;$.output+=B}if(U()!=="*"){I.output+=F;$.output+=F}}push(s)}while(I.brackets>0){if(r.strictBrackets===true)throw new SyntaxError(syntaxError("closing","]"));I.output=a.escapeLast(I.output,"[");decrement("brackets")}while(I.parens>0){if(r.strictBrackets===true)throw new SyntaxError(syntaxError("closing",")"));I.output=a.escapeLast(I.output,"(");decrement("parens")}while(I.braces>0){if(r.strictBrackets===true)throw new SyntaxError(syntaxError("closing","}"));I.output=a.escapeLast(I.output,"{");decrement("braces")}if(r.strictSlashes!==true&&($.type==="star"||$.type==="bracket")){push({type:"maybe_slash",value:"",output:`${x}?`})}if(I.backtrack===true){I.output="";for(const e of I.tokens){I.output+=e.output!=null?e.output:e.value;if(e.suffix){I.output+=e.suffix}}}return I};parse.fastpaths=(e,t)=>{const r={...t};const u=typeof r.maxLength==="number"?Math.min(o,r.maxLength):o;const c=e.length;if(c>u){throw new SyntaxError(`Input length: ${c}, exceeds maximum allowed length: ${u}`)}e=d[e]||e;const f=a.isWindows(t);const{DOT_LITERAL:p,SLASH_LITERAL:h,ONE_CHAR:v,DOTS_SLASH:D,NO_DOT:g,NO_DOTS:y,NO_DOTS_SLASH:m,STAR:_,START_ANCHOR:E}=s.globChars(f);const w=r.dot?y:g;const x=r.dot?m:g;const F=r.capture?"":"?:";const C={negated:false,prefix:""};let S=r.bash===true?".*?":_;if(r.capture){S=`(${S})`}const globstar=e=>{if(e.noglobstar===true)return S;return`(${F}(?:(?!${E}${e.dot?D:p}).)*?)`};const create=e=>{switch(e){case"*":return`${w}${v}${S}`;case".*":return`${p}${v}${S}`;case"*.*":return`${w}${S}${p}${v}${S}`;case"*/*":return`${w}${S}${h}${v}${x}${S}`;case"**":return w+globstar(r);case"**/*":return`(?:${w}${globstar(r)}${h})?${x}${v}${S}`;case"**/*.*":return`(?:${w}${globstar(r)}${h})?${x}${S}${p}${v}${S}`;case"**/.*":return`(?:${w}${globstar(r)}${h})?${p}${v}${S}`;default:{const t=/^(.*?)\.(\w+)$/.exec(e);if(!t)return;const r=create(t[1]);if(!r)return;return r+p+t[2]}}};const k=a.removePrefix(e,C);let A=create(k);if(A&&r.strictSlashes!==true){A+=`${h}?`}return A};e.exports=parse},7250:(e,t,r)=>{"use strict";const s=r(1017);const a=r(2964);const o=r(3632);const u=r(5502);const c=r(7798);const isObject=e=>e&&typeof e==="object"&&!Array.isArray(e);const picomatch=(e,t,r=false)=>{if(Array.isArray(e)){const s=e.map((e=>picomatch(e,t,r)));const arrayMatcher=e=>{for(const t of s){const r=t(e);if(r)return r}return false};return arrayMatcher}const s=isObject(e)&&e.tokens&&e.input;if(e===""||typeof e!=="string"&&!s){throw new TypeError("Expected pattern to be a non-empty string")}const a=t||{};const o=u.isWindows(t);const c=s?picomatch.compileRe(e,t):picomatch.makeRe(e,t,false,true);const f=c.state;delete c.state;let isIgnored=()=>false;if(a.ignore){const e={...t,ignore:null,onMatch:null,onResult:null};isIgnored=picomatch(a.ignore,e,r)}const matcher=(r,s=false)=>{const{isMatch:u,match:d,output:p}=picomatch.test(r,c,t,{glob:e,posix:o});const h={glob:e,state:f,regex:c,posix:o,input:r,output:p,match:d,isMatch:u};if(typeof a.onResult==="function"){a.onResult(h)}if(u===false){h.isMatch=false;return s?h:false}if(isIgnored(r)){if(typeof a.onIgnore==="function"){a.onIgnore(h)}h.isMatch=false;return s?h:false}if(typeof a.onMatch==="function"){a.onMatch(h)}return s?h:true};if(r){matcher.state=f}return matcher};picomatch.test=(e,t,r,{glob:s,posix:a}={})=>{if(typeof e!=="string"){throw new TypeError("Expected input to be a string")}if(e===""){return{isMatch:false,output:""}}const o=r||{};const c=o.format||(a?u.toPosixSlashes:null);let f=e===s;let d=f&&c?c(e):e;if(f===false){d=c?c(e):e;f=d===s}if(f===false||o.capture===true){if(o.matchBase===true||o.basename===true){f=picomatch.matchBase(e,t,r,a)}else{f=t.exec(d)}}return{isMatch:Boolean(f),match:f,output:d}};picomatch.matchBase=(e,t,r,a=u.isWindows(r))=>{const o=t instanceof RegExp?t:picomatch.makeRe(t,r);return o.test(s.basename(e))};picomatch.isMatch=(e,t,r)=>picomatch(t,r)(e);picomatch.parse=(e,t)=>{if(Array.isArray(e))return e.map((e=>picomatch.parse(e,t)));return o(e,{...t,fastpaths:false})};picomatch.scan=(e,t)=>a(e,t);picomatch.compileRe=(e,t,r=false,s=false)=>{if(r===true){return e.output}const a=t||{};const o=a.contains?"":"^";const u=a.contains?"":"$";let c=`${o}(?:${e.output})${u}`;if(e&&e.negated===true){c=`^(?!${c}).*$`}const f=picomatch.toRegex(c,t);if(s===true){f.state=e}return f};picomatch.makeRe=(e,t={},r=false,s=false)=>{if(!e||typeof e!=="string"){throw new TypeError("Expected a non-empty string")}let a={negated:false,fastpaths:true};if(t.fastpaths!==false&&(e[0]==="."||e[0]==="*")){a.output=o.fastpaths(e,t)}if(!a.output){a=o(e,t)}return picomatch.compileRe(a,t,r,s)};picomatch.toRegex=(e,t)=>{try{const r=t||{};return new RegExp(e,r.flags||(r.nocase?"i":""))}catch(e){if(t&&t.debug===true)throw e;return/$^/}};picomatch.constants=c;e.exports=picomatch},2964:(e,t,r)=>{"use strict";const s=r(5502);const{CHAR_ASTERISK:a,CHAR_AT:o,CHAR_BACKWARD_SLASH:u,CHAR_COMMA:c,CHAR_DOT:f,CHAR_EXCLAMATION_MARK:d,CHAR_FORWARD_SLASH:p,CHAR_LEFT_CURLY_BRACE:h,CHAR_LEFT_PARENTHESES:v,CHAR_LEFT_SQUARE_BRACKET:D,CHAR_PLUS:g,CHAR_QUESTION_MARK:y,CHAR_RIGHT_CURLY_BRACE:m,CHAR_RIGHT_PARENTHESES:_,CHAR_RIGHT_SQUARE_BRACKET:E}=r(7798);const isPathSeparator=e=>e===p||e===u;const depth=e=>{if(e.isPrefix!==true){e.depth=e.isGlobstar?Infinity:1}};const scan=(e,t)=>{const r=t||{};const w=e.length-1;const x=r.parts===true||r.scanToEnd===true;const F=[];const C=[];const S=[];let k=e;let A=-1;let R=0;let O=0;let T=false;let j=false;let B=false;let L=false;let N=false;let I=false;let P=false;let W=false;let M=false;let $=false;let q=0;let U;let G;let H={value:"",depth:0,isGlob:false};const eos=()=>A>=w;const peek=()=>k.charCodeAt(A+1);const advance=()=>{U=G;return k.charCodeAt(++A)};while(A0){z=k.slice(0,R);k=k.slice(R);O-=R}if(K&&B===true&&O>0){K=k.slice(0,O);V=k.slice(O)}else if(B===true){K="";V=k}else{K=k}if(K&&K!==""&&K!=="/"&&K!==k){if(isPathSeparator(K.charCodeAt(K.length-1))){K=K.slice(0,-1)}}if(r.unescape===true){if(V)V=s.removeBackslashes(V);if(K&&P===true){K=s.removeBackslashes(K)}}const Y={prefix:z,input:e,start:R,base:K,glob:V,isBrace:T,isBracket:j,isGlob:B,isExtglob:L,isGlobstar:N,negated:W,negatedExtglob:M};if(r.tokens===true){Y.maxDepth=0;if(!isPathSeparator(G)){C.push(H)}Y.tokens=C}if(r.parts===true||r.tokens===true){let t;for(let s=0;s{"use strict";const s=r(1017);const a=process.platform==="win32";const{REGEX_BACKSLASH:o,REGEX_REMOVE_BACKSLASH:u,REGEX_SPECIAL_CHARS:c,REGEX_SPECIAL_CHARS_GLOBAL:f}=r(7798);t.isObject=e=>e!==null&&typeof e==="object"&&!Array.isArray(e);t.hasRegexChars=e=>c.test(e);t.isRegexChar=e=>e.length===1&&t.hasRegexChars(e);t.escapeRegex=e=>e.replace(f,"\\$1");t.toPosixSlashes=e=>e.replace(o,"/");t.removeBackslashes=e=>e.replace(u,(e=>e==="\\"?"":e));t.supportsLookbehinds=()=>{const e=process.version.slice(1).split(".").map(Number);if(e.length===3&&e[0]>=9||e[0]===8&&e[1]>=10){return true}return false};t.isWindows=e=>{if(e&&typeof e.windows==="boolean"){return e.windows}return a===true||s.sep==="\\"};t.escapeLast=(e,r,s)=>{const a=e.lastIndexOf(r,s);if(a===-1)return e;if(e[a-1]==="\\")return t.escapeLast(e,r,a-1);return`${e.slice(0,a)}\\${e.slice(a)}`};t.removePrefix=(e,t={})=>{let r=e;if(r.startsWith("./")){r=r.slice(2);t.prefix="./"}return r};t.wrapOutput=(e,t={},r={})=>{const s=r.contains?"":"^";const a=r.contains?"":"$";let o=`${s}(?:${e})${a}`;if(t.negated===true){o=`(?:^(?!${o}).*$)`}return o}},9182:e=>{"use strict";if(typeof process==="undefined"||!process.version||process.version.indexOf("v0.")===0||process.version.indexOf("v1.")===0&&process.version.indexOf("v1.8.")!==0){e.exports={nextTick:nextTick}}else{e.exports=process}function nextTick(e,t,r,s){if(typeof e!=="function"){throw new TypeError('"callback" argument must be a function')}var a=arguments.length;var o,u;switch(a){case 0:case 1:return process.nextTick(e);case 2:return process.nextTick((function afterTickOne(){e.call(null,t)}));case 3:return process.nextTick((function afterTickTwo(){e.call(null,t,r)}));case 4:return process.nextTick((function afterTickThree(){e.call(null,t,r,s)}));default:o=new Array(a-1);u=0;while(u{"use strict";var s=r(9182);var a=Object.keys||function(e){var t=[];for(var r in e){t.push(r)}return t};e.exports=Duplex;var o=Object.create(r(1504));o.inherits=r(2842);var u=r(7355);var c=r(3517);o.inherits(Duplex,u);{var f=a(c.prototype);for(var d=0;d{"use strict";e.exports=PassThrough;var s=r(2162);var a=Object.create(r(1504));a.inherits=r(2842);a.inherits(PassThrough,s);function PassThrough(e){if(!(this instanceof PassThrough))return new PassThrough(e);s.call(this,e)}PassThrough.prototype._transform=function(e,t,r){r(null,e)}},7355:(e,t,r)=>{"use strict";var s=r(9182);e.exports=Readable;var a=r(1551);var o;Readable.ReadableState=ReadableState;var u=r(2361).EventEmitter;var EElistenerCount=function(e,t){return e.listeners(t).length};var c=r(2641);var f=r(291).Buffer;var d=global.Uint8Array||function(){};function _uint8ArrayToBuffer(e){return f.from(e)}function _isUint8Array(e){return f.isBuffer(e)||e instanceof d}var p=Object.create(r(1504));p.inherits=r(2842);var h=r(3837);var v=void 0;if(h&&h.debuglog){v=h.debuglog("stream")}else{v=function(){}}var D=r(4865);var g=r(2604);var y;p.inherits(Readable,c);var m=["error","close","destroy","pause","resume"];function prependListener(e,t,r){if(typeof e.prependListener==="function")return e.prependListener(t,r);if(!e._events||!e._events[t])e.on(t,r);else if(a(e._events[t]))e._events[t].unshift(r);else e._events[t]=[r,e._events[t]]}function ReadableState(e,t){o=o||r(4928);e=e||{};var s=t instanceof o;this.objectMode=!!e.objectMode;if(s)this.objectMode=this.objectMode||!!e.readableObjectMode;var a=e.highWaterMark;var u=e.readableHighWaterMark;var c=this.objectMode?16:16*1024;if(a||a===0)this.highWaterMark=a;else if(s&&(u||u===0))this.highWaterMark=u;else this.highWaterMark=c;this.highWaterMark=Math.floor(this.highWaterMark);this.buffer=new D;this.length=0;this.pipes=null;this.pipesCount=0;this.flowing=null;this.ended=false;this.endEmitted=false;this.reading=false;this.sync=true;this.needReadable=false;this.emittedReadable=false;this.readableListening=false;this.resumeScheduled=false;this.destroyed=false;this.defaultEncoding=e.defaultEncoding||"utf8";this.awaitDrain=0;this.readingMore=false;this.decoder=null;this.encoding=null;if(e.encoding){if(!y)y=r(4426).s;this.decoder=new y(e.encoding);this.encoding=e.encoding}}function Readable(e){o=o||r(4928);if(!(this instanceof Readable))return new Readable(e);this._readableState=new ReadableState(e,this);this.readable=true;if(e){if(typeof e.read==="function")this._read=e.read;if(typeof e.destroy==="function")this._destroy=e.destroy}c.call(this)}Object.defineProperty(Readable.prototype,"destroyed",{get:function(){if(this._readableState===undefined){return false}return this._readableState.destroyed},set:function(e){if(!this._readableState){return}this._readableState.destroyed=e}});Readable.prototype.destroy=g.destroy;Readable.prototype._undestroy=g.undestroy;Readable.prototype._destroy=function(e,t){this.push(null);t(e)};Readable.prototype.push=function(e,t){var r=this._readableState;var s;if(!r.objectMode){if(typeof e==="string"){t=t||r.defaultEncoding;if(t!==r.encoding){e=f.from(e,t);t=""}s=true}}else{s=true}return readableAddChunk(this,e,t,false,s)};Readable.prototype.unshift=function(e){return readableAddChunk(this,e,null,true,false)};function readableAddChunk(e,t,r,s,a){var o=e._readableState;if(t===null){o.reading=false;onEofChunk(e,o)}else{var u;if(!a)u=chunkInvalid(o,t);if(u){e.emit("error",u)}else if(o.objectMode||t&&t.length>0){if(typeof t!=="string"&&!o.objectMode&&Object.getPrototypeOf(t)!==f.prototype){t=_uint8ArrayToBuffer(t)}if(s){if(o.endEmitted)e.emit("error",new Error("stream.unshift() after end event"));else addChunk(e,o,t,true)}else if(o.ended){e.emit("error",new Error("stream.push() after EOF"))}else{o.reading=false;if(o.decoder&&!r){t=o.decoder.write(t);if(o.objectMode||t.length!==0)addChunk(e,o,t,false);else maybeReadMore(e,o)}else{addChunk(e,o,t,false)}}}else if(!s){o.reading=false}}return needMoreData(o)}function addChunk(e,t,r,s){if(t.flowing&&t.length===0&&!t.sync){e.emit("data",r);e.read(0)}else{t.length+=t.objectMode?1:r.length;if(s)t.buffer.unshift(r);else t.buffer.push(r);if(t.needReadable)emitReadable(e)}maybeReadMore(e,t)}function chunkInvalid(e,t){var r;if(!_isUint8Array(t)&&typeof t!=="string"&&t!==undefined&&!e.objectMode){r=new TypeError("Invalid non-string/buffer chunk")}return r}function needMoreData(e){return!e.ended&&(e.needReadable||e.length=_){e=_}else{e--;e|=e>>>1;e|=e>>>2;e|=e>>>4;e|=e>>>8;e|=e>>>16;e++}return e}function howMuchToRead(e,t){if(e<=0||t.length===0&&t.ended)return 0;if(t.objectMode)return 1;if(e!==e){if(t.flowing&&t.length)return t.buffer.head.data.length;else return t.length}if(e>t.highWaterMark)t.highWaterMark=computeNewHighWaterMark(e);if(e<=t.length)return e;if(!t.ended){t.needReadable=true;return 0}return t.length}Readable.prototype.read=function(e){v("read",e);e=parseInt(e,10);var t=this._readableState;var r=e;if(e!==0)t.emittedReadable=false;if(e===0&&t.needReadable&&(t.length>=t.highWaterMark||t.ended)){v("read: emitReadable",t.length,t.ended);if(t.length===0&&t.ended)endReadable(this);else emitReadable(this);return null}e=howMuchToRead(e,t);if(e===0&&t.ended){if(t.length===0)endReadable(this);return null}var s=t.needReadable;v("need readable",s);if(t.length===0||t.length-e0)a=fromList(e,t);else a=null;if(a===null){t.needReadable=true;e=0}else{t.length-=e}if(t.length===0){if(!t.ended)t.needReadable=true;if(r!==e&&t.ended)endReadable(this)}if(a!==null)this.emit("data",a);return a};function onEofChunk(e,t){if(t.ended)return;if(t.decoder){var r=t.decoder.end();if(r&&r.length){t.buffer.push(r);t.length+=t.objectMode?1:r.length}}t.ended=true;emitReadable(e)}function emitReadable(e){var t=e._readableState;t.needReadable=false;if(!t.emittedReadable){v("emitReadable",t.flowing);t.emittedReadable=true;if(t.sync)s.nextTick(emitReadable_,e);else emitReadable_(e)}}function emitReadable_(e){v("emit readable");e.emit("readable");flow(e)}function maybeReadMore(e,t){if(!t.readingMore){t.readingMore=true;s.nextTick(maybeReadMore_,e,t)}}function maybeReadMore_(e,t){var r=t.length;while(!t.reading&&!t.flowing&&!t.ended&&t.length1&&indexOf(a.pipes,e)!==-1)&&!f){v("false write response, pause",r._readableState.awaitDrain);r._readableState.awaitDrain++;d=true}r.pause()}}function onerror(t){v("onerror",t);unpipe();e.removeListener("error",onerror);if(EElistenerCount(e,"error")===0)e.emit("error",t)}prependListener(e,"error",onerror);function onclose(){e.removeListener("finish",onfinish);unpipe()}e.once("close",onclose);function onfinish(){v("onfinish");e.removeListener("close",onclose);unpipe()}e.once("finish",onfinish);function unpipe(){v("unpipe");r.unpipe(e)}e.emit("pipe",r);if(!a.flowing){v("pipe resume");r.resume()}return e};function pipeOnDrain(e){return function(){var t=e._readableState;v("pipeOnDrain",t.awaitDrain);if(t.awaitDrain)t.awaitDrain--;if(t.awaitDrain===0&&EElistenerCount(e,"data")){t.flowing=true;flow(e)}}}Readable.prototype.unpipe=function(e){var t=this._readableState;var r={hasUnpiped:false};if(t.pipesCount===0)return this;if(t.pipesCount===1){if(e&&e!==t.pipes)return this;if(!e)e=t.pipes;t.pipes=null;t.pipesCount=0;t.flowing=false;if(e)e.emit("unpipe",this,r);return this}if(!e){var s=t.pipes;var a=t.pipesCount;t.pipes=null;t.pipesCount=0;t.flowing=false;for(var o=0;o=t.length){if(t.decoder)r=t.buffer.join("");else if(t.buffer.length===1)r=t.buffer.head.data;else r=t.buffer.concat(t.length);t.buffer.clear()}else{r=fromListPartial(e,t.buffer,t.decoder)}return r}function fromListPartial(e,t,r){var s;if(eo.length?o.length:e;if(u===o.length)a+=o;else a+=o.slice(0,e);e-=u;if(e===0){if(u===o.length){++s;if(r.next)t.head=r.next;else t.head=t.tail=null}else{t.head=r;r.data=o.slice(u)}break}++s}t.length-=s;return a}function copyFromBuffer(e,t){var r=f.allocUnsafe(e);var s=t.head;var a=1;s.data.copy(r);e-=s.data.length;while(s=s.next){var o=s.data;var u=e>o.length?o.length:e;o.copy(r,r.length-e,0,u);e-=u;if(e===0){if(u===o.length){++a;if(s.next)t.head=s.next;else t.head=t.tail=null}else{t.head=s;s.data=o.slice(u)}break}++a}t.length-=a;return r}function endReadable(e){var t=e._readableState;if(t.length>0)throw new Error('"endReadable()" called on non-empty stream');if(!t.endEmitted){t.ended=true;s.nextTick(endReadableNT,t,e)}}function endReadableNT(e,t){if(!e.endEmitted&&e.length===0){e.endEmitted=true;t.readable=false;t.emit("end")}}function indexOf(e,t){for(var r=0,s=e.length;r{"use strict";e.exports=Transform;var s=r(4928);var a=Object.create(r(1504));a.inherits=r(2842);a.inherits(Transform,s);function afterTransform(e,t){var r=this._transformState;r.transforming=false;var s=r.writecb;if(!s){return this.emit("error",new Error("write callback called multiple times"))}r.writechunk=null;r.writecb=null;if(t!=null)this.push(t);s(e);var a=this._readableState;a.reading=false;if(a.needReadable||a.length{"use strict";var s=r(9182);e.exports=Writable;function WriteReq(e,t,r){this.chunk=e;this.encoding=t;this.callback=r;this.next=null}function CorkedRequest(e){var t=this;this.next=null;this.entry=null;this.finish=function(){onCorkedFinish(t,e)}}var a=!process.browser&&["v0.10","v0.9."].indexOf(process.version.slice(0,5))>-1?setImmediate:s.nextTick;var o;Writable.WritableState=WritableState;var u=Object.create(r(1504));u.inherits=r(2842);var c={deprecate:r(6124)};var f=r(2641);var d=r(291).Buffer;var p=global.Uint8Array||function(){};function _uint8ArrayToBuffer(e){return d.from(e)}function _isUint8Array(e){return d.isBuffer(e)||e instanceof p}var h=r(2604);u.inherits(Writable,f);function nop(){}function WritableState(e,t){o=o||r(4928);e=e||{};var s=t instanceof o;this.objectMode=!!e.objectMode;if(s)this.objectMode=this.objectMode||!!e.writableObjectMode;var a=e.highWaterMark;var u=e.writableHighWaterMark;var c=this.objectMode?16:16*1024;if(a||a===0)this.highWaterMark=a;else if(s&&(u||u===0))this.highWaterMark=u;else this.highWaterMark=c;this.highWaterMark=Math.floor(this.highWaterMark);this.finalCalled=false;this.needDrain=false;this.ending=false;this.ended=false;this.finished=false;this.destroyed=false;var f=e.decodeStrings===false;this.decodeStrings=!f;this.defaultEncoding=e.defaultEncoding||"utf8";this.length=0;this.writing=false;this.corked=0;this.sync=true;this.bufferProcessing=false;this.onwrite=function(e){onwrite(t,e)};this.writecb=null;this.writelen=0;this.bufferedRequest=null;this.lastBufferedRequest=null;this.pendingcb=0;this.prefinished=false;this.errorEmitted=false;this.bufferedRequestCount=0;this.corkedRequestsFree=new CorkedRequest(this)}WritableState.prototype.getBuffer=function getBuffer(){var e=this.bufferedRequest;var t=[];while(e){t.push(e);e=e.next}return t};(function(){try{Object.defineProperty(WritableState.prototype,"buffer",{get:c.deprecate((function(){return this.getBuffer()}),"_writableState.buffer is deprecated. Use _writableState.getBuffer "+"instead.","DEP0003")})}catch(e){}})();var v;if(typeof Symbol==="function"&&Symbol.hasInstance&&typeof Function.prototype[Symbol.hasInstance]==="function"){v=Function.prototype[Symbol.hasInstance];Object.defineProperty(Writable,Symbol.hasInstance,{value:function(e){if(v.call(this,e))return true;if(this!==Writable)return false;return e&&e._writableState instanceof WritableState}})}else{v=function(e){return e instanceof this}}function Writable(e){o=o||r(4928);if(!v.call(Writable,this)&&!(this instanceof o)){return new Writable(e)}this._writableState=new WritableState(e,this);this.writable=true;if(e){if(typeof e.write==="function")this._write=e.write;if(typeof e.writev==="function")this._writev=e.writev;if(typeof e.destroy==="function")this._destroy=e.destroy;if(typeof e.final==="function")this._final=e.final}f.call(this)}Writable.prototype.pipe=function(){this.emit("error",new Error("Cannot pipe, not readable"))};function writeAfterEnd(e,t){var r=new Error("write after end");e.emit("error",r);s.nextTick(t,r)}function validChunk(e,t,r,a){var o=true;var u=false;if(r===null){u=new TypeError("May not write null values to stream")}else if(typeof r!=="string"&&r!==undefined&&!t.objectMode){u=new TypeError("Invalid non-string/buffer chunk")}if(u){e.emit("error",u);s.nextTick(a,u);o=false}return o}Writable.prototype.write=function(e,t,r){var s=this._writableState;var a=false;var o=!s.objectMode&&_isUint8Array(e);if(o&&!d.isBuffer(e)){e=_uint8ArrayToBuffer(e)}if(typeof t==="function"){r=t;t=null}if(o)t="buffer";else if(!t)t=s.defaultEncoding;if(typeof r!=="function")r=nop;if(s.ended)writeAfterEnd(this,r);else if(o||validChunk(this,s,e,r)){s.pendingcb++;a=writeOrBuffer(this,s,o,e,t,r)}return a};Writable.prototype.cork=function(){var e=this._writableState;e.corked++};Writable.prototype.uncork=function(){var e=this._writableState;if(e.corked){e.corked--;if(!e.writing&&!e.corked&&!e.finished&&!e.bufferProcessing&&e.bufferedRequest)clearBuffer(this,e)}};Writable.prototype.setDefaultEncoding=function setDefaultEncoding(e){if(typeof e==="string")e=e.toLowerCase();if(!(["hex","utf8","utf-8","ascii","binary","base64","ucs2","ucs-2","utf16le","utf-16le","raw"].indexOf((e+"").toLowerCase())>-1))throw new TypeError("Unknown encoding: "+e);this._writableState.defaultEncoding=e;return this};function decodeChunk(e,t,r){if(!e.objectMode&&e.decodeStrings!==false&&typeof t==="string"){t=d.from(t,r)}return t}Object.defineProperty(Writable.prototype,"writableHighWaterMark",{enumerable:false,get:function(){return this._writableState.highWaterMark}});function writeOrBuffer(e,t,r,s,a,o){if(!r){var u=decodeChunk(t,s,a);if(s!==u){r=true;a="buffer";s=u}}var c=t.objectMode?1:s.length;t.length+=c;var f=t.length{"use strict";function _classCallCheck(e,t){if(!(e instanceof t)){throw new TypeError("Cannot call a class as a function")}}var s=r(291).Buffer;var a=r(3837);function copyBuffer(e,t,r){e.copy(t,r)}e.exports=function(){function BufferList(){_classCallCheck(this,BufferList);this.head=null;this.tail=null;this.length=0}BufferList.prototype.push=function push(e){var t={data:e,next:null};if(this.length>0)this.tail.next=t;else this.head=t;this.tail=t;++this.length};BufferList.prototype.unshift=function unshift(e){var t={data:e,next:this.head};if(this.length===0)this.tail=t;this.head=t;++this.length};BufferList.prototype.shift=function shift(){if(this.length===0)return;var e=this.head.data;if(this.length===1)this.head=this.tail=null;else this.head=this.head.next;--this.length;return e};BufferList.prototype.clear=function clear(){this.head=this.tail=null;this.length=0};BufferList.prototype.join=function join(e){if(this.length===0)return"";var t=this.head;var r=""+t.data;while(t=t.next){r+=e+t.data}return r};BufferList.prototype.concat=function concat(e){if(this.length===0)return s.alloc(0);if(this.length===1)return this.head.data;var t=s.allocUnsafe(e>>>0);var r=this.head;var a=0;while(r){copyBuffer(r.data,t,a);a+=r.data.length;r=r.next}return t};return BufferList}();if(a&&a.inspect&&a.inspect.custom){e.exports.prototype[a.inspect.custom]=function(){var e=a.inspect({length:this.length});return this.constructor.name+" "+e}}},2604:(e,t,r)=>{"use strict";var s=r(9182);function destroy(e,t){var r=this;var a=this._readableState&&this._readableState.destroyed;var o=this._writableState&&this._writableState.destroyed;if(a||o){if(t){t(e)}else if(e&&(!this._writableState||!this._writableState.errorEmitted)){s.nextTick(emitErrorNT,this,e)}return this}if(this._readableState){this._readableState.destroyed=true}if(this._writableState){this._writableState.destroyed=true}this._destroy(e||null,(function(e){if(!t&&e){s.nextTick(emitErrorNT,r,e);if(r._writableState){r._writableState.errorEmitted=true}}else if(t){t(e)}}));return this}function undestroy(){if(this._readableState){this._readableState.destroyed=false;this._readableState.reading=false;this._readableState.ended=false;this._readableState.endEmitted=false}if(this._writableState){this._writableState.destroyed=false;this._writableState.ended=false;this._writableState.ending=false;this._writableState.finished=false;this._writableState.errorEmitted=false}}function emitErrorNT(e,t){e.emit("error",t)}e.exports={destroy:destroy,undestroy:undestroy}},2641:(e,t,r)=>{e.exports=r(2781)},8511:(e,t,r)=>{var s=r(2781);if(process.env.READABLE_STREAM==="disable"&&s){e.exports=s;t=e.exports=s.Readable;t.Readable=s.Readable;t.Writable=s.Writable;t.Duplex=s.Duplex;t.Transform=s.Transform;t.PassThrough=s.PassThrough;t.Stream=s}else{t=e.exports=r(7355);t.Stream=s||t;t.Readable=t;t.Writable=r(3517);t.Duplex=r(4928);t.Transform=r(2162);t.PassThrough=r(9924)}},2382:(e,t,r)=>{"use strict";const s=r(1017);const a=r(8188);const o=r(7147);const resolveFrom=(e,t,r)=>{if(typeof e!=="string"){throw new TypeError(`Expected \`fromDir\` to be of type \`string\`, got \`${typeof e}\``)}if(typeof t!=="string"){throw new TypeError(`Expected \`moduleId\` to be of type \`string\`, got \`${typeof t}\``)}try{e=o.realpathSync(e)}catch(t){if(t.code==="ENOENT"){e=s.resolve(e)}else if(r){return}else{throw t}}const u=s.join(e,"noop.js");const resolveFileName=()=>a._resolveFilename(t,{id:u,filename:u,paths:a._nodeModulePaths(e)});if(r){try{return resolveFileName()}catch(e){return}}return resolveFileName()};e.exports=(e,t)=>resolveFrom(e,t);e.exports.silent=(e,t)=>resolveFrom(e,t,true)},4700:(e,t,r)=>{const s=r(9491);const a=r(1017);const o=r(7147);let u=undefined;try{u=r(3535)}catch(e){}const c={nosort:true,silent:true};let f=0;const d=process.platform==="win32";const defaults=e=>{const t=["unlink","chmod","stat","lstat","rmdir","readdir"];t.forEach((t=>{e[t]=e[t]||o[t];t=t+"Sync";e[t]=e[t]||o[t]}));e.maxBusyTries=e.maxBusyTries||3;e.emfileWait=e.emfileWait||1e3;if(e.glob===false){e.disableGlob=true}if(e.disableGlob!==true&&u===undefined){throw Error("glob dependency not found, set `options.disableGlob = true` if intentional")}e.disableGlob=e.disableGlob||false;e.glob=e.glob||c};const rimraf=(e,t,r)=>{if(typeof t==="function"){r=t;t={}}s(e,"rimraf: missing path");s.equal(typeof e,"string","rimraf: path should be a string");s.equal(typeof r,"function","rimraf: callback function required");s(t,"rimraf: invalid options argument provided");s.equal(typeof t,"object","rimraf: options should be object");defaults(t);let a=0;let o=null;let c=0;const next=e=>{o=o||e;if(--c===0)r(o)};const afterGlob=(e,s)=>{if(e)return r(e);c=s.length;if(c===0)return r();s.forEach((e=>{const CB=r=>{if(r){if((r.code==="EBUSY"||r.code==="ENOTEMPTY"||r.code==="EPERM")&&arimraf_(e,t,CB)),a*100)}if(r.code==="EMFILE"&&frimraf_(e,t,CB)),f++)}if(r.code==="ENOENT")r=null}f=0;next(r)};rimraf_(e,t,CB)}))};if(t.disableGlob||!u.hasMagic(e))return afterGlob(null,[e]);t.lstat(e,((r,s)=>{if(!r)return afterGlob(null,[e]);u(e,t.glob,afterGlob)}))};const rimraf_=(e,t,r)=>{s(e);s(t);s(typeof r==="function");t.lstat(e,((s,a)=>{if(s&&s.code==="ENOENT")return r(null);if(s&&s.code==="EPERM"&&d)fixWinEPERM(e,t,s,r);if(a&&a.isDirectory())return rmdir(e,t,s,r);t.unlink(e,(s=>{if(s){if(s.code==="ENOENT")return r(null);if(s.code==="EPERM")return d?fixWinEPERM(e,t,s,r):rmdir(e,t,s,r);if(s.code==="EISDIR")return rmdir(e,t,s,r)}return r(s)}))}))};const fixWinEPERM=(e,t,r,a)=>{s(e);s(t);s(typeof a==="function");t.chmod(e,438,(s=>{if(s)a(s.code==="ENOENT"?null:r);else t.stat(e,((s,o)=>{if(s)a(s.code==="ENOENT"?null:r);else if(o.isDirectory())rmdir(e,t,r,a);else t.unlink(e,a)}))}))};const fixWinEPERMSync=(e,t,r)=>{s(e);s(t);try{t.chmodSync(e,438)}catch(e){if(e.code==="ENOENT")return;else throw r}let a;try{a=t.statSync(e)}catch(e){if(e.code==="ENOENT")return;else throw r}if(a.isDirectory())rmdirSync(e,t,r);else t.unlinkSync(e)};const rmdir=(e,t,r,a)=>{s(e);s(t);s(typeof a==="function");t.rmdir(e,(s=>{if(s&&(s.code==="ENOTEMPTY"||s.code==="EEXIST"||s.code==="EPERM"))rmkids(e,t,a);else if(s&&s.code==="ENOTDIR")a(r);else a(s)}))};const rmkids=(e,t,r)=>{s(e);s(t);s(typeof r==="function");t.readdir(e,((s,o)=>{if(s)return r(s);let u=o.length;if(u===0)return t.rmdir(e,r);let c;o.forEach((s=>{rimraf(a.join(e,s),t,(s=>{if(c)return;if(s)return r(c=s);if(--u===0)t.rmdir(e,r)}))}))}))};const rimrafSync=(e,t)=>{t=t||{};defaults(t);s(e,"rimraf: missing path");s.equal(typeof e,"string","rimraf: path should be a string");s(t,"rimraf: missing options");s.equal(typeof t,"object","rimraf: options should be object");let r;if(t.disableGlob||!u.hasMagic(e)){r=[e]}else{try{t.lstatSync(e);r=[e]}catch(s){r=u.sync(e,t.glob)}}if(!r.length)return;for(let e=0;e{s(e);s(t);try{t.rmdirSync(e)}catch(s){if(s.code==="ENOENT")return;if(s.code==="ENOTDIR")throw r;if(s.code==="ENOTEMPTY"||s.code==="EEXIST"||s.code==="EPERM")rmkidsSync(e,t)}};const rmkidsSync=(e,t)=>{s(e);s(t);t.readdirSync(e).forEach((r=>rimrafSync(a.join(e,r),t)));const r=d?100:1;let o=0;do{let s=true;try{const a=t.rmdirSync(e,t);s=false;return a}finally{if(++o{var s=r(4300);var a=s.Buffer;function copyProps(e,t){for(var r in e){t[r]=e[r]}}if(a.from&&a.alloc&&a.allocUnsafe&&a.allocUnsafeSlow){e.exports=s}else{copyProps(s,t);t.Buffer=SafeBuffer}function SafeBuffer(e,t,r){return a(e,t,r)}copyProps(a,SafeBuffer);SafeBuffer.from=function(e,t,r){if(typeof e==="number"){throw new TypeError("Argument must not be a number")}return a(e,t,r)};SafeBuffer.alloc=function(e,t,r){if(typeof e!=="number"){throw new TypeError("Argument must be a number")}var s=a(e);if(t!==undefined){if(typeof r==="string"){s.fill(t,r)}else{s.fill(t)}}else{s.fill(0)}return s};SafeBuffer.allocUnsafe=function(e){if(typeof e!=="number"){throw new TypeError("Argument must be a number")}return a(e)};SafeBuffer.allocUnsafeSlow=function(e){if(typeof e!=="number"){throw new TypeError("Argument must be a number")}return s.SlowBuffer(e)}},2656:e=>{e.exports=function(e){[process.stdout,process.stderr].forEach((function(t){if(t._handle&&t.isTTY&&typeof t._handle.setBlocking==="function"){t._handle.setBlocking(e)}}))}},7234:(e,t,r)=>{var s=global.process;const processOk=function(e){return e&&typeof e==="object"&&typeof e.removeListener==="function"&&typeof e.emit==="function"&&typeof e.reallyExit==="function"&&typeof e.listeners==="function"&&typeof e.kill==="function"&&typeof e.pid==="number"&&typeof e.on==="function"};if(!processOk(s)){e.exports=function(){return function(){}}}else{var a=r(9491);var o=r(8986);var u=/^win/i.test(s.platform);var c=r(2361);if(typeof c!=="function"){c=c.EventEmitter}var f;if(s.__signal_exit_emitter__){f=s.__signal_exit_emitter__}else{f=s.__signal_exit_emitter__=new c;f.count=0;f.emitted={}}if(!f.infinite){f.setMaxListeners(Infinity);f.infinite=true}e.exports=function(e,t){if(!processOk(global.process)){return function(){}}a.equal(typeof e,"function","a callback must be provided for exit handler");if(v===false){D()}var r="exit";if(t&&t.alwaysLast){r="afterexit"}var remove=function(){f.removeListener(r,e);if(f.listeners("exit").length===0&&f.listeners("afterexit").length===0){d()}};f.on(r,e);return remove};var d=function unload(){if(!v||!processOk(global.process)){return}v=false;o.forEach((function(e){try{s.removeListener(e,h[e])}catch(e){}}));s.emit=m;s.reallyExit=g;f.count-=1};e.exports.unload=d;var p=function emit(e,t,r){if(f.emitted[e]){return}f.emitted[e]=true;f.emit(e,t,r)};var h={};o.forEach((function(e){h[e]=function listener(){if(!processOk(global.process)){return}var t=s.listeners(e);if(t.length===f.count){d();p("exit",null,e);p("afterexit",null,e);if(u&&e==="SIGHUP"){e="SIGINT"}s.kill(s.pid,e)}}}));e.exports.signals=function(){return o};var v=false;var D=function load(){if(v||!processOk(global.process)){return}v=true;f.count+=1;o=o.filter((function(e){try{s.on(e,h[e]);return true}catch(e){return false}}));s.emit=_;s.reallyExit=y};e.exports.load=D;var g=s.reallyExit;var y=function processReallyExit(e){if(!processOk(global.process)){return}s.exitCode=e||0;p("exit",s.exitCode,null);p("afterexit",s.exitCode,null);g.call(s,s.exitCode)};var m=s.emit;var _=function processEmit(e,t){if(e==="exit"&&processOk(global.process)){if(t!==undefined){s.exitCode=t}var r=m.apply(this,arguments);p("exit",s.exitCode,null);p("afterexit",s.exitCode,null);return r}else{return m.apply(this,arguments)}}}},8986:e=>{e.exports=["SIGABRT","SIGALRM","SIGHUP","SIGINT","SIGTERM"];if(process.platform!=="win32"){e.exports.push("SIGVTALRM","SIGXCPU","SIGXFSZ","SIGUSR2","SIGTRAP","SIGSYS","SIGQUIT","SIGIOT")}if(process.platform==="linux"){e.exports.push("SIGIO","SIGPOLL","SIGPWR","SIGSTKFLT","SIGUNUSED")}},8321:(e,t,r)=>{"use strict";var s=r(7518);var a=r(8589);var o=r(3279);e.exports=function(e){if(typeof e!=="string"||e.length===0){return 0}var t=0;e=s(e);for(var r=0;r=127&&u<=159){continue}if(u>=65536){r++}if(o(u)){t+=2}else{t++}}return t}},5663:(e,t,r)=>{"use strict";const s=r(7518);const a=r(8502);const o=r(3876);const stringWidth=e=>{if(typeof e!=="string"||e.length===0){return 0}e=s(e);if(e.length===0){return 0}e=e.replace(o()," ");let t=0;for(let r=0;r=127&&s<=159){continue}if(s>=768&&s<=879){continue}if(s>65535){r++}t+=a(s)?2:1}return t};e.exports=stringWidth;e.exports["default"]=stringWidth},4426:(e,t,r)=>{"use strict";var s=r(291).Buffer;var a=s.isEncoding||function(e){e=""+e;switch(e&&e.toLowerCase()){case"hex":case"utf8":case"utf-8":case"ascii":case"binary":case"base64":case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":case"raw":return true;default:return false}};function _normalizeEncoding(e){if(!e)return"utf8";var t;while(true){switch(e){case"utf8":case"utf-8":return"utf8";case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return"utf16le";case"latin1":case"binary":return"latin1";case"base64":case"ascii":case"hex":return e;default:if(t)return;e=(""+e).toLowerCase();t=true}}}function normalizeEncoding(e){var t=_normalizeEncoding(e);if(typeof t!=="string"&&(s.isEncoding===a||!a(e)))throw new Error("Unknown encoding: "+e);return t||e}t.s=StringDecoder;function StringDecoder(e){this.encoding=normalizeEncoding(e);var t;switch(this.encoding){case"utf16le":this.text=utf16Text;this.end=utf16End;t=4;break;case"utf8":this.fillLast=utf8FillLast;t=4;break;case"base64":this.text=base64Text;this.end=base64End;t=3;break;default:this.write=simpleWrite;this.end=simpleEnd;return}this.lastNeed=0;this.lastTotal=0;this.lastChar=s.allocUnsafe(t)}StringDecoder.prototype.write=function(e){if(e.length===0)return"";var t;var r;if(this.lastNeed){t=this.fillLast(e);if(t===undefined)return"";r=this.lastNeed;this.lastNeed=0}else{r=0}if(r>5===6)return 2;else if(e>>4===14)return 3;else if(e>>3===30)return 4;return e>>6===2?-1:-2}function utf8CheckIncomplete(e,t,r){var s=t.length-1;if(s=0){if(a>0)e.lastNeed=a-1;return a}if(--s=0){if(a>0)e.lastNeed=a-2;return a}if(--s=0){if(a>0){if(a===2)a=0;else e.lastNeed=a-3}return a}return 0}function utf8CheckExtraBytes(e,t,r){if((t[0]&192)!==128){e.lastNeed=0;return"�"}if(e.lastNeed>1&&t.length>1){if((t[1]&192)!==128){e.lastNeed=1;return"�"}if(e.lastNeed>2&&t.length>2){if((t[2]&192)!==128){e.lastNeed=2;return"�"}}}}function utf8FillLast(e){var t=this.lastTotal-this.lastNeed;var r=utf8CheckExtraBytes(this,e,t);if(r!==undefined)return r;if(this.lastNeed<=e.length){e.copy(this.lastChar,t,0,this.lastNeed);return this.lastChar.toString(this.encoding,0,this.lastTotal)}e.copy(this.lastChar,t,0,e.length);this.lastNeed-=e.length}function utf8Text(e,t){var r=utf8CheckIncomplete(this,e,t);if(!this.lastNeed)return e.toString("utf8",t);this.lastTotal=r;var s=e.length-(r-this.lastNeed);e.copy(this.lastChar,0,s);return e.toString("utf8",t,s)}function utf8End(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed)return t+"�";return t}function utf16Text(e,t){if((e.length-t)%2===0){var r=e.toString("utf16le",t);if(r){var s=r.charCodeAt(r.length-1);if(s>=55296&&s<=56319){this.lastNeed=2;this.lastTotal=4;this.lastChar[0]=e[e.length-2];this.lastChar[1]=e[e.length-1];return r.slice(0,-1)}}return r}this.lastNeed=1;this.lastTotal=2;this.lastChar[0]=e[e.length-1];return e.toString("utf16le",t,e.length-1)}function utf16End(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed){var r=this.lastTotal-this.lastNeed;return t+this.lastChar.toString("utf16le",0,r)}return t}function base64Text(e,t){var r=(e.length-t)%3;if(r===0)return e.toString("base64",t);this.lastNeed=3-r;this.lastTotal=3;if(r===1){this.lastChar[0]=e[e.length-1]}else{this.lastChar[0]=e[e.length-2];this.lastChar[1]=e[e.length-1]}return e.toString("base64",t,e.length-r)}function base64End(e){var t=e&&e.length?this.write(e):"";if(this.lastNeed)return t+this.lastChar.toString("base64",0,3-this.lastNeed);return t}function simpleWrite(e){return e.toString(this.encoding)}function simpleEnd(e){return e&&e.length?this.write(e):""}},6124:(e,t,r)=>{e.exports=r(3837).deprecate},1365:(e,t,r)=>{"use strict";var s=r(5663);t.center=alignCenter;t.left=alignLeft;t.right=alignRight;function createPadding(e){var t="";var r=" ";var s=e;do{if(s%2){t+=r}s=Math.floor(s/2);r+=r}while(s);return t}function alignLeft(e,t){var r=e.trimRight();if(r.length===0&&e.length>=t)return e;var a="";var o=s(r);if(o=t)return e;var a="";var o=s(r);if(o=t)return e;var a="";var o="";var u=s(r);if(u{module.exports=eval("require")("aws-sdk")},3930:module=>{module.exports=eval("require")("mock-aws-s3")},4997:module=>{module.exports=eval("require")("nock")},9491:e=>{"use strict";e.exports=require("assert")},4300:e=>{"use strict";e.exports=require("buffer")},2081:e=>{"use strict";e.exports=require("child_process")},2057:e=>{"use strict";e.exports=require("constants")},2361:e=>{"use strict";e.exports=require("events")},7147:e=>{"use strict";e.exports=require("fs")},8188:e=>{"use strict";e.exports=require("module")},1988:e=>{"use strict";e.exports=require("next/dist/compiled/acorn")},5749:e=>{"use strict";e.exports=require("next/dist/compiled/async-sema")},3535:e=>{"use strict";e.exports=require("next/dist/compiled/glob")},2540:e=>{"use strict";e.exports=require("next/dist/compiled/micromatch")},7849:e=>{"use strict";e.exports=require("next/dist/compiled/semver")},7518:e=>{"use strict";e.exports=require("next/dist/compiled/strip-ansi")},2037:e=>{"use strict";e.exports=require("os")},1017:e=>{"use strict";e.exports=require("path")},8102:e=>{"use strict";e.exports=require("repl")},2781:e=>{"use strict";e.exports=require("stream")},7310:e=>{"use strict";e.exports=require("url")},3837:e=>{"use strict";e.exports=require("util")},9663:(e,t,r)=>{"use strict";Object.defineProperty(t,"__esModule",{value:true});var s=r(1017);var a=r(3846);function _interopDefaultLegacy(e){return e&&typeof e==="object"&&"default"in e?e:{default:e}}var o=_interopDefaultLegacy(a);const u=function addExtension(e,t=".js"){let r=`${e}`;if(!s.extname(e))r+=t;return r};class WalkerBase{constructor(){WalkerBase.prototype.__init.call(this);WalkerBase.prototype.__init2.call(this);WalkerBase.prototype.__init3.call(this);WalkerBase.prototype.__init4.call(this)}__init(){this.should_skip=false}__init2(){this.should_remove=false}__init3(){this.replacement=null}__init4(){this.context={skip:()=>this.should_skip=true,remove:()=>this.should_remove=true,replace:e=>this.replacement=e}}replace(e,t,r,s){if(e){if(r!==null){e[t][r]=s}else{e[t]=s}}}remove(e,t,r){if(e){if(r!==null){e[t].splice(r,1)}else{delete e[t]}}}}class SyncWalkerClass extends WalkerBase{constructor(e){super();this.enter=e.enter;this.leave=e.leave}visit(e,t,r,s,a,o){if(e){if(r){const s=this.should_skip;const u=this.should_remove;const c=this.replacement;this.should_skip=false;this.should_remove=false;this.replacement=null;r.call(this.context,e,t,a,o);if(this.replacement){e=this.replacement;this.replace(t,a,o,e)}if(this.should_remove){this.remove(t,a,o)}const f=this.should_skip;const d=this.should_remove;this.should_skip=s;this.should_remove=u;this.replacement=c;if(f)return e;if(d)return null}for(const t in e){const a=e[t];if(typeof a!=="object"){continue}else if(Array.isArray(a)){for(let o=0;o{f(e).forEach((e=>{this.declarations[e]=true}))}))}}addDeclaration(e,t,r){if(!t&&this.isBlockScope){this.parent.addDeclaration(e,t,r)}else if(e.id){f(e.id).forEach((e=>{this.declarations[e]=true}))}}contains(e){return this.declarations[e]||(this.parent?this.parent.contains(e):false)}}const p=function attachScopes(e,t="scope"){let r=new Scope;walk(e,{enter(e,s){const a=e;if(/(Function|Class)Declaration/.test(a.type)){r.addDeclaration(a,false,false)}if(a.type==="VariableDeclaration"){const{kind:e}=a;const t=d[e];a.declarations.forEach((e=>{r.addDeclaration(e,t,true)}))}let o;if(/Function/.test(a.type)){const e=a;o=new Scope({parent:r,block:false,params:e.params});if(e.type==="FunctionExpression"&&e.id){o.addDeclaration(e,false,false)}}if(/For(In|Of)?Statement/.test(a.type)){o=new Scope({parent:r,block:true})}if(a.type==="BlockStatement"&&!/Function/.test(s.type)){o=new Scope({parent:r,block:true})}if(a.type==="CatchClause"){o=new Scope({parent:r,params:a.param?[a.param]:[],block:true})}if(o){Object.defineProperty(a,t,{value:o,configurable:true});r=o}},leave(e){const s=e;if(s[t])r=r.parent}});return r};function isArray(e){return Array.isArray(e)}function ensureArray(e){if(isArray(e))return e;if(e==null)return[];return[e]}const h=function normalizePath(e){return e.split(s.win32.sep).join(s.posix.sep)};function getMatcherString(e,t){if(t===false||s.isAbsolute(e)||e.startsWith("*")){return h(e)}const r=h(s.resolve(t||"")).replace(/[-^$*+?.()|[\]{}]/g,"\\$&");return s.posix.join(r,h(e))}const v=function createFilter(e,t,r){const s=r&&r.resolve;const getMatcher=e=>e instanceof RegExp?e:{test:t=>{const r=getMatcherString(e,s);const a=o["default"](r,{dot:true});const u=a(t);return u}};const a=ensureArray(e).map(getMatcher);const u=ensureArray(t).map(getMatcher);return function result(e){if(typeof e!=="string")return false;if(/\0/.test(e))return false;const t=h(e);for(let e=0;et.toUpperCase())).replace(/[^$_a-zA-Z0-9]/g,"_");if(/\d/.test(t[0])||y.has(t)){t=`_${t}`}return t||"_"};function stringify(e){return(JSON.stringify(e)||"undefined").replace(/[\u2028\u2029]/g,(e=>`\\u${`000${e.charCodeAt(0).toString(16)}`.slice(-4)}`))}function serializeArray(e,t,r){let s="[";const a=t?`\n${r}${t}`:"";for(let o=0;o0?",":""}${a}${serialize(u,t,r+t)}`}return`${s}${t?`\n${r}`:""}]`}function serializeObject(e,t,r){let s="{";const a=t?`\n${r}${t}`:"";const o=Object.entries(e);for(let e=0;e0?",":""}${a}${f}:${t?" ":""}${serialize(c,t,r+t)}`}return`${s}${t?`\n${r}`:""}}`}function serialize(e,t,r){if(typeof e==="object"&&e!==null){if(Array.isArray(e))return serializeArray(e,t,r);if(e instanceof Date)return`new Date(${e.getTime()})`;if(e instanceof RegExp)return e.toString();return serializeObject(e,t,r)}if(typeof e==="number"){if(e===Infinity)return"Infinity";if(e===-Infinity)return"-Infinity";if(e===0)return 1/e===Infinity?"0":"-0";if(e!==e)return"NaN"}if(typeof e==="symbol"){const t=Symbol.keyFor(e);if(t!==undefined)return`Symbol.for(${stringify(t)})`}if(typeof e==="bigint")return`${e}n`;return stringify(e)}const _=function dataToEsm(e,t={}){const r=t.compact?"":"indent"in t?t.indent:"\t";const s=t.compact?"":" ";const a=t.compact?"":"\n";const o=t.preferConst?"const":"var";if(t.namedExports===false||typeof e!=="object"||Array.isArray(e)||e instanceof Date||e instanceof RegExp||e===null){const a=serialize(e,t.compact?null:r,"");const o=s||(/^[{[\-\/]/.test(a)?"":" ");return`export default${o}${a};`}let u="";const c=[];for(const[f,d]of Object.entries(e)){if(f===m(f)){if(t.objectShorthand)c.push(f);else c.push(`${f}:${s}${f}`);u+=`export ${o} ${f}${s}=${s}${serialize(d,t.compact?null:r,"")};${a}`}else{c.push(`${stringify(f)}:${s}${serialize(d,t.compact?null:r,"")}`)}}return`${u}export default${s}{${a}${r}${c.join(`,${a}${r}`)}${a}};${a}`};var E={addExtension:u,attachScopes:p,createFilter:v,dataToEsm:_,extractAssignedNames:f,makeLegalIdentifier:m,normalizePath:h};t.addExtension=u;t.attachScopes=p;t.createFilter=v;t.dataToEsm=_;t["default"]=E;t.extractAssignedNames=f;t.makeLegalIdentifier=m;t.normalizePath=h},3982:function(e,t){(function(e,r){true?r(t):0})(this,(function(e){"use strict";class WalkerBase{constructor(){this.should_skip=false;this.should_remove=false;this.replacement=null;this.context={skip:()=>this.should_skip=true,remove:()=>this.should_remove=true,replace:e=>this.replacement=e}}replace(e,t,r,s){if(e){if(r!==null){e[t][r]=s}else{e[t]=s}}}remove(e,t,r){if(e){if(r!==null){e[t].splice(r,1)}else{delete e[t]}}}}class SyncWalker extends WalkerBase{constructor(e,t){super();this.enter=e;this.leave=t}visit(e,t,r,s){if(e){if(this.enter){const a=this.should_skip;const o=this.should_remove;const u=this.replacement;this.should_skip=false;this.should_remove=false;this.replacement=null;this.enter.call(this.context,e,t,r,s);if(this.replacement){e=this.replacement;this.replace(t,r,s,e)}if(this.should_remove){this.remove(t,r,s)}const c=this.should_skip;const f=this.should_remove;this.should_skip=a;this.should_remove=o;this.replacement=u;if(c)return e;if(f)return null}for(const t in e){const r=e[t];if(typeof r!=="object"){continue}else if(Array.isArray(r)){for(let s=0;s{"use strict";e.exports=JSON.parse('{"0.1.14":{"node_abi":null,"v8":"1.3"},"0.1.15":{"node_abi":null,"v8":"1.3"},"0.1.16":{"node_abi":null,"v8":"1.3"},"0.1.17":{"node_abi":null,"v8":"1.3"},"0.1.18":{"node_abi":null,"v8":"1.3"},"0.1.19":{"node_abi":null,"v8":"2.0"},"0.1.20":{"node_abi":null,"v8":"2.0"},"0.1.21":{"node_abi":null,"v8":"2.0"},"0.1.22":{"node_abi":null,"v8":"2.0"},"0.1.23":{"node_abi":null,"v8":"2.0"},"0.1.24":{"node_abi":null,"v8":"2.0"},"0.1.25":{"node_abi":null,"v8":"2.0"},"0.1.26":{"node_abi":null,"v8":"2.0"},"0.1.27":{"node_abi":null,"v8":"2.1"},"0.1.28":{"node_abi":null,"v8":"2.1"},"0.1.29":{"node_abi":null,"v8":"2.1"},"0.1.30":{"node_abi":null,"v8":"2.1"},"0.1.31":{"node_abi":null,"v8":"2.1"},"0.1.32":{"node_abi":null,"v8":"2.1"},"0.1.33":{"node_abi":null,"v8":"2.1"},"0.1.90":{"node_abi":null,"v8":"2.2"},"0.1.91":{"node_abi":null,"v8":"2.2"},"0.1.92":{"node_abi":null,"v8":"2.2"},"0.1.93":{"node_abi":null,"v8":"2.2"},"0.1.94":{"node_abi":null,"v8":"2.2"},"0.1.95":{"node_abi":null,"v8":"2.2"},"0.1.96":{"node_abi":null,"v8":"2.2"},"0.1.97":{"node_abi":null,"v8":"2.2"},"0.1.98":{"node_abi":null,"v8":"2.2"},"0.1.99":{"node_abi":null,"v8":"2.2"},"0.1.100":{"node_abi":null,"v8":"2.2"},"0.1.101":{"node_abi":null,"v8":"2.3"},"0.1.102":{"node_abi":null,"v8":"2.3"},"0.1.103":{"node_abi":null,"v8":"2.3"},"0.1.104":{"node_abi":null,"v8":"2.3"},"0.2.0":{"node_abi":1,"v8":"2.3"},"0.2.1":{"node_abi":1,"v8":"2.3"},"0.2.2":{"node_abi":1,"v8":"2.3"},"0.2.3":{"node_abi":1,"v8":"2.3"},"0.2.4":{"node_abi":1,"v8":"2.3"},"0.2.5":{"node_abi":1,"v8":"2.3"},"0.2.6":{"node_abi":1,"v8":"2.3"},"0.3.0":{"node_abi":1,"v8":"2.5"},"0.3.1":{"node_abi":1,"v8":"2.5"},"0.3.2":{"node_abi":1,"v8":"3.0"},"0.3.3":{"node_abi":1,"v8":"3.0"},"0.3.4":{"node_abi":1,"v8":"3.0"},"0.3.5":{"node_abi":1,"v8":"3.0"},"0.3.6":{"node_abi":1,"v8":"3.0"},"0.3.7":{"node_abi":1,"v8":"3.0"},"0.3.8":{"node_abi":1,"v8":"3.1"},"0.4.0":{"node_abi":1,"v8":"3.1"},"0.4.1":{"node_abi":1,"v8":"3.1"},"0.4.2":{"node_abi":1,"v8":"3.1"},"0.4.3":{"node_abi":1,"v8":"3.1"},"0.4.4":{"node_abi":1,"v8":"3.1"},"0.4.5":{"node_abi":1,"v8":"3.1"},"0.4.6":{"node_abi":1,"v8":"3.1"},"0.4.7":{"node_abi":1,"v8":"3.1"},"0.4.8":{"node_abi":1,"v8":"3.1"},"0.4.9":{"node_abi":1,"v8":"3.1"},"0.4.10":{"node_abi":1,"v8":"3.1"},"0.4.11":{"node_abi":1,"v8":"3.1"},"0.4.12":{"node_abi":1,"v8":"3.1"},"0.5.0":{"node_abi":1,"v8":"3.1"},"0.5.1":{"node_abi":1,"v8":"3.4"},"0.5.2":{"node_abi":1,"v8":"3.4"},"0.5.3":{"node_abi":1,"v8":"3.4"},"0.5.4":{"node_abi":1,"v8":"3.5"},"0.5.5":{"node_abi":1,"v8":"3.5"},"0.5.6":{"node_abi":1,"v8":"3.6"},"0.5.7":{"node_abi":1,"v8":"3.6"},"0.5.8":{"node_abi":1,"v8":"3.6"},"0.5.9":{"node_abi":1,"v8":"3.6"},"0.5.10":{"node_abi":1,"v8":"3.7"},"0.6.0":{"node_abi":1,"v8":"3.6"},"0.6.1":{"node_abi":1,"v8":"3.6"},"0.6.2":{"node_abi":1,"v8":"3.6"},"0.6.3":{"node_abi":1,"v8":"3.6"},"0.6.4":{"node_abi":1,"v8":"3.6"},"0.6.5":{"node_abi":1,"v8":"3.6"},"0.6.6":{"node_abi":1,"v8":"3.6"},"0.6.7":{"node_abi":1,"v8":"3.6"},"0.6.8":{"node_abi":1,"v8":"3.6"},"0.6.9":{"node_abi":1,"v8":"3.6"},"0.6.10":{"node_abi":1,"v8":"3.6"},"0.6.11":{"node_abi":1,"v8":"3.6"},"0.6.12":{"node_abi":1,"v8":"3.6"},"0.6.13":{"node_abi":1,"v8":"3.6"},"0.6.14":{"node_abi":1,"v8":"3.6"},"0.6.15":{"node_abi":1,"v8":"3.6"},"0.6.16":{"node_abi":1,"v8":"3.6"},"0.6.17":{"node_abi":1,"v8":"3.6"},"0.6.18":{"node_abi":1,"v8":"3.6"},"0.6.19":{"node_abi":1,"v8":"3.6"},"0.6.20":{"node_abi":1,"v8":"3.6"},"0.6.21":{"node_abi":1,"v8":"3.6"},"0.7.0":{"node_abi":1,"v8":"3.8"},"0.7.1":{"node_abi":1,"v8":"3.8"},"0.7.2":{"node_abi":1,"v8":"3.8"},"0.7.3":{"node_abi":1,"v8":"3.9"},"0.7.4":{"node_abi":1,"v8":"3.9"},"0.7.5":{"node_abi":1,"v8":"3.9"},"0.7.6":{"node_abi":1,"v8":"3.9"},"0.7.7":{"node_abi":1,"v8":"3.9"},"0.7.8":{"node_abi":1,"v8":"3.9"},"0.7.9":{"node_abi":1,"v8":"3.11"},"0.7.10":{"node_abi":1,"v8":"3.9"},"0.7.11":{"node_abi":1,"v8":"3.11"},"0.7.12":{"node_abi":1,"v8":"3.11"},"0.8.0":{"node_abi":1,"v8":"3.11"},"0.8.1":{"node_abi":1,"v8":"3.11"},"0.8.2":{"node_abi":1,"v8":"3.11"},"0.8.3":{"node_abi":1,"v8":"3.11"},"0.8.4":{"node_abi":1,"v8":"3.11"},"0.8.5":{"node_abi":1,"v8":"3.11"},"0.8.6":{"node_abi":1,"v8":"3.11"},"0.8.7":{"node_abi":1,"v8":"3.11"},"0.8.8":{"node_abi":1,"v8":"3.11"},"0.8.9":{"node_abi":1,"v8":"3.11"},"0.8.10":{"node_abi":1,"v8":"3.11"},"0.8.11":{"node_abi":1,"v8":"3.11"},"0.8.12":{"node_abi":1,"v8":"3.11"},"0.8.13":{"node_abi":1,"v8":"3.11"},"0.8.14":{"node_abi":1,"v8":"3.11"},"0.8.15":{"node_abi":1,"v8":"3.11"},"0.8.16":{"node_abi":1,"v8":"3.11"},"0.8.17":{"node_abi":1,"v8":"3.11"},"0.8.18":{"node_abi":1,"v8":"3.11"},"0.8.19":{"node_abi":1,"v8":"3.11"},"0.8.20":{"node_abi":1,"v8":"3.11"},"0.8.21":{"node_abi":1,"v8":"3.11"},"0.8.22":{"node_abi":1,"v8":"3.11"},"0.8.23":{"node_abi":1,"v8":"3.11"},"0.8.24":{"node_abi":1,"v8":"3.11"},"0.8.25":{"node_abi":1,"v8":"3.11"},"0.8.26":{"node_abi":1,"v8":"3.11"},"0.8.27":{"node_abi":1,"v8":"3.11"},"0.8.28":{"node_abi":1,"v8":"3.11"},"0.9.0":{"node_abi":1,"v8":"3.11"},"0.9.1":{"node_abi":10,"v8":"3.11"},"0.9.2":{"node_abi":10,"v8":"3.11"},"0.9.3":{"node_abi":10,"v8":"3.13"},"0.9.4":{"node_abi":10,"v8":"3.13"},"0.9.5":{"node_abi":10,"v8":"3.13"},"0.9.6":{"node_abi":10,"v8":"3.15"},"0.9.7":{"node_abi":10,"v8":"3.15"},"0.9.8":{"node_abi":10,"v8":"3.15"},"0.9.9":{"node_abi":11,"v8":"3.15"},"0.9.10":{"node_abi":11,"v8":"3.15"},"0.9.11":{"node_abi":11,"v8":"3.14"},"0.9.12":{"node_abi":11,"v8":"3.14"},"0.10.0":{"node_abi":11,"v8":"3.14"},"0.10.1":{"node_abi":11,"v8":"3.14"},"0.10.2":{"node_abi":11,"v8":"3.14"},"0.10.3":{"node_abi":11,"v8":"3.14"},"0.10.4":{"node_abi":11,"v8":"3.14"},"0.10.5":{"node_abi":11,"v8":"3.14"},"0.10.6":{"node_abi":11,"v8":"3.14"},"0.10.7":{"node_abi":11,"v8":"3.14"},"0.10.8":{"node_abi":11,"v8":"3.14"},"0.10.9":{"node_abi":11,"v8":"3.14"},"0.10.10":{"node_abi":11,"v8":"3.14"},"0.10.11":{"node_abi":11,"v8":"3.14"},"0.10.12":{"node_abi":11,"v8":"3.14"},"0.10.13":{"node_abi":11,"v8":"3.14"},"0.10.14":{"node_abi":11,"v8":"3.14"},"0.10.15":{"node_abi":11,"v8":"3.14"},"0.10.16":{"node_abi":11,"v8":"3.14"},"0.10.17":{"node_abi":11,"v8":"3.14"},"0.10.18":{"node_abi":11,"v8":"3.14"},"0.10.19":{"node_abi":11,"v8":"3.14"},"0.10.20":{"node_abi":11,"v8":"3.14"},"0.10.21":{"node_abi":11,"v8":"3.14"},"0.10.22":{"node_abi":11,"v8":"3.14"},"0.10.23":{"node_abi":11,"v8":"3.14"},"0.10.24":{"node_abi":11,"v8":"3.14"},"0.10.25":{"node_abi":11,"v8":"3.14"},"0.10.26":{"node_abi":11,"v8":"3.14"},"0.10.27":{"node_abi":11,"v8":"3.14"},"0.10.28":{"node_abi":11,"v8":"3.14"},"0.10.29":{"node_abi":11,"v8":"3.14"},"0.10.30":{"node_abi":11,"v8":"3.14"},"0.10.31":{"node_abi":11,"v8":"3.14"},"0.10.32":{"node_abi":11,"v8":"3.14"},"0.10.33":{"node_abi":11,"v8":"3.14"},"0.10.34":{"node_abi":11,"v8":"3.14"},"0.10.35":{"node_abi":11,"v8":"3.14"},"0.10.36":{"node_abi":11,"v8":"3.14"},"0.10.37":{"node_abi":11,"v8":"3.14"},"0.10.38":{"node_abi":11,"v8":"3.14"},"0.10.39":{"node_abi":11,"v8":"3.14"},"0.10.40":{"node_abi":11,"v8":"3.14"},"0.10.41":{"node_abi":11,"v8":"3.14"},"0.10.42":{"node_abi":11,"v8":"3.14"},"0.10.43":{"node_abi":11,"v8":"3.14"},"0.10.44":{"node_abi":11,"v8":"3.14"},"0.10.45":{"node_abi":11,"v8":"3.14"},"0.10.46":{"node_abi":11,"v8":"3.14"},"0.10.47":{"node_abi":11,"v8":"3.14"},"0.10.48":{"node_abi":11,"v8":"3.14"},"0.11.0":{"node_abi":12,"v8":"3.17"},"0.11.1":{"node_abi":12,"v8":"3.18"},"0.11.2":{"node_abi":12,"v8":"3.19"},"0.11.3":{"node_abi":12,"v8":"3.19"},"0.11.4":{"node_abi":12,"v8":"3.20"},"0.11.5":{"node_abi":12,"v8":"3.20"},"0.11.6":{"node_abi":12,"v8":"3.20"},"0.11.7":{"node_abi":12,"v8":"3.20"},"0.11.8":{"node_abi":13,"v8":"3.21"},"0.11.9":{"node_abi":13,"v8":"3.22"},"0.11.10":{"node_abi":13,"v8":"3.22"},"0.11.11":{"node_abi":14,"v8":"3.22"},"0.11.12":{"node_abi":14,"v8":"3.22"},"0.11.13":{"node_abi":14,"v8":"3.25"},"0.11.14":{"node_abi":14,"v8":"3.26"},"0.11.15":{"node_abi":14,"v8":"3.28"},"0.11.16":{"node_abi":14,"v8":"3.28"},"0.12.0":{"node_abi":14,"v8":"3.28"},"0.12.1":{"node_abi":14,"v8":"3.28"},"0.12.2":{"node_abi":14,"v8":"3.28"},"0.12.3":{"node_abi":14,"v8":"3.28"},"0.12.4":{"node_abi":14,"v8":"3.28"},"0.12.5":{"node_abi":14,"v8":"3.28"},"0.12.6":{"node_abi":14,"v8":"3.28"},"0.12.7":{"node_abi":14,"v8":"3.28"},"0.12.8":{"node_abi":14,"v8":"3.28"},"0.12.9":{"node_abi":14,"v8":"3.28"},"0.12.10":{"node_abi":14,"v8":"3.28"},"0.12.11":{"node_abi":14,"v8":"3.28"},"0.12.12":{"node_abi":14,"v8":"3.28"},"0.12.13":{"node_abi":14,"v8":"3.28"},"0.12.14":{"node_abi":14,"v8":"3.28"},"0.12.15":{"node_abi":14,"v8":"3.28"},"0.12.16":{"node_abi":14,"v8":"3.28"},"0.12.17":{"node_abi":14,"v8":"3.28"},"0.12.18":{"node_abi":14,"v8":"3.28"},"1.0.0":{"node_abi":42,"v8":"3.31"},"1.0.1":{"node_abi":42,"v8":"3.31"},"1.0.2":{"node_abi":42,"v8":"3.31"},"1.0.3":{"node_abi":42,"v8":"4.1"},"1.0.4":{"node_abi":42,"v8":"4.1"},"1.1.0":{"node_abi":43,"v8":"4.1"},"1.2.0":{"node_abi":43,"v8":"4.1"},"1.3.0":{"node_abi":43,"v8":"4.1"},"1.4.1":{"node_abi":43,"v8":"4.1"},"1.4.2":{"node_abi":43,"v8":"4.1"},"1.4.3":{"node_abi":43,"v8":"4.1"},"1.5.0":{"node_abi":43,"v8":"4.1"},"1.5.1":{"node_abi":43,"v8":"4.1"},"1.6.0":{"node_abi":43,"v8":"4.1"},"1.6.1":{"node_abi":43,"v8":"4.1"},"1.6.2":{"node_abi":43,"v8":"4.1"},"1.6.3":{"node_abi":43,"v8":"4.1"},"1.6.4":{"node_abi":43,"v8":"4.1"},"1.7.1":{"node_abi":43,"v8":"4.1"},"1.8.1":{"node_abi":43,"v8":"4.1"},"1.8.2":{"node_abi":43,"v8":"4.1"},"1.8.3":{"node_abi":43,"v8":"4.1"},"1.8.4":{"node_abi":43,"v8":"4.1"},"2.0.0":{"node_abi":44,"v8":"4.2"},"2.0.1":{"node_abi":44,"v8":"4.2"},"2.0.2":{"node_abi":44,"v8":"4.2"},"2.1.0":{"node_abi":44,"v8":"4.2"},"2.2.0":{"node_abi":44,"v8":"4.2"},"2.2.1":{"node_abi":44,"v8":"4.2"},"2.3.0":{"node_abi":44,"v8":"4.2"},"2.3.1":{"node_abi":44,"v8":"4.2"},"2.3.2":{"node_abi":44,"v8":"4.2"},"2.3.3":{"node_abi":44,"v8":"4.2"},"2.3.4":{"node_abi":44,"v8":"4.2"},"2.4.0":{"node_abi":44,"v8":"4.2"},"2.5.0":{"node_abi":44,"v8":"4.2"},"3.0.0":{"node_abi":45,"v8":"4.4"},"3.1.0":{"node_abi":45,"v8":"4.4"},"3.2.0":{"node_abi":45,"v8":"4.4"},"3.3.0":{"node_abi":45,"v8":"4.4"},"3.3.1":{"node_abi":45,"v8":"4.4"},"4.0.0":{"node_abi":46,"v8":"4.5"},"4.1.0":{"node_abi":46,"v8":"4.5"},"4.1.1":{"node_abi":46,"v8":"4.5"},"4.1.2":{"node_abi":46,"v8":"4.5"},"4.2.0":{"node_abi":46,"v8":"4.5"},"4.2.1":{"node_abi":46,"v8":"4.5"},"4.2.2":{"node_abi":46,"v8":"4.5"},"4.2.3":{"node_abi":46,"v8":"4.5"},"4.2.4":{"node_abi":46,"v8":"4.5"},"4.2.5":{"node_abi":46,"v8":"4.5"},"4.2.6":{"node_abi":46,"v8":"4.5"},"4.3.0":{"node_abi":46,"v8":"4.5"},"4.3.1":{"node_abi":46,"v8":"4.5"},"4.3.2":{"node_abi":46,"v8":"4.5"},"4.4.0":{"node_abi":46,"v8":"4.5"},"4.4.1":{"node_abi":46,"v8":"4.5"},"4.4.2":{"node_abi":46,"v8":"4.5"},"4.4.3":{"node_abi":46,"v8":"4.5"},"4.4.4":{"node_abi":46,"v8":"4.5"},"4.4.5":{"node_abi":46,"v8":"4.5"},"4.4.6":{"node_abi":46,"v8":"4.5"},"4.4.7":{"node_abi":46,"v8":"4.5"},"4.5.0":{"node_abi":46,"v8":"4.5"},"4.6.0":{"node_abi":46,"v8":"4.5"},"4.6.1":{"node_abi":46,"v8":"4.5"},"4.6.2":{"node_abi":46,"v8":"4.5"},"4.7.0":{"node_abi":46,"v8":"4.5"},"4.7.1":{"node_abi":46,"v8":"4.5"},"4.7.2":{"node_abi":46,"v8":"4.5"},"4.7.3":{"node_abi":46,"v8":"4.5"},"4.8.0":{"node_abi":46,"v8":"4.5"},"4.8.1":{"node_abi":46,"v8":"4.5"},"4.8.2":{"node_abi":46,"v8":"4.5"},"4.8.3":{"node_abi":46,"v8":"4.5"},"4.8.4":{"node_abi":46,"v8":"4.5"},"4.8.5":{"node_abi":46,"v8":"4.5"},"4.8.6":{"node_abi":46,"v8":"4.5"},"4.8.7":{"node_abi":46,"v8":"4.5"},"4.9.0":{"node_abi":46,"v8":"4.5"},"4.9.1":{"node_abi":46,"v8":"4.5"},"5.0.0":{"node_abi":47,"v8":"4.6"},"5.1.0":{"node_abi":47,"v8":"4.6"},"5.1.1":{"node_abi":47,"v8":"4.6"},"5.2.0":{"node_abi":47,"v8":"4.6"},"5.3.0":{"node_abi":47,"v8":"4.6"},"5.4.0":{"node_abi":47,"v8":"4.6"},"5.4.1":{"node_abi":47,"v8":"4.6"},"5.5.0":{"node_abi":47,"v8":"4.6"},"5.6.0":{"node_abi":47,"v8":"4.6"},"5.7.0":{"node_abi":47,"v8":"4.6"},"5.7.1":{"node_abi":47,"v8":"4.6"},"5.8.0":{"node_abi":47,"v8":"4.6"},"5.9.0":{"node_abi":47,"v8":"4.6"},"5.9.1":{"node_abi":47,"v8":"4.6"},"5.10.0":{"node_abi":47,"v8":"4.6"},"5.10.1":{"node_abi":47,"v8":"4.6"},"5.11.0":{"node_abi":47,"v8":"4.6"},"5.11.1":{"node_abi":47,"v8":"4.6"},"5.12.0":{"node_abi":47,"v8":"4.6"},"6.0.0":{"node_abi":48,"v8":"5.0"},"6.1.0":{"node_abi":48,"v8":"5.0"},"6.2.0":{"node_abi":48,"v8":"5.0"},"6.2.1":{"node_abi":48,"v8":"5.0"},"6.2.2":{"node_abi":48,"v8":"5.0"},"6.3.0":{"node_abi":48,"v8":"5.0"},"6.3.1":{"node_abi":48,"v8":"5.0"},"6.4.0":{"node_abi":48,"v8":"5.0"},"6.5.0":{"node_abi":48,"v8":"5.1"},"6.6.0":{"node_abi":48,"v8":"5.1"},"6.7.0":{"node_abi":48,"v8":"5.1"},"6.8.0":{"node_abi":48,"v8":"5.1"},"6.8.1":{"node_abi":48,"v8":"5.1"},"6.9.0":{"node_abi":48,"v8":"5.1"},"6.9.1":{"node_abi":48,"v8":"5.1"},"6.9.2":{"node_abi":48,"v8":"5.1"},"6.9.3":{"node_abi":48,"v8":"5.1"},"6.9.4":{"node_abi":48,"v8":"5.1"},"6.9.5":{"node_abi":48,"v8":"5.1"},"6.10.0":{"node_abi":48,"v8":"5.1"},"6.10.1":{"node_abi":48,"v8":"5.1"},"6.10.2":{"node_abi":48,"v8":"5.1"},"6.10.3":{"node_abi":48,"v8":"5.1"},"6.11.0":{"node_abi":48,"v8":"5.1"},"6.11.1":{"node_abi":48,"v8":"5.1"},"6.11.2":{"node_abi":48,"v8":"5.1"},"6.11.3":{"node_abi":48,"v8":"5.1"},"6.11.4":{"node_abi":48,"v8":"5.1"},"6.11.5":{"node_abi":48,"v8":"5.1"},"6.12.0":{"node_abi":48,"v8":"5.1"},"6.12.1":{"node_abi":48,"v8":"5.1"},"6.12.2":{"node_abi":48,"v8":"5.1"},"6.12.3":{"node_abi":48,"v8":"5.1"},"6.13.0":{"node_abi":48,"v8":"5.1"},"6.13.1":{"node_abi":48,"v8":"5.1"},"6.14.0":{"node_abi":48,"v8":"5.1"},"6.14.1":{"node_abi":48,"v8":"5.1"},"6.14.2":{"node_abi":48,"v8":"5.1"},"6.14.3":{"node_abi":48,"v8":"5.1"},"6.14.4":{"node_abi":48,"v8":"5.1"},"6.15.0":{"node_abi":48,"v8":"5.1"},"6.15.1":{"node_abi":48,"v8":"5.1"},"6.16.0":{"node_abi":48,"v8":"5.1"},"6.17.0":{"node_abi":48,"v8":"5.1"},"6.17.1":{"node_abi":48,"v8":"5.1"},"7.0.0":{"node_abi":51,"v8":"5.4"},"7.1.0":{"node_abi":51,"v8":"5.4"},"7.2.0":{"node_abi":51,"v8":"5.4"},"7.2.1":{"node_abi":51,"v8":"5.4"},"7.3.0":{"node_abi":51,"v8":"5.4"},"7.4.0":{"node_abi":51,"v8":"5.4"},"7.5.0":{"node_abi":51,"v8":"5.4"},"7.6.0":{"node_abi":51,"v8":"5.5"},"7.7.0":{"node_abi":51,"v8":"5.5"},"7.7.1":{"node_abi":51,"v8":"5.5"},"7.7.2":{"node_abi":51,"v8":"5.5"},"7.7.3":{"node_abi":51,"v8":"5.5"},"7.7.4":{"node_abi":51,"v8":"5.5"},"7.8.0":{"node_abi":51,"v8":"5.5"},"7.9.0":{"node_abi":51,"v8":"5.5"},"7.10.0":{"node_abi":51,"v8":"5.5"},"7.10.1":{"node_abi":51,"v8":"5.5"},"8.0.0":{"node_abi":57,"v8":"5.8"},"8.1.0":{"node_abi":57,"v8":"5.8"},"8.1.1":{"node_abi":57,"v8":"5.8"},"8.1.2":{"node_abi":57,"v8":"5.8"},"8.1.3":{"node_abi":57,"v8":"5.8"},"8.1.4":{"node_abi":57,"v8":"5.8"},"8.2.0":{"node_abi":57,"v8":"5.8"},"8.2.1":{"node_abi":57,"v8":"5.8"},"8.3.0":{"node_abi":57,"v8":"6.0"},"8.4.0":{"node_abi":57,"v8":"6.0"},"8.5.0":{"node_abi":57,"v8":"6.0"},"8.6.0":{"node_abi":57,"v8":"6.0"},"8.7.0":{"node_abi":57,"v8":"6.1"},"8.8.0":{"node_abi":57,"v8":"6.1"},"8.8.1":{"node_abi":57,"v8":"6.1"},"8.9.0":{"node_abi":57,"v8":"6.1"},"8.9.1":{"node_abi":57,"v8":"6.1"},"8.9.2":{"node_abi":57,"v8":"6.1"},"8.9.3":{"node_abi":57,"v8":"6.1"},"8.9.4":{"node_abi":57,"v8":"6.1"},"8.10.0":{"node_abi":57,"v8":"6.2"},"8.11.0":{"node_abi":57,"v8":"6.2"},"8.11.1":{"node_abi":57,"v8":"6.2"},"8.11.2":{"node_abi":57,"v8":"6.2"},"8.11.3":{"node_abi":57,"v8":"6.2"},"8.11.4":{"node_abi":57,"v8":"6.2"},"8.12.0":{"node_abi":57,"v8":"6.2"},"8.13.0":{"node_abi":57,"v8":"6.2"},"8.14.0":{"node_abi":57,"v8":"6.2"},"8.14.1":{"node_abi":57,"v8":"6.2"},"8.15.0":{"node_abi":57,"v8":"6.2"},"8.15.1":{"node_abi":57,"v8":"6.2"},"8.16.0":{"node_abi":57,"v8":"6.2"},"8.16.1":{"node_abi":57,"v8":"6.2"},"8.16.2":{"node_abi":57,"v8":"6.2"},"8.17.0":{"node_abi":57,"v8":"6.2"},"9.0.0":{"node_abi":59,"v8":"6.2"},"9.1.0":{"node_abi":59,"v8":"6.2"},"9.2.0":{"node_abi":59,"v8":"6.2"},"9.2.1":{"node_abi":59,"v8":"6.2"},"9.3.0":{"node_abi":59,"v8":"6.2"},"9.4.0":{"node_abi":59,"v8":"6.2"},"9.5.0":{"node_abi":59,"v8":"6.2"},"9.6.0":{"node_abi":59,"v8":"6.2"},"9.6.1":{"node_abi":59,"v8":"6.2"},"9.7.0":{"node_abi":59,"v8":"6.2"},"9.7.1":{"node_abi":59,"v8":"6.2"},"9.8.0":{"node_abi":59,"v8":"6.2"},"9.9.0":{"node_abi":59,"v8":"6.2"},"9.10.0":{"node_abi":59,"v8":"6.2"},"9.10.1":{"node_abi":59,"v8":"6.2"},"9.11.0":{"node_abi":59,"v8":"6.2"},"9.11.1":{"node_abi":59,"v8":"6.2"},"9.11.2":{"node_abi":59,"v8":"6.2"},"10.0.0":{"node_abi":64,"v8":"6.6"},"10.1.0":{"node_abi":64,"v8":"6.6"},"10.2.0":{"node_abi":64,"v8":"6.6"},"10.2.1":{"node_abi":64,"v8":"6.6"},"10.3.0":{"node_abi":64,"v8":"6.6"},"10.4.0":{"node_abi":64,"v8":"6.7"},"10.4.1":{"node_abi":64,"v8":"6.7"},"10.5.0":{"node_abi":64,"v8":"6.7"},"10.6.0":{"node_abi":64,"v8":"6.7"},"10.7.0":{"node_abi":64,"v8":"6.7"},"10.8.0":{"node_abi":64,"v8":"6.7"},"10.9.0":{"node_abi":64,"v8":"6.8"},"10.10.0":{"node_abi":64,"v8":"6.8"},"10.11.0":{"node_abi":64,"v8":"6.8"},"10.12.0":{"node_abi":64,"v8":"6.8"},"10.13.0":{"node_abi":64,"v8":"6.8"},"10.14.0":{"node_abi":64,"v8":"6.8"},"10.14.1":{"node_abi":64,"v8":"6.8"},"10.14.2":{"node_abi":64,"v8":"6.8"},"10.15.0":{"node_abi":64,"v8":"6.8"},"10.15.1":{"node_abi":64,"v8":"6.8"},"10.15.2":{"node_abi":64,"v8":"6.8"},"10.15.3":{"node_abi":64,"v8":"6.8"},"10.16.0":{"node_abi":64,"v8":"6.8"},"10.16.1":{"node_abi":64,"v8":"6.8"},"10.16.2":{"node_abi":64,"v8":"6.8"},"10.16.3":{"node_abi":64,"v8":"6.8"},"10.17.0":{"node_abi":64,"v8":"6.8"},"10.18.0":{"node_abi":64,"v8":"6.8"},"10.18.1":{"node_abi":64,"v8":"6.8"},"10.19.0":{"node_abi":64,"v8":"6.8"},"10.20.0":{"node_abi":64,"v8":"6.8"},"10.20.1":{"node_abi":64,"v8":"6.8"},"10.21.0":{"node_abi":64,"v8":"6.8"},"10.22.0":{"node_abi":64,"v8":"6.8"},"10.22.1":{"node_abi":64,"v8":"6.8"},"10.23.0":{"node_abi":64,"v8":"6.8"},"10.23.1":{"node_abi":64,"v8":"6.8"},"10.23.2":{"node_abi":64,"v8":"6.8"},"10.23.3":{"node_abi":64,"v8":"6.8"},"10.24.0":{"node_abi":64,"v8":"6.8"},"10.24.1":{"node_abi":64,"v8":"6.8"},"11.0.0":{"node_abi":67,"v8":"7.0"},"11.1.0":{"node_abi":67,"v8":"7.0"},"11.2.0":{"node_abi":67,"v8":"7.0"},"11.3.0":{"node_abi":67,"v8":"7.0"},"11.4.0":{"node_abi":67,"v8":"7.0"},"11.5.0":{"node_abi":67,"v8":"7.0"},"11.6.0":{"node_abi":67,"v8":"7.0"},"11.7.0":{"node_abi":67,"v8":"7.0"},"11.8.0":{"node_abi":67,"v8":"7.0"},"11.9.0":{"node_abi":67,"v8":"7.0"},"11.10.0":{"node_abi":67,"v8":"7.0"},"11.10.1":{"node_abi":67,"v8":"7.0"},"11.11.0":{"node_abi":67,"v8":"7.0"},"11.12.0":{"node_abi":67,"v8":"7.0"},"11.13.0":{"node_abi":67,"v8":"7.0"},"11.14.0":{"node_abi":67,"v8":"7.0"},"11.15.0":{"node_abi":67,"v8":"7.0"},"12.0.0":{"node_abi":72,"v8":"7.4"},"12.1.0":{"node_abi":72,"v8":"7.4"},"12.2.0":{"node_abi":72,"v8":"7.4"},"12.3.0":{"node_abi":72,"v8":"7.4"},"12.3.1":{"node_abi":72,"v8":"7.4"},"12.4.0":{"node_abi":72,"v8":"7.4"},"12.5.0":{"node_abi":72,"v8":"7.5"},"12.6.0":{"node_abi":72,"v8":"7.5"},"12.7.0":{"node_abi":72,"v8":"7.5"},"12.8.0":{"node_abi":72,"v8":"7.5"},"12.8.1":{"node_abi":72,"v8":"7.5"},"12.9.0":{"node_abi":72,"v8":"7.6"},"12.9.1":{"node_abi":72,"v8":"7.6"},"12.10.0":{"node_abi":72,"v8":"7.6"},"12.11.0":{"node_abi":72,"v8":"7.7"},"12.11.1":{"node_abi":72,"v8":"7.7"},"12.12.0":{"node_abi":72,"v8":"7.7"},"12.13.0":{"node_abi":72,"v8":"7.7"},"12.13.1":{"node_abi":72,"v8":"7.7"},"12.14.0":{"node_abi":72,"v8":"7.7"},"12.14.1":{"node_abi":72,"v8":"7.7"},"12.15.0":{"node_abi":72,"v8":"7.7"},"12.16.0":{"node_abi":72,"v8":"7.8"},"12.16.1":{"node_abi":72,"v8":"7.8"},"12.16.2":{"node_abi":72,"v8":"7.8"},"12.16.3":{"node_abi":72,"v8":"7.8"},"12.17.0":{"node_abi":72,"v8":"7.8"},"12.18.0":{"node_abi":72,"v8":"7.8"},"12.18.1":{"node_abi":72,"v8":"7.8"},"12.18.2":{"node_abi":72,"v8":"7.8"},"12.18.3":{"node_abi":72,"v8":"7.8"},"12.18.4":{"node_abi":72,"v8":"7.8"},"12.19.0":{"node_abi":72,"v8":"7.8"},"12.19.1":{"node_abi":72,"v8":"7.8"},"12.20.0":{"node_abi":72,"v8":"7.8"},"12.20.1":{"node_abi":72,"v8":"7.8"},"12.20.2":{"node_abi":72,"v8":"7.8"},"12.21.0":{"node_abi":72,"v8":"7.8"},"12.22.0":{"node_abi":72,"v8":"7.8"},"12.22.1":{"node_abi":72,"v8":"7.8"},"13.0.0":{"node_abi":79,"v8":"7.8"},"13.0.1":{"node_abi":79,"v8":"7.8"},"13.1.0":{"node_abi":79,"v8":"7.8"},"13.2.0":{"node_abi":79,"v8":"7.9"},"13.3.0":{"node_abi":79,"v8":"7.9"},"13.4.0":{"node_abi":79,"v8":"7.9"},"13.5.0":{"node_abi":79,"v8":"7.9"},"13.6.0":{"node_abi":79,"v8":"7.9"},"13.7.0":{"node_abi":79,"v8":"7.9"},"13.8.0":{"node_abi":79,"v8":"7.9"},"13.9.0":{"node_abi":79,"v8":"7.9"},"13.10.0":{"node_abi":79,"v8":"7.9"},"13.10.1":{"node_abi":79,"v8":"7.9"},"13.11.0":{"node_abi":79,"v8":"7.9"},"13.12.0":{"node_abi":79,"v8":"7.9"},"13.13.0":{"node_abi":79,"v8":"7.9"},"13.14.0":{"node_abi":79,"v8":"7.9"},"14.0.0":{"node_abi":83,"v8":"8.1"},"14.1.0":{"node_abi":83,"v8":"8.1"},"14.2.0":{"node_abi":83,"v8":"8.1"},"14.3.0":{"node_abi":83,"v8":"8.1"},"14.4.0":{"node_abi":83,"v8":"8.1"},"14.5.0":{"node_abi":83,"v8":"8.3"},"14.6.0":{"node_abi":83,"v8":"8.4"},"14.7.0":{"node_abi":83,"v8":"8.4"},"14.8.0":{"node_abi":83,"v8":"8.4"},"14.9.0":{"node_abi":83,"v8":"8.4"},"14.10.0":{"node_abi":83,"v8":"8.4"},"14.10.1":{"node_abi":83,"v8":"8.4"},"14.11.0":{"node_abi":83,"v8":"8.4"},"14.12.0":{"node_abi":83,"v8":"8.4"},"14.13.0":{"node_abi":83,"v8":"8.4"},"14.13.1":{"node_abi":83,"v8":"8.4"},"14.14.0":{"node_abi":83,"v8":"8.4"},"14.15.0":{"node_abi":83,"v8":"8.4"},"14.15.1":{"node_abi":83,"v8":"8.4"},"14.15.2":{"node_abi":83,"v8":"8.4"},"14.15.3":{"node_abi":83,"v8":"8.4"},"14.15.4":{"node_abi":83,"v8":"8.4"},"14.15.5":{"node_abi":83,"v8":"8.4"},"14.16.0":{"node_abi":83,"v8":"8.4"},"14.16.1":{"node_abi":83,"v8":"8.4"},"15.0.0":{"node_abi":88,"v8":"8.6"},"15.0.1":{"node_abi":88,"v8":"8.6"},"15.1.0":{"node_abi":88,"v8":"8.6"},"15.2.0":{"node_abi":88,"v8":"8.6"},"15.2.1":{"node_abi":88,"v8":"8.6"},"15.3.0":{"node_abi":88,"v8":"8.6"},"15.4.0":{"node_abi":88,"v8":"8.6"},"15.5.0":{"node_abi":88,"v8":"8.6"},"15.5.1":{"node_abi":88,"v8":"8.6"},"15.6.0":{"node_abi":88,"v8":"8.6"},"15.7.0":{"node_abi":88,"v8":"8.6"},"15.8.0":{"node_abi":88,"v8":"8.6"},"15.9.0":{"node_abi":88,"v8":"8.6"},"15.10.0":{"node_abi":88,"v8":"8.6"},"15.11.0":{"node_abi":88,"v8":"8.6"},"15.12.0":{"node_abi":88,"v8":"8.6"},"15.13.0":{"node_abi":88,"v8":"8.6"},"15.14.0":{"node_abi":88,"v8":"8.6"},"16.0.0":{"node_abi":93,"v8":"9.0"}}')},7399:e=>{"use strict";e.exports=JSON.parse('{"name":"@mapbox/node-pre-gyp","description":"Node.js native addon binary install tool","version":"1.0.5","keywords":["native","addon","module","c","c++","bindings","binary"],"license":"BSD-3-Clause","author":"Dane Springmeyer ","repository":{"type":"git","url":"git://github.com/mapbox/node-pre-gyp.git"},"bin":"./bin/node-pre-gyp","main":"./lib/node-pre-gyp.js","dependencies":{"detect-libc":"^1.0.3","https-proxy-agent":"^5.0.0","make-dir":"^3.1.0","node-fetch":"^2.6.1","nopt":"^5.0.0","npmlog":"^4.1.2","rimraf":"^3.0.2","semver":"^7.3.4","tar":"^6.1.0"},"devDependencies":{"@mapbox/cloudfriend":"^4.6.0","@mapbox/eslint-config-mapbox":"^3.0.0","action-walk":"^2.2.0","aws-sdk":"^2.840.0","codecov":"^3.8.1","eslint":"^7.18.0","eslint-plugin-node":"^11.1.0","mock-aws-s3":"^4.0.1","nock":"^12.0.3","node-addon-api":"^3.1.0","nyc":"^15.1.0","tape":"^5.2.2","tar-fs":"^2.1.1"},"nyc":{"all":true,"skip-full":false,"exclude":["test/**"]},"scripts":{"coverage":"nyc --all --include index.js --include lib/ npm test","upload-coverage":"nyc report --reporter json && codecov --clear --flags=unit --file=./coverage/coverage-final.json","lint":"eslint bin/node-pre-gyp lib/*js lib/util/*js test/*js scripts/*js","fix":"npm run lint -- --fix","update-crosswalk":"node scripts/abi_crosswalk.js","test":"tape test/*test.js"}}')}};var __webpack_module_cache__={};function __nccwpck_require__(e){var t=__webpack_module_cache__[e];if(t!==undefined){return t.exports}var r=__webpack_module_cache__[e]={exports:{}};var s=true;try{__webpack_modules__[e].call(r.exports,r,r.exports,__nccwpck_require__);s=false}finally{if(s)delete __webpack_module_cache__[e]}return r.exports}if(typeof __nccwpck_require__!=="undefined")__nccwpck_require__.ab=__dirname+"/";var __webpack_exports__=__nccwpck_require__(6223);module.exports=__webpack_exports__})(); \ No newline at end of file diff --git a/packages/next/src/lib/fs/rename.ts b/packages/next/src/lib/fs/rename.ts new file mode 100644 index 0000000000000..679bc323e833d --- /dev/null +++ b/packages/next/src/lib/fs/rename.ts @@ -0,0 +1,107 @@ +/* +MIT License + +Copyright (c) 2015 - present Microsoft Corporation + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + */ + +// This file is based on https://github.com/microsoft/vscode/blob/f860fcf11022f10a992440fd54c6e45674e39617/src/vs/base/node/pfs.ts +// See the LICENSE at the top of the file + +import * as fs from 'graceful-fs' +import { promisify } from 'util' + +/** + * A drop-in replacement for `fs.rename` that: + * - allows to move across multiple disks + * - attempts to retry the operation for certain error codes on Windows + */ +export async function rename( + source: string, + target: string, + windowsRetryTimeout: number | false = 60000 /* matches graceful-fs */ +): Promise { + if (source === target) { + return // simulate node.js behaviour here and do a no-op if paths match + } + + if (process.platform === 'win32' && typeof windowsRetryTimeout === 'number') { + // On Windows, a rename can fail when either source or target + // is locked by AV software. We do leverage graceful-fs to iron + // out these issues, however in case the target file exists, + // graceful-fs will immediately return without retry for fs.rename(). + await renameWithRetry(source, target, Date.now(), windowsRetryTimeout) + } else { + await promisify(fs.rename)(source, target) + } +} + +async function renameWithRetry( + source: string, + target: string, + startTime: number, + retryTimeout: number, + attempt = 0 +): Promise { + try { + return await promisify(fs.rename)(source, target) + } catch (error: any) { + if ( + error.code !== 'EACCES' && + error.code !== 'EPERM' && + error.code !== 'EBUSY' + ) { + throw error // only for errors we think are temporary + } + + if (Date.now() - startTime >= retryTimeout) { + console.error( + `[node.js fs] rename failed after ${attempt} retries with error: ${error}` + ) + + throw error // give up after configurable timeout + } + + if (attempt === 0) { + let abortRetry = false + try { + const stat = await promisify(fs.stat)(target) + if (!stat.isFile()) { + abortRetry = true // if target is not a file, EPERM error may be raised and we should not attempt to retry + } + } catch (e) { + // Ignore + } + + if (abortRetry) { + throw error + } + } + + // Delay with incremental backoff up to 100ms + await timeout(Math.min(100, attempt * 10)) + + // Attempt again + return renameWithRetry(source, target, startTime, retryTimeout, attempt + 1) + } +} + +const timeout = (millis: number) => + new Promise((resolve) => setTimeout(resolve, millis)) diff --git a/packages/next/src/lib/fs/write-atomic.ts b/packages/next/src/lib/fs/write-atomic.ts new file mode 100644 index 0000000000000..abe31621d4fa7 --- /dev/null +++ b/packages/next/src/lib/fs/write-atomic.ts @@ -0,0 +1,20 @@ +import { unlink, writeFile } from 'fs/promises' +import { rename } from './rename' + +export async function writeFileAtomic( + filePath: string, + content: string +): Promise { + const tempPath = filePath + '.tmp.' + Math.random().toString(36).slice(2) + try { + await writeFile(tempPath, content, 'utf-8') + await rename(tempPath, filePath) + } catch (e) { + try { + await unlink(tempPath) + } catch { + // ignore + } + throw e + } +} diff --git a/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts b/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts index af3a417c2a462..4e1dea7bb0d13 100644 --- a/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts +++ b/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts @@ -104,7 +104,7 @@ import { getOverlayMiddleware, createOriginalStackFrame as createOriginalTurboStackFrame, } from 'next/dist/compiled/@next/react-dev-overlay/dist/middleware-turbopack' -import { mkdir, readFile, writeFile, rename, unlink } from 'fs/promises' +import { mkdir, readFile, writeFile } from 'fs/promises' import { PageNotFoundError } from '../../../shared/lib/utils' import { type ClientBuildManifest, @@ -128,6 +128,7 @@ import { denormalizePagePath } from '../../../shared/lib/page-path/denormalize-p import type { LoadableManifest } from '../../load-components' import { generateRandomActionKeyRaw } from '../../app-render/action-encryption-utils' import { bold, green, red } from '../../../lib/picocolors' +import { writeFileAtomic } from '../../../lib/fs/write-atomic' const wsServer = new ws.Server({ noServer: true }) @@ -817,24 +818,6 @@ async function startWatcher(opts: SetupOpts) { return manifest } - async function writeFileAtomic( - filePath: string, - content: string - ): Promise { - const tempPath = filePath + '.tmp.' + Math.random().toString(36).slice(2) - try { - await writeFile(tempPath, content, 'utf-8') - await rename(tempPath, filePath) - } catch (e) { - try { - await unlink(tempPath) - } catch { - // ignore - } - throw e - } - } - async function writeBuildManifest( rewrites: SetupOpts['fsChecker']['rewrites'] ): Promise { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index be1463742f0fd..fb362850a9d15 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -814,6 +814,9 @@ importers: caniuse-lite: specifier: 1.0.30001406 version: 1.0.30001406 + graceful-fs: + specifier: ^4.2.11 + version: 4.2.11 postcss: specifier: 8.4.31 version: 8.4.31 @@ -1004,6 +1007,9 @@ importers: '@types/glob': specifier: 7.1.1 version: 7.1.1 + '@types/graceful-fs': + specifier: 4.1.9 + version: 4.1.9 '@types/jsonwebtoken': specifier: 9.0.0 version: 9.0.0 @@ -4223,7 +4229,7 @@ packages: chalk: 4.1.2 convert-source-map: 2.0.0 fast-json-stable-stringify: 2.1.0 - graceful-fs: 4.2.10 + graceful-fs: 4.2.11 jest-haste-map: 29.5.0 jest-regex-util: 29.4.3 jest-util: 29.5.0 @@ -6488,8 +6494,8 @@ packages: '@types/node': 20.2.5 dev: true - /@types/graceful-fs@4.1.3: - resolution: {integrity: sha512-AiHRaEB50LQg0pZmm659vNBb9f4SJ0qrAnteuzhSeAUcJKxoYgEnprg/83kppCnc2zvtCKbdZry1a5pVY3lOTQ==} + /@types/graceful-fs@4.1.9: + resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} dependencies: '@types/node': 20.2.5 dev: true @@ -7149,7 +7155,7 @@ packages: bindings: 1.5.0 estree-walker: 2.0.2 glob: 7.2.0 - graceful-fs: 4.2.10 + graceful-fs: 4.2.11 micromatch: 4.0.4 node-gyp-build: 4.2.3 resolve-from: 5.0.0 @@ -12421,7 +12427,7 @@ packages: engines: {node: '>=10'} dependencies: at-least-node: 1.0.0 - graceful-fs: 4.2.9 + graceful-fs: 4.2.11 jsonfile: 6.0.1 universalify: 1.0.0 dev: true @@ -12965,16 +12971,9 @@ packages: url-parse-lax: 3.0.0 dev: true - /graceful-fs@4.2.10: - resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} - dev: true - /graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} - /graceful-fs@4.2.9: - resolution: {integrity: sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==} - /grapheme-splitter@1.0.4: resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==} @@ -14823,7 +14822,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.5.0 - '@types/graceful-fs': 4.1.3 + '@types/graceful-fs': 4.1.9 '@types/node': 20.2.5 anymatch: 3.1.3 fb-watchman: 2.0.1 @@ -14842,7 +14841,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/types': 29.6.3 - '@types/graceful-fs': 4.1.3 + '@types/graceful-fs': 4.1.9 '@types/node': 20.2.5 anymatch: 3.1.3 fb-watchman: 2.0.1 @@ -15228,7 +15227,7 @@ packages: babel-core: 7.0.0-bridge.0(@babel/core@7.22.5) chalk: 4.1.2 flow-parser: 0.131.0 - graceful-fs: 4.2.9 + graceful-fs: 4.2.11 micromatch: 3.1.10 neo-async: 2.6.2 node-dir: 0.1.17 From 8f2c48272962cd005f9ca6078afde4f4ef9b1052 Mon Sep 17 00:00:00 2001 From: Zack Tanner Date: Mon, 27 Nov 2023 07:29:51 -0800 Subject: [PATCH 054/481] unify server action detection logic (#58879) In anticipation of #58885 (and to avoid adding another spot where we're checking the same headers), this unifies the logic that parses the request headers and determines if the request corresponds with a server action. There was already some drift between the check in `base-server` and `action-handler` (unsure if this was intentional - let me know if so, in which case maybe separated handling is the better approach. I couldn't think of a good reason why it would be different, though). Existing tests should be sufficient for testing this changeset. --- .../src/server/app-render/action-handler.ts | 22 +++++----- packages/next/src/server/base-server.ts | 12 +----- .../server/lib/server-action-request-meta.ts | 41 +++++++++++++++++++ 3 files changed, 54 insertions(+), 21 deletions(-) create mode 100644 packages/next/src/server/lib/server-action-request-meta.ts diff --git a/packages/next/src/server/app-render/action-handler.ts b/packages/next/src/server/app-render/action-handler.ts index a1e3057817468..787ee62d9d575 100644 --- a/packages/next/src/server/app-render/action-handler.ts +++ b/packages/next/src/server/app-render/action-handler.ts @@ -11,7 +11,6 @@ import type { AppRenderContext, GenerateFlight } from './app-render' import type { AppPageModule } from '../../server/future/route-modules/app-page/module' import { - ACTION, RSC_HEADER, RSC_CONTENT_TYPE_HEADER, } from '../../client/components/app-router-headers' @@ -36,6 +35,10 @@ import { NEXT_CACHE_REVALIDATED_TAGS_HEADER, NEXT_CACHE_REVALIDATE_TAG_TOKEN_HEADER, } from '../../lib/constants' +import { + getIsServerAction, + getServerActionRequestMetadata, +} from '../lib/server-action-request-meta' function formDataFromSearchQueryString(query: string) { const searchParams = new URLSearchParams(query) @@ -271,20 +274,13 @@ export async function handleAction({ formState?: any } > { - let actionId = req.headers[ACTION.toLowerCase()] as string const contentType = req.headers['content-type'] - const isURLEncodedAction = - req.method === 'POST' && contentType === 'application/x-www-form-urlencoded' - const isMultipartAction = - req.method === 'POST' && contentType?.startsWith('multipart/form-data') - const isFetchAction = - actionId !== undefined && - typeof actionId === 'string' && - req.method === 'POST' + const { actionId, isURLEncodedAction, isMultipartAction, isFetchAction } = + getServerActionRequestMetadata(req) // If it's not a Server Action, skip handling. - if (!(isFetchAction || isURLEncodedAction || isMultipartAction)) { + if (!getIsServerAction(req)) { return } @@ -528,6 +524,10 @@ To configure the body size limit for Server Actions, see: https://nextjs.org/doc let actionModId: string try { + if (!actionId) { + throw new Error('Invariant: actionId should be set') + } + actionModId = serverModuleMap[actionId].id } catch (err) { // When this happens, it could be a deployment skew where the action came diff --git a/packages/next/src/server/base-server.ts b/packages/next/src/server/base-server.ts index 4bd8258598318..79504e567728d 100644 --- a/packages/next/src/server/base-server.ts +++ b/packages/next/src/server/base-server.ts @@ -82,7 +82,6 @@ import { RSC_HEADER, RSC_VARY_HEADER, NEXT_RSC_UNION_QUERY, - ACTION, NEXT_ROUTER_PREFETCH_HEADER, } from '../client/components/app-router-headers' import type { @@ -129,6 +128,7 @@ import { } from './future/route-modules/checks' import { PrefetchRSCPathnameNormalizer } from './future/normalizers/request/prefetch-rsc' import { NextDataPathnameNormalizer } from './future/normalizers/request/next-data' +import { getIsServerAction } from './lib/server-action-request-meta' export type FindComponentsResult = { components: LoadComponentsReturnType @@ -1749,15 +1749,7 @@ export default abstract class Server { const isAppPath = components.isAppPath === true const hasServerProps = !!components.getServerSideProps let hasStaticPaths = !!components.getStaticPaths - const actionId = req.headers[ACTION.toLowerCase()] as string - const contentType = req.headers['content-type'] - const isMultipartAction = - req.method === 'POST' && contentType?.startsWith('multipart/form-data') - const isFetchAction = - actionId !== undefined && - typeof actionId === 'string' && - req.method === 'POST' - const isServerAction = isFetchAction || isMultipartAction + const isServerAction = getIsServerAction(req) const hasGetInitialProps = !!components.Component?.getInitialProps let isSSG = !!components.getStaticProps diff --git a/packages/next/src/server/lib/server-action-request-meta.ts b/packages/next/src/server/lib/server-action-request-meta.ts new file mode 100644 index 0000000000000..4d18a3dae58fb --- /dev/null +++ b/packages/next/src/server/lib/server-action-request-meta.ts @@ -0,0 +1,41 @@ +import type { IncomingMessage } from 'http' +import type { BaseNextRequest } from '../base-http' +import { ACTION } from '../../client/components/app-router-headers' + +export function getServerActionRequestMetadata( + req: IncomingMessage | BaseNextRequest +): { + actionId: string | null + isURLEncodedAction: boolean + isMultipartAction: boolean + isFetchAction: boolean +} { + let actionId: string | null + let contentType: string | null + + actionId = (req.headers[ACTION.toLowerCase()] as string) ?? null + contentType = req.headers['content-type'] ?? null + + const isURLEncodedAction = Boolean( + req.method === 'POST' && contentType === 'application/x-www-form-urlencoded' + ) + const isMultipartAction = Boolean( + req.method === 'POST' && contentType?.startsWith('multipart/form-data') + ) + const isFetchAction = Boolean( + actionId !== undefined && + typeof actionId === 'string' && + req.method === 'POST' + ) + + return { actionId, isURLEncodedAction, isMultipartAction, isFetchAction } +} + +export function getIsServerAction( + req: IncomingMessage | BaseNextRequest +): boolean { + const { isFetchAction, isURLEncodedAction, isMultipartAction } = + getServerActionRequestMetadata(req) + + return Boolean(isFetchAction || isURLEncodedAction || isMultipartAction) +} From 46bcd11326e0c5cb6d3187075109c7f0d10070a7 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Mon, 27 Nov 2023 16:53:18 +0100 Subject: [PATCH 055/481] Fix nested fetch logging indentation (#58955) The indentation of nested logging requests are not correct ### After ### Before reported by @shuding --- packages/next/src/server/next-server.ts | 19 ++++++++------- .../app-dir/logging/app/default-cache/page.js | 24 +++++++++++++++++-- .../e2e/app-dir/logging/fetch-logging.test.ts | 18 ++++++++++++++ 3 files changed, 50 insertions(+), 11 deletions(-) diff --git a/packages/next/src/server/next-server.ts b/packages/next/src/server/next-server.ts index 7495f46aa0b9d..4380057f10ca1 100644 --- a/packages/next/src/server/next-server.ts +++ b/packages/next/src/server/next-server.ts @@ -1125,7 +1125,7 @@ export default class NextNodeServer extends BaseServer { } } - return `${' │ '.repeat(nestedLevel)}` + return nestedLevel === 0 ? ' ' : `${' │ '.repeat(nestedLevel)}` } for (let i = 0; i < fetchMetrics.length; i++) { @@ -1173,16 +1173,16 @@ export default class NextNodeServer extends BaseServer { if (enabledVerboseLogging) { const newLineLeadingChar = '│' const nestedIndent = calcNestedLevel( - fetchMetrics.slice(0, i), + fetchMetrics.slice(0, i + 1), metric.start ) writeStdoutLine( - `${`${newLineLeadingChar}${nestedIndent}${ - i === 0 ? ' ' : '' - }${white(bold(metric.method))} ${gray(url)} ${ - metric.status - } in ${getDurationStr(duration)} (cache: ${cacheStatus})`}` + ` ${`${newLineLeadingChar}${nestedIndent}${white( + bold(metric.method) + )} ${gray(url)} ${metric.status} in ${getDurationStr( + duration + )} (cache: ${cacheStatus})`}` ) if (cacheReasonStr) { const nextNestedIndent = calcNestedLevel( @@ -1190,9 +1190,10 @@ export default class NextNodeServer extends BaseServer { metric.start ) writeStdoutLine( - newLineLeadingChar + + ' ' + + newLineLeadingChar + nextNestedIndent + - (i > 0 ? ' ' : ' ') + + ' ' + newLineLeadingChar + ' ' + cacheReasonStr diff --git a/test/e2e/app-dir/logging/app/default-cache/page.js b/test/e2e/app-dir/logging/app/default-cache/page.js index aee6e7fdabf6f..6b6b31e1932a6 100644 --- a/test/e2e/app-dir/logging/app/default-cache/page.js +++ b/test/e2e/app-dir/logging/app/default-cache/page.js @@ -1,6 +1,17 @@ export const fetchCache = 'default-cache' -export default async function Page() { +async function AnotherRsc() { + const data = await fetch( + 'https://next-data-api-endpoint.vercel.app/api/random?another-no-cache', + { + cache: 'no-cache', + } + ).then((res) => res.text()) + + return

"another-no-cache" {data}

+} + +async function FirstRsc() { const dataNoCache = await fetch( 'https://next-data-api-endpoint.vercel.app/api/random?no-cache', { @@ -49,7 +60,6 @@ export default async function Page() { return ( <> -

/force-cache

"cache: no-cache" {dataNoCache}

"cache: force-cache" {dataForceCache}

"revalidate: 0" {dataRevalidate0}

@@ -61,3 +71,13 @@ export default async function Page() { ) } + +export default async function Page() { + return ( + <> +

Default Cache

+ + + + ) +} diff --git a/test/e2e/app-dir/logging/fetch-logging.test.ts b/test/e2e/app-dir/logging/fetch-logging.test.ts index f3b81958a758b..885fd61241ab3 100644 --- a/test/e2e/app-dir/logging/fetch-logging.test.ts +++ b/test/e2e/app-dir/logging/fetch-logging.test.ts @@ -118,6 +118,24 @@ createNextDescribe( } }, 'success') }) + + it('should log requests with correct indentation', async () => { + const outputIndex = next.cliOutput.length + await next.fetch('/default-cache') + + await check(() => { + const logs = stripAnsi(next.cliOutput.slice(outputIndex)) + const hasLogs = + logs.includes(' GET /default-cache') && + logs.includes(' │ GET ') && + logs.includes(' │ │ GET ') && + logs.includes(' │ │ Cache missed reason') + + if (hasLogs) { + return 'success' + } + }, 'success') + }) } } else { it('should not log fetch requests at all', async () => { From f7459025cfb3790f6230a1b463915c42576d27ad Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Mon, 27 Nov 2023 11:31:43 -0500 Subject: [PATCH 056/481] Delete preloadComponent module (#58741) We previously used preloadComponent to render nested page/layouts in parallel, but now that all layouts are passed to React at the top level (#58669), we no longer need this special module. A flaw of preloadComponent was that it only called the top-most component per layout. In the new approach, React can preload non-layout components, too. Co-authored-by: Zack Tanner --- .../server/app-render/preload-component.ts | 31 ------------------- 1 file changed, 31 deletions(-) delete mode 100644 packages/next/src/server/app-render/preload-component.ts diff --git a/packages/next/src/server/app-render/preload-component.ts b/packages/next/src/server/app-render/preload-component.ts deleted file mode 100644 index c4b82c006a634..0000000000000 --- a/packages/next/src/server/app-render/preload-component.ts +++ /dev/null @@ -1,31 +0,0 @@ -export function preloadComponent(Component: any, props: any) { - const prev = console.error - // Hide invalid hook call warning when calling component - console.error = function (msg) { - if (msg.startsWith('Warning: Invalid hook call.')) { - // ignore - } else { - // @ts-expect-error argument is defined - prev.apply(console, arguments) - } - } - try { - let result = Component(props) - if (result && typeof result.then === 'function') { - // Catch promise rejections to prevent unhandledRejection errors - result.then( - () => {}, - () => {} - ) - } - return function () { - // We know what this component will render already. - return result - } - } catch (x) { - // something suspended or errored, try again later - } finally { - console.error = prev - } - return Component -} From 1c5ff6e73586b24a560120658f568472773f1a3f Mon Sep 17 00:00:00 2001 From: Andrew Clark Date: Mon, 27 Nov 2023 11:32:10 -0500 Subject: [PATCH 057/481] Remove `cache` field from action types (#58938) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The app router reducer state used to be managed by `useReducer`, so it was written to be resilient to rebasing — the same action may be processed multiple times. Now that we've lifted the reducer outside of React (#56497), each action runs only a single time. So we can simplify some of the logic. Previously, actions that update that cache were passed an empty cache object as part of the action payload. Now, we can instead create these objects on demand in the reducer. (We should do the same for the `mutable` object, but there's a unit test which relies on this implementation detail, so I've left that for a separate PR.) --- .../next/src/client/components/app-router.tsx | 5 -- .../reducers/fast-refresh-reducer.ts | 23 ++++---- .../reducers/navigate-reducer.test.tsx | 54 ------------------- .../reducers/navigate-reducer.ts | 5 +- .../reducers/refresh-reducer.test.tsx | 24 --------- .../reducers/refresh-reducer.ts | 27 +++++----- .../reducers/server-action-reducer.ts | 9 +++- .../reducers/server-patch-reducer.test.tsx | 24 --------- .../reducers/server-patch-reducer.ts | 6 ++- .../router-reducer/router-reducer-types.ts | 5 -- .../src/shared/lib/router/action-queue.ts | 2 - 11 files changed, 41 insertions(+), 143 deletions(-) diff --git a/packages/next/src/client/components/app-router.tsx b/packages/next/src/client/components/app-router.tsx index 0cd0c44abb209..9eed33d73db20 100644 --- a/packages/next/src/client/components/app-router.tsx +++ b/packages/next/src/client/components/app-router.tsx @@ -166,7 +166,6 @@ function useServerActionDispatcher(dispatch: React.Dispatch) { ...actionPayload, type: ACTION_SERVER_ACTION, mutable: {}, - cache: createEmptyCacheNode(), }) }) }, @@ -193,7 +192,6 @@ function useChangeByServerResponse( flightData, previousTree, overrideCanonicalUrl, - cache: createEmptyCacheNode(), mutable: {}, }) }) @@ -214,7 +212,6 @@ function useNavigate(dispatch: React.Dispatch): RouterNavigate { locationSearch: location.search, shouldScroll: shouldScroll ?? true, navigateType, - cache: createEmptyCacheNode(), mutable: {}, }) }, @@ -344,7 +341,6 @@ function Router({ startTransition(() => { dispatch({ type: ACTION_REFRESH, - cache: createEmptyCacheNode(), mutable: {}, origin: window.location.origin, }) @@ -360,7 +356,6 @@ function Router({ startTransition(() => { dispatch({ type: ACTION_FAST_REFRESH, - cache: createEmptyCacheNode(), mutable: {}, origin: window.location.origin, }) diff --git a/packages/next/src/client/components/router-reducer/reducers/fast-refresh-reducer.ts b/packages/next/src/client/components/router-reducer/reducers/fast-refresh-reducer.ts index e02151925823d..fbe499d572e67 100644 --- a/packages/next/src/client/components/router-reducer/reducers/fast-refresh-reducer.ts +++ b/packages/next/src/client/components/router-reducer/reducers/fast-refresh-reducer.ts @@ -10,13 +10,15 @@ import type { import { handleExternalUrl } from './navigate-reducer' import { handleMutable } from '../handle-mutable' import { applyFlightData } from '../apply-flight-data' +import type { CacheNode } from '../../../../shared/lib/app-router-context.shared-runtime' +import { createEmptyCacheNode } from '../../app-router' // A version of refresh reducer that keeps the cache around instead of wiping all of it. function fastRefreshReducerImpl( state: ReadonlyReducerState, action: FastRefreshAction ): ReducerState { - const { cache, mutable, origin } = action + const { mutable, origin } = action const href = state.canonicalUrl const isForCurrentTree = @@ -28,16 +30,15 @@ function fastRefreshReducerImpl( mutable.preserveCustomHistoryState = false - if (!cache.data) { - // TODO-APP: verify that `href` is not an external url. - // Fetch data from the root of the tree. - cache.data = fetchServerResponse( - new URL(href, origin), - [state.tree[0], state.tree[1], state.tree[2], 'refetch'], - state.nextUrl, - state.buildId - ) - } + const cache: CacheNode = createEmptyCacheNode() + // TODO-APP: verify that `href` is not an external url. + // Fetch data from the root of the tree. + cache.data = fetchServerResponse( + new URL(href, origin), + [state.tree[0], state.tree[1], state.tree[2], 'refetch'], + state.nextUrl, + state.buildId + ) return cache.data.then( ([flightData, canonicalUrlOverride]) => { diff --git a/packages/next/src/client/components/router-reducer/reducers/navigate-reducer.test.tsx b/packages/next/src/client/components/router-reducer/reducers/navigate-reducer.test.tsx index 95dbaa10243ce..c757b59ebd935 100644 --- a/packages/next/src/client/components/router-reducer/reducers/navigate-reducer.test.tsx +++ b/packages/next/src/client/components/router-reducer/reducers/navigate-reducer.test.tsx @@ -187,12 +187,6 @@ describe('navigateReducer', () => { locationSearch: '', navigateType: 'push', shouldScroll: true, - cache: { - status: CacheStates.LAZY_INITIALIZED, - data: null, - subTreeData: null, - parallelRoutes: new Map(), - }, mutable: {}, } @@ -401,12 +395,6 @@ describe('navigateReducer', () => { locationSearch: '', navigateType: 'push', shouldScroll: true, - cache: { - status: CacheStates.LAZY_INITIALIZED, - data: null, - subTreeData: null, - parallelRoutes: new Map(), - }, mutable: {}, } @@ -596,12 +584,6 @@ describe('navigateReducer', () => { locationSearch: '', navigateType: 'push', shouldScroll: true, - cache: { - status: CacheStates.LAZY_INITIALIZED, - data: null, - subTreeData: null, - parallelRoutes: new Map(), - }, mutable: {}, } @@ -755,12 +737,6 @@ describe('navigateReducer', () => { locationSearch: '', navigateType: 'replace', shouldScroll: true, - cache: { - status: CacheStates.LAZY_INITIALIZED, - data: null, - subTreeData: null, - parallelRoutes: new Map(), - }, mutable: {}, } @@ -911,12 +887,6 @@ describe('navigateReducer', () => { locationSearch: '', navigateType: 'push', shouldScroll: false, // should not scroll - cache: { - status: CacheStates.LAZY_INITIALIZED, - data: null, - subTreeData: null, - parallelRoutes: new Map(), - }, mutable: {}, } @@ -1081,12 +1051,6 @@ describe('navigateReducer', () => { navigateType: 'push', locationSearch: '', shouldScroll: true, - cache: { - status: CacheStates.LAZY_INITIALIZED, - data: null, - subTreeData: null, - parallelRoutes: new Map(), - }, mutable: {}, } @@ -1364,12 +1328,6 @@ describe('navigateReducer', () => { locationSearch: '', navigateType: 'push', shouldScroll: true, - cache: { - status: CacheStates.LAZY_INITIALIZED, - data: null, - subTreeData: null, - parallelRoutes: new Map(), - }, mutable: {}, } @@ -1569,12 +1527,6 @@ describe('navigateReducer', () => { locationSearch: '', navigateType: 'push', shouldScroll: true, - cache: { - status: CacheStates.LAZY_INITIALIZED, - data: null, - subTreeData: null, - parallelRoutes: new Map(), - }, mutable: { canonicalUrl: '/linking#hash', previousTree: initialTree, @@ -1718,12 +1670,6 @@ describe('navigateReducer', () => { locationSearch: '', navigateType: 'push', shouldScroll: true, - cache: { - status: CacheStates.LAZY_INITIALIZED, - data: null, - subTreeData: null, - parallelRoutes: new Map(), - }, mutable: {}, } diff --git a/packages/next/src/client/components/router-reducer/reducers/navigate-reducer.ts b/packages/next/src/client/components/router-reducer/reducers/navigate-reducer.ts index c27d480865e26..83ef239c8bdba 100644 --- a/packages/next/src/client/components/router-reducer/reducers/navigate-reducer.ts +++ b/packages/next/src/client/components/router-reducer/reducers/navigate-reducer.ts @@ -27,6 +27,7 @@ import { } from '../get-prefetch-cache-entry-status' import { prunePrefetchCache } from './prune-prefetch-cache' import { prefetchQueue } from './prefetch-reducer' +import { createEmptyCacheNode } from '../../app-router' export function handleExternalUrl( state: ReadonlyReducerState, @@ -98,8 +99,7 @@ export function navigateReducer( state: ReadonlyReducerState, action: NavigateAction ): ReducerState { - const { url, isExternalUrl, navigateType, cache, mutable, shouldScroll } = - action + const { url, isExternalUrl, navigateType, mutable, shouldScroll } = action const { hash } = url const href = createHrefFromUrl(url) const pendingPush = navigateType === 'push' @@ -207,6 +207,7 @@ export function navigateReducer( return handleExternalUrl(state, mutable, href, pendingPush) } + const cache: CacheNode = createEmptyCacheNode() let applied = applyFlightData( currentCache, cache, diff --git a/packages/next/src/client/components/router-reducer/reducers/refresh-reducer.test.tsx b/packages/next/src/client/components/router-reducer/reducers/refresh-reducer.test.tsx index 934cbf9b9dfa0..8b30a15938e03 100644 --- a/packages/next/src/client/components/router-reducer/reducers/refresh-reducer.test.tsx +++ b/packages/next/src/client/components/router-reducer/reducers/refresh-reducer.test.tsx @@ -135,12 +135,6 @@ describe('refreshReducer', () => { }) const action: RefreshAction = { type: ACTION_REFRESH, - cache: { - status: CacheStates.LAZY_INITIALIZED, - data: null, - subTreeData: null, - parallelRoutes: new Map(), - }, mutable: {}, origin: new URL('/linking', 'https://localhost').origin, } @@ -297,12 +291,6 @@ describe('refreshReducer', () => { const action: RefreshAction = { type: ACTION_REFRESH, - cache: { - status: CacheStates.LAZY_INITIALIZED, - data: null, - subTreeData: null, - parallelRoutes: new Map(), - }, mutable: {}, origin: new URL('/linking', 'https://localhost').origin, } @@ -485,12 +473,6 @@ describe('refreshReducer', () => { const action: RefreshAction = { type: ACTION_REFRESH, - cache: { - status: CacheStates.LAZY_INITIALIZED, - data: null, - subTreeData: null, - parallelRoutes: new Map(), - }, mutable: {}, origin: new URL('/linking', 'https://localhost').origin, } @@ -722,12 +704,6 @@ describe('refreshReducer', () => { const action: RefreshAction = { type: ACTION_REFRESH, - cache: { - status: CacheStates.LAZY_INITIALIZED, - data: null, - subTreeData: null, - parallelRoutes: new Map(), - }, mutable: {}, origin: new URL('/linking', 'https://localhost').origin, } diff --git a/packages/next/src/client/components/router-reducer/reducers/refresh-reducer.ts b/packages/next/src/client/components/router-reducer/reducers/refresh-reducer.ts index bf9571e6a11d8..f7fd84d839a8b 100644 --- a/packages/next/src/client/components/router-reducer/reducers/refresh-reducer.ts +++ b/packages/next/src/client/components/router-reducer/reducers/refresh-reducer.ts @@ -9,14 +9,18 @@ import type { } from '../router-reducer-types' import { handleExternalUrl } from './navigate-reducer' import { handleMutable } from '../handle-mutable' -import { CacheStates } from '../../../../shared/lib/app-router-context.shared-runtime' +import { + CacheStates, + type CacheNode, +} from '../../../../shared/lib/app-router-context.shared-runtime' import { fillLazyItemsTillLeafWithHead } from '../fill-lazy-items-till-leaf-with-head' +import { createEmptyCacheNode } from '../../app-router' export function refreshReducer( state: ReadonlyReducerState, action: RefreshAction ): ReducerState { - const { cache, mutable, origin } = action + const { mutable, origin } = action const href = state.canonicalUrl let currentTree = state.tree @@ -30,16 +34,15 @@ export function refreshReducer( mutable.preserveCustomHistoryState = false - if (!cache.data) { - // TODO-APP: verify that `href` is not an external url. - // Fetch data from the root of the tree. - cache.data = fetchServerResponse( - new URL(href, origin), - [currentTree[0], currentTree[1], currentTree[2], 'refetch'], - state.nextUrl, - state.buildId - ) - } + const cache: CacheNode = createEmptyCacheNode() + // TODO-APP: verify that `href` is not an external url. + // Fetch data from the root of the tree. + cache.data = fetchServerResponse( + new URL(href, origin), + [currentTree[0], currentTree[1], currentTree[2], 'refetch'], + state.nextUrl, + state.buildId + ) return cache.data.then( ([flightData, canonicalUrlOverride]) => { diff --git a/packages/next/src/client/components/router-reducer/reducers/server-action-reducer.ts b/packages/next/src/client/components/router-reducer/reducers/server-action-reducer.ts index 05f4b1d370cdf..12c44752e9792 100644 --- a/packages/next/src/client/components/router-reducer/reducers/server-action-reducer.ts +++ b/packages/next/src/client/components/router-reducer/reducers/server-action-reducer.ts @@ -32,9 +32,13 @@ import { createHrefFromUrl } from '../create-href-from-url' import { handleExternalUrl } from './navigate-reducer' import { applyRouterStatePatchToTree } from '../apply-router-state-patch-to-tree' import { isNavigatingToNewRootLayout } from '../is-navigating-to-new-root-layout' -import { CacheStates } from '../../../../shared/lib/app-router-context.shared-runtime' +import { + CacheStates, + type CacheNode, +} from '../../../../shared/lib/app-router-context.shared-runtime' import { handleMutable } from '../handle-mutable' import { fillLazyItemsTillLeafWithHead } from '../fill-lazy-items-till-leaf-with-head' +import { createEmptyCacheNode } from '../../app-router' type FetchServerActionResult = { redirectLocation: URL | undefined @@ -145,7 +149,7 @@ export function serverActionReducer( state: ReadonlyReducerState, action: ServerActionAction ): ReducerState { - const { mutable, cache, resolve, reject } = action + const { mutable, resolve, reject } = action const href = state.canonicalUrl let currentTree = state.tree @@ -241,6 +245,7 @@ export function serverActionReducer( // Handles case where prefetch only returns the router tree patch without rendered components. if (subTreeData !== null) { + const cache: CacheNode = createEmptyCacheNode() cache.status = CacheStates.READY cache.subTreeData = subTreeData fillLazyItemsTillLeafWithHead( diff --git a/packages/next/src/client/components/router-reducer/reducers/server-patch-reducer.test.tsx b/packages/next/src/client/components/router-reducer/reducers/server-patch-reducer.test.tsx index f357caa2f3a59..7ab04b1ec09da 100644 --- a/packages/next/src/client/components/router-reducer/reducers/server-patch-reducer.test.tsx +++ b/packages/next/src/client/components/router-reducer/reducers/server-patch-reducer.test.tsx @@ -171,12 +171,6 @@ describe('serverPatchReducer', () => { true, ], overrideCanonicalUrl: undefined, - cache: { - status: CacheStates.LAZY_INITIALIZED, - data: null, - subTreeData: null, - parallelRoutes: new Map(), - }, mutable: {}, } @@ -363,12 +357,6 @@ describe('serverPatchReducer', () => { true, ], overrideCanonicalUrl: undefined, - cache: { - status: CacheStates.LAZY_INITIALIZED, - data: null, - subTreeData: null, - parallelRoutes: new Map(), - }, mutable: {}, } @@ -502,12 +490,6 @@ describe('serverPatchReducer', () => { locationSearch: '', navigateType: 'push', shouldScroll: true, - cache: { - status: CacheStates.LAZY_INITIALIZED, - data: null, - subTreeData: null, - parallelRoutes: new Map(), - }, mutable: {}, } @@ -544,12 +526,6 @@ describe('serverPatchReducer', () => { true, ], overrideCanonicalUrl: undefined, - cache: { - status: CacheStates.LAZY_INITIALIZED, - data: null, - subTreeData: null, - parallelRoutes: new Map(), - }, mutable: {}, } diff --git a/packages/next/src/client/components/router-reducer/reducers/server-patch-reducer.ts b/packages/next/src/client/components/router-reducer/reducers/server-patch-reducer.ts index 2c9200793b601..0221aab10a100 100644 --- a/packages/next/src/client/components/router-reducer/reducers/server-patch-reducer.ts +++ b/packages/next/src/client/components/router-reducer/reducers/server-patch-reducer.ts @@ -9,13 +9,14 @@ import type { import { handleExternalUrl } from './navigate-reducer' import { applyFlightData } from '../apply-flight-data' import { handleMutable } from '../handle-mutable' +import type { CacheNode } from '../../../../shared/lib/app-router-context.shared-runtime' +import { createEmptyCacheNode } from '../../app-router' export function serverPatchReducer( state: ReadonlyReducerState, action: ServerPatchAction ): ReducerState { - const { flightData, previousTree, overrideCanonicalUrl, cache, mutable } = - action + const { flightData, previousTree, overrideCanonicalUrl, mutable } = action const isForCurrentTree = JSON.stringify(previousTree) === JSON.stringify(state.tree) @@ -81,6 +82,7 @@ export function serverPatchReducer( mutable.canonicalUrl = canonicalUrlOverrideHref } + const cache: CacheNode = createEmptyCacheNode() applyFlightData(currentCache, cache, flightDataPath) mutable.previousTree = currentTree diff --git a/packages/next/src/client/components/router-reducer/router-reducer-types.ts b/packages/next/src/client/components/router-reducer/router-reducer-types.ts index 4649d0729ec58..3dba27297705e 100644 --- a/packages/next/src/client/components/router-reducer/router-reducer-types.ts +++ b/packages/next/src/client/components/router-reducer/router-reducer-types.ts @@ -52,14 +52,12 @@ export interface ServerActionMutable extends Mutable { */ export interface RefreshAction { type: typeof ACTION_REFRESH - cache: CacheNode mutable: Mutable origin: Location['origin'] } export interface FastRefreshAction { type: typeof ACTION_FAST_REFRESH - cache: CacheNode mutable: Mutable origin: Location['origin'] } @@ -77,7 +75,6 @@ export interface ServerActionAction { actionArgs: any[] resolve: (value: any) => void reject: (reason?: any) => void - cache: CacheNode mutable: ServerActionMutable } @@ -118,7 +115,6 @@ export interface NavigateAction { locationSearch: Location['search'] navigateType: 'push' | 'replace' shouldScroll: boolean - cache: CacheNode mutable: Mutable } @@ -145,7 +141,6 @@ export interface ServerPatchAction { flightData: FlightData previousTree: FlightRouterState overrideCanonicalUrl: URL | undefined - cache: CacheNode mutable: Mutable } diff --git a/packages/next/src/shared/lib/router/action-queue.ts b/packages/next/src/shared/lib/router/action-queue.ts index c3ff9f7ab54bc..ad212a233e696 100644 --- a/packages/next/src/shared/lib/router/action-queue.ts +++ b/packages/next/src/shared/lib/router/action-queue.ts @@ -10,7 +10,6 @@ import { import type { ReduxDevToolsInstance } from '../../../client/components/use-reducer-with-devtools' import { reducer } from '../../../client/components/router-reducer/router-reducer' import React, { startTransition } from 'react' -import { createEmptyCacheNode } from '../../../client/components/app-router' export type DispatchStatePromise = React.Dispatch @@ -82,7 +81,6 @@ async function runAction({ actionQueue.dispatch( { type: ACTION_REFRESH, - cache: createEmptyCacheNode(), mutable: {}, origin: window.location.origin, }, From cdf2b79ea9668e5f6e5285819ca2bfa76bc98c0a Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Mon, 27 Nov 2023 17:53:26 +0100 Subject: [PATCH 058/481] Add nodejs version check (#58958) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There're some reports related to using incorrect Node.js version, sometimes users ended up in weird errors. As pkg manager like pnpm only gives a warning ` WARN  Unsupported engine: wanted: {"node":">=18.17.0"} (current: {"node":"v16.18.0","pnpm":"8.9.0"})` which is not easy to investigate the issue. We're adding a version check at the beginning of the Next.js process so if Node.js version is mis-match the version specified in package.json, bail with error. Examples node 16.x ``` You are using Node.js 16.18.0. Node.js >= v18.17.0 is required. ``` node.18.16 ``` You are using Node.js 18.16.1. Node.js >= v18.17.0 is required. ``` --- packages/next/src/bin/next.ts | 10 ++++++++++ .../plugins/flight-client-entry-plugin.ts | 12 ------------ packages/next/taskfile-swc.js | 4 ++++ test/unit/next-swc.test.ts | 16 ++++++++++++++++ 4 files changed, 30 insertions(+), 12 deletions(-) diff --git a/packages/next/src/bin/next.ts b/packages/next/src/bin/next.ts index 9f84b7d1774e3..dc36f33e1f921 100755 --- a/packages/next/src/bin/next.ts +++ b/packages/next/src/bin/next.ts @@ -3,6 +3,7 @@ performance.mark('next-start') import '../server/require-hook' import * as log from '../build/output/log' import arg from 'next/dist/compiled/arg/index.js' +import semver from 'next/dist/compiled/semver' import { NON_STANDARD_NODE_ENV } from '../lib/constants' import { commands } from '../lib/commands' import { commandArgs } from '../lib/command-args' @@ -115,6 +116,15 @@ async function main() { } } + if ( + semver.lt(process.versions.node, process.env.__NEXT_REQUIRED_NODE_VERSION!) + ) { + console.error( + `You are using Node.js ${process.versions.node}. For Next.js, Node.js version >= v${process.env.__NEXT_REQUIRED_NODE_VERSION} is required.` + ) + process.exit(1) + } + await commands[command]() .then((exec) => exec(validatedArgs)) .then(() => { diff --git a/packages/next/src/build/webpack/plugins/flight-client-entry-plugin.ts b/packages/next/src/build/webpack/plugins/flight-client-entry-plugin.ts index 018f48fb759e5..69a2700cd71a0 100644 --- a/packages/next/src/build/webpack/plugins/flight-client-entry-plugin.ts +++ b/packages/next/src/build/webpack/plugins/flight-client-entry-plugin.ts @@ -32,7 +32,6 @@ import { import { traverseModules, forEachEntryModule } from '../utils' import { normalizePathSep } from '../../../shared/lib/page-path/normalize-path-sep' import { getProxiedPluginState } from '../../build-context' -import semver from 'next/dist/compiled/semver' import { generateRandomActionKeyRaw } from '../../../server/app-render/action-encryption-utils' interface Options { @@ -788,17 +787,6 @@ export class FlightClientEntryPlugin { }) { const actionsArray = Array.from(actions.entries()) - // Node < 18.11 does not have sufficient support for FormData - if (actionsArray.length > 0 && semver.lt(process.version, '18.11.0')) { - compilation.errors.push( - new compilation.compiler.webpack.WebpackError( - 'Your version of Node does not support server actions. Please upgrade to Node 18.11 or higher.' - ) - ) - - return Promise.resolve() - } - const actionLoader = `next-flight-action-entry-loader?${stringify({ actions: JSON.stringify(actionsArray), __client_imported__: fromClient, diff --git a/packages/next/taskfile-swc.js b/packages/next/taskfile-swc.js index 3e5a80fcfb909..a1cd97efbe966 100644 --- a/packages/next/taskfile-swc.js +++ b/packages/next/taskfile-swc.js @@ -190,6 +190,10 @@ function setNextVersion(code) { /process\.env\.__NEXT_VERSION/g, `"${require('./package.json').version}"` ) + .replace( + /process\.env\.__NEXT_REQUIRED_NODE_VERSION/g, + `"${require('./package.json').engines.node.replace('>=', '')}"` + ) .replace( /process\.env\.REQUIRED_APP_REACT_VERSION/, `"${ diff --git a/test/unit/next-swc.test.ts b/test/unit/next-swc.test.ts index d86b7a5812a1a..7a25c7452e113 100644 --- a/test/unit/next-swc.test.ts +++ b/test/unit/next-swc.test.ts @@ -1,5 +1,7 @@ /* eslint-env jest */ import { transform } from 'next/dist/build/swc' +import path from 'path' +import fsp from 'fs/promises' const swc = async (code) => { let output = await transform(code) @@ -111,4 +113,18 @@ describe('next/swc', () => { `) }) }) + + describe('private env replacement', () => { + it('__NEXT_REQUIRED_NODE_VERSION is replaced', async () => { + const pkgDir = path.dirname(require.resolve('next/package.json')) + const nextEntryContent = await fsp.readFile( + path.join(pkgDir, 'dist/bin/next'), + 'utf8' + ) + expect(nextEntryContent).not.toContain('__NEXT_REQUIRED_NODE_VERSION') + expect(nextEntryContent).toMatch( + /For Next.js, Node.js version >= v\$\{"\d+\.\d+\.\d*"\}/ + ) + }) + }) }) From 7ff3e3e32d9de44a3f9a3b50f1f088e8b55c630d Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Mon, 27 Nov 2023 23:22:35 +0000 Subject: [PATCH 059/481] v14.0.4-canary.19 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 18 +++++++++--------- 18 files changed, 34 insertions(+), 34 deletions(-) diff --git a/lerna.json b/lerna.json index f4d4b84da3585..3198bd6a9f2d3 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.18" + "version": "14.0.4-canary.19" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index b3706d547c451..b22b81f4d599e 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.18", + "version": "14.0.4-canary.19", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 6e5608b2ec000..10826c9eeafd1 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.18", + "version": "14.0.4-canary.19", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.18", + "@next/eslint-plugin-next": "14.0.4-canary.19", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 26cf52da66b7d..0bc29fdb43db5 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.18", + "version": "14.0.4-canary.19", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index 05f6b90b5adc2..87703c001408c 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.18", + "version": "14.0.4-canary.19", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 325108c03e0bc..c4e2bb725b0c1 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.18", + "version": "14.0.4-canary.19", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index c3d0cb55edcf0..79acb0d78bb58 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.18", + "version": "14.0.4-canary.19", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 32c94ca88eac0..fec191f7e85ea 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.18", + "version": "14.0.4-canary.19", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index ac4190e01a399..f11d76a4accf6 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.18", + "version": "14.0.4-canary.19", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 0e33aee20b72e..80ee1d7264675 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.18", + "version": "14.0.4-canary.19", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index 29f3d6fb4a1c0..7739a291d411a 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.18", + "version": "14.0.4-canary.19", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index 87c87e80c1bed..f48872688d982 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.18", + "version": "14.0.4-canary.19", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index b04f24d7b1284..ec2c9e6502717 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.18", + "version": "14.0.4-canary.19", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index a82113d24de6a..e4a3d8e3ceab9 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.18", + "version": "14.0.4-canary.19", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.18", + "@next/env": "14.0.4-canary.19", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -147,11 +147,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.18", - "@next/polyfill-nomodule": "14.0.4-canary.18", - "@next/react-dev-overlay": "14.0.4-canary.18", - "@next/react-refresh-utils": "14.0.4-canary.18", - "@next/swc": "14.0.4-canary.18", + "@next/polyfill-module": "14.0.4-canary.19", + "@next/polyfill-nomodule": "14.0.4-canary.19", + "@next/react-dev-overlay": "14.0.4-canary.19", + "@next/react-refresh-utils": "14.0.4-canary.19", + "@next/swc": "14.0.4-canary.19", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index f10537ee23980..ab3a15b566c47 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.18", + "version": "14.0.4-canary.19", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index 3cfbd74ea6192..43c03b8d07cb9 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.18", + "version": "14.0.4-canary.19", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index ba4cfa004fd3d..3a6cb5f628278 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.18", + "version": "14.0.4-canary.19", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -23,7 +23,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.18", + "next": "14.0.4-canary.19", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fb362850a9d15..b3618a13b5efe 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -738,7 +738,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.18 + specifier: 14.0.4-canary.19 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -803,7 +803,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.18 + specifier: 14.0.4-canary.19 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -930,19 +930,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.18 + specifier: 14.0.4-canary.19 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.18 + specifier: 14.0.4-canary.19 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.18 + specifier: 14.0.4-canary.19 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.18 + specifier: 14.0.4-canary.19 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.18 + specifier: 14.0.4-canary.19 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1596,7 +1596,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.18 + specifier: 14.0.4-canary.19 version: link:../next outdent: specifier: 0.8.0 @@ -24649,7 +24649,7 @@ packages: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.3(react-refresh@0.12.0)(webpack@5.86.0)': - resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.3} + resolution: {registry: https://registry.npmjs.org/, tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.3} id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.3' name: '@vercel/turbopack-ecmascript-runtime' version: 0.0.0 From 0d6d53cc26c04212914db142ed69af008628820c Mon Sep 17 00:00:00 2001 From: Shu Ding Date: Tue, 28 Nov 2023 17:41:05 +0800 Subject: [PATCH 060/481] Code refactoring (#58737) Saw this pattern when looking at something else. Did a search & replacement. We probably want to setup a lint rule for it. --- .../loaders/css-loader/src/CssSyntaxError.ts | 2 +- .../loaders/postcss-loader/src/Error.ts | 2 +- .../loaders/postcss-loader/src/Warning.ts | 2 +- .../webpack/plugins/pages-manifest-plugin.ts | 24 +++++++++---------- .../wellknown-errors-plugin/getModuleTrace.ts | 2 +- packages/next/src/export/index.ts | 5 +--- .../lib/router-utils/setup-dev-bundler.ts | 2 +- packages/next/src/server/next-server.ts | 9 ++++--- .../router/utils/get-asset-path-from-route.ts | 2 +- .../shared/lib/router/utils/route-regex.ts | 2 +- 10 files changed, 23 insertions(+), 29 deletions(-) diff --git a/packages/next/src/build/webpack/loaders/css-loader/src/CssSyntaxError.ts b/packages/next/src/build/webpack/loaders/css-loader/src/CssSyntaxError.ts index f5b5ac2b8a2d9..d66c41b6f9c0d 100644 --- a/packages/next/src/build/webpack/loaders/css-loader/src/CssSyntaxError.ts +++ b/packages/next/src/build/webpack/loaders/css-loader/src/CssSyntaxError.ts @@ -15,7 +15,7 @@ export default class CssSyntaxError extends Error { this.message += `(${line}:${column}) ` } - this.message += `${reason}` + this.message += reason const code = error.showSourceCode() diff --git a/packages/next/src/build/webpack/loaders/postcss-loader/src/Error.ts b/packages/next/src/build/webpack/loaders/postcss-loader/src/Error.ts index b71a82d90d94a..280bae9ae463e 100644 --- a/packages/next/src/build/webpack/loaders/postcss-loader/src/Error.ts +++ b/packages/next/src/build/webpack/loaders/postcss-loader/src/Error.ts @@ -25,7 +25,7 @@ export default class PostCSSSyntaxError extends Error { this.message += plugin ? `${plugin}: ` : '' this.message += file ? `${file} ` : ' ' - this.message += `${reason}` + this.message += reason const code = error.showSourceCode() diff --git a/packages/next/src/build/webpack/loaders/postcss-loader/src/Warning.ts b/packages/next/src/build/webpack/loaders/postcss-loader/src/Warning.ts index ca368c6836773..9cb7e396aa229 100644 --- a/packages/next/src/build/webpack/loaders/postcss-loader/src/Warning.ts +++ b/packages/next/src/build/webpack/loaders/postcss-loader/src/Warning.ts @@ -24,7 +24,7 @@ export default class Warning extends Error { } this.message += plugin ? `${plugin}: ` : '' - this.message += `${text}` + this.message += text this.stack = false } diff --git a/packages/next/src/build/webpack/plugins/pages-manifest-plugin.ts b/packages/next/src/build/webpack/plugins/pages-manifest-plugin.ts index 1374395ffa399..1645cc17a47b8 100644 --- a/packages/next/src/build/webpack/plugins/pages-manifest-plugin.ts +++ b/packages/next/src/build/webpack/plugins/pages-manifest-plugin.ts @@ -132,18 +132,17 @@ export default class PagesManifestPlugin ...nodeServerPages, }) } else { - assets[ - `${!this.dev && !this.isEdgeRuntime ? '../' : ''}` + PAGES_MANIFEST - ] = new sources.RawSource( - JSON.stringify( - { - ...edgeServerPages, - ...nodeServerPages, - }, - null, - 2 + assets[(!this.dev && !this.isEdgeRuntime ? '../' : '') + PAGES_MANIFEST] = + new sources.RawSource( + JSON.stringify( + { + ...edgeServerPages, + ...nodeServerPages, + }, + null, + 2 + ) ) - ) } if (this.appDirEnabled) { @@ -159,8 +158,7 @@ export default class PagesManifestPlugin }) } else { assets[ - `${!this.dev && !this.isEdgeRuntime ? '../' : ''}` + - APP_PATHS_MANIFEST + (!this.dev && !this.isEdgeRuntime ? '../' : '') + APP_PATHS_MANIFEST ] = new sources.RawSource( JSON.stringify( { diff --git a/packages/next/src/build/webpack/plugins/wellknown-errors-plugin/getModuleTrace.ts b/packages/next/src/build/webpack/plugins/wellknown-errors-plugin/getModuleTrace.ts index caf26636e6c87..5d67ded10ca3d 100644 --- a/packages/next/src/build/webpack/plugins/wellknown-errors-plugin/getModuleTrace.ts +++ b/packages/next/src/build/webpack/plugins/wellknown-errors-plugin/getModuleTrace.ts @@ -52,7 +52,7 @@ export function formatModuleTrace( return { lastInternalFileName: importTrace[0], invalidImportMessage, - formattedModuleTrace: `${importTrace.map((mod) => ' ' + mod).join('\n')}`, + formattedModuleTrace: importTrace.map((mod) => ' ' + mod).join('\n'), } } diff --git a/packages/next/src/export/index.ts b/packages/next/src/export/index.ts index 62569fd09f927..1a87913baf089 100644 --- a/packages/next/src/export/index.ts +++ b/packages/next/src/export/index.ts @@ -632,10 +632,7 @@ export async function exportAppImpl( const progress = !options.silent && - createProgress( - filteredPaths.length, - `${options.statusMessage || 'Exporting'}` - ) + createProgress(filteredPaths.length, options.statusMessage || 'Exporting') const pagesDataDir = options.buildExport ? outDir : join(outDir, '_next/data', buildId) diff --git a/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts b/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts index 4e1dea7bb0d13..e5df2e83d4dc2 100644 --- a/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts +++ b/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts @@ -316,7 +316,7 @@ async function startWatcher(opts: SetupOpts) { } else if (formattedFilePath) { message = `${formattedFilePath} ${formattedTitle}` } else { - message = `${formattedTitle}` + message = formattedTitle } if (source?.range && source.source.content) { diff --git a/packages/next/src/server/next-server.ts b/packages/next/src/server/next-server.ts index 4380057f10ca1..fce65ccca4739 100644 --- a/packages/next/src/server/next-server.ts +++ b/packages/next/src/server/next-server.ts @@ -1124,8 +1124,7 @@ export default class NextNodeServer extends BaseServer { nestedLevel += 1 } } - - return nestedLevel === 0 ? ' ' : `${' │ '.repeat(nestedLevel)}` + return nestedLevel === 0 ? ' ' : ' │ '.repeat(nestedLevel) } for (let i = 0; i < fetchMetrics.length; i++) { @@ -1138,10 +1137,10 @@ export default class NextNodeServer extends BaseServer { if (cacheStatus === 'hit') { cacheStatus = green('HIT') } else if (cacheStatus === 'skip') { - cacheStatus = `${yellow('SKIP')}` - cacheReasonStr = `${gray( + cacheStatus = yellow('SKIP') + cacheReasonStr = gray( `Cache missed reason: (${white(cacheReason)})` - )}` + ) } else { cacheStatus = yellow('MISS') } diff --git a/packages/next/src/shared/lib/router/utils/get-asset-path-from-route.ts b/packages/next/src/shared/lib/router/utils/get-asset-path-from-route.ts index b1da430dd9b3b..cd4ea4b2f5441 100644 --- a/packages/next/src/shared/lib/router/utils/get-asset-path-from-route.ts +++ b/packages/next/src/shared/lib/router/utils/get-asset-path-from-route.ts @@ -9,6 +9,6 @@ export default function getAssetPathFromRoute( ? '/index' : /^\/index(\/|$)/.test(route) ? `/index${route}` - : `${route}` + : route return path + ext } diff --git a/packages/next/src/shared/lib/router/utils/route-regex.ts b/packages/next/src/shared/lib/router/utils/route-regex.ts index 177e01a20c274..caf003e99b758 100644 --- a/packages/next/src/shared/lib/router/utils/route-regex.ts +++ b/packages/next/src/shared/lib/router/utils/route-regex.ts @@ -134,7 +134,7 @@ function getSafeKeyFromSegment({ if (keyPrefix) { routeKeys[cleanedKey] = `${keyPrefix}${key}` } else { - routeKeys[cleanedKey] = `${key}` + routeKeys[cleanedKey] = key } return repeat From 7bdb61c28d5046a90e14c98b3ee2d01cd143daa2 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Tue, 28 Nov 2023 10:50:14 +0100 Subject: [PATCH 061/481] Fix bugs with baseUrl and mdxRs (#58968) ## What? Was investigating an issue with Turbopack and MDX, in the process found a few bugs: - When you have a `tsconfig.json` or `jsconfig.json` the `baseUrl: '.'` is used by default which causes the top-level directories to be available as e.g. `design-system` (without a prefix). - This is not how TypeScript's default setting for `baseUrl` works. While it should resolve `paths` relative to `.` when none is specified it does not do additional resolving for the top level directories/files. - When `"baseUrl": "."` is added to `tsconfig.js` explicitly it handles the top level directories. - `modularizeImports` and other SWC transforms weren't applied to `.mdx` files when `experimental.mdxRs` is enabled, which caused compilation to fail. - `modularIzeImports` and other SWC transforms are not applied to `.mdx` files when using Turbopack. - @kwonoj is investigating this, will be handled in a follow-up PR. ## How? - Added a test suite for `modularizeImports` with MDX tests - Removed the condition that disables swcLoader in webpack when using mdxRs - Changed the check for `tsconfig.json` / `jsconfig.json` baseUrl to include if it was implicitly or explicitly set, disabled the module resolving when it is implicitly set --------- Co-authored-by: Tobias Koppers --- packages/next-mdx/index.js | 7 +---- packages/next/src/build/load-jsconfig.ts | 30 ++++++++++++++----- .../next/src/build/swc/jest-transformer.ts | 3 +- packages/next/src/build/swc/options.ts | 13 ++++---- packages/next/src/build/webpack-config.ts | 22 +++++++++----- .../webpack/plugins/jsconfig-paths-plugin.ts | 11 +++++-- .../lib/router-utils/setup-dev-bundler.ts | 22 +++++++++----- test/e2e/app-dir/modularizeimports/.gitignore | 1 + .../app-dir/modularizeimports/app/layout.tsx | 7 +++++ .../e2e/app-dir/modularizeimports/app/page.js | 11 +++++++ .../design-system/icons/cart.js | 3 ++ .../design-system/icons/search.js | 3 ++ .../modularizeimports/mdx-components.tsx | 5 ++++ .../modularizeimports.test.ts | 26 ++++++++++++++++ .../app-dir/modularizeimports/next.config.js | 19 ++++++++++++ .../modularizeimports/pages/mdx/index.mdx | 7 +++++ .../app-dir/modularizeimports/tsconfig.json | 25 ++++++++++++++++ 17 files changed, 177 insertions(+), 38 deletions(-) create mode 100644 test/e2e/app-dir/modularizeimports/.gitignore create mode 100644 test/e2e/app-dir/modularizeimports/app/layout.tsx create mode 100644 test/e2e/app-dir/modularizeimports/app/page.js create mode 100644 test/e2e/app-dir/modularizeimports/design-system/icons/cart.js create mode 100644 test/e2e/app-dir/modularizeimports/design-system/icons/search.js create mode 100644 test/e2e/app-dir/modularizeimports/mdx-components.tsx create mode 100644 test/e2e/app-dir/modularizeimports/modularizeimports.test.ts create mode 100644 test/e2e/app-dir/modularizeimports/next.config.js create mode 100644 test/e2e/app-dir/modularizeimports/pages/mdx/index.mdx create mode 100644 test/e2e/app-dir/modularizeimports/tsconfig.json diff --git a/packages/next-mdx/index.js b/packages/next-mdx/index.js index 0c9eeb27f2670..407ec26023491 100644 --- a/packages/next-mdx/index.js +++ b/packages/next-mdx/index.js @@ -28,12 +28,7 @@ module.exports = ] config.module.rules.push({ test: extension, - use: [ - nextConfig?.experimental?.mdxRs - ? undefined - : options.defaultLoaders.babel, - loader, - ].filter(Boolean), + use: [options.defaultLoaders.babel, loader], }) if (typeof nextConfig.webpack === 'function') { diff --git a/packages/next/src/build/load-jsconfig.ts b/packages/next/src/build/load-jsconfig.ts index 28f37dc6ce7d3..434cd811b4c92 100644 --- a/packages/next/src/build/load-jsconfig.ts +++ b/packages/next/src/build/load-jsconfig.ts @@ -37,10 +37,20 @@ function parseJsonFile(filePath: string) { } } +export type ResolvedBaseUrl = + | { baseUrl: string; isImplicit: boolean } + | undefined + +export type JsConfig = { compilerOptions: Record } | undefined + export default async function loadJsConfig( dir: string, config: NextConfigComplete -) { +): Promise<{ + useTypeScript: boolean + jsConfig: JsConfig + resolvedBaseUrl: ResolvedBaseUrl +}> { let typeScriptPath: string | undefined try { const deps = await hasNecessaryDependencies(dir, [ @@ -81,12 +91,18 @@ export default async function loadJsConfig( implicitBaseurl = path.dirname(jsConfigPath) } - let resolvedBaseUrl - if (jsConfig) { - if (jsConfig.compilerOptions?.baseUrl) { - resolvedBaseUrl = path.resolve(dir, jsConfig.compilerOptions.baseUrl) - } else { - resolvedBaseUrl = implicitBaseurl + let resolvedBaseUrl: ResolvedBaseUrl + if (jsConfig?.compilerOptions?.baseUrl) { + resolvedBaseUrl = { + baseUrl: path.resolve(dir, jsConfig.compilerOptions.baseUrl), + isImplicit: false, + } + } else { + if (implicitBaseurl) { + resolvedBaseUrl = { + baseUrl: implicitBaseurl, + isImplicit: true, + } } } diff --git a/packages/next/src/build/swc/jest-transformer.ts b/packages/next/src/build/swc/jest-transformer.ts index 7eb455ab786be..30740ed7faf2f 100644 --- a/packages/next/src/build/swc/jest-transformer.ts +++ b/packages/next/src/build/swc/jest-transformer.ts @@ -36,11 +36,12 @@ import type { } from '@jest/transform' import type { Config } from '@jest/types' import type { NextConfig, ExperimentalConfig } from '../../server/config-shared' +import type { ResolvedBaseUrl } from '../load-jsconfig' type TransformerConfig = Config.TransformerConfig[1] export interface JestTransformerConfig extends TransformerConfig { jsConfig: any - resolvedBaseUrl?: string + resolvedBaseUrl?: ResolvedBaseUrl pagesDir?: string serverComponents?: boolean isEsmProject: boolean diff --git a/packages/next/src/build/swc/options.ts b/packages/next/src/build/swc/options.ts index 2172b5ec8cdfe..fb9cef6116440 100644 --- a/packages/next/src/build/swc/options.ts +++ b/packages/next/src/build/swc/options.ts @@ -4,6 +4,7 @@ import type { EmotionConfig, StyledComponentsConfig, } from '../../server/config-shared' +import type { ResolvedBaseUrl } from '../load-jsconfig' const nextDistPath = /(next[\\/]dist[\\/]shared[\\/]lib)|(next[\\/]dist[\\/]client)|(next[\\/]dist[\\/]pages)/ @@ -52,7 +53,7 @@ function getBaseSWCOptions({ modularizeImports?: NextConfig['modularizeImports'] compilerOptions: NextConfig['compiler'] swcPlugins: ExperimentalConfig['swcPlugins'] - resolvedBaseUrl?: string + resolvedBaseUrl?: ResolvedBaseUrl jsConfig: any swcCacheDir?: string serverComponents?: boolean @@ -77,7 +78,7 @@ function getBaseSWCOptions({ jsc: { ...(resolvedBaseUrl && paths ? { - baseUrl: resolvedBaseUrl, + baseUrl: resolvedBaseUrl.baseUrl, paths, } : {}), @@ -257,7 +258,7 @@ export function getJestSWCOptions({ swcPlugins: ExperimentalConfig['swcPlugins'] compilerOptions: NextConfig['compiler'] jsConfig: any - resolvedBaseUrl?: string + resolvedBaseUrl?: ResolvedBaseUrl pagesDir?: string serverComponents?: boolean }) { @@ -298,6 +299,8 @@ export function getJestSWCOptions({ } export function getLoaderSWCOptions({ + // This is not passed yet as "paths" resolving is handled by webpack currently. + // resolvedBaseUrl, filename, development, isServer, @@ -316,9 +319,7 @@ export function getLoaderSWCOptions({ relativeFilePathFromRoot, serverComponents, isReactServerLayer, -}: // This is not passed yet as "paths" resolving is handled by webpack currently. -// resolvedBaseUrl, -{ +}: { filename: string development: boolean isServer: boolean diff --git a/packages/next/src/build/webpack-config.ts b/packages/next/src/build/webpack-config.ts index 72f7c6f4813da..a371aa27d1f87 100644 --- a/packages/next/src/build/webpack-config.ts +++ b/packages/next/src/build/webpack-config.ts @@ -51,7 +51,10 @@ import type { } from './webpack/plugins/telemetry-plugin' import type { Span } from '../trace' import type { MiddlewareMatcher } from './analysis/get-page-static-info' -import loadJsConfig from './load-jsconfig' +import loadJsConfig, { + type JsConfig, + type ResolvedBaseUrl, +} from './load-jsconfig' import { loadBindings } from './swc' import { AppBuildManifestPlugin } from './webpack/plugins/app-build-manifest-plugin' import { SubresourceIntegrityPlugin } from './webpack/plugins/subresource-integrity-plugin' @@ -231,7 +234,11 @@ export async function loadProjectInfo({ dir: string config: NextConfigComplete dev: boolean -}) { +}): Promise<{ + jsConfig: JsConfig + resolvedBaseUrl: ResolvedBaseUrl + supportedBrowsers: string[] | undefined +}> { const { jsConfig, resolvedBaseUrl } = await loadJsConfig(dir, config) const supportedBrowsers = await getSupportedBrowsers(dir, dev) return { @@ -310,7 +317,7 @@ export default async function getBaseWebpackConfig( middlewareMatchers?: MiddlewareMatcher[] noMangling?: boolean jsConfig: any - resolvedBaseUrl: string | undefined + resolvedBaseUrl: ResolvedBaseUrl supportedBrowsers: string[] | undefined clientRouterFilters?: { staticFilter: ReturnType< @@ -1802,16 +1809,17 @@ export default async function getBaseWebpackConfig( } // Support tsconfig and jsconfig baseUrl - if (resolvedBaseUrl) { - webpackConfig.resolve?.modules?.push(resolvedBaseUrl) + // Only add the baseUrl if it's explicitly set in tsconfig/jsconfig + if (resolvedBaseUrl && !resolvedBaseUrl.isImplicit) { + webpackConfig.resolve?.modules?.push(resolvedBaseUrl.baseUrl) } - // allows add JsConfigPathsPlugin to allow hot-reloading + // always add JsConfigPathsPlugin to allow hot-reloading // if the config is added/removed webpackConfig.resolve?.plugins?.unshift( new JsConfigPathsPlugin( jsConfig?.compilerOptions?.paths || {}, - resolvedBaseUrl || dir + resolvedBaseUrl ) ) diff --git a/packages/next/src/build/webpack/plugins/jsconfig-paths-plugin.ts b/packages/next/src/build/webpack/plugins/jsconfig-paths-plugin.ts index 2e65e9e74ed33..078fb193b3ca9 100644 --- a/packages/next/src/build/webpack/plugins/jsconfig-paths-plugin.ts +++ b/packages/next/src/build/webpack/plugins/jsconfig-paths-plugin.ts @@ -6,6 +6,7 @@ import path from 'path' import type { webpack } from 'next/dist/compiled/webpack/webpack' import { debug } from 'next/dist/compiled/debug' +import type { ResolvedBaseUrl } from '../../load-jsconfig' const log = debug('next:jsconfig-paths-plugin') @@ -168,10 +169,10 @@ type Paths = { [match: string]: string[] } */ export class JsConfigPathsPlugin implements webpack.ResolvePluginInstance { paths: Paths - resolvedBaseUrl: string + resolvedBaseUrl: ResolvedBaseUrl jsConfigPlugin: true - constructor(paths: Paths, resolvedBaseUrl: string) { + constructor(paths: Paths, resolvedBaseUrl: ResolvedBaseUrl) { this.paths = paths this.resolvedBaseUrl = resolvedBaseUrl this.jsConfigPlugin = true @@ -189,6 +190,10 @@ export class JsConfigPathsPlugin implements webpack.ResolvePluginInstance { resolveContext: any, callback: (err?: any, result?: any) => void ) => { + const resolvedBaseUrl = this.resolvedBaseUrl + if (resolvedBaseUrl === undefined) { + return callback() + } const paths = this.paths const pathsKeys = Object.keys(paths) @@ -248,7 +253,7 @@ export class JsConfigPathsPlugin implements webpack.ResolvePluginInstance { // try next path candidate return pathCallback() } - const candidate = path.join(this.resolvedBaseUrl, curPath) + const candidate = path.join(resolvedBaseUrl.baseUrl, curPath) const obj = Object.assign({}, request, { request: candidate, }) diff --git a/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts b/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts index e5df2e83d4dc2..1a0a5aca5fc9f 100644 --- a/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts +++ b/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts @@ -2083,15 +2083,21 @@ async function startWatcher(opts: SetupOpts) { (item) => item === currentResolvedBaseUrl ) - if ( - resolvedBaseUrl && - resolvedBaseUrl !== currentResolvedBaseUrl - ) { - // remove old baseUrl and add new one - if (resolvedUrlIndex && resolvedUrlIndex > -1) { - config.resolve?.modules?.splice(resolvedUrlIndex, 1) + if (resolvedBaseUrl) { + if ( + resolvedBaseUrl.baseUrl !== currentResolvedBaseUrl.baseUrl + ) { + // remove old baseUrl and add new one + if (resolvedUrlIndex && resolvedUrlIndex > -1) { + config.resolve?.modules?.splice(resolvedUrlIndex, 1) + } + + // If the resolvedBaseUrl is implicit we only remove the previous value. + // Only add the baseUrl if it's explicitly set in tsconfig/jsconfig + if (!resolvedBaseUrl.isImplicit) { + config.resolve?.modules?.push(resolvedBaseUrl.baseUrl) + } } - config.resolve?.modules?.push(resolvedBaseUrl) } if (jsConfig?.compilerOptions?.paths && resolvedBaseUrl) { diff --git a/test/e2e/app-dir/modularizeimports/.gitignore b/test/e2e/app-dir/modularizeimports/.gitignore new file mode 100644 index 0000000000000..b66bc617d0e2c --- /dev/null +++ b/test/e2e/app-dir/modularizeimports/.gitignore @@ -0,0 +1 @@ +!tsconfig.json \ No newline at end of file diff --git a/test/e2e/app-dir/modularizeimports/app/layout.tsx b/test/e2e/app-dir/modularizeimports/app/layout.tsx new file mode 100644 index 0000000000000..e7077399c03ce --- /dev/null +++ b/test/e2e/app-dir/modularizeimports/app/layout.tsx @@ -0,0 +1,7 @@ +export default function Root({ children }: { children: React.ReactNode }) { + return ( + + {children} + + ) +} diff --git a/test/e2e/app-dir/modularizeimports/app/page.js b/test/e2e/app-dir/modularizeimports/app/page.js new file mode 100644 index 0000000000000..195d89af00f88 --- /dev/null +++ b/test/e2e/app-dir/modularizeimports/app/page.js @@ -0,0 +1,11 @@ +import { Cart, Search } from 'design-system/icons' + +export default function Page() { + return ( + <> +

ModularizeImports

+ + + + ) +} diff --git a/test/e2e/app-dir/modularizeimports/design-system/icons/cart.js b/test/e2e/app-dir/modularizeimports/design-system/icons/cart.js new file mode 100644 index 0000000000000..b2d4924dd3b28 --- /dev/null +++ b/test/e2e/app-dir/modularizeimports/design-system/icons/cart.js @@ -0,0 +1,3 @@ +export function Cart() { + return

Cart Icon

+} diff --git a/test/e2e/app-dir/modularizeimports/design-system/icons/search.js b/test/e2e/app-dir/modularizeimports/design-system/icons/search.js new file mode 100644 index 0000000000000..0e5dec0a6f731 --- /dev/null +++ b/test/e2e/app-dir/modularizeimports/design-system/icons/search.js @@ -0,0 +1,3 @@ +export function Search() { + return

Search Icon

+} diff --git a/test/e2e/app-dir/modularizeimports/mdx-components.tsx b/test/e2e/app-dir/modularizeimports/mdx-components.tsx new file mode 100644 index 0000000000000..47e587962a757 --- /dev/null +++ b/test/e2e/app-dir/modularizeimports/mdx-components.tsx @@ -0,0 +1,5 @@ +export function useMDXComponents(components) { + return { + ...components, + } +} diff --git a/test/e2e/app-dir/modularizeimports/modularizeimports.test.ts b/test/e2e/app-dir/modularizeimports/modularizeimports.test.ts new file mode 100644 index 0000000000000..2b6f4d7382a1f --- /dev/null +++ b/test/e2e/app-dir/modularizeimports/modularizeimports.test.ts @@ -0,0 +1,26 @@ +import { createNextDescribe } from 'e2e-utils' + +createNextDescribe( + 'modularizeImports', + { + files: __dirname, + dependencies: { + '@next/mdx': 'canary', + '@mdx-js/loader': '^2.2.1', + '@mdx-js/react': '^2.2.1', + }, + }, + ({ next }) => { + it('should work', async () => { + const $ = await next.render$('/') + expect($('#cart-icon').text()).toBe('Cart Icon') + expect($('#search-icon').text()).toBe('Search Icon') + }) + + it('should work with MDX', async () => { + const $ = await next.render$('/mdx') + expect($('#cart-icon').text()).toBe('Cart Icon') + expect($('#search-icon').text()).toBe('Search Icon') + }) + } +) diff --git a/test/e2e/app-dir/modularizeimports/next.config.js b/test/e2e/app-dir/modularizeimports/next.config.js new file mode 100644 index 0000000000000..c867bac7347ec --- /dev/null +++ b/test/e2e/app-dir/modularizeimports/next.config.js @@ -0,0 +1,19 @@ +const withMDX = require('@next/mdx')() + +/** + * @type {import('next').NextConfig} + */ +const nextConfig = { + pageExtensions: ['js', 'jsx', 'ts', 'tsx', 'md', 'mdx'], + modularizeImports: { + 'design-system/icons': { + transform: 'design-system/icons/{{ kebabCase member }}', + skipDefaultConversion: true, + }, + }, + experimental: { + mdxRs: true, + }, +} + +module.exports = withMDX(nextConfig) diff --git a/test/e2e/app-dir/modularizeimports/pages/mdx/index.mdx b/test/e2e/app-dir/modularizeimports/pages/mdx/index.mdx new file mode 100644 index 0000000000000..02a334d9d8c48 --- /dev/null +++ b/test/e2e/app-dir/modularizeimports/pages/mdx/index.mdx @@ -0,0 +1,7 @@ +import { Cart, Search } from 'design-system/icons' + +# ModularizeImports + + + + diff --git a/test/e2e/app-dir/modularizeimports/tsconfig.json b/test/e2e/app-dir/modularizeimports/tsconfig.json new file mode 100644 index 0000000000000..bd052d943b466 --- /dev/null +++ b/test/e2e/app-dir/modularizeimports/tsconfig.json @@ -0,0 +1,25 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "lib": ["dom", "dom.iterable", "esnext"], + "allowJs": true, + "skipLibCheck": true, + "strict": false, + "noEmit": true, + "incremental": true, + "esModuleInterop": true, + "module": "esnext", + "moduleResolution": "node", + "resolveJsonModule": true, + "isolatedModules": true, + "jsx": "preserve", + "plugins": [ + { + "name": "next" + } + ], + "strictNullChecks": true + }, + "include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"], + "exclude": ["node_modules"] +} From c85caae8d6b4e87b71c4482461fb5cd5e4d647f1 Mon Sep 17 00:00:00 2001 From: Shu Ding Date: Tue, 28 Nov 2023 18:20:47 +0800 Subject: [PATCH 062/481] Fix encoding in encryption of Server Actions (#59000) Utils `stringToUint8Array` and `arrayBufferToString` assume that the values are just arbitrary fixed width data. However that doesn't work when we do unicode concatenation (`actionId + arg`) which requires Text encoder/decoder to be used. Closes #58463, closes #58579. In general any complex unicode characters will cause the same issue, for example emojis. --- .../next/src/server/app-render/action-encryption.ts | 7 +++++-- test/e2e/app-dir/actions/app/server/page.js | 10 +++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/packages/next/src/server/app-render/action-encryption.ts b/packages/next/src/server/app-render/action-encryption.ts index 5705fec51f831..6b222b6236b6c 100644 --- a/packages/next/src/server/app-render/action-encryption.ts +++ b/packages/next/src/server/app-render/action-encryption.ts @@ -23,6 +23,9 @@ import { stringToUint8Array, } from './action-encryption-utils' +const textEncoder = new TextEncoder() +const textDecoder = new TextDecoder() + async function decodeActionBoundArg(actionId: string, arg: string) { const key = await getActionEncryptionKey() if (typeof key === 'undefined') { @@ -39,7 +42,7 @@ async function decodeActionBoundArg(actionId: string, arg: string) { throw new Error('Invalid Server Action payload.') } - const decrypted = arrayBufferToString( + const decrypted = textDecoder.decode( await decrypt(key, stringToUint8Array(ivValue), stringToUint8Array(payload)) ) @@ -66,7 +69,7 @@ async function encodeActionBoundArg(actionId: string, arg: string) { const encrypted = await encrypt( key, randomBytes, - stringToUint8Array(actionId + arg) + textEncoder.encode(actionId + arg) ) return btoa(ivValue + arrayBufferToString(encrypted)) diff --git a/test/e2e/app-dir/actions/app/server/page.js b/test/e2e/app-dir/actions/app/server/page.js index 0c2e5bbd76be6..b885f12cc1ad4 100644 --- a/test/e2e/app-dir/actions/app/server/page.js +++ b/test/e2e/app-dir/actions/app/server/page.js @@ -7,6 +7,10 @@ import { log } from './actions-2' export default function Page() { const two = { value: 2 } + + // https://github.com/vercel/next.js/issues/58463 + const data = '你好' + return ( <> { 'use server' - return x * two.value + if (data === '你好') { + return x * two.value + } + // Wrong answer + return 42 }} />
From 048ab21f6b033b2865353b236f52de7d48b44754 Mon Sep 17 00:00:00 2001 From: OJ Kwon <1210596+kwonoj@users.noreply.github.com> Date: Tue, 28 Nov 2023 04:54:46 -0800 Subject: [PATCH 063/481] fix(turbopack): treat .mdx as valid ecma asset (#58985) ### What Pairing with https://github.com/vercel/turbo/pull/6602, enables ecma-related transform support in mdx. notably fixes test cases in https://github.com/vercel/next.js/pull/58968 . With turbopack side fix, still modularize imports are not being applied as we limite it to .js* extension only. PR expands it to include mdx if mdx is enabled. PR is failling until turbopack side fix lands. Closes PACK-2045 --------- Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- Cargo.lock | 68 +++++++++---------- Cargo.toml | 6 +- .../next-core/src/next_client/transforms.rs | 18 +++-- .../next-core/src/next_server/context.rs | 4 +- .../next-core/src/next_server/transforms.rs | 33 ++++++--- .../src/next_shared/transforms/mod.rs | 26 +++++-- .../transforms/modularize_imports.rs | 3 +- .../next_shared/transforms/next_dynamic.rs | 3 +- .../src/next_shared/transforms/next_font.rs | 4 +- .../transforms/next_strip_page_exports.rs | 3 +- .../next_shared/transforms/server_actions.rs | 7 +- packages/next/package.json | 2 +- pnpm-lock.yaml | 10 +-- 13 files changed, 115 insertions(+), 72 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9387dd7d74c70..456f2d6b7660a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -322,7 +322,7 @@ dependencies = [ [[package]] name = "auto-hash-map" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" dependencies = [ "serde", "smallvec", @@ -3549,7 +3549,7 @@ dependencies = [ [[package]] name = "node-file-trace" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" dependencies = [ "anyhow", "serde", @@ -7678,7 +7678,7 @@ dependencies = [ [[package]] name = "turbo-tasks" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" dependencies = [ "anyhow", "async-trait", @@ -7710,7 +7710,7 @@ dependencies = [ [[package]] name = "turbo-tasks-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" dependencies = [ "anyhow", "cargo-lock", @@ -7722,7 +7722,7 @@ dependencies = [ [[package]] name = "turbo-tasks-bytes" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" dependencies = [ "anyhow", "bytes", @@ -7737,7 +7737,7 @@ dependencies = [ [[package]] name = "turbo-tasks-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" dependencies = [ "anyhow", "dotenvs", @@ -7751,7 +7751,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fetch" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7768,7 +7768,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fs" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" dependencies = [ "anyhow", "auto-hash-map", @@ -7798,7 +7798,7 @@ dependencies = [ [[package]] name = "turbo-tasks-hash" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" dependencies = [ "base16", "hex", @@ -7810,7 +7810,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" dependencies = [ "anyhow", "convert_case 0.6.0", @@ -7824,7 +7824,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros-shared" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" dependencies = [ "proc-macro2", "quote", @@ -7834,7 +7834,7 @@ dependencies = [ [[package]] name = "turbo-tasks-malloc" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" dependencies = [ "mimalloc", ] @@ -7842,7 +7842,7 @@ dependencies = [ [[package]] name = "turbo-tasks-memory" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" dependencies = [ "anyhow", "auto-hash-map", @@ -7867,7 +7867,7 @@ dependencies = [ [[package]] name = "turbopack" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" dependencies = [ "anyhow", "async-recursion", @@ -7898,7 +7898,7 @@ dependencies = [ [[package]] name = "turbopack-binding" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" dependencies = [ "auto-hash-map", "mdxjs", @@ -7939,7 +7939,7 @@ dependencies = [ [[package]] name = "turbopack-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7962,7 +7962,7 @@ dependencies = [ [[package]] name = "turbopack-cli-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" dependencies = [ "anyhow", "clap 4.4.2", @@ -7980,7 +7980,7 @@ dependencies = [ [[package]] name = "turbopack-core" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" dependencies = [ "anyhow", "async-recursion", @@ -8010,7 +8010,7 @@ dependencies = [ [[package]] name = "turbopack-css" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" dependencies = [ "anyhow", "async-trait", @@ -8036,7 +8036,7 @@ dependencies = [ [[package]] name = "turbopack-dev" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -8060,7 +8060,7 @@ dependencies = [ [[package]] name = "turbopack-dev-server" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" dependencies = [ "anyhow", "async-compression", @@ -8097,7 +8097,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" dependencies = [ "anyhow", "async-trait", @@ -8131,7 +8131,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-hmr-protocol" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" dependencies = [ "serde", "serde_json", @@ -8142,7 +8142,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-plugins" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" dependencies = [ "anyhow", "async-trait", @@ -8165,7 +8165,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-runtime" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" dependencies = [ "anyhow", "indoc", @@ -8182,7 +8182,7 @@ dependencies = [ [[package]] name = "turbopack-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -8198,7 +8198,7 @@ dependencies = [ [[package]] name = "turbopack-image" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" dependencies = [ "anyhow", "base64 0.21.4", @@ -8218,7 +8218,7 @@ dependencies = [ [[package]] name = "turbopack-json" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" dependencies = [ "anyhow", "serde", @@ -8233,7 +8233,7 @@ dependencies = [ [[package]] name = "turbopack-mdx" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" dependencies = [ "anyhow", "mdxjs", @@ -8248,7 +8248,7 @@ dependencies = [ [[package]] name = "turbopack-node" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" dependencies = [ "anyhow", "async-stream", @@ -8283,7 +8283,7 @@ dependencies = [ [[package]] name = "turbopack-static" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" dependencies = [ "anyhow", "serde", @@ -8299,7 +8299,7 @@ dependencies = [ [[package]] name = "turbopack-swc-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" dependencies = [ "swc_core", "turbo-tasks", @@ -8310,7 +8310,7 @@ dependencies = [ [[package]] name = "turbopack-trace-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" dependencies = [ "anyhow", "crossbeam-channel", @@ -8325,7 +8325,7 @@ dependencies = [ [[package]] name = "turbopack-wasm" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.3#cb1496ca9ee93f5270041e4988080c2eb52b0e35" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" dependencies = [ "anyhow", "indexmap 1.9.3", diff --git a/Cargo.toml b/Cargo.toml index 4c7e71f5b53d9..4a27aa315019c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,11 +43,11 @@ swc_core = { version = "0.86.81", features = [ testing = { version = "0.35.11" } # Turbo crates -turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231127.3" } +turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231127.4" } # [TODO]: need to refactor embed_directory! macro usages, as well as resolving turbo_tasks::function, macros.. -turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231127.3" } +turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231127.4" } # [TODO]: need to refactor embed_directory! macro usage in next-core -turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231127.3" } +turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231127.4" } # General Deps diff --git a/packages/next-swc/crates/next-core/src/next_client/transforms.rs b/packages/next-swc/crates/next-core/src/next_client/transforms.rs index b387763cf01fb..ef849c32cbcc7 100644 --- a/packages/next-swc/crates/next-core/src/next_client/transforms.rs +++ b/packages/next-swc/crates/next-core/src/next_client/transforms.rs @@ -25,26 +25,34 @@ pub async fn get_next_client_transforms_rules( let modularize_imports_config = &next_config.await?.modularize_imports; if let Some(modularize_imports_config) = modularize_imports_config { - rules.push(get_next_modularize_imports_rule(modularize_imports_config)); + rules.push(get_next_modularize_imports_rule( + modularize_imports_config, + *next_config.mdx_rs().await?, + )); } - rules.push(get_next_font_transform_rule()); + let mdx_rs = *next_config.mdx_rs().await?; + rules.push(get_next_font_transform_rule(mdx_rs)); let pages_dir = match context_ty { ClientContextType::Pages { pages_dir } => { rules.push( - get_next_pages_transforms_rule(pages_dir, ExportFilter::StripDataExports).await?, + get_next_pages_transforms_rule(pages_dir, ExportFilter::StripDataExports, mdx_rs) + .await?, ); Some(pages_dir) } ClientContextType::App { .. } => { - rules.push(get_server_actions_transform_rule(ActionsTransform::Client)); + rules.push(get_server_actions_transform_rule( + ActionsTransform::Client, + mdx_rs, + )); None } ClientContextType::Fallback | ClientContextType::Other => None, }; - rules.push(get_next_dynamic_transform_rule(false, false, pages_dir, mode).await?); + rules.push(get_next_dynamic_transform_rule(false, false, pages_dir, mode, mdx_rs).await?); rules.push(get_next_image_rule()); diff --git a/packages/next-swc/crates/next-core/src/next_server/context.rs b/packages/next-swc/crates/next-core/src/next_server/context.rs index 9bf41b1a9e9ee..02e3adbb12edd 100644 --- a/packages/next-swc/crates/next-core/src/next_server/context.rs +++ b/packages/next-swc/crates/next-core/src/next_server/context.rs @@ -255,7 +255,9 @@ pub async fn get_server_module_options_context( next_config: Vc, ) -> Result> { let custom_rules = get_next_server_transforms_rules(next_config, ty.into_value(), mode).await?; - let internal_custom_rules = get_next_server_internal_transforms_rules(ty.into_value()).await?; + let internal_custom_rules = + get_next_server_internal_transforms_rules(ty.into_value(), *next_config.mdx_rs().await?) + .await?; let foreign_code_context_condition = foreign_code_context_condition(next_config, project_path).await?; diff --git a/packages/next-swc/crates/next-core/src/next_server/transforms.rs b/packages/next-swc/crates/next-core/src/next_server/transforms.rs index c939e0ed5e385..61e48d91c6851 100644 --- a/packages/next-swc/crates/next-core/src/next_server/transforms.rs +++ b/packages/next-swc/crates/next-core/src/next_server/transforms.rs @@ -25,10 +25,14 @@ pub async fn get_next_server_transforms_rules( let mut rules = vec![]; let modularize_imports_config = &next_config.await?.modularize_imports; + let mdx_rs = *next_config.mdx_rs().await?; if let Some(modularize_imports_config) = modularize_imports_config { - rules.push(get_next_modularize_imports_rule(modularize_imports_config)); + rules.push(get_next_modularize_imports_rule( + modularize_imports_config, + mdx_rs, + )); } - rules.push(get_next_font_transform_rule()); + rules.push(get_next_font_transform_rule(mdx_rs)); let (is_server_components, pages_dir) = match context_ty { ServerContextType::Pages { pages_dir } | ServerContextType::PagesApi { pages_dir } => { @@ -36,19 +40,26 @@ pub async fn get_next_server_transforms_rules( } ServerContextType::PagesData { pages_dir } => { rules.push( - get_next_pages_transforms_rule(pages_dir, ExportFilter::StripDefaultExport).await?, + get_next_pages_transforms_rule(pages_dir, ExportFilter::StripDefaultExport, mdx_rs) + .await?, ); (false, Some(pages_dir)) } ServerContextType::AppSSR { .. } => { // Yah, this is SSR, but this is still treated as a Client transform layer. - rules.push(get_server_actions_transform_rule(ActionsTransform::Client)); + rules.push(get_server_actions_transform_rule( + ActionsTransform::Client, + mdx_rs, + )); (false, None) } ServerContextType::AppRSC { client_transition, .. } => { - rules.push(get_server_actions_transform_rule(ActionsTransform::Server)); + rules.push(get_server_actions_transform_rule( + ActionsTransform::Server, + mdx_rs, + )); if let Some(client_transition) = client_transition { rules.push(get_next_css_client_reference_transforms_rule( client_transition, @@ -60,7 +71,10 @@ pub async fn get_next_server_transforms_rules( ServerContextType::Middleware { .. } => (false, None), }; - rules.push(get_next_dynamic_transform_rule(true, is_server_components, pages_dir, mode).await?); + rules.push( + get_next_dynamic_transform_rule(true, is_server_components, pages_dir, mode, mdx_rs) + .await?, + ); rules.push(get_next_image_rule()); @@ -71,23 +85,24 @@ pub async fn get_next_server_transforms_rules( /// transforms, but which are only applied to internal modules. pub async fn get_next_server_internal_transforms_rules( context_ty: ServerContextType, + mdx_rs: bool, ) -> Result> { let mut rules = vec![]; match context_ty { ServerContextType::Pages { .. } => { // Apply next/font transforms to foreign code - rules.push(get_next_font_transform_rule()); + rules.push(get_next_font_transform_rule(mdx_rs)); } ServerContextType::PagesApi { .. } => {} ServerContextType::PagesData { .. } => {} ServerContextType::AppSSR { .. } => { - rules.push(get_next_font_transform_rule()); + rules.push(get_next_font_transform_rule(mdx_rs)); } ServerContextType::AppRSC { client_transition, .. } => { - rules.push(get_next_font_transform_rule()); + rules.push(get_next_font_transform_rule(mdx_rs)); if let Some(client_transition) = client_transition { rules.push(get_next_css_client_reference_transforms_rule( client_transition, diff --git a/packages/next-swc/crates/next-core/src/next_shared/transforms/mod.rs b/packages/next-swc/crates/next-core/src/next_shared/transforms/mod.rs index 49c4fe4320894..ca47788165365 100644 --- a/packages/next-swc/crates/next-core/src/next_shared/transforms/mod.rs +++ b/packages/next-swc/crates/next-core/src/next_shared/transforms/mod.rs @@ -56,16 +56,28 @@ pub fn get_next_image_rule() -> ModuleRule { } /// Returns a rule which applies the Next.js dynamic transform. -pub(crate) fn module_rule_match_js_no_url() -> ModuleRuleCondition { +pub(crate) fn module_rule_match_js_no_url(enable_mdx_rs: bool) -> ModuleRuleCondition { + let mut conditions = vec![ + ModuleRuleCondition::ResourcePathEndsWith(".js".to_string()), + ModuleRuleCondition::ResourcePathEndsWith(".jsx".to_string()), + ModuleRuleCondition::ResourcePathEndsWith(".ts".to_string()), + ModuleRuleCondition::ResourcePathEndsWith(".tsx".to_string()), + ]; + + if enable_mdx_rs { + conditions.append( + vec![ + ModuleRuleCondition::ResourcePathEndsWith(".md".to_string()), + ModuleRuleCondition::ResourcePathEndsWith(".mdx".to_string()), + ] + .as_mut(), + ); + } + ModuleRuleCondition::all(vec![ ModuleRuleCondition::not(ModuleRuleCondition::ReferenceType(ReferenceType::Url( UrlReferenceSubType::Undefined, ))), - ModuleRuleCondition::any(vec![ - ModuleRuleCondition::ResourcePathEndsWith(".js".to_string()), - ModuleRuleCondition::ResourcePathEndsWith(".jsx".to_string()), - ModuleRuleCondition::ResourcePathEndsWith(".ts".to_string()), - ModuleRuleCondition::ResourcePathEndsWith(".tsx".to_string()), - ]), + ModuleRuleCondition::any(conditions), ]) } diff --git a/packages/next-swc/crates/next-core/src/next_shared/transforms/modularize_imports.rs b/packages/next-swc/crates/next-core/src/next_shared/transforms/modularize_imports.rs index ada8add3ef787..33f452726b3d1 100644 --- a/packages/next-swc/crates/next-core/src/next_shared/transforms/modularize_imports.rs +++ b/packages/next-swc/crates/next-core/src/next_shared/transforms/modularize_imports.rs @@ -44,12 +44,13 @@ pub enum Transform { /// Returns a rule which applies the Next.js modularize imports transform. pub fn get_next_modularize_imports_rule( modularize_imports_config: &IndexMap, + enable_mdx_rs: bool, ) -> ModuleRule { let transformer = EcmascriptInputTransform::Plugin(Vc::cell(Box::new( ModularizeImportsTransformer::new(modularize_imports_config), ) as _)); ModuleRule::new( - module_rule_match_js_no_url(), + module_rule_match_js_no_url(enable_mdx_rs), vec![ModuleRuleEffect::AddEcmascriptTransforms(Vc::cell(vec![ transformer, ]))], diff --git a/packages/next-swc/crates/next-core/src/next_shared/transforms/next_dynamic.rs b/packages/next-swc/crates/next-core/src/next_shared/transforms/next_dynamic.rs index 468f55085114c..e5153d8f63e93 100644 --- a/packages/next-swc/crates/next-core/src/next_shared/transforms/next_dynamic.rs +++ b/packages/next-swc/crates/next-core/src/next_shared/transforms/next_dynamic.rs @@ -28,6 +28,7 @@ pub async fn get_next_dynamic_transform_rule( is_react_server_layer: bool, pages_dir: Option>, mode: NextMode, + enable_mdx_rs: bool, ) -> Result { let dynamic_transform = EcmascriptInputTransform::Plugin(Vc::cell(Box::new(NextJsDynamic { is_server_compiler, @@ -39,7 +40,7 @@ pub async fn get_next_dynamic_transform_rule( mode, }) as _)); Ok(ModuleRule::new( - module_rule_match_js_no_url(), + module_rule_match_js_no_url(enable_mdx_rs), vec![ModuleRuleEffect::AddEcmascriptTransforms(Vc::cell(vec![ dynamic_transform, ]))], diff --git a/packages/next-swc/crates/next-core/src/next_shared/transforms/next_font.rs b/packages/next-swc/crates/next-core/src/next_shared/transforms/next_font.rs index 098bcbe266945..5285893ae6312 100644 --- a/packages/next-swc/crates/next-core/src/next_shared/transforms/next_font.rs +++ b/packages/next-swc/crates/next-core/src/next_shared/transforms/next_font.rs @@ -10,7 +10,7 @@ use turbopack_binding::turbopack::{ use super::module_rule_match_js_no_url; /// Returns a rule which applies the Next.js font transform. -pub fn get_next_font_transform_rule() -> ModuleRule { +pub fn get_next_font_transform_rule(enable_mdx_rs: bool) -> ModuleRule { let font_loaders = vec![ "next/font/google".into(), "@next/font/google".into(), @@ -22,7 +22,7 @@ pub fn get_next_font_transform_rule() -> ModuleRule { EcmascriptInputTransform::Plugin(Vc::cell(Box::new(NextJsFont { font_loaders }) as _)); ModuleRule::new( // TODO: Only match in pages (not pages/api), app/, etc. - module_rule_match_js_no_url(), + module_rule_match_js_no_url(enable_mdx_rs), vec![ModuleRuleEffect::AddEcmascriptTransforms(Vc::cell(vec![ transformer, ]))], diff --git a/packages/next-swc/crates/next-core/src/next_shared/transforms/next_strip_page_exports.rs b/packages/next-swc/crates/next-core/src/next_shared/transforms/next_strip_page_exports.rs index bc5be315ed17f..28fb090be92fc 100644 --- a/packages/next-swc/crates/next-core/src/next_shared/transforms/next_strip_page_exports.rs +++ b/packages/next-swc/crates/next-core/src/next_shared/transforms/next_strip_page_exports.rs @@ -23,6 +23,7 @@ use super::module_rule_match_js_no_url; pub async fn get_next_pages_transforms_rule( pages_dir: Vc, export_filter: ExportFilter, + enable_mdx_rs: bool, ) -> Result { // Apply the Next SSG transform to all pages. let strip_transform = EcmascriptInputTransform::Plugin(Vc::cell(Box::new( @@ -51,7 +52,7 @@ pub async fn get_next_pages_transforms_rule( ), ])), ]), - module_rule_match_js_no_url(), + module_rule_match_js_no_url(enable_mdx_rs), ]), vec![ModuleRuleEffect::AddEcmascriptTransforms(Vc::cell(vec![ strip_transform, diff --git a/packages/next-swc/crates/next-core/src/next_shared/transforms/server_actions.rs b/packages/next-swc/crates/next-core/src/next_shared/transforms/server_actions.rs index a8cbfd14fa7c6..6f9a3f3c5e284 100644 --- a/packages/next-swc/crates/next-core/src/next_shared/transforms/server_actions.rs +++ b/packages/next-swc/crates/next-core/src/next_shared/transforms/server_actions.rs @@ -20,11 +20,14 @@ pub enum ActionsTransform { } /// Returns a rule which applies the Next.js Server Actions transform. -pub fn get_server_actions_transform_rule(transform: ActionsTransform) -> ModuleRule { +pub fn get_server_actions_transform_rule( + transform: ActionsTransform, + enable_mdx_rs: bool, +) -> ModuleRule { let transformer = EcmascriptInputTransform::Plugin(Vc::cell(Box::new(NextServerActions { transform }) as _)); ModuleRule::new( - module_rule_match_js_no_url(), + module_rule_match_js_no_url(enable_mdx_rs), vec![ModuleRuleEffect::AddEcmascriptTransforms(Vc::cell(vec![ transformer, ]))], diff --git a/packages/next/package.json b/packages/next/package.json index e4a3d8e3ceab9..e731ddb990437 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -195,7 +195,7 @@ "@types/ws": "8.2.0", "@vercel/ncc": "0.34.0", "@vercel/nft": "0.22.6", - "@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.3", + "@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.4", "acorn": "8.5.0", "amphtml-validator": "1.0.35", "anser": "1.4.9", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b3618a13b5efe..b26b30f633c53 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1074,8 +1074,8 @@ importers: specifier: 0.22.6 version: 0.22.6 '@vercel/turbopack-ecmascript-runtime': - specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.3 - version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.3(react-refresh@0.12.0)(webpack@5.86.0)' + specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.4 + version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.4(react-refresh@0.12.0)(webpack@5.86.0)' acorn: specifier: 8.5.0 version: 8.5.0 @@ -24648,9 +24648,9 @@ packages: /zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} - '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.3(react-refresh@0.12.0)(webpack@5.86.0)': - resolution: {registry: https://registry.npmjs.org/, tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.3} - id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.3' + '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.4(react-refresh@0.12.0)(webpack@5.86.0)': + resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.4} + id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.4' name: '@vercel/turbopack-ecmascript-runtime' version: 0.0.0 dependencies: From cd66493749a9e76ab32913f839e56b9828b22523 Mon Sep 17 00:00:00 2001 From: Zack Tanner Date: Tue, 28 Nov 2023 06:38:59 -0800 Subject: [PATCH 064/481] dedupe pending revalidation requests (#58990) ### What? We currently dedupe fetch requests, but if those fetch requests contain a `revalidate` time, when that window is expired all of those fetches will be invoked without deduping. ### Why? We track revalidations on the `staticGenerationStore` but we don't have a way to dedupe them, as it's currently just an array. When the (patched) fetch is invoked and catches a stale entry, it'll push each fetch onto the `pendingRevalidates` array which will later be invoked via `Promise.all`. ### How? This updates the shape of `pendingRevalidates` to be a map, that way we can reliably dedupe if we see a key that is already pending revalidation. Closes NEXT-1744 [slack x-ref](https://vercel.slack.com/archives/C03S8ED1DKM/p1700836529460289) --- ...tatic-generation-async-storage.external.ts | 2 +- .../src/server/app-render/action-handler.ts | 12 +++-- .../next/src/server/app-render/app-render.tsx | 2 +- .../future/route-modules/app-route/module.ts | 4 +- packages/next/src/server/lib/patch-fetch.ts | 9 ++-- .../web/spec-extension/revalidate-tag.ts | 8 ++-- .../web/spec-extension/unstable-cache.ts | 7 ++- .../app-fetch-deduping.test.ts | 44 ++++++++++++++++++- 8 files changed, 68 insertions(+), 20 deletions(-) diff --git a/packages/next/src/client/components/static-generation-async-storage.external.ts b/packages/next/src/client/components/static-generation-async-storage.external.ts index 1c30022ce392a..b216ec5dca5d4 100644 --- a/packages/next/src/client/components/static-generation-async-storage.external.ts +++ b/packages/next/src/client/components/static-generation-async-storage.external.ts @@ -26,7 +26,7 @@ export interface StaticGenerationStore { revalidate?: false | number forceStatic?: boolean dynamicShouldError?: boolean - pendingRevalidates?: Promise[] + pendingRevalidates?: Record> postponeWasTriggered?: boolean postpone?: (reason: string) => never diff --git a/packages/next/src/server/app-render/action-handler.ts b/packages/next/src/server/app-render/action-handler.ts index 787ee62d9d575..0ff64ebb8f360 100644 --- a/packages/next/src/server/app-render/action-handler.ts +++ b/packages/next/src/server/app-render/action-handler.ts @@ -111,7 +111,9 @@ async function addRevalidationHeader( requestStore: RequestStore } ) { - await Promise.all(staticGenerationStore.pendingRevalidates || []) + await Promise.all( + Object.values(staticGenerationStore.pendingRevalidates || []) + ) // If a tag was revalidated, the client router needs to invalidate all the // client router cache as they may be stale. And if a path was revalidated, the @@ -348,7 +350,9 @@ export async function handleAction({ if (isFetchAction) { res.statusCode = 500 - await Promise.all(staticGenerationStore.pendingRevalidates || []) + await Promise.all( + Object.values(staticGenerationStore.pendingRevalidates || []) + ) const promise = Promise.reject(error) try { @@ -640,7 +644,9 @@ To configure the body size limit for Server Actions, see: https://nextjs.org/doc if (isFetchAction) { res.statusCode = 500 - await Promise.all(staticGenerationStore.pendingRevalidates || []) + await Promise.all( + Object.values(staticGenerationStore.pendingRevalidates || []) + ) const promise = Promise.reject(err) try { // we need to await the promise to trigger the rejection early diff --git a/packages/next/src/server/app-render/app-render.tsx b/packages/next/src/server/app-render/app-render.tsx index 252bb68d83ab4..9b56b8a13a2ee 100644 --- a/packages/next/src/server/app-render/app-render.tsx +++ b/packages/next/src/server/app-render/app-render.tsx @@ -1037,7 +1037,7 @@ async function renderToHTMLOrFlightImpl( pageData: await stringifiedFlightPayloadPromise, // If we have pending revalidates, wait until they are all resolved. waitUntil: staticGenerationStore.pendingRevalidates - ? Promise.all(staticGenerationStore.pendingRevalidates) + ? Promise.all(Object.values(staticGenerationStore.pendingRevalidates)) : undefined, } ) diff --git a/packages/next/src/server/future/route-modules/app-route/module.ts b/packages/next/src/server/future/route-modules/app-route/module.ts index 56abebde7a5d0..0aab61b356361 100644 --- a/packages/next/src/server/future/route-modules/app-route/module.ts +++ b/packages/next/src/server/future/route-modules/app-route/module.ts @@ -368,7 +368,9 @@ export class AppRouteRouteModule extends RouteModule< staticGenerationStore.fetchMetrics context.renderOpts.waitUntil = Promise.all( - staticGenerationStore.pendingRevalidates || [] + Object.values( + staticGenerationStore.pendingRevalidates || [] + ) ) addImplicitTags(staticGenerationStore) diff --git a/packages/next/src/server/lib/patch-fetch.ts b/packages/next/src/server/lib/patch-fetch.ts index 4a831e9788151..d90e2ba11640a 100644 --- a/packages/next/src/server/lib/patch-fetch.ts +++ b/packages/next/src/server/lib/patch-fetch.ts @@ -546,12 +546,11 @@ export function patchFetch({ // so the revalidated entry has the updated data if (!(staticGenerationStore.isRevalidate && entry.isStale)) { if (entry.isStale) { - if (!staticGenerationStore.pendingRevalidates) { - staticGenerationStore.pendingRevalidates = [] + staticGenerationStore.pendingRevalidates ??= {} + if (!staticGenerationStore.pendingRevalidates[cacheKey]) { + staticGenerationStore.pendingRevalidates[cacheKey] = + doOriginalFetch(true).catch(console.error) } - staticGenerationStore.pendingRevalidates.push( - doOriginalFetch(true).catch(console.error) - ) } const resData = entry.value.data diff --git a/packages/next/src/server/web/spec-extension/revalidate-tag.ts b/packages/next/src/server/web/spec-extension/revalidate-tag.ts index fcd3be4fb80c3..2b3a7734561b2 100644 --- a/packages/next/src/server/web/spec-extension/revalidate-tag.ts +++ b/packages/next/src/server/web/spec-extension/revalidate-tag.ts @@ -30,13 +30,13 @@ export function revalidateTag(tag: string) { } if (!store.pendingRevalidates) { - store.pendingRevalidates = [] + store.pendingRevalidates = {} } - store.pendingRevalidates.push( - store.incrementalCache.revalidateTag?.(tag).catch((err) => { + store.pendingRevalidates[tag] = store.incrementalCache + .revalidateTag?.(tag) + .catch((err) => { console.error(`revalidateTag failed for ${tag}`, err) }) - ) // TODO: only revalidate if the path matches store.pathWasRevalidated = true diff --git a/packages/next/src/server/web/spec-extension/unstable-cache.ts b/packages/next/src/server/web/spec-extension/unstable-cache.ts index abf9a3d46cbf5..237bdf1688a28 100644 --- a/packages/next/src/server/web/spec-extension/unstable-cache.ts +++ b/packages/next/src/server/web/spec-extension/unstable-cache.ts @@ -166,12 +166,11 @@ export function unstable_cache( return invokeCallback() } else { if (!store.pendingRevalidates) { - store.pendingRevalidates = [] + store.pendingRevalidates = {} } - store.pendingRevalidates.push( - invokeCallback().catch((err) => + store.pendingRevalidates[joinedKey] = invokeCallback().catch( + (err) => console.error(`revalidating cache with key: ${joinedKey}`, err) - ) ) } } diff --git a/test/e2e/app-dir/app-fetch-deduping/app-fetch-deduping.test.ts b/test/e2e/app-dir/app-fetch-deduping/app-fetch-deduping.test.ts index a049db1517c30..1657be6e9ee19 100644 --- a/test/e2e/app-dir/app-fetch-deduping/app-fetch-deduping.test.ts +++ b/test/e2e/app-dir/app-fetch-deduping/app-fetch-deduping.test.ts @@ -1,4 +1,4 @@ -import { findPort } from 'next-test-utils' +import { findPort, waitFor } from 'next-test-utils' import http from 'http' import { outdent } from 'outdent' import { FileRef, createNext } from 'e2e-utils' @@ -82,6 +82,48 @@ describe('app-fetch-deduping', () => { await next.destroy() }) + + it('should dedupe pending revalidation requests', async () => { + const next = await createNext({ + files: new FileRef(__dirname), + }) + + await next.patchFile( + 'app/test/page.tsx', + outdent` + async function getTime() { + const res = await fetch("http://localhost:${next.appPort}/api/time", { next: { revalidate: 5 } }) + return res.text() + } + + export default async function Home() { + await getTime() + await getTime() + const time = await getTime() + + return

{time}

+ } + ` + ) + + await next.render('/test') + + let count = next.cliOutput.split('Starting...').length - 1 + expect(count).toBe(1) + + const outputIndex = next.cliOutput.length + + // wait for the revalidation to finish + await waitFor(6000) + + await next.render('/test') + + count = + next.cliOutput.slice(outputIndex).split('Starting...').length - 1 + expect(count).toBe(1) + + await next.destroy() + }) }) } else { it('should skip other scenarios', () => {}) From 8d1c619ad650f5d147207f267441caf12acd91d1 Mon Sep 17 00:00:00 2001 From: Jan Amann Date: Tue, 28 Nov 2023 16:14:47 +0100 Subject: [PATCH 065/481] fix: Put back type for `NavigateOptions.scroll` (#59001) It seems like in https://github.com/vercel/next.js/commit/24b2ff16abaa973d695247a9c1ac4e229640d4ca#diff-421107ce62efb02560358d25c5eb086d5d82d2ad1c7c4929ebfb768c2ea1c973 `forceOptimisticNavigation` was removed, but the `@internal` flag that was originally assigned to this option remained in place. Due to this, it seems like `scroll` is missing in the built types (see [`app-router-context.shared-runtime.d.ts` in the latest canary](https://unpkg.com/browse/next@14.0.4-canary.18/dist/shared/lib/app-router-context.shared-runtime.d.ts)). Co-authored-by: Zack Tanner --- .../next/src/shared/lib/app-router-context.shared-runtime.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/next/src/shared/lib/app-router-context.shared-runtime.ts b/packages/next/src/shared/lib/app-router-context.shared-runtime.ts index 250151cbb7a56..6b6ee05e900c8 100644 --- a/packages/next/src/shared/lib/app-router-context.shared-runtime.ts +++ b/packages/next/src/shared/lib/app-router-context.shared-runtime.ts @@ -68,7 +68,6 @@ export type CacheNode = } export interface NavigateOptions { - /** @internal */ scroll?: boolean } From f4c14935aa27b11cc7f2bf3b37b389668eeb4428 Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Tue, 28 Nov 2023 09:10:38 -0700 Subject: [PATCH 066/481] Cleanup Render Result (#58782) This improves some of the typings around the `RenderResult` returned during renders. Previously it had a single large metadata object that was shared across both the pages and app render pipelines. To add more type safety, this splits the types used by each of the render pipelines into their own types while still allowing the default `RenderResult` to reference metadata from either render pipeline. This also improved the flight data generation for app renders. Previously, the promise was inlined, and errors were swallowed. With the advent of improvements in #58779 the postpone errors are no longer returned by the flight generation and are instead handled correctly inside the render by React so it can emit properly postponed flight data. Besides that there was some whitespace changes, so hiding whitespace differences during review should make it much clearer to review! --- packages/next/src/build/utils.ts | 8 +- ...tatic-generation-async-storage.external.ts | 4 +- .../components/static-generation-bailout.ts | 12 +- packages/next/src/export/routes/app-page.ts | 16 +- .../src/server/app-render/action-handler.ts | 5 +- .../next/src/server/app-render/app-render.tsx | 275 +++++++++++------- .../server/app-render/flight-render-result.ts | 2 +- packages/next/src/server/base-server.ts | 8 +- packages/next/src/server/render-result.ts | 68 +++-- packages/next/src/server/render.tsx | 50 ++-- .../stream-utils/node-web-streams-helper.ts | 12 +- 11 files changed, 271 insertions(+), 189 deletions(-) diff --git a/packages/next/src/build/utils.ts b/packages/next/src/build/utils.ts index d99d6e3a28eea..3dfce139d23cb 100644 --- a/packages/next/src/build/utils.ts +++ b/packages/next/src/build/utils.ts @@ -1127,10 +1127,16 @@ export async function buildStaticPaths({ } } +export type AppConfigDynamic = + | 'auto' + | 'error' + | 'force-static' + | 'force-dynamic' + export type AppConfig = { revalidate?: number | false dynamicParams?: true | false - dynamic?: 'auto' | 'error' | 'force-static' | 'force-dynamic' + dynamic?: AppConfigDynamic fetchCache?: 'force-cache' | 'only-cache' preferredRegion?: string } diff --git a/packages/next/src/client/components/static-generation-async-storage.external.ts b/packages/next/src/client/components/static-generation-async-storage.external.ts index b216ec5dca5d4..1119969c6c275 100644 --- a/packages/next/src/client/components/static-generation-async-storage.external.ts +++ b/packages/next/src/client/components/static-generation-async-storage.external.ts @@ -2,6 +2,8 @@ import type { AsyncLocalStorage } from 'async_hooks' import type { IncrementalCache } from '../../server/lib/incremental-cache' import type { DynamicServerError } from './hooks-server-context' import type { FetchMetrics } from '../../server/base-http' +import type { Revalidate } from '../../server/lib/revalidate' + import { createAsyncLocalStorage } from './async-local-storage' export interface StaticGenerationStore { @@ -23,7 +25,7 @@ export interface StaticGenerationStore { | 'default-no-store' | 'only-no-store' - revalidate?: false | number + revalidate?: Revalidate forceStatic?: boolean dynamicShouldError?: boolean pendingRevalidates?: Record> diff --git a/packages/next/src/client/components/static-generation-bailout.ts b/packages/next/src/client/components/static-generation-bailout.ts index 354ee9a162a12..558c2ec763081 100644 --- a/packages/next/src/client/components/static-generation-bailout.ts +++ b/packages/next/src/client/components/static-generation-bailout.ts @@ -1,3 +1,5 @@ +import type { AppConfigDynamic } from '../../build/utils' + import { DynamicServerError } from './hooks-server-context' import { maybePostpone } from './maybe-postpone' import { staticGenerationAsyncStorage } from './static-generation-async-storage.external' @@ -6,7 +8,7 @@ class StaticGenBailoutError extends Error { code = 'NEXT_STATIC_GEN_BAILOUT' } -type BailoutOpts = { dynamic?: string; link?: string } +type BailoutOpts = { dynamic?: AppConfigDynamic; link?: string } export type StaticGenerationBailout = ( reason: string, @@ -23,7 +25,7 @@ function formatErrorMessage(reason: string, opts?: BailoutOpts) { export const staticGenerationBailout: StaticGenerationBailout = ( reason, - opts + { dynamic, link } = {} ) => { const staticGenerationStore = staticGenerationAsyncStorage.getStore() if (!staticGenerationStore) return false @@ -34,12 +36,12 @@ export const staticGenerationBailout: StaticGenerationBailout = ( if (staticGenerationStore.dynamicShouldError) { throw new StaticGenBailoutError( - formatErrorMessage(reason, { ...opts, dynamic: opts?.dynamic ?? 'error' }) + formatErrorMessage(reason, { link, dynamic: dynamic ?? 'error' }) ) } const message = formatErrorMessage(reason, { - ...opts, + dynamic, // this error should be caught by Next to bail out of static generation // in case it's uncaught, this link provides some additional context as to why link: 'https://nextjs.org/docs/messages/dynamic-server-error', @@ -51,7 +53,7 @@ export const staticGenerationBailout: StaticGenerationBailout = ( // to 0. staticGenerationStore.revalidate = 0 - if (!opts?.dynamic) { + if (!dynamic) { // we can statically prefetch pages that opt into dynamic, // but not things like headers/cookies staticGenerationStore.staticPrefetchBailout = true diff --git a/packages/next/src/export/routes/app-page.ts b/packages/next/src/export/routes/app-page.ts index 64b62dfc9405d..cc0c885d87e7f 100644 --- a/packages/next/src/export/routes/app-page.ts +++ b/packages/next/src/export/routes/app-page.ts @@ -25,6 +25,7 @@ import { lazyRenderAppPage } from '../../server/future/route-modules/app-page/mo export const enum ExportedAppPageFiles { HTML = 'HTML', FLIGHT = 'FLIGHT', + PREFETCH_FLIGHT = 'PREFETCH_FLIGHT', META = 'META', POSTPONED = 'POSTPONED', } @@ -128,10 +129,8 @@ export async function exportAppPage( const html = result.toUnchunkedString() - const { - metadata: { pageData, revalidate = false, postponed, fetchTags }, - } = result const { metadata } = result + const { flightData, revalidate = false, postponed, fetchTags } = metadata // Ensure we don't postpone without having PPR enabled. if (postponed && !renderOpts.experimental.ppr) { @@ -169,6 +168,11 @@ export async function exportAppPage( return { revalidate: 0 } } + // If page data isn't available, it means that the page couldn't be rendered + // properly. + else if (!flightData) { + throw new Error(`Invariant: failed to get page data for ${path}`) + } // If PPR is enabled, we want to emit a prefetch rsc file for the page // instead of the standard rsc. This is because the standard rsc will // contain the dynamic data. @@ -176,16 +180,16 @@ export async function exportAppPage( // If PPR is enabled, we should emit the flight data as the prefetch // payload. await fileWriter( - ExportedAppPageFiles.FLIGHT, + ExportedAppPageFiles.PREFETCH_FLIGHT, htmlFilepath.replace(/\.html$/, RSC_PREFETCH_SUFFIX), - pageData + flightData ) } else { // Writing the RSC payload to a file if we don't have PPR enabled. await fileWriter( ExportedAppPageFiles.FLIGHT, htmlFilepath.replace(/\.html$/, RSC_SUFFIX), - pageData + flightData ) } diff --git a/packages/next/src/server/app-render/action-handler.ts b/packages/next/src/server/app-render/action-handler.ts index 0ff64ebb8f360..d507553404e8a 100644 --- a/packages/next/src/server/app-render/action-handler.ts +++ b/packages/next/src/server/app-render/action-handler.ts @@ -210,7 +210,8 @@ async function createRedirectRenderResult( console.error(`failed to get redirect response`, err) } } - return new RenderResult(JSON.stringify({})) + + return RenderResult.fromStatic('{}') } // Used to compare Host header and Origin header. @@ -607,7 +608,7 @@ To configure the body size limit for Server Actions, see: https://nextjs.org/doc res.statusCode = 303 return { type: 'done', - result: new RenderResult(''), + result: RenderResult.fromStatic(''), } } else if (isNotFoundError(err)) { res.statusCode = 404 diff --git a/packages/next/src/server/app-render/app-render.tsx b/packages/next/src/server/app-render/app-render.tsx index 9b56b8a13a2ee..53664456c2119 100644 --- a/packages/next/src/server/app-render/app-render.tsx +++ b/packages/next/src/server/app-render/app-render.tsx @@ -15,6 +15,7 @@ import type { NextParsedUrlQuery } from '../request-meta' import type { LoaderTree } from '../lib/app-dir-module' import type { AppPageModule } from '../future/route-modules/app-page/module' import type { ClientReferenceManifest } from '../../build/webpack/plugins/flight-manifest-plugin' +import type { Revalidate } from '../lib/revalidate' import React from 'react' @@ -22,7 +23,11 @@ import { createServerComponentRenderer, type ServerComponentRendererOptions, } from './create-server-components-renderer' -import RenderResult, { type RenderResultMetadata } from '../render-result' +import RenderResult, { + type AppPageRenderResultMetadata, + type RenderResultOptions, + type RenderResultResponse, +} from '../render-result' import { renderToInitialFizzStream, continueFizzStream, @@ -106,7 +111,7 @@ export type AppRenderContext = AppRenderBaseContext & { appUsingSizeAdjustment: boolean providedFlightRouterState?: FlightRouterState requestId: string - defaultRevalidate: StaticGenerationStore['revalidate'] + defaultRevalidate: Revalidate pagePath: string clientReferenceManifest: ClientReferenceManifest assetPrefix: string @@ -303,6 +308,34 @@ async function generateFlight( return new FlightRenderResult(flightReadableStream) } +/** + * Creates a resolver that eagerly generates a flight payload that is then + * resolved when the resolver is called. + */ +function createFlightDataResolver(ctx: AppRenderContext) { + // Generate the flight data and as soon as it can, convert it into a string. + const promise = generateFlight(ctx) + .then(async (result) => ({ + flightData: await result.toUnchunkedString(true), + })) + // Otherwise if it errored, return the error. + .catch((err) => ({ err })) + + return async () => { + // Resolve the promise to get the flight data or error. + const result = await promise + + // If the flight data failed to render due to an error, re-throw the error + // here. + if ('err' in result) { + throw result.err + } + + // Otherwise, return the flight data. + return result.flightData + } +} + type ServerComponentsRendererOptions = { ctx: AppRenderContext preinitScripts: () => void @@ -430,7 +463,7 @@ async function renderToHTMLOrFlightImpl( globalThis.__next_chunk_load__ = ComponentMod.__next_app__.loadChunk } - const extraRenderResultMeta: RenderResultMetadata = {} + const metadata: AppPageRenderResultMetadata = {} const appUsingSizeAdjustment = !!nextFontManifest?.appUsingSizeAdjust @@ -469,7 +502,7 @@ async function renderToHTMLOrFlightImpl( const allCapturedErrors: Error[] = [] const isNextExport = !!renderOpts.nextExport const { staticGenerationStore, requestStore } = baseCtx - const isStaticGeneration = staticGenerationStore.isStaticGeneration + const { isStaticGeneration } = staticGenerationStore // when static generation fails during PPR, we log the errors separately. We intentionally // silence the error logger in this case to avoid double logging. const silenceStaticGenerationErrors = @@ -537,7 +570,7 @@ async function renderToHTMLOrFlightImpl( const { urlPathname } = staticGenerationStore staticGenerationStore.fetchMetrics = [] - extraRenderResultMeta.fetchMetrics = staticGenerationStore.fetchMetrics + metadata.fetchMetrics = staticGenerationStore.fetchMetrics // don't modify original query object query = { ...query } @@ -615,11 +648,14 @@ async function renderToHTMLOrFlightImpl( const hasPostponed = typeof renderOpts.postponed === 'string' - let stringifiedFlightPayloadPromise = isStaticGeneration - ? generateFlight(ctx) - .then((renderResult) => renderResult.toUnchunkedString(true)) - .catch(() => null) - : Promise.resolve(null) + // Create the resolver that can get the flight payload when it's ready or + // throw the error if it occurred. If we are not generating static HTML, we + // don't need to generate the flight payload because it's a dynamic request + // which means we're either getting the flight payload only or just the + // regular HTML. + const flightDataResolver = isStaticGeneration + ? createFlightDataResolver(ctx) + : null // Get the nonce from the incoming request if it has one. const csp = req.headers['content-security-policy'] @@ -754,8 +790,8 @@ async function renderToHTMLOrFlightImpl( // result. if (isStaticGeneration) { headers.forEach((value, key) => { - extraRenderResultMeta.headers ??= {} - extraRenderResultMeta.headers[key] = value + metadata.headers ??= {} + metadata.headers[key] = value }) // Resolve the promise to continue the stream. @@ -779,7 +815,7 @@ async function renderToHTMLOrFlightImpl( // If the stream was postponed, we need to add the result to the // metadata so that it can be resumed later. if (postponed) { - extraRenderResultMeta.postponed = JSON.stringify(postponed) + metadata.postponed = JSON.stringify(postponed) // We don't need to "continue" this stream now as it's continued when // we resume the stream. @@ -789,8 +825,7 @@ async function renderToHTMLOrFlightImpl( const options: ContinueStreamOptions = { inlinedDataStream: serverComponentsRenderOpts.inlinedDataTransformStream.readable, - generateStaticHTML: - staticGenerationStore.isStaticGeneration || generateStaticHTML, + isStaticGeneration: isStaticGeneration || generateStaticHTML, getServerInsertedHTML: () => getServerInsertedHTML(allCapturedErrors), serverInsertedHTMLToHead: !renderOpts.postponed, // If this render generated a postponed state or this is a resume @@ -968,7 +1003,7 @@ async function renderToHTMLOrFlightImpl( inlinedDataStream: serverErrorComponentsRenderOpts.inlinedDataTransformStream .readable, - generateStaticHTML: staticGenerationStore.isStaticGeneration, + isStaticGeneration, getServerInsertedHTML: () => getServerInsertedHTML([]), serverInsertedHTMLToHead: true, validateRootLayout, @@ -1012,11 +1047,11 @@ async function renderToHTMLOrFlightImpl( tree: notFoundLoaderTree, formState, }), - { ...extraRenderResultMeta } + { metadata } ) } else if (actionRequestResult.type === 'done') { if (actionRequestResult.result) { - actionRequestResult.result.extendMetadata(extraRenderResultMeta) + actionRequestResult.result.assignMetadata(metadata) return actionRequestResult.result } else if (actionRequestResult.formState) { formState = actionRequestResult.formState @@ -1024,114 +1059,130 @@ async function renderToHTMLOrFlightImpl( } } - const renderResult = new RenderResult( - await renderToStream({ - asNotFound: isNotFoundPath, - tree: loaderTree, - formState, - }), - { - ...extraRenderResultMeta, - // Wait for and collect the flight payload data if we don't have it - // already. - pageData: await stringifiedFlightPayloadPromise, - // If we have pending revalidates, wait until they are all resolved. - waitUntil: staticGenerationStore.pendingRevalidates - ? Promise.all(Object.values(staticGenerationStore.pendingRevalidates)) - : undefined, - } - ) + const options: RenderResultOptions = { + metadata, + } - addImplicitTags(staticGenerationStore) - extraRenderResultMeta.fetchTags = staticGenerationStore.tags?.join(',') - renderResult.extendMetadata({ - fetchTags: extraRenderResultMeta.fetchTags, + let response: RenderResultResponse = await renderToStream({ + asNotFound: isNotFoundPath, + tree: loaderTree, + formState, }) - if (staticGenerationStore.isStaticGeneration) { - // Collect the entire render result to a string (by streaming it to a - // string). - const htmlResult = await renderResult.toUnchunkedString(true) - - // Timeout after 1.5 seconds for the headers to write. If it takes - // longer than this it's more likely that the stream has stalled and - // there is a React bug. The headers will then be updated in the render - // result below when the metadata is re-added to the new render result. - const onTimeout = new DetachedPromise() - const timeout = setTimeout(() => { - onTimeout.reject( - new Error( - 'Timeout waiting for headers to be emitted, this is a bug in Next.js' - ) - ) - }, 1500) - - // Race against the timeout and the headers being written. - await Promise.race([onHeadersFinished.promise, onTimeout.promise]) - - // It got here, which means it did not reject, so clear the timeout to avoid - // it from rejecting again (which is a no-op anyways). - clearTimeout(timeout) - - if ( - // if PPR is enabled - renderOpts.experimental.ppr && - // and a call to `maybePostpone` happened - staticGenerationStore.postponeWasTriggered && - // but there's no postpone state - !extraRenderResultMeta.postponed - ) { - // a call to postpone was made but was caught and not detected by Next.js. We should fail the build immediately - // as we won't be able to generate the static part - warn('') - error( - `Prerendering ${urlPathname} needs to partially bail out because something dynamic was used. ` + - `React throws a special object to indicate where we need to bail out but it was caught ` + - `by a try/catch or a Promise was not awaited. These special objects should not be caught ` + - `by your own try/catch. Learn more: https://nextjs.org/docs/messages/ppr-caught-error` - ) + // If we have pending revalidates, wait until they are all resolved. + if (staticGenerationStore.pendingRevalidates) { + options.waitUntil = Promise.all( + Object.values(staticGenerationStore.pendingRevalidates) + ) + } - if (capturedErrors.length > 0) { - warn( - 'The following error was thrown during build, and may help identify the source of the issue:' - ) + addImplicitTags(staticGenerationStore) - error(capturedErrors[0]) - } + if (staticGenerationStore.tags) { + metadata.fetchTags = staticGenerationStore.tags.join(',') + } - throw new MissingPostponeDataError( - `An unexpected error occurred while prerendering ${urlPathname}. Please check the logs above for more details.` + // Create the new render result for the response. + const result = new RenderResult(response, options) + + // If we aren't performing static generation, we can return the result now. + if (!isStaticGeneration) { + return result + } + + // If this is static generation, we should read this in now rather than + // sending it back to be sent to the client. + response = await result.toUnchunkedString(true) + + // Timeout after 1.5 seconds for the headers to write. If it takes + // longer than this it's more likely that the stream has stalled and + // there is a React bug. The headers will then be updated in the render + // result below when the metadata is re-added to the new render result. + const onTimeout = new DetachedPromise() + const timeout = setTimeout(() => { + onTimeout.reject( + new Error( + 'Timeout waiting for headers to be emitted, this is a bug in Next.js' ) - } + ) + }, 1500) + + // Race against the timeout and the headers being written. + await Promise.race([onHeadersFinished.promise, onTimeout.promise]) + + // It got here, which means it did not reject, so clear the timeout to avoid + // it from rejecting again (which is a no-op anyways). + clearTimeout(timeout) + + if ( + // if PPR is enabled + renderOpts.experimental.ppr && + // and a call to `maybePostpone` happened + staticGenerationStore.postponeWasTriggered && + // but there's no postpone state + !metadata.postponed + ) { + // a call to postpone was made but was caught and not detected by Next.js. We should fail the build immediately + // as we won't be able to generate the static part + warn('') + error( + `Prerendering ${urlPathname} needs to partially bail out because something dynamic was used. ` + + `React throws a special object to indicate where we need to bail out but it was caught ` + + `by a try/catch or a Promise was not awaited. These special objects should not be caught ` + + `by your own try/catch. Learn more: https://nextjs.org/docs/messages/ppr-caught-error` + ) - // if we encountered any unexpected errors during build - // we fail the prerendering phase and the build if (capturedErrors.length > 0) { - throw capturedErrors[0] - } + warn( + 'The following error was thrown during build, and may help identify the source of the issue:' + ) - if (staticGenerationStore.forceStatic === false) { - staticGenerationStore.revalidate = 0 + error(capturedErrors[0]) } - // TODO-APP: derive this from same pass to prevent additional - // render during static generation - extraRenderResultMeta.pageData = await stringifiedFlightPayloadPromise - extraRenderResultMeta.revalidate = - staticGenerationStore.revalidate ?? ctx.defaultRevalidate - - // provide bailout info for debugging - if (extraRenderResultMeta.revalidate === 0) { - extraRenderResultMeta.staticBailoutInfo = { - description: staticGenerationStore.dynamicUsageDescription, - stack: staticGenerationStore.dynamicUsageStack, - } - } + throw new MissingPostponeDataError( + `An unexpected error occurred while prerendering ${urlPathname}. Please check the logs above for more details.` + ) + } + + if (!flightDataResolver) { + throw new Error( + 'Invariant: Flight data resolver is missing when generating static HTML' + ) + } + + // If we encountered any unexpected errors during build we fail the + // prerendering phase and the build. + if (capturedErrors.length > 0) { + throw capturedErrors[0] + } - return new RenderResult(htmlResult, { ...extraRenderResultMeta }) + // Wait for and collect the flight payload data if we don't have it + // already + const flightData = await flightDataResolver() + if (flightData) { + metadata.flightData = flightData + } + + // If force static is specifically set to false, we should not revalidate + // the page. + if (staticGenerationStore.forceStatic === false) { + staticGenerationStore.revalidate = 0 + } + + // Copy the revalidation value onto the render result metadata. + metadata.revalidate = + staticGenerationStore.revalidate ?? ctx.defaultRevalidate + + // provide bailout info for debugging + if (metadata.revalidate === 0) { + metadata.staticBailoutInfo = { + description: staticGenerationStore.dynamicUsageDescription, + stack: staticGenerationStore.dynamicUsageStack, + } } - return renderResult + return new RenderResult(response, options) } export type AppPageRender = ( @@ -1140,7 +1191,7 @@ export type AppPageRender = ( pagePath: string, query: NextParsedUrlQuery, renderOpts: RenderOpts -) => Promise +) => Promise> export const renderToHTMLOrFlight: AppPageRender = ( req, diff --git a/packages/next/src/server/app-render/flight-render-result.ts b/packages/next/src/server/app-render/flight-render-result.ts index e37ffc8c95587..f14dfbc97b94b 100644 --- a/packages/next/src/server/app-render/flight-render-result.ts +++ b/packages/next/src/server/app-render/flight-render-result.ts @@ -6,6 +6,6 @@ import RenderResult from '../render-result' */ export class FlightRenderResult extends RenderResult { constructor(response: string | ReadableStream) { - super(response, { contentType: RSC_CONTENT_TYPE_HEADER }) + super(response, { contentType: RSC_CONTENT_TYPE_HEADER, metadata: {} }) } } diff --git a/packages/next/src/server/base-server.ts b/packages/next/src/server/base-server.ts index 79504e567728d..ba353d82ee7bb 100644 --- a/packages/next/src/server/base-server.ts +++ b/packages/next/src/server/base-server.ts @@ -2406,7 +2406,7 @@ export default abstract class Server { // should return. // Handle `isNotFound`. - if (metadata.isNotFound) { + if ('isNotFound' in metadata && metadata.isNotFound) { return { value: null, revalidate: metadata.revalidate } } @@ -2415,7 +2415,7 @@ export default abstract class Server { return { value: { kind: 'REDIRECT', - props: metadata.pageData, + props: metadata.pageData ?? metadata.flightData, }, revalidate: metadata.revalidate, } @@ -2431,7 +2431,7 @@ export default abstract class Server { value: { kind: 'PAGE', html: result, - pageData: metadata.pageData, + pageData: metadata.pageData ?? metadata.flightData, postponed: metadata.postponed, headers, status: isAppPath ? res.statusCode : undefined, @@ -3224,7 +3224,7 @@ export default abstract class Server { if (this.renderOpts.dev && ctx.pathname === '/favicon.ico') { return { type: 'html', - body: new RenderResult(''), + body: RenderResult.fromStatic(''), } } const { res, query } = ctx diff --git a/packages/next/src/server/render-result.ts b/packages/next/src/server/render-result.ts index 8a498e6fb0bd1..6f9f87d0f6f50 100644 --- a/packages/next/src/server/render-result.ts +++ b/packages/next/src/server/render-result.ts @@ -1,6 +1,6 @@ import type { OutgoingHttpHeaders, ServerResponse } from 'http' -import type { StaticGenerationStore } from '../client/components/static-generation-async-storage.external' import type { Revalidate } from './lib/revalidate' +import type { FetchMetrics } from './base-http' import { chainStreams, @@ -11,38 +11,58 @@ import { isAbortError, pipeToNodeResponse } from './pipe-readable' type ContentTypeOption = string | undefined -export type RenderResultMetadata = { - pageData?: any +export type AppPageRenderResultMetadata = { + flightData?: string revalidate?: Revalidate staticBailoutInfo?: { stack?: string description?: string } - assetQueryString?: string - isNotFound?: boolean - isRedirect?: boolean - fetchMetrics?: StaticGenerationStore['fetchMetrics'] - fetchTags?: string - waitUntil?: Promise /** - * The headers to set on the response that were added by the render. + * The postponed state if the render had postponed and needs to be resumed. */ - headers?: OutgoingHttpHeaders + postponed?: string /** - * The postponed state if the render had postponed and needs to be resumed. + * The headers to set on the response that were added by the render. */ - postponed?: string + headers?: OutgoingHttpHeaders + fetchTags?: string + fetchMetrics?: FetchMetrics +} + +export type PagesRenderResultMetadata = { + pageData?: any + revalidate?: Revalidate + assetQueryString?: string + isNotFound?: boolean + isRedirect?: boolean } -type RenderResultResponse = +export type StaticRenderResultMetadata = {} + +export type RenderResultMetadata = AppPageRenderResultMetadata & + PagesRenderResultMetadata & + StaticRenderResultMetadata + +export type RenderResultResponse = | ReadableStream[] | ReadableStream | string | null -export default class RenderResult { +export type RenderResultOptions< + Metadata extends RenderResultMetadata = RenderResultMetadata +> = { + contentType?: ContentTypeOption + waitUntil?: Promise + metadata: Metadata +} + +export default class RenderResult< + Metadata extends RenderResultMetadata = RenderResultMetadata +> { /** * The detected content type for the response. This is used to set the * `Content-Type` header. @@ -53,7 +73,7 @@ export default class RenderResult { * The metadata for the response. This is used to set the revalidation times * and other metadata. */ - public readonly metadata: RenderResultMetadata + public readonly metadata: Readonly /** * The response itself. This can be a string, a stream, or null. If it's a @@ -69,21 +89,15 @@ export default class RenderResult { * @param value the static response value * @returns a new RenderResult instance */ - public static fromStatic(value: string): RenderResult { - return new RenderResult(value) + public static fromStatic(value: string) { + return new RenderResult(value, { metadata: {} }) } - private waitUntil?: Promise + private readonly waitUntil?: Promise constructor( response: RenderResultResponse, - { - contentType, - waitUntil, - ...metadata - }: { - contentType?: ContentTypeOption - } & RenderResultMetadata = {} + { contentType, waitUntil, metadata }: RenderResultOptions ) { this.response = response this.contentType = contentType @@ -91,7 +105,7 @@ export default class RenderResult { this.waitUntil = waitUntil } - public extendMetadata(metadata: RenderResultMetadata) { + public assignMetadata(metadata: Metadata) { Object.assign(this.metadata, metadata) } diff --git a/packages/next/src/server/render.tsx b/packages/next/src/server/render.tsx index 5ca9b50977162..7b079fbd7162e 100644 --- a/packages/next/src/server/render.tsx +++ b/packages/next/src/server/render.tsx @@ -78,7 +78,7 @@ import { normalizePagePath } from '../shared/lib/page-path/normalize-page-path' import { denormalizePagePath } from '../shared/lib/page-path/denormalize-page-path' import { getRequestMeta } from './request-meta' import { allowedStatusCodes, getRedirectStatus } from '../lib/redirect-status' -import RenderResult, { type RenderResultMetadata } from './render-result' +import RenderResult, { type PagesRenderResultMetadata } from './render-result' import isError from '../lib/is-error' import { streamFromString, @@ -414,20 +414,20 @@ export async function renderToHTMLImpl( // Adds support for reading `cookies` in `getServerSideProps` when SSR. setLazyProp({ req: req as any }, 'cookies', getCookieParser(req.headers)) - const renderResultMeta: RenderResultMetadata = {} + const metadata: PagesRenderResultMetadata = {} // In dev we invalidate the cache by appending a timestamp to the resource URL. // This is a workaround to fix https://github.com/vercel/next.js/issues/5860 // TODO: remove this workaround when https://bugs.webkit.org/show_bug.cgi?id=187726 is fixed. - renderResultMeta.assetQueryString = renderOpts.dev + metadata.assetQueryString = renderOpts.dev ? renderOpts.assetQueryString || `?ts=${Date.now()}` : '' // if deploymentId is provided we append it to all asset requests if (renderOpts.deploymentId) { - renderResultMeta.assetQueryString += `${ - renderResultMeta.assetQueryString ? '&' : '?' - }dpl=${renderOpts.deploymentId}` + metadata.assetQueryString += `${metadata.assetQueryString ? '&' : '?'}dpl=${ + renderOpts.deploymentId + }` } // don't modify original query object @@ -454,7 +454,7 @@ export async function renderToHTMLImpl( } = renderOpts const { App } = extra - const assetQueryString = renderResultMeta.assetQueryString + const assetQueryString = metadata.assetQueryString let Document = extra.Document @@ -892,7 +892,7 @@ export async function renderToHTMLImpl( ) } - renderResultMeta.isNotFound = true + metadata.isNotFound = true } if ( @@ -916,12 +916,12 @@ export async function renderToHTMLImpl( if (typeof data.redirect.basePath !== 'undefined') { ;(data as any).props.__N_REDIRECT_BASE_PATH = data.redirect.basePath } - renderResultMeta.isRedirect = true + metadata.isRedirect = true } if ( (dev || isBuildTimeSSG) && - !renderResultMeta.isNotFound && + !metadata.isNotFound && !isSerializableProps(pathname, 'getStaticProps', (data as any).props) ) { // this fn should throw an error instead of ever returning `false` @@ -992,12 +992,12 @@ export async function renderToHTMLImpl( ) // pass up revalidate and props for export - renderResultMeta.revalidate = revalidate - renderResultMeta.pageData = props + metadata.revalidate = revalidate + metadata.pageData = props // this must come after revalidate is added to renderResultMeta - if (renderResultMeta.isNotFound) { - return new RenderResult(null, renderResultMeta) + if (metadata.isNotFound) { + return new RenderResult(null, { metadata }) } } @@ -1110,8 +1110,8 @@ export async function renderToHTMLImpl( ) } - renderResultMeta.isNotFound = true - return new RenderResult(null, renderResultMeta) + metadata.isNotFound = true + return new RenderResult(null, { metadata }) } if ('redirect' in data && typeof data.redirect === 'object') { @@ -1123,7 +1123,7 @@ export async function renderToHTMLImpl( if (typeof data.redirect.basePath !== 'undefined') { ;(data as any).props.__N_REDIRECT_BASE_PATH = data.redirect.basePath } - renderResultMeta.isRedirect = true + metadata.isRedirect = true } if (deferredContent) { @@ -1141,7 +1141,7 @@ export async function renderToHTMLImpl( } props.pageProps = Object.assign({}, props.pageProps, (data as any).props) - renderResultMeta.pageData = props + metadata.pageData = props } if ( @@ -1158,8 +1158,10 @@ export async function renderToHTMLImpl( // Avoid rendering page un-necessarily for getServerSideProps data request // and getServerSideProps/getStaticProps redirects - if ((isDataReq && !isSSG) || renderResultMeta.isRedirect) { - return new RenderResult(JSON.stringify(props), renderResultMeta) + if ((isDataReq && !isSSG) || metadata.isRedirect) { + return new RenderResult(JSON.stringify(props), { + metadata, + }) } // We don't call getStaticProps or getServerSideProps while generating @@ -1169,7 +1171,7 @@ export async function renderToHTMLImpl( } // the response might be finished on the getInitialProps call - if (isResSent(res) && !isSSG) return new RenderResult(null, renderResultMeta) + if (isResSent(res) && !isSSG) return new RenderResult(null, { metadata }) // we preload the buildManifest for auto-export dynamic pages // to speed up hydrating query values @@ -1333,7 +1335,7 @@ export async function renderToHTMLImpl( return continueFizzStream(initialStream, { suffix, inlinedDataStream: serverComponentsInlinedTransformStream?.readable, - generateStaticHTML: true, + isStaticGeneration: true, // this must be called inside bodyResult so appWrappers is // up to date when `wrapApp` is called getServerInsertedHTML: () => { @@ -1408,7 +1410,7 @@ export async function renderToHTMLImpl( async () => renderDocument() ) if (!documentResult) { - return new RenderResult(null, renderResultMeta) + return new RenderResult(null, { metadata }) } const dynamicImportsIds = new Set() @@ -1567,7 +1569,7 @@ export async function renderToHTMLImpl( hybridAmp, }) - return new RenderResult(optimizedHtml, renderResultMeta) + return new RenderResult(optimizedHtml, { metadata }) } export type PagesRender = ( diff --git a/packages/next/src/server/stream-utils/node-web-streams-helper.ts b/packages/next/src/server/stream-utils/node-web-streams-helper.ts index 77a27cee01396..3b249ead98dcd 100644 --- a/packages/next/src/server/stream-utils/node-web-streams-helper.ts +++ b/packages/next/src/server/stream-utils/node-web-streams-helper.ts @@ -442,7 +442,7 @@ function chainTransformers( export type ContinueStreamOptions = { inlinedDataStream: ReadableStream | undefined - generateStaticHTML: boolean + isStaticGeneration: boolean getServerInsertedHTML: (() => Promise) | undefined serverInsertedHTMLToHead: boolean validateRootLayout: @@ -462,7 +462,7 @@ export async function continueFizzStream( { suffix, inlinedDataStream, - generateStaticHTML, + isStaticGeneration, getServerInsertedHTML, serverInsertedHTMLToHead, validateRootLayout, @@ -475,7 +475,7 @@ export async function continueFizzStream( // If we're generating static HTML and there's an `allReady` promise on the // stream, we need to wait for it to resolve before continuing. - if (generateStaticHTML && 'allReady' in renderStream) { + if (isStaticGeneration && 'allReady' in renderStream) { await renderStream.allReady } @@ -518,7 +518,7 @@ export async function continueFizzStream( type ContinuePostponedStreamOptions = Pick< ContinueStreamOptions, | 'inlinedDataStream' - | 'generateStaticHTML' + | 'isStaticGeneration' | 'getServerInsertedHTML' | 'serverInsertedHTMLToHead' > @@ -527,7 +527,7 @@ export async function continuePostponedFizzStream( renderStream: ReactReadableStream, { inlinedDataStream, - generateStaticHTML, + isStaticGeneration, getServerInsertedHTML, serverInsertedHTMLToHead, }: ContinuePostponedStreamOptions @@ -536,7 +536,7 @@ export async function continuePostponedFizzStream( // If we're generating static HTML and there's an `allReady` promise on the // stream, we need to wait for it to resolve before continuing. - if (generateStaticHTML && 'allReady' in renderStream) { + if (isStaticGeneration && 'allReady' in renderStream) { await renderStream.allReady } From 9c791866107d8818ea099f870d394d21acb87820 Mon Sep 17 00:00:00 2001 From: Leah Date: Tue, 28 Nov 2023 17:41:28 +0100 Subject: [PATCH 067/481] =?UTF-8?q?fix(turbopack):=20add=20list=20of=20pac?= =?UTF-8?q?kages=20that=20should=20never=20be=20marked=20as=20e=E2=80=A6?= =?UTF-8?q?=20(#59020)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ### What? Turbopack was missing the list of modules / requests that should never be marked as external: https://github.com/vercel/next.js/blob/8d1c619ad650f5d147207f267441caf12acd91d1/packages/next/src/build/handle-externals.ts#L188 This could lead to errors with i.e. `next/image` not receiving the correct image config. Closes PACK-2047 Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com> --- .../crates/next-core/src/next_server/resolve.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/next-swc/crates/next-core/src/next_server/resolve.rs b/packages/next-swc/crates/next-core/src/next_server/resolve.rs index 2cee86cf225ab..411030c757ed1 100644 --- a/packages/next-swc/crates/next-core/src/next_server/resolve.rs +++ b/packages/next-swc/crates/next-core/src/next_server/resolve.rs @@ -80,7 +80,15 @@ impl ResolvePlugin for ExternalCjsModulesResolvePlugin { if *condition(self.root).matches(context).await? { return Ok(ResolveResultOption::none()); } - if !matches!(&*request.await?, Request::Module { .. }) { + let request_value = &*request.await?; + if !matches!(request_value, Request::Module { .. }) { + return Ok(ResolveResultOption::none()); + } + + // from https://github.com/vercel/next.js/blob/8d1c619ad650f5d147207f267441caf12acd91d1/packages/next/src/build/handle-externals.ts#L188 + let never_external_regex = lazy_regex::regex!("^(?:private-next-pages\\/|next\\/(?:dist\\/pages\\/|(?:app|document|link|image|legacy\\/image|constants|dynamic|script|navigation|headers|router)$)|string-hash|private-next-rsc-action-validate|private-next-rsc-action-client-wrapper|private-next-rsc-action-proxy$)"); + + if never_external_regex.is_match(&request_value.request().unwrap_or_default()) { return Ok(ResolveResultOption::none()); } From 113a125a93316bed2f6a73184af9d2480fde9435 Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Tue, 28 Nov 2023 16:44:35 +0000 Subject: [PATCH 068/481] v14.0.4-canary.20 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 18 +++++++++--------- 18 files changed, 34 insertions(+), 34 deletions(-) diff --git a/lerna.json b/lerna.json index 3198bd6a9f2d3..6a9d6005180e8 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.19" + "version": "14.0.4-canary.20" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index b22b81f4d599e..1e1084867564b 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.19", + "version": "14.0.4-canary.20", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 10826c9eeafd1..e404a87720057 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.19", + "version": "14.0.4-canary.20", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.19", + "@next/eslint-plugin-next": "14.0.4-canary.20", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 0bc29fdb43db5..0e329b1758e4e 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.19", + "version": "14.0.4-canary.20", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index 87703c001408c..76efd598eb21f 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.19", + "version": "14.0.4-canary.20", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index c4e2bb725b0c1..d2392c1046026 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.19", + "version": "14.0.4-canary.20", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 79acb0d78bb58..ff29fb14d5a1c 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.19", + "version": "14.0.4-canary.20", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index fec191f7e85ea..e0d6ae26917d2 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.19", + "version": "14.0.4-canary.20", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index f11d76a4accf6..52d6b79268165 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.19", + "version": "14.0.4-canary.20", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 80ee1d7264675..5b6121815b88c 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.19", + "version": "14.0.4-canary.20", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index 7739a291d411a..b85a06bd9fa50 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.19", + "version": "14.0.4-canary.20", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index f48872688d982..6e1bcacefd7a6 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.19", + "version": "14.0.4-canary.20", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index ec2c9e6502717..1028e75335e09 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.19", + "version": "14.0.4-canary.20", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index e731ddb990437..0957fc97e544a 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.19", + "version": "14.0.4-canary.20", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.19", + "@next/env": "14.0.4-canary.20", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -147,11 +147,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.19", - "@next/polyfill-nomodule": "14.0.4-canary.19", - "@next/react-dev-overlay": "14.0.4-canary.19", - "@next/react-refresh-utils": "14.0.4-canary.19", - "@next/swc": "14.0.4-canary.19", + "@next/polyfill-module": "14.0.4-canary.20", + "@next/polyfill-nomodule": "14.0.4-canary.20", + "@next/react-dev-overlay": "14.0.4-canary.20", + "@next/react-refresh-utils": "14.0.4-canary.20", + "@next/swc": "14.0.4-canary.20", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index ab3a15b566c47..c96e0901cce7b 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.19", + "version": "14.0.4-canary.20", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index 43c03b8d07cb9..b44431b8996ff 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.19", + "version": "14.0.4-canary.20", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index 3a6cb5f628278..eecc3f4a59a68 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.19", + "version": "14.0.4-canary.20", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -23,7 +23,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.19", + "next": "14.0.4-canary.20", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b26b30f633c53..c462e8b803790 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -738,7 +738,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.19 + specifier: 14.0.4-canary.20 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -803,7 +803,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.19 + specifier: 14.0.4-canary.20 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -930,19 +930,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.19 + specifier: 14.0.4-canary.20 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.19 + specifier: 14.0.4-canary.20 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.19 + specifier: 14.0.4-canary.20 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.19 + specifier: 14.0.4-canary.20 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.19 + specifier: 14.0.4-canary.20 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1596,7 +1596,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.19 + specifier: 14.0.4-canary.20 version: link:../next outdent: specifier: 0.8.0 @@ -24649,7 +24649,7 @@ packages: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.4(react-refresh@0.12.0)(webpack@5.86.0)': - resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.4} + resolution: {registry: https://registry.npmjs.org/, tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.4} id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.4' name: '@vercel/turbopack-ecmascript-runtime' version: 0.0.0 From 6fd3c3b9921e0732fb46738135a0667c234345f8 Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Tue, 28 Nov 2023 17:00:46 +0000 Subject: [PATCH 069/481] v14.0.4-canary.21 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 16 ++++++++-------- 18 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lerna.json b/lerna.json index 6a9d6005180e8..ec99754294ba5 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.20" + "version": "14.0.4-canary.21" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 1e1084867564b..af1c7817b6944 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.20", + "version": "14.0.4-canary.21", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index e404a87720057..48d4f12e749b7 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.20", + "version": "14.0.4-canary.21", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.20", + "@next/eslint-plugin-next": "14.0.4-canary.21", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 0e329b1758e4e..314ff38296e3e 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.20", + "version": "14.0.4-canary.21", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index 76efd598eb21f..c6f8d33fb190d 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.20", + "version": "14.0.4-canary.21", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index d2392c1046026..0a89b3b0241e8 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.20", + "version": "14.0.4-canary.21", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index ff29fb14d5a1c..a2d5517335be7 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.20", + "version": "14.0.4-canary.21", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index e0d6ae26917d2..961dd2fa6da24 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.20", + "version": "14.0.4-canary.21", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 52d6b79268165..80fdb4a950a5f 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.20", + "version": "14.0.4-canary.21", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 5b6121815b88c..2c43fed816b41 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.20", + "version": "14.0.4-canary.21", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index b85a06bd9fa50..c2b30b0021b74 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.20", + "version": "14.0.4-canary.21", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index 6e1bcacefd7a6..3a93b85969a54 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.20", + "version": "14.0.4-canary.21", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index 1028e75335e09..745024cef8c35 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.20", + "version": "14.0.4-canary.21", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index 0957fc97e544a..5f47cec572be1 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.20", + "version": "14.0.4-canary.21", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.20", + "@next/env": "14.0.4-canary.21", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -147,11 +147,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.20", - "@next/polyfill-nomodule": "14.0.4-canary.20", - "@next/react-dev-overlay": "14.0.4-canary.20", - "@next/react-refresh-utils": "14.0.4-canary.20", - "@next/swc": "14.0.4-canary.20", + "@next/polyfill-module": "14.0.4-canary.21", + "@next/polyfill-nomodule": "14.0.4-canary.21", + "@next/react-dev-overlay": "14.0.4-canary.21", + "@next/react-refresh-utils": "14.0.4-canary.21", + "@next/swc": "14.0.4-canary.21", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index c96e0901cce7b..99ccdedd263c9 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.20", + "version": "14.0.4-canary.21", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index b44431b8996ff..0cd4cb428f1e0 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.20", + "version": "14.0.4-canary.21", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index eecc3f4a59a68..e55265f5dfbbd 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.20", + "version": "14.0.4-canary.21", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -23,7 +23,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.20", + "next": "14.0.4-canary.21", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c462e8b803790..a8c1ce7f7742d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -738,7 +738,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.20 + specifier: 14.0.4-canary.21 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -803,7 +803,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.20 + specifier: 14.0.4-canary.21 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -930,19 +930,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.20 + specifier: 14.0.4-canary.21 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.20 + specifier: 14.0.4-canary.21 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.20 + specifier: 14.0.4-canary.21 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.20 + specifier: 14.0.4-canary.21 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.20 + specifier: 14.0.4-canary.21 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1596,7 +1596,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.20 + specifier: 14.0.4-canary.21 version: link:../next outdent: specifier: 0.8.0 From 38e9bc97704d2c299d9b247fbd39f039be8b1f9f Mon Sep 17 00:00:00 2001 From: Delba de Oliveira <32464864+delbaoliveira@users.noreply.github.com> Date: Tue, 28 Nov 2023 17:19:05 +0000 Subject: [PATCH 070/481] Docs: Add missing diagram (#59008) Slack feedback. Add missing diagram, and polish wording for `layout.tsx` explanation. --- .../02-file-conventions/layout.mdx | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/docs/02-app/02-api-reference/02-file-conventions/layout.mdx b/docs/02-app/02-api-reference/02-file-conventions/layout.mdx index 91e7805948f64..8ad0337e940e9 100644 --- a/docs/02-app/02-api-reference/02-file-conventions/layout.mdx +++ b/docs/02-app/02-api-reference/02-file-conventions/layout.mdx @@ -100,17 +100,15 @@ When using client-side navigation, Next.js automatically only renders the part o For example, in the following directory structure, `dashboard/layout.tsx` is the common layout for both `/dashboard/settings` and `/dashboard/analytics`: -```txt highight={3} hideLineNumbers -app -└── dashboard - ├── layout.tsx - ├── settings - │ └── page.tsx - └── analytics - └── page.js -``` - -When navigating from `/dashboard/settings` to `/dashboard/analytics`, `page.tsx` in `/dashboard/analytics` will be rendered on the server because it is UI that changed, while `dashboard/layout.tsx` will **not** be re-rendered because it is a common UI between the two routes. +File structure showing a dashboard folder nesting a layout.tsx file, and settings and analytics folders with their own pages + +When navigating from `/dashboard/settings` to `/dashboard/analytics`, `page.tsx` in `/dashboard/analytics` will rerender on the server, while `dashboard/layout.tsx` will **not** rerender because it's a common UI shared between the two routes. This performance optimization allows navigation between pages that share a layout to be quicker as only the data fetching and rendering for the page has to run, instead of the entire route that could include shared layouts that fetch their own data. From c5acef61509f7f1388245b3b1cf80ececde5b059 Mon Sep 17 00:00:00 2001 From: Delba de Oliveira <32464864+delbaoliveira@users.noreply.github.com> Date: Tue, 28 Nov 2023 17:20:05 +0000 Subject: [PATCH 071/481] Docs: Update revalidate example (#59002) Closing: https://github.com/vercel/feedback/issues/47084 - The example previously showed `export const revalidate` being called from a `utils` file, whereas we want to call it from a route segment (layout or page) --- .../01-fetching-caching-and-revalidating.mdx | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/docs/02-app/01-building-your-application/02-data-fetching/01-fetching-caching-and-revalidating.mdx b/docs/02-app/01-building-your-application/02-data-fetching/01-fetching-caching-and-revalidating.mdx index 0afee64dfe2de..a275d8cf600cc 100644 --- a/docs/02-app/01-building-your-application/02-data-fetching/01-fetching-caching-and-revalidating.mdx +++ b/docs/02-app/01-building-your-application/02-data-fetching/01-fetching-caching-and-revalidating.mdx @@ -210,25 +210,21 @@ You can also use the experimental [`unstable_cache` API](/docs/app/api-reference In the example below: -- The `revalidate` option is set to `3600`, meaning the data will be cached and revalidated at most every hour. - The React `cache` function is used to [memoize](/docs/app/building-your-application/caching#request-memoization) data requests. +- The `revalidate` option is set to `3600` in the `layout.ts` and `page.ts` segments, meaning the data will be cached and revalidated at most every hour. -```ts filename="utils/get-item.ts" switcher +```ts filename="app/utils.ts" switcher import { cache } from 'react' -export const revalidate = 3600 // revalidate the data at most every hour - export const getItem = cache(async (id: string) => { const item = await db.item.findUnique({ id }) return item }) ``` -```js filename="utils/get-item.js" switcher +```js filename="app/utils.js" switcher import { cache } from 'react' -export const revalidate = 3600 // revalidate the data at most every hour - export const getItem = cache(async (id) => { const item = await db.item.findUnique({ id }) return item @@ -240,6 +236,8 @@ Although the `getItem` function is called twice, only one query will be made to ```tsx filename="app/item/[id]/layout.tsx" switcher import { getItem } from '@/utils/get-item' +export const revalidate = 3600 // revalidate the data at most every hour + export default async function Layout({ params: { id }, }: { @@ -253,6 +251,8 @@ export default async function Layout({ ```jsx filename="app/item/[id]/layout.js" switcher import { getItem } from '@/utils/get-item' +export const revalidate = 3600 // revalidate the data at most every hour + export default async function Layout({ params: { id } }) { const item = await getItem(id) // ... @@ -262,6 +262,8 @@ export default async function Layout({ params: { id } }) { ```tsx filename="app/item/[id]/page.tsx" switcher import { getItem } from '@/utils/get-item' +export const revalidate = 3600 // revalidate the data at most every hour + export default async function Page({ params: { id }, }: { @@ -275,6 +277,8 @@ export default async function Page({ ```jsx filename="app/item/[id]/page.js" switcher import { getItem } from '@/utils/get-item' +export const revalidate = 3600 // revalidate the data at most every hour + export default async function Page({ params: { id } }) { const item = await getItem(id) // ... From d0c5673d37c0393cbab8152ae951ffa8411d31f2 Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Tue, 28 Nov 2023 18:26:06 +0000 Subject: [PATCH 072/481] v14.0.4-canary.22 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 16 ++++++++-------- 18 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lerna.json b/lerna.json index ec99754294ba5..965d4a266d76a 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.21" + "version": "14.0.4-canary.22" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index af1c7817b6944..1b3ffe29dc234 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.21", + "version": "14.0.4-canary.22", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 48d4f12e749b7..9975c9945e36c 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.21", + "version": "14.0.4-canary.22", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.21", + "@next/eslint-plugin-next": "14.0.4-canary.22", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 314ff38296e3e..d141545d7021c 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.21", + "version": "14.0.4-canary.22", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index c6f8d33fb190d..9b1beace9e363 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.21", + "version": "14.0.4-canary.22", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 0a89b3b0241e8..66acf7e60c74b 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.21", + "version": "14.0.4-canary.22", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index a2d5517335be7..ce4fe6d633553 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.21", + "version": "14.0.4-canary.22", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 961dd2fa6da24..b73f564950e60 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.21", + "version": "14.0.4-canary.22", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 80fdb4a950a5f..90fa6226da23d 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.21", + "version": "14.0.4-canary.22", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 2c43fed816b41..75c4235d747d5 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.21", + "version": "14.0.4-canary.22", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index c2b30b0021b74..de4a813e0f32a 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.21", + "version": "14.0.4-canary.22", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index 3a93b85969a54..2ab1f2747c1d6 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.21", + "version": "14.0.4-canary.22", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index 745024cef8c35..2631d27649ee6 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.21", + "version": "14.0.4-canary.22", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index 5f47cec572be1..b41109e25bc9f 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.21", + "version": "14.0.4-canary.22", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.21", + "@next/env": "14.0.4-canary.22", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -147,11 +147,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.21", - "@next/polyfill-nomodule": "14.0.4-canary.21", - "@next/react-dev-overlay": "14.0.4-canary.21", - "@next/react-refresh-utils": "14.0.4-canary.21", - "@next/swc": "14.0.4-canary.21", + "@next/polyfill-module": "14.0.4-canary.22", + "@next/polyfill-nomodule": "14.0.4-canary.22", + "@next/react-dev-overlay": "14.0.4-canary.22", + "@next/react-refresh-utils": "14.0.4-canary.22", + "@next/swc": "14.0.4-canary.22", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index 99ccdedd263c9..2b3ed37b02e17 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.21", + "version": "14.0.4-canary.22", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index 0cd4cb428f1e0..c226bec7d456c 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.21", + "version": "14.0.4-canary.22", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index e55265f5dfbbd..3cc952b41c939 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.21", + "version": "14.0.4-canary.22", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -23,7 +23,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.21", + "next": "14.0.4-canary.22", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a8c1ce7f7742d..25ea12b9f69d6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -738,7 +738,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.21 + specifier: 14.0.4-canary.22 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -803,7 +803,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.21 + specifier: 14.0.4-canary.22 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -930,19 +930,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.21 + specifier: 14.0.4-canary.22 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.21 + specifier: 14.0.4-canary.22 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.21 + specifier: 14.0.4-canary.22 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.21 + specifier: 14.0.4-canary.22 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.21 + specifier: 14.0.4-canary.22 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1596,7 +1596,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.21 + specifier: 14.0.4-canary.22 version: link:../next outdent: specifier: 0.8.0 From 91471878e1e5049a3f090d4c3cc38ce162c9a88d Mon Sep 17 00:00:00 2001 From: Dima Voytenko Date: Tue, 28 Nov 2023 11:40:15 -0800 Subject: [PATCH 073/481] Testmode: provide test info for rewrite requests (#59033) The rewrite request appear to bypass the `BaseServer` or are executed in the sandbox. However, these requests have the correct test info in the headers that can be used instead of the `AsyncLocalStorage`. --- .../next/src/experimental/testmode/server.ts | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/next/src/experimental/testmode/server.ts b/packages/next/src/experimental/testmode/server.ts index 0bb53755693ab..cfad40108b32a 100644 --- a/packages/next/src/experimental/testmode/server.ts +++ b/packages/next/src/experimental/testmode/server.ts @@ -84,11 +84,26 @@ function buildResponse(proxyResponse: ProxyFetchResponse): Response { }) } +function extractTestInfoFromRequest(req: Request): TestReqInfo | undefined { + const proxyPortHeader = req.headers.get('next-test-proxy-port') + if (!proxyPortHeader) { + return undefined + } + const url = req.url + const proxyPort = Number(proxyPortHeader) + const testData = req.headers.get('next-test-data') ?? '' + return { + url, + proxyPort, + testData, + } +} + async function handleFetch( originalFetch: Fetch, request: Request ): Promise { - const testInfo = testStorage.getStore() + const testInfo = testStorage.getStore() ?? extractTestInfoFromRequest(request) if (!testInfo) { throw new Error('No test info') } From 05f2c68b7a31f94ca9e298f41af89ac0d0b5d67a Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Tue, 28 Nov 2023 12:15:35 -0800 Subject: [PATCH 074/481] Increase default timeout for swc build (#59035) x-ref: https://github.com/vercel/next.js/actions/runs/7022943529/attempts/3 --- .github/workflows/build_and_deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build_and_deploy.yml b/.github/workflows/build_and_deploy.yml index 583a5c0be50f5..134b082e194d3 100644 --- a/.github/workflows/build_and_deploy.yml +++ b/.github/workflows/build_and_deploy.yml @@ -228,7 +228,7 @@ jobs: name: stable - ${{ matrix.settings.target }} - node@16 runs-on: ${{ matrix.settings.host }} - timeout-minutes: 30 + timeout-minutes: 45 steps: # https://github.com/actions/virtual-environments/issues/1187 - name: tune linux network From 72af59a1c1e47d983142adc2d0b647643dfbbbd7 Mon Sep 17 00:00:00 2001 From: OJ Kwon <1210596+kwonoj@users.noreply.github.com> Date: Tue, 28 Nov 2023 12:42:26 -0800 Subject: [PATCH 075/481] build(cargo): bump up turbopack (#59032) ### What? Bump up turbopack which includes url rewrite related improvements. This makes `test/integration/url` test passes. Note there are some lacking behavior around edge runtime + url behavior, it is being tracked in PACK-2014. Closes PACK-2051 --- Cargo.lock | 68 +++++++++++++++--------------- Cargo.toml | 6 +-- packages/next/package.json | 2 +- pnpm-lock.yaml | 10 ++--- test/turbopack-tests-manifest.json | 5 +-- 5 files changed, 45 insertions(+), 46 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 456f2d6b7660a..6d85b6ef8043a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -322,7 +322,7 @@ dependencies = [ [[package]] name = "auto-hash-map" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231128.2#0f828c5744c17c19235fe3a6cb4006a3102183bb" dependencies = [ "serde", "smallvec", @@ -3549,7 +3549,7 @@ dependencies = [ [[package]] name = "node-file-trace" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231128.2#0f828c5744c17c19235fe3a6cb4006a3102183bb" dependencies = [ "anyhow", "serde", @@ -7678,7 +7678,7 @@ dependencies = [ [[package]] name = "turbo-tasks" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231128.2#0f828c5744c17c19235fe3a6cb4006a3102183bb" dependencies = [ "anyhow", "async-trait", @@ -7710,7 +7710,7 @@ dependencies = [ [[package]] name = "turbo-tasks-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231128.2#0f828c5744c17c19235fe3a6cb4006a3102183bb" dependencies = [ "anyhow", "cargo-lock", @@ -7722,7 +7722,7 @@ dependencies = [ [[package]] name = "turbo-tasks-bytes" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231128.2#0f828c5744c17c19235fe3a6cb4006a3102183bb" dependencies = [ "anyhow", "bytes", @@ -7737,7 +7737,7 @@ dependencies = [ [[package]] name = "turbo-tasks-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231128.2#0f828c5744c17c19235fe3a6cb4006a3102183bb" dependencies = [ "anyhow", "dotenvs", @@ -7751,7 +7751,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fetch" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231128.2#0f828c5744c17c19235fe3a6cb4006a3102183bb" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7768,7 +7768,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fs" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231128.2#0f828c5744c17c19235fe3a6cb4006a3102183bb" dependencies = [ "anyhow", "auto-hash-map", @@ -7798,7 +7798,7 @@ dependencies = [ [[package]] name = "turbo-tasks-hash" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231128.2#0f828c5744c17c19235fe3a6cb4006a3102183bb" dependencies = [ "base16", "hex", @@ -7810,7 +7810,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231128.2#0f828c5744c17c19235fe3a6cb4006a3102183bb" dependencies = [ "anyhow", "convert_case 0.6.0", @@ -7824,7 +7824,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros-shared" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231128.2#0f828c5744c17c19235fe3a6cb4006a3102183bb" dependencies = [ "proc-macro2", "quote", @@ -7834,7 +7834,7 @@ dependencies = [ [[package]] name = "turbo-tasks-malloc" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231128.2#0f828c5744c17c19235fe3a6cb4006a3102183bb" dependencies = [ "mimalloc", ] @@ -7842,7 +7842,7 @@ dependencies = [ [[package]] name = "turbo-tasks-memory" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231128.2#0f828c5744c17c19235fe3a6cb4006a3102183bb" dependencies = [ "anyhow", "auto-hash-map", @@ -7867,7 +7867,7 @@ dependencies = [ [[package]] name = "turbopack" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231128.2#0f828c5744c17c19235fe3a6cb4006a3102183bb" dependencies = [ "anyhow", "async-recursion", @@ -7898,7 +7898,7 @@ dependencies = [ [[package]] name = "turbopack-binding" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231128.2#0f828c5744c17c19235fe3a6cb4006a3102183bb" dependencies = [ "auto-hash-map", "mdxjs", @@ -7939,7 +7939,7 @@ dependencies = [ [[package]] name = "turbopack-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231128.2#0f828c5744c17c19235fe3a6cb4006a3102183bb" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7962,7 +7962,7 @@ dependencies = [ [[package]] name = "turbopack-cli-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231128.2#0f828c5744c17c19235fe3a6cb4006a3102183bb" dependencies = [ "anyhow", "clap 4.4.2", @@ -7980,7 +7980,7 @@ dependencies = [ [[package]] name = "turbopack-core" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231128.2#0f828c5744c17c19235fe3a6cb4006a3102183bb" dependencies = [ "anyhow", "async-recursion", @@ -8010,7 +8010,7 @@ dependencies = [ [[package]] name = "turbopack-css" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231128.2#0f828c5744c17c19235fe3a6cb4006a3102183bb" dependencies = [ "anyhow", "async-trait", @@ -8036,7 +8036,7 @@ dependencies = [ [[package]] name = "turbopack-dev" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231128.2#0f828c5744c17c19235fe3a6cb4006a3102183bb" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -8060,7 +8060,7 @@ dependencies = [ [[package]] name = "turbopack-dev-server" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231128.2#0f828c5744c17c19235fe3a6cb4006a3102183bb" dependencies = [ "anyhow", "async-compression", @@ -8097,7 +8097,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231128.2#0f828c5744c17c19235fe3a6cb4006a3102183bb" dependencies = [ "anyhow", "async-trait", @@ -8131,7 +8131,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-hmr-protocol" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231128.2#0f828c5744c17c19235fe3a6cb4006a3102183bb" dependencies = [ "serde", "serde_json", @@ -8142,7 +8142,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-plugins" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231128.2#0f828c5744c17c19235fe3a6cb4006a3102183bb" dependencies = [ "anyhow", "async-trait", @@ -8165,7 +8165,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-runtime" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231128.2#0f828c5744c17c19235fe3a6cb4006a3102183bb" dependencies = [ "anyhow", "indoc", @@ -8182,7 +8182,7 @@ dependencies = [ [[package]] name = "turbopack-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231128.2#0f828c5744c17c19235fe3a6cb4006a3102183bb" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -8198,7 +8198,7 @@ dependencies = [ [[package]] name = "turbopack-image" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231128.2#0f828c5744c17c19235fe3a6cb4006a3102183bb" dependencies = [ "anyhow", "base64 0.21.4", @@ -8218,7 +8218,7 @@ dependencies = [ [[package]] name = "turbopack-json" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231128.2#0f828c5744c17c19235fe3a6cb4006a3102183bb" dependencies = [ "anyhow", "serde", @@ -8233,7 +8233,7 @@ dependencies = [ [[package]] name = "turbopack-mdx" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231128.2#0f828c5744c17c19235fe3a6cb4006a3102183bb" dependencies = [ "anyhow", "mdxjs", @@ -8248,7 +8248,7 @@ dependencies = [ [[package]] name = "turbopack-node" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231128.2#0f828c5744c17c19235fe3a6cb4006a3102183bb" dependencies = [ "anyhow", "async-stream", @@ -8283,7 +8283,7 @@ dependencies = [ [[package]] name = "turbopack-static" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231128.2#0f828c5744c17c19235fe3a6cb4006a3102183bb" dependencies = [ "anyhow", "serde", @@ -8299,7 +8299,7 @@ dependencies = [ [[package]] name = "turbopack-swc-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231128.2#0f828c5744c17c19235fe3a6cb4006a3102183bb" dependencies = [ "swc_core", "turbo-tasks", @@ -8310,7 +8310,7 @@ dependencies = [ [[package]] name = "turbopack-trace-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231128.2#0f828c5744c17c19235fe3a6cb4006a3102183bb" dependencies = [ "anyhow", "crossbeam-channel", @@ -8325,7 +8325,7 @@ dependencies = [ [[package]] name = "turbopack-wasm" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231127.4#df8666fcd6177e926e7f17c63860e62cdc9ded34" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231128.2#0f828c5744c17c19235fe3a6cb4006a3102183bb" dependencies = [ "anyhow", "indexmap 1.9.3", diff --git a/Cargo.toml b/Cargo.toml index 4a27aa315019c..6590c2b0352ed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,11 +43,11 @@ swc_core = { version = "0.86.81", features = [ testing = { version = "0.35.11" } # Turbo crates -turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231127.4" } +turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231128.2" } # [TODO]: need to refactor embed_directory! macro usages, as well as resolving turbo_tasks::function, macros.. -turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231127.4" } +turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231128.2" } # [TODO]: need to refactor embed_directory! macro usage in next-core -turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231127.4" } +turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231128.2" } # General Deps diff --git a/packages/next/package.json b/packages/next/package.json index b41109e25bc9f..bdb80dd520841 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -195,7 +195,7 @@ "@types/ws": "8.2.0", "@vercel/ncc": "0.34.0", "@vercel/nft": "0.22.6", - "@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.4", + "@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231128.2", "acorn": "8.5.0", "amphtml-validator": "1.0.35", "anser": "1.4.9", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 25ea12b9f69d6..b109c54d0c55c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1074,8 +1074,8 @@ importers: specifier: 0.22.6 version: 0.22.6 '@vercel/turbopack-ecmascript-runtime': - specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.4 - version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.4(react-refresh@0.12.0)(webpack@5.86.0)' + specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231128.2 + version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231128.2(react-refresh@0.12.0)(webpack@5.86.0)' acorn: specifier: 8.5.0 version: 8.5.0 @@ -24648,9 +24648,9 @@ packages: /zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} - '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.4(react-refresh@0.12.0)(webpack@5.86.0)': - resolution: {registry: https://registry.npmjs.org/, tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.4} - id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231127.4' + '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231128.2(react-refresh@0.12.0)(webpack@5.86.0)': + resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231128.2} + id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231128.2' name: '@vercel/turbopack-ecmascript-runtime' version: 0.0.0 dependencies: diff --git a/test/turbopack-tests-manifest.json b/test/turbopack-tests-manifest.json index 352c2623a12e2..b2cdc1c95a857 100644 --- a/test/turbopack-tests-manifest.json +++ b/test/turbopack-tests-manifest.json @@ -14886,12 +14886,11 @@ "Handle new URL asset references in next dev should render the /ssr page", "Handle new URL asset references in next dev should render the /static page", "Handle new URL asset references in next dev should respond on basename api", - "Handle new URL asset references in next dev should respond on size api" - ], - "failed": [ + "Handle new URL asset references in next dev should respond on size api", "Handle new URL asset references in next dev should client-render the /ssg page", "Handle new URL asset references in next dev should client-render the /ssr page" ], + "failed": [], "pending": [ "Handle new URL asset references in next build should client-render the /ssg page", "Handle new URL asset references in next build should client-render the /ssr page", From 6ac1367687aebeeec1530bc6d6528ac296ffc2db Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Tue, 28 Nov 2023 22:24:13 +0000 Subject: [PATCH 076/481] v14.0.4-canary.23 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 18 +++++++++--------- 18 files changed, 34 insertions(+), 34 deletions(-) diff --git a/lerna.json b/lerna.json index 965d4a266d76a..8d6d402166f51 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.22" + "version": "14.0.4-canary.23" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 1b3ffe29dc234..0b6a1ec0f1364 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.22", + "version": "14.0.4-canary.23", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 9975c9945e36c..4f38ef5a79997 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.22", + "version": "14.0.4-canary.23", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.22", + "@next/eslint-plugin-next": "14.0.4-canary.23", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index d141545d7021c..16e17c13f82d3 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.22", + "version": "14.0.4-canary.23", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index 9b1beace9e363..2ca00e4ba41b7 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.22", + "version": "14.0.4-canary.23", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 66acf7e60c74b..0d8a3f99e679f 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.22", + "version": "14.0.4-canary.23", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index ce4fe6d633553..113703bb9a866 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.22", + "version": "14.0.4-canary.23", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index b73f564950e60..aba071f003a97 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.22", + "version": "14.0.4-canary.23", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 90fa6226da23d..d0bb708a02264 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.22", + "version": "14.0.4-canary.23", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 75c4235d747d5..37ea68836d1bc 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.22", + "version": "14.0.4-canary.23", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index de4a813e0f32a..02ed553fed981 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.22", + "version": "14.0.4-canary.23", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index 2ab1f2747c1d6..c9273e7497334 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.22", + "version": "14.0.4-canary.23", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index 2631d27649ee6..1bf0ee5613b4e 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.22", + "version": "14.0.4-canary.23", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index bdb80dd520841..fe0d003b6c23a 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.22", + "version": "14.0.4-canary.23", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.22", + "@next/env": "14.0.4-canary.23", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -147,11 +147,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.22", - "@next/polyfill-nomodule": "14.0.4-canary.22", - "@next/react-dev-overlay": "14.0.4-canary.22", - "@next/react-refresh-utils": "14.0.4-canary.22", - "@next/swc": "14.0.4-canary.22", + "@next/polyfill-module": "14.0.4-canary.23", + "@next/polyfill-nomodule": "14.0.4-canary.23", + "@next/react-dev-overlay": "14.0.4-canary.23", + "@next/react-refresh-utils": "14.0.4-canary.23", + "@next/swc": "14.0.4-canary.23", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index 2b3ed37b02e17..1e55f9fbb6d92 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.22", + "version": "14.0.4-canary.23", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index c226bec7d456c..5ec55766b1371 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.22", + "version": "14.0.4-canary.23", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index 3cc952b41c939..e768ce7d02832 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.22", + "version": "14.0.4-canary.23", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -23,7 +23,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.22", + "next": "14.0.4-canary.23", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b109c54d0c55c..eb26c8202eda1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -738,7 +738,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.22 + specifier: 14.0.4-canary.23 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -803,7 +803,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.22 + specifier: 14.0.4-canary.23 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -930,19 +930,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.22 + specifier: 14.0.4-canary.23 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.22 + specifier: 14.0.4-canary.23 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.22 + specifier: 14.0.4-canary.23 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.22 + specifier: 14.0.4-canary.23 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.22 + specifier: 14.0.4-canary.23 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1596,7 +1596,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.22 + specifier: 14.0.4-canary.23 version: link:../next outdent: specifier: 0.8.0 @@ -24649,7 +24649,7 @@ packages: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231128.2(react-refresh@0.12.0)(webpack@5.86.0)': - resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231128.2} + resolution: {registry: https://registry.npmjs.org/, tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231128.2} id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231128.2' name: '@vercel/turbopack-ecmascript-runtime' version: 0.0.0 From 298bbe54896a5c26fa23605d431c950914c9f7ed Mon Sep 17 00:00:00 2001 From: Zack Tanner Date: Tue, 28 Nov 2023 14:54:04 -0800 Subject: [PATCH 077/481] fix async action queue behavior (#59038) ### What? When the router action queue receives a bunch of async actions in quick succession, some of those requests are dropped, and as a result, anything observing pending transitions will be stuck in a pending state. ### Why? When adding items to the action queue, the intended behavior is for new actions to be added to the end of the action queue, to be picked up by `runRemainingActions` once the in-flight action is processed. However, new actions are erroneously overwriting pending actions in the queue rather than appending them, as `actionQueue.last` might have a pending action attached to it. ### How? This moves the assignment of `actionQueue.last` to always be in `dispatchAction`, rather than the function that processes the action, so that we always have a single spot where `last` is assigned and to prevent it from erroneously omitted/overwritten. Fixes #59011 --- .../src/shared/lib/router/action-queue.ts | 9 ++++- test/e2e/app-dir/actions/app-action.test.ts | 39 +++++++++++++++++++ .../actions/app/use-transition/action.js | 9 +++++ .../actions/app/use-transition/page.js | 24 ++++++++++++ 4 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 test/e2e/app-dir/actions/app/use-transition/action.js create mode 100644 test/e2e/app-dir/actions/app/use-transition/page.js diff --git a/packages/next/src/shared/lib/router/action-queue.ts b/packages/next/src/shared/lib/router/action-queue.ts index ad212a233e696..4310faba9caf3 100644 --- a/packages/next/src/shared/lib/router/action-queue.ts +++ b/packages/next/src/shared/lib/router/action-queue.ts @@ -67,7 +67,6 @@ async function runAction({ } actionQueue.pending = action - actionQueue.last = action const payload = action.payload const actionResult = actionQueue.action(prevState, payload) @@ -142,6 +141,9 @@ function dispatchAction( // Check if the queue is empty if (actionQueue.pending === null) { // The queue is empty, so add the action and start it immediately + // Mark this action as the last in the queue + actionQueue.last = newAction + runAction({ actionQueue, action: newAction, @@ -152,6 +154,9 @@ function dispatchAction( // Mark the pending action as discarded (so the state is never applied) and start the navigation action immediately. actionQueue.pending.discarded = true + // Mark this action as the last in the queue + actionQueue.last = newAction + // if the pending action was a server action, mark the queue as needing a refresh once events are processed if (actionQueue.pending.payload.type === ACTION_SERVER_ACTION) { actionQueue.needsRefresh = true @@ -164,7 +169,7 @@ function dispatchAction( }) } else { // The queue is not empty, so add the action to the end of the queue - // It will be started by finishRunningAction after the previous action finishes + // It will be started by runRemainingActions after the previous action finishes if (actionQueue.last !== null) { actionQueue.last.next = newAction } diff --git a/test/e2e/app-dir/actions/app-action.test.ts b/test/e2e/app-dir/actions/app-action.test.ts index 90423006d4997..7fa91cbb1884c 100644 --- a/test/e2e/app-dir/actions/app-action.test.ts +++ b/test/e2e/app-dir/actions/app-action.test.ts @@ -370,6 +370,45 @@ createNextDescribe( expect(requestCount).toBe(1) }) + it('should handle actions executed in quick succession', async () => { + let requestCount = 0 + const browser = await next.browser('/use-transition', { + beforePageLoad(page) { + page.on('request', (request) => { + const url = new URL(request.url()) + if (url.pathname === '/use-transition') { + requestCount++ + } + }) + }, + }) + + expect(await browser.elementByCss('h1').text()).toBe( + 'Transition is: idle' + ) + const button = await browser.elementById('action-button') + + // fire off 6 successive requests by clicking the button 6 times + for (let i = 0; i < 6; i++) { + await button.click() + + // add a little bit of delay to simulate user behavior & give + // the requests a moment to start running + await waitFor(500) + } + + expect(await browser.elementByCss('h1').text()).toBe( + 'Transition is: pending' + ) + + await check(() => requestCount, 6) + + await check( + () => browser.elementByCss('h1').text(), + 'Transition is: idle' + ) + }) + if (isNextStart) { it('should not expose action content in sourcemaps', async () => { const sourcemap = ( diff --git a/test/e2e/app-dir/actions/app/use-transition/action.js b/test/e2e/app-dir/actions/app/use-transition/action.js new file mode 100644 index 0000000000000..fdc8fc8c93abb --- /dev/null +++ b/test/e2e/app-dir/actions/app/use-transition/action.js @@ -0,0 +1,9 @@ +'use server' + +export async function addToCart() { + return new Promise((resolve, reject) => { + setTimeout(() => { + resolve('Add to cart') + }, 1000) + }) +} diff --git a/test/e2e/app-dir/actions/app/use-transition/page.js b/test/e2e/app-dir/actions/app/use-transition/page.js new file mode 100644 index 0000000000000..a7df1d63b9252 --- /dev/null +++ b/test/e2e/app-dir/actions/app/use-transition/page.js @@ -0,0 +1,24 @@ +'use client' + +import { useTransition } from 'react' +import { addToCart } from './action' + +export default function Page() { + const [isPending, startTransition] = useTransition() + + return ( +
+

Transition is: {isPending ? 'pending' : 'idle'}

+ +
+ ) +} From 266fc8e3187c47238afe1d6ddbea213b6b4345ac Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Tue, 28 Nov 2023 23:04:45 +0000 Subject: [PATCH 078/481] v14.0.4-canary.24 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 16 ++++++++-------- 18 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lerna.json b/lerna.json index 8d6d402166f51..ac22f4678fdc8 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.23" + "version": "14.0.4-canary.24" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 0b6a1ec0f1364..7560651fafb52 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.23", + "version": "14.0.4-canary.24", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 4f38ef5a79997..8ad742e9a1572 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.23", + "version": "14.0.4-canary.24", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.23", + "@next/eslint-plugin-next": "14.0.4-canary.24", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 16e17c13f82d3..9d23a48262a6e 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.23", + "version": "14.0.4-canary.24", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index 2ca00e4ba41b7..920a417dd0cd1 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.23", + "version": "14.0.4-canary.24", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 0d8a3f99e679f..68c1fb28934f7 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.23", + "version": "14.0.4-canary.24", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 113703bb9a866..05186945d7332 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.23", + "version": "14.0.4-canary.24", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index aba071f003a97..22b3fd6f8f8f4 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.23", + "version": "14.0.4-canary.24", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index d0bb708a02264..fac4f31eb0fa9 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.23", + "version": "14.0.4-canary.24", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 37ea68836d1bc..472b3a9f7192a 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.23", + "version": "14.0.4-canary.24", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index 02ed553fed981..f2f97bdbf45d3 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.23", + "version": "14.0.4-canary.24", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index c9273e7497334..5797cbebeb5e6 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.23", + "version": "14.0.4-canary.24", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index 1bf0ee5613b4e..e1d2b1e3d5e13 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.23", + "version": "14.0.4-canary.24", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index fe0d003b6c23a..52bcb8e3a332a 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.23", + "version": "14.0.4-canary.24", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.23", + "@next/env": "14.0.4-canary.24", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -147,11 +147,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.23", - "@next/polyfill-nomodule": "14.0.4-canary.23", - "@next/react-dev-overlay": "14.0.4-canary.23", - "@next/react-refresh-utils": "14.0.4-canary.23", - "@next/swc": "14.0.4-canary.23", + "@next/polyfill-module": "14.0.4-canary.24", + "@next/polyfill-nomodule": "14.0.4-canary.24", + "@next/react-dev-overlay": "14.0.4-canary.24", + "@next/react-refresh-utils": "14.0.4-canary.24", + "@next/swc": "14.0.4-canary.24", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index 1e55f9fbb6d92..2d95f7a89f6f5 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.23", + "version": "14.0.4-canary.24", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index 5ec55766b1371..0ae91b6f7ec3a 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.23", + "version": "14.0.4-canary.24", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index e768ce7d02832..37686abc819cb 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.23", + "version": "14.0.4-canary.24", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -23,7 +23,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.23", + "next": "14.0.4-canary.24", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index eb26c8202eda1..b57385b86dd65 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -738,7 +738,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.23 + specifier: 14.0.4-canary.24 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -803,7 +803,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.23 + specifier: 14.0.4-canary.24 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -930,19 +930,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.23 + specifier: 14.0.4-canary.24 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.23 + specifier: 14.0.4-canary.24 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.23 + specifier: 14.0.4-canary.24 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.23 + specifier: 14.0.4-canary.24 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.23 + specifier: 14.0.4-canary.24 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1596,7 +1596,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.23 + specifier: 14.0.4-canary.24 version: link:../next outdent: specifier: 0.8.0 From e1a2b12beeeca2f7b4c5b7214ec44dece7039485 Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Tue, 28 Nov 2023 23:22:30 +0000 Subject: [PATCH 079/481] v14.0.4-canary.25 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 16 ++++++++-------- 18 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lerna.json b/lerna.json index ac22f4678fdc8..e8cda90f644db 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.24" + "version": "14.0.4-canary.25" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 7560651fafb52..f445caa5d3298 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.24", + "version": "14.0.4-canary.25", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 8ad742e9a1572..e4c352d47dd48 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.24", + "version": "14.0.4-canary.25", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.24", + "@next/eslint-plugin-next": "14.0.4-canary.25", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 9d23a48262a6e..349f543fdeff3 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.24", + "version": "14.0.4-canary.25", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index 920a417dd0cd1..0fd534874a73b 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.24", + "version": "14.0.4-canary.25", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 68c1fb28934f7..06bf49a923a53 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.24", + "version": "14.0.4-canary.25", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 05186945d7332..2823e3f3d3b62 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.24", + "version": "14.0.4-canary.25", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 22b3fd6f8f8f4..70a96c4f789b9 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.24", + "version": "14.0.4-canary.25", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index fac4f31eb0fa9..5af0e73617afb 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.24", + "version": "14.0.4-canary.25", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 472b3a9f7192a..442f4ac923e4e 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.24", + "version": "14.0.4-canary.25", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index f2f97bdbf45d3..6b5a678b384a3 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.24", + "version": "14.0.4-canary.25", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index 5797cbebeb5e6..370ba33ce6b88 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.24", + "version": "14.0.4-canary.25", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index e1d2b1e3d5e13..97b943b199e23 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.24", + "version": "14.0.4-canary.25", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index 52bcb8e3a332a..a5b438b7f82aa 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.24", + "version": "14.0.4-canary.25", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.24", + "@next/env": "14.0.4-canary.25", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -147,11 +147,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.24", - "@next/polyfill-nomodule": "14.0.4-canary.24", - "@next/react-dev-overlay": "14.0.4-canary.24", - "@next/react-refresh-utils": "14.0.4-canary.24", - "@next/swc": "14.0.4-canary.24", + "@next/polyfill-module": "14.0.4-canary.25", + "@next/polyfill-nomodule": "14.0.4-canary.25", + "@next/react-dev-overlay": "14.0.4-canary.25", + "@next/react-refresh-utils": "14.0.4-canary.25", + "@next/swc": "14.0.4-canary.25", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index 2d95f7a89f6f5..434ebddf216b2 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.24", + "version": "14.0.4-canary.25", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index 0ae91b6f7ec3a..091400d33ab01 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.24", + "version": "14.0.4-canary.25", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index 37686abc819cb..3fccaf91b5f16 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.24", + "version": "14.0.4-canary.25", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -23,7 +23,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.24", + "next": "14.0.4-canary.25", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b57385b86dd65..9fc5f7abb5430 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -738,7 +738,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.24 + specifier: 14.0.4-canary.25 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -803,7 +803,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.24 + specifier: 14.0.4-canary.25 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -930,19 +930,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.24 + specifier: 14.0.4-canary.25 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.24 + specifier: 14.0.4-canary.25 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.24 + specifier: 14.0.4-canary.25 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.24 + specifier: 14.0.4-canary.25 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.24 + specifier: 14.0.4-canary.25 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1596,7 +1596,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.24 + specifier: 14.0.4-canary.25 version: link:../next outdent: specifier: 0.8.0 From ef3c6490fe6eabcbf9a1bd51244f4d14473e1c64 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Wed, 29 Nov 2023 03:35:06 +0100 Subject: [PATCH 080/481] start performance profiling after node.js version is checked (#59028) Providing better feedback loop for next bindary. Some users with old node.js version are seeing `performance` is not defined in #57385, we should check the version first. For compilation, `performace.mark` will also be compiled after those imports since they're hoisted as ESM. This PR moves performance profiling after the `--help` and `--version` processures and node.js version check. So users can see the "upgrade node.js" hint if the node.js version is too old instead of "performance is not defined" --- packages/next/src/bin/next.ts | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/packages/next/src/bin/next.ts b/packages/next/src/bin/next.ts index dc36f33e1f921..061227d66f78e 100755 --- a/packages/next/src/bin/next.ts +++ b/packages/next/src/bin/next.ts @@ -1,5 +1,5 @@ #!/usr/bin/env node -performance.mark('next-start') + import '../server/require-hook' import * as log from '../build/output/log' import arg from 'next/dist/compiled/arg/index.js' @@ -9,7 +9,6 @@ import { commands } from '../lib/commands' import { commandArgs } from '../lib/command-args' import { getValidatedArgs } from '../lib/get-validated-args' -const defaultCommand = 'dev' const args = arg( { // Types @@ -56,6 +55,20 @@ if (!foundCommand && args['--help']) { process.exit(0) } +// Check supported Node.js version first +if ( + semver.lt(process.versions.node, process.env.__NEXT_REQUIRED_NODE_VERSION!) +) { + console.error( + `You are using Node.js ${process.versions.node}. For Next.js, Node.js version >= v${process.env.__NEXT_REQUIRED_NODE_VERSION} is required.` + ) + process.exit(1) +} + +// Start performance profiling after Node.js version is checked +performance.mark('next-start') + +const defaultCommand = 'dev' const command = foundCommand ? args._[0] : defaultCommand if (['experimental-compile', 'experimental-generate'].includes(command)) { @@ -116,15 +129,6 @@ async function main() { } } - if ( - semver.lt(process.versions.node, process.env.__NEXT_REQUIRED_NODE_VERSION!) - ) { - console.error( - `You are using Node.js ${process.versions.node}. For Next.js, Node.js version >= v${process.env.__NEXT_REQUIRED_NODE_VERSION} is required.` - ) - process.exit(1) - } - await commands[command]() .then((exec) => exec(validatedArgs)) .then(() => { From ca19ffb63b6a17e55828f601eb3677033e523e41 Mon Sep 17 00:00:00 2001 From: Tore Lervik Date: Wed, 29 Nov 2023 03:54:31 +0100 Subject: [PATCH 081/481] Fixed stale fetch using when page regenerates (#58926) fixes: #58909 x-ref: #58321, #56472, #56231 Removed the Math.round of age since it can cause stale fetch data to be considered not stale if the age rounds downwards. (5.49 is rounded to 5) Note: This most likely also fixes some bugs with revalidateTag/revalidatePath. Tested some tag/path issues that got fixed with this change. I think this is because revalidatetag/path sets [data.revalidatedAt = Date.now()](https://github.com/vercel/next.js/blob/canary/packages/next/src/server/lib/incremental-cache/file-system-cache.ts#L120) for file-system-cache. And with the current code that value would continue to be "not stale" for up to 0.499 ms. Co-authored-by: JJ Kasper Co-authored-by: Zack Tanner --- packages/next/src/server/lib/incremental-cache/index.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/next/src/server/lib/incremental-cache/index.ts b/packages/next/src/server/lib/incremental-cache/index.ts index 271cff2ae4fa6..39c2278eca0a0 100644 --- a/packages/next/src/server/lib/incremental-cache/index.ts +++ b/packages/next/src/server/lib/incremental-cache/index.ts @@ -460,9 +460,7 @@ export class IncrementalCache implements IncrementalCacheType { } revalidate = revalidate || cacheData.value.revalidate - const age = Math.round( - (Date.now() - (cacheData.lastModified || 0)) / 1000 - ) + const age = (Date.now() - (cacheData.lastModified || 0)) / 1000 const isStale = age > revalidate const data = cacheData.value.data From 809164d7768369f4cfda0111fbdfe66bef97213e Mon Sep 17 00:00:00 2001 From: Zack Tanner Date: Tue, 28 Nov 2023 19:22:45 -0800 Subject: [PATCH 082/481] Enable PPR tests for test suites (#59030) Cherry-picks #58708 without the dependency on https://github.com/vercel/next.js/pull/58779 Co-authored-by: Wyatt Johnson <633002+wyattjoh@users.noreply.github.com> --- .github/workflows/build_and_test.yml | 52 +++++++++- package.json | 3 +- packages/next/src/server/config-shared.ts | 10 +- packages/next/src/server/config.ts | 9 ++ pnpm-lock.yaml | 3 + run-tests.js | 103 +++++++++---------- test/e2e/app-dir/rsc-basic/rsc-basic.test.ts | 18 ++-- test/get-test-filter.js | 85 +++++++++++++++ test/ppr-tests-manifest.json | 67 ++++++++++++ 9 files changed, 286 insertions(+), 64 deletions(-) create mode 100644 test/get-test-filter.js create mode 100644 test/ppr-tests-manifest.json diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index b1534867b9f19..fb0dd41371923 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -183,12 +183,10 @@ jobs: fail-fast: false matrix: group: [1, 2, 3] - uses: ./.github/workflows/build_reusable.yml with: skipForDocsOnly: 'yes' afterBuild: NEXT_TEST_MODE=dev node run-tests.js --timings -g ${{ matrix.group }}/3 -c ${TEST_CONCURRENCY} --type development - secrets: inherit test-prod: @@ -198,7 +196,6 @@ jobs: fail-fast: false matrix: group: [1, 2, 3, 4, 5] - uses: ./.github/workflows/build_reusable.yml with: skipForDocsOnly: 'yes' @@ -212,7 +209,6 @@ jobs: fail-fast: false matrix: group: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] - uses: ./.github/workflows/build_reusable.yml with: nodeVersion: 18.17.0 @@ -230,6 +226,48 @@ jobs: afterBuild: pnpm playwright install && BROWSER_NAME=firefox node run-tests.js test/production/pages-dir/production/test/index.test.ts && BROWSER_NAME=safari NEXT_TEST_MODE=start node run-tests.js -c 1 test/production/pages-dir/production/test/index.test.ts test/e2e/basepath.test.ts && BROWSER_NAME=safari DEVICE_NAME='iPhone XR' node run-tests.js -c 1 test/production/prerender-prefetch/index.test.ts secrets: inherit + # TODO: remove these jobs once PPR is the default + # Manifest generated via: https://gist.github.com/wyattjoh/2ceaebd82a5bcff4819600fd60126431 + test-ppr-integration: + name: test ppr integration + needs: ['build-native', 'build-next'] + strategy: + fail-fast: false + matrix: + group: [1, 2, 3] + uses: ./.github/workflows/build_reusable.yml + with: + nodeVersion: 18.17.0 + skipForDocsOnly: 'yes' + afterBuild: __NEXT_EXPERIMENTAL_PPR=true NEXT_EXTERNAL_TESTS_FILTERS="test/ppr-tests-manifest.json" node run-tests.js --timings -g ${{ matrix.group }}/3 -c ${TEST_CONCURRENCY} --type integration + secrets: inherit + + test-ppr-dev: + name: test ppr dev + needs: ['build-native', 'build-next'] + strategy: + fail-fast: false + matrix: + group: [1, 2, 3] + uses: ./.github/workflows/build_reusable.yml + with: + skipForDocsOnly: 'yes' + afterBuild: __NEXT_EXPERIMENTAL_PPR=true NEXT_EXTERNAL_TESTS_FILTERS="test/ppr-tests-manifest.json" NEXT_TEST_MODE=dev node run-tests.js --timings -g ${{ matrix.group }}/3 -c ${TEST_CONCURRENCY} --type development + secrets: inherit + + test-ppr-prod: + name: test ppr prod + needs: ['build-native', 'build-next'] + strategy: + fail-fast: false + matrix: + group: [1, 2, 3] + uses: ./.github/workflows/build_reusable.yml + with: + skipForDocsOnly: 'yes' + afterBuild: __NEXT_EXPERIMENTAL_PPR=true NEXT_EXTERNAL_TESTS_FILTERS="test/ppr-tests-manifest.json" NEXT_TEST_MODE=start node run-tests.js --timings -g ${{ matrix.group }}/3 -c ${TEST_CONCURRENCY} --type production + secrets: inherit + report-test-results: needs: [ @@ -237,6 +275,9 @@ jobs: 'test-dev', 'test-prod', 'test-integration', + 'test-ppr-dev', + 'test-ppr-prod', + 'test-ppr-integration', 'test-turbopack-dev', 'test-turbopack-integration', ] @@ -275,6 +316,9 @@ jobs: 'test-dev', 'test-prod', 'test-integration', + 'test-ppr-dev', + 'test-ppr-prod', + 'test-ppr-integration', 'test-cargo-unit', 'test-cargo-integration', 'test-cargo-bench', diff --git a/package.json b/package.json index 8df96c207df80..d7f2939cbfa14 100644 --- a/package.json +++ b/package.json @@ -235,7 +235,8 @@ "webpack": "5.86.0", "webpack-bundle-analyzer": "4.7.0", "whatwg-fetch": "3.0.0", - "ws": "8.2.3" + "ws": "8.2.3", + "yargs": "16.2.0" }, "resolutions": { "webpack": "5.86.0", diff --git a/packages/next/src/server/config-shared.ts b/packages/next/src/server/config-shared.ts index 34f4f749ff2ca..d2dda84b82f4b 100644 --- a/packages/next/src/server/config-shared.ts +++ b/packages/next/src/server/config-shared.ts @@ -797,7 +797,15 @@ export const defaultConfig: NextConfig = { typedRoutes: false, instrumentationHook: false, bundlePagesExternals: false, - ppr: false, + ppr: + // TODO: remove once we've made PPR default + // If we're testing, and the `__NEXT_EXPERIMENTAL_PPR` environment variable + // has been set to `true`, enable the experimental PPR feature so long as it + // wasn't explicitly disabled in the config. + process.env.__NEXT_TEST_MODE && + process.env.__NEXT_EXPERIMENTAL_PPR === 'true' + ? true + : false, }, } diff --git a/packages/next/src/server/config.ts b/packages/next/src/server/config.ts index b0cba57e061da..3968b19e60a7a 100644 --- a/packages/next/src/server/config.ts +++ b/packages/next/src/server/config.ts @@ -251,6 +251,15 @@ function assignDefaults( {} ) + // TODO: remove once we've made PPR default + // If this was defaulted to true, it implies that the configuration was + // overridden for testing to be defaulted on. + if (defaultConfig.experimental?.ppr) { + Log.warn( + `\`experimental.ppr\` has been defaulted to \`true\` because \`__NEXT_EXPERIMENTAL_PPR\` was set to \`true\` during testing.` + ) + } + const result = { ...defaultConfig, ...config } if ( diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9fc5f7abb5430..096a7bf6957e2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -554,6 +554,9 @@ importers: ws: specifier: 8.2.3 version: 8.2.3 + yargs: + specifier: 16.2.0 + version: 16.2.0 bench/app-router-server: dependencies: diff --git a/run-tests.js b/run-tests.js index 95a835de6ef9a..38fa2cdfd4b6b 100644 --- a/run-tests.js +++ b/run-tests.js @@ -13,6 +13,18 @@ const { createNextInstall } = require('./test/lib/create-next-install') const glob = promisify(_glob) const exec = promisify(execOrig) const core = require('@actions/core') +const { getTestFilter } = require('./test/get-test-filter') + +let argv = require('yargs/yargs')(process.argv.slice(2)) + .string('type') + .string('test-pattern') + .boolean('timings') + .boolean('write-timings') + .boolean('debug') + .string('g') + .alias('g', 'group') + .number('c') + .alias('c', 'concurrency').argv function escapeRegexp(str) { return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&') @@ -25,11 +37,8 @@ function escapeRegexp(str) { const GROUP = process.env.CI ? '##[group]' : '' const ENDGROUP = process.env.CI ? '##[endgroup]' : '' -// Try to read an external array-based json to filter tests to be allowed / or disallowed. -// If process.argv contains a test to be executed, this'll append it to the list. -const externalTestsFilterLists = process.env.NEXT_EXTERNAL_TESTS_FILTERS - ? require(process.env.NEXT_EXTERNAL_TESTS_FILTERS) - : null +const externalTestsFilter = getTestFilter() + const timings = [] const DEFAULT_NUM_RETRIES = os.platform() === 'win32' ? 2 : 1 const DEFAULT_CONCURRENCY = 2 @@ -173,23 +182,25 @@ async function getTestTimings() { async function main() { let numRetries = DEFAULT_NUM_RETRIES - let concurrencyIdx = process.argv.indexOf('-c') - let concurrency = - (concurrencyIdx > -1 && parseInt(process.argv[concurrencyIdx + 1], 10)) || - DEFAULT_CONCURRENCY - - const hideOutput = !process.argv.includes('--debug') - const outputTimings = process.argv.includes('--timings') - const writeTimings = process.argv.includes('--write-timings') - const groupIdx = process.argv.indexOf('-g') - const groupArg = groupIdx !== -1 && process.argv[groupIdx + 1] - const testPatternIdx = process.argv.indexOf('--test-pattern') - const testPattern = testPatternIdx !== -1 && process.argv[testPatternIdx + 1] - const testTypeIdx = process.argv.indexOf('--type') - const testType = testTypeIdx > -1 ? process.argv[testTypeIdx + 1] : undefined + + // Ensure we have the arguments awaited from yargs. + argv = await argv + + const options = { + concurrency: argv.concurrency || DEFAULT_CONCURRENCY, + debug: argv.debug ?? false, + timings: argv.timings ?? false, + writeTimings: argv.writeTimings ?? false, + group: argv.group ?? false, + testPattern: argv.testPattern ?? false, + type: argv.type ?? false, + } + + const hideOutput = !options.debug + let filterTestsBy - switch (testType) { + switch (options.type) { case 'unit': { numRetries = 0 filterTestsBy = testFilters.unit @@ -200,27 +211,27 @@ async function main() { break } default: { - filterTestsBy = testFilters[testType] + filterTestsBy = testFilters[options.type] break } } - console.log('Running tests with concurrency:', concurrency) + console.log('Running tests with concurrency:', options.concurrency) /** @type TestFile[] */ - let tests = process.argv - .filter((arg) => arg.match(/\.test\.(js|ts|tsx)/)) - .map((file) => ({ + let tests = argv._.filter((arg) => arg.match(/\.test\.(js|ts|tsx)/)).map( + (file) => ({ file, excludedCases: [], - })) + }) + ) let prevTimings if (tests.length === 0) { let testPatternRegex - if (testPattern) { - testPatternRegex = new RegExp(testPattern) + if (options.testPattern) { + testPatternRegex = new RegExp(options.testPattern) } tests = ( @@ -252,7 +263,7 @@ async function main() { })) } - if (outputTimings && groupArg) { + if (options.timings && options.group) { console.log('Fetching previous timings data') try { const timingsFile = path.join(process.cwd(), 'test-timings.json') @@ -267,7 +278,7 @@ async function main() { prevTimings = await getTestTimings() console.log('Fetched previous timings data successfully') - if (writeTimings) { + if (options.writeTimings) { await fsp.writeFile(timingsFile, JSON.stringify(prevTimings)) console.log('Wrote previous timings data to', timingsFile) await cleanUpAndExit(0) @@ -280,20 +291,8 @@ async function main() { } // If there are external manifest contains list of tests, apply it to the test lists. - if (externalTestsFilterLists) { - tests = tests - .filter((test) => { - const info = externalTestsFilterLists[test.file] - return info && info.passed.length > 0 && !info.runtimeError - }) - .map((test) => { - const info = externalTestsFilterLists[test.file] - // Exclude failing and flakey tests, newly added tests are automatically included - if (info.failed.length > 0 || info.flakey.length > 0) { - test.excludedCases = info.failed.concat(info.flakey) - } - return test - }) + if (externalTestsFilter) { + tests = externalTestsFilter(tests) } let testSet = new Set() @@ -308,8 +307,8 @@ async function main() { return true }) - if (groupArg) { - const groupParts = groupArg.split('/') + if (options.group) { + const groupParts = options.group.split('/') const groupPos = parseInt(groupParts[0], 10) const groupTotal = parseInt(groupParts[1], 10) @@ -354,7 +353,7 @@ async function main() { } if (tests.length === 0) { - console.log('No tests found for', testType, 'exiting..') + console.log('No tests found for', options.type, 'exiting..') return cleanUpAndExit(1) } @@ -373,7 +372,7 @@ ${ENDGROUP}`) if ( process.platform !== 'win32' && process.env.NEXT_TEST_MODE !== 'deploy' && - ((testType && testType !== 'unit') || hasIsolatedTests) + ((options.type && options.type !== 'unit') || hasIsolatedTests) ) { // for isolated next tests: e2e, dev, prod we create // a starter Next.js install to re-use to speed up tests @@ -400,7 +399,7 @@ ${ENDGROUP}`) console.log(`${ENDGROUP}`) } - const sema = new Sema(concurrency, { capacity: tests.length }) + const sema = new Sema(options.concurrency, { capacity: tests.length }) const outputSema = new Sema(1, { capacity: tests.length }) const children = new Set() const jestPath = path.join( @@ -462,8 +461,8 @@ ${ENDGROUP}`) // [NOTE]: This won't affect if junit reporter is not enabled JEST_SUITE_NAME: [ `${process.env.NEXT_TEST_MODE ?? 'default'}`, - groupArg, - testType, + options.group, + options.type, test.file, ] .filter(Boolean) @@ -681,7 +680,7 @@ ${ENDGROUP}`) }) ) - if (outputTimings) { + if (options.timings) { const curTimings = {} // let junitData = `` /* diff --git a/test/e2e/app-dir/rsc-basic/rsc-basic.test.ts b/test/e2e/app-dir/rsc-basic/rsc-basic.test.ts index b8d7c7f336adf..3d8b005d2115e 100644 --- a/test/e2e/app-dir/rsc-basic/rsc-basic.test.ts +++ b/test/e2e/app-dir/rsc-basic/rsc-basic.test.ts @@ -454,6 +454,12 @@ createNextDescribe( expect(await res.text()).toBe('Hello from import-test.js') }) + // TODO: (PPR) remove once PPR is stable + const bundledReactVersionPattern = + process.env.__NEXT_EXPERIMENTAL_PPR === 'true' + ? '-experimental-' + : '-canary-' + it('should not use bundled react for pages with app', async () => { const ssrPaths = ['/pages-react', '/edge-pages-react'] const promises = ssrPaths.map(async (pathname) => { @@ -465,7 +471,7 @@ createNextDescribe( ] ssrPagesReactVersions.forEach((version) => { - expect(version).not.toMatch('-canary-') + expect(version).not.toMatch(bundledReactVersionPattern) }) }) await Promise.all(promises) @@ -478,7 +484,7 @@ createNextDescribe( ] ssrAppReactVersions.forEach((version) => - expect(version).toMatch('-canary-') + expect(version).toMatch(bundledReactVersionPattern) ) const browser = await next.browser('/pages-react') @@ -500,10 +506,10 @@ createNextDescribe( `) browserPagesReactVersions.forEach((version) => - expect(version).not.toMatch('-canary-') + expect(version).not.toMatch(bundledReactVersionPattern) ) browserEdgePagesReactVersions.forEach((version) => - expect(version).not.toMatch('-canary-') + expect(version).not.toMatch(bundledReactVersionPattern) ) }) @@ -519,7 +525,7 @@ createNextDescribe( ] ssrPagesReactVersions.forEach((version) => { - expect(version).toMatch('-canary-') + expect(version).toMatch(bundledReactVersionPattern) }) const browser = await next.browser('/app-react') @@ -534,7 +540,7 @@ createNextDescribe( ] `) browserAppReactVersions.forEach((version) => - expect(version).toMatch('-canary-') + expect(version).toMatch(bundledReactVersionPattern) ) }) diff --git a/test/get-test-filter.js b/test/get-test-filter.js new file mode 100644 index 0000000000000..4eacd8f083ac6 --- /dev/null +++ b/test/get-test-filter.js @@ -0,0 +1,85 @@ +const path = require('path') +const minimatch = require('minimatch') + +function getTestFilter() { + const manifest = process.env.NEXT_EXTERNAL_TESTS_FILTERS + ? require(path.resolve(process.env.NEXT_EXTERNAL_TESTS_FILTERS)) + : null + if (!manifest) return null + + // For the legacy manifest without a version, we assume it's a complete list + // of all the tests. + if (!manifest.version || typeof manifest.version !== 'number') { + return (tests) => + tests + .filter((test) => { + const info = manifest[test.file] + return info && info.passed.length > 0 && !info.runtimeError + }) + .map((test) => { + const info = manifest[test.file] + // Exclude failing and flakey tests, newly added tests are automatically included + if (info.failed.length > 0 || info.flakey.length > 0) { + test.excludedCases = info.failed.concat(info.flakey) + } + return test + }) + } + + // The new manifest version 2 only contains the list of tests that should + // be run, with exclusions added based on rules. Any new tests that are added + // will be automatically included if they match the include rules. + if (manifest.version === 2) { + return (tests) => + tests + .filter((test) => { + // Check to see if this was included as-is in the manifest. + if (test.file in manifest.suites) return true + + // If this file doesn't match any of the include patterns, then it + // should be excluded. + if ( + manifest.rules.include.every( + (pattern) => !minimatch(test.file, pattern) + ) + ) { + return false + } + + // If the file matches any of the exclude patterns, then it should be + // excluded. + if ( + manifest.rules.exclude?.some((pattern) => + minimatch(test.file, pattern) + ) + ) { + return false + } + + // Otherwise, it should be included. + return true + }) + .map((test) => { + const info = manifest.suites[test.file] + + // If there's no info for this test, then it's a test that has no + // failures or flakey tests, so we can just include it as-is. + if (!info) { + return test + } + + // Exclude failing and flakey tests, newly added tests are + // automatically included. + const { failed = [], flakey = [] } = info + if (failed.length > 0 || flakey.length > 0) { + test.excludedCases = failed.concat(flakey) + } + + return test + }) + } + + throw new Error(`Unknown manifest version: ${manifest.version}`) +} + +module.exports = { getTestFilter } diff --git a/test/ppr-tests-manifest.json b/test/ppr-tests-manifest.json new file mode 100644 index 0000000000000..faaa19186704e --- /dev/null +++ b/test/ppr-tests-manifest.json @@ -0,0 +1,67 @@ +{ + "version": 2, + "suites": { + "test/e2e/app-dir/app-client-cache/client-cache.test.ts": { + "failed": [ + "app dir client cache semantics prefetch={undefined} - default should re-use the full cache for only 30 seconds", + "app dir client cache semantics prefetch={undefined} - default should refetch below the fold after 30 seconds" + ] + }, + "test/e2e/app-dir/headers-static-bailout/headers-static-bailout.test.ts": { + "failed": [ + "headers-static-bailout it provides a helpful link in case static generation bailout is uncaught" + ] + }, + "test/e2e/app-dir/parallel-routes-and-interception/parallel-routes-and-interception.test.ts": { + "failed": [ + "parallel-routes-and-interception route intercepting should render modal when paired with parallel routes", + "parallel-routes-and-interception route intercepting should support intercepting local dynamic sibling routes" + ] + }, + "test/e2e/app-dir/error-boundary-navigation/override-node-env.test.ts": { + "failed": [ + "app dir - not found navigation - with overridden node env should be able to navigate to other page from root not-found page" + ] + }, + "test/e2e/opentelemetry/opentelemetry.test.ts": { + "failed": [ + "opentelemetry root context app router should handle RSC with fetch", + "opentelemetry incoming context propagation app router should handle RSC with fetch", + "opentelemetry incoming context propagation app router should handle route handlers in app router" + ] + }, + "test/e2e/app-dir/rsc-basic/rsc-basic.test.ts": { + "failed": [ + "app dir - rsc basics should render initial styles of css-in-js in edge SSR correctly", + "app dir - rsc basics should render initial styles of css-in-js in nodejs SSR correctly", + "app dir - rsc basics should render server components correctly" + ] + }, + "test/production/app-dir/unexpected-error/unexpected-error.test.ts": { + "failed": [ + "unexpected-error should set response status to 500 for unexpected errors in ssr app route", + "unexpected-error should set response status to 500 for unexpected errors in isr app route" + ] + } + }, + "rules": { + "include": [ + "test/e2e/**/*.test.{t,j}s{,x}", + "test/integration/app-*/**/*.test.{t,j}s{,x}", + "test/production/app-*/**/*.test.{t,j}s{,x}", + "test/development/app-*/**/*.test.{t,j}s{,x}" + ], + "exclude": [ + "test/integration/app-dir-export/**/*", + "test/e2e/app-dir/next-font/**/*", + "test/e2e/app-dir/ppr/**/*", + "test/e2e/app-dir/app-prefetch*/**/*", + "test/e2e/app-dir/interception-middleware-rewrite/interception-middleware-rewrite.test.ts", + "test/e2e/app-dir/searchparams-static-bailout/searchparams-static-bailout.test.ts", + "test/e2e/app-dir/app-static/app-static-custom-handler.test.ts", + "test/e2e/app-dir/app-static/app-static.test.ts", + "test/e2e/app-dir/app-static/app-static-custom-cache-handler-esm.test.ts", + "test/e2e/app-dir/navigation/navigation.test.ts" + ] + } +} From 4d55364b7a8a3c363fc0e72b191cc6f6cd7af0af Mon Sep 17 00:00:00 2001 From: Vercel Release Bot <88769842+vercel-release-bot@users.noreply.github.com> Date: Wed, 29 Nov 2023 03:08:15 -0500 Subject: [PATCH 083/481] Update font data (#59043) This auto-generated PR updates font data with latest available --- packages/font/src/google/font-data.json | 26 ++++++++++++++--- packages/font/src/google/index.ts | 39 ++++++++++++++++++++++--- 2 files changed, 57 insertions(+), 8 deletions(-) diff --git a/packages/font/src/google/font-data.json b/packages/font/src/google/font-data.json index dc9db8b040144..7a05dc31961a1 100644 --- a/packages/font/src/google/font-data.json +++ b/packages/font/src/google/font-data.json @@ -4583,6 +4583,24 @@ "styles": ["normal"], "subsets": ["latin", "latin-ext"] }, + "Hedvig Letters Sans": { + "weights": ["400"], + "styles": ["normal"], + "subsets": ["latin", "latin-ext", "math", "symbols"] + }, + "Hedvig Letters Serif": { + "weights": ["400", "variable"], + "styles": ["normal"], + "axes": [ + { + "tag": "opsz", + "min": 12, + "max": 24, + "defaultValue": 24 + } + ], + "subsets": ["latin", "latin-ext", "math", "symbols"] + }, "Heebo": { "weights": [ "100", @@ -7124,9 +7142,9 @@ "subsets": ["latin"] }, "Narnoor": { - "weights": ["400"], + "weights": ["400", "500", "600", "700", "800"], "styles": ["normal"], - "subsets": ["gunjala-gondi", "latin", "latin-ext"] + "subsets": ["gunjala-gondi", "latin", "latin-ext", "math", "symbols"] }, "Neonderthaw": { "weights": ["400"], @@ -7841,7 +7859,7 @@ "defaultValue": 400 } ], - "subsets": ["gujarati", "latin", "latin-ext"] + "subsets": ["gujarati", "latin", "latin-ext", "math", "symbols"] }, "Noto Sans Gunjala Gondi": { "weights": ["400", "500", "600", "700", "variable"], @@ -9370,7 +9388,7 @@ "defaultValue": 400 } ], - "subsets": ["gujarati", "latin", "latin-ext"] + "subsets": ["gujarati", "latin", "latin-ext", "math", "symbols"] }, "Noto Serif Gurmukhi": { "weights": [ diff --git a/packages/font/src/google/index.ts b/packages/font/src/google/index.ts index 8637b15f5a3c9..c6b9cd987f496 100644 --- a/packages/font/src/google/index.ts +++ b/packages/font/src/google/index.ts @@ -8078,6 +8078,31 @@ export declare function Headland_One< adjustFontFallback?: boolean subsets?: Array<'latin' | 'latin-ext'> }): T extends undefined ? NextFont : NextFontWithVariable +export declare function Hedvig_Letters_Sans< + T extends CssVariable | undefined = undefined +>(options: { + weight: '400' | Array<'400'> + style?: 'normal' | Array<'normal'> + display?: Display + variable?: T + preload?: boolean + fallback?: string[] + adjustFontFallback?: boolean + subsets?: Array<'latin' | 'latin-ext' | 'math' | 'symbols'> +}): T extends undefined ? NextFont : NextFontWithVariable +export declare function Hedvig_Letters_Serif< + T extends CssVariable | undefined = undefined +>(options?: { + weight?: '400' | 'variable' | Array<'400'> + style?: 'normal' | Array<'normal'> + display?: Display + variable?: T + preload?: boolean + fallback?: string[] + adjustFontFallback?: boolean + subsets?: Array<'latin' | 'latin-ext' | 'math' | 'symbols'> + axes?: 'opsz'[] +}): T extends undefined ? NextFont : NextFontWithVariable export declare function Heebo< T extends CssVariable | undefined = undefined >(options?: { @@ -12960,14 +12985,20 @@ export declare function Nanum_Pen_Script< export declare function Narnoor< T extends CssVariable | undefined = undefined >(options: { - weight: '400' | Array<'400'> + weight: + | '400' + | '500' + | '600' + | '700' + | '800' + | Array<'400' | '500' | '600' | '700' | '800'> style?: 'normal' | Array<'normal'> display?: Display variable?: T preload?: boolean fallback?: string[] adjustFontFallback?: boolean - subsets?: Array<'gunjala-gondi' | 'latin' | 'latin-ext'> + subsets?: Array<'gunjala-gondi' | 'latin' | 'latin-ext' | 'math' | 'symbols'> }): T extends undefined ? NextFont : NextFontWithVariable export declare function Neonderthaw< T extends CssVariable | undefined = undefined @@ -14030,7 +14061,7 @@ export declare function Noto_Sans_Gujarati< preload?: boolean fallback?: string[] adjustFontFallback?: boolean - subsets?: Array<'gujarati' | 'latin' | 'latin-ext'> + subsets?: Array<'gujarati' | 'latin' | 'latin-ext' | 'math' | 'symbols'> axes?: 'wdth'[] }): T extends undefined ? NextFont : NextFontWithVariable export declare function Noto_Sans_Gunjala_Gondi< @@ -16178,7 +16209,7 @@ export declare function Noto_Serif_Gujarati< preload?: boolean fallback?: string[] adjustFontFallback?: boolean - subsets?: Array<'gujarati' | 'latin' | 'latin-ext'> + subsets?: Array<'gujarati' | 'latin' | 'latin-ext' | 'math' | 'symbols'> }): T extends undefined ? NextFont : NextFontWithVariable export declare function Noto_Serif_Gurmukhi< T extends CssVariable | undefined = undefined From 9656f15a484b94d3c1f76f76b3fa9ca37013a35a Mon Sep 17 00:00:00 2001 From: Lee Robinson Date: Wed, 29 Nov 2023 02:26:03 -0600 Subject: [PATCH 084/481] docs: patch upgrade guide to pin install version (#58993) Closes https://github.com/vercel/feedback/issues/47076. --- .../08-upgrading/04-version-13.mdx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/03-pages/01-building-your-application/08-upgrading/04-version-13.mdx b/docs/03-pages/01-building-your-application/08-upgrading/04-version-13.mdx index a0ecf42876019..f58193db64ad7 100644 --- a/docs/03-pages/01-building-your-application/08-upgrading/04-version-13.mdx +++ b/docs/03-pages/01-building-your-application/08-upgrading/04-version-13.mdx @@ -8,19 +8,19 @@ description: Upgrade your Next.js Application from Version 12 to 13. To update to Next.js version 13, run the following command using your preferred package manager: ```bash filename="Terminal" -npm i next@latest react@latest react-dom@latest eslint-config-next@latest +npm i next@13 react@latest react-dom@latest eslint-config-next@13 ``` ```bash filename="Terminal" -yarn add next@latest react@latest react-dom@latest eslint-config-next@latest +yarn add next@13 react@latest react-dom@latest eslint-config-next@13 ``` ```bash filename="Terminal" -pnpm up next react react-dom eslint-config-next --latest +pnpm i next@13 react@latest react-dom@latest eslint-config-next@13 ``` ```bash filename="Terminal" -bun add next@latest react@latest react-dom@latest eslint-config-next@latest +bun add next@13 react@latest react-dom@latest eslint-config-next@13 ``` > **Good to know:** If you are using TypeScript, ensure you also upgrade `@types/react` and `@types/react-dom` to their latest versions. From eafaba39cba3287add4726f7884973a78430325d Mon Sep 17 00:00:00 2001 From: Zack Tanner Date: Wed, 29 Nov 2023 00:35:50 -0800 Subject: [PATCH 085/481] update status codes for `redirect` and `permanentRedirect` in action handlers (#58885) ### What? Calling `redirect` or `permanentRedirect` with a route handler used by a server action will result in that POST request following the redirect. This could result in unexpected behavior, such as re-submitting an action (in the case where the redirected URL makes use of the same server action). ### Why? By spec, 307 and 308 status codes will attempt to reuse the original request method & body on the redirected URL. ### How? In all cases when calling a `redirect` handler inside of an action, we'll return a `303 See Other` response which is a typical status code when redirecting to a success / confirmation page as a result of a POST/PUT. The other option would be to use 301 / 302 status codes, but since we're already doing a 303 status code [here](https://github.com/vercel/next.js/blob/canary/packages/next/src/server/app-render/action-handler.ts#L603), this aligns the behavior for the route handler case. Closes NEXT-1733 See also: https://github.com/vercel/next.js/issues/51592#issuecomment-1810212676 [Slack x-ref](https://vercel.slack.com/archives/C03S8ED1DKM/p1700060786749079) --- .../04-functions/permanentRedirect.mdx | 2 +- .../04-functions/redirect.mdx | 2 +- .../next/src/client/components/redirect.ts | 50 ++++++++++---- packages/next/src/lib/redirect-status.ts | 9 ++- .../src/server/app-render/action-handler.ts | 4 +- .../make-get-server-inserted-html.tsx | 4 +- packages/next/src/server/base-http/index.ts | 4 +- packages/next/src/server/base-server.ts | 4 +- .../future/route-modules/app-route/module.ts | 2 + packages/next/src/server/lib/router-server.ts | 4 +- .../server/lib/server-action-request-meta.ts | 14 ++-- packages/next/src/shared/lib/constants.ts | 8 ++- ...app-action-progressive-enhancement.test.ts | 13 ++++ test/e2e/app-dir/actions/app-action.test.ts | 67 ++++++++++++++++++- .../redirects/api-redirect-permanent/route.js | 5 ++ .../app/redirects/api-redirect/route.js | 5 ++ .../e2e/app-dir/actions/app/redirects/page.js | 18 +++++ 17 files changed, 181 insertions(+), 34 deletions(-) create mode 100644 test/e2e/app-dir/actions/app/redirects/api-redirect-permanent/route.js create mode 100644 test/e2e/app-dir/actions/app/redirects/api-redirect/route.js create mode 100644 test/e2e/app-dir/actions/app/redirects/page.js diff --git a/docs/02-app/02-api-reference/04-functions/permanentRedirect.mdx b/docs/02-app/02-api-reference/04-functions/permanentRedirect.mdx index 3162d2a8c7027..cd2279636fdb8 100644 --- a/docs/02-app/02-api-reference/04-functions/permanentRedirect.mdx +++ b/docs/02-app/02-api-reference/04-functions/permanentRedirect.mdx @@ -5,7 +5,7 @@ description: API Reference for the permanentRedirect function. The `permanentRedirect` function allows you to redirect the user to another URL. `permanentRedirect` can be used in Server Components, Client Components, [Route Handlers](/docs/app/building-your-application/routing/route-handlers), and [Server Actions](/docs/app/building-your-application/data-fetching/forms-and-mutations). -When used in a streaming context, this will insert a meta tag to emit the redirect on the client side. Otherwise, it will serve a 308 (Permanent) HTTP redirect response to the caller. +When used in a streaming context, this will insert a meta tag to emit the redirect on the client side. When used in a server action, it will serve a 303 HTTP redirect response to the caller. Otherwise, it will serve a 308 (Permanent) HTTP redirect response to the caller. If a resource doesn't exist, you can use the [`notFound` function](/docs/app/api-reference/functions/not-found) instead. diff --git a/docs/02-app/02-api-reference/04-functions/redirect.mdx b/docs/02-app/02-api-reference/04-functions/redirect.mdx index 6ab95b3bc5a6b..5ef879da65aac 100644 --- a/docs/02-app/02-api-reference/04-functions/redirect.mdx +++ b/docs/02-app/02-api-reference/04-functions/redirect.mdx @@ -5,7 +5,7 @@ description: API Reference for the redirect function. The `redirect` function allows you to redirect the user to another URL. `redirect` can be used in Server Components, Client Components, [Route Handlers](/docs/app/building-your-application/routing/route-handlers), and [Server Actions](/docs/app/building-your-application/data-fetching/forms-and-mutations). -When used in a [streaming context](/docs/app/building-your-application/routing/loading-ui-and-streaming#what-is-streaming), this will insert a meta tag to emit the redirect on the client side. Otherwise, it will serve a 307 HTTP redirect response to the caller. +When used in a [streaming context](/docs/app/building-your-application/routing/loading-ui-and-streaming#what-is-streaming), this will insert a meta tag to emit the redirect on the client side. When used in a server action, it will serve a 303 HTTP redirect response to the caller. Otherwise, it will serve a 307 HTTP redirect response to the caller. If a resource doesn't exist, you can use the [`notFound` function](/docs/app/api-reference/functions/not-found) instead. diff --git a/packages/next/src/client/components/redirect.ts b/packages/next/src/client/components/redirect.ts index d21deecb7754a..28ad8f0fafad8 100644 --- a/packages/next/src/client/components/redirect.ts +++ b/packages/next/src/client/components/redirect.ts @@ -1,5 +1,7 @@ import { requestAsyncStorage } from './request-async-storage.external' import type { ResponseCookies } from '../../server/web/spec-extension/cookies' +import { actionAsyncStorage } from './action-async-storage.external' +import { RedirectStatusCode } from '../../shared/lib/constants' const REDIRECT_ERROR_CODE = 'NEXT_REDIRECT' @@ -9,17 +11,17 @@ export enum RedirectType { } export type RedirectError = Error & { - digest: `${typeof REDIRECT_ERROR_CODE};${RedirectType};${U};${boolean}` + digest: `${typeof REDIRECT_ERROR_CODE};${RedirectType};${U};${RedirectStatusCode};` mutableCookies: ResponseCookies } export function getRedirectError( url: string, type: RedirectType, - permanent: boolean = false + statusCode: RedirectStatusCode = RedirectStatusCode.TemporaryRedirect ): RedirectError { const error = new Error(REDIRECT_ERROR_CODE) as RedirectError - error.digest = `${REDIRECT_ERROR_CODE};${type};${url};${permanent}` + error.digest = `${REDIRECT_ERROR_CODE};${type};${url};${statusCode};` const requestStore = requestAsyncStorage.getStore() if (requestStore) { error.mutableCookies = requestStore.mutableCookies @@ -30,7 +32,7 @@ export function getRedirectError( /** * When used in a streaming context, this will insert a meta tag to * redirect the user to the target page. When used in a custom app route, it - * will serve a 307 to the caller. + * will serve a 307/303 to the caller. * * @param url the url to redirect to */ @@ -38,13 +40,23 @@ export function redirect( url: string, type: RedirectType = RedirectType.replace ): never { - throw getRedirectError(url, type, false) + const actionStore = actionAsyncStorage.getStore() + throw getRedirectError( + url, + type, + // If we're in an action, we want to use a 303 redirect + // as we don't want the POST request to follow the redirect, + // as it could result in erroneous re-submissions. + actionStore?.isAction + ? RedirectStatusCode.SeeOther + : RedirectStatusCode.TemporaryRedirect + ) } /** * When used in a streaming context, this will insert a meta tag to * redirect the user to the target page. When used in a custom app route, it - * will serve a 308 to the caller. + * will serve a 308/303 to the caller. * * @param url the url to redirect to */ @@ -52,7 +64,17 @@ export function permanentRedirect( url: string, type: RedirectType = RedirectType.replace ): never { - throw getRedirectError(url, type, true) + const actionStore = actionAsyncStorage.getStore() + throw getRedirectError( + url, + type, + // If we're in an action, we want to use a 303 redirect + // as we don't want the POST request to follow the redirect, + // as it could result in erroneous re-submissions. + actionStore?.isAction + ? RedirectStatusCode.SeeOther + : RedirectStatusCode.PermanentRedirect + ) } /** @@ -67,15 +89,19 @@ export function isRedirectError( ): error is RedirectError { if (typeof error?.digest !== 'string') return false - const [errorCode, type, destination, permanent] = ( - error.digest as string - ).split(';', 4) + const [errorCode, type, destination, status] = (error.digest as string).split( + ';', + 4 + ) + + const statusCode = Number(status) return ( errorCode === REDIRECT_ERROR_CODE && (type === 'replace' || type === 'push') && typeof destination === 'string' && - (permanent === 'true' || permanent === 'false') + !isNaN(statusCode) && + statusCode in RedirectStatusCode ) } @@ -114,5 +140,5 @@ export function getRedirectStatusCodeFromError( throw new Error('Not a redirect error') } - return error.digest.split(';', 4)[3] === 'true' ? 308 : 307 + return Number(error.digest.split(';', 4)[3]) } diff --git a/packages/next/src/lib/redirect-status.ts b/packages/next/src/lib/redirect-status.ts index 5483a02a55e70..d4fd5740edfd2 100644 --- a/packages/next/src/lib/redirect-status.ts +++ b/packages/next/src/lib/redirect-status.ts @@ -1,7 +1,4 @@ -import { - PERMANENT_REDIRECT_STATUS, - TEMPORARY_REDIRECT_STATUS, -} from '../shared/lib/constants' +import { RedirectStatusCode } from '../shared/lib/constants' export const allowedStatusCodes = new Set([301, 302, 303, 307, 308]) @@ -11,7 +8,9 @@ export function getRedirectStatus(route: { }): number { return ( route.statusCode || - (route.permanent ? PERMANENT_REDIRECT_STATUS : TEMPORARY_REDIRECT_STATUS) + (route.permanent + ? RedirectStatusCode.PermanentRedirect + : RedirectStatusCode.TemporaryRedirect) ) } diff --git a/packages/next/src/server/app-render/action-handler.ts b/packages/next/src/server/app-render/action-handler.ts index d507553404e8a..11614419091fe 100644 --- a/packages/next/src/server/app-render/action-handler.ts +++ b/packages/next/src/server/app-render/action-handler.ts @@ -16,6 +16,7 @@ import { } from '../../client/components/app-router-headers' import { isNotFoundError } from '../../client/components/not-found' import { + getRedirectStatusCodeFromError, getURLFromRedirectError, isRedirectError, } from '../../client/components/redirect' @@ -574,6 +575,7 @@ To configure the body size limit for Server Actions, see: https://nextjs.org/doc } catch (err) { if (isRedirectError(err)) { const redirectUrl = getURLFromRedirectError(err) + const statusCode = getRedirectStatusCodeFromError(err) // if it's a fetch action, we don't want to mess with the status code // and we'll handle it on the client router @@ -605,7 +607,7 @@ To configure the body size limit for Server Actions, see: https://nextjs.org/doc } res.setHeader('Location', redirectUrl) - res.statusCode = 303 + res.statusCode = statusCode return { type: 'done', result: RenderResult.fromStatic(''), diff --git a/packages/next/src/server/app-render/make-get-server-inserted-html.tsx b/packages/next/src/server/app-render/make-get-server-inserted-html.tsx index 7e4505823105e..11c8e7ec46298 100644 --- a/packages/next/src/server/app-render/make-get-server-inserted-html.tsx +++ b/packages/next/src/server/app-render/make-get-server-inserted-html.tsx @@ -7,6 +7,7 @@ import { } from '../../client/components/redirect' import { renderToReadableStream } from 'react-dom/server.edge' import { streamToString } from '../stream-utils/node-web-streams-helper' +import { RedirectStatusCode } from '../../shared/lib/constants' export function makeGetServerInsertedHTML({ polyfills, @@ -38,8 +39,9 @@ export function makeGetServerInsertedHTML({ ) } else if (isRedirectError(error)) { const redirectUrl = getURLFromRedirectError(error) + const statusCode = getRedirectStatusCodeFromError(error) const isPermanent = - getRedirectStatusCodeFromError(error) === 308 ? true : false + statusCode === RedirectStatusCode.PermanentRedirect ? true : false if (redirectUrl) { errorMetaTags.push( { // Since IE11 doesn't support the 308 header add backwards // compatibility using refresh header - if (statusCode === PERMANENT_REDIRECT_STATUS) { + if (statusCode === RedirectStatusCode.PermanentRedirect) { this.setHeader('Refresh', `0;url=${destination}`) } return this diff --git a/packages/next/src/server/base-server.ts b/packages/next/src/server/base-server.ts index ba353d82ee7bb..bd8b872095bf2 100644 --- a/packages/next/src/server/base-server.ts +++ b/packages/next/src/server/base-server.ts @@ -50,8 +50,8 @@ import { APP_PATHS_MANIFEST, NEXT_BUILTIN_DOCUMENT, PAGES_MANIFEST, + RedirectStatusCode, STATIC_STATUS_PAGES, - TEMPORARY_REDIRECT_STATUS, } from '../shared/lib/constants' import { isDynamicRoute } from '../shared/lib/router/utils' import { checkIsOnDemandRevalidate } from './api-utils' @@ -1213,7 +1213,7 @@ export default abstract class Server { if (redirect) { return res - .redirect(redirect, TEMPORARY_REDIRECT_STATUS) + .redirect(redirect, RedirectStatusCode.TemporaryRedirect) .body(redirect) .send() } diff --git a/packages/next/src/server/future/route-modules/app-route/module.ts b/packages/next/src/server/future/route-modules/app-route/module.ts index 0aab61b356361..eb8cc3e41d5f9 100644 --- a/packages/next/src/server/future/route-modules/app-route/module.ts +++ b/packages/next/src/server/future/route-modules/app-route/module.ts @@ -42,6 +42,7 @@ import { requestAsyncStorage } from '../../../../client/components/request-async import { staticGenerationAsyncStorage } from '../../../../client/components/static-generation-async-storage.external' import { actionAsyncStorage } from '../../../../client/components/action-async-storage.external' import * as sharedModules from './shared-modules' +import { getIsServerAction } from '../../../lib/server-action-request-meta' /** * The AppRouteModule is the type of the module exported by the bundled App @@ -274,6 +275,7 @@ export class AppRouteRouteModule extends RouteModule< const response: unknown = await this.actionAsyncStorage.run( { isAppRoute: true, + isAction: getIsServerAction(request), }, () => RequestAsyncStorageWrapper.wrap( diff --git a/packages/next/src/server/lib/router-server.ts b/packages/next/src/server/lib/router-server.ts index c04bb1ce4a4ec..46c563ca38e2a 100644 --- a/packages/next/src/server/lib/router-server.ts +++ b/packages/next/src/server/lib/router-server.ts @@ -29,7 +29,7 @@ import { isPostpone } from './router-utils/is-postpone' import { PHASE_PRODUCTION_SERVER, PHASE_DEVELOPMENT_SERVER, - PERMANENT_REDIRECT_STATUS, + RedirectStatusCode, } from '../../shared/lib/constants' import { DevBundlerService } from './dev-bundler-service' import { type Span, trace } from '../../trace' @@ -353,7 +353,7 @@ export async function initialize(opts: { res.statusCode = statusCode res.setHeader('location', destination) - if (statusCode === PERMANENT_REDIRECT_STATUS) { + if (statusCode === RedirectStatusCode.PermanentRedirect) { res.setHeader('Refresh', `0;url=${destination}`) } return res.end(destination) diff --git a/packages/next/src/server/lib/server-action-request-meta.ts b/packages/next/src/server/lib/server-action-request-meta.ts index 4d18a3dae58fb..45e5ff7a7dd8b 100644 --- a/packages/next/src/server/lib/server-action-request-meta.ts +++ b/packages/next/src/server/lib/server-action-request-meta.ts @@ -1,9 +1,10 @@ import type { IncomingMessage } from 'http' import type { BaseNextRequest } from '../base-http' +import type { NextRequest } from '../web/exports' import { ACTION } from '../../client/components/app-router-headers' export function getServerActionRequestMetadata( - req: IncomingMessage | BaseNextRequest + req: IncomingMessage | BaseNextRequest | NextRequest ): { actionId: string | null isURLEncodedAction: boolean @@ -13,8 +14,13 @@ export function getServerActionRequestMetadata( let actionId: string | null let contentType: string | null - actionId = (req.headers[ACTION.toLowerCase()] as string) ?? null - contentType = req.headers['content-type'] ?? null + if (req.headers instanceof Headers) { + actionId = req.headers.get(ACTION.toLowerCase()) ?? null + contentType = req.headers.get('content-type') + } else { + actionId = (req.headers[ACTION.toLowerCase()] as string) ?? null + contentType = req.headers['content-type'] ?? null + } const isURLEncodedAction = Boolean( req.method === 'POST' && contentType === 'application/x-www-form-urlencoded' @@ -32,7 +38,7 @@ export function getServerActionRequestMetadata( } export function getIsServerAction( - req: IncomingMessage | BaseNextRequest + req: IncomingMessage | BaseNextRequest | NextRequest ): boolean { const { isFetchAction, isURLEncodedAction, isMultipartAction } = getServerActionRequestMetadata(req) diff --git a/packages/next/src/shared/lib/constants.ts b/packages/next/src/shared/lib/constants.ts index 69ef1107ab3aa..d02e14896c7ac 100644 --- a/packages/next/src/shared/lib/constants.ts +++ b/packages/next/src/shared/lib/constants.ts @@ -95,8 +95,6 @@ export const CLIENT_STATIC_FILES_RUNTIME_POLYFILLS_SYMBOL = Symbol( CLIENT_STATIC_FILES_RUNTIME_POLYFILLS ) export const EDGE_RUNTIME_WEBPACK = 'edge-runtime-webpack' -export const TEMPORARY_REDIRECT_STATUS = 307 -export const PERMANENT_REDIRECT_STATUS = 308 export const STATIC_PROPS_ID = '__N_SSG' export const SERVER_PROPS_ID = '__N_SSP' export const PAGE_SEGMENT_KEY = '__PAGE__' @@ -156,3 +154,9 @@ export const SYSTEM_ENTRYPOINTS = new Set([ CLIENT_STATIC_FILES_RUNTIME_AMP, CLIENT_STATIC_FILES_RUNTIME_MAIN_APP, ]) + +export enum RedirectStatusCode { + SeeOther = 303, + TemporaryRedirect = 307, + PermanentRedirect = 308, +} diff --git a/test/e2e/app-dir/actions/app-action-progressive-enhancement.test.ts b/test/e2e/app-dir/actions/app-action-progressive-enhancement.test.ts index 13951b3448006..f1e17141a0284 100644 --- a/test/e2e/app-dir/actions/app-action-progressive-enhancement.test.ts +++ b/test/e2e/app-dir/actions/app-action-progressive-enhancement.test.ts @@ -1,6 +1,7 @@ /* eslint-disable jest/no-standalone-expect */ import { createNextDescribe } from 'e2e-utils' import { check } from 'next-test-utils' +import type { Response } from 'playwright-chromium' createNextDescribe( 'app-dir action progressive enhancement', @@ -15,8 +16,18 @@ createNextDescribe( }, ({ next, isNextDev, isNextStart, isNextDeploy }) => { it('should support formData and redirect without JS', async () => { + let responseCode const browser = await next.browser('/server', { disableJavaScript: true, + beforePageLoad(page) { + page.on('response', (response: Response) => { + const url = new URL(response.url()) + const status = response.status() + if (url.pathname.includes('/server')) { + responseCode = status + } + }) + }, }) await browser.eval(`document.getElementById('name').value = 'test'`) @@ -25,6 +36,8 @@ createNextDescribe( await check(() => { return browser.eval('window.location.pathname + window.location.search') }, '/header?name=test&constructor=_FormData&hidden-info=hi') + + expect(responseCode).toBe(303) }) it('should support actions from client without JS', async () => { diff --git a/test/e2e/app-dir/actions/app-action.test.ts b/test/e2e/app-dir/actions/app-action.test.ts index 7fa91cbb1884c..5a3692a2b0266 100644 --- a/test/e2e/app-dir/actions/app-action.test.ts +++ b/test/e2e/app-dir/actions/app-action.test.ts @@ -1,7 +1,7 @@ /* eslint-disable jest/no-standalone-expect */ import { createNextDescribe } from 'e2e-utils' import { check, waitFor } from 'next-test-utils' -import { Request } from 'playwright-chromium' +import { Request, Response } from 'playwright-chromium' import fs from 'fs-extra' import { join } from 'path' @@ -897,5 +897,70 @@ createNextDescribe( expect(html).not.toContain('qwerty123') }) }) + + describe('redirects', () => { + it('redirects properly when server action handler uses `redirect`', async () => { + const postRequests = [] + const responseCodes = [] + + const browser = await next.browser('/redirects', { + beforePageLoad(page) { + page.on('request', (request: Request) => { + const url = new URL(request.url()) + if (request.method() === 'POST') { + postRequests.push(url.pathname) + } + }) + + page.on('response', (response: Response) => { + const url = new URL(response.url()) + const status = response.status() + + if (postRequests.includes(`${url.pathname}${url.search}`)) { + responseCodes.push(status) + } + }) + }, + }) + await browser.elementById('submit-api-redirect').click() + await check(() => browser.url(), /success=true/) + + // verify that the POST request was only made to the action handler + expect(postRequests).toEqual(['/redirects/api-redirect']) + expect(responseCodes).toEqual([303]) + }) + + it('redirects properly when server action handler uses `permanentRedirect`', async () => { + const postRequests = [] + const responseCodes = [] + + const browser = await next.browser('/redirects', { + beforePageLoad(page) { + page.on('request', (request: Request) => { + const url = new URL(request.url()) + if (request.method() === 'POST') { + postRequests.push(url.pathname) + } + }) + + page.on('response', (response: Response) => { + const url = new URL(response.url()) + const status = response.status() + + if (postRequests.includes(`${url.pathname}${url.search}`)) { + responseCodes.push(status) + } + }) + }, + }) + + await browser.elementById('submit-api-redirect-permanent').click() + await check(() => browser.url(), /success=true/) + + // verify that the POST request was only made to the action handler + expect(postRequests).toEqual(['/redirects/api-redirect-permanent']) + expect(responseCodes).toEqual([303]) + }) + }) } ) diff --git a/test/e2e/app-dir/actions/app/redirects/api-redirect-permanent/route.js b/test/e2e/app-dir/actions/app/redirects/api-redirect-permanent/route.js new file mode 100644 index 0000000000000..f09f5aacc586c --- /dev/null +++ b/test/e2e/app-dir/actions/app/redirects/api-redirect-permanent/route.js @@ -0,0 +1,5 @@ +import { permanentRedirect } from 'next/navigation' + +export function POST(request) { + permanentRedirect('/redirects/?success=true') +} diff --git a/test/e2e/app-dir/actions/app/redirects/api-redirect/route.js b/test/e2e/app-dir/actions/app/redirects/api-redirect/route.js new file mode 100644 index 0000000000000..8db7d6cd1ca6f --- /dev/null +++ b/test/e2e/app-dir/actions/app/redirects/api-redirect/route.js @@ -0,0 +1,5 @@ +import { redirect } from 'next/navigation' + +export function POST(request) { + redirect('/redirects/?success=true') +} diff --git a/test/e2e/app-dir/actions/app/redirects/page.js b/test/e2e/app-dir/actions/app/redirects/page.js new file mode 100644 index 0000000000000..68afb2f2d2fb1 --- /dev/null +++ b/test/e2e/app-dir/actions/app/redirects/page.js @@ -0,0 +1,18 @@ +export default function Home() { + return ( +
+

POST /api-redirect (`redirect()`)

+ + + +

POST /api-redirect-permanent (`permanentRedirect()`)

+
+ +
+
+ ) +} From d6d41dc66d60b5a2bdd732deb2ac3f99bb959ee1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bal=C3=A1zs=20Orb=C3=A1n?= Date: Wed, 29 Nov 2023 15:35:26 +0100 Subject: [PATCH 086/481] chore: bump `nissuer` (issue validator) (#59060) ### What? Bumping the issue validator action [`nissuer`](https://github.com/balazsorban44/nissuer) ### Why? It introduces two new features: - Comments made by members of the Vercel organization are never hidden to avoid hiding useful information. Example: https://github.com/vercel/next.js/actions/runs/6780069984/job/18428144215 - A new option was added to do not allow `https://github.com/vercel/next.js.*` URLs as valid reproductions, as they are non-modified versions. We should require the reporter to go through the process of creating an isolated reproduction that we can clone and verify easily. ### How? See https://github.com/balazsorban44/nissuer/releases/tag/1.8.0 --- .github/workflows/issue_validator.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/issue_validator.yml b/.github/workflows/issue_validator.yml index b6134dfbd9fe7..6337cdb2bbc9d 100644 --- a/.github/workflows/issue_validator.yml +++ b/.github/workflows/issue_validator.yml @@ -18,7 +18,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Nissuer - uses: balazsorban44/nissuer@1.5.0 + uses: balazsorban44/nissuer@1.8.1 with: label-area-prefix: 'area:' label-area-section: 'Which area\(s\) are affected\? \(Select all that apply\)(.*)### Additional context' @@ -30,6 +30,7 @@ jobs: } reproduction-comment: '.github/invalid-link.md' reproduction-hosts: 'github.com,codesandbox.io' + reproduction-blocklist: 'github.com/vercel/next.js.*' reproduction-link-section: '### Link to the code that reproduces this issue(.*)### To Reproduce' reproduction-invalid-label: 'invalid link' reproduction-issue-labels: 'template: bug' From 72388bc986f409d089a1f4ea0885e574558f189b Mon Sep 17 00:00:00 2001 From: Leah Date: Wed, 29 Nov 2023 18:13:58 +0100 Subject: [PATCH 087/481] fix(test): don't use latest sharp (#59074) --- test/integration/image-optimizer/test/sharp.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/image-optimizer/test/sharp.test.ts b/test/integration/image-optimizer/test/sharp.test.ts index 6adb74221122a..e2b5b209d88d2 100644 --- a/test/integration/image-optimizer/test/sharp.test.ts +++ b/test/integration/image-optimizer/test/sharp.test.ts @@ -14,7 +14,7 @@ describe('with latest sharp', () => { packageManager: 'yarn@1.22.19', }) ) - await execa('yarn', ['add', 'sharp'], { + await execa('yarn', ['add', 'sharp@^0.32.0'], { cwd: appDir, stdio: 'inherit', }) From 9e33bf6ab929c81f694880460cce90156ecbfd6f Mon Sep 17 00:00:00 2001 From: Jimmy Lai Date: Wed, 29 Nov 2023 18:19:00 +0100 Subject: [PATCH 088/481] misc: disable automerge (#59077) Disabling the auto merging behaviour from kodiak. You can queue stuff up by adding an automerge label though. Closes NEXT-1751 --- .github/.kodiak.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/.kodiak.toml b/.github/.kodiak.toml index c993778527988..9aa718b793eef 100644 --- a/.github/.kodiak.toml +++ b/.github/.kodiak.toml @@ -2,8 +2,8 @@ version = 1 [merge] -automerge_label = "ready to land" -require_automerge_label = false +automerge_label = "automerge" +require_automerge_label = true method = "squash" delete_branch_on_merge = true optimistic_updates = false From 7d129451910c72579811930a3c415ac9dbb5469f Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Wed, 29 Nov 2023 10:03:25 -0800 Subject: [PATCH 089/481] Ensure stale build fetch data is not unexpectedly used (#59076) If a build time fetch cache is present from a previous build we don't want to unexpectedly use it when flush to disk is set to false in a successive build as it can leverage stale data unexpectedly. x-ref: [slack thread](https://vercel.slack.com/archives/C03S8ED1DKM/p1701266754905909) Closes NEXT-1750 Co-authored-by: Zack Tanner --- .../incremental-cache/file-system-cache.ts | 2 +- test/lib/next-modes/base.ts | 3 +- .../app-fetch-build-cache.test.ts | 33 +++++++++++++++++++ .../app-fetch-build-cache/app/layout.tsx | 7 ++++ .../app-fetch-build-cache/app/page.tsx | 16 +++++++++ .../app-fetch-build-cache/next.config.js | 6 ++++ 6 files changed, 65 insertions(+), 2 deletions(-) create mode 100644 test/production/app-dir/app-fetch-build-cache/app-fetch-build-cache.test.ts create mode 100644 test/production/app-dir/app-fetch-build-cache/app/layout.tsx create mode 100644 test/production/app-dir/app-fetch-build-cache/app/page.tsx create mode 100644 test/production/app-dir/app-fetch-build-cache/next.config.js diff --git a/packages/next/src/server/lib/incremental-cache/file-system-cache.ts b/packages/next/src/server/lib/incremental-cache/file-system-cache.ts index 0f0610452266b..dc4709bb4f364 100644 --- a/packages/next/src/server/lib/incremental-cache/file-system-cache.ts +++ b/packages/next/src/server/lib/incremental-cache/file-system-cache.ts @@ -187,7 +187,7 @@ export default class FileSystemCache implements CacheHandler { const fileData = await this.fs.readFile(filePath, 'utf8') const { mtime } = await this.fs.stat(filePath) - if (kind === 'fetch') { + if (kind === 'fetch' && this.flushToDisk) { const lastModified = mtime.getTime() const parsedData: CachedFetchValue = JSON.parse(fileData) data = { diff --git a/test/lib/next-modes/base.ts b/test/lib/next-modes/base.ts index 3543eff2751f3..f3c06e778e795 100644 --- a/test/lib/next-modes/base.ts +++ b/test/lib/next-modes/base.ts @@ -64,11 +64,12 @@ export class NextInstance { protected _parsedUrl: URL protected packageJson?: PackageJson = {} protected basePath?: string - protected env?: Record + public env: Record public forcedPort?: string public dirSuffix: string = '' constructor(opts: NextInstanceOpts) { + this.env = {} Object.assign(this, opts) if (!(global as any).isNextDeploy) { diff --git a/test/production/app-dir/app-fetch-build-cache/app-fetch-build-cache.test.ts b/test/production/app-dir/app-fetch-build-cache/app-fetch-build-cache.test.ts new file mode 100644 index 0000000000000..183025e8f3a04 --- /dev/null +++ b/test/production/app-dir/app-fetch-build-cache/app-fetch-build-cache.test.ts @@ -0,0 +1,33 @@ +import { createNextDescribe } from 'e2e-utils' + +createNextDescribe( + 'app fetch build cache', + { + files: __dirname, + }, + ({ next }) => { + let initialData + + it('should have done initial build', async () => { + const $ = await next.render$('/') + expect($('#page').text()).toBe('index page') + + initialData = $('#data').text() + expect(initialData).toBeTruthy() + }) + + it('should not use stale data if present', async () => { + await next.stop() + + next.env['NOW_BUILDER'] = '1' + await next.start() + + const $ = await next.render$('/') + expect($('#page').text()).toBe('index page') + + const newData = $('#data').text() + expect(newData).toBeTruthy() + expect(newData).not.toBe(initialData) + }) + } +) diff --git a/test/production/app-dir/app-fetch-build-cache/app/layout.tsx b/test/production/app-dir/app-fetch-build-cache/app/layout.tsx new file mode 100644 index 0000000000000..e7077399c03ce --- /dev/null +++ b/test/production/app-dir/app-fetch-build-cache/app/layout.tsx @@ -0,0 +1,7 @@ +export default function Root({ children }: { children: React.ReactNode }) { + return ( + + {children} + + ) +} diff --git a/test/production/app-dir/app-fetch-build-cache/app/page.tsx b/test/production/app-dir/app-fetch-build-cache/app/page.tsx new file mode 100644 index 0000000000000..83a0c9dc90c4f --- /dev/null +++ b/test/production/app-dir/app-fetch-build-cache/app/page.tsx @@ -0,0 +1,16 @@ +import React from 'react' + +export const revalidate = 30 + +export default async function Page() { + const data = await fetch( + 'https://next-data-api-endpoint.vercel.app/api/random' + ).then((res) => res.text()) + + return ( + <> +

index page

+

{data}

+ + ) +} diff --git a/test/production/app-dir/app-fetch-build-cache/next.config.js b/test/production/app-dir/app-fetch-build-cache/next.config.js new file mode 100644 index 0000000000000..807126e4cf0bf --- /dev/null +++ b/test/production/app-dir/app-fetch-build-cache/next.config.js @@ -0,0 +1,6 @@ +/** + * @type {import('next').NextConfig} + */ +const nextConfig = {} + +module.exports = nextConfig From 5b94850d97a35eea138b21be0a4cf210ed452644 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Wed, 29 Nov 2023 10:07:22 -0800 Subject: [PATCH 090/481] Update checkout step (#59079) When jobs are cancelled we can end up with a bad `.git` tree so this updates to have a fresh checkout step to avoid this x-ref: https://github.com/vercel/next.js/actions/runs/7036193103/job/19148358339?pr=59076 --- .github/workflows/build_reusable.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/build_reusable.yml b/.github/workflows/build_reusable.yml index f6dd49fc5b386..22ce68b9e5ddf 100644 --- a/.github/workflows/build_reusable.yml +++ b/.github/workflows/build_reusable.yml @@ -89,6 +89,8 @@ jobs: - run: corepack enable - run: pwd + - run: rm -rf .git + - uses: actions/checkout@v3 with: fetch-depth: 25 From 7ce4a02bdca2d18f7fd2c45ea24f0dc0f22ac533 Mon Sep 17 00:00:00 2001 From: Leah Date: Wed, 29 Nov 2023 19:25:01 +0100 Subject: [PATCH 091/481] ci: don't try to upload to datadog for docs only changes (#59068) --- .github/workflows/build_and_test.yml | 111 +++++++++++++++++++-------- .github/workflows/build_reusable.yml | 26 +------ scripts/run-for-change.js | 5 +- 3 files changed, 81 insertions(+), 61 deletions(-) diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index fb0dd41371923..f342b4c4179cf 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -28,6 +28,37 @@ env: NEXT_TEST_JOB: 1 jobs: + changes: + name: Determine changes + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 25 + + - name: check for docs only change + id: docs-change + run: | + echo "DOCS_ONLY<> $GITHUB_OUTPUT; + echo "$(node scripts/run-for-change.js --not --type docs --exec echo 'false')" >> $GITHUB_OUTPUT; + echo 'EOF' >> $GITHUB_OUTPUT + + - name: check for release + id: is-release + run: | + if [[ $(node ./scripts/check-is-release.js 2> /dev/null || :) = v* ]]; + then + echo "IS_RELEASE=true" >> $GITHUB_OUTPUT + else + echo "IS_RELEASE=false" >> $GITHUB_OUTPUT + fi + + outputs: + docs-only: ${{ steps.docs-change.outputs.DOCS_ONLY != 'false' }} + is-release: ${{ steps.is-release.outputs.IS_RELEASE == 'true' }} + build-native: name: build-native uses: ./.github/workflows/build_reusable.yml @@ -66,21 +97,21 @@ jobs: check-types-precompiled: name: types and precompiled - needs: ['build-native', 'build-next'] + needs: ['changes', 'build-native', 'build-next'] + if: ${{ needs.changes.outputs.docs-only == 'false' }} uses: ./.github/workflows/build_reusable.yml with: afterBuild: pnpm types-and-precompiled - skipForDocsOnly: 'yes' secrets: inherit test-cargo-unit: name: test cargo unit - needs: ['build-next'] + needs: ['changes', 'build-next'] + if: ${{ needs.changes.outputs.docs-only == 'false' }} uses: ./.github/workflows/build_reusable.yml with: - skipForDocsOnly: 'yes' needsRust: 'yes' skipInstallBuild: 'yes' skipNativeBuild: 'yes' @@ -90,11 +121,11 @@ jobs: test-cargo-integration: name: test cargo integration - needs: ['build-next'] + needs: ['changes', 'build-next'] + if: ${{ needs.changes.outputs.docs-only == 'false' }} uses: ./.github/workflows/build_reusable.yml with: - skipForDocsOnly: 'yes' needsNextest: 'yes' needsRust: 'yes' skipNativeBuild: 'yes' @@ -102,23 +133,22 @@ jobs: test-cargo-bench: name: test cargo benchmarks - needs: ['build-next'] + needs: ['changes', 'build-next'] + if: ${{ needs.changes.outputs.docs-only == 'false' || needs.changes.outputs.is-release == 'false' }} uses: ./.github/workflows/build_reusable.yml with: - skipForDocsOnly: 'yes' - skipForRelease: 'yes' needsRust: 'yes' skipNativeBuild: 'yes' afterBuild: xvfb-run turbo run test-cargo-bench rust-check: name: rust check - needs: ['build-next'] + needs: ['changes', 'build-next'] + if: ${{ needs.changes.outputs.docs-only == 'false' }} uses: ./.github/workflows/build_reusable.yml with: - skipForDocsOnly: 'yes' needsRust: 'yes' skipInstallBuild: 'yes' skipNativeBuild: 'yes' @@ -127,20 +157,23 @@ jobs: test-turbopack-dev: name: test turbopack dev - needs: ['build-native', 'build-next'] + needs: ['changes', 'build-next'] + if: ${{ needs.changes.outputs.docs-only == 'false' }} + strategy: fail-fast: false matrix: group: [1, 2, 3, 4, 5] uses: ./.github/workflows/build_reusable.yml with: - skipForDocsOnly: 'yes' afterBuild: RUST_BACKTRACE=0 NEXT_EXTERNAL_TESTS_FILTERS="$(pwd)/test/turbopack-tests-manifest.json" TURBOPACK=1 NEXT_E2E_TEST_TIMEOUT=240000 NEXT_TEST_MODE=dev node run-tests.js --test-pattern '^(test\/(development|e2e))/.*\.test\.(js|jsx|ts|tsx)$' --timings -g ${{ matrix.group }}/5 -c ${TEST_CONCURRENCY} secrets: inherit test-turbopack-integration: name: test turbopack integration - needs: ['build-native', 'build-next'] + needs: ['changes', 'build-next'] + if: ${{ needs.changes.outputs.docs-only == 'false' }} + strategy: fail-fast: false matrix: @@ -148,21 +181,24 @@ jobs: uses: ./.github/workflows/build_reusable.yml with: nodeVersion: 18.17.0 - skipForDocsOnly: 'yes' afterBuild: RUST_BACKTRACE=0 NEXT_EXTERNAL_TESTS_FILTERS="$(pwd)/test/turbopack-tests-manifest.json" TURBOPACK=1 node run-tests.js --timings -g ${{ matrix.group }}/5 -c ${TEST_CONCURRENCY} --type integration secrets: inherit test-next-swc-wasm: name: test next-swc wasm - needs: ['build-native', 'build-next'] + needs: ['changes', 'build-next'] + if: ${{ needs.changes.outputs.docs-only == 'false' }} + uses: ./.github/workflows/build_reusable.yml with: - skipForDocsOnly: 'yes' afterBuild: rustup target add wasm32-unknown-unknown && curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh && node ./scripts/normalize-version-bump.js && turbo run build-wasm -- --target nodejs --features tracing/release_max_level_info && git checkout . && mv packages/next-swc/crates/wasm/pkg packages/next-swc/crates/wasm/pkg-nodejs && node ./scripts/setup-wasm.mjs && NEXT_TEST_MODE=start TEST_WASM=true node run-tests.js test/production/pages-dir/production/test/index.test.ts test/e2e/streaming-ssr/index.test.ts secrets: inherit test-unit: name: test unit + needs: ['changes'] + if: ${{ needs.changes.outputs.docs-only == 'false' }} + strategy: fail-fast: false matrix: @@ -171,40 +207,43 @@ jobs: uses: ./.github/workflows/build_reusable.yml with: nodeVersion: ${{ matrix.node }} - skipForDocsOnly: 'yes' afterBuild: node run-tests.js -c ${TEST_CONCURRENCY} --type unit secrets: inherit test-dev: name: test dev - needs: ['build-native', 'build-next'] + needs: ['changes', 'build-native', 'build-next'] + if: ${{ needs.changes.outputs.docs-only == 'false' }} + strategy: fail-fast: false matrix: group: [1, 2, 3] uses: ./.github/workflows/build_reusable.yml with: - skipForDocsOnly: 'yes' afterBuild: NEXT_TEST_MODE=dev node run-tests.js --timings -g ${{ matrix.group }}/3 -c ${TEST_CONCURRENCY} --type development secrets: inherit test-prod: name: test prod - needs: ['build-native', 'build-next'] + needs: ['changes', 'build-native', 'build-next'] + if: ${{ needs.changes.outputs.docs-only == 'false' }} + strategy: fail-fast: false matrix: group: [1, 2, 3, 4, 5] uses: ./.github/workflows/build_reusable.yml with: - skipForDocsOnly: 'yes' afterBuild: NEXT_TEST_MODE=start node run-tests.js --timings -g ${{ matrix.group }}/5 -c ${TEST_CONCURRENCY} --type production secrets: inherit test-integration: name: test integration - needs: ['build-native', 'build-next'] + needs: ['changes', 'build-native', 'build-next'] + if: ${{ needs.changes.outputs.docs-only == 'false' }} + strategy: fail-fast: false matrix: @@ -212,17 +251,16 @@ jobs: uses: ./.github/workflows/build_reusable.yml with: nodeVersion: 18.17.0 - skipForDocsOnly: 'yes' afterBuild: node run-tests.js --timings -g ${{ matrix.group }}/12 -c ${TEST_CONCURRENCY} --type integration secrets: inherit test-firefox-safari: name: test firefox and safari - needs: ['build-native', 'build-next'] + needs: ['changes', 'build-native', 'build-next'] + if: ${{ needs.changes.outputs.docs-only == 'false' }} uses: ./.github/workflows/build_reusable.yml with: - skipForDocsOnly: 'yes' afterBuild: pnpm playwright install && BROWSER_NAME=firefox node run-tests.js test/production/pages-dir/production/test/index.test.ts && BROWSER_NAME=safari NEXT_TEST_MODE=start node run-tests.js -c 1 test/production/pages-dir/production/test/index.test.ts test/e2e/basepath.test.ts && BROWSER_NAME=safari DEVICE_NAME='iPhone XR' node run-tests.js -c 1 test/production/prerender-prefetch/index.test.ts secrets: inherit @@ -230,7 +268,9 @@ jobs: # Manifest generated via: https://gist.github.com/wyattjoh/2ceaebd82a5bcff4819600fd60126431 test-ppr-integration: name: test ppr integration - needs: ['build-native', 'build-next'] + needs: ['changes', 'build-native', 'build-next'] + if: ${{ needs.changes.outputs.docs-only == 'false' }} + strategy: fail-fast: false matrix: @@ -238,39 +278,41 @@ jobs: uses: ./.github/workflows/build_reusable.yml with: nodeVersion: 18.17.0 - skipForDocsOnly: 'yes' afterBuild: __NEXT_EXPERIMENTAL_PPR=true NEXT_EXTERNAL_TESTS_FILTERS="test/ppr-tests-manifest.json" node run-tests.js --timings -g ${{ matrix.group }}/3 -c ${TEST_CONCURRENCY} --type integration secrets: inherit test-ppr-dev: name: test ppr dev - needs: ['build-native', 'build-next'] + needs: ['changes', 'build-native', 'build-next'] + if: ${{ needs.changes.outputs.docs-only == 'false' }} + strategy: fail-fast: false matrix: group: [1, 2, 3] uses: ./.github/workflows/build_reusable.yml with: - skipForDocsOnly: 'yes' afterBuild: __NEXT_EXPERIMENTAL_PPR=true NEXT_EXTERNAL_TESTS_FILTERS="test/ppr-tests-manifest.json" NEXT_TEST_MODE=dev node run-tests.js --timings -g ${{ matrix.group }}/3 -c ${TEST_CONCURRENCY} --type development secrets: inherit test-ppr-prod: name: test ppr prod - needs: ['build-native', 'build-next'] + needs: ['changes', 'build-native', 'build-next'] + if: ${{ needs.changes.outputs.docs-only == 'false' }} + strategy: fail-fast: false matrix: group: [1, 2, 3] uses: ./.github/workflows/build_reusable.yml with: - skipForDocsOnly: 'yes' afterBuild: __NEXT_EXPERIMENTAL_PPR=true NEXT_EXTERNAL_TESTS_FILTERS="test/ppr-tests-manifest.json" NEXT_TEST_MODE=start node run-tests.js --timings -g ${{ matrix.group }}/3 -c ${TEST_CONCURRENCY} --type production secrets: inherit report-test-results: needs: [ + 'changes', 'test-unit', 'test-dev', 'test-prod', @@ -281,7 +323,8 @@ jobs: 'test-turbopack-dev', 'test-turbopack-integration', ] - if: always() + if: ${{ always() && needs.changes.outputs.docs-only == 'false' && !github.event.pull_request.head.repo.fork }} + runs-on: ubuntu-latest name: report test results to datadog steps: @@ -333,4 +376,4 @@ jobs: name: thank you, next steps: - run: exit 1 - if: ${{ always() && (contains(needs.*.result, 'failure') || contains(needs.*.result, 'skipped') || contains(needs.*.result, 'cancelled')) }} + if: ${{ always() && (contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')) }} diff --git a/.github/workflows/build_reusable.yml b/.github/workflows/build_reusable.yml index 22ce68b9e5ddf..6e8778def5f29 100644 --- a/.github/workflows/build_reusable.yml +++ b/.github/workflows/build_reusable.yml @@ -25,14 +25,6 @@ on: required: false description: 'whether to upload analyzer artifacts' type: string - skipForDocsOnly: - required: false - description: 'skip for docs only changes' - type: string - skipForRelease: - required: false - description: 'skip for release' - type: string nodeVersion: required: false description: 'version of Node.js to use' @@ -132,28 +124,15 @@ jobs: - run: cargo clean if: ${{ inputs.skipNativeBuild != 'yes' || inputs.needsNextest == 'yes' || inputs.needsRust == 'yes' }} - - run: echo "DOCS_CHANGE<> $GITHUB_OUTPUT; echo "$(node scripts/run-for-change.js --not --type docs --exec echo 'nope')" >> $GITHUB_OUTPUT; echo 'EOF' >> $GITHUB_OUTPUT - name: check docs only change - id: docs-change - - - id: is-release - run: | - if [[ $(node ./scripts/check-is-release.js 2> /dev/null || :) = v* ]]; - then - echo "IS_RELEASE=yes" >> $GITHUB_OUTPUT - else - echo "IS_RELEASE=nope" >> $GITHUB_OUTPUT - fi - # normalize versions before build-native for better cache hits - run: node scripts/normalize-version-bump.js name: normalize versions - run: turbo run build-native-release -vvv --remote-cache-timeout 90 --summarize -- --target x86_64-unknown-linux-gnu - if: ${{ inputs.skipNativeBuild != 'yes' && steps.docs-change.outputs.DOCS_CHANGE == 'nope' }} + if: ${{ inputs.skipNativeBuild != 'yes' }} - name: Upload next-swc artifact - if: ${{ inputs.uploadSwcArtifact == 'yes' && steps.docs-change.outputs.DOCS_CHANGE == 'nope' }} + if: ${{ inputs.uploadSwcArtifact == 'yes' }} uses: actions/upload-artifact@v3 with: name: next-swc-binary @@ -178,7 +157,6 @@ jobs: - run: turbo run get-test-timings -- --build ${{ github.sha }} - run: /bin/bash -c "${{ inputs.afterBuild }}" - if: ${{(inputs.skipForDocsOnly != 'yes' || steps.docs-change.outputs.DOCS_CHANGE == 'nope') && (inputs.skipForRelease != 'yes' || steps.is-release.outputs.IS_RELEASE == 'nope')}} - name: Upload artifact uses: actions/upload-artifact@v3 diff --git a/scripts/run-for-change.js b/scripts/run-for-change.js index 62ae100d334d3..88aa740845307 100644 --- a/scripts/run-for-change.js +++ b/scripts/run-for-change.js @@ -60,9 +60,8 @@ async function main() { const remoteUrl = eventData?.head?.repo?.full_name || process.env.GITHUB_REPOSITORY || - (await exec('git remote get-url origin').stdout) + (await exec('git remote get-url origin')).stdout - let changedFilesOutput = '' const isCanary = branchName.trim() === 'canary' && remoteUrl.includes('vercel/next.js') @@ -85,7 +84,7 @@ async function main() { } ) console.error({ branchName, remoteUrl, isCanary, changesResult }) - changedFilesOutput = changesResult.stdout + const changedFilesOutput = changesResult.stdout const typeIndex = process.argv.indexOf('--type') const type = typeIndex > -1 && process.argv[typeIndex + 1] From cec374f98c8e6342b818b1465f5c93ede55dbe0e Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Wed, 29 Nov 2023 18:34:18 +0000 Subject: [PATCH 092/481] v14.0.4-canary.26 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 16 ++++++++-------- 18 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lerna.json b/lerna.json index e8cda90f644db..eafb20a6a3a87 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.25" + "version": "14.0.4-canary.26" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index f445caa5d3298..4d2f23e9bd3f1 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.25", + "version": "14.0.4-canary.26", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index e4c352d47dd48..2937b5de1be82 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.25", + "version": "14.0.4-canary.26", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.25", + "@next/eslint-plugin-next": "14.0.4-canary.26", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 349f543fdeff3..9f847e2dcb45c 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.25", + "version": "14.0.4-canary.26", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index 0fd534874a73b..d45e1ab992a05 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.25", + "version": "14.0.4-canary.26", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 06bf49a923a53..307b4e4a454de 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.25", + "version": "14.0.4-canary.26", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 2823e3f3d3b62..13f0d642ba42e 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.25", + "version": "14.0.4-canary.26", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 70a96c4f789b9..f4a5af6230ad6 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.25", + "version": "14.0.4-canary.26", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 5af0e73617afb..26df08c9bc798 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.25", + "version": "14.0.4-canary.26", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 442f4ac923e4e..051c82573376b 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.25", + "version": "14.0.4-canary.26", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index 6b5a678b384a3..f9de50c1aff87 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.25", + "version": "14.0.4-canary.26", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index 370ba33ce6b88..a27e4ebb307fb 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.25", + "version": "14.0.4-canary.26", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index 97b943b199e23..541b9471936fc 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.25", + "version": "14.0.4-canary.26", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index a5b438b7f82aa..dd4d5aebc3f87 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.25", + "version": "14.0.4-canary.26", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.25", + "@next/env": "14.0.4-canary.26", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -147,11 +147,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.25", - "@next/polyfill-nomodule": "14.0.4-canary.25", - "@next/react-dev-overlay": "14.0.4-canary.25", - "@next/react-refresh-utils": "14.0.4-canary.25", - "@next/swc": "14.0.4-canary.25", + "@next/polyfill-module": "14.0.4-canary.26", + "@next/polyfill-nomodule": "14.0.4-canary.26", + "@next/react-dev-overlay": "14.0.4-canary.26", + "@next/react-refresh-utils": "14.0.4-canary.26", + "@next/swc": "14.0.4-canary.26", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index 434ebddf216b2..d4686b0639b56 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.25", + "version": "14.0.4-canary.26", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index 091400d33ab01..d248bdac265b3 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.25", + "version": "14.0.4-canary.26", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index 3fccaf91b5f16..463fd4c9f725f 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.25", + "version": "14.0.4-canary.26", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -23,7 +23,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.25", + "next": "14.0.4-canary.26", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 096a7bf6957e2..ce979c1ac3d15 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -741,7 +741,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.25 + specifier: 14.0.4-canary.26 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -806,7 +806,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.25 + specifier: 14.0.4-canary.26 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -933,19 +933,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.25 + specifier: 14.0.4-canary.26 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.25 + specifier: 14.0.4-canary.26 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.25 + specifier: 14.0.4-canary.26 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.25 + specifier: 14.0.4-canary.26 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.25 + specifier: 14.0.4-canary.26 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1599,7 +1599,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.25 + specifier: 14.0.4-canary.26 version: link:../next outdent: specifier: 0.8.0 From e17b368760eae1aaa99cea086490a29a3105afdf Mon Sep 17 00:00:00 2001 From: Jimmy Lai Date: Wed, 29 Nov 2023 19:38:33 +0100 Subject: [PATCH 093/481] misc: delete kodiak (#59082) We don't need the auto merging from kodiak since Github has one. Closes NEXT-1753 --- .github/.kodiak.toml | 19 ------------------- 1 file changed, 19 deletions(-) delete mode 100644 .github/.kodiak.toml diff --git a/.github/.kodiak.toml b/.github/.kodiak.toml deleted file mode 100644 index 9aa718b793eef..0000000000000 --- a/.github/.kodiak.toml +++ /dev/null @@ -1,19 +0,0 @@ -# .kodiak.toml -version = 1 - -[merge] -automerge_label = "automerge" -require_automerge_label = true -method = "squash" -delete_branch_on_merge = true -optimistic_updates = false -prioritize_ready_to_merge = true -notify_on_conflict = false - -[merge.message] -title = "pull_request_title" -body = "pull_request_body" -include_coauthors= true -include_pr_number = true -body_type = "markdown" -strip_html_comments = true \ No newline at end of file From 6b651b0b12b4c1889ead0bf39cd391c884f37256 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Wed, 29 Nov 2023 20:01:38 +0100 Subject: [PATCH 094/481] add support for instrumentation (#59070) Closes PACK-2057 --- .../crates/napi/src/next_api/endpoint.rs | 10 +- .../crates/napi/src/next_api/project.rs | 36 +++- packages/next-swc/crates/next-api/src/app.rs | 18 +- .../crates/next-api/src/entrypoints.rs | 3 +- .../crates/next-api/src/instrumentation.rs | 197 +++++++++++++++++ packages/next-swc/crates/next-api/src/lib.rs | 1 + .../crates/next-api/src/middleware.rs | 25 +-- .../next-swc/crates/next-api/src/pages.rs | 18 +- .../next-swc/crates/next-api/src/project.rs | 78 ++++++- .../next-swc/crates/next-api/src/route.rs | 3 - .../crates/next-core/src/instrumentation.rs | 16 ++ packages/next-swc/crates/next-core/src/lib.rs | 1 + .../crates/next-core/src/next_edge/context.rs | 3 +- .../crates/next-core/src/next_import_map.rs | 9 +- .../next-core/src/next_manifests/mod.rs | 14 ++ .../next-core/src/next_server/context.rs | 24 ++- .../next-core/src/next_server/transforms.rs | 5 +- packages/next/src/build/swc/index.ts | 24 ++- packages/next/src/lib/turbopack-warning.ts | 2 +- .../lib/router-utils/setup-dev-bundler.ts | 71 +++++- .../instrumentation-hook-src.test.ts | 113 +++++----- .../instrumentation-hook.test.ts | 202 +++++++++--------- 22 files changed, 622 insertions(+), 251 deletions(-) create mode 100644 packages/next-swc/crates/next-api/src/instrumentation.rs create mode 100644 packages/next-swc/crates/next-core/src/instrumentation.rs diff --git a/packages/next-swc/crates/napi/src/next_api/endpoint.rs b/packages/next-swc/crates/napi/src/next_api/endpoint.rs index f1ae5c58f4445..06704354a0bc9 100644 --- a/packages/next-swc/crates/napi/src/next_api/endpoint.rs +++ b/packages/next-swc/crates/napi/src/next_api/endpoint.rs @@ -39,8 +39,6 @@ pub struct NapiWrittenEndpoint { pub r#type: String, pub entry_path: Option, pub server_paths: Option>, - pub files: Option>, - pub global_var_name: Option, pub config: NapiEndpointConfig, } @@ -56,15 +54,9 @@ impl From<&WrittenEndpoint> for NapiWrittenEndpoint { server_paths: Some(server_paths.iter().map(From::from).collect()), ..Default::default() }, - WrittenEndpoint::Edge { - files, - global_var_name, - server_paths, - } => Self { + WrittenEndpoint::Edge { server_paths } => Self { r#type: "edge".to_string(), - files: Some(files.clone()), server_paths: Some(server_paths.iter().map(From::from).collect()), - global_var_name: Some(global_var_name.clone()), ..Default::default() }, } diff --git a/packages/next-swc/crates/napi/src/next_api/project.rs b/packages/next-swc/crates/napi/src/next_api/project.rs index 80ef449ec1b77..a4c4e375026cb 100644 --- a/packages/next-swc/crates/napi/src/next_api/project.rs +++ b/packages/next-swc/crates/napi/src/next_api/project.rs @@ -7,7 +7,10 @@ use napi::{ JsFunction, Status, }; use next_api::{ - project::{DefineEnv, Middleware, PartialProjectOptions, ProjectContainer, ProjectOptions}, + project::{ + DefineEnv, Instrumentation, Middleware, PartialProjectOptions, ProjectContainer, + ProjectOptions, + }, route::{Endpoint, Route}, }; use next_core::tracing_presets::{ @@ -385,10 +388,36 @@ impl NapiMiddleware { }) } } + +#[napi(object)] +struct NapiInstrumentation { + pub node_js: External, + pub edge: External, +} + +impl NapiInstrumentation { + fn from_instrumentation( + value: &Instrumentation, + turbo_tasks: &Arc>, + ) -> Result { + Ok(NapiInstrumentation { + node_js: External::new(ExternalEndpoint(VcArc::new( + turbo_tasks.clone(), + value.node_js, + ))), + edge: External::new(ExternalEndpoint(VcArc::new( + turbo_tasks.clone(), + value.edge, + ))), + }) + } +} + #[napi(object)] struct NapiEntrypoints { pub routes: Vec, pub middleware: Option, + pub instrumentation: Option, pub pages_document_endpoint: External, pub pages_app_endpoint: External, pub pages_error_endpoint: External, @@ -430,6 +459,11 @@ pub fn project_entrypoints_subscribe( .as_ref() .map(|m| NapiMiddleware::from_middleware(m, &turbo_tasks)) .transpose()?, + instrumentation: entrypoints + .instrumentation + .as_ref() + .map(|m| NapiInstrumentation::from_instrumentation(m, &turbo_tasks)) + .transpose()?, pages_document_endpoint: External::new(ExternalEndpoint(VcArc::new( turbo_tasks.clone(), entrypoints.pages_document_endpoint, diff --git a/packages/next-swc/crates/next-api/src/app.rs b/packages/next-swc/crates/next-api/src/app.rs index 5c4255063b809..37d792e02112b 100644 --- a/packages/next-swc/crates/next-api/src/app.rs +++ b/packages/next-swc/crates/next-api/src/app.rs @@ -918,10 +918,10 @@ impl AppEndpoint { }; let middleware_manifest_v2 = MiddlewaresManifestV2 { sorted_middleware: vec![app_entry.original_name.clone()], - middleware: Default::default(), functions: [(app_entry.original_name.clone(), edge_function_definition)] .into_iter() .collect(), + ..Default::default() }; let manifest_path_prefix = get_asset_prefix_from_pathname(&app_entry.pathname); let middleware_manifest_v2 = Vc::upcast(VirtualOutputAsset::new( @@ -1111,21 +1111,7 @@ impl Endpoint for AppEndpoint { .to_string(), server_paths, }, - AppEndpointOutput::Edge { files, .. } => WrittenEndpoint::Edge { - files: files - .await? - .iter() - .map(|&file| async move { - Ok(node_root_ref - .get_path_to(&*file.ident().path().await?) - .context("edge chunk file path must be inside the node root")? - .to_string()) - }) - .try_join() - .await?, - global_var_name: "TODO".to_string(), - server_paths, - }, + AppEndpointOutput::Edge { .. } => WrittenEndpoint::Edge { server_paths }, }; Ok(written_endpoint.cell()) } diff --git a/packages/next-swc/crates/next-api/src/entrypoints.rs b/packages/next-swc/crates/next-api/src/entrypoints.rs index 9268ba6dc1818..578a3aba34695 100644 --- a/packages/next-swc/crates/next-api/src/entrypoints.rs +++ b/packages/next-swc/crates/next-api/src/entrypoints.rs @@ -2,7 +2,7 @@ use indexmap::IndexMap; use turbo_tasks::Vc; use crate::{ - project::Middleware, + project::{Instrumentation, Middleware}, route::{Endpoint, Route}, }; @@ -10,6 +10,7 @@ use crate::{ pub struct Entrypoints { pub routes: IndexMap, pub middleware: Option, + pub instrumentation: Option, pub pages_document_endpoint: Vc>, pub pages_app_endpoint: Vc>, pub pages_error_endpoint: Vc>, diff --git a/packages/next-swc/crates/next-api/src/instrumentation.rs b/packages/next-swc/crates/next-api/src/instrumentation.rs new file mode 100644 index 0000000000000..b25607bb2ce6d --- /dev/null +++ b/packages/next-swc/crates/next-api/src/instrumentation.rs @@ -0,0 +1,197 @@ +use anyhow::{bail, Context, Result}; +use next_core::{ + mode::NextMode, + next_edge::entry::wrap_edge_entry, + next_manifests::{InstrumentationDefinition, MiddlewaresManifestV2}, + next_server::{get_server_chunking_context, get_server_runtime_entries, ServerContextType}, +}; +use turbo_tasks::{Completion, TryJoinIterExt, Value, Vc}; +use turbopack_binding::{ + turbo::tasks_fs::{File, FileContent}, + turbopack::{ + core::{ + asset::AssetContent, + chunk::ChunkingContext, + context::AssetContext, + module::Module, + output::{OutputAsset, OutputAssets}, + virtual_output::VirtualOutputAsset, + }, + ecmascript::chunk::EcmascriptChunkPlaceable, + }, +}; + +use crate::{ + project::Project, + route::{Endpoint, WrittenEndpoint}, + server_paths::all_server_paths, +}; + +#[turbo_tasks::value] +pub struct InstrumentationEndpoint { + project: Vc, + context: Vc>, + userland_module: Vc>, + is_edge: bool, +} + +#[turbo_tasks::value_impl] +impl InstrumentationEndpoint { + #[turbo_tasks::function] + pub fn new( + project: Vc, + context: Vc>, + userland_module: Vc>, + is_edge: bool, + ) -> Vc { + Self { + project, + context, + userland_module, + is_edge, + } + .cell() + } + + #[turbo_tasks::function] + async fn edge_files(&self) -> Result> { + let module = wrap_edge_entry( + self.context, + self.project.project_path(), + self.userland_module, + "instrumentation".to_string(), + ); + + let mut evaluatable_assets = get_server_runtime_entries( + Value::new(ServerContextType::Middleware), + NextMode::Development, + ) + .resolve_entries(self.context) + .await? + .clone_value(); + + let Some(module) = + Vc::try_resolve_downcast::>(module).await? + else { + bail!("Entry module must be evaluatable"); + }; + + let Some(evaluatable) = Vc::try_resolve_sidecast(module).await? else { + bail!("Entry module must be evaluatable"); + }; + evaluatable_assets.push(evaluatable); + + let edge_chunking_context = self.project.edge_chunking_context(); + + let edge_files = edge_chunking_context + .evaluated_chunk_group(module.ident(), Vc::cell(evaluatable_assets)); + + Ok(edge_files) + } + + #[turbo_tasks::function] + async fn node_chunk(&self) -> Result>> { + let chunking_context = get_server_chunking_context( + self.project.project_path(), + self.project.node_root(), + self.project.client_relative_path(), + self.project.next_config().computed_asset_prefix(), + self.project.server_compile_time_info().environment(), + ); + + let Some(module) = Vc::try_resolve_downcast(self.userland_module).await? else { + bail!("Entry module must be evaluatable"); + }; + + let chunk = chunking_context.entry_chunk_group( + self.project + .node_root() + .join("server/instrumentation.js".to_string()), + module, + get_server_runtime_entries( + Value::new(ServerContextType::Instrumentation), + NextMode::Development, + ) + .resolve_entries(self.context), + ); + Ok(chunk) + } + + #[turbo_tasks::function] + async fn output_assets(self: Vc) -> Result> { + let this = self.await?; + + if this.is_edge { + let mut output_assets = self.edge_files().await?.clone_value(); + + let node_root = this.project.node_root(); + + let files_paths_from_root = { + let node_root = &node_root.await?; + output_assets + .iter() + .map(|&file| async move { + Ok(node_root + .get_path_to(&*file.ident().path().await?) + .context("middleware file path must be inside the node root")? + .to_string()) + }) + .try_join() + .await? + }; + + let instrumentation_definition = InstrumentationDefinition { + files: files_paths_from_root, + name: "instrumentation".to_string(), + ..Default::default() + }; + let middleware_manifest_v2 = MiddlewaresManifestV2 { + instrumentation: Some(instrumentation_definition), + ..Default::default() + }; + let middleware_manifest_v2 = Vc::upcast(VirtualOutputAsset::new( + node_root.join("server/instrumentation/middleware-manifest.json".to_string()), + AssetContent::file( + FileContent::Content(File::from(serde_json::to_string_pretty( + &middleware_manifest_v2, + )?)) + .cell(), + ), + )); + output_assets.push(middleware_manifest_v2); + + Ok(Vc::cell(output_assets)) + } else { + Ok(Vc::cell(vec![self.node_chunk()])) + } + } +} + +#[turbo_tasks::value_impl] +impl Endpoint for InstrumentationEndpoint { + #[turbo_tasks::function] + async fn write_to_disk(self: Vc) -> Result> { + let this = self.await?; + let output_assets = self.output_assets(); + this.project + .emit_all_output_assets(Vc::cell(output_assets)) + .await?; + + let node_root = this.project.node_root(); + let server_paths = all_server_paths(output_assets, node_root) + .await? + .clone_value(); + + Ok(WrittenEndpoint::Edge { server_paths }.cell()) + } + + #[turbo_tasks::function] + async fn server_changed(self: Vc) -> Result> { + Ok(self.await?.project.server_changed(self.output_assets())) + } + + #[turbo_tasks::function] + fn client_changed(self: Vc) -> Vc { + Completion::immutable() + } +} diff --git a/packages/next-swc/crates/next-api/src/lib.rs b/packages/next-swc/crates/next-api/src/lib.rs index 299adf0a061a4..0a1402928e328 100644 --- a/packages/next-swc/crates/next-api/src/lib.rs +++ b/packages/next-swc/crates/next-api/src/lib.rs @@ -4,6 +4,7 @@ mod app; mod dynamic_imports; mod entrypoints; +mod instrumentation; mod middleware; mod pages; pub mod project; diff --git a/packages/next-swc/crates/next-api/src/middleware.rs b/packages/next-swc/crates/next-api/src/middleware.rs index e8e613dfd0e72..ed49350c90f47 100644 --- a/packages/next-swc/crates/next-api/src/middleware.rs +++ b/packages/next-swc/crates/next-api/src/middleware.rs @@ -143,11 +143,10 @@ impl MiddlewareEndpoint { ..Default::default() }; let middleware_manifest_v2 = MiddlewaresManifestV2 { - sorted_middleware: Default::default(), middleware: [("/".to_string(), edge_function_definition)] .into_iter() .collect(), - functions: Default::default(), + ..Default::default() }; let middleware_manifest_v2 = Vc::upcast(VirtualOutputAsset::new( node_root.join("server/middleware/middleware-manifest.json".to_string()), @@ -169,7 +168,6 @@ impl Endpoint for MiddlewareEndpoint { #[turbo_tasks::function] async fn write_to_disk(self: Vc) -> Result> { let this = self.await?; - let files = self.edge_files(); let output_assets = self.output_assets(); this.project .emit_all_output_assets(Vc::cell(output_assets)) @@ -180,26 +178,7 @@ impl Endpoint for MiddlewareEndpoint { .await? .clone_value(); - let node_root = &node_root.await?; - - let files = files - .await? - .iter() - .map(|&file| async move { - Ok(node_root - .get_path_to(&*file.ident().path().await?) - .context("middleware file path must be inside the node root")? - .to_string()) - }) - .try_join() - .await?; - - Ok(WrittenEndpoint::Edge { - files, - global_var_name: "TODO".to_string(), - server_paths, - } - .cell()) + Ok(WrittenEndpoint::Edge { server_paths }.cell()) } #[turbo_tasks::function] diff --git a/packages/next-swc/crates/next-api/src/pages.rs b/packages/next-swc/crates/next-api/src/pages.rs index 35bb83441799c..8d18ef351b533 100644 --- a/packages/next-swc/crates/next-api/src/pages.rs +++ b/packages/next-swc/crates/next-api/src/pages.rs @@ -1012,10 +1012,10 @@ impl PageEndpoint { }; let middleware_manifest_v2 = MiddlewaresManifestV2 { sorted_middleware: vec![pathname.to_string()], - middleware: Default::default(), functions: [(pathname.to_string(), edge_function_definition)] .into_iter() .collect(), + ..Default::default() }; let manifest_path_prefix = get_asset_prefix_from_pathname(&this.pathname.await?); let middleware_manifest_v2 = Vc::upcast(VirtualOutputAsset::new( @@ -1081,21 +1081,7 @@ impl Endpoint for PageEndpoint { .to_string(), server_paths, }, - PageEndpointOutput::Edge { files, .. } => WrittenEndpoint::Edge { - files: files - .await? - .iter() - .map(|&file| async move { - Ok(node_root - .get_path_to(&*file.ident().path().await?) - .context("ssr chunk file path must be inside the node root")? - .to_string()) - }) - .try_join() - .await?, - global_var_name: "TODO".to_string(), - server_paths, - }, + PageEndpointOutput::Edge { .. } => WrittenEndpoint::Edge { server_paths }, }; Ok(written_endpoint.cell()) diff --git a/packages/next-swc/crates/next-api/src/project.rs b/packages/next-swc/crates/next-api/src/project.rs index 84fe32744bace..b5431ac3774f6 100644 --- a/packages/next-swc/crates/next-api/src/project.rs +++ b/packages/next-swc/crates/next-api/src/project.rs @@ -7,13 +7,14 @@ use next_core::{ app_structure::find_app_dir, emit_assets, get_edge_chunking_context, get_edge_compile_time_info, get_edge_resolve_options_context, + instrumentation::instrumentation_files, middleware::middleware_files, mode::NextMode, next_client::{get_client_chunking_context, get_client_compile_time_info}, next_config::{JsConfig, NextConfig}, next_server::{ get_server_chunking_context, get_server_compile_time_info, - get_server_module_options_context, ServerContextType, + get_server_module_options_context, get_server_resolve_options_context, ServerContextType, }, next_telemetry::NextFeatureTelemetry, }; @@ -57,6 +58,7 @@ use crate::{ app::{AppProject, OptionAppProject}, build, entrypoints::Entrypoints, + instrumentation::InstrumentationEndpoint, middleware::MiddlewareEndpoint, pages::PagesProject, route::{Endpoint, Route}, @@ -136,6 +138,12 @@ pub struct Middleware { pub endpoint: Vc>, } +#[derive(Serialize, Deserialize, TraceRawVcs, PartialEq, Eq, ValueDebugFormat)] +pub struct Instrumentation { + pub node_js: Vc>, + pub edge: Vc>, +} + #[turbo_tasks::value] pub struct ProjectContainer { options_state: State, @@ -661,9 +669,34 @@ impl Project { None }; + let instrumentation = find_context_file( + self.project_path(), + instrumentation_files(self.next_config().page_extensions()), + ); + let instrumentation = if let FindContextFileResult::Found(fs_path, _) = + *instrumentation.await? + { + let source = Vc::upcast(FileSource::new(fs_path)); + Some(Instrumentation { + node_js: TraitRef::cell( + Vc::upcast::>(self.instrumentation_endpoint(source, false)) + .into_trait_ref() + .await?, + ), + edge: TraitRef::cell( + Vc::upcast::>(self.instrumentation_endpoint(source, true)) + .into_trait_ref() + .await?, + ), + }) + } else { + None + }; + Ok(Entrypoints { routes, middleware, + instrumentation, pages_document_endpoint, pages_app_endpoint, pages_error_endpoint, @@ -706,6 +739,49 @@ impl Project { MiddlewareEndpoint::new(self, context, module) } + #[turbo_tasks::function] + fn node_instrumentation_context(self: Vc) -> Vc> { + Vc::upcast(ModuleAssetContext::new( + Default::default(), + self.server_compile_time_info(), + get_server_module_options_context( + self.project_path(), + self.execution_context(), + Value::new(ServerContextType::Instrumentation), + NextMode::Development, + self.next_config(), + ), + get_server_resolve_options_context( + self.project_path(), + Value::new(ServerContextType::Instrumentation), + NextMode::Development, + self.next_config(), + self.execution_context(), + ), + Vc::cell("instrumentation".to_string()), + )) + } + + #[turbo_tasks::function] + fn instrumentation_endpoint( + self: Vc, + source: Vc>, + is_edge: bool, + ) -> Vc { + let context = if is_edge { + self.middleware_context() + } else { + self.node_instrumentation_context() + }; + + let module = context.process( + source, + Value::new(ReferenceType::Entry(EntryReferenceSubType::Undefined)), + ); + + InstrumentationEndpoint::new(self, context, module, is_edge) + } + #[turbo_tasks::function] pub async fn emit_all_output_assets( self: Vc, diff --git a/packages/next-swc/crates/next-api/src/route.rs b/packages/next-swc/crates/next-api/src/route.rs index c313f90fffd4e..8dd78f029c749 100644 --- a/packages/next-swc/crates/next-api/src/route.rs +++ b/packages/next-swc/crates/next-api/src/route.rs @@ -39,9 +39,6 @@ pub enum WrittenEndpoint { server_paths: Vec, }, Edge { - /// Relative to the root_path - files: Vec, - global_var_name: String, server_paths: Vec, }, } diff --git a/packages/next-swc/crates/next-core/src/instrumentation.rs b/packages/next-swc/crates/next-core/src/instrumentation.rs new file mode 100644 index 0000000000000..21df0efcec2e3 --- /dev/null +++ b/packages/next-swc/crates/next-core/src/instrumentation.rs @@ -0,0 +1,16 @@ +use anyhow::Result; +use turbo_tasks::Vc; + +#[turbo_tasks::function] +pub async fn instrumentation_files(page_extensions: Vc>) -> Result>> { + let extensions = page_extensions.await?; + let files = ["instrumentation.", "src/instrumentation."] + .into_iter() + .flat_map(|f| { + extensions + .iter() + .map(move |ext| String::from(f) + ext.as_str()) + }) + .collect(); + Ok(Vc::cell(files)) +} diff --git a/packages/next-swc/crates/next-core/src/lib.rs b/packages/next-swc/crates/next-core/src/lib.rs index 1eff791f9a41b..b789484cef712 100644 --- a/packages/next-swc/crates/next-core/src/lib.rs +++ b/packages/next-swc/crates/next-core/src/lib.rs @@ -11,6 +11,7 @@ mod babel; mod bootstrap; mod embed_js; mod emit; +pub mod instrumentation; mod loader_tree; pub mod middleware; pub mod mode; diff --git a/packages/next-swc/crates/next-core/src/next_edge/context.rs b/packages/next-swc/crates/next-core/src/next_edge/context.rs index 3566acf915ae6..f0c58bbdad633 100644 --- a/packages/next-swc/crates/next-core/src/next_edge/context.rs +++ b/packages/next-swc/crates/next-core/src/next_edge/context.rs @@ -117,7 +117,8 @@ pub async fn get_edge_resolve_options_context( | ServerContextType::PagesData { .. } | ServerContextType::PagesApi { .. } | ServerContextType::AppSSR { .. } - | ServerContextType::Middleware { .. } => {} + | ServerContextType::Middleware { .. } + | ServerContextType::Instrumentation { .. } => {} }; let resolve_options_context = ResolveOptionsContext { diff --git a/packages/next-swc/crates/next-core/src/next_import_map.rs b/packages/next-swc/crates/next-core/src/next_import_map.rs index 031fbd8cb0fbc..34c14a3131cde 100644 --- a/packages/next-swc/crates/next-core/src/next_import_map.rs +++ b/packages/next-swc/crates/next-core/src/next_import_map.rs @@ -318,7 +318,7 @@ pub async fn get_next_server_import_map( request_to_import_mapping(project_path, "next/dist/shared/lib/app-dynamic"), ); } - ServerContextType::Middleware => {} + ServerContextType::Middleware | ServerContextType::Instrumentation => {} } insert_next_server_special_aliases( @@ -428,7 +428,7 @@ pub async fn get_next_edge_import_map( request_to_import_mapping(project_path, "next/dist/shared/lib/app-dynamic"), ); } - ServerContextType::Middleware => {} + ServerContextType::Middleware | ServerContextType::Instrumentation => {} } insert_next_server_special_aliases( @@ -562,7 +562,7 @@ async fn insert_next_server_special_aliases( rsc_aliases(import_map, project_path, ty, runtime, next_config).await?; } - ServerContextType::Middleware => {} + ServerContextType::Middleware | ServerContextType::Instrumentation => {} } // see https://github.com/vercel/next.js/blob/8013ef7372fc545d49dbd060461224ceb563b454/packages/next/src/build/webpack-config.ts#L1449-L1531 @@ -584,7 +584,8 @@ async fn insert_next_server_special_aliases( // TODO: should include `ServerContextType::PagesApi` routes, but that type doesn't exist. ServerContextType::AppRSC { .. } | ServerContextType::AppRoute { .. } - | ServerContextType::Middleware => { + | ServerContextType::Middleware + | ServerContextType::Instrumentation => { insert_exact_alias_map( import_map, project_path, diff --git a/packages/next-swc/crates/next-core/src/next_manifests/mod.rs b/packages/next-swc/crates/next-core/src/next_manifests/mod.rs index b6f727de4ccd0..5f9e5e2447305 100644 --- a/packages/next-swc/crates/next-core/src/next_manifests/mod.rs +++ b/packages/next-swc/crates/next-core/src/next_manifests/mod.rs @@ -29,6 +29,7 @@ pub struct BuildManifest { #[derive(Serialize, Debug)] #[serde(rename_all = "camelCase", tag = "version")] +#[allow(clippy::large_enum_variant)] pub enum MiddlewaresManifest { #[serde(rename = "2")] MiddlewaresManifestV2(MiddlewaresManifestV2), @@ -100,6 +101,18 @@ pub struct EdgeFunctionDefinition { pub regions: Option, } +#[derive(Serialize, Default, Debug)] +pub struct InstrumentationDefinition { + pub files: Vec, + pub name: String, + // TODO: AssetBinding[] + #[serde(skip_serializing_if = "Option::is_none")] + pub wasm: Option>, + // TODO: AssetBinding[] + #[serde(skip_serializing_if = "Option::is_none")] + pub assets: Option>, +} + #[derive(Serialize, Debug)] #[serde(untagged)] pub enum Regions { @@ -111,6 +124,7 @@ pub enum Regions { pub struct MiddlewaresManifestV2 { pub sorted_middleware: Vec, pub middleware: HashMap, + pub instrumentation: Option, pub functions: HashMap, } diff --git a/packages/next-swc/crates/next-core/src/next_server/context.rs b/packages/next-swc/crates/next-core/src/next_server/context.rs index 02e3adbb12edd..41efaa11ecba1 100644 --- a/packages/next-swc/crates/next-core/src/next_server/context.rs +++ b/packages/next-swc/crates/next-core/src/next_server/context.rs @@ -90,6 +90,7 @@ pub enum ServerContextType { app_dir: Vc, }, Middleware, + Instrumentation, } #[turbo_tasks::function] @@ -140,7 +141,8 @@ pub async fn get_server_resolve_options_context( | ServerContextType::PagesData { .. } | ServerContextType::PagesApi { .. } | ServerContextType::AppSSR { .. } - | ServerContextType::Middleware { .. } => {} + | ServerContextType::Middleware { .. } + | ServerContextType::Instrumentation { .. } => {} }; let external_cjs_modules_plugin = ExternalCjsModulesResolvePlugin::new( project_path, @@ -168,8 +170,7 @@ pub async fn get_server_resolve_options_context( } ServerContextType::AppSSR { .. } | ServerContextType::AppRSC { .. } - | ServerContextType::AppRoute { .. } - | ServerContextType::Middleware { .. } => { + | ServerContextType::AppRoute { .. } => { vec![ Vc::upcast(module_feature_report_resolve_plugin), Vc::upcast(server_component_externals_plugin), @@ -178,6 +179,21 @@ pub async fn get_server_resolve_options_context( Vc::upcast(next_node_shared_runtime_plugin), ] } + ServerContextType::Middleware { .. } => { + vec![ + Vc::upcast(module_feature_report_resolve_plugin), + Vc::upcast(unsupported_modules_resolve_plugin), + Vc::upcast(next_node_shared_runtime_plugin), + ] + } + ServerContextType::Instrumentation { .. } => { + vec![ + Vc::upcast(module_feature_report_resolve_plugin), + Vc::upcast(unsupported_modules_resolve_plugin), + Vc::upcast(next_external_plugin), + Vc::upcast(next_node_shared_runtime_plugin), + ] + } }; let resolve_options_context = ResolveOptionsContext { enable_node_modules: Some(root_dir), @@ -594,7 +610,7 @@ pub async fn get_server_module_options_context( ..module_options_context } } - ServerContextType::Middleware => { + ServerContextType::Middleware | ServerContextType::Instrumentation => { let mut base_source_transforms: Vec> = vec![ styled_components_transform_plugin, styled_jsx_transform_plugin, diff --git a/packages/next-swc/crates/next-core/src/next_server/transforms.rs b/packages/next-swc/crates/next-core/src/next_server/transforms.rs index 61e48d91c6851..019b8366b1a38 100644 --- a/packages/next-swc/crates/next-core/src/next_server/transforms.rs +++ b/packages/next-swc/crates/next-core/src/next_server/transforms.rs @@ -68,7 +68,9 @@ pub async fn get_next_server_transforms_rules( (true, None) } ServerContextType::AppRoute { .. } => (false, None), - ServerContextType::Middleware { .. } => (false, None), + ServerContextType::Middleware { .. } | ServerContextType::Instrumentation { .. } => { + (false, None) + } }; rules.push( @@ -112,6 +114,7 @@ pub async fn get_next_server_internal_transforms_rules( } ServerContextType::AppRoute { .. } => {} ServerContextType::Middleware { .. } => {} + ServerContextType::Instrumentation { .. } => {} }; Ok(rules) diff --git a/packages/next/src/build/swc/index.ts b/packages/next/src/build/swc/index.ts index 225a0e9a4107c..116ca37b277da 100644 --- a/packages/next/src/build/swc/index.ts +++ b/packages/next/src/build/swc/index.ts @@ -531,9 +531,15 @@ export interface Middleware { endpoint: Endpoint } +export interface Instrumentation { + nodeJs: Endpoint + edge: Endpoint +} + export interface Entrypoints { routes: Map middleware?: Middleware + instrumentation?: Instrumentation pagesDocumentEndpoint: Endpoint pagesAppEndpoint: Endpoint pagesErrorEndpoint: Endpoint @@ -648,10 +654,8 @@ export type WrittenEndpoint = } | { type: 'edge' - files: string[] /** All server paths that has been written for the endpoint. */ serverPaths: ServerPath[] - globalVarName: string config: EndpointConfig } @@ -797,6 +801,7 @@ function bindingToApi(binding: any, _wasm: boolean) { type NapiEntrypoints = { routes: NapiRoute[] middleware?: NapiMiddleware + instrumentation?: NapiInstrumentation pagesDocumentEndpoint: NapiEndpoint pagesAppEndpoint: NapiEndpoint pagesErrorEndpoint: NapiEndpoint @@ -808,6 +813,11 @@ function bindingToApi(binding: any, _wasm: boolean) { matcher?: string[] } + type NapiInstrumentation = { + nodeJs: NapiEndpoint + edge: NapiEndpoint + } + type NapiRoute = { pathname: string } & ( @@ -894,9 +904,19 @@ function bindingToApi(binding: any, _wasm: boolean) { const middleware = entrypoints.middleware ? napiMiddlewareToMiddleware(entrypoints.middleware) : undefined + const napiInstrumentationToInstrumentation = ( + instrumentation: NapiInstrumentation + ) => ({ + nodeJs: new EndpointImpl(instrumentation.nodeJs), + edge: new EndpointImpl(instrumentation.edge), + }) + const instrumentation = entrypoints.instrumentation + ? napiInstrumentationToInstrumentation(entrypoints.instrumentation) + : undefined yield { routes, middleware, + instrumentation, pagesDocumentEndpoint: new EndpointImpl( entrypoints.pagesDocumentEndpoint ), diff --git a/packages/next/src/lib/turbopack-warning.ts b/packages/next/src/lib/turbopack-warning.ts index aff0d1d2ce7f5..70290ee3a4dd7 100644 --- a/packages/next/src/lib/turbopack-warning.ts +++ b/packages/next/src/lib/turbopack-warning.ts @@ -68,6 +68,7 @@ const supportedTurbopackNextConfigOptions = [ 'experimental.deploymentId', 'experimental.useLightningcss', 'experimental.windowHistorySupport', + 'experimental.instrumentationHook', // Experimental options that don't affect compilation 'experimental.ppr', @@ -106,7 +107,6 @@ const supportedTurbopackNextConfigOptions = [ // 'compiler.removeConsole', // 'compiler.styledComponents', // 'experimental.fetchCacheKeyPrefix', - // 'experimental.instrumentationHook', // Left to be implemented 'excludeDefaultMomentLocales', diff --git a/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts b/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts index 1a0a5aca5fc9f..59d561927cee2 100644 --- a/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts +++ b/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts @@ -573,13 +573,18 @@ async function startWatcher(opts: SetupOpts) { async function loadPartialManifest( name: string, pageName: string, - type: 'pages' | 'app' | 'app-route' | 'middleware' = 'pages' + type: + | 'pages' + | 'app' + | 'app-route' + | 'middleware' + | 'instrumentation' = 'pages' ): Promise { const manifestPath = path.posix.join( distDir, `server`, type === 'app-route' ? 'app' : type, - type === 'middleware' + type === 'middleware' || type === 'instrumentation' ? '' : pageName === '/' ? 'index' @@ -594,11 +599,18 @@ async function startWatcher(opts: SetupOpts) { ) as T } + type TurbopackMiddlewareManifest = MiddlewareManifest & { + instrumentation?: { + files: string[] + name: 'instrumentation' + } + } + const buildManifests = new Map() const appBuildManifests = new Map() const pagesManifests = new Map() const appPathsManifests = new Map() - const middlewareManifests = new Map() + const middlewareManifests = new Map() const actionManifests = new Map() const clientToHmrSubscription = new Map< ws, @@ -609,7 +621,7 @@ async function startWatcher(opts: SetupOpts) { async function loadMiddlewareManifest( pageName: string, - type: 'pages' | 'app' | 'app-route' | 'middleware' + type: 'pages' | 'app' | 'app-route' | 'middleware' | 'instrumentation' ): Promise { middlewareManifests.set( pageName, @@ -751,7 +763,7 @@ async function startWatcher(opts: SetupOpts) { } function mergeMiddlewareManifests( - manifests: Iterable + manifests: Iterable ): MiddlewareManifest { const manifest: MiddlewareManifest = { version: 2, @@ -759,13 +771,20 @@ async function startWatcher(opts: SetupOpts) { sortedMiddleware: [], functions: {}, } + let instrumentation = undefined for (const m of manifests) { Object.assign(manifest.functions, m.functions) Object.assign(manifest.middleware, m.middleware) + if (m.instrumentation) { + instrumentation = m.instrumentation + } } for (const fun of Object.values(manifest.functions).concat( Object.values(manifest.middleware) )) { + if (instrumentation) { + fun.files.unshift(...instrumentation.files) + } for (const matcher of fun.matchers) { if (!matcher.regexp) { matcher.regexp = pathToRegexp(matcher.originalSource, [], { @@ -777,6 +796,7 @@ async function startWatcher(opts: SetupOpts) { } } manifest.sortedMiddleware = Object.keys(manifest.middleware) + return manifest } @@ -1091,7 +1111,7 @@ async function startWatcher(opts: SetupOpts) { } } - const { middleware } = entrypoints + const { middleware, instrumentation } = entrypoints // We check for explicit true/false, since it's initialized to // undefined during the first loop (middlewareChanges event is // unnecessary during the first serve) @@ -1107,6 +1127,43 @@ async function startWatcher(opts: SetupOpts) { event: HMR_ACTIONS_SENT_TO_BROWSER.MIDDLEWARE_CHANGES, }) } + if (instrumentation) { + const processInstrumentation = async ( + displayName: string, + name: string, + prop: 'nodeJs' | 'edge' + ) => { + const writtenEndpoint = await processResult( + displayName, + await instrumentation[prop].writeToDisk() + ) + processIssues(displayName, name, writtenEndpoint) + } + await processInstrumentation( + 'instrumentation (node.js)', + 'instrumentation.nodeJs', + 'nodeJs' + ) + await processInstrumentation( + 'instrumentation (edge)', + 'instrumentation.edge', + 'edge' + ) + await loadMiddlewareManifest('instrumentation', 'instrumentation') + NextBuildContext.hasInstrumentationHook = true + serverFields.actualInstrumentationHookFile = '/instrumentation' + await propagateServerField( + 'actualInstrumentationHookFile', + serverFields.actualInstrumentationHookFile + ) + } else { + NextBuildContext.hasInstrumentationHook = false + serverFields.actualInstrumentationHookFile = undefined + await propagateServerField( + 'actualInstrumentationHookFile', + serverFields.actualInstrumentationHookFile + ) + } if (middleware) { const processMiddleware = async () => { const writtenEndpoint = await processResult( @@ -1418,6 +1475,8 @@ async function startWatcher(opts: SetupOpts) { if (page === '/_document') return if (page === '/middleware') return if (page === '/src/middleware') return + if (page === '/instrumentation') return + if (page === '/src/instrumentation') return throw new PageNotFoundError(`route not found ${page}`) } diff --git a/test/e2e/instrumentation-hook-src/instrumentation-hook-src.test.ts b/test/e2e/instrumentation-hook-src/instrumentation-hook-src.test.ts index 80577132112e6..bc840d423a0a6 100644 --- a/test/e2e/instrumentation-hook-src/instrumentation-hook-src.test.ts +++ b/test/e2e/instrumentation-hook-src/instrumentation-hook-src.test.ts @@ -1,65 +1,62 @@ import { createNextDescribe } from 'e2e-utils' import { check } from 'next-test-utils' -;(process.env.TURBOPACK ? describe.skip : describe)( - 'instrumentation-hook-rsc', - () => { - createNextDescribe( - 'instrumentation', - { - files: __dirname, - nextConfig: { - experimental: { - instrumentationHook: true, - }, +describe('instrumentation-hook-rsc', () => { + createNextDescribe( + 'instrumentation', + { + files: __dirname, + nextConfig: { + experimental: { + instrumentationHook: true, }, - skipDeployment: true, }, - ({ next, isNextDev }) => { - it('should run the instrumentation hook', async () => { + skipDeployment: true, + }, + ({ next, isNextDev }) => { + it('should run the instrumentation hook', async () => { + await next.render('/') + await check(() => next.cliOutput, /instrumentation hook/) + }) + it('should not overlap with a instrumentation page', async () => { + const page = await next.render('/instrumentation') + expect(page).toContain('Hello') + }) + it('should run the edge instrumentation compiled version with the edge runtime', async () => { + await next.render('/edge') + await check(() => next.cliOutput, /instrumentation hook on the edge/) + }) + if (isNextDev) { + // TODO: Implement handling for changing the instrument file. + it.skip('should reload the server when the instrumentation hook changes', async () => { await next.render('/') - await check(() => next.cliOutput, /instrumentation hook/) + await next.patchFile( + './src/instrumentation.js', + `export function register() {console.log('toast')}` + ) + await check(() => next.cliOutput, /toast/) + await next.renameFile( + './src/instrumentation.js', + './src/instrumentation.js.bak' + ) + await check( + () => next.cliOutput, + /The instrumentation file has been removed/ + ) + await next.patchFile( + './src/instrumentation.js.bak', + `export function register() {console.log('bread')}` + ) + await next.renameFile( + './src/instrumentation.js.bak', + './src/instrumentation.js' + ) + await check( + () => next.cliOutput, + /The instrumentation file was added/ + ) + await check(() => next.cliOutput, /bread/) }) - it('should not overlap with a instrumentation page', async () => { - const page = await next.render('/instrumentation') - expect(page).toContain('Hello') - }) - it('should run the edge instrumentation compiled version with the edge runtime', async () => { - await next.render('/edge') - await check(() => next.cliOutput, /instrumentation hook on the edge/) - }) - if (isNextDev) { - // TODO: Implement handling for changing the instrument file. - it.skip('should reload the server when the instrumentation hook changes', async () => { - await next.render('/') - await next.patchFile( - './src/instrumentation.js', - `export function register() {console.log('toast')}` - ) - await check(() => next.cliOutput, /toast/) - await next.renameFile( - './src/instrumentation.js', - './src/instrumentation.js.bak' - ) - await check( - () => next.cliOutput, - /The instrumentation file has been removed/ - ) - await next.patchFile( - './src/instrumentation.js.bak', - `export function register() {console.log('bread')}` - ) - await next.renameFile( - './src/instrumentation.js.bak', - './src/instrumentation.js' - ) - await check( - () => next.cliOutput, - /The instrumentation file was added/ - ) - await check(() => next.cliOutput, /bread/) - }) - } } - ) - } -) + } + ) +}) diff --git a/test/e2e/instrumentation-hook/instrumentation-hook.test.ts b/test/e2e/instrumentation-hook/instrumentation-hook.test.ts index 7e83ce4dd1512..a4fafd0424bb0 100644 --- a/test/e2e/instrumentation-hook/instrumentation-hook.test.ts +++ b/test/e2e/instrumentation-hook/instrumentation-hook.test.ts @@ -20,123 +20,117 @@ const describeCase = ( callback ) } -;(process.env.TURBOPACK ? describe.skip : describe)( - 'Instrumentation Hook', - () => { - // TODO: investigate the failure with esm import - // createNextDescribe( - // 'with-esm-import', - // { - // files: path.join(__dirname, 'with-esm-import'), - // nextConfig: { - // experimental: { - // instrumentationHook: true, - // }, - // }, - // dependencies: { - // // This test is mostly for compatibility with this package - // '@vercel/otel': 'latest', - // }, - // skipDeployment: true, - // }, - // ({ next }) => { - // eslint-disable-next-line jest/no-commented-out-tests - // it('with-esm-import should run the instrumentation hook', async () => { - // await next.render('/') - // await check( - // () => next.cliOutput, - // /register in instrumentation\.js is running/ - // ) - // }) - // } - // ) +describe('Instrumentation Hook', () => { + // TODO: investigate the failure with esm import + // createNextDescribe( + // 'with-esm-import', + // { + // files: path.join(__dirname, 'with-esm-import'), + // nextConfig: { + // experimental: { + // instrumentationHook: true, + // }, + // }, + // dependencies: { + // // This test is mostly for compatibility with this package + // '@vercel/otel': 'latest', + // }, + // skipDeployment: true, + // }, + // ({ next }) => { + // eslint-disable-next-line jest/no-commented-out-tests + // it('with-esm-import should run the instrumentation hook', async () => { + // await next.render('/') + // await check( + // () => next.cliOutput, + // /register in instrumentation\.js is running/ + // ) + // }) + // } + // ) - describeCase('with-middleware', ({ next }) => { - it('with-middleware should run the instrumentation hook', async () => { - await next.render('/') - await check(() => next.cliOutput, /instrumentation hook on the edge/) - }) + describeCase('with-middleware', ({ next }) => { + it('with-middleware should run the instrumentation hook', async () => { + await next.render('/') + await check(() => next.cliOutput, /instrumentation hook on the edge/) }) + }) - describeCase('with-edge-api', ({ next }) => { - it('with-edge-api should run the instrumentation hook', async () => { - await next.render('/api') - await check(() => next.cliOutput, /instrumentation hook on the edge/) - }) + describeCase('with-edge-api', ({ next }) => { + it('with-edge-api should run the instrumentation hook', async () => { + await next.render('/api') + await check(() => next.cliOutput, /instrumentation hook on the edge/) }) + }) - describeCase('with-edge-page', ({ next }) => { - it('with-edge-page should run the instrumentation hook', async () => { - await next.render('/') - await check(() => next.cliOutput, /instrumentation hook on the edge/) - }) + describeCase('with-edge-page', ({ next }) => { + it('with-edge-page should run the instrumentation hook', async () => { + await next.render('/') + await check(() => next.cliOutput, /instrumentation hook on the edge/) }) + }) - describeCase('with-node-api', ({ next }) => { - it('with-node-api should run the instrumentation hook', async () => { - await next.render('/api') - await check(() => next.cliOutput, /instrumentation hook on nodejs/) - }) + describeCase('with-node-api', ({ next }) => { + it('with-node-api should run the instrumentation hook', async () => { + await next.render('/api') + await check(() => next.cliOutput, /instrumentation hook on nodejs/) }) + }) - describeCase('with-node-page', ({ next }) => { - it('with-node-page should run the instrumentation hook', async () => { - await next.render('/') - await check(() => next.cliOutput, /instrumentation hook on nodejs/) - }) + describeCase('with-node-page', ({ next }) => { + it('with-node-page should run the instrumentation hook', async () => { + await next.render('/') + await check(() => next.cliOutput, /instrumentation hook on nodejs/) }) + }) - describeCase('with-async-node-page', ({ next }) => { - it('with-async-node-page should run the instrumentation hook', async () => { - const page = await next.render('/') - expect(page).toContain('Node - finished: true') - }) + describeCase('with-async-node-page', ({ next }) => { + it('with-async-node-page should run the instrumentation hook', async () => { + const page = await next.render('/') + expect(page).toContain('Node - finished: true') }) + }) - describeCase('with-async-edge-page', ({ next }) => { - it('with-async-edge-page should run the instrumentation hook', async () => { - const page = await next.render('/') - expect(page).toContain('Edge - finished: true') - }) + describeCase('with-async-edge-page', ({ next }) => { + it('with-async-edge-page should run the instrumentation hook', async () => { + const page = await next.render('/') + expect(page).toContain('Edge - finished: true') }) + }) - describeCase('general', ({ next, isNextDev }) => { - it('should not overlap with a instrumentation page', async () => { - const page = await next.render('/instrumentation') - expect(page).toContain('Hello') - }) - if (isNextDev) { - // TODO: Implement handling for changing the instrument file. - it.skip('should reload the server when the instrumentation hook changes', async () => { - await next.render('/') - await next.patchFile( - './instrumentation.js', - `export function register() {console.log('toast')}` - ) - await check(() => next.cliOutput, /toast/) - await next.renameFile( - './instrumentation.js', - './instrumentation.js.bak' - ) - await check( - () => next.cliOutput, - /The instrumentation file has been removed/ - ) - await next.patchFile( - './instrumentation.js.bak', - `export function register() {console.log('bread')}` - ) - await next.renameFile( - './instrumentation.js.bak', - './instrumentation.js' - ) - await check( - () => next.cliOutput, - /The instrumentation file was added/ - ) - await check(() => next.cliOutput, /bread/) - }) - } + describeCase('general', ({ next, isNextDev }) => { + it('should not overlap with a instrumentation page', async () => { + const page = await next.render('/instrumentation') + expect(page).toContain('Hello') }) - } -) + if (isNextDev) { + // TODO: Implement handling for changing the instrument file. + it.skip('should reload the server when the instrumentation hook changes', async () => { + await next.render('/') + await next.patchFile( + './instrumentation.js', + `export function register() {console.log('toast')}` + ) + await check(() => next.cliOutput, /toast/) + await next.renameFile( + './instrumentation.js', + './instrumentation.js.bak' + ) + await check( + () => next.cliOutput, + /The instrumentation file has been removed/ + ) + await next.patchFile( + './instrumentation.js.bak', + `export function register() {console.log('bread')}` + ) + await next.renameFile( + './instrumentation.js.bak', + './instrumentation.js' + ) + await check(() => next.cliOutput, /The instrumentation file was added/) + await check(() => next.cliOutput, /bread/) + }) + } + }) +}) From e8c0273677bade4801ab6229a013f146e3e209f0 Mon Sep 17 00:00:00 2001 From: Zack Tanner Date: Wed, 29 Nov 2023 11:34:01 -0800 Subject: [PATCH 095/481] add full PPR e2e tests (#59025) This copies over the E2E tests that were added to `vercel/vercel` in https://github.com/vercel/vercel/pull/10808 and https://github.com/vercel/vercel/pull/10823, with some minor adjustments to reflect the differences in cache behavior between start & deploy. --- .../app/dynamic/force-dynamic/page.jsx | 16 ++ .../app/dynamic/force-static/page.jsx | 15 ++ test/e2e/app-dir/ppr-full/app/layout.jsx | 19 +++ .../ppr-full/app/loading/[slug]/page.jsx | 16 ++ .../app-dir/ppr-full/app/loading/loading.jsx | 3 + .../ppr-full/app/nested/[slug]/page.jsx | 16 ++ .../app/no-suspense/nested/[slug]/page.jsx | 10 ++ .../app-dir/ppr-full/app/no-suspense/page.jsx | 6 + .../ppr-full/app/on-demand/[slug]/page.jsx | 10 ++ test/e2e/app-dir/ppr-full/app/page.jsx | 10 ++ test/e2e/app-dir/ppr-full/app/static/page.jsx | 6 + .../app-dir/ppr-full/components/dynamic.jsx | 37 +++++ .../e2e/app-dir/ppr-full/components/links.jsx | 42 +++++ test/e2e/app-dir/ppr-full/next.config.js | 8 + test/e2e/app-dir/ppr-full/ppr-full.test.ts | 145 ++++++++++++++++++ test/e2e/app-dir/ppr/ppr.test.ts | 1 - 16 files changed, 359 insertions(+), 1 deletion(-) create mode 100644 test/e2e/app-dir/ppr-full/app/dynamic/force-dynamic/page.jsx create mode 100644 test/e2e/app-dir/ppr-full/app/dynamic/force-static/page.jsx create mode 100644 test/e2e/app-dir/ppr-full/app/layout.jsx create mode 100644 test/e2e/app-dir/ppr-full/app/loading/[slug]/page.jsx create mode 100644 test/e2e/app-dir/ppr-full/app/loading/loading.jsx create mode 100644 test/e2e/app-dir/ppr-full/app/nested/[slug]/page.jsx create mode 100644 test/e2e/app-dir/ppr-full/app/no-suspense/nested/[slug]/page.jsx create mode 100644 test/e2e/app-dir/ppr-full/app/no-suspense/page.jsx create mode 100644 test/e2e/app-dir/ppr-full/app/on-demand/[slug]/page.jsx create mode 100644 test/e2e/app-dir/ppr-full/app/page.jsx create mode 100644 test/e2e/app-dir/ppr-full/app/static/page.jsx create mode 100644 test/e2e/app-dir/ppr-full/components/dynamic.jsx create mode 100644 test/e2e/app-dir/ppr-full/components/links.jsx create mode 100644 test/e2e/app-dir/ppr-full/next.config.js create mode 100644 test/e2e/app-dir/ppr-full/ppr-full.test.ts diff --git a/test/e2e/app-dir/ppr-full/app/dynamic/force-dynamic/page.jsx b/test/e2e/app-dir/ppr-full/app/dynamic/force-dynamic/page.jsx new file mode 100644 index 0000000000000..97c8772e3bef9 --- /dev/null +++ b/test/e2e/app-dir/ppr-full/app/dynamic/force-dynamic/page.jsx @@ -0,0 +1,16 @@ +import React, { Suspense } from 'react' +import { Dynamic } from '../../../components/dynamic' + +export const dynamic = 'force-dynamic' + +export default ({ params: { slug } }) => { + return ( + + } + > + + + ) +} diff --git a/test/e2e/app-dir/ppr-full/app/dynamic/force-static/page.jsx b/test/e2e/app-dir/ppr-full/app/dynamic/force-static/page.jsx new file mode 100644 index 0000000000000..195abf0da924c --- /dev/null +++ b/test/e2e/app-dir/ppr-full/app/dynamic/force-static/page.jsx @@ -0,0 +1,15 @@ +import React, { Suspense } from 'react' +import { Dynamic } from '../../../components/dynamic' + +export const dynamic = 'force-static' +export const revalidate = 60 + +export default ({ params: { slug } }) => { + return ( + } + > + + + ) +} diff --git a/test/e2e/app-dir/ppr-full/app/layout.jsx b/test/e2e/app-dir/ppr-full/app/layout.jsx new file mode 100644 index 0000000000000..a9a05c18834d6 --- /dev/null +++ b/test/e2e/app-dir/ppr-full/app/layout.jsx @@ -0,0 +1,19 @@ +import { Links } from '../components/links' + +export default ({ children }) => { + return ( + + +

Partial Prerendering

+

+ Below are links that are associated with different pages that all will + partially prerender +

+ +
{children}
+ + + ) +} diff --git a/test/e2e/app-dir/ppr-full/app/loading/[slug]/page.jsx b/test/e2e/app-dir/ppr-full/app/loading/[slug]/page.jsx new file mode 100644 index 0000000000000..027d39da1c2b6 --- /dev/null +++ b/test/e2e/app-dir/ppr-full/app/loading/[slug]/page.jsx @@ -0,0 +1,16 @@ +import React, { Suspense } from 'react' +import { Dynamic } from '../../../components/dynamic' + +export const revalidate = 60 + +export default ({ params: { slug } }) => { + return ( + }> + + + ) +} + +export const generateStaticParams = async () => { + return [{ slug: 'a' }] +} diff --git a/test/e2e/app-dir/ppr-full/app/loading/loading.jsx b/test/e2e/app-dir/ppr-full/app/loading/loading.jsx new file mode 100644 index 0000000000000..d3dcfed2a403a --- /dev/null +++ b/test/e2e/app-dir/ppr-full/app/loading/loading.jsx @@ -0,0 +1,3 @@ +export default () => { + return loading.jsx +} diff --git a/test/e2e/app-dir/ppr-full/app/nested/[slug]/page.jsx b/test/e2e/app-dir/ppr-full/app/nested/[slug]/page.jsx new file mode 100644 index 0000000000000..fec0c0923d427 --- /dev/null +++ b/test/e2e/app-dir/ppr-full/app/nested/[slug]/page.jsx @@ -0,0 +1,16 @@ +import React, { Suspense } from 'react' +import { Dynamic } from '../../../components/dynamic' + +export const revalidate = 60 + +export default ({ params: { slug } }) => { + return ( + }> + + + ) +} + +export const generateStaticParams = async () => { + return [{ slug: 'a' }] +} diff --git a/test/e2e/app-dir/ppr-full/app/no-suspense/nested/[slug]/page.jsx b/test/e2e/app-dir/ppr-full/app/no-suspense/nested/[slug]/page.jsx new file mode 100644 index 0000000000000..d7f48f3a26137 --- /dev/null +++ b/test/e2e/app-dir/ppr-full/app/no-suspense/nested/[slug]/page.jsx @@ -0,0 +1,10 @@ +import React from 'react' +import { Dynamic } from '../../../../components/dynamic' + +export default ({ params: { slug } }) => { + return +} + +export const generateStaticParams = async () => { + return [{ slug: 'a' }] +} diff --git a/test/e2e/app-dir/ppr-full/app/no-suspense/page.jsx b/test/e2e/app-dir/ppr-full/app/no-suspense/page.jsx new file mode 100644 index 0000000000000..ef2cf10a32aaa --- /dev/null +++ b/test/e2e/app-dir/ppr-full/app/no-suspense/page.jsx @@ -0,0 +1,6 @@ +import React from 'react' +import { Dynamic } from '../../components/dynamic' + +export default () => { + return +} diff --git a/test/e2e/app-dir/ppr-full/app/on-demand/[slug]/page.jsx b/test/e2e/app-dir/ppr-full/app/on-demand/[slug]/page.jsx new file mode 100644 index 0000000000000..289d8a9d63256 --- /dev/null +++ b/test/e2e/app-dir/ppr-full/app/on-demand/[slug]/page.jsx @@ -0,0 +1,10 @@ +import React, { Suspense } from 'react' +import { Dynamic } from '../../../components/dynamic' + +export default ({ params: { slug } }) => { + return ( + }> + + + ) +} diff --git a/test/e2e/app-dir/ppr-full/app/page.jsx b/test/e2e/app-dir/ppr-full/app/page.jsx new file mode 100644 index 0000000000000..1d5918209416d --- /dev/null +++ b/test/e2e/app-dir/ppr-full/app/page.jsx @@ -0,0 +1,10 @@ +import React, { Suspense } from 'react' +import { Dynamic } from '../components/dynamic' + +export default () => { + return ( + }> + + + ) +} diff --git a/test/e2e/app-dir/ppr-full/app/static/page.jsx b/test/e2e/app-dir/ppr-full/app/static/page.jsx new file mode 100644 index 0000000000000..f90cd84e78518 --- /dev/null +++ b/test/e2e/app-dir/ppr-full/app/static/page.jsx @@ -0,0 +1,6 @@ +import React from 'react' +import { Dynamic } from '../../components/dynamic' + +export default () => { + return +} diff --git a/test/e2e/app-dir/ppr-full/components/dynamic.jsx b/test/e2e/app-dir/ppr-full/components/dynamic.jsx new file mode 100644 index 0000000000000..0c931f8500f5e --- /dev/null +++ b/test/e2e/app-dir/ppr-full/components/dynamic.jsx @@ -0,0 +1,37 @@ +import React from 'react' +import { headers } from 'next/headers' + +export const Dynamic = ({ pathname, fallback }) => { + if (fallback) { + return
Loading...
+ } + + const messages = [] + const names = ['x-test-input', 'user-agent'] + const list = headers() + + for (const name of names) { + messages.push({ name, value: list.get(name) }) + } + + return ( +
+
+ {pathname && ( + <> +
Pathname
+
{pathname}
+ + )} + {messages.map(({ name, value }) => ( + +
+ Header: {name} +
+
{value ?? 'null'}
+
+ ))} +
+
+ ) +} diff --git a/test/e2e/app-dir/ppr-full/components/links.jsx b/test/e2e/app-dir/ppr-full/components/links.jsx new file mode 100644 index 0000000000000..645fcc8259542 --- /dev/null +++ b/test/e2e/app-dir/ppr-full/components/links.jsx @@ -0,0 +1,42 @@ +import React from 'react' +import Link from 'next/link' + +const links = [ + { href: '/', tag: 'pre-generated' }, + { href: '/nested/a', tag: 'pre-generated' }, + { href: '/nested/b', tag: 'on-demand' }, + { href: '/nested/c', tag: 'on-demand' }, + { href: '/on-demand/a', tag: 'on-demand, no-gsp' }, + { href: '/on-demand/b', tag: 'on-demand, no-gsp' }, + { href: '/on-demand/c', tag: 'on-demand, no-gsp' }, + { href: '/loading/a', tag: 'loading.jsx, pre-generated' }, + { href: '/loading/b', tag: 'loading.jsx, on-demand' }, + { href: '/loading/c', tag: 'loading.jsx, on-demand' }, + { href: '/static', tag: 'static' }, + { href: '/no-suspense', tag: 'no suspense' }, + { href: '/no-suspense/nested/a', tag: 'no suspense, pre-generated' }, + { href: '/no-suspense/nested/b', tag: 'no suspense, on-demand' }, + { href: '/no-suspense/nested/c', tag: 'no suspense, on-demand' }, + { href: '/dynamic/force-dynamic', tag: "dynamic = 'force-dynamic'" }, + { href: '/dynamic/force-static', tag: "dynamic = 'force-static'" }, + { href: '/edge/suspense', tag: 'edge, pre-generated' }, + { href: '/edge/suspense/a', tag: 'edge, pre-generated' }, + { href: '/edge/suspense/b', tag: 'edge, on-demand' }, + { href: '/edge/suspense/c', tag: 'edge, on-demand' }, + { href: '/edge/no-suspense', tag: 'edge, no suspense, pre-generated' }, + { href: '/edge/no-suspense/a', tag: 'edge, no suspense, pre-generated' }, + { href: '/edge/no-suspense/b', tag: 'edge, no suspense, on-demand' }, + { href: '/edge/no-suspense/c', tag: 'edge, no suspense, on-demand' }, +] + +export const Links = () => { + return ( +
    + {links.map(({ href, tag }) => ( +
  • + {href} {tag} +
  • + ))} +
+ ) +} diff --git a/test/e2e/app-dir/ppr-full/next.config.js b/test/e2e/app-dir/ppr-full/next.config.js new file mode 100644 index 0000000000000..49ab599c5039b --- /dev/null +++ b/test/e2e/app-dir/ppr-full/next.config.js @@ -0,0 +1,8 @@ +/** @type {import('next').NextConfig} */ +const nextConfig = { + experimental: { + ppr: true, + }, +} + +module.exports = nextConfig diff --git a/test/e2e/app-dir/ppr-full/ppr-full.test.ts b/test/e2e/app-dir/ppr-full/ppr-full.test.ts new file mode 100644 index 0000000000000..b9086bb2499eb --- /dev/null +++ b/test/e2e/app-dir/ppr-full/ppr-full.test.ts @@ -0,0 +1,145 @@ +import { createNextDescribe } from 'e2e-utils' + +const pages = [ + { pathname: '/', dynamic: true }, + { pathname: '/nested/a', dynamic: true, revalidate: 60 }, + { pathname: '/nested/b', dynamic: true, revalidate: 60 }, + { pathname: '/nested/c', dynamic: true, revalidate: 60 }, + { pathname: '/on-demand/a', dynamic: true }, + { pathname: '/on-demand/b', dynamic: true }, + { pathname: '/on-demand/c', dynamic: true }, + { pathname: '/loading/a', dynamic: true, revalidate: 60 }, + { pathname: '/loading/b', dynamic: true, revalidate: 60 }, + { pathname: '/loading/c', dynamic: true, revalidate: 60 }, + { pathname: '/static', dynamic: false }, + { pathname: '/no-suspense', dynamic: true }, + { pathname: '/no-suspense/nested/a', dynamic: true }, + { pathname: '/no-suspense/nested/b', dynamic: true }, + { pathname: '/no-suspense/nested/c', dynamic: true }, + // TODO: uncomment when we've fixed the 404 case for force-dynamic pages + // { pathname: '/dynamic/force-dynamic', dynamic: 'force-dynamic' }, + { + pathname: '/dynamic/force-static', + dynamic: 'force-static', + revalidate: 60, + }, +] + +createNextDescribe( + 'ppr-full', + { + files: __dirname, + }, + ({ next, isNextDev, isNextStart, isNextDeploy }) => { + describe('dynamic pages should resume', () => { + it.each(pages.filter((p) => p.dynamic === true))( + 'should resume $pathname', + async ({ pathname }) => { + const expected = `${Date.now()}:${Math.random()}` + const res = await next.fetch(pathname, { + headers: { 'X-Test-Input': expected }, + }) + expect(res.status).toEqual(200) + expect(res.headers.get('content-type')).toEqual( + 'text/html; charset=utf-8' + ) + const html = await res.text() + expect(html).toContain(expected) + expect(html).toContain('') + } + ) + }) + + if (!isNextDev) { + describe('prefetch RSC payloads should return', () => { + it.each(pages)( + 'should prefetch $pathname', + async ({ pathname, dynamic, revalidate }) => { + const unexpected = `${Date.now()}:${Math.random()}` + const res = await next.fetch(pathname, { + headers: { + RSC: '1', + 'Next-Router-Prefetch': '1', + 'X-Test-Input': unexpected, + }, + }) + expect(res.status).toEqual(200) + expect(res.headers.get('content-type')).toEqual('text/x-component') + + const cache = res.headers.get('cache-control') + + // cache header handling is different when in minimal mode + if (isNextDeploy) { + expect(cache).toContain('public') + expect(cache).toContain('must-revalidate') + } else { + expect(cache).toContain(`s-maxage=${revalidate || '31536000'}`) + expect(cache).toContain('stale-while-revalidate') + } + + // Expect that static RSC prefetches do not contain the dynamic text. + const text = await res.text() + expect(text).not.toContain(unexpected) + + if (dynamic === true) { + // The dynamic component will contain the text "needle" if it was + // rendered using dynamic content. + expect(text).not.toContain('needle') + expect(res.headers.get('X-NextJS-Postponed')).toEqual('1') + } else { + if (dynamic !== false) { + expect(text).toContain('needle') + } + + expect(res.headers.has('X-NextJS-Postponed')).toEqual(false) + } + } + ) + }) + + describe('dynamic RSC payloads should return', () => { + it.each(pages)( + 'should fetch $pathname', + async ({ pathname, dynamic }) => { + const expected = `${Date.now()}:${Math.random()}` + const res = await next.fetch(pathname, { + headers: { RSC: '1', 'X-Test-Input': expected }, + }) + expect(res.status).toEqual(200) + expect(res.headers.get('content-type')).toEqual('text/x-component') + expect(res.headers.has('X-NextJS-Postponed')).toEqual(false) + + const cache = res.headers.get('cache-control') + + // cache header handling is different when in minimal mode + if (isNextDeploy) { + expect(cache).toContain('private') + expect(cache).toContain('no-store') + expect(cache).toContain('no-cache') + expect(cache).toContain('max-age=0') + expect(cache).toContain('must-revalidate') + } else { + expect(cache).toContain('s-maxage=1') + expect(cache).toContain('stale-while-revalidate') + } + + const text = await res.text() + + if (dynamic !== false) { + expect(text).toContain('needle') + } + + if (dynamic === true) { + // Expect that dynamic RSC prefetches do contain the dynamic text. + expect(text).toContain(expected) + } else { + // Expect that dynamic RSC prefetches do not contain the dynamic text + // when we're forced static. + expect(text).not.toContain(expected) + } + } + ) + }) + } + } +) diff --git a/test/e2e/app-dir/ppr/ppr.test.ts b/test/e2e/app-dir/ppr/ppr.test.ts index 8d12a693716a4..51151ee03b6e5 100644 --- a/test/e2e/app-dir/ppr/ppr.test.ts +++ b/test/e2e/app-dir/ppr/ppr.test.ts @@ -5,7 +5,6 @@ createNextDescribe( 'ppr', { files: __dirname, - skipDeployment: true, }, ({ next, isNextDev, isNextStart }) => { it('should indicate the feature is experimental', async () => { From 77f8889b7ca6072f386d382d7ce65b57a5065ce2 Mon Sep 17 00:00:00 2001 From: Zack Tanner Date: Wed, 29 Nov 2023 11:45:06 -0800 Subject: [PATCH 096/481] use 303 status code for redirects in fetch actions (#59017) ### What? A `redirect` that occurs during a fetch action will get a status code of 200, while the redirection logic is handled client-side. ### Why? In this scenario, the redirect is handled by the client router, so no `Location` is set on the action response. However for debugging / logging purposes, it'd be useful to still return the same status code used in other cases (see #58885) ### How? Rather than selectively setting the status to 303 in the non-fetch action case, this always applies it. Closes NEXT-1745 --- .../next/src/server/app-render/action-handler.ts | 7 ++++--- test/e2e/app-dir/actions/app-action.test.ts | 13 ++++++++++++- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/packages/next/src/server/app-render/action-handler.ts b/packages/next/src/server/app-render/action-handler.ts index 11614419091fe..9fcf679dfae61 100644 --- a/packages/next/src/server/app-render/action-handler.ts +++ b/packages/next/src/server/app-render/action-handler.ts @@ -577,13 +577,15 @@ To configure the body size limit for Server Actions, see: https://nextjs.org/doc const redirectUrl = getURLFromRedirectError(err) const statusCode = getRedirectStatusCodeFromError(err) - // if it's a fetch action, we don't want to mess with the status code - // and we'll handle it on the client router await addRevalidationHeader(res, { staticGenerationStore, requestStore, }) + // if it's a fetch action, we'll set the status code for logging/debugging purposes + // but we won't set a Location header, as the redirect will be handled by the client router + res.statusCode = statusCode + if (isFetchAction) { return { type: 'done', @@ -607,7 +609,6 @@ To configure the body size limit for Server Actions, see: https://nextjs.org/doc } res.setHeader('Location', redirectUrl) - res.statusCode = statusCode return { type: 'done', result: RenderResult.fromStatic(''), diff --git a/test/e2e/app-dir/actions/app-action.test.ts b/test/e2e/app-dir/actions/app-action.test.ts index 5a3692a2b0266..77f287e91f8e9 100644 --- a/test/e2e/app-dir/actions/app-action.test.ts +++ b/test/e2e/app-dir/actions/app-action.test.ts @@ -592,7 +592,17 @@ createNextDescribe( }) it('should handle redirect to a relative URL in a single pass', async () => { - const browser = await next.browser('/client') + let responseCode: number + const browser = await next.browser('/client', { + beforePageLoad(page) { + page.on('response', async (res: Response) => { + const headers = await res.allHeaders() + if (headers['x-action-redirect']) { + responseCode = res.status() + } + }) + }, + }) await waitFor(3000) @@ -606,6 +616,7 @@ createNextDescribe( // no other requests should be made expect(requests).toEqual(['/client']) + await check(() => responseCode, 303) }) it('should handle regular redirects', async () => { From 8395059d3326d9dca089e6f0309fdb016ca7ace2 Mon Sep 17 00:00:00 2001 From: Zack Tanner Date: Wed, 29 Nov 2023 11:55:00 -0800 Subject: [PATCH 097/481] verify action id before parsing body (#58977) ### What? When handling a server action, in the non-progressive enhanced case, React will attempt to parse the request body before verifying if a valid server action is received. This results in an "Error: Connection Closed" error being thrown, rather than ignoring the action and failing more gracefully ### Why? To support progressive enhancement with form actions, the `actionId` value is added as a hidden input in the form, so the action ID from the header shouldn't be verified until determining that we've reached the non-PE case. ([React ref](https://github.com/facebook/react/pull/26774)). However, in https://github.com/vercel/next.js/pull/49187, support was added for a URL encoded form (which is not currently used, as indicated on the PR). Despite it not being used for server actions, it's currently possible to trigger this codepath, ie by calling redirect in an action handler with a 307/308 status code with some data in the URL. This would result in a 500 error. ### How? React should not attempt to parse the URL encoded form data until after we've verified the server action header for the non-PE case. x-ref NEXT-1733 [Slack context](https://vercel.slack.com/archives/C03S8ED1DKM/p1700674895218399?thread_ts=1700060786.749079&cid=C03S8ED1DKM) --- .../src/server/app-render/action-handler.ts | 89 +++++++++++++++---- test/e2e/app-dir/actions/app-action.test.ts | 68 ++++++++++++++ .../app/redirects/api-redirect-307/route.js | 6 ++ .../app/redirects/api-redirect-308/route.js | 6 ++ .../e2e/app-dir/actions/app/redirects/page.js | 8 ++ 5 files changed, 158 insertions(+), 19 deletions(-) create mode 100644 test/e2e/app-dir/actions/app/redirects/api-redirect-307/route.js create mode 100644 test/e2e/app-dir/actions/app/redirects/api-redirect-308/route.js diff --git a/packages/next/src/server/app-render/action-handler.ts b/packages/next/src/server/app-render/action-handler.ts index 9fcf679dfae61..c89751955d905 100644 --- a/packages/next/src/server/app-render/action-handler.ts +++ b/packages/next/src/server/app-render/action-handler.ts @@ -238,6 +238,16 @@ function limitUntrustedHeaderValueForLogs(value: string) { return value.length > 100 ? value.slice(0, 100) + '...' : value } +type ServerModuleMap = Record< + string, + | { + id: string + chunks: string[] + name: string + } + | undefined +> + export async function handleAction({ req, res, @@ -252,13 +262,7 @@ export async function handleAction({ req: IncomingMessage res: ServerResponse ComponentMod: AppPageModule - serverModuleMap: { - [id: string]: { - id: string - chunks: string[] - name: string - } - } + serverModuleMap: ServerModuleMap generateFlight: GenerateFlight staticGenerationStore: StaticGenerationStore requestStore: RequestStore @@ -392,6 +396,7 @@ export async function handleAction({ let actionResult: RenderResult | undefined let formState: any | undefined + let actionModId: string | undefined try { await actionAsyncStorage.run({ isAction: true }, async () => { @@ -418,6 +423,15 @@ export async function handleAction({ return } } else { + try { + actionModId = getActionModIdOrError(actionId, serverModuleMap) + } catch (err) { + console.error(err) + return { + type: 'not-found', + } + } + let actionData = '' const reader = webRequest.body.getReader() @@ -487,6 +501,15 @@ export async function handleAction({ return } } else { + try { + actionModId = getActionModIdOrError(actionId, serverModuleMap) + } catch (err) { + console.error(err) + return { + type: 'not-found', + } + } + const chunks = [] for await (const chunk of req) { @@ -528,19 +551,11 @@ To configure the body size limit for Server Actions, see: https://nextjs.org/doc // / -> fire action -> POST / -> appRender1 -> modId for the action file // /foo -> fire action -> POST /foo -> appRender2 -> modId for the action file - let actionModId: string try { - if (!actionId) { - throw new Error('Invariant: actionId should be set') - } - - actionModId = serverModuleMap[actionId].id + actionModId = + actionModId ?? getActionModIdOrError(actionId, serverModuleMap) } catch (err) { - // When this happens, it could be a deployment skew where the action came - // from a different deployment. We'll just return a 404 with a message logged. - console.error( - `Failed to find Server Action "${actionId}". This request might be from an older or newer deployment.` - ) + console.error(err) return { type: 'not-found', } @@ -548,7 +563,10 @@ To configure the body size limit for Server Actions, see: https://nextjs.org/doc const actionHandler = ( await ComponentMod.__next_app__.require(actionModId) - )[actionId] + )[ + // `actionId` must exist if we got here, as otherwise we would have thrown an error above + actionId! + ] const returnVal = await actionHandler.apply(null, bound) @@ -675,3 +693,36 @@ To configure the body size limit for Server Actions, see: https://nextjs.org/doc throw err } } + +/** + * Attempts to find the module ID for the action from the module map. When this fails, it could be a deployment skew where + * the action came from a different deployment. It could also simply be an invalid POST request that is not a server action. + * In either case, we'll throw an error to be handled by the caller. + */ +function getActionModIdOrError( + actionId: string | null, + serverModuleMap: ServerModuleMap +): string { + try { + // if we're missing the action ID header, we can't do any further processing + if (!actionId) { + throw new Error("Invariant: Missing 'next-action' header.") + } + + const actionModId = serverModuleMap?.[actionId]?.id + + if (!actionModId) { + throw new Error( + "Invariant: Couldn't find action module ID from module map." + ) + } + + return actionModId + } catch (err) { + throw new Error( + `Failed to find Server Action "${actionId}". This request might be from an older or newer deployment. ${ + err instanceof Error ? `Original error: ${err.message}` : '' + }` + ) + } +} diff --git a/test/e2e/app-dir/actions/app-action.test.ts b/test/e2e/app-dir/actions/app-action.test.ts index 77f287e91f8e9..7a002f2f3712c 100644 --- a/test/e2e/app-dir/actions/app-action.test.ts +++ b/test/e2e/app-dir/actions/app-action.test.ts @@ -409,6 +409,34 @@ createNextDescribe( ) }) + it('should 404 when POSTing an invalid server action', async () => { + const res = await next.fetch('/non-existent-route', { + method: 'POST', + headers: { + 'content-type': 'application/x-www-form-urlencoded', + }, + body: 'foo=bar', + }) + + expect(res.status).toBe(404) + }) + + it('should log a warning when a server action is not found but an id is provided', async () => { + await next.fetch('/server', { + method: 'POST', + headers: { + 'content-type': 'application/x-www-form-urlencoded', + 'next-action': 'abc123', + }, + body: 'foo=bar', + }) + + await check( + () => next.cliOutput, + /Failed to find Server Action "abc123". This request might be from an older or newer deployment./ + ) + }) + if (isNextStart) { it('should not expose action content in sourcemaps', async () => { const sourcemap = ( @@ -972,6 +1000,46 @@ createNextDescribe( expect(postRequests).toEqual(['/redirects/api-redirect-permanent']) expect(responseCodes).toEqual([303]) }) + + it.each(['307', '308'])( + `redirects properly when server action handler redirects with a %s status code`, + async (statusCode) => { + const postRequests = [] + const responseCodes = [] + + const browser = await next.browser('/redirects', { + beforePageLoad(page) { + page.on('request', (request: Request) => { + const url = new URL(request.url()) + if (request.method() === 'POST') { + postRequests.push(`${url.pathname}${url.search}`) + } + }) + + page.on('response', (response: Response) => { + const url = new URL(response.url()) + const status = response.status() + + if (postRequests.includes(`${url.pathname}${url.search}`)) { + responseCodes.push(status) + } + }) + }, + }) + + await browser.elementById(`submit-api-redirect-${statusCode}`).click() + await check(() => browser.url(), /success=true/) + expect(await browser.elementById('redirect-page')).toBeTruthy() + + // since a 307/308 status code follows the redirect, the POST request should be made to both the action handler and the redirect target + expect(postRequests).toEqual([ + `/redirects/api-redirect-${statusCode}`, + `/redirects?success=true`, + ]) + + expect(responseCodes).toEqual([Number(statusCode), 200]) + } + ) }) } ) diff --git a/test/e2e/app-dir/actions/app/redirects/api-redirect-307/route.js b/test/e2e/app-dir/actions/app/redirects/api-redirect-307/route.js new file mode 100644 index 0000000000000..c3b2be27f1c2c --- /dev/null +++ b/test/e2e/app-dir/actions/app/redirects/api-redirect-307/route.js @@ -0,0 +1,6 @@ +export function POST(request) { + return Response.redirect( + `${request.nextUrl.origin}/redirects?success=true`, + 307 + ) +} diff --git a/test/e2e/app-dir/actions/app/redirects/api-redirect-308/route.js b/test/e2e/app-dir/actions/app/redirects/api-redirect-308/route.js new file mode 100644 index 0000000000000..f273fe224e652 --- /dev/null +++ b/test/e2e/app-dir/actions/app/redirects/api-redirect-308/route.js @@ -0,0 +1,6 @@ +export function POST(request) { + return Response.redirect( + `${request.nextUrl.origin}/redirects?success=true`, + 308 + ) +} diff --git a/test/e2e/app-dir/actions/app/redirects/page.js b/test/e2e/app-dir/actions/app/redirects/page.js index 68afb2f2d2fb1..99a64701d630d 100644 --- a/test/e2e/app-dir/actions/app/redirects/page.js +++ b/test/e2e/app-dir/actions/app/redirects/page.js @@ -13,6 +13,14 @@ export default function Home() { id="submit-api-redirect-permanent" /> +

POST /api-reponse-redirect-307

+
+ +
+

POST /api-reponse-redirect-308

+
+ +
) } From 0345ee85f8d72e09de2220e8f890eaf3fd75ed94 Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Wed, 29 Nov 2023 20:00:26 +0000 Subject: [PATCH 098/481] v14.0.4-canary.27 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 16 ++++++++-------- 18 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lerna.json b/lerna.json index eafb20a6a3a87..9ec81f43fd4f3 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.26" + "version": "14.0.4-canary.27" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 4d2f23e9bd3f1..eec873fdd1d52 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.26", + "version": "14.0.4-canary.27", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 2937b5de1be82..d9f69fc9d8cc0 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.26", + "version": "14.0.4-canary.27", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.26", + "@next/eslint-plugin-next": "14.0.4-canary.27", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 9f847e2dcb45c..82fb9d7fd5d1a 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.26", + "version": "14.0.4-canary.27", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index d45e1ab992a05..51323878d19f9 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.26", + "version": "14.0.4-canary.27", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 307b4e4a454de..acb82b138bc41 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.26", + "version": "14.0.4-canary.27", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 13f0d642ba42e..b33d825572cd3 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.26", + "version": "14.0.4-canary.27", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index f4a5af6230ad6..82425948fda27 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.26", + "version": "14.0.4-canary.27", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 26df08c9bc798..9ac4e29677736 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.26", + "version": "14.0.4-canary.27", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 051c82573376b..06dfc4e8992a9 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.26", + "version": "14.0.4-canary.27", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index f9de50c1aff87..68ffac87ea513 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.26", + "version": "14.0.4-canary.27", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index a27e4ebb307fb..a883f8777add9 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.26", + "version": "14.0.4-canary.27", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index 541b9471936fc..806d5a7eefcc6 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.26", + "version": "14.0.4-canary.27", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index dd4d5aebc3f87..15ee51a69e6db 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.26", + "version": "14.0.4-canary.27", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.26", + "@next/env": "14.0.4-canary.27", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -147,11 +147,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.26", - "@next/polyfill-nomodule": "14.0.4-canary.26", - "@next/react-dev-overlay": "14.0.4-canary.26", - "@next/react-refresh-utils": "14.0.4-canary.26", - "@next/swc": "14.0.4-canary.26", + "@next/polyfill-module": "14.0.4-canary.27", + "@next/polyfill-nomodule": "14.0.4-canary.27", + "@next/react-dev-overlay": "14.0.4-canary.27", + "@next/react-refresh-utils": "14.0.4-canary.27", + "@next/swc": "14.0.4-canary.27", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index d4686b0639b56..f815e1d368e7d 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.26", + "version": "14.0.4-canary.27", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index d248bdac265b3..35e8a8e5977cb 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.26", + "version": "14.0.4-canary.27", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index 463fd4c9f725f..4ee5f72544075 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.26", + "version": "14.0.4-canary.27", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -23,7 +23,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.26", + "next": "14.0.4-canary.27", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ce979c1ac3d15..0d3081fbfc6db 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -741,7 +741,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.26 + specifier: 14.0.4-canary.27 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -806,7 +806,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.26 + specifier: 14.0.4-canary.27 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -933,19 +933,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.26 + specifier: 14.0.4-canary.27 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.26 + specifier: 14.0.4-canary.27 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.26 + specifier: 14.0.4-canary.27 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.26 + specifier: 14.0.4-canary.27 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.26 + specifier: 14.0.4-canary.27 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1599,7 +1599,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.26 + specifier: 14.0.4-canary.27 version: link:../next outdent: specifier: 0.8.0 From c1f94cfc7385d852b1d812ed0badf2a0ac4def93 Mon Sep 17 00:00:00 2001 From: Delba de Oliveira <32464864+delbaoliveira@users.noreply.github.com> Date: Wed, 29 Nov 2023 21:29:47 +0000 Subject: [PATCH 099/481] Docs: Delete fast refresh example (#59003) Closing: https://github.com/vercel/feedback/issues/47083 This example no longer exists in the Next.js repo. --- docs/04-architecture/fast-refresh.mdx | 7 ------- 1 file changed, 7 deletions(-) diff --git a/docs/04-architecture/fast-refresh.mdx b/docs/04-architecture/fast-refresh.mdx index 9a1f15702ee62..02ff4810aa941 100644 --- a/docs/04-architecture/fast-refresh.mdx +++ b/docs/04-architecture/fast-refresh.mdx @@ -3,13 +3,6 @@ title: Fast Refresh description: Fast Refresh is a hot module reloading experience that gives you instantaneous feedback on edits made to your React components. --- -
- Examples - -- [Fast Refresh Demo](https://github.com/vercel/next.js/tree/canary/examples/fast-refresh-demo) - -
- Fast Refresh is a Next.js feature that gives you instantaneous feedback on edits made to your React components. Fast Refresh is enabled by default in all Next.js applications on **9.4 or newer**. With Next.js Fast Refresh enabled, From 54544c90198f4839944fcaeed886a0d2d145a829 Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Wed, 29 Nov 2023 23:22:05 +0000 Subject: [PATCH 100/481] v14.0.4-canary.28 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 16 ++++++++-------- 18 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lerna.json b/lerna.json index 9ec81f43fd4f3..8273886632ca5 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.27" + "version": "14.0.4-canary.28" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index eec873fdd1d52..43bfd6c638c26 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.27", + "version": "14.0.4-canary.28", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index d9f69fc9d8cc0..5b6833a2f19e7 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.27", + "version": "14.0.4-canary.28", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.27", + "@next/eslint-plugin-next": "14.0.4-canary.28", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 82fb9d7fd5d1a..491e33ed3f5b8 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.27", + "version": "14.0.4-canary.28", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index 51323878d19f9..3bdcb4b9931ad 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.27", + "version": "14.0.4-canary.28", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index acb82b138bc41..16663e746f3cb 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.27", + "version": "14.0.4-canary.28", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index b33d825572cd3..fdf85f9a75812 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.27", + "version": "14.0.4-canary.28", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 82425948fda27..b393af8e0dadc 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.27", + "version": "14.0.4-canary.28", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 9ac4e29677736..c91d75144c59e 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.27", + "version": "14.0.4-canary.28", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 06dfc4e8992a9..9f834f812b0db 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.27", + "version": "14.0.4-canary.28", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index 68ffac87ea513..b153602bf8423 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.27", + "version": "14.0.4-canary.28", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index a883f8777add9..70cc83594274e 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.27", + "version": "14.0.4-canary.28", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index 806d5a7eefcc6..ff864cd1215ea 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.27", + "version": "14.0.4-canary.28", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index 15ee51a69e6db..2e2b949d755a1 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.27", + "version": "14.0.4-canary.28", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.27", + "@next/env": "14.0.4-canary.28", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -147,11 +147,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.27", - "@next/polyfill-nomodule": "14.0.4-canary.27", - "@next/react-dev-overlay": "14.0.4-canary.27", - "@next/react-refresh-utils": "14.0.4-canary.27", - "@next/swc": "14.0.4-canary.27", + "@next/polyfill-module": "14.0.4-canary.28", + "@next/polyfill-nomodule": "14.0.4-canary.28", + "@next/react-dev-overlay": "14.0.4-canary.28", + "@next/react-refresh-utils": "14.0.4-canary.28", + "@next/swc": "14.0.4-canary.28", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index f815e1d368e7d..80995b9c7458d 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.27", + "version": "14.0.4-canary.28", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index 35e8a8e5977cb..c9d8745071fb3 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.27", + "version": "14.0.4-canary.28", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index 4ee5f72544075..41e5febcdce60 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.27", + "version": "14.0.4-canary.28", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -23,7 +23,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.27", + "next": "14.0.4-canary.28", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0d3081fbfc6db..c066f462f8b52 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -741,7 +741,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.27 + specifier: 14.0.4-canary.28 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -806,7 +806,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.27 + specifier: 14.0.4-canary.28 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -933,19 +933,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.27 + specifier: 14.0.4-canary.28 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.27 + specifier: 14.0.4-canary.28 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.27 + specifier: 14.0.4-canary.28 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.27 + specifier: 14.0.4-canary.28 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.27 + specifier: 14.0.4-canary.28 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1599,7 +1599,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.27 + specifier: 14.0.4-canary.28 version: link:../next outdent: specifier: 0.8.0 From 92f7d0c5e9335f62a4fab6e20263439d27fd5b2b Mon Sep 17 00:00:00 2001 From: Luke Schlangen Date: Wed, 29 Nov 2023 18:54:44 -0600 Subject: [PATCH 101/481] examples: add direct link to Dockerfile (#58793) --- examples/with-docker/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/with-docker/README.md b/examples/with-docker/README.md index acfc0263f6011..12cb7cb60c5db 100644 --- a/examples/with-docker/README.md +++ b/examples/with-docker/README.md @@ -24,7 +24,7 @@ You can view your images created with `docker images`. ### In existing projects -To add support for Docker to an existing project, just copy the `Dockerfile` into the root of the project and add the following to the `next.config.js` file: +To add support for Docker to an existing project, just copy the [`Dockerfile`](https://github.com/vercel/next.js/blob/canary/examples/with-docker/Dockerfile) into the root of the project and add the following to the `next.config.js` file: ```js // next.config.js From d509c2d52894e23e89eaec136847a0a60cd26519 Mon Sep 17 00:00:00 2001 From: Dylan700 <54528768+Dylan700@users.noreply.github.com> Date: Thu, 30 Nov 2023 13:37:03 +1100 Subject: [PATCH 102/481] examples: Update Electron Typescript Example with Best Practices (#58947) Co-authored-by: Lee Robinson --- examples/with-electron-typescript/README.md | 4 +-- .../electron-src/index.ts | 2 +- .../electron-src/preload.ts | 25 +++++++++---------- .../with-electron-typescript/package.json | 16 ++++++------ .../renderer/interfaces/index.ts | 9 ++++--- .../renderer/pages/index.tsx | 8 +++--- .../renderer/tsconfig.json | 5 ++-- 7 files changed, 35 insertions(+), 34 deletions(-) diff --git a/examples/with-electron-typescript/README.md b/examples/with-electron-typescript/README.md index d4331039e6da8..26e7ae8197f27 100644 --- a/examples/with-electron-typescript/README.md +++ b/examples/with-electron-typescript/README.md @@ -1,6 +1,6 @@ # Electron with Typescript application example -This example show how you can use Next.js inside an Electron application to avoid a lot of configuration, use Next.js router as view and use server-render to speed up the initial render of the application. Both Next.js and Electron layers are written in TypeScript and compiled to JavaScript during the build process. +This example shows how to use Next.js inside an Electron application. To avoid a lot of configuration, we use Next.js as a router for pages, and use server rendering to speed up the initial render of the application. Both Next.js and Electron layers are written in TypeScript and compiled to JavaScript during the build process. | Part | Source code (Typescript) | Builds (JavaScript) | | ---------- | ------------------------ | ------------------- | @@ -8,7 +8,7 @@ This example show how you can use Next.js inside an Electron application to avoi | Electron | `/electron-src` | `/main` | | Production | | `/dist` | -For development it's going to run a HTTP server and let Next.js handle routing. In production it use `output: 'export'` to pre-generate HTML static files and use them in your app instead of running an HTTP server. +For development it's going to run a HTTP server and let Next.js handle routing. In production it will use `output: 'export'` to pre-generate HTML static files and use them in your app (instead of running a HTTP server). ## How to use diff --git a/examples/with-electron-typescript/electron-src/index.ts b/examples/with-electron-typescript/electron-src/index.ts index 424360a4f19fb..13a20750a0b2b 100644 --- a/examples/with-electron-typescript/electron-src/index.ts +++ b/examples/with-electron-typescript/electron-src/index.ts @@ -16,7 +16,7 @@ app.on('ready', async () => { height: 600, webPreferences: { nodeIntegration: false, - contextIsolation: false, + contextIsolation: true, preload: join(__dirname, 'preload.js'), }, }) diff --git a/examples/with-electron-typescript/electron-src/preload.ts b/examples/with-electron-typescript/electron-src/preload.ts index 607ed7667007b..926a9a75b96b5 100644 --- a/examples/with-electron-typescript/electron-src/preload.ts +++ b/examples/with-electron-typescript/electron-src/preload.ts @@ -1,17 +1,16 @@ /* eslint-disable @typescript-eslint/no-namespace */ // eslint-disable-next-line @typescript-eslint/no-unused-vars -import { ipcRenderer, IpcRenderer } from 'electron' +import { contextBridge, ipcRenderer } from 'electron' +import { IpcRendererEvent } from 'electron/main' -declare global { - namespace NodeJS { - interface Global { - ipcRenderer: IpcRenderer - } - } -} - -// Since we disabled nodeIntegration we can reintroduce -// needed node functionality here -process.once('loaded', () => { - global.ipcRenderer = ipcRenderer +// We are using the context bridge to securely expose NodeAPIs. +// Please note that many Node APIs grant access to local system resources. +// Be very cautious about which globals and APIs you expose to untrusted remote content. +contextBridge.exposeInMainWorld('electron', { + sayHello: () => ipcRenderer.send('message', 'hi from next'), + receiveHello: (handler: (event: IpcRendererEvent, ...args: any[]) => void) => + ipcRenderer.on('message', handler), + stopReceivingHello: ( + handler: (event: IpcRendererEvent, ...args: any[]) => void + ) => ipcRenderer.removeListener('message', handler), }) diff --git a/examples/with-electron-typescript/package.json b/examples/with-electron-typescript/package.json index e1f5f9f2dbf0e..1c147597c6391 100644 --- a/examples/with-electron-typescript/package.json +++ b/examples/with-electron-typescript/package.json @@ -13,20 +13,20 @@ "type-check": "tsc -p ./renderer/tsconfig.json && tsc -p ./electron-src/tsconfig.json" }, "dependencies": { - "electron-is-dev": "^1.1.0", + "electron-is-dev": "^1.2.0", "electron-next": "^3.1.5", "react": "^18.2.0", "react-dom": "^18.2.0" }, "devDependencies": { - "@types/node": "^14.14.6", - "@types/react": "^16.9.9", - "@types/react-dom": "^16.9.9", - "electron": "^13", - "electron-builder": "^23.0.3", + "@types/node": "^14.18.63", + "@types/react": "^16.14.52", + "@types/react-dom": "^16.9.24", + "electron": "^27.1.2", + "electron-builder": "^24.9.1", "next": "latest", - "rimraf": "^3.0.0", - "typescript": "^4.0.5" + "rimraf": "^3.0.2", + "typescript": "^4.9.5" }, "build": { "asar": true, diff --git a/examples/with-electron-typescript/renderer/interfaces/index.ts b/examples/with-electron-typescript/renderer/interfaces/index.ts index 76dd79475ba49..3179369fb109f 100644 --- a/examples/with-electron-typescript/renderer/interfaces/index.ts +++ b/examples/with-electron-typescript/renderer/interfaces/index.ts @@ -4,13 +4,14 @@ // // import User from 'path/to/interfaces'; // eslint-disable-next-line @typescript-eslint/no-unused-vars -import { IpcRenderer } from 'electron' declare global { // eslint-disable-next-line @typescript-eslint/no-namespace - namespace NodeJS { - interface Global { - ipcRenderer: IpcRenderer + interface Window { + electron: { + sayHello: () => void + receiveHello: (handler: (event, args) => void) => void + stopReceivingHello: (handler: (event, args) => void) => void } } } diff --git a/examples/with-electron-typescript/renderer/pages/index.tsx b/examples/with-electron-typescript/renderer/pages/index.tsx index 50324118de465..8b4303901d5ac 100644 --- a/examples/with-electron-typescript/renderer/pages/index.tsx +++ b/examples/with-electron-typescript/renderer/pages/index.tsx @@ -6,16 +6,16 @@ const IndexPage = () => { useEffect(() => { const handleMessage = (_event, args) => alert(args) - // add a listener to 'message' channel - global.ipcRenderer.addListener('message', handleMessage) + // listen to the 'message' channel + window.electron.receiveHello(handleMessage) return () => { - global.ipcRenderer.removeListener('message', handleMessage) + window.electron.stopReceivingHello(handleMessage) } }, []) const onSayHiClick = () => { - global.ipcRenderer.send('message', 'hi from next') + window.electron.sayHello() } return ( diff --git a/examples/with-electron-typescript/renderer/tsconfig.json b/examples/with-electron-typescript/renderer/tsconfig.json index 93a83a407c40c..771b6d8ee5d3b 100644 --- a/examples/with-electron-typescript/renderer/tsconfig.json +++ b/examples/with-electron-typescript/renderer/tsconfig.json @@ -12,8 +12,9 @@ "moduleResolution": "node", "resolveJsonModule": true, "isolatedModules": true, - "jsx": "preserve" + "jsx": "preserve", + "incremental": true }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "../next.config.js"], "exclude": ["node_modules"] } From d605ef610136b9bb62583b0d0f02c56f515188d8 Mon Sep 17 00:00:00 2001 From: Zack Tanner Date: Wed, 29 Nov 2023 23:57:42 -0800 Subject: [PATCH 103/481] fix interception routes with rewrites (#59094) ### What? When using interception routes & rewrites, on first interception the router will properly handle the request. But when using the back button and attempting another interception, it won't work ### Why? Intercepting routes rely on the accuracy of `nextUrl` -- but when `ACTION_RESTORE` is dispatched (in the `popstate` event), `nextUrl` is restored from `url.pathname` rather than the flight router state. ### How? This uses the `extractPathFromFlightRouterState` util which will properly handle setting `nextUrl`. This util is also used when creating the initial router state. Closes NEXT-1747 Fixes #56072 --- .../router-reducer/reducers/restore-reducer.ts | 3 ++- .../app/[lang]/@modal/(.)photos/[id]/page.tsx | 7 +++++++ .../app/[lang]/layout.tsx | 4 ++++ .../app/[lang]/photos/[id]/page.tsx | 7 +++++++ .../interception-middleware-rewrite.test.ts | 17 +++++++++++++++++ 5 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 test/e2e/app-dir/interception-middleware-rewrite/app/[lang]/@modal/(.)photos/[id]/page.tsx create mode 100644 test/e2e/app-dir/interception-middleware-rewrite/app/[lang]/photos/[id]/page.tsx diff --git a/packages/next/src/client/components/router-reducer/reducers/restore-reducer.ts b/packages/next/src/client/components/router-reducer/reducers/restore-reducer.ts index 06e453c6edfcc..801971be406ef 100644 --- a/packages/next/src/client/components/router-reducer/reducers/restore-reducer.ts +++ b/packages/next/src/client/components/router-reducer/reducers/restore-reducer.ts @@ -4,6 +4,7 @@ import type { ReducerState, RestoreAction, } from '../router-reducer-types' +import { extractPathFromFlightRouterState } from '../compute-changed-path' export function restoreReducer( state: ReadonlyReducerState, @@ -27,6 +28,6 @@ export function restoreReducer( prefetchCache: state.prefetchCache, // Restore provided tree tree: tree, - nextUrl: url.pathname, + nextUrl: extractPathFromFlightRouterState(tree) ?? url.pathname, } } diff --git a/test/e2e/app-dir/interception-middleware-rewrite/app/[lang]/@modal/(.)photos/[id]/page.tsx b/test/e2e/app-dir/interception-middleware-rewrite/app/[lang]/@modal/(.)photos/[id]/page.tsx new file mode 100644 index 0000000000000..97e9206db9830 --- /dev/null +++ b/test/e2e/app-dir/interception-middleware-rewrite/app/[lang]/@modal/(.)photos/[id]/page.tsx @@ -0,0 +1,7 @@ +export default function PhotoModal({ + params: { id: photoId }, +}: { + params: { id: string } +}) { + return
Intercepted Photo ID: {photoId}
+} diff --git a/test/e2e/app-dir/interception-middleware-rewrite/app/[lang]/layout.tsx b/test/e2e/app-dir/interception-middleware-rewrite/app/[lang]/layout.tsx index 58431c5495637..521cc03120ad5 100644 --- a/test/e2e/app-dir/interception-middleware-rewrite/app/[lang]/layout.tsx +++ b/test/e2e/app-dir/interception-middleware-rewrite/app/[lang]/layout.tsx @@ -6,6 +6,10 @@ export default function Layout({ children, modal, params }) {
feed
+
+ Photos: Photo 1{' '} + Photo 2 +
{params.lang}
{children}
diff --git a/test/e2e/app-dir/interception-middleware-rewrite/app/[lang]/photos/[id]/page.tsx b/test/e2e/app-dir/interception-middleware-rewrite/app/[lang]/photos/[id]/page.tsx new file mode 100644 index 0000000000000..d7f45379cfc72 --- /dev/null +++ b/test/e2e/app-dir/interception-middleware-rewrite/app/[lang]/photos/[id]/page.tsx @@ -0,0 +1,7 @@ +export default function PhotoPage({ + params: { id }, +}: { + params: { id: string } +}) { + return
Page Photo ID: {id}
+} diff --git a/test/e2e/app-dir/interception-middleware-rewrite/interception-middleware-rewrite.test.ts b/test/e2e/app-dir/interception-middleware-rewrite/interception-middleware-rewrite.test.ts index 490d8c34d150e..a92937cc684c1 100644 --- a/test/e2e/app-dir/interception-middleware-rewrite/interception-middleware-rewrite.test.ts +++ b/test/e2e/app-dir/interception-middleware-rewrite/interception-middleware-rewrite.test.ts @@ -31,5 +31,22 @@ createNextDescribe( await check(() => browser.waitForElementByCss('#modal').text(), '') }) + + it('should continue to work after using browser back button and following another intercepting route', async () => { + const browser = await next.browser('/') + await check(() => browser.elementById('children').text(), 'root') + + await browser.elementByCss('[href="/photos/1"]').click() + await check( + () => browser.elementById('modal').text(), + 'Intercepted Photo ID: 1' + ) + await browser.back() + await browser.elementByCss('[href="/photos/2"]').click() + await check( + () => browser.elementById('modal').text(), + 'Intercepted Photo ID: 2' + ) + }) } ) From 956636c86f508bb79cfc10c6a9bc40039de6366c Mon Sep 17 00:00:00 2001 From: Leah Date: Thu, 30 Nov 2023 14:03:44 +0100 Subject: [PATCH 104/481] ci: don't retry or notify on failures from forks (#59118) ### Why? For some reason the retry action can be triggered if there's a PR from the canary branch of a fork. https://github.com/vercel/next.js/actions/runs/7040561852/attempts/3 Closes PACK-2062 --- .github/workflows/retry_test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/retry_test.yml b/.github/workflows/retry_test.yml index a766f56b02ecc..478e2d1ddc282 100644 --- a/.github/workflows/retry_test.yml +++ b/.github/workflows/retry_test.yml @@ -16,7 +16,7 @@ permissions: jobs: retry-on-failure: name: retry failed jobs - if: ${{ github.event.workflow_run.conclusion == 'failure' && github.event.workflow_run.run_attempt < 3 }} + if: ${{ github.event.workflow_run.conclusion == 'failure' && github.event.workflow_run.run_attempt < 3 && github.repository == 'vercel/next.js' }} runs-on: ubuntu-latest steps: - name: send retry request to GitHub API @@ -31,7 +31,7 @@ jobs: report-failure: name: report failure to slack - if: ${{ github.event.workflow_run.conclusion == 'failure' && github.event.workflow_run.run_attempt >= 3 }} + if: ${{ github.event.workflow_run.conclusion == 'failure' && github.event.workflow_run.run_attempt >= 3 && github.repository == 'vercel/next.js' }} runs-on: ubuntu-latest steps: - name: send webhook From d37b5076297e39e11b81e9154ccb8fef3dafa56c Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Thu, 30 Nov 2023 16:36:14 +0100 Subject: [PATCH 105/481] Fix next internal is missing in flight manifest (#59085) --- .../build/webpack/loaders/next-app-loader.ts | 17 ++++++----- .../plugins/flight-client-entry-plugin.ts | 6 ++-- .../next/src/server/app-render/entry-base.ts | 6 ++-- .../catch-all/app/[lang]/[...slug]/page.js | 6 ++++ .../catch-all/app/[lang]/global-error.js | 11 +++++++ .../catch-all/app/[lang]/layout.js | 9 ++++++ .../global-error/catch-all/index.test.ts | 29 +++++++++++++++++++ test/e2e/app-dir/global-error/next.config.js | 1 - 8 files changed, 71 insertions(+), 14 deletions(-) create mode 100644 test/e2e/app-dir/global-error/catch-all/app/[lang]/[...slug]/page.js create mode 100644 test/e2e/app-dir/global-error/catch-all/app/[lang]/global-error.js create mode 100644 test/e2e/app-dir/global-error/catch-all/app/[lang]/layout.js create mode 100644 test/e2e/app-dir/global-error/catch-all/index.test.ts delete mode 100644 test/e2e/app-dir/global-error/next.config.js diff --git a/packages/next/src/build/webpack/loaders/next-app-loader.ts b/packages/next/src/build/webpack/loaders/next-app-loader.ts index 8731b5177096f..4f6fbc609bf27 100644 --- a/packages/next/src/build/webpack/loaders/next-app-loader.ts +++ b/packages/next/src/build/webpack/loaders/next-app-loader.ts @@ -56,6 +56,8 @@ const PAGE_SEGMENT = 'page$' const PARALLEL_CHILDREN_SEGMENT = 'children$' const defaultNotFoundPath = 'next/dist/client/components/not-found-error' +const defaultGlobalErrorPath = 'next/dist/client/components/error-boundary' +const defaultLayoutPath = 'next/dist/client/components/default-layout' type DirResolver = (pathToResolve: string) => string type PathResolver = ( @@ -176,7 +178,7 @@ async function createTreeCodeFromPath( treeCode: string pages: string rootLayout: string | undefined - globalError: string | undefined + globalError: string }> { const splittedPath = pagePath.split(/[\\/]/, 1) const isNotFoundRoute = page === '/_not-found' @@ -188,7 +190,7 @@ async function createTreeCodeFromPath( const pages: string[] = [] let rootLayout: string | undefined - let globalError: string | undefined + let globalError: string = defaultGlobalErrorPath async function resolveAdjacentParallelSegments( segmentPath: string @@ -345,14 +347,17 @@ async function createTreeCodeFromPath( rootLayout = layoutPath if (isDefaultNotFound && !layoutPath) { - rootLayout = 'next/dist/client/components/default-layout' + rootLayout = defaultLayoutPath definedFilePaths.push(['layout', rootLayout]) } if (layoutPath) { - globalError = await resolver( + const resolvedGlobalErrorPath = await resolver( `${path.dirname(layoutPath)}/${GLOBAL_ERROR_FILE_TYPE}` ) + if (resolvedGlobalErrorPath) { + globalError = resolvedGlobalErrorPath + } } } @@ -698,9 +703,7 @@ const nextAppLoader: AppLoader = async function nextAppLoader() { { VAR_DEFINITION_PAGE: page, VAR_DEFINITION_PATHNAME: pathname, - VAR_MODULE_GLOBAL_ERROR: treeCodeResult.globalError - ? treeCodeResult.globalError - : 'next/dist/client/components/error-boundary', + VAR_MODULE_GLOBAL_ERROR: treeCodeResult.globalError, VAR_ORIGINAL_PATHNAME: page, }, { diff --git a/packages/next/src/build/webpack/plugins/flight-client-entry-plugin.ts b/packages/next/src/build/webpack/plugins/flight-client-entry-plugin.ts index 69a2700cd71a0..b9014ad967395 100644 --- a/packages/next/src/build/webpack/plugins/flight-client-entry-plugin.ts +++ b/packages/next/src/build/webpack/plugins/flight-client-entry-plugin.ts @@ -393,14 +393,14 @@ export class FlightClientEntryPlugin { // We need to create extra action entries that are created from the // client layer. // Start from each entry's created SSR dependency from our previous step. - for (const [name, ssrEntryDepdendencies] of Object.entries( + for (const [name, ssrEntryDependencies] of Object.entries( createdSSRDependenciesForEntry )) { // Collect from all entries, e.g. layout.js, page.js, loading.js, ... - // add agregate them. + // add aggregate them. const actionEntryImports = this.collectClientActionsFromDependencies({ compilation, - dependencies: ssrEntryDepdendencies, + dependencies: ssrEntryDependencies, }) if (actionEntryImports.size > 0) { diff --git a/packages/next/src/server/app-render/entry-base.ts b/packages/next/src/server/app-render/entry-base.ts index 920c02b635b37..ebd618faa7eb0 100644 --- a/packages/next/src/server/app-render/entry-base.ts +++ b/packages/next/src/server/app-render/entry-base.ts @@ -16,7 +16,10 @@ import { staticGenerationBailout } from '../../client/components/static-generati import StaticGenerationSearchParamsBailoutProvider from '../../client/components/static-generation-searchparams-bailout-provider' import { createSearchParamsBailoutProxy } from '../../client/components/searchparams-bailout-proxy' import * as serverHooks from '../../client/components/hooks-server-context' +import { NotFoundBoundary } from '../../client/components/not-found-boundary' import { patchFetch as _patchFetch } from '../lib/patch-fetch' +// not being used but needs to be included in the client manifest for /_not-found +import '../../client/components/error-boundary' import { preloadStyle, @@ -26,9 +29,6 @@ import { import { taintObjectReference } from '../../server/app-render/rsc/taint' -const { NotFoundBoundary } = - require('next/dist/client/components/not-found-boundary') as typeof import('../../client/components/not-found-boundary') - // patchFetch makes use of APIs such as `React.unstable_postpone` which are only available // in the experimental channel of React, so export it from here so that it comes from the bundled runtime function patchFetch() { diff --git a/test/e2e/app-dir/global-error/catch-all/app/[lang]/[...slug]/page.js b/test/e2e/app-dir/global-error/catch-all/app/[lang]/[...slug]/page.js new file mode 100644 index 0000000000000..8ed52fb421dab --- /dev/null +++ b/test/e2e/app-dir/global-error/catch-all/app/[lang]/[...slug]/page.js @@ -0,0 +1,6 @@ +export default async function Page({ params }) { + if (params.slug[0] === 'error') { + throw new Error('trigger error') + } + return 'catch-all page' +} diff --git a/test/e2e/app-dir/global-error/catch-all/app/[lang]/global-error.js b/test/e2e/app-dir/global-error/catch-all/app/[lang]/global-error.js new file mode 100644 index 0000000000000..48af4bf693b0a --- /dev/null +++ b/test/e2e/app-dir/global-error/catch-all/app/[lang]/global-error.js @@ -0,0 +1,11 @@ +'use client' + +export default function GlobalError() { + return ( + + +
global-error
+ + + ) +} diff --git a/test/e2e/app-dir/global-error/catch-all/app/[lang]/layout.js b/test/e2e/app-dir/global-error/catch-all/app/[lang]/layout.js new file mode 100644 index 0000000000000..4328f6b8b8aa2 --- /dev/null +++ b/test/e2e/app-dir/global-error/catch-all/app/[lang]/layout.js @@ -0,0 +1,9 @@ +export default async function RootLayout({ children }) { + return ( + + {children} + + ) +} + +export const dynamic = 'force-dynamic' diff --git a/test/e2e/app-dir/global-error/catch-all/index.test.ts b/test/e2e/app-dir/global-error/catch-all/index.test.ts new file mode 100644 index 0000000000000..e2a3bae8f8087 --- /dev/null +++ b/test/e2e/app-dir/global-error/catch-all/index.test.ts @@ -0,0 +1,29 @@ +import { createNextDescribe } from 'e2e-utils' + +createNextDescribe( + 'app dir - global error - with catch-all route', + { + files: __dirname, + skipDeployment: true, + }, + ({ next, isNextStart }) => { + it('should render catch-all route correctly', async () => { + expect(await next.render('/en/foo')).toContain('catch-all page') + }) + + it('should render 404 page correctly', async () => { + expect(await next.render('/en')).toContain( + 'This page could not be found.' + ) + }) + + if (isNextStart) { + it('should render global error correctly', async () => { + const browser = await next.browser('/en/error') + + const text = await browser.elementByCss('#global-error').text() + expect(text).toBe('global-error') + }) + } + } +) diff --git a/test/e2e/app-dir/global-error/next.config.js b/test/e2e/app-dir/global-error/next.config.js deleted file mode 100644 index 4ba52ba2c8df6..0000000000000 --- a/test/e2e/app-dir/global-error/next.config.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = {} From 778fb871314e840390496f4147483ba18d974d83 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Thu, 30 Nov 2023 16:44:49 +0100 Subject: [PATCH 106/481] Support generating multi-meta tahs for metadata api other prop (#59106) --- .../04-functions/generate-metadata.mdx | 14 ++++++++++++++ .../next/src/lib/metadata/generate/alternate.tsx | 2 +- packages/next/src/lib/metadata/generate/basic.tsx | 15 +++++++++------ test/e2e/app-dir/metadata/metadata.test.ts | 1 + 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/docs/02-app/02-api-reference/04-functions/generate-metadata.mdx b/docs/02-app/02-api-reference/04-functions/generate-metadata.mdx index 00d5aab0e7dc0..4ec8b18f2bbaa 100644 --- a/docs/02-app/02-api-reference/04-functions/generate-metadata.mdx +++ b/docs/02-app/02-api-reference/04-functions/generate-metadata.mdx @@ -930,6 +930,20 @@ export const metadata = { ``` +If you want to generate multiple same key meta tags you can use array value. + +```jsx filename="layout.js | page.js" +export const metadata = { + other: { + custom: ['meta1', 'meta2'], + }, +} +``` + +```html filename=" output" hideLineNumbers + +``` + ## Unsupported Metadata The following metadata types do not currently have built-in support. However, they can still be rendered in the layout or page itself. diff --git a/packages/next/src/lib/metadata/generate/alternate.tsx b/packages/next/src/lib/metadata/generate/alternate.tsx index 8ccc816ba509d..cb4377b591036 100644 --- a/packages/next/src/lib/metadata/generate/alternate.tsx +++ b/packages/next/src/lib/metadata/generate/alternate.tsx @@ -1,7 +1,7 @@ import type { ResolvedMetadata } from '../types/metadata-interface' +import type { AlternateLinkDescriptor } from '../types/alternative-urls-types' import React from 'react' -import type { AlternateLinkDescriptor } from '../types/alternative-urls-types' import { MetaFilter } from './meta' function AlternateLink({ diff --git a/packages/next/src/lib/metadata/generate/basic.tsx b/packages/next/src/lib/metadata/generate/basic.tsx index 78c3df8e00676..5f52cd3d84562 100644 --- a/packages/next/src/lib/metadata/generate/basic.tsx +++ b/packages/next/src/lib/metadata/generate/basic.tsx @@ -87,12 +87,15 @@ export function BasicMeta({ metadata }: { metadata: ResolvedMetadata }) { Meta({ name: 'category', content: metadata.category }), Meta({ name: 'classification', content: metadata.classification }), ...(metadata.other - ? Object.entries(metadata.other).map(([name, content]) => - Meta({ - name, - content: Array.isArray(content) ? content.join(',') : content, - }) - ) + ? Object.entries(metadata.other).map(([name, content]) => { + if (Array.isArray(content)) { + return content.map((contentItem) => + Meta({ name, content: contentItem }) + ) + } else { + return Meta({ name, content }) + } + }) : []), ]) } diff --git a/test/e2e/app-dir/metadata/metadata.test.ts b/test/e2e/app-dir/metadata/metadata.test.ts index 6f8ef4ddbe239..d489e4f0833bc 100644 --- a/test/e2e/app-dir/metadata/metadata.test.ts +++ b/test/e2e/app-dir/metadata/metadata.test.ts @@ -359,6 +359,7 @@ createNextDescribe( 'yandex-verification': 'yandex', me: ['my-email', 'my-link'], }) + expect($('meta[name="me"]').length).toBe(2) }) it('should support appLinks tags', async () => { From 156f7860e2fa69e7f20aaf45c7cc1d542c5a50b6 Mon Sep 17 00:00:00 2001 From: Will Binns-Smith Date: Thu, 30 Nov 2023 08:34:56 -0800 Subject: [PATCH 107/481] Turbopack: Align some "Module not found" errors with webpack (#58518) This: - Sends an hmr sync event so that errors that occur after the initial hmr connection are sent to the client - Aligns on `path/to/file.js:line:column` format across error overlay implementations in the cli and on the web - Adapts "Module not found" errors from Turbopack to include Next.js-relevant formatting and documentation links to align with webpack Test Plan: Passes 3 tests that were previously failing Closes PACK-1974 --------- Co-authored-by: Tobias Koppers Co-authored-by: Leah Co-authored-by: Zack Tanner --- .../components/Terminal/EditorLink.tsx | 2 +- .../next/src/server/dev/hot-reloader-types.ts | 2 +- .../lib/router-utils/setup-dev-bundler.ts | 175 ++++++++++-------- test/build-turbopack-tests-manifest.js | 3 - .../ReactRefreshLogBox-builtins.test.ts | 79 +++++--- .../acceptance-app/ReactRefreshLogBox.test.ts | 2 +- .../ReactRefreshLogBox-scss.test.ts.snap | 2 +- .../ReactRefreshLogBox.test.ts.snap | 4 +- .../ReactRefreshLogBox-builtins.test.ts | 34 +++- test/turbopack-tests-manifest.json | 49 ++--- 10 files changed, 206 insertions(+), 146 deletions(-) diff --git a/packages/next/src/client/components/react-dev-overlay/internal/components/Terminal/EditorLink.tsx b/packages/next/src/client/components/react-dev-overlay/internal/components/Terminal/EditorLink.tsx index f397001c8c460..518c29e4c7023 100644 --- a/packages/next/src/client/components/react-dev-overlay/internal/components/Terminal/EditorLink.tsx +++ b/packages/next/src/client/components/react-dev-overlay/internal/components/Terminal/EditorLink.tsx @@ -31,7 +31,7 @@ export function EditorLink({ file, isSourceFile, location }: EditorLinkProps) { title={'Click to open in your editor'} > {file} - {location ? ` (${location.line}:${location.column})` : null} + {location ? `:${location.line}:${location.column}` : null} diff --git a/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts b/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts index 59d561927cee2..713b47ff9d8e0 100644 --- a/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts +++ b/packages/next/src/server/lib/router-utils/setup-dev-bundler.ts @@ -23,6 +23,7 @@ import type { HMR_ACTION_TYPES, NextJsHotReloaderInterface, ReloadPageAction, + SyncAction, TurbopackConnectedAction, } from '../../dev/hot-reloader-types' @@ -166,6 +167,8 @@ async function verifyTypeScript(opts: SetupOpts) { return usingTypeScript } +class ModuleBuildError extends Error {} + async function startWatcher(opts: SetupOpts) { const { nextConfig, appDir, pagesDir, dir } = opts const { useFileSystemPublicRoutes } = nextConfig @@ -285,20 +288,29 @@ async function startWatcher(opts: SetupOpts) { return [ issue.severity, issue.filePath, - issue.title, + JSON.stringify(issue.title), JSON.stringify(issue.description), ].join('-') } function formatIssue(issue: Issue) { - const { filePath, title, description, source, detail } = issue + const { filePath, title, description, source } = issue + let { documentationLink } = issue let formattedTitle = renderStyledStringToErrorAnsi(title).replace( /\n/g, '\n ' ) + // TODO: Use error codes to identify these + // TODO: Generalize adapting Turbopack errors to Next.js errors + if (formattedTitle.includes('Module not found')) { + // For compatiblity with webpack + // TODO: include columns in webpack errors. + documentationLink = 'https://nextjs.org/docs/messages/module-not-found' + } + let formattedFilePath = filePath - .replace('[project]/', '') + .replace('[project]/', './') .replaceAll('/./', '/') .replace('\\\\?\\', '') @@ -307,17 +319,18 @@ async function startWatcher(opts: SetupOpts) { if (source) { if (source.range) { const { start } = source.range - message = `${issue.severity} - ${formattedFilePath}:${ - start.line + 1 - }:${start.column} ${formattedTitle}` + message = `${formattedFilePath}:${start.line + 1}:${ + start.column + }\n${formattedTitle}` } else { - message = `${issue.severity} - ${formattedFilePath} ${formattedTitle}` + message = formattedFilePath } } else if (formattedFilePath) { - message = `${formattedFilePath} ${formattedTitle}` + message = `${formattedFilePath}\n${formattedTitle}` } else { message = formattedTitle } + message += '\n' if (source?.range && source.source.content) { const { start, end } = source.range @@ -326,70 +339,56 @@ async function startWatcher(opts: SetupOpts) { } = require('next/dist/compiled/babel/code-frame') message += - '\n\n' + codeFrameColumns( source.source.content, { - start: { line: start.line + 1, column: start.column + 1 }, - end: { line: end.line + 1, column: end.column + 1 }, + start: { + line: start.line + 1, + column: start.column + 1, + }, + end: { + line: end.line + 1, + column: end.column + 1, + }, }, { forceColor: true } - ) + ).trim() + '\n\n' } if (description) { - message += `\n${renderStyledStringToErrorAnsi(description).replace( - /\n/g, - '\n ' - )}` + message += renderStyledStringToErrorAnsi(description) + '\n\n' } - if (detail) { - message += `\n${renderStyledStringToErrorAnsi(detail).replace( - /\n/g, - '\n ' - )}` + // TODO: Include a trace from the issue. + + if (documentationLink) { + message += documentationLink + '\n\n' } return message } - class ModuleBuildError extends Error {} - function processIssues( - displayName: string, name: string, result: TurbopackResult, throwIssue = false ) { - const oldSet = issues.get(name) ?? new Map() - const newSet = new Map() - issues.set(name, newSet) + const newIssues = new Map() + issues.set(name, newIssues) const relevantIssues = new Set() for (const issue of result.issues) { - // TODO better formatting if (issue.severity !== 'error' && issue.severity !== 'fatal') continue const key = issueKey(issue) const formatted = formatIssue(issue) - if (!oldSet.has(key) && !newSet.has(key)) { - console.error(` ⚠ ${displayName} ${formatted}\n\n`) - } - newSet.set(key, issue) + newIssues.set(key, issue) // We show errors in node_modules to the console, but don't throw for them if (/(^|\/)node_modules(\/|$)/.test(issue.filePath)) continue relevantIssues.add(formatted) } - // TODO: Format these messages correctly. - // for (const issue of oldSet.keys()) { - // if (!newSet.has(issue)) { - // console.error(`✅ ${displayName} fixed ${issue}`) - // } - // } - if (relevantIssues.size && throwIssue) { throw new ModuleBuildError([...relevantIssues].join('\n\n')) } @@ -702,7 +701,7 @@ async function startWatcher(opts: SetupOpts) { const changed = await changedPromise for await (const change of changed) { - processIssues(key, page, change) + processIssues(page, change) const payload = await makePayload(page, change) if (payload) sendHmr('endpoint-change', key, payload) } @@ -1045,7 +1044,7 @@ async function startWatcher(opts: SetupOpts) { await subscription.next() for await (const data of subscription) { - processIssues('hmr', id, data) + processIssues(id, data) sendTurbopackMessage(data) } } catch (e) { @@ -1137,7 +1136,7 @@ async function startWatcher(opts: SetupOpts) { displayName, await instrumentation[prop].writeToDisk() ) - processIssues(displayName, name, writtenEndpoint) + processIssues(name, writtenEndpoint) } await processInstrumentation( 'instrumentation (node.js)', @@ -1170,7 +1169,7 @@ async function startWatcher(opts: SetupOpts) { 'middleware', await middleware.endpoint.writeToDisk() ) - processIssues('middleware', 'middleware', writtenEndpoint) + processIssues('middleware', writtenEndpoint) await loadMiddlewareManifest('middleware', 'middleware') serverFields.actualMiddlewareFile = 'middleware' serverFields.middleware = { @@ -1367,6 +1366,28 @@ async function startWatcher(opts: SetupOpts) { type: HMR_ACTIONS_SENT_TO_BROWSER.TURBOPACK_CONNECTED, } client.send(JSON.stringify(turbopackConnected)) + + const errors = [] + for (const pageIssues of issues.values()) { + for (const issue of pageIssues.values()) { + errors.push({ + message: formatIssue(issue), + }) + } + } + + const sync: SyncAction = { + action: HMR_ACTIONS_SENT_TO_BROWSER.SYNC, + errors, + warnings: [], + hash: '', + versionInfo: { + installed: '0.0.0', + staleness: 'unknown', + }, + } + + this.send(sync) }) }, @@ -1389,8 +1410,23 @@ async function startWatcher(opts: SetupOpts) { async stop() { // Not implemented yet. }, - async getCompilationErrors(_page) { - return [] + async getCompilationErrors(page) { + const thisPageIssues = issues.get(page) + if (thisPageIssues !== undefined && thisPageIssues.size > 0) { + // If there is an error related to the requesting page we display it instead of the first error + return [...thisPageIssues.values()].map( + (issue) => new Error(formatIssue(issue)) + ) + } + + // Otherwise, return all errors across pages + const errors = [] + for (const pageIssues of issues.values()) { + for (const issue of pageIssues.values()) { + errors.push(new Error(formatIssue(issue))) + } + } + return errors }, invalidate(/* Unused parameter: { reloadAfterInvalidation } */) { // Not implemented yet. @@ -1417,7 +1453,7 @@ async function startWatcher(opts: SetupOpts) { '_app', await globalEntries.app.writeToDisk() ) - processIssues('_app', '_app', writtenEndpoint) + processIssues('_app', writtenEndpoint) } await loadBuildManifest('_app') await loadPagesManifest('_app') @@ -1436,7 +1472,7 @@ async function startWatcher(opts: SetupOpts) { return { action: HMR_ACTIONS_SENT_TO_BROWSER.RELOAD_PAGE } } ) - processIssues('_document', '_document', writtenEndpoint) + processIssues('_document', writtenEndpoint) } await loadPagesManifest('_document') @@ -1445,7 +1481,7 @@ async function startWatcher(opts: SetupOpts) { '_error', await globalEntries.error.writeToDisk() ) - processIssues(page, page, writtenEndpoint) + processIssues(page, writtenEndpoint) } await loadBuildManifest('_error') await loadPagesManifest('_error') @@ -1481,25 +1517,6 @@ async function startWatcher(opts: SetupOpts) { throw new PageNotFoundError(`route not found ${page}`) } - let suffix - switch (route.type) { - case 'app-page': - suffix = 'page' - break - case 'app-route': - suffix = 'route' - break - case 'page': - case 'page-api': - suffix = '' - break - default: - throw new Error('Unexpected route type ' + route.type) - } - - const buildingKey = `${page}${ - !page.endsWith('/') && suffix.length > 0 ? '/' : '' - }${suffix}` let finishBuilding: (() => void) | undefined = undefined try { @@ -1511,14 +1528,14 @@ async function startWatcher(opts: SetupOpts) { ) } - finishBuilding = startBuilding(buildingKey, requestUrl) + finishBuilding = startBuilding(page, requestUrl) try { if (globalEntries.app) { const writtenEndpoint = await processResult( '_app', await globalEntries.app.writeToDisk() ) - processIssues('_app', '_app', writtenEndpoint) + processIssues('_app', writtenEndpoint) } await loadBuildManifest('_app') await loadPagesManifest('_app') @@ -1538,7 +1555,7 @@ async function startWatcher(opts: SetupOpts) { return { action: HMR_ACTIONS_SENT_TO_BROWSER.RELOAD_PAGE } } ) - processIssues('_document', '_document', writtenEndpoint) + processIssues('_document', writtenEndpoint) } await loadPagesManifest('_document') @@ -1564,7 +1581,7 @@ async function startWatcher(opts: SetupOpts) { await writeMiddlewareManifest() await writeLoadableManifest() - processIssues(page, page, writtenEndpoint) + processIssues(page, writtenEndpoint) } finally { changeSubscription( page, @@ -1599,7 +1616,7 @@ async function startWatcher(opts: SetupOpts) { // since this can happen when app pages make // api requests to page API routes. - finishBuilding = startBuilding(buildingKey, requestUrl) + finishBuilding = startBuilding(page, requestUrl) const writtenEndpoint = await processResult( page, await route.endpoint.writeToDisk() @@ -1619,12 +1636,12 @@ async function startWatcher(opts: SetupOpts) { await writeMiddlewareManifest() await writeLoadableManifest() - processIssues(page, page, writtenEndpoint) + processIssues(page, writtenEndpoint) break } case 'app-page': { - finishBuilding = startBuilding(buildingKey, requestUrl) + finishBuilding = startBuilding(page, requestUrl) const writtenEndpoint = await processResult( page, await route.htmlEndpoint.writeToDisk() @@ -1670,12 +1687,12 @@ async function startWatcher(opts: SetupOpts) { await writeActionManifest() await writeLoadableManifest() - processIssues(page, page, writtenEndpoint, true) + processIssues(page, writtenEndpoint, true) break } case 'app-route': { - finishBuilding = startBuilding(buildingKey, requestUrl) + finishBuilding = startBuilding(page, requestUrl) const writtenEndpoint = await processResult( page, await route.endpoint.writeToDisk() @@ -1696,7 +1713,7 @@ async function startWatcher(opts: SetupOpts) { await writeMiddlewareManifest() await writeLoadableManifest() - processIssues(page, page, writtenEndpoint, true) + processIssues(page, writtenEndpoint, true) break } @@ -2520,7 +2537,9 @@ async function startWatcher(opts: SetupOpts) { } if (!usedOriginalStack) { - if (type === 'warning') { + if (err instanceof ModuleBuildError) { + Log.error(err.message) + } else if (type === 'warning') { Log.warn(err) } else if (type === 'app-dir') { logAppDirError(err) diff --git a/test/build-turbopack-tests-manifest.js b/test/build-turbopack-tests-manifest.js index fbbc4b5d24b35..1230c4f8d4a2d 100644 --- a/test/build-turbopack-tests-manifest.js +++ b/test/build-turbopack-tests-manifest.js @@ -23,9 +23,6 @@ const INITIALIZING_TEST_CASES = [ // please make sure this is sorted alphabetically when making changes. const SKIPPED_TEST_SUITES = { - 'test/development/acceptance-app/ReactRefreshLogBox-builtins.test.ts': [ - 'ReactRefreshLogBox app turbo Module not found missing global CSS', - ], 'test/development/acceptance-app/ReactRefreshRegression.test.ts': [ 'ReactRefreshRegression app can fast refresh a page with dynamic rendering', 'ReactRefreshRegression app can fast refresh a page with config', diff --git a/test/development/acceptance-app/ReactRefreshLogBox-builtins.test.ts b/test/development/acceptance-app/ReactRefreshLogBox-builtins.test.ts index f021abbbfd4be..36278161698db 100644 --- a/test/development/acceptance-app/ReactRefreshLogBox-builtins.test.ts +++ b/test/development/acceptance-app/ReactRefreshLogBox-builtins.test.ts @@ -51,7 +51,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => { ) expect(await session.hasRedbox(true)).toBe(true) expect(await session.getRedboxSource()).toMatchInlineSnapshot(` - "./node_modules/my-package/index.js (1:0) + "./node_modules/my-package/index.js:1:0 Module not found: Can't resolve 'dns' https://nextjs.org/docs/messages/module-not-found @@ -85,7 +85,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => { const source = await session.getRedboxSource() expect(source).toMatchInlineSnapshot(` - "./index.js (1:0) + "./index.js:1:0 Module not found: Can't resolve 'b' > 1 | import Comp from 'b' 2 | export default function Oops() { @@ -122,17 +122,32 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => { expect(await session.hasRedbox(true)).toBe(true) const source = await session.getRedboxSource() - expect(source).toMatchInlineSnapshot(` - "./app/page.js (2:0) - Module not found: Can't resolve 'b' - 1 | 'use client' - > 2 | import Comp from 'b' - 3 | export default function Oops() { - 4 | return ( - 5 |
- - https://nextjs.org/docs/messages/module-not-found" - `) + if (process.env.TURBOPACK) { + expect(source).toMatchInlineSnapshot(` + "./app/page.js:2:0 + Module not found: Can't resolve 'b' + 1 | 'use client' + > 2 | import Comp from 'b' + | ^^^^^^^^^^^^^^^^^^^^ + 3 | export default function Oops() { + 4 | return ( + 5 |
+ + https://nextjs.org/docs/messages/module-not-found" + `) + } else { + expect(source).toMatchInlineSnapshot(` + "./app/page.js:2:0 + Module not found: Can't resolve 'b' + 1 | 'use client' + > 2 | import Comp from 'b' + 3 | export default function Oops() { + 4 | return ( + 5 |
+ + https://nextjs.org/docs/messages/module-not-found" + `) + } await cleanup() }) @@ -156,18 +171,32 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => { expect(await session.hasRedbox(true)).toBe(true) const source = await session.getRedboxSource() - expect(source).toMatchInlineSnapshot(` - "./app/page.js:2:0 - Module not found: Can't resolve './non-existent.css' - 1 | 'use client' - > 2 | import './non-existent.css' - 3 | export default function Page(props) { - 4 | return

index page

- 5 | } - - https://nextjs.org/docs/messages/module-not-found" - `) - + if (process.env.TURBOPACK) { + expect(source).toMatchInlineSnapshot(` + "./app/page.js:2:0 + Module not found: Can't resolve './non-existent.css' + 1 | 'use client' + > 2 | import './non-existent.css' + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 3 | export default function Page(props) { + 4 | return

index page

+ 5 | } + + https://nextjs.org/docs/messages/module-not-found" + `) + } else { + expect(source).toMatchInlineSnapshot(` + "./app/page.js:2:0 + Module not found: Can't resolve './non-existent.css' + 1 | 'use client' + > 2 | import './non-existent.css' + 3 | export default function Page(props) { + 4 | return

index page

+ 5 | } + + https://nextjs.org/docs/messages/module-not-found" + `) + } await session.patch( 'app/page.js', outdent` diff --git a/test/development/acceptance-app/ReactRefreshLogBox.test.ts b/test/development/acceptance-app/ReactRefreshLogBox.test.ts index bd75f6f16c923..ee98f29cc5e5b 100644 --- a/test/development/acceptance-app/ReactRefreshLogBox.test.ts +++ b/test/development/acceptance-app/ReactRefreshLogBox.test.ts @@ -344,7 +344,7 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox app %s', () => { await session.patch('index.module.css', `.button {`) expect(await session.hasRedbox(true)).toBe(true) const source = await session.getRedboxSource() - expect(source).toMatch('./index.module.css (1:1)') + expect(source).toMatch('./index.module.css:1:1') expect(source).toMatch('Syntax error: ') expect(source).toMatch('Unclosed block') expect(source).toMatch('> 1 | .button {') diff --git a/test/development/acceptance-app/__snapshots__/ReactRefreshLogBox-scss.test.ts.snap b/test/development/acceptance-app/__snapshots__/ReactRefreshLogBox-scss.test.ts.snap index 4aabd710b78bc..5e5ca86ac1578 100644 --- a/test/development/acceptance-app/__snapshots__/ReactRefreshLogBox-scss.test.ts.snap +++ b/test/development/acceptance-app/__snapshots__/ReactRefreshLogBox-scss.test.ts.snap @@ -16,7 +16,7 @@ Import trace for requested module: `; exports[`ReactRefreshLogBox app scss syntax errors 2`] = ` -"./index.module.scss (1:1) +"./index.module.scss:1:1 Syntax error: Selector "button" is not pure (pure selectors must contain at least one local class or id) > 1 | button { font-size: 5px; } diff --git a/test/development/acceptance-app/__snapshots__/ReactRefreshLogBox.test.ts.snap b/test/development/acceptance-app/__snapshots__/ReactRefreshLogBox.test.ts.snap index e6abc90aa8daf..64be47456117e 100644 --- a/test/development/acceptance-app/__snapshots__/ReactRefreshLogBox.test.ts.snap +++ b/test/development/acceptance-app/__snapshots__/ReactRefreshLogBox.test.ts.snap @@ -11,7 +11,7 @@ Import trace for requested module: `; exports[`ReactRefreshLogBox app default Import trace when module not found in layout 1`] = ` -"./app/module.js (1:0) +"./app/module.js:1:0 Module not found: Can't resolve 'non-existing-module' > 1 | import "non-existing-module" @@ -52,7 +52,7 @@ exports[`ReactRefreshLogBox app default conversion to class component (1) 1`] = `; exports[`ReactRefreshLogBox app default css syntax errors 1`] = ` -"./index.module.css (1:1) +"./index.module.css:1:1 Syntax error: Selector "button" is not pure (pure selectors must contain at least one local class or id) > 1 | button {} diff --git a/test/development/acceptance/ReactRefreshLogBox-builtins.test.ts b/test/development/acceptance/ReactRefreshLogBox-builtins.test.ts index 3ae613fdca192..cba0c3fe12f6d 100644 --- a/test/development/acceptance/ReactRefreshLogBox-builtins.test.ts +++ b/test/development/acceptance/ReactRefreshLogBox-builtins.test.ts @@ -118,16 +118,30 @@ describe.each(['default', 'turbo'])('ReactRefreshLogBox %s', () => { expect(await session.hasRedbox(true)).toBe(true) const source = await session.getRedboxSource() - expect(source).toMatchInlineSnapshot(` - "./pages/index.js:1:0 - Module not found: Can't resolve 'b' - > 1 | import Comp from 'b' - 2 | - 3 | export default function Oops() { - 4 | return ( - - https://nextjs.org/docs/messages/module-not-found" - `) + if (process.env.TURBOPACK) { + expect(source).toMatchInlineSnapshot(` + "./pages/index.js:1:0 + Module not found: Can't resolve 'b' + > 1 | import Comp from 'b' + | ^^^^^^^^^^^^^^^^^^^^ + 2 | + 3 | export default function Oops() { + 4 | return ( + + https://nextjs.org/docs/messages/module-not-found" + `) + } else { + expect(source).toMatchInlineSnapshot(` + "./pages/index.js:1:0 + Module not found: Can't resolve 'b' + > 1 | import Comp from 'b' + 2 | + 3 | export default function Oops() { + 4 | return ( + + https://nextjs.org/docs/messages/module-not-found" + `) + } await cleanup() }) diff --git a/test/turbopack-tests-manifest.json b/test/turbopack-tests-manifest.json index b2cdc1c95a857..5a3fa8d053b95 100644 --- a/test/turbopack-tests-manifest.json +++ b/test/turbopack-tests-manifest.json @@ -875,10 +875,12 @@ "runtimeError": false }, "test/development/acceptance-app/ReactRefreshLogBox-builtins.test.ts": { - "passed": [], + "passed": [ + "ReactRefreshLogBox app turbo Module not found empty import trace", + "ReactRefreshLogBox app turbo Module not found missing global CSS" + ], "failed": [ "ReactRefreshLogBox app turbo Module not found", - "ReactRefreshLogBox app turbo Module not found empty import trace", "ReactRefreshLogBox app turbo Node.js builtins" ], "pending": [ @@ -887,9 +889,7 @@ "ReactRefreshLogBox app default Module not found missing global CSS", "ReactRefreshLogBox app default Node.js builtins" ], - "flakey": [ - "ReactRefreshLogBox app turbo Module not found missing global CSS" - ], + "flakey": [], "runtimeError": false }, "test/development/acceptance-app/ReactRefreshLogBox-scss.test.ts": { @@ -1211,10 +1211,11 @@ "runtimeError": false }, "test/development/acceptance/ReactRefreshLogBox-builtins.test.ts": { - "passed": [], + "passed": [ + "ReactRefreshLogBox turbo Module not found (empty import trace)" + ], "failed": [ "ReactRefreshLogBox turbo Module not found", - "ReactRefreshLogBox turbo Module not found (empty import trace)", "ReactRefreshLogBox turbo Module not found (missing global CSS)", "ReactRefreshLogBox turbo Node.js builtins" ], @@ -2074,15 +2075,15 @@ "test/development/tsconfig-path-reloading/index.test.ts": { "passed": [ "tsconfig-path-reloading tsconfig added after starting dev should load with initial paths config correctly", - "tsconfig-path-reloading tsconfig added after starting dev should recover from module not found when paths is updated", - "tsconfig-path-reloading tsconfig should load with initial paths config correctly", - "tsconfig-path-reloading tsconfig should recover from module not found when paths is updated" + "tsconfig-path-reloading tsconfig should load with initial paths config correctly" ], "failed": [], "pending": [], "flakey": [ "tsconfig-path-reloading tsconfig added after starting dev should automatically fast refresh content when path is added without error", - "tsconfig-path-reloading tsconfig should automatically fast refresh content when path is added without error" + "tsconfig-path-reloading tsconfig added after starting dev should recover from module not found when paths is updated", + "tsconfig-path-reloading tsconfig should automatically fast refresh content when path is added without error", + "tsconfig-path-reloading tsconfig should recover from module not found when paths is updated" ], "runtimeError": false }, @@ -5252,24 +5253,12 @@ }, "test/e2e/next-font/index.test.ts": { "passed": [ - "next/font app Fallback fontfaces google Fraunces", - "next/font app Fallback fontfaces local Fraunces", - "next/font app Fallback fontfaces local Indie flower", - "next/font app Fallback fontfaces local Roboto multiple weights and styles", - "next/font app Fallback fontfaces local Roboto multiple weights and styles - variable 1", - "next/font app Fallback fontfaces local Roboto multiple weights and styles - variable 2", "next/font app computed styles page using fallback fonts", "next/font app computed styles page using variables", "next/font app computed styles page with fonts", "next/font app import values Variable font without weight range", "next/font app import values page with font", "next/font app import values page with local fonts", - "next/font app-old Fallback fontfaces google Fraunces", - "next/font app-old Fallback fontfaces local Fraunces", - "next/font app-old Fallback fontfaces local Indie flower", - "next/font app-old Fallback fontfaces local Roboto multiple weights and styles", - "next/font app-old Fallback fontfaces local Roboto multiple weights and styles - variable 1", - "next/font app-old Fallback fontfaces local Roboto multiple weights and styles - variable 2", "next/font app-old computed styles page using fallback fonts", "next/font app-old computed styles page using variables", "next/font app-old computed styles page with fonts", @@ -5278,14 +5267,26 @@ "next/font app-old import values page with local fonts" ], "failed": [ + "next/font app Fallback fontfaces google Fraunces", "next/font app Fallback fontfaces google Indie flower", + "next/font app Fallback fontfaces local Fraunces", + "next/font app Fallback fontfaces local Indie flower", + "next/font app Fallback fontfaces local Roboto multiple weights and styles", + "next/font app Fallback fontfaces local Roboto multiple weights and styles - variable 1", + "next/font app Fallback fontfaces local Roboto multiple weights and styles - variable 2", "next/font app preload font without preloadable subsets", "next/font app preload font without size adjust", "next/font app preload google fonts with multiple weights/styles", "next/font app preload page with fonts", "next/font app preload page with local fonts", "next/font app preload page without fonts", + "next/font app-old Fallback fontfaces google Fraunces", "next/font app-old Fallback fontfaces google Indie flower", + "next/font app-old Fallback fontfaces local Fraunces", + "next/font app-old Fallback fontfaces local Indie flower", + "next/font app-old Fallback fontfaces local Roboto multiple weights and styles", + "next/font app-old Fallback fontfaces local Roboto multiple weights and styles - variable 1", + "next/font app-old Fallback fontfaces local Roboto multiple weights and styles - variable 2", "next/font app-old preload font without preloadable subsets", "next/font app-old preload font without size adjust", "next/font app-old preload google fonts with multiple weights/styles", @@ -7186,7 +7187,6 @@ }, "test/integration/css/test/css-modules.test.js": { "passed": [ - "CSS Modules Composes Ordering Development Mode should have correct color on index page (on load)", "Ordering with Global CSS and Modules (dev) should not execute scripts in any order" ], "failed": [ @@ -7194,6 +7194,7 @@ "Basic CSS Modules Ordering Development Mode should have correct color on index page (on load)", "Basic CSS Modules Ordering Development Mode should have correct color on index page (on nav)", "CSS Modules Composes Ordering Development Mode should have correct color on index page (on hover)", + "CSS Modules Composes Ordering Development Mode should have correct color on index page (on load)", "Ordering with Global CSS and Modules (dev) should have the correct color (css ordering)", "Ordering with Global CSS and Modules (dev) should have the correct color (css ordering) during hot reloads" ], From d5bc1f7f90f2cb2ad31d5c3ddaeaddf52ff466d1 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Thu, 30 Nov 2023 14:41:55 -0800 Subject: [PATCH 108/481] Fix dynamic usage errors logging unexpectedly (#59133) This ensures we don't spam build logs with dynamic usage errors or similar unexpectedly as they can be caught by this worker process listener but shouldn't be logged. Closes NEXT-1763 --- packages/next/src/export/worker.ts | 11 +++++++++-- .../src/server/app-render/create-error-handler.tsx | 13 ++----------- packages/next/taskfile.js | 10 ++++++++++ 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/packages/next/src/export/worker.ts b/packages/next/src/export/worker.ts index 2ab330d52c8e4..a3541a4a1e5ce 100644 --- a/packages/next/src/export/worker.ts +++ b/packages/next/src/export/worker.ts @@ -34,6 +34,7 @@ import { getParams } from './helpers/get-params' import { createIncrementalCache } from './helpers/create-incremental-cache' import { isPostpone } from '../server/lib/router-utils/is-postpone' import { isMissingPostponeDataError } from '../server/app-render/is-missing-postpone-error' +import { isDynamicUsageError } from './helpers/is-dynamic-usage-error' const envConfig = require('../shared/lib/runtime-config.external') @@ -376,17 +377,23 @@ export default async function exportPage( } } -process.on('unhandledRejection', (err) => { +process.on('unhandledRejection', (err: unknown) => { // if it's a postpone error, it'll be handled later // when the postponed promise is actually awaited. if (isPostpone(err)) { return } + + // we don't want to log these errors + if (isDynamicUsageError(err)) { + return + } + console.error(err) }) process.on('rejectionHandled', () => { // It is ok to await a Promise late in Next.js as it allows for better - // prefetching patterns to avoid waterfalls. We ignore loggining these. + // prefetching patterns to avoid waterfalls. We ignore logging these. // We should've already errored in anyway unhandledRejection. }) diff --git a/packages/next/src/server/app-render/create-error-handler.tsx b/packages/next/src/server/app-render/create-error-handler.tsx index 636a7049aeebb..356411c06c6bc 100644 --- a/packages/next/src/server/app-render/create-error-handler.tsx +++ b/packages/next/src/server/app-render/create-error-handler.tsx @@ -1,11 +1,8 @@ -import { DYNAMIC_ERROR_CODE } from '../../client/components/hooks-server-context' import stringHash from 'next/dist/compiled/string-hash' import { formatServerError } from '../../lib/format-server-error' -import { isNotFoundError } from '../../client/components/not-found' -import { isRedirectError } from '../../client/components/redirect' -import { NEXT_DYNAMIC_NO_SSR_CODE } from '../../shared/lib/lazy-dynamic/no-ssr-error' import { SpanStatusCode, getTracer } from '../lib/trace/tracer' import { isAbortError } from '../pipe-readable' +import { isDynamicUsageError } from '../../export/helpers/is-dynamic-usage-error' export type ErrorHandler = (err: any) => string | undefined @@ -37,13 +34,7 @@ export function createErrorHandler({ return (err) => { if (allCapturedErrors) allCapturedErrors.push(err) - if ( - err && - (err.digest === DYNAMIC_ERROR_CODE || - isNotFoundError(err) || - err.digest === NEXT_DYNAMIC_NO_SSR_CODE || - isRedirectError(err)) - ) { + if (isDynamicUsageError(err)) { return err.digest } diff --git a/packages/next/taskfile.js b/packages/next/taskfile.js index 62d73669c09b2..5fb652bd4d080 100644 --- a/packages/next/taskfile.js +++ b/packages/next/taskfile.js @@ -2375,6 +2375,7 @@ export async function next_compile(task, opts) { 'nextbuild', 'nextbuildjest', 'nextbuildstatic', + 'nextbuildstatic_esm', 'nextbuild_esm', 'pages', 'pages_esm', @@ -2522,6 +2523,14 @@ export async function nextbuildstatic(task, opts) { .target('dist/export') } +// export is a reserved keyword for functions +export async function nextbuildstatic_esm(task, opts) { + await task + .source('src/export/**/!(*.test).+(js|ts|tsx)') + .swc('server', { dev: opts.dev, esm: true }) + .target('dist/esm/export') +} + export async function pages_app(task, opts) { await task .source('src/pages/_app.tsx') @@ -2641,6 +2650,7 @@ export default async function (task) { opts ) await task.watch('src/export', 'nextbuildstatic', opts) + await task.watch('src/export', 'nextbuildstatic_esm', opts) await task.watch('src/client', 'client', opts) await task.watch('src/client', 'client_esm', opts) await task.watch('src/lib', 'lib', opts) From c5834ab48db1f351b35422f5cc3664d21c7824c2 Mon Sep 17 00:00:00 2001 From: Meril Date: Thu, 30 Nov 2023 22:52:44 +0000 Subject: [PATCH 109/481] Fix: remove deprecated option from standalone server (#59036) Remove deprecated option passed to nextjs server when running in standalone mode. Co-authored-by: JJ Kasper --- packages/next/src/build/utils.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/next/src/build/utils.ts b/packages/next/src/build/utils.ts index 3dfce139d23cb..643ca58b94036 100644 --- a/packages/next/src/build/utils.ts +++ b/packages/next/src/build/utils.ts @@ -2029,7 +2029,6 @@ startServer({ port: currentPort, allowRetry: false, keepAliveTimeout, - useWorkers: true, }).catch((err) => { console.error(err); process.exit(1); From 73d4ca577516602eb5492a5264b412d806bed06d Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Thu, 30 Nov 2023 22:56:34 +0000 Subject: [PATCH 110/481] v14.0.4-canary.29 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 16 ++++++++-------- 18 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lerna.json b/lerna.json index 8273886632ca5..a3bd105416226 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.28" + "version": "14.0.4-canary.29" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 43bfd6c638c26..c867915eccef7 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.28", + "version": "14.0.4-canary.29", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 5b6833a2f19e7..4ef83fad6f6ee 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.28", + "version": "14.0.4-canary.29", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.28", + "@next/eslint-plugin-next": "14.0.4-canary.29", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 491e33ed3f5b8..c7702fcf5898f 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.28", + "version": "14.0.4-canary.29", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index 3bdcb4b9931ad..1317d9f225f0f 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.28", + "version": "14.0.4-canary.29", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 16663e746f3cb..6633094f73b1f 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.28", + "version": "14.0.4-canary.29", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index fdf85f9a75812..603fb2e7db25c 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.28", + "version": "14.0.4-canary.29", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index b393af8e0dadc..10707b34a9631 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.28", + "version": "14.0.4-canary.29", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index c91d75144c59e..002e22c00802a 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.28", + "version": "14.0.4-canary.29", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 9f834f812b0db..64be9c56aa697 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.28", + "version": "14.0.4-canary.29", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index b153602bf8423..cf2098c6940a4 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.28", + "version": "14.0.4-canary.29", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index 70cc83594274e..d816cecc38995 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.28", + "version": "14.0.4-canary.29", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index ff864cd1215ea..03b7e78a33f7a 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.28", + "version": "14.0.4-canary.29", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index 2e2b949d755a1..7f274f0019578 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.28", + "version": "14.0.4-canary.29", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.28", + "@next/env": "14.0.4-canary.29", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -147,11 +147,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.28", - "@next/polyfill-nomodule": "14.0.4-canary.28", - "@next/react-dev-overlay": "14.0.4-canary.28", - "@next/react-refresh-utils": "14.0.4-canary.28", - "@next/swc": "14.0.4-canary.28", + "@next/polyfill-module": "14.0.4-canary.29", + "@next/polyfill-nomodule": "14.0.4-canary.29", + "@next/react-dev-overlay": "14.0.4-canary.29", + "@next/react-refresh-utils": "14.0.4-canary.29", + "@next/swc": "14.0.4-canary.29", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index 80995b9c7458d..71e78fc03cacc 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.28", + "version": "14.0.4-canary.29", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index c9d8745071fb3..d248388ad3f63 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.28", + "version": "14.0.4-canary.29", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index 41e5febcdce60..03c719ec74b40 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.28", + "version": "14.0.4-canary.29", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -23,7 +23,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.28", + "next": "14.0.4-canary.29", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c066f462f8b52..993494735b96b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -741,7 +741,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.28 + specifier: 14.0.4-canary.29 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -806,7 +806,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.28 + specifier: 14.0.4-canary.29 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -933,19 +933,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.28 + specifier: 14.0.4-canary.29 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.28 + specifier: 14.0.4-canary.29 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.28 + specifier: 14.0.4-canary.29 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.28 + specifier: 14.0.4-canary.29 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.28 + specifier: 14.0.4-canary.29 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1599,7 +1599,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.28 + specifier: 14.0.4-canary.29 version: link:../next outdent: specifier: 0.8.0 From f241f44b3888bc9d537610e620fa3c087e0a7120 Mon Sep 17 00:00:00 2001 From: Zack Tanner Date: Thu, 30 Nov 2023 15:07:05 -0800 Subject: [PATCH 111/481] skip release if no new commits (#59134) Prevents publishing canaries if there are no changes Closes NEXT-1748 --- .github/workflows/trigger_release.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/trigger_release.yml b/.github/workflows/trigger_release.yml index cac8403d282a7..03e31b1bf1d6a 100644 --- a/.github/workflows/trigger_release.yml +++ b/.github/workflows/trigger_release.yml @@ -51,7 +51,18 @@ jobs: - run: git clone https://github.com/vercel/next.js.git --depth=25 . - - run: git describe || echo 'failed to get tag' + - name: Get commit of the latest tag + run: echo "LATEST_TAG_COMMIT=$(git rev-list -n 1 $(git describe --tags --abbrev=0))" >> $GITHUB_ENV + + - name: Get latest commit + run: echo "LATEST_COMMIT=$(git rev-parse HEAD)" >> $GITHUB_ENV + + - name: Check if new commits since last tag + run: | + if [ "$LATEST_TAG" = "$LATEST_COMMIT" ]; then + echo "No new commits. Exiting..." + exit 1 + fi # https://github.com/actions/virtual-environments/issues/1187 - name: tune linux network From 3159fa197bf851df07c867c57029ae9c0b217729 Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Thu, 30 Nov 2023 23:10:37 +0000 Subject: [PATCH 112/481] v14.0.4-canary.30 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 16 ++++++++-------- 18 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lerna.json b/lerna.json index a3bd105416226..613b5b0575fd5 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.29" + "version": "14.0.4-canary.30" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index c867915eccef7..46ab3663b7dda 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.29", + "version": "14.0.4-canary.30", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 4ef83fad6f6ee..415018a661538 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.29", + "version": "14.0.4-canary.30", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.29", + "@next/eslint-plugin-next": "14.0.4-canary.30", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index c7702fcf5898f..b1597c79091f6 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.29", + "version": "14.0.4-canary.30", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index 1317d9f225f0f..7a2aa16c7e74e 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.29", + "version": "14.0.4-canary.30", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 6633094f73b1f..911b23aca8d9c 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.29", + "version": "14.0.4-canary.30", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 603fb2e7db25c..80878bcb65009 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.29", + "version": "14.0.4-canary.30", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 10707b34a9631..b875f6149bedf 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.29", + "version": "14.0.4-canary.30", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 002e22c00802a..139b5a4956e26 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.29", + "version": "14.0.4-canary.30", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 64be9c56aa697..2ce968de008a3 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.29", + "version": "14.0.4-canary.30", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index cf2098c6940a4..eaf8e01607be4 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.29", + "version": "14.0.4-canary.30", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index d816cecc38995..13e9cfe8a85ef 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.29", + "version": "14.0.4-canary.30", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index 03b7e78a33f7a..415765b214077 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.29", + "version": "14.0.4-canary.30", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index 7f274f0019578..12d4de8de2c3d 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.29", + "version": "14.0.4-canary.30", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.29", + "@next/env": "14.0.4-canary.30", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -147,11 +147,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.29", - "@next/polyfill-nomodule": "14.0.4-canary.29", - "@next/react-dev-overlay": "14.0.4-canary.29", - "@next/react-refresh-utils": "14.0.4-canary.29", - "@next/swc": "14.0.4-canary.29", + "@next/polyfill-module": "14.0.4-canary.30", + "@next/polyfill-nomodule": "14.0.4-canary.30", + "@next/react-dev-overlay": "14.0.4-canary.30", + "@next/react-refresh-utils": "14.0.4-canary.30", + "@next/swc": "14.0.4-canary.30", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index 71e78fc03cacc..cd0615a61711c 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.29", + "version": "14.0.4-canary.30", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index d248388ad3f63..1b1dc1be3740c 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.29", + "version": "14.0.4-canary.30", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index 03c719ec74b40..62b36c002aad5 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.29", + "version": "14.0.4-canary.30", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -23,7 +23,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.29", + "next": "14.0.4-canary.30", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 993494735b96b..0a51b52456b2d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -741,7 +741,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.29 + specifier: 14.0.4-canary.30 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -806,7 +806,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.29 + specifier: 14.0.4-canary.30 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -933,19 +933,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.29 + specifier: 14.0.4-canary.30 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.29 + specifier: 14.0.4-canary.30 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.29 + specifier: 14.0.4-canary.30 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.29 + specifier: 14.0.4-canary.30 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.29 + specifier: 14.0.4-canary.30 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1599,7 +1599,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.29 + specifier: 14.0.4-canary.30 version: link:../next outdent: specifier: 0.8.0 From 511867ceec25441cec83e89ab93d83257658549c Mon Sep 17 00:00:00 2001 From: Zack Tanner Date: Thu, 30 Nov 2023 15:19:46 -0800 Subject: [PATCH 113/481] fix variable name in release workflow (#59135) Follow up to https://github.com/vercel/next.js/pull/59134 --- .github/workflows/trigger_release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/trigger_release.yml b/.github/workflows/trigger_release.yml index 03e31b1bf1d6a..286b896da6ff6 100644 --- a/.github/workflows/trigger_release.yml +++ b/.github/workflows/trigger_release.yml @@ -59,7 +59,7 @@ jobs: - name: Check if new commits since last tag run: | - if [ "$LATEST_TAG" = "$LATEST_COMMIT" ]; then + if [ "$LATEST_TAG_COMMIT" = "$LATEST_COMMIT" ]; then echo "No new commits. Exiting..." exit 1 fi From 1b08dfe040c95f83134a1002519091655c1cf7db Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Thu, 30 Nov 2023 23:22:21 +0000 Subject: [PATCH 114/481] v14.0.4-canary.31 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 16 ++++++++-------- 18 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lerna.json b/lerna.json index 613b5b0575fd5..ca249a31ba439 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.30" + "version": "14.0.4-canary.31" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 46ab3663b7dda..0778bc11aafbf 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.30", + "version": "14.0.4-canary.31", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 415018a661538..5f8d493c22e41 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.30", + "version": "14.0.4-canary.31", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.30", + "@next/eslint-plugin-next": "14.0.4-canary.31", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index b1597c79091f6..0dcd727c8eeb3 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.30", + "version": "14.0.4-canary.31", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index 7a2aa16c7e74e..f6c60f89f6bd4 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.30", + "version": "14.0.4-canary.31", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 911b23aca8d9c..bff6a17c3350c 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.30", + "version": "14.0.4-canary.31", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 80878bcb65009..d398f07d74eea 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.30", + "version": "14.0.4-canary.31", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index b875f6149bedf..2fc7f1503109d 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.30", + "version": "14.0.4-canary.31", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 139b5a4956e26..87bee0c0020c3 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.30", + "version": "14.0.4-canary.31", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 2ce968de008a3..9736c9fcf640f 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.30", + "version": "14.0.4-canary.31", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index eaf8e01607be4..04efb1517d1e4 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.30", + "version": "14.0.4-canary.31", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index 13e9cfe8a85ef..14e7d73cb8a2f 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.30", + "version": "14.0.4-canary.31", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index 415765b214077..557ee400d7ddc 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.30", + "version": "14.0.4-canary.31", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index 12d4de8de2c3d..9704d00d85117 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.30", + "version": "14.0.4-canary.31", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.30", + "@next/env": "14.0.4-canary.31", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -147,11 +147,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.30", - "@next/polyfill-nomodule": "14.0.4-canary.30", - "@next/react-dev-overlay": "14.0.4-canary.30", - "@next/react-refresh-utils": "14.0.4-canary.30", - "@next/swc": "14.0.4-canary.30", + "@next/polyfill-module": "14.0.4-canary.31", + "@next/polyfill-nomodule": "14.0.4-canary.31", + "@next/react-dev-overlay": "14.0.4-canary.31", + "@next/react-refresh-utils": "14.0.4-canary.31", + "@next/swc": "14.0.4-canary.31", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index cd0615a61711c..7e9b084dff371 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.30", + "version": "14.0.4-canary.31", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index 1b1dc1be3740c..b6660b9be0894 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.30", + "version": "14.0.4-canary.31", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index 62b36c002aad5..5dcf2bece864e 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.30", + "version": "14.0.4-canary.31", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -23,7 +23,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.30", + "next": "14.0.4-canary.31", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0a51b52456b2d..e5683fcda124e 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -741,7 +741,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.30 + specifier: 14.0.4-canary.31 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -806,7 +806,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.30 + specifier: 14.0.4-canary.31 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -933,19 +933,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.30 + specifier: 14.0.4-canary.31 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.30 + specifier: 14.0.4-canary.31 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.30 + specifier: 14.0.4-canary.31 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.30 + specifier: 14.0.4-canary.31 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.30 + specifier: 14.0.4-canary.31 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1599,7 +1599,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.30 + specifier: 14.0.4-canary.31 version: link:../next outdent: specifier: 0.8.0 From 1c61153d779da0699d2542842a7d87f8d2cd4d65 Mon Sep 17 00:00:00 2001 From: Vercel Release Bot <88769842+vercel-release-bot@users.noreply.github.com> Date: Thu, 30 Nov 2023 20:20:22 -0500 Subject: [PATCH 115/481] Update font data (#59138) This auto-generated PR updates font data with latest available --- packages/font/src/google/font-data.json | 27 ++++++++++++++++++++++++- packages/font/src/google/index.ts | 6 ++++-- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/packages/font/src/google/font-data.json b/packages/font/src/google/font-data.json index 7a05dc31961a1..7ad4f398d1714 100644 --- a/packages/font/src/google/font-data.json +++ b/packages/font/src/google/font-data.json @@ -7348,8 +7348,33 @@ "subsets": ["hebrew", "latin", "latin-ext"] }, "Noto Sans": { - "weights": ["100", "200", "300", "400", "500", "600", "700", "800", "900"], + "weights": [ + "100", + "200", + "300", + "400", + "500", + "600", + "700", + "800", + "900", + "variable" + ], "styles": ["normal", "italic"], + "axes": [ + { + "tag": "wdth", + "min": 62.5, + "max": 100, + "defaultValue": 100 + }, + { + "tag": "wght", + "min": 100, + "max": 900, + "defaultValue": 400 + } + ], "subsets": [ "cyrillic", "cyrillic-ext", diff --git a/packages/font/src/google/index.ts b/packages/font/src/google/index.ts index c6b9cd987f496..c32c3f54b8745 100644 --- a/packages/font/src/google/index.ts +++ b/packages/font/src/google/index.ts @@ -13376,8 +13376,8 @@ export declare function Noto_Rashi_Hebrew< }): T extends undefined ? NextFont : NextFontWithVariable export declare function Noto_Sans< T extends CssVariable | undefined = undefined ->(options: { - weight: +>(options?: { + weight?: | '100' | '200' | '300' @@ -13387,6 +13387,7 @@ export declare function Noto_Sans< | '700' | '800' | '900' + | 'variable' | Array< '100' | '200' | '300' | '400' | '500' | '600' | '700' | '800' | '900' > @@ -13406,6 +13407,7 @@ export declare function Noto_Sans< | 'latin-ext' | 'vietnamese' > + axes?: 'wdth'[] }): T extends undefined ? NextFont : NextFontWithVariable export declare function Noto_Sans_Adlam< T extends CssVariable | undefined = undefined From a5e60f179b9589fc64f8c11d42940a7a5628d0e5 Mon Sep 17 00:00:00 2001 From: Zack Tanner Date: Thu, 30 Nov 2023 18:25:08 -0800 Subject: [PATCH 116/481] fix typedRoutes when used with webpackBuildWorker (#59140) When using `experimental.typedRoutes` in conjunction with `experimental.webpackBuildWorker`, type errors would be erroneously thrown during build. This is because the build workers are parallelized between multiple runtimes (edge, server, client), but the `typedRoutes` is unique to each `webpackBuild`. The state needs to shared between the different compile steps for each instance of the types plugin. This leverages plugin state to keep share the `typedRoutes` state amongst the different workers. Closes NEXT-1734 Fixes #58369 --- .../plugins/next-types-plugin/index.ts | 52 ++++++++++--------- packages/next/src/server/config-shared.ts | 1 + .../bad-routes/app/api/hello/route.ts | 7 +++ .../bad-routes/app/layout.tsx | 11 ++++ .../bad-routes/app/page.tsx | 9 ++++ .../bad-routes/next.config.js | 7 +++ .../good-routes/app/api/hello/route.ts | 7 +++ .../good-routes/app/layout.tsx | 11 ++++ .../good-routes/app/page.tsx | 9 ++++ .../good-routes/next.config.js | 7 +++ .../typed-routes-with-webpack-worker.test.ts | 40 ++++++++++++++ 11 files changed, 136 insertions(+), 25 deletions(-) create mode 100755 test/production/app-dir/typed-routes-with-webpack-worker/bad-routes/app/api/hello/route.ts create mode 100644 test/production/app-dir/typed-routes-with-webpack-worker/bad-routes/app/layout.tsx create mode 100644 test/production/app-dir/typed-routes-with-webpack-worker/bad-routes/app/page.tsx create mode 100644 test/production/app-dir/typed-routes-with-webpack-worker/bad-routes/next.config.js create mode 100755 test/production/app-dir/typed-routes-with-webpack-worker/good-routes/app/api/hello/route.ts create mode 100644 test/production/app-dir/typed-routes-with-webpack-worker/good-routes/app/layout.tsx create mode 100644 test/production/app-dir/typed-routes-with-webpack-worker/good-routes/app/page.tsx create mode 100644 test/production/app-dir/typed-routes-with-webpack-worker/good-routes/next.config.js create mode 100644 test/production/app-dir/typed-routes-with-webpack-worker/typed-routes-with-webpack-worker.test.ts diff --git a/packages/next/src/build/webpack/plugins/next-types-plugin/index.ts b/packages/next/src/build/webpack/plugins/next-types-plugin/index.ts index caee8b07de407..30ab132edcb09 100644 --- a/packages/next/src/build/webpack/plugins/next-types-plugin/index.ts +++ b/packages/next/src/build/webpack/plugins/next-types-plugin/index.ts @@ -15,6 +15,7 @@ import { isDynamicRoute } from '../../../../shared/lib/router/utils' import { normalizeAppPath } from '../../../../shared/lib/router/utils/app-paths' import { getPageFromPath } from '../../../entries' import { devPageFiles } from './shared' +import { getProxiedPluginState } from '../../../build-context' const PLUGIN_NAME = 'NextTypesPlugin' @@ -221,23 +222,23 @@ async function collectNamedSlots(layoutPath: string) { // By exposing the static route types separately as string literals, // editors can provide autocompletion for them. However it's currently not // possible to provide the same experience for dynamic routes. -const routeTypes: Record< - 'edge' | 'node' | 'extra', - Record<'static' | 'dynamic', string> -> = { - edge: { - static: '', - dynamic: '', - }, - node: { - static: '', - dynamic: '', - }, - extra: { - static: '', - dynamic: '', - }, -} + +const pluginState = getProxiedPluginState({ + routeTypes: { + edge: { + static: '', + dynamic: '', + }, + node: { + static: '', + dynamic: '', + }, + extra: { + static: '', + dynamic: '', + }, + } as Record<'edge' | 'node' | 'extra', Record<'static' | 'dynamic', string>>, +}) function formatRouteToRouteType(route: string) { const isDynamic = isDynamicRoute(route) @@ -341,7 +342,8 @@ function addRedirectsRewritesRouteTypes( for (const normalizedRoute of possibleNormalizedRoutes) { const { isDynamic, routeType } = formatRouteToRouteType(normalizedRoute) - routeTypes.extra[isDynamic ? 'dynamic' : 'static'] += routeType + pluginState.routeTypes.extra[isDynamic ? 'dynamic' : 'static'] += + routeType } } } @@ -374,8 +376,8 @@ function createRouteDefinitions() { let dynamicRouteTypes = '' for (const type of ['edge', 'node', 'extra'] as const) { - staticRouteTypes += routeTypes[type].static - dynamicRouteTypes += routeTypes[type].dynamic + staticRouteTypes += pluginState.routeTypes[type].static + dynamicRouteTypes += pluginState.routeTypes[type].dynamic } // If both StaticRoutes and DynamicRoutes are empty, fallback to type 'string'. @@ -578,7 +580,7 @@ export class NextTypesPlugin { const { isDynamic, routeType } = formatRouteToRouteType(route) - routeTypes[this.isEdgeServer ? 'edge' : 'node'][ + pluginState.routeTypes[this.isEdgeServer ? 'edge' : 'node'][ isDynamic ? 'dynamic' : 'static' ] += routeType } @@ -667,11 +669,11 @@ export class NextTypesPlugin { // Clear routes if (this.isEdgeServer) { - routeTypes.edge.dynamic = '' - routeTypes.edge.static = '' + pluginState.routeTypes.edge.dynamic = '' + pluginState.routeTypes.edge.static = '' } else { - routeTypes.node.dynamic = '' - routeTypes.node.static = '' + pluginState.routeTypes.node.dynamic = '' + pluginState.routeTypes.node.static = '' } compilation.chunkGroups.forEach((chunkGroup) => { diff --git a/packages/next/src/server/config-shared.ts b/packages/next/src/server/config-shared.ts index d2dda84b82f4b..7ba9a6ad3bb7c 100644 --- a/packages/next/src/server/config-shared.ts +++ b/packages/next/src/server/config-shared.ts @@ -806,6 +806,7 @@ export const defaultConfig: NextConfig = { process.env.__NEXT_EXPERIMENTAL_PPR === 'true' ? true : false, + webpackBuildWorker: false, }, } diff --git a/test/production/app-dir/typed-routes-with-webpack-worker/bad-routes/app/api/hello/route.ts b/test/production/app-dir/typed-routes-with-webpack-worker/bad-routes/app/api/hello/route.ts new file mode 100755 index 0000000000000..b72d3b2cc4faa --- /dev/null +++ b/test/production/app-dir/typed-routes-with-webpack-worker/bad-routes/app/api/hello/route.ts @@ -0,0 +1,7 @@ +import { NextRequest, NextResponse } from 'next/server' + +export const runtime = 'edge' + +export async function GET(request: NextRequest) { + return NextResponse.json({ hello: 'world' }) +} diff --git a/test/production/app-dir/typed-routes-with-webpack-worker/bad-routes/app/layout.tsx b/test/production/app-dir/typed-routes-with-webpack-worker/bad-routes/app/layout.tsx new file mode 100644 index 0000000000000..ce81757e7c107 --- /dev/null +++ b/test/production/app-dir/typed-routes-with-webpack-worker/bad-routes/app/layout.tsx @@ -0,0 +1,11 @@ +import React from 'react' + +export const dynamic = 'force-dynamic' + +export default function Root({ children }: { children: React.ReactNode }) { + return ( + + {children} + + ) +} diff --git a/test/production/app-dir/typed-routes-with-webpack-worker/bad-routes/app/page.tsx b/test/production/app-dir/typed-routes-with-webpack-worker/bad-routes/app/page.tsx new file mode 100644 index 0000000000000..f30de2d088aa2 --- /dev/null +++ b/test/production/app-dir/typed-routes-with-webpack-worker/bad-routes/app/page.tsx @@ -0,0 +1,9 @@ +import Link from 'next/link' + +export default function Home() { + return ( +
+ Hello, world! +
+ ) +} diff --git a/test/production/app-dir/typed-routes-with-webpack-worker/bad-routes/next.config.js b/test/production/app-dir/typed-routes-with-webpack-worker/bad-routes/next.config.js new file mode 100644 index 0000000000000..ed7707d2a91a3 --- /dev/null +++ b/test/production/app-dir/typed-routes-with-webpack-worker/bad-routes/next.config.js @@ -0,0 +1,7 @@ +/** @type {import('next').NextConfig} */ +module.exports = { + experimental: { + typedRoutes: true, + webpackBuildWorker: true, + }, +} diff --git a/test/production/app-dir/typed-routes-with-webpack-worker/good-routes/app/api/hello/route.ts b/test/production/app-dir/typed-routes-with-webpack-worker/good-routes/app/api/hello/route.ts new file mode 100755 index 0000000000000..b72d3b2cc4faa --- /dev/null +++ b/test/production/app-dir/typed-routes-with-webpack-worker/good-routes/app/api/hello/route.ts @@ -0,0 +1,7 @@ +import { NextRequest, NextResponse } from 'next/server' + +export const runtime = 'edge' + +export async function GET(request: NextRequest) { + return NextResponse.json({ hello: 'world' }) +} diff --git a/test/production/app-dir/typed-routes-with-webpack-worker/good-routes/app/layout.tsx b/test/production/app-dir/typed-routes-with-webpack-worker/good-routes/app/layout.tsx new file mode 100644 index 0000000000000..ce81757e7c107 --- /dev/null +++ b/test/production/app-dir/typed-routes-with-webpack-worker/good-routes/app/layout.tsx @@ -0,0 +1,11 @@ +import React from 'react' + +export const dynamic = 'force-dynamic' + +export default function Root({ children }: { children: React.ReactNode }) { + return ( + + {children} + + ) +} diff --git a/test/production/app-dir/typed-routes-with-webpack-worker/good-routes/app/page.tsx b/test/production/app-dir/typed-routes-with-webpack-worker/good-routes/app/page.tsx new file mode 100644 index 0000000000000..556d2ef63ad5d --- /dev/null +++ b/test/production/app-dir/typed-routes-with-webpack-worker/good-routes/app/page.tsx @@ -0,0 +1,9 @@ +import Link from 'next/link' + +export default function Home() { + return ( +
+ Hello, world! +
+ ) +} diff --git a/test/production/app-dir/typed-routes-with-webpack-worker/good-routes/next.config.js b/test/production/app-dir/typed-routes-with-webpack-worker/good-routes/next.config.js new file mode 100644 index 0000000000000..ed7707d2a91a3 --- /dev/null +++ b/test/production/app-dir/typed-routes-with-webpack-worker/good-routes/next.config.js @@ -0,0 +1,7 @@ +/** @type {import('next').NextConfig} */ +module.exports = { + experimental: { + typedRoutes: true, + webpackBuildWorker: true, + }, +} diff --git a/test/production/app-dir/typed-routes-with-webpack-worker/typed-routes-with-webpack-worker.test.ts b/test/production/app-dir/typed-routes-with-webpack-worker/typed-routes-with-webpack-worker.test.ts new file mode 100644 index 0000000000000..a2d5880ba26d9 --- /dev/null +++ b/test/production/app-dir/typed-routes-with-webpack-worker/typed-routes-with-webpack-worker.test.ts @@ -0,0 +1,40 @@ +import { nextBuild } from 'next-test-utils' +import path from 'path' + +describe('app dir - typed-routes-with-webpack-worker', () => { + it('builds successfully without errors', async () => { + const output = await nextBuild( + path.join(__dirname, 'good-routes'), + undefined, + { + stdout: true, + stderr: true, + } + ) + + // check for the experimental flag warning + expect(output.stdout).toContain('webpackBuildWorker') + // should have a successful build + expect(output.code).toBe(0) + // with no errors + expect(output.stderr).not.toContain(`"/" is not an existing route.`) + }) + + it('builds with valid errors', async () => { + const output = await nextBuild( + path.join(__dirname, 'bad-routes'), + undefined, + { + stdout: true, + stderr: true, + } + ) + + // check for the experimental flag warning + expect(output.stdout).toContain('webpackBuildWorker') + // should have a failed build + expect(output.code).toBe(1) + // with correct error + expect(output.stderr).toContain(`"/asdfasdfasdf" is not an existing route.`) + }) +}) From cdff6df0980b854b7c0ce06ada82bc58ab545d2a Mon Sep 17 00:00:00 2001 From: Michael Diodone <8616698+mdio@users.noreply.github.com> Date: Fri, 1 Dec 2023 04:05:20 +0100 Subject: [PATCH 117/481] Add NEXT_MANUAL_SIG_HANDLE handling to start-server.ts (#59117) If a manual signal handler is registered, SIGINT and SIGTERM should not be handled by Next.js. This was already the case in the standalone server.js but was missing here, rendering the env flag useless. With this fix, the example given in https://nextjs.org/docs/pages/building-your-application/deploying#manual-graceful-shutdowns is working (again). Fixes #56810. Co-authored-by: Zack Tanner --- packages/next/src/server/lib/start-server.ts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/packages/next/src/server/lib/start-server.ts b/packages/next/src/server/lib/start-server.ts index fd501c6ab8ad0..84610325b0632 100644 --- a/packages/next/src/server/lib/start-server.ts +++ b/packages/next/src/server/lib/start-server.ts @@ -280,9 +280,11 @@ export async function startServer( console.error(err) } process.on('exit', (code) => cleanup(code)) - // callback value is signal string, exit with 0 - process.on('SIGINT', () => cleanup(0)) - process.on('SIGTERM', () => cleanup(0)) + if (!process.env.NEXT_MANUAL_SIG_HANDLE) { + // callback value is signal string, exit with 0 + process.on('SIGINT', () => cleanup(0)) + process.on('SIGTERM', () => cleanup(0)) + } process.on('rejectionHandled', () => { // It is ok to await a Promise late in Next.js as it allows for better // prefetching patterns to avoid waterfalls. We ignore loggining these. From 7458ffa042c2141bd18b119d93d064acaba42315 Mon Sep 17 00:00:00 2001 From: Christian Vuerings Date: Thu, 30 Nov 2023 19:40:57 -0800 Subject: [PATCH 118/481] Support adding CSP nonce with `content-security-policy-report-only` header (#59071) **Note**: this is a 1-to-1 copy of #48969 by @danieltott with all the merge conflicts fixed. ## Checklist * Fixes https://github.com/vercel/next.js/issues/48966 * Tests added to `test/production/app-dir/subresource-integrity/subresource-integrity.test.ts` ## Description Currently `renderToHTMLOrFlight` in app-render pulls out a nonce value from a `content-security-policy` header for use in generating script tags: https://github.com/vercel/next.js/blob/e7c9d3c051e6027cf187e0d70565417d6037e37c/packages/next/src/server/app-render/app-render.tsx#L1204 That misses the ability to use a [content-security-policy-report-only header](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy-Report-Only). Many times this is a required step to enabling a CSP - by shipping a CSP with report-only and collecting reports before actually blocking resources. ## Changes * Added ability to check `content-security-policy-report-only` header in `renderToHTMLOrFlight()` * Added test to verify `nonce` is correctly applied when `content-security-policy-report-only` header exists Co-authored-by: Dan Ott Co-authored-by: Zack Tanner --- .../next/src/server/app-render/app-render.tsx | 4 +- .../subresource-integrity.test.ts | 44 +++++++++++++++++-- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/packages/next/src/server/app-render/app-render.tsx b/packages/next/src/server/app-render/app-render.tsx index 53664456c2119..407b66af3adeb 100644 --- a/packages/next/src/server/app-render/app-render.tsx +++ b/packages/next/src/server/app-render/app-render.tsx @@ -658,7 +658,9 @@ async function renderToHTMLOrFlightImpl( : null // Get the nonce from the incoming request if it has one. - const csp = req.headers['content-security-policy'] + const csp = + req.headers['content-security-policy'] || + req.headers['content-security-policy-report-only'] let nonce: string | undefined if (csp && typeof csp === 'string') { nonce = getScriptNonceFromHeader(csp) diff --git a/test/production/app-dir/subresource-integrity/subresource-integrity.test.ts b/test/production/app-dir/subresource-integrity/subresource-integrity.test.ts index 7664abf7fd129..61cd9be169a1c 100644 --- a/test/production/app-dir/subresource-integrity/subresource-integrity.test.ts +++ b/test/production/app-dir/subresource-integrity/subresource-integrity.test.ts @@ -9,18 +9,24 @@ createNextDescribe( files: path.join(__dirname, 'fixture'), }, ({ next }) => { - function fetchWithPolicy(policy: string | null) { + function fetchWithPolicy(policy: string | null, reportOnly?: boolean) { + const cspKey = reportOnly + ? 'Content-Security-Policy-Report-Only' + : 'Content-Security-Policy' return next.fetch('/dashboard', { headers: policy ? { - 'Content-Security-Policy': policy, + [cspKey]: policy, } : {}, }) } - async function renderWithPolicy(policy: string | null) { - const res = await fetchWithPolicy(policy) + async function renderWithPolicy( + policy: string | null, + reportOnly?: boolean + ) { + const res = await fetchWithPolicy(policy, reportOnly) expect(res.ok).toBe(true) @@ -78,6 +84,36 @@ createNextDescribe( } }) + it('includes a nonce value with inline scripts when Content-Security-Policy-Report-Only header is defined', async () => { + // A random nonce value, base64 encoded. + const nonce = 'cmFuZG9tCg==' + + // Validate all the cases where we could parse the nonce. + const policies = [ + `script-src 'nonce-${nonce}'`, // base case + ` script-src 'nonce-${nonce}' `, // extra space added around sources and directive + `style-src 'self'; script-src 'nonce-${nonce}'`, // extra directives + `script-src 'self' 'nonce-${nonce}' 'nonce-othernonce'`, // extra nonces + `default-src 'nonce-othernonce'; script-src 'nonce-${nonce}';`, // script and then fallback case + `default-src 'nonce-${nonce}'`, // fallback case + ] + + for (const policy of policies) { + const $ = await renderWithPolicy(policy, true) + + // Find all the script tags without src attributes. + const elements = $('script:not([src])') + + // Expect there to be at least 1 script tag without a src attribute. + expect(elements.length).toBeGreaterThan(0) + + // Expect all inline scripts to have the nonce value. + elements.each((i, el) => { + expect(el.attribs['nonce']).toBe(nonce) + }) + } + }) + it('includes a nonce value with bootstrap scripts when Content-Security-Policy header is defined', async () => { // A random nonce value, base64 encoded. const nonce = 'cmFuZG9tCg==' From fa9cd3efc4b310557aeb0ca2a008a4d5bda34046 Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Fri, 1 Dec 2023 04:31:03 +0000 Subject: [PATCH 119/481] v14.0.4-canary.32 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 16 ++++++++-------- 18 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lerna.json b/lerna.json index ca249a31ba439..9dc50ac12635a 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.31" + "version": "14.0.4-canary.32" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 0778bc11aafbf..ed9d905cdda11 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.31", + "version": "14.0.4-canary.32", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 5f8d493c22e41..783563105fdf1 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.31", + "version": "14.0.4-canary.32", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.31", + "@next/eslint-plugin-next": "14.0.4-canary.32", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 0dcd727c8eeb3..9eb41bf8a28fd 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.31", + "version": "14.0.4-canary.32", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index f6c60f89f6bd4..b4b2b0ede045c 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.31", + "version": "14.0.4-canary.32", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index bff6a17c3350c..2a8920dcfa71b 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.31", + "version": "14.0.4-canary.32", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index d398f07d74eea..5085450317c45 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.31", + "version": "14.0.4-canary.32", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 2fc7f1503109d..7638b48733614 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.31", + "version": "14.0.4-canary.32", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 87bee0c0020c3..8e6c50d2bf49c 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.31", + "version": "14.0.4-canary.32", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 9736c9fcf640f..9a65f5a7365b9 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.31", + "version": "14.0.4-canary.32", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index 04efb1517d1e4..95861675a41c1 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.31", + "version": "14.0.4-canary.32", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index 14e7d73cb8a2f..93496f85776cb 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.31", + "version": "14.0.4-canary.32", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index 557ee400d7ddc..ae92bdba6c1de 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.31", + "version": "14.0.4-canary.32", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index 9704d00d85117..4dd3e435abd7f 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.31", + "version": "14.0.4-canary.32", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.31", + "@next/env": "14.0.4-canary.32", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -147,11 +147,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.31", - "@next/polyfill-nomodule": "14.0.4-canary.31", - "@next/react-dev-overlay": "14.0.4-canary.31", - "@next/react-refresh-utils": "14.0.4-canary.31", - "@next/swc": "14.0.4-canary.31", + "@next/polyfill-module": "14.0.4-canary.32", + "@next/polyfill-nomodule": "14.0.4-canary.32", + "@next/react-dev-overlay": "14.0.4-canary.32", + "@next/react-refresh-utils": "14.0.4-canary.32", + "@next/swc": "14.0.4-canary.32", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index 7e9b084dff371..dd02ce6438b66 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.31", + "version": "14.0.4-canary.32", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index b6660b9be0894..a28de74e82edc 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.31", + "version": "14.0.4-canary.32", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index 5dcf2bece864e..b37c7c31872b4 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.31", + "version": "14.0.4-canary.32", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -23,7 +23,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.31", + "next": "14.0.4-canary.32", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e5683fcda124e..39fa286d13e51 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -741,7 +741,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.31 + specifier: 14.0.4-canary.32 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -806,7 +806,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.31 + specifier: 14.0.4-canary.32 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -933,19 +933,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.31 + specifier: 14.0.4-canary.32 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.31 + specifier: 14.0.4-canary.32 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.31 + specifier: 14.0.4-canary.32 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.31 + specifier: 14.0.4-canary.32 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.31 + specifier: 14.0.4-canary.32 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1599,7 +1599,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.31 + specifier: 14.0.4-canary.32 version: link:../next outdent: specifier: 0.8.0 From 89f6322cda88b4972a7e11651327e53144b0ea10 Mon Sep 17 00:00:00 2001 From: Ahmed Abdelbaset Date: Fri, 1 Dec 2023 10:53:02 +0200 Subject: [PATCH 120/481] chore: fix typo in jsDoc (#58224) --- packages/next/types/index.d.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/next/types/index.d.ts b/packages/next/types/index.d.ts index e22cdbc21efb2..062e333c2f217 100644 --- a/packages/next/types/index.d.ts +++ b/packages/next/types/index.d.ts @@ -87,7 +87,7 @@ export type Redirect = } /** - * `Page` type, use it as a guide to create `pages`. + * `NextPage` type, use it as a guide to create `pages`. */ export type NextPage = NextComponentType< NextPageContext, From b02a10e331dcc6e484cecd6954ec4e07dea96fda Mon Sep 17 00:00:00 2001 From: Karl Horky Date: Fri, 1 Dec 2023 09:57:57 +0100 Subject: [PATCH 121/481] Enable typechecking on config (#57892) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Lee Robinson Co-authored-by: Balázs Orbán --- examples/reproduction-template-pages/next.config.js | 4 +++- examples/reproduction-template/next.config.js | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/examples/reproduction-template-pages/next.config.js b/examples/reproduction-template-pages/next.config.js index 0e5c476c943b1..4e2b4c73287b4 100644 --- a/examples/reproduction-template-pages/next.config.js +++ b/examples/reproduction-template-pages/next.config.js @@ -1,4 +1,6 @@ /** @type {import("next").NextConfig} */ -module.exports = { +const nextConfig = { reactStrictMode: true, } + +module.exports = nextConfig diff --git a/examples/reproduction-template/next.config.js b/examples/reproduction-template/next.config.js index 0e5c476c943b1..4e2b4c73287b4 100644 --- a/examples/reproduction-template/next.config.js +++ b/examples/reproduction-template/next.config.js @@ -1,4 +1,6 @@ /** @type {import("next").NextConfig} */ -module.exports = { +const nextConfig = { reactStrictMode: true, } + +module.exports = nextConfig From f47640375ad894cdc9cc5a9fef7d0efe5fbbe22c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20H=C3=A4nisch?= Date: Fri, 1 Dec 2023 10:58:02 +0100 Subject: [PATCH 122/481] fix: add `maxDuration` to `PageConfig` type (#55918) --- packages/next/types/index.d.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/packages/next/types/index.d.ts b/packages/next/types/index.d.ts index 062e333c2f217..bda45bbd50066 100644 --- a/packages/next/types/index.d.ts +++ b/packages/next/types/index.d.ts @@ -140,6 +140,11 @@ export type PageConfig = { externalResolver?: true } env?: Array + /** + * Configures the longest time in seconds a serverless function can process an HTTP + * request before responding. + */ + maxDuration?: number runtime?: ServerRuntime unstable_runtimeJS?: false unstable_JsPreload?: false From cc42e437ea54e3705eb6efd9f94b8908db77820c Mon Sep 17 00:00:00 2001 From: Vercel Release Bot <88769842+vercel-release-bot@users.noreply.github.com> Date: Fri, 1 Dec 2023 05:16:28 -0500 Subject: [PATCH 123/481] Update Turbopack test manifest (#59109) This auto-generated PR updates the integration test manifest used when testing Turbopack. --------- Co-authored-by: Tobias Koppers --- test/build-turbopack-tests-manifest.js | 53 +++- test/turbopack-tests-manifest.json | 372 ++++++++++++++++++------- 2 files changed, 320 insertions(+), 105 deletions(-) diff --git a/test/build-turbopack-tests-manifest.js b/test/build-turbopack-tests-manifest.js index 1230c4f8d4a2d..a49c01bae27ad 100644 --- a/test/build-turbopack-tests-manifest.js +++ b/test/build-turbopack-tests-manifest.js @@ -24,21 +24,21 @@ const INITIALIZING_TEST_CASES = [ // please make sure this is sorted alphabetically when making changes. const SKIPPED_TEST_SUITES = { 'test/development/acceptance-app/ReactRefreshRegression.test.ts': [ - 'ReactRefreshRegression app can fast refresh a page with dynamic rendering', 'ReactRefreshRegression app can fast refresh a page with config', + 'ReactRefreshRegression app can fast refresh a page with dynamic rendering', ], 'test/development/acceptance-app/ReactRefreshRequire.test.ts': [ - 'ReactRefreshRequire app re-runs accepted modules', 'ReactRefreshRequire app propagates a hot update to closest accepted module', 'ReactRefreshRequire app propagates hot update to all inverse dependencies', + 'ReactRefreshRequire app re-runs accepted modules', ], 'test/development/acceptance/ReactRefreshLogBox.test.ts': [ 'ReactRefreshLogBox turbo conversion to class component (1)', ], 'test/development/acceptance/ReactRefreshRequire.test.ts': [ - 'ReactRefreshRequire re-runs accepted modules', 'ReactRefreshRequire propagates a hot update to closest accepted module', 'ReactRefreshRequire propagates hot update to all inverse dependencies', + 'ReactRefreshRequire re-runs accepted modules', ], 'test/development/basic/hmr.test.ts': [ 'basic HMR, basePath: "/docs" Error Recovery should show the error on all pages', @@ -47,8 +47,16 @@ const SKIPPED_TEST_SUITES = { /should automatically fast refresh content when path is added without error/, /should recover from module not found when paths is updated/, ], + 'test/development/middleware-errors/index.test.ts': [ + 'middleware - development errors when there is a compilation error after boot logs the error correctly', + 'middleware - development errors when there is a compilation error from boot logs the error correctly', + ], 'test/development/tsconfig-path-reloading/index.test.ts': [ /should automatically fast refresh content when path is added without error/, + 'tsconfig-path-reloading tsconfig added after starting dev should load with initial paths config correctly', + ], + 'test/e2e/app-dir/app-compilation/index.test.ts': [ + 'app dir HMR should not cause error when removing loading.js', ], 'test/e2e/app-dir/app-css/index.test.ts': [ 'app dir - css css support server layouts should support external css imports', @@ -68,6 +76,9 @@ const SKIPPED_TEST_SUITES = { 'basePath should 404 when manually adding basePath with router.push', 'basePath should 404 when manually adding basePath with router.replace', ], + 'test/e2e/conflicting-app-page-error/index.test.ts': [ + 'Conflict between app file and pages file should not show error overlay for non conflict pages under app or pages dir', + ], 'test/e2e/middleware-rewrites/test/index.test.ts': [ 'Middleware Rewrite should have props for afterFiles rewrite to SSG page', ], @@ -82,8 +93,8 @@ const SKIPPED_TEST_SUITES = { 'Document and App Client side should detect the changes to pages/_document.js and display it', ], 'test/integration/css/test/css-modules.test.js': [ - 'CSS Modules Composes Ordering Development Mode should have correct color on index page (on nav from other)', 'CSS Modules Composes Ordering Development Mode should have correct color on index page (on nav from index)', + 'CSS Modules Composes Ordering Development Mode should have correct color on index page (on nav from other)', ], 'test/integration/custom-error/test/index.test.js': [/Custom _error/], 'test/integration/dynamic-routing/test/index.test.js': [ @@ -96,13 +107,41 @@ const SKIPPED_TEST_SUITES = { 'Dynamic Routing production mode should output a routes-manifest correctly', ], 'test/integration/env-config/test/index.test.js': [ - 'Env Config dev mode with hot reload should provide env for SSG', - 'Env Config dev mode with hot reload should provide env correctly for SSR', 'Env Config dev mode with hot reload should provide env correctly for API routes', + 'Env Config dev mode with hot reload should provide env correctly for SSR', + 'Env Config dev mode with hot reload should provide env for SSG', ], 'test/integration/import-assertion/test/index.test.js': [ /should handle json assertions/, ], + 'test/integration/next-image-legacy/unicode/test/index.test.ts': [ + /Image Component Unicode Image URL/, + ], + 'test/integration/next-image-new/unicode/test/index.test.ts': [ + /Image Component Unicode Image URL/, + ], +} + +function checkSorted(arr, name) { + const sorted = [...arr].sort() + if (JSON.stringify(arr) !== JSON.stringify(sorted)) { + console.log(`Expected order of ${name}:`) + for (let i = 0; i < arr.length; i++) { + if (arr[i] === sorted[i]) { + console.log(` ${arr[i]}`) + } else { + console.log(bold().red(`- ${arr[i]}`)) + console.log(bold().green(`+ ${sorted[i]}`)) + } + } + throw new Error(`${name} is not sorted`) + } +} + +checkSorted(Object.keys(SKIPPED_TEST_SUITES), 'SKIPPED_TEST_SUITES') + +for (const [key, value] of Object.entries(SKIPPED_TEST_SUITES)) { + checkSorted(value, `SKIPPED_TEST_SUITES['${key}']`) } /** @@ -234,7 +273,7 @@ async function updatePassingTests() { if (skippedPassingNames.length > 0) { console.log( - `${bold().red(filepath)} has ${ + `${bold().yellow(filepath)} has ${ skippedPassingNames.length } passing tests that are marked as skipped:\n${skippedPassingNames .map((name) => ` - ${name}`) diff --git a/test/turbopack-tests-manifest.json b/test/turbopack-tests-manifest.json index 5a3fa8d053b95..3e09257874799 100644 --- a/test/turbopack-tests-manifest.json +++ b/test/turbopack-tests-manifest.json @@ -204,23 +204,6 @@ "flakey": [], "runtimeError": false }, - "packages/next/src/client/components/router-reducer/create-optimistic-tree.test.ts": { - "passed": ["createOptimisticTree should create an optimistic tree"], - "failed": [], - "pending": [], - "flakey": [], - "runtimeError": false - }, - "packages/next/src/client/components/router-reducer/create-record-from-thenable.test.ts": { - "passed": [ - "createRecordFromThenable rejecting promise", - "createRecordFromThenable successful promise" - ], - "failed": [], - "pending": [], - "flakey": [], - "runtimeError": false - }, "packages/next/src/client/components/router-reducer/create-router-cache-key.test.ts": { "passed": [ "createRouterCacheKey should support catch all segment", @@ -462,6 +445,16 @@ "flakey": [], "runtimeError": false }, + "packages/next/src/server/config.test.ts": { + "passed": [ + "loadConfig nextConfig.images defaults should assign a `images.remotePatterns` when using assetPrefix", + "loadConfig nextConfig.images defaults should not assign a duplicate `images.remotePatterns` value when using assetPrefix" + ], + "failed": [], + "pending": [], + "flakey": [], + "runtimeError": false + }, "packages/next/src/server/dev/parse-version-info.test.ts": { "passed": [ "parse version info installed: 12.0.0, latest: 13.1.1, canary: 13.0.1-canary.0 yields stale-major", @@ -1401,6 +1394,13 @@ "flakey": [], "runtimeError": false }, + "test/development/app-dir/experimental-lightningcss/experimental-lightningcss.test.ts": { + "passed": ["experimental-lightningcss should support css modules"], + "failed": [], + "pending": [], + "flakey": [], + "runtimeError": false + }, "test/development/app-dir/multiple-compiles-single-route/multiple-compiles-single-route.test.ts": { "passed": [ "multiple-compiles-single-route should not compile additional matching paths" @@ -1449,15 +1449,16 @@ "runtimeError": false }, "test/development/basic/barrel-optimization/barrel-optimization.test.ts": { - "passed": [], + "passed": [ + "optimizePackageImports should handle recursive wildcard exports", + "optimizePackageImports should not break \"use client\" directive in optimized packages", + "optimizePackageImports should support \"use client\" directive in barrel file" + ], "failed": [ "optimizePackageImports app - should optimize recursive wildcard export mapping", "optimizePackageImports app - should render the icons correctly without creating all the modules", "optimizePackageImports pages - should optimize recursive wildcard export mapping", "optimizePackageImports pages - should render the icons correctly without creating all the modules", - "optimizePackageImports should handle recursive wildcard exports", - "optimizePackageImports should not break \"use client\" directive in optimized packages", - "optimizePackageImports should support \"use client\" directive in barrel file", "optimizePackageImports should support visx" ], "pending": [], @@ -1841,6 +1842,7 @@ "middleware - development errors when middleware throws synchronously renders the error correctly and recovers", "middleware - development errors when running invalid dynamic code with eval logs the error correctly", "middleware - development errors when there is a compilation error after boot renders the error correctly and recovers", + "middleware - development errors when there is a compilation error from boot renders the error correctly and recovers", "middleware - development errors when there is an unhandled rejection while loading a dependency does not render the error", "middleware - development errors when there is an unhandled rejection while loading a dependency logs the error correctly", "middleware - development errors when there is an unhandled rejection while loading the module does not render the error", @@ -1849,14 +1851,14 @@ "failed": [ "middleware - development errors when middleware throws synchronously logs the error correctly", "middleware - development errors when running invalid dynamic code with eval renders the error correctly and recovers", - "middleware - development errors when there is a compilation error after boot logs the error correctly", - "middleware - development errors when there is a compilation error from boot logs the error correctly", - "middleware - development errors when there is a compilation error from boot renders the error correctly and recovers", "middleware - development errors when throwing while loading the module logs the error correctly", "middleware - development errors when throwing while loading the module renders the error correctly and recovers" ], "pending": [], - "flakey": [], + "flakey": [ + "middleware - development errors when there is a compilation error after boot logs the error correctly", + "middleware - development errors when there is a compilation error from boot logs the error correctly" + ], "runtimeError": false }, "test/development/middleware-warnings/index.test.ts": { @@ -2074,16 +2076,17 @@ }, "test/development/tsconfig-path-reloading/index.test.ts": { "passed": [ - "tsconfig-path-reloading tsconfig added after starting dev should load with initial paths config correctly", "tsconfig-path-reloading tsconfig should load with initial paths config correctly" ], - "failed": [], + "failed": [ + "tsconfig-path-reloading tsconfig added after starting dev should recover from module not found when paths is updated", + "tsconfig-path-reloading tsconfig should recover from module not found when paths is updated" + ], "pending": [], "flakey": [ "tsconfig-path-reloading tsconfig added after starting dev should automatically fast refresh content when path is added without error", - "tsconfig-path-reloading tsconfig added after starting dev should recover from module not found when paths is updated", - "tsconfig-path-reloading tsconfig should automatically fast refresh content when path is added without error", - "tsconfig-path-reloading tsconfig should recover from module not found when paths is updated" + "tsconfig-path-reloading tsconfig added after starting dev should load with initial paths config correctly", + "tsconfig-path-reloading tsconfig should automatically fast refresh content when path is added without error" ], "runtimeError": false }, @@ -2131,7 +2134,7 @@ "failed": [], "pending": [], "flakey": [], - "runtimeError": true + "runtimeError": false }, "test/e2e/app-dir-legacy-edge-runtime-config/index.test.ts": { "passed": [], @@ -2241,8 +2244,15 @@ "app-dir action handling fetch actions should revalidate when cookies.set is called", "app-dir action handling fetch actions should revalidate when cookies.set is called in a client action", "app-dir action handling fetch actions should store revalidation data in the prefetch cache", + "app-dir action handling redirects redirects properly when server action handler redirects with a 307 status code", + "app-dir action handling redirects redirects properly when server action handler redirects with a 308 status code", + "app-dir action handling redirects redirects properly when server action handler uses `permanentRedirect`", + "app-dir action handling redirects redirects properly when server action handler uses `redirect`", + "app-dir action handling should 404 when POSTing an invalid server action", "app-dir action handling should bundle external libraries if they are on the action layer", + "app-dir action handling should handle actions executed in quick succession", "app-dir action handling should handle basic actions correctly", + "app-dir action handling should log a warning when a server action is not found but an id is provided", "app-dir action handling should not block navigation events while a server action is in flight", "app-dir action handling should only submit action once when resubmitting an action after navigation", "app-dir action handling should push new route when redirecting", @@ -2255,6 +2265,7 @@ "app-dir action handling should support importing actions in client components", "app-dir action handling should support importing the same action module instance in both server and action layers", "app-dir action handling should support next/dynamic with ssr: false", + "app-dir action handling should support next/dynamic with ssr: false (edge)", "app-dir action handling should support notFound", "app-dir action handling should support notFound (javascript disabled)", "app-dir action handling should support setting cookies in route handlers with the correct overrides", @@ -2312,10 +2323,10 @@ "runtimeError": false }, "test/e2e/app-dir/app-compilation/index.test.ts": { - "passed": ["app dir HMR should not cause error when removing loading.js"], + "passed": [], "failed": [], "pending": [], - "flakey": [], + "flakey": ["app dir HMR should not cause error when removing loading.js"], "runtimeError": false }, "test/e2e/app-dir/app-config-crossorigin/index.test.ts": { @@ -2420,6 +2431,7 @@ "passed": [ "app dir - external dependency react in external esm packages should use the same react in client app", "app dir - external dependency react in external esm packages should use the same react in edge server app", + "app dir - external dependency react in external esm packages should use the same react in pages", "app dir - external dependency react in external esm packages should use the same react in server app", "app dir - external dependency should correctly collect global css imports and mark them as side effects", "app dir - external dependency should export client module references in esm", @@ -2435,7 +2447,6 @@ "app dir - external dependency should use the same export type for packages in both ssr and client" ], "failed": [ - "app dir - external dependency react in external esm packages should use the same react in pages", "app dir - external dependency should be able to opt-out 3rd party packages being bundled in server components", "app dir - external dependency should have proper tree-shaking for known modules in CJS" ], @@ -2445,6 +2456,7 @@ }, "test/e2e/app-dir/app-fetch-deduping/app-fetch-deduping.test.ts": { "passed": [ + "app-fetch-deduping during next dev should dedupe pending revalidation requests", "app-fetch-deduping during next dev should dedupe requests called from the same component" ], "failed": [], @@ -2454,9 +2466,12 @@ }, "test/e2e/app-dir/app-middleware/app-middleware.test.ts": { "passed": [ - "app dir - middleware without pages dir Updates headers", "app dir - middleware with middleware in src dir works without crashing when using requestAsyncStorage", + "app dir - middleware without pages dir Updates headers", + "app-dir with middleware Mutate request headers for Edge Functions Adds new headers", + "app-dir with middleware Mutate request headers for Edge Functions Deletes headers", "app-dir with middleware Mutate request headers for Edge Functions Supports draft mode", + "app-dir with middleware Mutate request headers for Edge Functions Updates headers", "app-dir with middleware Mutate request headers for Serverless Functions Adds new headers", "app-dir with middleware Mutate request headers for Serverless Functions Deletes headers", "app-dir with middleware Mutate request headers for Serverless Functions Supports draft mode", @@ -2465,9 +2480,6 @@ "app-dir with middleware Mutate request headers for next/headers Deletes headers", "app-dir with middleware Mutate request headers for next/headers Supports draft mode", "app-dir with middleware Mutate request headers for next/headers Updates headers", - "app-dir with middleware Mutate request headers for Edge Functions Adds new headers", - "app-dir with middleware Mutate request headers for Edge Functions Deletes headers", - "app-dir with middleware Mutate request headers for Edge Functions Updates headers", "app-dir with middleware should filter correctly after middleware rewrite" ], "failed": [], @@ -2475,6 +2487,16 @@ "flakey": [], "runtimeError": false }, + "test/e2e/app-dir/app-prefetch-false-loading/app-prefetch-false-loading.test.ts": { + "passed": [ + "app-prefetch-false-loading should not re-trigger loading state when navigating between pages that share a dynamic layout", + "app-prefetch-false-loading should render loading for the inital render" + ], + "failed": [], + "pending": [], + "flakey": [], + "runtimeError": false + }, "test/e2e/app-dir/app-prefetch-false/app-prefetch-false.test.ts": { "passed": [], "failed": [], @@ -2568,6 +2590,7 @@ "app-custom-routes hooks notFound can respond correctly", "app-custom-routes hooks permanentRedirect can respond correctly", "app-custom-routes hooks redirect can respond correctly", + "app-custom-routes hooks req.cookies gets the correct values", "app-custom-routes invalid exports should print an error when exporting a default handler in dev", "app-custom-routes no response returned should print an error when no response is returned", "app-custom-routes works with api prefix correctly does not statically generate with dynamic usage", @@ -2632,6 +2655,7 @@ "app-custom-routes hooks notFound can respond correctly", "app-custom-routes hooks permanentRedirect can respond correctly", "app-custom-routes hooks redirect can respond correctly", + "app-custom-routes hooks req.cookies gets the correct values", "app-custom-routes invalid exports should print an error when exporting a default handler in dev", "app-custom-routes no response returned should print an error when no response is returned", "app-custom-routes works with api prefix correctly does not statically generate with dynamic usage", @@ -3088,6 +3112,8 @@ }, "test/e2e/app-dir/dynamic/dynamic.test.ts": { "passed": [ + "app dir - next/dynamic no SSR should not render client component imported through ssr: false in client components", + "app dir - next/dynamic no SSR should not render client component imported through ssr: false in client components in edge runtime", "app dir - next/dynamic should generate correct client manifest for dynamic chunks", "app dir - next/dynamic should handle next/dynamic in SSR correctly", "app dir - next/dynamic should handle next/dynamic in hydration correctly", @@ -3098,6 +3124,16 @@ "flakey": [], "runtimeError": false }, + "test/e2e/app-dir/edge-route-rewrite/edge-route-rewrite.test.ts": { + "passed": [ + "edge-route-rewrite it should support a rewrite to a dynamic edge route", + "edge-route-rewrite it should support a rewrite to an edge route" + ], + "failed": [], + "pending": [], + "flakey": [], + "runtimeError": false + }, "test/e2e/app-dir/edge-runtime-node-compatibility/edge-runtime-node-compatibility.test.ts": { "passed": [], "failed": [ @@ -3184,6 +3220,17 @@ "flakey": [], "runtimeError": false }, + "test/e2e/app-dir/global-error/catch-all/index.test.ts": { + "passed": [ + "app dir - global error - with catch-all route should render catch-all route correctly" + ], + "failed": [ + "app dir - global error - with catch-all route should render 404 page correctly" + ], + "pending": [], + "flakey": [], + "runtimeError": false + }, "test/e2e/app-dir/global-error/layout-error/index.test.ts": { "passed": [ "app dir - global error - layout error should render global error for error in server components" @@ -3271,6 +3318,7 @@ }, "test/e2e/app-dir/interception-middleware-rewrite/interception-middleware-rewrite.test.ts": { "passed": [ + "interception-middleware-rewrite should continue to work after using browser back button and following another intercepting route", "interception-middleware-rewrite should support intercepting routes with a middleware rewrite" ], "failed": [], @@ -3304,19 +3352,20 @@ "flakey": [], "runtimeError": false }, - "test/e2e/app-dir/logging/index.test.ts": { + "test/e2e/app-dir/logging/fetch-logging.test.ts": { "passed": [ + "app-dir - logging with default logging should not contain trailing word page for app router routes", "app-dir - logging with default logging should not log fetch requests at all" ], "failed": [ "app-dir - logging with default logging should not contain metadata internal segments for dynamic metadata routes", - "app-dir - logging with default logging should not contain trailing word page for app router routes", "app-dir - logging with verbose logging for edge runtime should not contain metadata internal segments for dynamic metadata routes", "app-dir - logging with verbose logging for edge runtime should not contain trailing word page for app router routes", "app-dir - logging with verbose logging for edge runtime should not log fetch requests at all", "app-dir - logging with verbose logging should log 'skip' cache status with a reason when cache: 'no-cache' is used", "app-dir - logging with verbose logging should log 'skip' cache status with a reason when revalidate: 0 is used", "app-dir - logging with verbose logging should log 'skip' cache status with a reason when the browser indicates caching should be ignored", + "app-dir - logging with verbose logging should log requests with correct indentation", "app-dir - logging with verbose logging should not contain metadata internal segments for dynamic metadata routes", "app-dir - logging with verbose logging should not contain trailing word page for app router routes", "app-dir - logging with verbose logging should only log requests in dev mode" @@ -3325,6 +3374,17 @@ "flakey": [], "runtimeError": false }, + "test/e2e/app-dir/logging/fetch-warning.test.ts": { + "passed": [ + "app-dir - fetch warnings should log when request input is a Request instance", + "app-dir - fetch warnings should log when request input is a string", + "app-dir - fetch warnings should not log when overriding cache within the Request object" + ], + "failed": [], + "pending": [], + "flakey": [], + "runtimeError": false + }, "test/e2e/app-dir/mdx/mdx.test.ts": { "passed": [ "mdx with-mdx-rs app directory should allow importing client components", @@ -3375,17 +3435,18 @@ "runtimeError": false }, "test/e2e/app-dir/metadata-edge/index.test.ts": { - "passed": [], - "failed": [ + "passed": [ "app dir - Metadata API on the Edge runtime should render OpenGraph image meta tag correctly" ], + "failed": [], "pending": [], "flakey": [], "runtimeError": false }, "test/e2e/app-dir/metadata-missing-metadata-base/index.test.ts": { "passed": [ - "app dir - metadata missing metadataBase should fallback to localhost if metadataBase is missing for absolute urls resolving" + "app dir - metadata missing metadataBase should fallback to localhost if metadataBase is missing for absolute urls resolving", + "app dir - metadata missing metadataBase should warn for unsupported metadata properties" ], "failed": [], "pending": [], @@ -3455,6 +3516,23 @@ ], "runtimeError": false }, + "test/e2e/app-dir/mjs-as-extension/mjs-as-extension.test.ts": { + "passed": ["mjs as extension should render the page correctly"], + "failed": [], + "pending": [], + "flakey": [], + "runtimeError": false + }, + "test/e2e/app-dir/modularizeimports/modularizeimports.test.ts": { + "passed": [ + "modularizeImports should work", + "modularizeImports should work with MDX" + ], + "failed": [], + "pending": [], + "flakey": [], + "runtimeError": false + }, "test/e2e/app-dir/navigation/navigation.test.ts": { "passed": [ "app dir - navigation SEO should contain default meta tags in error page", @@ -3479,6 +3557,7 @@ "app dir - navigation not-found should trigger not-found in a server component", "app dir - navigation not-found should trigger not-found while streaming", "app dir - navigation query string should handle unicode search params", + "app dir - navigation query string should not reset shallow url updates on prefetch", "app dir - navigation query string should set query correctly", "app dir - navigation query string useParams identity between renders should be stable in app", "app dir - navigation redirect components should redirect client-side", @@ -3522,12 +3601,14 @@ "app app dir - next-font computed styles should have correct styles at /client", "app app dir - next-font import values should have correct values at /", "app app dir - next-font import values should have correct values at /client", + "app app dir - next-font import values should transform code in node_modules", "app app dir - next-font navigation should not have duplicate preload tags on navigation", "app-old app dir - next-font Dev errors should recover on font loader error", "app-old app dir - next-font computed styles should have correct styles at /", "app-old app dir - next-font computed styles should have correct styles at /client", "app-old app dir - next-font import values should have correct values at /", "app-old app dir - next-font import values should have correct values at /client", + "app-old app dir - next-font import values should transform code in node_modules", "app-old app dir - next-font navigation should not have duplicate preload tags on navigation" ], "pending": [], @@ -3681,8 +3762,8 @@ "parallel-routes-and-interception route intercepting with dynamic routes should render intercepted route" ], "failed": [ - "parallel-routes-and-interception parallel routes should apply the catch-all route to the parallel route if no matching route is found", "parallel-routes-and-interception parallel routes Should match the catch-all routes of the more specific path, If there is more than one catch-all route", + "parallel-routes-and-interception parallel routes should apply the catch-all route to the parallel route if no matching route is found", "parallel-routes-and-interception parallel routes should throw an error when a route groups causes a conflict with a parallel segment" ], "pending": [], @@ -3699,11 +3780,11 @@ "runtimeError": false }, "test/e2e/app-dir/params-hooks-compat/index.test.ts": { - "passed": [], - "failed": [ + "passed": [ "app-dir - params hooks compat should only access path params with useParams", "app-dir - params hooks compat should only access search params with useSearchParams" ], + "failed": [], "pending": [], "flakey": [], "runtimeError": false @@ -3723,6 +3804,28 @@ "flakey": [], "runtimeError": false }, + "test/e2e/app-dir/ppr-full/ppr-full.test.ts": { + "passed": [ + "ppr-full dynamic pages should resume should resume /", + "ppr-full dynamic pages should resume should resume /loading/a", + "ppr-full dynamic pages should resume should resume /loading/b", + "ppr-full dynamic pages should resume should resume /loading/c", + "ppr-full dynamic pages should resume should resume /nested/a", + "ppr-full dynamic pages should resume should resume /nested/b", + "ppr-full dynamic pages should resume should resume /nested/c", + "ppr-full dynamic pages should resume should resume /no-suspense", + "ppr-full dynamic pages should resume should resume /no-suspense/nested/a", + "ppr-full dynamic pages should resume should resume /no-suspense/nested/b", + "ppr-full dynamic pages should resume should resume /no-suspense/nested/c", + "ppr-full dynamic pages should resume should resume /on-demand/a", + "ppr-full dynamic pages should resume should resume /on-demand/b", + "ppr-full dynamic pages should resume should resume /on-demand/c" + ], + "failed": [], + "pending": [], + "flakey": [], + "runtimeError": false + }, "test/e2e/app-dir/ppr/ppr.test.ts": { "passed": [ "ppr /no-suspense/node/gsp/[slug] should serve the static & dynamic parts", @@ -3752,6 +3855,16 @@ "flakey": [], "runtimeError": false }, + "test/e2e/app-dir/revalidate-dynamic/revalidate-dynamic.test.ts": { + "passed": [ + "app-dir revalidate-dynamic should revalidate the data with /api/revalidate-path", + "app-dir revalidate-dynamic should revalidate the data with /api/revalidate-tag" + ], + "failed": [], + "pending": [], + "flakey": [], + "runtimeError": false + }, "test/e2e/app-dir/rewrites-redirects/rewrites-redirects.test.ts": { "passed": [ "redirects and rewrites navigation using button should redirect from middleware correctly", @@ -3925,14 +4038,35 @@ "test/e2e/app-dir/set-cookies/set-cookies.test.ts": { "passed": [ "set-cookies for edge runtime for /app should set two set-cookie headers", + "set-cookies for edge runtime for /pages should set two set-cookie headers", "set-cookies for experimental-edge runtime for /app should set two set-cookie headers", + "set-cookies for experimental-edge runtime for /pages should set two set-cookie headers", "set-cookies for node runtime for /app should set two set-cookie headers", "set-cookies for node runtime for /pages should set two set-cookie headers" ], - "failed": [ - "set-cookies for edge runtime for /pages should set two set-cookie headers", - "set-cookies for experimental-edge runtime for /pages should set two set-cookie headers" + "failed": [], + "pending": [], + "flakey": [], + "runtimeError": false + }, + "test/e2e/app-dir/shallow-routing/shallow-routing.test.ts": { + "passed": [ + "shallow-routing back and forward client-side navigation should support setting a different pathname reflected on usePathname and then still support navigating back and forward", + "shallow-routing back and forward mpa navigation should support setting data and then still support navigating back and forward", + "shallow-routing pushState should support setting a different pathname reflected on usePathname", + "shallow-routing pushState should support setting a different searchParam reflected on useSearchParams", + "shallow-routing pushState should support setting a different url using a string", + "shallow-routing pushState should support setting data", + "shallow-routing pushState should work when given a null state value", + "shallow-routing replaceState should support setting a different pathname reflected on usePathname", + "shallow-routing replaceState should support setting a different searchParam reflected on useSearchParams", + "shallow-routing replaceState should support setting a different url using a string", + "shallow-routing replaceState should support setting data", + "shallow-routing replaceState should work when given a null state value", + "shallow-routing replaceState should work when given an undefined state value", + "shallow-routing should work when given an undefined state value" ], + "failed": [], "pending": [], "flakey": [], "runtimeError": false @@ -4046,7 +4180,11 @@ "runtimeError": false }, "test/e2e/app-dir/x-forwarded-headers/x-forwarded-headers.test.ts": { - "passed": ["x-forwarded-headers should include x-forwarded-* headers"], + "passed": [ + "x-forwarded-headers already assigned should not override existing x-forwarded-* headers", + "x-forwarded-headers host header exists should include x-forwarded-* headers relative to host", + "x-forwarded-headers should include x-forwarded-* headers" + ], "failed": [], "pending": [], "flakey": [], @@ -4086,6 +4224,8 @@ "basePath should handle query/hash correctly during query updating #hello? $search", "basePath should handle query/hash correctly during query updating #hello?world $search", "basePath should have basePath field on Router", + "basePath should have correct href for a link", + "basePath should have correct href for a link to /", "basePath should have correct router paths on first load of /", "basePath should have correct router paths on first load of /hello", "basePath should navigate an absolute local url with basePath", @@ -4125,10 +4265,7 @@ "basePath should work with nested folder with same name as basePath", "basePath should work with normal dynamic page" ], - "failed": [ - "basePath should have correct href for a link", - "basePath should have correct href for a link to /" - ], + "failed": [], "pending": [ "basePath should navigate back to a non-basepath 404 that starts with basepath", "basePath should navigate to nested index page with getStaticProps" @@ -4215,21 +4352,22 @@ "passed": [], "failed": [ "Conflict between app file and pages file should error again when there is new conflict", - "Conflict between app file and pages file should not show error overlay for non conflict pages under app or pages dir", "Conflict between app file and pages file should show error overlay for /", "Conflict between app file and pages file should show error overlay for /another", "Conflict between app file and pages file should support hmr with conflicts" ], "pending": [], - "flakey": [], + "flakey": [ + "Conflict between app file and pages file should not show error overlay for non conflict pages under app or pages dir" + ], "runtimeError": false }, "test/e2e/custom-app-render/custom-app-render.test.ts": { - "passed": [], - "failed": [ + "passed": [ "custom-app-render should render /", "custom-app-render should render /render" ], + "failed": [], "pending": [], "flakey": [], "runtimeError": false @@ -4723,23 +4861,21 @@ "runtimeError": false }, "test/e2e/instrumentation-hook-src/instrumentation-hook-src.test.ts": { - "passed": [], - "failed": [], - "pending": [ + "passed": [ "instrumentation-hook-rsc instrumentation should not overlap with a instrumentation page", - "instrumentation-hook-rsc instrumentation should reload the server when the instrumentation hook changes", "instrumentation-hook-rsc instrumentation should run the edge instrumentation compiled version with the edge runtime", "instrumentation-hook-rsc instrumentation should run the instrumentation hook" ], + "failed": [], + "pending": [ + "instrumentation-hook-rsc instrumentation should reload the server when the instrumentation hook changes" + ], "flakey": [], "runtimeError": false }, "test/e2e/instrumentation-hook/instrumentation-hook.test.ts": { - "passed": [], - "failed": [], - "pending": [ + "passed": [ "Instrumentation Hook general should not overlap with a instrumentation page", - "Instrumentation Hook general should reload the server when the instrumentation hook changes", "Instrumentation Hook with-async-edge-page with-async-edge-page should run the instrumentation hook", "Instrumentation Hook with-async-node-page with-async-node-page should run the instrumentation hook", "Instrumentation Hook with-edge-api with-edge-api should run the instrumentation hook", @@ -4748,6 +4884,10 @@ "Instrumentation Hook with-node-api with-node-api should run the instrumentation hook", "Instrumentation Hook with-node-page with-node-page should run the instrumentation hook" ], + "failed": [], + "pending": [ + "Instrumentation Hook general should reload the server when the instrumentation hook changes" + ], "flakey": [], "runtimeError": false }, @@ -5586,6 +5726,7 @@ "skip-trailing-slash-redirect pages dir should navigate client side correctly", "skip-trailing-slash-redirect pages dir should not apply trailing slash redirect (with slash)", "skip-trailing-slash-redirect pages dir should not apply trailing slash redirect (without slash)", + "skip-trailing-slash-redirect pages dir should preserve original trailing slashes to links on client", "skip-trailing-slash-redirect pages dir should respond to dynamic route correctly", "skip-trailing-slash-redirect pages dir should respond to index correctly", "skip-trailing-slash-redirect should allow response body from middleware with flag", @@ -5606,18 +5747,16 @@ "skip-trailing-slash-redirect should parse locale info for data request correctly", "skip-trailing-slash-redirect should provide original _next/data URL with skipMiddlewareUrlNormalize" ], - "failed": [ - "skip-trailing-slash-redirect pages dir should preserve original trailing slashes to links on client" - ], + "failed": [], "pending": [], "flakey": [], "runtimeError": false }, "test/e2e/socket-io/index.test.js": { - "passed": [], - "failed": [ + "passed": [ "socket-io should support socket.io without falling back to polling" ], + "failed": [], "pending": [], "flakey": [], "runtimeError": false @@ -6675,6 +6814,7 @@ "CLI Usage dev -h", "CLI Usage dev -p", "CLI Usage dev -p conflict", + "CLI Usage dev -p reserved", "CLI Usage dev NODE_OPTIONS='--inspect'", "CLI Usage dev PORT=0", "CLI Usage dev custom directory", @@ -6696,7 +6836,7 @@ "CLI Usage no command detects command typos", "CLI Usage no command invalid directory" ], - "failed": ["CLI Usage dev -p reserved"], + "failed": [], "pending": [ "CLI Usage production mode start --help", "CLI Usage production mode start --keepAliveTimeout Infinity", @@ -6939,6 +7079,7 @@ "should infer pnpm as the package manager with example", "should infer yarn as the package manager", "should infer yarn as the package manager with example", + "should use Bun as the package manager on supplying --use-bun", "should use Bun as the package manager on supplying --use-bun with example", "should use Yarn as the package manager on supplying --use-yarn", "should use Yarn as the package manager on supplying --use-yarn with example", @@ -6947,7 +7088,7 @@ "should use pnpm as the package manager on supplying --use-pnpm", "should use pnpm as the package manager on supplying --use-pnpm with example" ], - "failed": ["should use Bun as the package manager on supplying --use-bun"], + "failed": [], "pending": [], "flakey": [], "runtimeError": false @@ -7291,11 +7432,11 @@ "runtimeError": false }, "test/integration/custom-page-extension/test/index.test.js": { - "passed": [], - "failed": [ + "passed": [ "Custom page extension dev mode should work dynamic page", "Custom page extension dev mode should work with normal page" ], + "failed": [], "pending": [ "Custom page extension production mode should work dynamic page", "Custom page extension production mode should work with normal page" @@ -8267,11 +8408,12 @@ "runtimeError": false }, "test/integration/edge-runtime-module-errors/test/module-imports.test.js": { - "passed": [], + "passed": [ + "Edge runtime code with imports Edge API importing unused node.js module does not throw in dev at runtime" + ], "failed": [ "Edge runtime code with imports Edge API dynamically importing 3rd party module throws not-found module error in dev at runtime and highlights the faulty line", "Edge runtime code with imports Edge API importing unused 3rd party module throws not-found module error in dev at runtime and highlights the faulty line", - "Edge runtime code with imports Edge API importing unused node.js module does not throw in dev at runtime", "Edge runtime code with imports Edge API statically importing node.js module throws unsupported module error in dev at runtime and highlights the faulty line", "Edge runtime code with imports Middleware dynamically importing 3rd party module throws not-found module error in dev at runtime and highlights the faulty line", "Edge runtime code with imports Middleware importing unused 3rd party module throws not-found module error in dev at runtime and highlights the faulty line", @@ -11105,6 +11247,7 @@ "test/integration/image-optimizer/test/index.test.ts": { "passed": [ "Image Optimizer Server support for trailingSlash in next.config.js should return successful response for original loader", + "Image Optimizer config checks should error when assetPrefix is provided but is invalid", "Image Optimizer config checks should error when deviceSizes contains invalid widths", "Image Optimizer config checks should error when domains length exceeds 50", "Image Optimizer config checks should error when imageSizes contains invalid widths", @@ -11116,6 +11259,7 @@ "Image Optimizer config checks should error when images.loader is assigned but images.path is not", "Image Optimizer config checks should error when images.loaderFile does not exist", "Image Optimizer config checks should error when images.minimumCacheTTL is not valid", + "Image Optimizer config checks should error when images.remotePatterns is invalid", "Image Optimizer config checks should error when images.unoptimized is not a boolean", "Image Optimizer config checks should error when loader contains invalid value", "Image Optimizer config checks should error when remotePatterns has invalid prop", @@ -11983,6 +12127,38 @@ "flakey": [], "runtimeError": false }, + "test/integration/jsconfig-paths-wildcard/test/index.test.js": { + "passed": [], + "failed": [ + "jsconfig paths wildcard default behavior should resolve a wildcard alias", + "jsconfig paths without baseurl wildcard default behavior should resolve a wildcard alias" + ], + "pending": [], + "flakey": [], + "runtimeError": false + }, + "test/integration/jsconfig-paths/test/index.test.js": { + "passed": [ + "jsconfig paths default behavior should alias components", + "jsconfig paths default behavior should resolve a single matching alias", + "jsconfig paths default behavior should resolve the first item in the array first", + "jsconfig paths default behavior should resolve the second item as fallback", + "jsconfig paths without baseurl default behavior should alias components", + "jsconfig paths without baseurl default behavior should resolve a single matching alias", + "jsconfig paths without baseurl default behavior should resolve the first item in the array first", + "jsconfig paths without baseurl default behavior should resolve the second item as fallback" + ], + "failed": [ + "jsconfig paths default behavior should have correct module not found error", + "jsconfig paths without baseurl default behavior should have correct module not found error" + ], + "pending": [ + "jsconfig paths should build production mode should trace correctly", + "jsconfig paths without baseurl should build production mode should trace correctly" + ], + "flakey": [], + "runtimeError": false + }, "test/integration/jsconfig/test/index.test.js": { "passed": [], "failed": [], @@ -12505,21 +12681,20 @@ }, "test/integration/next-image-legacy/unicode/test/index.test.ts": { "passed": [], - "failed": [ + "failed": [], + "pending": [], + "flakey": [ "Image Component Unicode Image URL dev mode should load external image with space", "Image Component Unicode Image URL dev mode should load external unicode image", "Image Component Unicode Image URL dev mode should load internal image with space", "Image Component Unicode Image URL dev mode should load internal unicode image", - "Image Component Unicode Image URL dev mode should load static unicode image" - ], - "pending": [ + "Image Component Unicode Image URL dev mode should load static unicode image", "Image Component Unicode Image URL production mode should load external image with space", "Image Component Unicode Image URL production mode should load external unicode image", "Image Component Unicode Image URL production mode should load internal image with space", "Image Component Unicode Image URL production mode should load internal unicode image", "Image Component Unicode Image URL production mode should load static unicode image" ], - "flakey": [], "runtimeError": false }, "test/integration/next-image-legacy/unoptimized/test/index.test.ts": { @@ -12675,11 +12850,14 @@ "runtimeError": false }, "test/integration/next-image-new/asset-prefix/test/index.test.js": { - "passed": [], + "passed": [ + "Image Component assetPrefix Tests dev mode should not log a deprecation warning about using `images.domains`" + ], "failed": [ "Image Component assetPrefix Tests dev mode should include assetPrefix when placeholder=blur during next dev" ], "pending": [ + "Image Component assetPrefix Tests production mode should not log a deprecation warning about using `images.domains`", "Image Component assetPrefix Tests production mode should use base64 data url with placeholder=blur during next start" ], "flakey": [], @@ -13024,21 +13202,20 @@ }, "test/integration/next-image-new/unicode/test/index.test.ts": { "passed": [], - "failed": [ + "failed": [], + "pending": [], + "flakey": [ "Image Component Unicode Image URL dev mode should load external image with space", "Image Component Unicode Image URL dev mode should load external unicode image", "Image Component Unicode Image URL dev mode should load internal image with space", "Image Component Unicode Image URL dev mode should load internal unicode image", - "Image Component Unicode Image URL dev mode should load static unicode image" - ], - "pending": [ + "Image Component Unicode Image URL dev mode should load static unicode image", "Image Component Unicode Image URL production mode should load external image with space", "Image Component Unicode Image URL production mode should load external unicode image", "Image Component Unicode Image URL production mode should load internal image with space", "Image Component Unicode Image URL production mode should load internal unicode image", "Image Component Unicode Image URL production mode should load static unicode image" ], - "flakey": [], "runtimeError": false }, "test/integration/next-image-new/unoptimized/test/index.test.ts": { @@ -14251,10 +14428,10 @@ "runtimeError": false }, "test/integration/server-asset-modules/test/index.test.js": { - "passed": [], - "failed": [ + "passed": [ "serverside asset modules dev mode should enable reading local files in api routes" ], + "failed": [], "pending": [ "serverside asset modules production mode should enable reading local files in api routes" ], @@ -14263,13 +14440,13 @@ }, "test/integration/server-side-dev-errors/test/index.test.js": { "passed": [ + "server-side dev errors should show server-side error for api route correctly", + "server-side dev errors should show server-side error for dynamic api route correctly", "server-side dev errors should show server-side error for dynamic gssp page correctly", "server-side dev errors should show server-side error for gsp page correctly", "server-side dev errors should show server-side error for gssp page correctly" ], "failed": [ - "server-side dev errors should show server-side error for api route correctly", - "server-side dev errors should show server-side error for dynamic api route correctly", "server-side dev errors should show server-side error for uncaught empty exception correctly", "server-side dev errors should show server-side error for uncaught empty rejection correctly", "server-side dev errors should show server-side error for uncaught exception correctly", @@ -14431,11 +14608,10 @@ }, "test/integration/telemetry/test/page-features.test.js": { "passed": [ + "page features telemetry detects --turbo correctly for `next dev`", "page features telemetry detects --turbo correctly for `next dev` stopped" ], - "failed": [ - "page features telemetry detects --turbo correctly for `next dev`" - ], + "failed": [], "pending": [], "flakey": [], "runtimeError": false @@ -14882,14 +15058,14 @@ }, "test/integration/url/test/index.test.js": { "passed": [ + "Handle new URL asset references in next dev should client-render the /ssg page", + "Handle new URL asset references in next dev should client-render the /ssr page", "Handle new URL asset references in next dev should client-render the /static page", "Handle new URL asset references in next dev should render the /ssg page", "Handle new URL asset references in next dev should render the /ssr page", "Handle new URL asset references in next dev should render the /static page", "Handle new URL asset references in next dev should respond on basename api", - "Handle new URL asset references in next dev should respond on size api", - "Handle new URL asset references in next dev should client-render the /ssg page", - "Handle new URL asset references in next dev should client-render the /ssr page" + "Handle new URL asset references in next dev should respond on size api" ], "failed": [], "pending": [ From 87e0b4495a2710a7851a14430738519f27b2ebe4 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Fri, 1 Dec 2023 15:23:43 +0100 Subject: [PATCH 124/481] Fix mixed module swc compilation for app router (#58967) --- packages/next/src/build/handle-externals.ts | 5 ++- packages/next/src/build/swc/options.ts | 21 +++++++++- .../src/build/webpack-config-rules/resolve.ts | 14 +++---- packages/next/src/build/webpack-config.ts | 41 +++++++++++-------- .../build/webpack/loaders/next-swc-loader.ts | 3 ++ .../app-dir/app-external/app-external.test.ts | 18 ++++++++ .../app-external/app/mixed/dynamic/page.js | 12 ++++++ .../app-external/app/mixed/import/client.js | 7 ++++ .../app/mixed/import/mixed-mod.mjs | 5 +++ .../app-external/app/mixed/import/page.js | 15 +++++++ .../mixed-syntax-esm/index.mjs | 14 +++++++ .../mixed-syntax-esm/package.json | 3 ++ .../e2e/app-dir/third-parties/app/gtm/page.js | 2 +- 13 files changed, 131 insertions(+), 29 deletions(-) create mode 100644 test/e2e/app-dir/app-external/app/mixed/dynamic/page.js create mode 100644 test/e2e/app-dir/app-external/app/mixed/import/client.js create mode 100644 test/e2e/app-dir/app-external/app/mixed/import/mixed-mod.mjs create mode 100644 test/e2e/app-dir/app-external/app/mixed/import/page.js create mode 100644 test/e2e/app-dir/app-external/node_modules_bak/mixed-syntax-esm/index.mjs create mode 100644 test/e2e/app-dir/app-external/node_modules_bak/mixed-syntax-esm/package.json diff --git a/packages/next/src/build/handle-externals.ts b/packages/next/src/build/handle-externals.ts index 9365b50d44282..8c7f4ccc55ce7 100644 --- a/packages/next/src/build/handle-externals.ts +++ b/packages/next/src/build/handle-externals.ts @@ -28,8 +28,9 @@ export function isResourceInPackages( resource: string, packageNames?: string[], packageDirMapping?: Map -) { - return packageNames?.some((p: string) => +): boolean { + if (!packageNames) return false + return packageNames.some((p: string) => packageDirMapping && packageDirMapping.has(p) ? resource.startsWith(packageDirMapping.get(p)! + path.sep) : resource.includes( diff --git a/packages/next/src/build/swc/options.ts b/packages/next/src/build/swc/options.ts index fb9cef6116440..da59be94ec2c3 100644 --- a/packages/next/src/build/swc/options.ts +++ b/packages/next/src/build/swc/options.ts @@ -209,6 +209,22 @@ function getStyledComponentsOptions( } } +/* +Output module type + +For app router where server components is enabled, we prefer to bundle es6 modules, +Use output module es6 to make sure: +- the esm module is present +- if the module is mixed syntax, the esm + cjs code are both present + +For pages router will remain untouched +*/ +function getModuleOptions( + esm: boolean | undefined = false +): { module: { type: 'es6' } } | {} { + return esm ? { module: { type: 'es6' } } : {} +} + function getEmotionOptions( emotionConfig: undefined | boolean | EmotionConfig, development: boolean @@ -319,6 +335,7 @@ export function getLoaderSWCOptions({ relativeFilePathFromRoot, serverComponents, isReactServerLayer, + esm, }: { filename: string development: boolean @@ -338,6 +355,7 @@ export function getLoaderSWCOptions({ supportedBrowsers: string[] | undefined swcCacheDir: string relativeFilePathFromRoot: string + esm?: boolean serverComponents?: boolean isReactServerLayer?: boolean }) { @@ -412,6 +430,7 @@ export function getLoaderSWCOptions({ node: process.versions.node, }, }, + ...getModuleOptions(esm), } } else { const options = { @@ -423,7 +442,7 @@ export function getLoaderSWCOptions({ type: 'commonjs', }, } - : {}), + : getModuleOptions(esm)), disableNextSsg: !isPageFile, isDevelopment: development, isServerCompiler: isServer, diff --git a/packages/next/src/build/webpack-config-rules/resolve.ts b/packages/next/src/build/webpack-config-rules/resolve.ts index f50f6c92ee629..35f9f56969ef4 100644 --- a/packages/next/src/build/webpack-config-rules/resolve.ts +++ b/packages/next/src/build/webpack-config-rules/resolve.ts @@ -12,20 +12,20 @@ export const edgeConditionNames = [ ] const mainFieldsPerCompiler: Record< - CompilerNameValues | 'app-router-server', + CompilerNameValues | 'server-esm', string[] > = { // For default case, prefer CJS over ESM on server side. e.g. pages dir SSR [COMPILER_NAMES.server]: ['main', 'module'], [COMPILER_NAMES.client]: ['browser', 'module', 'main'], [COMPILER_NAMES.edgeServer]: edgeConditionNames, - // For app router since everything is bundled, prefer ESM over CJS - 'app-router-server': ['module', 'main'], + // For bundling-all strategy, prefer ESM over CJS + 'server-esm': ['module', 'main'], } export function getMainField( - pageType: 'app' | 'pages', - compilerType: CompilerNameValues + compilerType: CompilerNameValues, + preferEsm: boolean ) { if (compilerType === COMPILER_NAMES.edgeServer) { return edgeConditionNames @@ -34,7 +34,7 @@ export function getMainField( } // Prefer module fields over main fields for isomorphic packages on server layer - return pageType === 'app' - ? mainFieldsPerCompiler['app-router-server'] + return preferEsm + ? mainFieldsPerCompiler['server-esm'] : mainFieldsPerCompiler[COMPILER_NAMES.server] } diff --git a/packages/next/src/build/webpack-config.ts b/packages/next/src/build/webpack-config.ts index a371aa27d1f87..cec79d499fcc9 100644 --- a/packages/next/src/build/webpack-config.ts +++ b/packages/next/src/build/webpack-config.ts @@ -437,17 +437,26 @@ export default async function getBaseWebpackConfig( } } + // RSC loaders, prefer ESM, set `esm` to true const swcServerLayerLoader = getSwcLoader({ serverComponents: true, isReactServerLayer: true, + esm: true, }) const swcClientLayerLoader = getSwcLoader({ serverComponents: true, isReactServerLayer: false, + esm: true, + }) + // Default swc loaders for pages doesn't prefer ESM. + const swcDefaultLoader = getSwcLoader({ + serverComponents: true, + isReactServerLayer: false, + esm: false, }) const defaultLoaders = { - babel: useSWCLoader ? swcClientLayerLoader : babelLoader!, + babel: useSWCLoader ? swcDefaultLoader : babelLoader!, } const swcLoaderForServerLayer = hasAppDir @@ -621,7 +630,7 @@ export default async function getBaseWebpackConfig( } : undefined), // default main fields use pages dir ones, and customize app router ones in loaders. - mainFields: getMainField('pages', compilerType), + mainFields: getMainField(compilerType, false), ...(isEdgeServer && { conditionNames: edgeConditionNames, }), @@ -736,8 +745,13 @@ export default async function getBaseWebpackConfig( const shouldIncludeExternalDirs = config.experimental.externalDir || !!config.transpilePackages - function createLoaderRuleExclude(skipNodeModules: boolean) { - return (excludePath: string) => { + const codeCondition = { + test: /\.(tsx|ts|js|cjs|mjs|jsx)$/, + ...(shouldIncludeExternalDirs + ? // Allowing importing TS/TSX files from outside of the root dir. + {} + : { include: [dir, ...babelIncludeRegexes] }), + exclude: (excludePath: string) => { if (babelIncludeRegexes.some((r) => r.test(excludePath))) { return false } @@ -748,17 +762,8 @@ export default async function getBaseWebpackConfig( ) if (shouldBeBundled) return false - return skipNodeModules && excludePath.includes('node_modules') - } - } - - const codeCondition = { - test: /\.(tsx|ts|js|cjs|mjs|jsx)$/, - ...(shouldIncludeExternalDirs - ? // Allowing importing TS/TSX files from outside of the root dir. - {} - : { include: [dir, ...babelIncludeRegexes] }), - exclude: createLoaderRuleExclude(true), + return excludePath.includes('node_modules') + }, } let webpackConfig: webpack.Configuration = { @@ -1281,7 +1286,7 @@ export default async function getBaseWebpackConfig( ], }, resolve: { - mainFields: getMainField('app', compilerType), + mainFields: getMainField(compilerType, true), conditionNames: reactServerCondition, // If missing the alias override here, the default alias will be used which aliases // react to the direct file path, not the package name. In that case the condition @@ -1416,7 +1421,7 @@ export default async function getBaseWebpackConfig( issuerLayer: [WEBPACK_LAYERS.appPagesBrowser], use: swcLoaderForClientLayer, resolve: { - mainFields: getMainField('app', compilerType), + mainFields: getMainField(compilerType, true), }, }, { @@ -1424,7 +1429,7 @@ export default async function getBaseWebpackConfig( issuerLayer: [WEBPACK_LAYERS.serverSideRendering], use: swcLoaderForClientLayer, resolve: { - mainFields: getMainField('app', compilerType), + mainFields: getMainField(compilerType, true), }, }, ] diff --git a/packages/next/src/build/webpack/loaders/next-swc-loader.ts b/packages/next/src/build/webpack/loaders/next-swc-loader.ts index 511c0773fd63b..aff07d2700b61 100644 --- a/packages/next/src/build/webpack/loaders/next-swc-loader.ts +++ b/packages/next/src/build/webpack/loaders/next-swc-loader.ts @@ -44,6 +44,7 @@ export interface SWCLoaderOptions { swcCacheDir: string serverComponents?: boolean isReactServerLayer?: boolean + esm?: boolean } async function loaderTransform( @@ -69,6 +70,7 @@ async function loaderTransform( swcCacheDir, serverComponents, isReactServerLayer, + esm, } = loaderOptions const isPageFile = filename.startsWith(pagesDir) const relativeFilePathFromRoot = path.relative(rootDir, filename) @@ -92,6 +94,7 @@ async function loaderTransform( relativeFilePathFromRoot, serverComponents, isReactServerLayer, + esm, }) const programmaticOptions = { diff --git a/test/e2e/app-dir/app-external/app-external.test.ts b/test/e2e/app-dir/app-external/app-external.test.ts index dbf044d7324cc..c458ab3397da9 100644 --- a/test/e2e/app-dir/app-external/app-external.test.ts +++ b/test/e2e/app-dir/app-external/app-external.test.ts @@ -210,6 +210,24 @@ createNextDescribe( }) }) + describe('mixed syntax external modules', () => { + it('should handle mixed module with next/dynamic', async () => { + const browser = await next.browser('/mixed/dynamic') + expect(await browser.elementByCss('#component').text()).toContain( + 'mixed-syntax-esm' + ) + }) + + it('should handle mixed module in server and client components', async () => { + const $ = await next.render$('/mixed/import') + expect(await $('#server').text()).toContain('server:mixed-syntax-esm') + expect(await $('#client').text()).toContain('client:mixed-syntax-esm') + expect(await $('#relative-mixed').text()).toContain( + 'relative-mixed-syntax-esm' + ) + }) + }) + it('should export client module references in esm', async () => { const html = await next.render('/esm-client-ref') expect(html).toContain('hello') diff --git a/test/e2e/app-dir/app-external/app/mixed/dynamic/page.js b/test/e2e/app-dir/app-external/app/mixed/dynamic/page.js new file mode 100644 index 0000000000000..65c82ecbb6560 --- /dev/null +++ b/test/e2e/app-dir/app-external/app/mixed/dynamic/page.js @@ -0,0 +1,12 @@ +'use client' + +import dynamic from 'next/dynamic' + +const Dynamic = dynamic( + () => import('mixed-syntax-esm').then((mod) => mod.Component), + { ssr: false } +) + +export default function Page() { + return +} diff --git a/test/e2e/app-dir/app-external/app/mixed/import/client.js b/test/e2e/app-dir/app-external/app/mixed/import/client.js new file mode 100644 index 0000000000000..c5f9320ac7a13 --- /dev/null +++ b/test/e2e/app-dir/app-external/app/mixed/import/client.js @@ -0,0 +1,7 @@ +'use client' + +import { value } from 'mixed-syntax-esm' + +export function Client() { + return 'client:' + value +} diff --git a/test/e2e/app-dir/app-external/app/mixed/import/mixed-mod.mjs b/test/e2e/app-dir/app-external/app/mixed/import/mixed-mod.mjs new file mode 100644 index 0000000000000..327be28b64f12 --- /dev/null +++ b/test/e2e/app-dir/app-external/app/mixed/import/mixed-mod.mjs @@ -0,0 +1,5 @@ +;(module) => { + module.exports = {} +} + +export const value = 'relative-mixed-syntax-esm' diff --git a/test/e2e/app-dir/app-external/app/mixed/import/page.js b/test/e2e/app-dir/app-external/app/mixed/import/page.js new file mode 100644 index 0000000000000..67ce376201f32 --- /dev/null +++ b/test/e2e/app-dir/app-external/app/mixed/import/page.js @@ -0,0 +1,15 @@ +import { value } from 'mixed-syntax-esm' +import { Client } from './client' +import { value as relativeMixedValue } from './mixed-mod.mjs' + +export default function Page() { + return ( + <> +

{'server:' + value}

+

+ +

+

{relativeMixedValue}

+ + ) +} diff --git a/test/e2e/app-dir/app-external/node_modules_bak/mixed-syntax-esm/index.mjs b/test/e2e/app-dir/app-external/node_modules_bak/mixed-syntax-esm/index.mjs new file mode 100644 index 0000000000000..ca05246cd1486 --- /dev/null +++ b/test/e2e/app-dir/app-external/node_modules_bak/mixed-syntax-esm/index.mjs @@ -0,0 +1,14 @@ +import React from 'react' +;(module) => { + module.exports = {} +} + +export const value = 'mixed-syntax-esm' + +export function Component() { + return /*#__PURE__*/ React.createElement( + 'p', + { id: 'component' }, + 'mixed-syntax-esm' + ) +} diff --git a/test/e2e/app-dir/app-external/node_modules_bak/mixed-syntax-esm/package.json b/test/e2e/app-dir/app-external/node_modules_bak/mixed-syntax-esm/package.json new file mode 100644 index 0000000000000..b6629e247888a --- /dev/null +++ b/test/e2e/app-dir/app-external/node_modules_bak/mixed-syntax-esm/package.json @@ -0,0 +1,3 @@ +{ + "exports": "./index.mjs" +} diff --git a/test/e2e/app-dir/third-parties/app/gtm/page.js b/test/e2e/app-dir/third-parties/app/gtm/page.js index 34d56d8508d59..3662bc2cf72e4 100644 --- a/test/e2e/app-dir/third-parties/app/gtm/page.js +++ b/test/e2e/app-dir/third-parties/app/gtm/page.js @@ -9,7 +9,7 @@ const Page = () => { } return ( -
+

GTM

+ + ) +} diff --git a/test/e2e/app-dir/actions/app/interception-routes/(with-modal)/@modal/default.js b/test/e2e/app-dir/actions/app/interception-routes/(with-modal)/@modal/default.js new file mode 100644 index 0000000000000..e9a7f8c6b8cfa --- /dev/null +++ b/test/e2e/app-dir/actions/app/interception-routes/(with-modal)/@modal/default.js @@ -0,0 +1,3 @@ +export default function Empty() { + return null +} diff --git a/test/e2e/app-dir/actions/app/interception-routes/(with-modal)/layout.js b/test/e2e/app-dir/actions/app/interception-routes/(with-modal)/layout.js new file mode 100644 index 0000000000000..a97ec9e4afad1 --- /dev/null +++ b/test/e2e/app-dir/actions/app/interception-routes/(with-modal)/layout.js @@ -0,0 +1,8 @@ +export default function Layout({ children, modal }) { + return ( + <> + +
{children}
+ + ) +} diff --git a/test/e2e/app-dir/actions/app/interception-routes/(with-modal)/page.js b/test/e2e/app-dir/actions/app/interception-routes/(with-modal)/page.js new file mode 100644 index 0000000000000..3360b339b70ea --- /dev/null +++ b/test/e2e/app-dir/actions/app/interception-routes/(with-modal)/page.js @@ -0,0 +1,5 @@ +import Link from 'next/link' + +export default function InterceptedPage() { + return Open modal +} diff --git a/test/e2e/app-dir/actions/app/interception-routes/test/page.js b/test/e2e/app-dir/actions/app/interception-routes/test/page.js new file mode 100644 index 0000000000000..4ab7d9943e044 --- /dev/null +++ b/test/e2e/app-dir/actions/app/interception-routes/test/page.js @@ -0,0 +1,16 @@ +export default function TestPage() { + async function action(data) { + 'use server' + + console.log('Action Submitted (Page)') + } + + return ( +
+ in "page" + +
+ ) +} From 7d8fab2f4d1eb6a530ad8754031eadadb5bb3775 Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Fri, 1 Dec 2023 23:22:14 +0000 Subject: [PATCH 132/481] v14.0.4-canary.35 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 16 ++++++++-------- 18 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lerna.json b/lerna.json index d0baf00e74ee9..1d18673adce94 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.34" + "version": "14.0.4-canary.35" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index d69837450096c..9420155d42a1b 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.34", + "version": "14.0.4-canary.35", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 8f33f64aec387..d1207e250002c 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.34", + "version": "14.0.4-canary.35", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.34", + "@next/eslint-plugin-next": "14.0.4-canary.35", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 2b1f2c0219b6c..2bd4e5a492d50 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.34", + "version": "14.0.4-canary.35", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index efd0dcfc015a0..fb52511b0799c 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.34", + "version": "14.0.4-canary.35", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 45f7e767d40c3..cd056c772d6c6 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.34", + "version": "14.0.4-canary.35", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index eb16810219954..5e75513dfa938 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.34", + "version": "14.0.4-canary.35", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 853953d1ec066..3d42f0deea926 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.34", + "version": "14.0.4-canary.35", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 4700f38f24286..ec84e79bb3434 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.34", + "version": "14.0.4-canary.35", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index d784a527b7a41..57a8fe651bb80 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.34", + "version": "14.0.4-canary.35", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index 12b0a7d2fb665..923620bce11a2 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.34", + "version": "14.0.4-canary.35", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index 708f43e88b6d8..31c1b091c7013 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.34", + "version": "14.0.4-canary.35", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index d6cef8f70bb67..26439bc8b8203 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.34", + "version": "14.0.4-canary.35", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index f0eebbea0789b..f20644d6eae29 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.34", + "version": "14.0.4-canary.35", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.34", + "@next/env": "14.0.4-canary.35", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -147,11 +147,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.34", - "@next/polyfill-nomodule": "14.0.4-canary.34", - "@next/react-dev-overlay": "14.0.4-canary.34", - "@next/react-refresh-utils": "14.0.4-canary.34", - "@next/swc": "14.0.4-canary.34", + "@next/polyfill-module": "14.0.4-canary.35", + "@next/polyfill-nomodule": "14.0.4-canary.35", + "@next/react-dev-overlay": "14.0.4-canary.35", + "@next/react-refresh-utils": "14.0.4-canary.35", + "@next/swc": "14.0.4-canary.35", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index 559c9f57093fa..74248f9cc8b3e 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.34", + "version": "14.0.4-canary.35", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index 713b086afdc72..eaad28bb78b72 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.34", + "version": "14.0.4-canary.35", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index e7fcc52348180..1a79f45ab7346 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.34", + "version": "14.0.4-canary.35", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -23,7 +23,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.34", + "next": "14.0.4-canary.35", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 01d4c16ac39ad..a05a9f9d32421 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -741,7 +741,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.34 + specifier: 14.0.4-canary.35 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -806,7 +806,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.34 + specifier: 14.0.4-canary.35 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -933,19 +933,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.34 + specifier: 14.0.4-canary.35 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.34 + specifier: 14.0.4-canary.35 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.34 + specifier: 14.0.4-canary.35 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.34 + specifier: 14.0.4-canary.35 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.34 + specifier: 14.0.4-canary.35 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1599,7 +1599,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.34 + specifier: 14.0.4-canary.35 version: link:../next outdent: specifier: 0.8.0 From 43b076620cea3fa799c179e43a0a1666c940f158 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Fri, 1 Dec 2023 17:23:50 -0800 Subject: [PATCH 133/481] Fix ssgCacheKey in minimal mode (#59181) This ensures we use the correct `srcPathname` in minimal mode so that we can normalize the URL and generate the correct `ssgCacheKey` which is used for request caching/de-duping. We aren't able to add a reliable test case for this as it is a race condition within a second of a previous request although this was verified against a stress test repro here https://overlapping-segments-h1455lwvk-vtest314-ijjk-testing.vercel.app/repro/tutorials/demo This behavior seems to have regressed in https://github.com/vercel/next.js/pull/45716 Closes NEXT-1777 --- packages/next/src/server/base-server.ts | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/packages/next/src/server/base-server.ts b/packages/next/src/server/base-server.ts index bd8b872095bf2..8e49d9d1c52ee 100644 --- a/packages/next/src/server/base-server.ts +++ b/packages/next/src/server/base-server.ts @@ -1024,15 +1024,20 @@ export default abstract class Server { matchedPath = denormalizePagePath(matchedPath) let srcPathname = matchedPath - const match = await this.matchers.match(matchedPath, { - i18n: localeAnalysisResult, - }) + let pageIsDynamic = isDynamicRoute(srcPathname) - // Update the source pathname to the matched page's pathname. - if (match) srcPathname = match.definition.pathname + if (!pageIsDynamic) { + const match = await this.matchers.match(srcPathname, { + i18n: localeAnalysisResult, + }) - // The page is dynamic if the params are defined. - const pageIsDynamic = typeof match?.params !== 'undefined' + // Update the source pathname to the matched page's pathname. + if (match) { + srcPathname = match.definition.pathname + // The page is dynamic if the params are defined. + pageIsDynamic = typeof match.params !== 'undefined' + } + } // The rest of this function can't handle i18n properly, so ensure we // restore the pathname with the locale information stripped from it From e7589e05db7eb80cafb09ede74f9d3c8a5759bf8 Mon Sep 17 00:00:00 2001 From: Murat Ogulcan Sahin Date: Sat, 2 Dec 2023 03:35:22 -0500 Subject: [PATCH 134/481] docs:Add react hydration error case. (#59147) --- errors/react-hydration-error.mdx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/errors/react-hydration-error.mdx b/errors/react-hydration-error.mdx index e01b20d7042ae..3f301eeac4665 100644 --- a/errors/react-hydration-error.mdx +++ b/errors/react-hydration-error.mdx @@ -15,7 +15,8 @@ Hydration errors can occur from: 1. Incorrect nesting of HTML tags 1. `

` nested in another `

` tag 2. `

` nested in a `

` tag - 3. [Interactive Content](https://html.spec.whatwg.org/#interactive-content-2) cannot be nested (`` nested in a `` tag, ` +} diff --git a/test/turbopack-tests-manifest.json b/test/turbopack-tests-manifest.json index 4638dba61e735..5bc1830d28c67 100644 --- a/test/turbopack-tests-manifest.json +++ b/test/turbopack-tests-manifest.json @@ -1459,7 +1459,8 @@ "optimizePackageImports app - should render the icons correctly without creating all the modules", "optimizePackageImports pages - should optimize recursive wildcard export mapping", "optimizePackageImports pages - should render the icons correctly without creating all the modules", - "optimizePackageImports should support visx" + "optimizePackageImports should support visx", + "optimizePackageImports should support MUI" ], "pending": [], "flakey": [], From 2003f5f8489b1a5a12c1eb05d3dd595f6342fe5e Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Tue, 5 Dec 2023 16:33:54 +0000 Subject: [PATCH 175/481] v14.0.4-canary.42 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 16 ++++++++-------- 18 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lerna.json b/lerna.json index 14d9138d077f4..6cbd8611d3abc 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.41" + "version": "14.0.4-canary.42" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index eb526559abad2..c6e7dcecf3efe 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.41", + "version": "14.0.4-canary.42", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 9bed74002ddc3..d91c844240f40 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.41", + "version": "14.0.4-canary.42", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.41", + "@next/eslint-plugin-next": "14.0.4-canary.42", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 08127fa5bab24..6f59fb7c3fee5 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.41", + "version": "14.0.4-canary.42", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index b00bc90ea44a6..3f508b2cfd5d2 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.41", + "version": "14.0.4-canary.42", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 2727155e91b0e..0c49975c656a5 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.41", + "version": "14.0.4-canary.42", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 1196568eeec6d..c0e6d754584ae 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.41", + "version": "14.0.4-canary.42", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 3cb5caf7b2b15..a7fd1b8e0631a 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.41", + "version": "14.0.4-canary.42", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index d401fe692ddcc..493e0abce3d42 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.41", + "version": "14.0.4-canary.42", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 56c8a3b799a62..6518408bcc3ce 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.41", + "version": "14.0.4-canary.42", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index 113392d5f973b..4d3e42c657383 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.41", + "version": "14.0.4-canary.42", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index c6da999132e4d..0b1fc481388f5 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.41", + "version": "14.0.4-canary.42", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index a083a1001c22f..41adddeaf10be 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.41", + "version": "14.0.4-canary.42", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index 97b0b0358073f..f649dd4c343d9 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.41", + "version": "14.0.4-canary.42", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.41", + "@next/env": "14.0.4-canary.42", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -147,11 +147,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.41", - "@next/polyfill-nomodule": "14.0.4-canary.41", - "@next/react-dev-overlay": "14.0.4-canary.41", - "@next/react-refresh-utils": "14.0.4-canary.41", - "@next/swc": "14.0.4-canary.41", + "@next/polyfill-module": "14.0.4-canary.42", + "@next/polyfill-nomodule": "14.0.4-canary.42", + "@next/react-dev-overlay": "14.0.4-canary.42", + "@next/react-refresh-utils": "14.0.4-canary.42", + "@next/swc": "14.0.4-canary.42", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index 9715030b0ac32..0dc8d34cad62d 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.41", + "version": "14.0.4-canary.42", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index eb7bd749ea4dc..e5274626f30e8 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.41", + "version": "14.0.4-canary.42", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index a103db4e6c02b..52ce3baa0b33c 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.41", + "version": "14.0.4-canary.42", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -25,7 +25,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.41", + "next": "14.0.4-canary.42", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7894bf69d71e6..fe006d2a4a1d0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -741,7 +741,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.41 + specifier: 14.0.4-canary.42 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -806,7 +806,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.41 + specifier: 14.0.4-canary.42 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -933,19 +933,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.41 + specifier: 14.0.4-canary.42 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.41 + specifier: 14.0.4-canary.42 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.41 + specifier: 14.0.4-canary.42 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.41 + specifier: 14.0.4-canary.42 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.41 + specifier: 14.0.4-canary.42 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1599,7 +1599,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.41 + specifier: 14.0.4-canary.42 version: link:../next outdent: specifier: 0.8.0 From 78a2eb0b9b031f49eed4867dbbcffe369be98baf Mon Sep 17 00:00:00 2001 From: Zack Tanner Date: Tue, 5 Dec 2023 08:47:40 -0800 Subject: [PATCH 176/481] fix interception routes with dynamic segments (#59273) ### What? Using an interception marker next to a dynamic segment does not behave properly when deployed to Vercel ### Why? The named route regex that gets created is not accounting for the interception marker, which is causing the non-intercepted route to match the intercepted serverless function. ### How? This factors in the interception marker when building the named route regex so that the non-intercepted route regex properly matches when loading the non-intercepted page. Deployment verified here: https://test-intercept-mu.vercel.app/ Closes NEXT-1786 Fixes #54650 --- .../lib/router/utils/route-regex.test.ts | 12 ++++++++++ .../shared/lib/router/utils/route-regex.ts | 18 ++++++++++++--- .../app/@modal/(.)[username]/[id]/page.tsx | 3 +++ .../app/@modal/default.tsx | 1 + .../app/[username]/[id]/page.tsx | 3 +++ .../app/default.tsx | 3 +++ .../app/layout.tsx | 13 +++++++++++ .../interception-dynamic-segment/app/page.tsx | 9 ++++++++ .../interception-dynamic-segment.test.ts | 23 +++++++++++++++++++ .../next.config.js | 6 +++++ 10 files changed, 88 insertions(+), 3 deletions(-) create mode 100644 test/e2e/app-dir/interception-dynamic-segment/app/@modal/(.)[username]/[id]/page.tsx create mode 100644 test/e2e/app-dir/interception-dynamic-segment/app/@modal/default.tsx create mode 100644 test/e2e/app-dir/interception-dynamic-segment/app/[username]/[id]/page.tsx create mode 100644 test/e2e/app-dir/interception-dynamic-segment/app/default.tsx create mode 100644 test/e2e/app-dir/interception-dynamic-segment/app/layout.tsx create mode 100644 test/e2e/app-dir/interception-dynamic-segment/app/page.tsx create mode 100644 test/e2e/app-dir/interception-dynamic-segment/interception-dynamic-segment.test.ts create mode 100644 test/e2e/app-dir/interception-dynamic-segment/next.config.js diff --git a/packages/next/src/shared/lib/router/utils/route-regex.test.ts b/packages/next/src/shared/lib/router/utils/route-regex.test.ts index 858d750d75223..1b7eb4ae8e8c5 100644 --- a/packages/next/src/shared/lib/router/utils/route-regex.test.ts +++ b/packages/next/src/shared/lib/router/utils/route-regex.test.ts @@ -24,6 +24,18 @@ describe('getNamedRouteRegex', () => { expect(regex.re.test('/photos/(.)next/123')).toBe(true) }) + it('should match named routes correctly when interception markers are adjacent to dynamic segments', () => { + let regex = getNamedRouteRegex('/(.)[author]/[id]', true) + let namedRegexp = new RegExp(regex.namedRegex) + expect(namedRegexp.test('/[author]/[id]')).toBe(false) + expect(namedRegexp.test('/(.)[author]/[id]')).toBe(true) + + regex = getNamedRouteRegex('/(..)(..)[author]/[id]', true) + namedRegexp = new RegExp(regex.namedRegex) + expect(namedRegexp.test('/[author]/[id]')).toBe(false) + expect(namedRegexp.test('/(..)(..)[author]/[id]')).toBe(true) + }) + it('should handle multi-level interception markers', () => { const regex = getNamedRouteRegex('/photos/(..)(..)[author]/[id]', true) diff --git a/packages/next/src/shared/lib/router/utils/route-regex.ts b/packages/next/src/shared/lib/router/utils/route-regex.ts index caf003e99b758..5ec7668fd90f6 100644 --- a/packages/next/src/shared/lib/router/utils/route-regex.ts +++ b/packages/next/src/shared/lib/router/utils/route-regex.ts @@ -97,11 +97,13 @@ function buildGetSafeRouteKey() { } function getSafeKeyFromSegment({ + interceptionMarker, getSafeRouteKey, segment, routeKeys, keyPrefix, }: { + interceptionMarker?: string getSafeRouteKey: () => string segment: string routeKeys: Record @@ -137,11 +139,18 @@ function getSafeKeyFromSegment({ routeKeys[cleanedKey] = key } + // if the segment has an interception marker, make sure that's part of the regex pattern + // this is to ensure that the route with the interception marker doesn't incorrectly match + // the non-intercepted route (ie /app/(.)[username] should not match /app/[username]) + const interceptionPrefix = interceptionMarker + ? escapeStringRegexp(interceptionMarker) + : '' + return repeat ? optional - ? `(?:/(?<${cleanedKey}>.+?))?` - : `/(?<${cleanedKey}>.+?)` - : `/(?<${cleanedKey}>[^/]+?)` + ? `(?:/${interceptionPrefix}(?<${cleanedKey}>.+?))?` + : `/${interceptionPrefix}(?<${cleanedKey}>.+?)` + : `/${interceptionPrefix}(?<${cleanedKey}>[^/]+?)` } function getNamedParametrizedRoute(route: string, prefixRouteKeys: boolean) { @@ -157,8 +166,11 @@ function getNamedParametrizedRoute(route: string, prefixRouteKeys: boolean) { const paramMatches = segment.match(/\[((?:\[.*\])|.+)\]/) // Check for parameters if (hasInterceptionMarker && paramMatches) { + const [usedMarker] = segment.split(paramMatches[0]) + return getSafeKeyFromSegment({ getSafeRouteKey, + interceptionMarker: usedMarker, segment: paramMatches[1], routeKeys, keyPrefix: prefixRouteKeys diff --git a/test/e2e/app-dir/interception-dynamic-segment/app/@modal/(.)[username]/[id]/page.tsx b/test/e2e/app-dir/interception-dynamic-segment/app/@modal/(.)[username]/[id]/page.tsx new file mode 100644 index 0000000000000..7c48f6584136b --- /dev/null +++ b/test/e2e/app-dir/interception-dynamic-segment/app/@modal/(.)[username]/[id]/page.tsx @@ -0,0 +1,3 @@ +export default function Page() { + return 'intercepted' +} diff --git a/test/e2e/app-dir/interception-dynamic-segment/app/@modal/default.tsx b/test/e2e/app-dir/interception-dynamic-segment/app/@modal/default.tsx new file mode 100644 index 0000000000000..ad4e17b5767f9 --- /dev/null +++ b/test/e2e/app-dir/interception-dynamic-segment/app/@modal/default.tsx @@ -0,0 +1 @@ +export default () => null diff --git a/test/e2e/app-dir/interception-dynamic-segment/app/[username]/[id]/page.tsx b/test/e2e/app-dir/interception-dynamic-segment/app/[username]/[id]/page.tsx new file mode 100644 index 0000000000000..cab6f9416b983 --- /dev/null +++ b/test/e2e/app-dir/interception-dynamic-segment/app/[username]/[id]/page.tsx @@ -0,0 +1,3 @@ +export default function Page() { + return 'not intercepted' +} diff --git a/test/e2e/app-dir/interception-dynamic-segment/app/default.tsx b/test/e2e/app-dir/interception-dynamic-segment/app/default.tsx new file mode 100644 index 0000000000000..86b9e9a388129 --- /dev/null +++ b/test/e2e/app-dir/interception-dynamic-segment/app/default.tsx @@ -0,0 +1,3 @@ +export default function Default() { + return null +} diff --git a/test/e2e/app-dir/interception-dynamic-segment/app/layout.tsx b/test/e2e/app-dir/interception-dynamic-segment/app/layout.tsx new file mode 100644 index 0000000000000..6a674f5ea764a --- /dev/null +++ b/test/e2e/app-dir/interception-dynamic-segment/app/layout.tsx @@ -0,0 +1,13 @@ +export default function Layout(props: { + children: React.ReactNode + modal: React.ReactNode +}) { + return ( + + +

{props.children}
+ + + + ) +} diff --git a/test/e2e/app-dir/interception-dynamic-segment/app/page.tsx b/test/e2e/app-dir/interception-dynamic-segment/app/page.tsx new file mode 100644 index 0000000000000..9fd53376265da --- /dev/null +++ b/test/e2e/app-dir/interception-dynamic-segment/app/page.tsx @@ -0,0 +1,9 @@ +import Link from 'next/link' + +export default function Page() { + return ( +
+ Foo Foo +
+ ) +} diff --git a/test/e2e/app-dir/interception-dynamic-segment/interception-dynamic-segment.test.ts b/test/e2e/app-dir/interception-dynamic-segment/interception-dynamic-segment.test.ts new file mode 100644 index 0000000000000..3eac834fbdc15 --- /dev/null +++ b/test/e2e/app-dir/interception-dynamic-segment/interception-dynamic-segment.test.ts @@ -0,0 +1,23 @@ +import { createNextDescribe } from 'e2e-utils' +import { check } from 'next-test-utils' + +createNextDescribe( + 'interception-dynamic-segment', + { + files: __dirname, + }, + ({ next }) => { + it('should work when interception route is paired with a dynamic segment', async () => { + const browser = await next.browser('/') + + await browser.elementByCss('[href="/foo/1"]').click() + await check(() => browser.elementById('modal').text(), /intercepted/) + await browser.refresh() + await check(() => browser.elementById('modal').text(), '') + await check( + () => browser.elementById('children').text(), + /not intercepted/ + ) + }) + } +) diff --git a/test/e2e/app-dir/interception-dynamic-segment/next.config.js b/test/e2e/app-dir/interception-dynamic-segment/next.config.js new file mode 100644 index 0000000000000..807126e4cf0bf --- /dev/null +++ b/test/e2e/app-dir/interception-dynamic-segment/next.config.js @@ -0,0 +1,6 @@ +/** + * @type {import('next').NextConfig} + */ +const nextConfig = {} + +module.exports = nextConfig From 1436a3606e45a104c58d82364090e8340930a6c2 Mon Sep 17 00:00:00 2001 From: Shu Ding Date: Wed, 6 Dec 2023 00:49:51 +0800 Subject: [PATCH 177/481] Clean up builtin `modularizeImports` configs (#59294) Most of them can now be handled by `optimizePackageImports` as I manually tested them locally. The main benefit is that structural updates from these libs won't affect our internal configurations anymore, as they're automatic with the new approach. The little downside is that the automatic way is a bit slower than the `modularizeImports` config as it needs to do extra analyzation. But overall, this is a good direction. Depends on #59254. --- packages/next/src/server/config.ts | 45 +++++------------------------- 1 file changed, 7 insertions(+), 38 deletions(-) diff --git a/packages/next/src/server/config.ts b/packages/next/src/server/config.ts index 3968b19e60a7a..e97e764b3b65b 100644 --- a/packages/next/src/server/config.ts +++ b/packages/next/src/server/config.ts @@ -808,47 +808,9 @@ function assignDefaults( '@mui/icons-material': { transform: '@mui/icons-material/{{member}}', }, - 'date-fns': { - transform: 'date-fns/{{member}}', - }, lodash: { transform: 'lodash/{{member}}', }, - 'lodash-es': { - transform: 'lodash-es/{{member}}', - }, - ramda: { - transform: 'ramda/es/{{member}}', - }, - 'react-bootstrap': { - transform: { - useAccordionButton: - 'modularize-import-loader?name=useAccordionButton&from=named&as=default!react-bootstrap/AccordionButton', - '*': 'react-bootstrap/{{member}}', - }, - }, - antd: { - transform: 'antd/es/{{kebabCase member}}', - }, - ahooks: { - transform: { - createUpdateEffect: - 'modularize-import-loader?name=createUpdateEffect&from=named&as=default!ahooks/es/createUpdateEffect', - '*': 'ahooks/es/{{member}}', - }, - }, - '@ant-design/icons': { - transform: { - IconProvider: - 'modularize-import-loader?name=IconProvider&from=named&as=default!@ant-design/icons', - createFromIconfontCN: '@ant-design/icons/es/components/IconFont', - getTwoToneColor: - 'modularize-import-loader?name=getTwoToneColor&from=named&as=default!@ant-design/icons/es/components/twoTonePrimaryColor', - setTwoToneColor: - 'modularize-import-loader?name=setTwoToneColor&from=named&as=default!@ant-design/icons/es/components/twoTonePrimaryColor', - '*': '@ant-design/icons/lib/icons/{{member}}', - }, - }, 'next/server': { transform: 'next/dist/server/web/exports/{{ kebabCase member }}', }, @@ -863,6 +825,13 @@ function assignDefaults( ...new Set([ ...userProvidedOptimizePackageImports, 'lucide-react', + 'date-fns', + 'lodash-es', + 'ramda', + 'antd', + 'react-bootstrap', + 'ahooks', + '@ant-design/icons', '@headlessui/react', '@headlessui-float/react', '@heroicons/react/20/solid', From 6387c9cbcbaf53adb9fdba1306a5b8a3f76a8cd5 Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Tue, 5 Dec 2023 23:22:24 +0000 Subject: [PATCH 178/481] v14.0.4-canary.43 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 16 ++++++++-------- 18 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lerna.json b/lerna.json index 6cbd8611d3abc..5e136c52b67bb 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.42" + "version": "14.0.4-canary.43" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index c6e7dcecf3efe..f2e42be16b65c 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.42", + "version": "14.0.4-canary.43", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index d91c844240f40..bd56c4f074b44 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.42", + "version": "14.0.4-canary.43", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.42", + "@next/eslint-plugin-next": "14.0.4-canary.43", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 6f59fb7c3fee5..a115145aab69c 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.42", + "version": "14.0.4-canary.43", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index 3f508b2cfd5d2..ba174df65a3dd 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.42", + "version": "14.0.4-canary.43", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 0c49975c656a5..f4b871687d792 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.42", + "version": "14.0.4-canary.43", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index c0e6d754584ae..47764b7a10c52 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.42", + "version": "14.0.4-canary.43", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index a7fd1b8e0631a..f7535b5c80964 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.42", + "version": "14.0.4-canary.43", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 493e0abce3d42..93d3330593541 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.42", + "version": "14.0.4-canary.43", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 6518408bcc3ce..5cca06057f3d7 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.42", + "version": "14.0.4-canary.43", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index 4d3e42c657383..204c4a38832b3 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.42", + "version": "14.0.4-canary.43", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index 0b1fc481388f5..212b0ac961f37 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.42", + "version": "14.0.4-canary.43", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index 41adddeaf10be..648665cdf944d 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.42", + "version": "14.0.4-canary.43", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index f649dd4c343d9..41d7aa76bec0b 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.42", + "version": "14.0.4-canary.43", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.42", + "@next/env": "14.0.4-canary.43", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -147,11 +147,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.42", - "@next/polyfill-nomodule": "14.0.4-canary.42", - "@next/react-dev-overlay": "14.0.4-canary.42", - "@next/react-refresh-utils": "14.0.4-canary.42", - "@next/swc": "14.0.4-canary.42", + "@next/polyfill-module": "14.0.4-canary.43", + "@next/polyfill-nomodule": "14.0.4-canary.43", + "@next/react-dev-overlay": "14.0.4-canary.43", + "@next/react-refresh-utils": "14.0.4-canary.43", + "@next/swc": "14.0.4-canary.43", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index 0dc8d34cad62d..94b480d735c1b 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.42", + "version": "14.0.4-canary.43", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index e5274626f30e8..5909160ebaa1d 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.42", + "version": "14.0.4-canary.43", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index 52ce3baa0b33c..1c38eb47ab223 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.42", + "version": "14.0.4-canary.43", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -25,7 +25,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.42", + "next": "14.0.4-canary.43", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fe006d2a4a1d0..513a8290d8328 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -741,7 +741,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.42 + specifier: 14.0.4-canary.43 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -806,7 +806,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.42 + specifier: 14.0.4-canary.43 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -933,19 +933,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.42 + specifier: 14.0.4-canary.43 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.42 + specifier: 14.0.4-canary.43 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.42 + specifier: 14.0.4-canary.43 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.42 + specifier: 14.0.4-canary.43 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.42 + specifier: 14.0.4-canary.43 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1599,7 +1599,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.42 + specifier: 14.0.4-canary.43 version: link:../next outdent: specifier: 0.8.0 From eab1fe83976f1a5b49f6fc65eef8be8d5f20929f Mon Sep 17 00:00:00 2001 From: Wyatt Johnson Date: Tue, 5 Dec 2023 18:10:00 -0700 Subject: [PATCH 179/481] Enable PPR for `dynamic = "force-dynamic"` (#58779) This makes some critical modifications to the app render pipeline when PPR has been enabled for pages with segments defining: ```js export const dynamic = "force-dynamic" ``` Importantly, it no longer modifies the revalidation time to zero for those pages, and now falls back to the provided default revalidation time. When static render occurs, if the page being rendered has a segment config defining `dynamic === "force-dynamic"`, then it will postpone at the root of the component tree. This ensures that no render code is executed for the page, as the entirety of the tree will have postponed. This fixes the bug where the flight prefetch wasn't generated correctly as well. --- .github/workflows/build_and_test.yml | 44 ++++++----- packages/next/src/build/utils.ts | 5 +- .../src/client/components/maybe-postpone.ts | 30 -------- ...tatic-generation-async-storage.external.ts | 12 +-- .../components/static-generation-bailout.ts | 4 +- .../next/src/server/app-render/app-render.tsx | 2 +- .../app-render/create-component-tree.tsx | 73 ++++++++++++++----- ...static-generation-async-storage-wrapper.ts | 18 ++++- packages/next/src/server/base-server.ts | 56 +++++++------- packages/next/src/server/lib/patch-fetch.ts | 27 ++++--- packages/next/src/server/render-result.ts | 38 +++++++--- .../web/spec-extension/unstable-cache.ts | 10 +-- .../e2e/app-dir/app-static/app-static.test.ts | 41 ++++++----- .../[slug]/page.js | 15 +--- .../app/gen-params-dynamic/[slug]/page.js | 15 +--- .../post-method/page.js | 15 +--- .../headers-instance/page.js | 13 +--- .../variable-revalidate/post-method/page.js | 13 +--- .../variable-revalidate/status-code/page.js | 15 +--- .../e2e/app-dir/app-static/lib/fetch-retry.js | 22 ++++++ test/ppr-tests-manifest.json | 30 ++++++-- 21 files changed, 269 insertions(+), 229 deletions(-) delete mode 100644 packages/next/src/client/components/maybe-postpone.ts create mode 100644 test/e2e/app-dir/app-static/lib/fetch-retry.js diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml index 9a361911cf58c..375510c625013 100644 --- a/.github/workflows/build_and_test.yml +++ b/.github/workflows/build_and_test.yml @@ -163,10 +163,10 @@ jobs: strategy: fail-fast: false matrix: - group: [1, 2, 3, 4, 5] + group: [1/5, 2/5, 3/5, 4/5, 5/5] uses: ./.github/workflows/build_reusable.yml with: - afterBuild: RUST_BACKTRACE=0 NEXT_EXTERNAL_TESTS_FILTERS="$(pwd)/test/turbopack-tests-manifest.json" TURBOPACK=1 NEXT_E2E_TEST_TIMEOUT=240000 NEXT_TEST_MODE=dev node run-tests.js --test-pattern '^(test\/(development|e2e))/.*\.test\.(js|jsx|ts|tsx)$' --timings -g ${{ matrix.group }}/5 -c ${TEST_CONCURRENCY} + afterBuild: RUST_BACKTRACE=0 NEXT_EXTERNAL_TESTS_FILTERS="$(pwd)/test/turbopack-tests-manifest.json" TURBOPACK=1 NEXT_E2E_TEST_TIMEOUT=240000 NEXT_TEST_MODE=dev node run-tests.js --test-pattern '^(test\/(development|e2e))/.*\.test\.(js|jsx|ts|tsx)$' --timings -g ${{ matrix.group }} -c ${TEST_CONCURRENCY} secrets: inherit test-turbopack-integration: @@ -177,11 +177,11 @@ jobs: strategy: fail-fast: false matrix: - group: [1, 2, 3, 4, 5] + group: [1/5, 2/5, 3/5, 4/5, 5/5] uses: ./.github/workflows/build_reusable.yml with: nodeVersion: 18.17.0 - afterBuild: RUST_BACKTRACE=0 NEXT_EXTERNAL_TESTS_FILTERS="$(pwd)/test/turbopack-tests-manifest.json" TURBOPACK=1 node run-tests.js --timings -g ${{ matrix.group }}/5 -c ${TEST_CONCURRENCY} --type integration + afterBuild: RUST_BACKTRACE=0 NEXT_EXTERNAL_TESTS_FILTERS="$(pwd)/test/turbopack-tests-manifest.json" TURBOPACK=1 node run-tests.js --timings -g ${{ matrix.group }} -c ${TEST_CONCURRENCY} --type integration secrets: inherit test-next-swc-wasm: @@ -219,10 +219,10 @@ jobs: strategy: fail-fast: false matrix: - group: [1, 2, 3] + group: [1/4, 2/4, 3/4, 4/4] uses: ./.github/workflows/build_reusable.yml with: - afterBuild: NEXT_TEST_MODE=dev node run-tests.js --timings -g ${{ matrix.group }}/3 -c ${TEST_CONCURRENCY} --type development + afterBuild: NEXT_TEST_MODE=dev node run-tests.js --timings -g ${{ matrix.group }} -c ${TEST_CONCURRENCY} --type development secrets: inherit test-prod: @@ -233,10 +233,10 @@ jobs: strategy: fail-fast: false matrix: - group: [1, 2, 3, 4, 5] + group: [1/5, 2/5, 3/5, 4/5, 5/5] uses: ./.github/workflows/build_reusable.yml with: - afterBuild: NEXT_TEST_MODE=start node run-tests.js --timings -g ${{ matrix.group }}/5 -c ${TEST_CONCURRENCY} --type production + afterBuild: NEXT_TEST_MODE=start node run-tests.js --timings -g ${{ matrix.group }} -c ${TEST_CONCURRENCY} --type production secrets: inherit test-integration: @@ -247,11 +247,23 @@ jobs: strategy: fail-fast: false matrix: - group: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12] + group: + - 1/12 + - 2/12 + - 3/12 + - 4/12 + - 5/12 + - 6/12 + - 7/12 + - 8/12 + - 9/12 + - 10/12 + - 11/12 + - 12/12 uses: ./.github/workflows/build_reusable.yml with: nodeVersion: 18.17.0 - afterBuild: node run-tests.js --timings -g ${{ matrix.group }}/12 -c ${TEST_CONCURRENCY} --type integration + afterBuild: node run-tests.js --timings -g ${{ matrix.group }}2 -c ${TEST_CONCURRENCY} --type integration secrets: inherit test-firefox-safari: @@ -273,12 +285,10 @@ jobs: strategy: fail-fast: false - matrix: - group: [1, 2, 3] uses: ./.github/workflows/build_reusable.yml with: nodeVersion: 18.17.0 - afterBuild: __NEXT_EXPERIMENTAL_PPR=true NEXT_EXTERNAL_TESTS_FILTERS="test/ppr-tests-manifest.json" node run-tests.js --timings -g ${{ matrix.group }}/3 -c ${TEST_CONCURRENCY} --type integration + afterBuild: __NEXT_EXPERIMENTAL_PPR=true NEXT_EXTERNAL_TESTS_FILTERS="test/ppr-tests-manifest.json" node run-tests.js --timings -c ${TEST_CONCURRENCY} --type integration secrets: inherit test-ppr-dev: @@ -289,10 +299,10 @@ jobs: strategy: fail-fast: false matrix: - group: [1, 2, 3] + group: [1/4, 2/4, 3/4, 4/4] uses: ./.github/workflows/build_reusable.yml with: - afterBuild: __NEXT_EXPERIMENTAL_PPR=true NEXT_EXTERNAL_TESTS_FILTERS="test/ppr-tests-manifest.json" NEXT_TEST_MODE=dev node run-tests.js --timings -g ${{ matrix.group }}/3 -c ${TEST_CONCURRENCY} --type development + afterBuild: __NEXT_EXPERIMENTAL_PPR=true NEXT_EXTERNAL_TESTS_FILTERS="test/ppr-tests-manifest.json" NEXT_TEST_MODE=dev node run-tests.js --timings -g ${{ matrix.group }} -c ${TEST_CONCURRENCY} --type development secrets: inherit test-ppr-prod: @@ -303,10 +313,10 @@ jobs: strategy: fail-fast: false matrix: - group: [1, 2, 3] + group: [1/4, 2/4, 3/4, 4/4] uses: ./.github/workflows/build_reusable.yml with: - afterBuild: __NEXT_EXPERIMENTAL_PPR=true NEXT_EXTERNAL_TESTS_FILTERS="test/ppr-tests-manifest.json" NEXT_TEST_MODE=start node run-tests.js --timings -g ${{ matrix.group }}/3 -c ${TEST_CONCURRENCY} --type production + afterBuild: __NEXT_EXPERIMENTAL_PPR=true NEXT_EXTERNAL_TESTS_FILTERS="test/ppr-tests-manifest.json" NEXT_TEST_MODE=start node run-tests.js --timings -g ${{ matrix.group }} -c ${TEST_CONCURRENCY} --type production secrets: inherit report-test-results: diff --git a/packages/next/src/build/utils.ts b/packages/next/src/build/utils.ts index 643ca58b94036..9accdee7157f1 100644 --- a/packages/next/src/build/utils.ts +++ b/packages/next/src/build/utils.ts @@ -1572,7 +1572,10 @@ export async function isPageStatic({ ) } - if (appConfig.dynamic === 'force-dynamic') { + // If force dynamic was set and we don't have PPR enabled, then set the + // revalidate to 0. + // TODO: (PPR) remove this once PPR is enabled by default + if (appConfig.dynamic === 'force-dynamic' && !ppr) { appConfig.revalidate = 0 } diff --git a/packages/next/src/client/components/maybe-postpone.ts b/packages/next/src/client/components/maybe-postpone.ts deleted file mode 100644 index de216a5a378bc..0000000000000 --- a/packages/next/src/client/components/maybe-postpone.ts +++ /dev/null @@ -1,30 +0,0 @@ -import type { StaticGenerationStore } from './static-generation-async-storage.external' - -export function maybePostpone( - staticGenerationStore: StaticGenerationStore, - reason: string -) { - // If we aren't performing a static generation or we aren't using PPR then - // we don't need to postpone. - if ( - !staticGenerationStore.isStaticGeneration || - !staticGenerationStore.experimental.ppr - ) { - return - } - - if (!staticGenerationStore.postpone) { - throw new Error( - 'Invariant: PPR is enabled but the postpone API is unavailable' - ) - } - - // Keep track of if the postpone API has been called. - staticGenerationStore.postponeWasTriggered = true - - staticGenerationStore.postpone( - `This page needs to bail out of prerendering at this point because it used ${reason}. ` + - `React throws this special object to indicate where. It should not be caught by ` + - `your own try/catch. Learn more: https://nextjs.org/docs/messages/ppr-caught-error` - ) -} diff --git a/packages/next/src/client/components/static-generation-async-storage.external.ts b/packages/next/src/client/components/static-generation-async-storage.external.ts index 1119969c6c275..205143ad7b66a 100644 --- a/packages/next/src/client/components/static-generation-async-storage.external.ts +++ b/packages/next/src/client/components/static-generation-async-storage.external.ts @@ -16,6 +16,13 @@ export interface StaticGenerationStore { readonly isRevalidate?: boolean readonly isUnstableCacheCallback?: boolean + /** + * If defined, this function when called will throw an error postponing + * rendering during the React render phase. This should not be invoked outside + * of the React render phase as it'll throw an error. + */ + readonly postpone: ((reason: string) => never) | undefined + forceDynamic?: boolean fetchCache?: | 'only-cache' @@ -30,7 +37,6 @@ export interface StaticGenerationStore { dynamicShouldError?: boolean pendingRevalidates?: Record> postponeWasTriggered?: boolean - postpone?: (reason: string) => never dynamicUsageDescription?: string dynamicUsageStack?: string @@ -46,10 +52,6 @@ export interface StaticGenerationStore { fetchMetrics?: FetchMetrics isDraftMode?: boolean - - readonly experimental: { - readonly ppr: boolean - } } export type StaticGenerationAsyncStorage = diff --git a/packages/next/src/client/components/static-generation-bailout.ts b/packages/next/src/client/components/static-generation-bailout.ts index 558c2ec763081..df9df4123d085 100644 --- a/packages/next/src/client/components/static-generation-bailout.ts +++ b/packages/next/src/client/components/static-generation-bailout.ts @@ -1,7 +1,6 @@ import type { AppConfigDynamic } from '../../build/utils' import { DynamicServerError } from './hooks-server-context' -import { maybePostpone } from './maybe-postpone' import { staticGenerationAsyncStorage } from './static-generation-async-storage.external' class StaticGenBailoutError extends Error { @@ -47,7 +46,8 @@ export const staticGenerationBailout: StaticGenerationBailout = ( link: 'https://nextjs.org/docs/messages/dynamic-server-error', }) - maybePostpone(staticGenerationStore, reason) + // If postpone is available, we should postpone the render. + staticGenerationStore.postpone?.(reason) // As this is a bailout, we don't want to revalidate, so set the revalidate // to 0. diff --git a/packages/next/src/server/app-render/app-render.tsx b/packages/next/src/server/app-render/app-render.tsx index 407b66af3adeb..a22b23fee4765 100644 --- a/packages/next/src/server/app-render/app-render.tsx +++ b/packages/next/src/server/app-render/app-render.tsx @@ -1119,7 +1119,7 @@ async function renderToHTMLOrFlightImpl( if ( // if PPR is enabled renderOpts.experimental.ppr && - // and a call to `maybePostpone` happened + // and a call to `postpone` happened staticGenerationStore.postponeWasTriggered && // but there's no postpone state !metadata.postponed diff --git a/packages/next/src/server/app-render/create-component-tree.tsx b/packages/next/src/server/app-render/create-component-tree.tsx index 9da1f4e8a148c..12a01c9c63efd 100644 --- a/packages/next/src/server/app-render/create-component-tree.tsx +++ b/packages/next/src/server/app-render/create-component-tree.tsx @@ -1,5 +1,5 @@ import type { FlightSegmentPath, CacheNodeSeedData } from './types' -import React from 'react' +import React, { type ReactNode } from 'react' import { isClientReference } from '../../lib/client-reference' import { getLayoutOrPageModule } from '../lib/app-dir-module' import type { LoaderTree } from '../lib/app-dir-module' @@ -10,10 +10,26 @@ import { createComponentStylesAndScripts } from './create-component-styles-and-s import { getLayerAssets } from './get-layer-assets' import { hasLoadingComponentInTree } from './has-loading-component-in-tree' +type ComponentTree = { + seedData: CacheNodeSeedData + styles: ReactNode +} + /** - * Use the provided loader tree to create the React Component tree. + * This component will call `React.postpone` that throws the postponed error. */ +export const Postpone = ({ + postpone, +}: { + postpone: (reason: string) => never +}): never => { + // Call the postpone API now with the reason set to "force-dynamic". + return postpone('dynamic = "force-dynamic" was used') +} +/** + * Use the provided loader tree to create the React Component tree. + */ export async function createComponentTree({ createSegmentPath, loaderTree: tree, @@ -38,10 +54,7 @@ export async function createComponentTree({ asNotFound?: boolean metadataOutlet?: React.ReactNode ctx: AppRenderContext -}): Promise<{ - seedData: CacheNodeSeedData - styles: React.ReactNode -}> { +}): Promise { const { renderOpts: { nextConfigOutput }, staticGenerationStore, @@ -155,7 +168,13 @@ export async function createComponentTree({ staticGenerationStore.dynamicShouldError = true } else if (dynamic === 'force-dynamic') { staticGenerationStore.forceDynamic = true - staticGenerationBailout(`force-dynamic`, { dynamic }) + + // TODO: (PPR) remove this bailout once PPR is the default + if (!staticGenerationStore.postpone) { + // If the postpone API isn't available, we can't postpone the render and + // therefore we can't use the dynamic API. + staticGenerationBailout(`force-dynamic`, { dynamic }) + } } else { staticGenerationStore.dynamicShouldError = false if (dynamic === 'force-static') { @@ -183,7 +202,10 @@ export async function createComponentTree({ if ( staticGenerationStore.isStaticGeneration && - ctx.defaultRevalidate === 0 + ctx.defaultRevalidate === 0 && + // If the postpone API isn't available, we can't postpone the render and + // therefore we can't use the dynamic API. + !staticGenerationStore.postpone ) { const dynamicUsageDescription = `revalidate: 0 configured ${segment}` staticGenerationStore.dynamicUsageDescription = dynamicUsageDescription @@ -192,10 +214,8 @@ export async function createComponentTree({ } } - if ( - staticGenerationStore?.dynamicUsageErr && - !staticGenerationStore.experimental.ppr - ) { + // If there's a dynamic usage error attached to the store, throw it. + if (staticGenerationStore.dynamicUsageErr) { throw staticGenerationStore.dynamicUsageErr } @@ -391,6 +411,21 @@ export async function createComponentTree({ } } + // If force-dynamic is used and the current render supports postponing, we + // replace it with a node that will postpone the render. This ensures that the + // postpone is invoked during the react render phase and not during the next + // render phase. + if (staticGenerationStore.forceDynamic && staticGenerationStore.postpone) { + return { + seedData: [ + actualSegment, + parallelRouteCacheNodeSeedData, + , + ], + styles: layerAssets, + } + } + const isClientComponent = isClientReference(layoutOrPageMod) // If it's a not found route, and we don't have any matched parallel @@ -453,13 +488,13 @@ export async function createComponentTree({ )} {/* This null is currently critical. The wrapped Component can render null and if there was not fragment - surrounding it this would look like a pending tree data state on the client which will cause an errror - and break the app. Long-term we need to move away from using null as a partial tree identifier since it - is a valid return type for the components we wrap. Once we make this change we can safely remove the - fragment. The reason the extra null here is required is that fragments which only have 1 child are elided. - If the Component above renders null the actual treedata will look like `[null, null]`. If we remove the extra - null it will look like `null` (the array is elided) and this is what confuses the client router. - TODO-APP update router to use a Symbol for partial tree detection */} + surrounding it this would look like a pending tree data state on the client which will cause an error + and break the app. Long-term we need to move away from using null as a partial tree identifier since it + is a valid return type for the components we wrap. Once we make this change we can safely remove the + fragment. The reason the extra null here is required is that fragments which only have 1 child are elided. + If the Component above renders null the actual tree data will look like `[null, null]`. If we remove the extra + null it will look like `null` (the array is elided) and this is what confuses the client router. + TODO-APP update router to use a Symbol for partial tree detection */} {null} , ], diff --git a/packages/next/src/server/async-storage/static-generation-async-storage-wrapper.ts b/packages/next/src/server/async-storage/static-generation-async-storage-wrapper.ts index 18e0076a9f781..f3068d3f3924f 100644 --- a/packages/next/src/server/async-storage/static-generation-async-storage-wrapper.ts +++ b/packages/next/src/server/async-storage/static-generation-async-storage-wrapper.ts @@ -77,8 +77,22 @@ export const StaticGenerationAsyncStorageWrapper: AsyncStorageWrapper< isOnDemandRevalidate: renderOpts.isOnDemandRevalidate, isDraftMode: renderOpts.isDraftMode, - experimental: renderOpts.experimental, - postpone, + + postpone: + // If we aren't performing a static generation or we aren't using PPR then + // we don't need to postpone. + isStaticGeneration && renderOpts.experimental.ppr && postpone + ? (reason: string) => { + // Keep track of if the postpone API has been called. + store.postponeWasTriggered = true + + return postpone( + `This page needs to bail out of prerendering at this point because it used ${reason}. ` + + `React throws this special object to indicate where. It should not be caught by ` + + `your own try/catch. Learn more: https://nextjs.org/docs/messages/ppr-caught-error` + ) + } + : undefined, } // TODO: remove this when we resolve accessing the store outside the execution context diff --git a/packages/next/src/server/base-server.ts b/packages/next/src/server/base-server.ts index 8e49d9d1c52ee..2e3933245e84c 100644 --- a/packages/next/src/server/base-server.ts +++ b/packages/next/src/server/base-server.ts @@ -1886,13 +1886,7 @@ export default abstract class Server { // If we're in minimal mode, then try to get the postponed information from // the request metadata. If available, use it for resuming the postponed // render. - let resumed: { postponed: string } | null = null - if (this.minimalMode) { - const postponed = getRequestMeta(req, 'postponed') - if (postponed) { - resumed = { postponed } - } - } + const minimalPostponed = getRequestMeta(req, 'postponed') // If PPR is enabled, and this is a RSC request (but not a prefetch), then // we can use this fact to only generate the flight data for the request @@ -1921,7 +1915,7 @@ export default abstract class Server { // Server actions can use non-GET/HEAD methods. !isServerAction && // Resume can use non-GET/HEAD methods. - !resumed && + !minimalPostponed && !is404Page && !is500Page && pathname !== '/_error' && @@ -2079,7 +2073,7 @@ export default abstract class Server { isSSG && !opts.supportsDynamicHTML && !isServerAction && - !resumed && + !minimalPostponed && !isDynamicRSCRequest ) { ssgCacheKey = `${locale ? `/${locale}` : ''}${ @@ -2142,11 +2136,15 @@ export default abstract class Server { const { routeModule } = components - type Renderer = ( + type Renderer = (context: { + /** + * The postponed data for this render. This is only provided when resuming + * a render that has been postponed. + */ postponed: string | undefined - ) => Promise + }) => Promise - const doRender: Renderer = async (postponed) => { + const doRender: Renderer = async ({ postponed }) => { // In development, we always want to generate dynamic HTML. const supportsDynamicHTML: boolean = // If this isn't a data request and we're not in development, then we @@ -2157,7 +2155,7 @@ export default abstract class Server { (!isSSG && !hasStaticPaths) || // If this request has provided postponed data, it supports dynamic // HTML. - !!postponed || + typeof postponed === 'string' || // If this is a dynamic RSC request, then this render supports dynamic // HTML (it's dynamic). isDynamicRSCRequest @@ -2186,7 +2184,11 @@ export default abstract class Server { ...(isAppPath ? { incrementalCache, - isRevalidate: isSSG, + // This is a revalidation request if the request is for a static + // page and it is not being resumed from a postponed render and + // it is not a dynamic RSC request then it is a revalidation + // request. + isRevalidate: isSSG && !postponed && !isDynamicRSCRequest, originalPathname: components.ComponentMod.originalPathname, serverActions: this.nextConfig.experimental.serverActions, } @@ -2386,7 +2388,8 @@ export default abstract class Server { isAppPath && isSSG && metadata.revalidate === 0 && - !this.renderOpts.dev + !this.renderOpts.dev && + !renderOpts.experimental.ppr ) { const staticBailoutInfo = metadata.staticBailoutInfo @@ -2489,12 +2492,6 @@ export default abstract class Server { isOnDemandRevalidate = true } - // Only requests that aren't revalidating can be resumed. - const postponed = - !isOnDemandRevalidate && !isRevalidating && resumed - ? resumed.postponed - : undefined - // only allow on-demand revalidate for fallback: true/blocking // or for prerendered fallback: false paths if ( @@ -2577,7 +2574,7 @@ export default abstract class Server { // We pass `undefined` as there cannot be a postponed state in // development. - const result = await doRender(undefined) + const result = await doRender({ postponed: undefined }) if (!result) { return null } @@ -2588,7 +2585,14 @@ export default abstract class Server { } } - const result = await doRender(postponed) + const result = await doRender({ + // Only requests that aren't revalidating can be resumed. If we have the + // minimal postponed data, then we should resume the render with it. + postponed: + !isOnDemandRevalidate && !isRevalidating && minimalPostponed + ? minimalPostponed + : undefined, + }) if (!result) { return null } @@ -2648,7 +2652,7 @@ export default abstract class Server { // If this is a resume request in minimal mode it is streamed with dynamic // content and should not be cached. - if (this.minimalMode && resumed?.postponed) { + if (minimalPostponed) { revalidate = 0 } @@ -2765,7 +2769,7 @@ export default abstract class Server { } else if (isAppPath) { // If the request has a postponed state and it's a resume request we // should error. - if (cachedData.postponed && resumed) { + if (cachedData.postponed && minimalPostponed) { throw new Error( 'Invariant: postponed state should not be present on a resume request' ) @@ -2875,7 +2879,7 @@ export default abstract class Server { // Perform the render again, but this time, provide the postponed state. // We don't await because we want the result to start streaming now, and // we've already chained the transformer's readable to the render result. - doRender(cachedData.postponed) + doRender({ postponed: cachedData.postponed }) .then(async (result) => { if (!result) { throw new Error('Invariant: expected a result to be returned') diff --git a/packages/next/src/server/lib/patch-fetch.ts b/packages/next/src/server/lib/patch-fetch.ts index d90e2ba11640a..8efbc228aea63 100644 --- a/packages/next/src/server/lib/patch-fetch.ts +++ b/packages/next/src/server/lib/patch-fetch.ts @@ -12,7 +12,6 @@ import { NEXT_CACHE_TAG_MAX_LENGTH, } from '../../lib/constants' import * as Log from '../../build/output/log' -import { maybePostpone } from '../../client/components/maybe-postpone' const isEdgeRuntime = process.env.NEXT_RUNTIME === 'edge' @@ -372,15 +371,19 @@ export function patchFetch({ // we don't consider autoNoCache to switch to dynamic during // revalidate although if it occurs during build we do !autoNoCache && + // If the revalidate value isn't currently set or the value is less + // than the current revalidate value, we should update the revalidate + // value. (typeof staticGenerationStore.revalidate === 'undefined' || (typeof revalidate === 'number' && (staticGenerationStore.revalidate === false || (typeof staticGenerationStore.revalidate === 'number' && revalidate < staticGenerationStore.revalidate)))) ) { - // If enabled, we should bail out of static generation. + // If we were setting the revalidate value to 0, we should try to + // postpone instead first. if (revalidate === 0) { - maybePostpone(staticGenerationStore, 'revalidate: 0') + staticGenerationStore.postpone?.('revalidate: 0') } staticGenerationStore.revalidate = revalidate @@ -594,17 +597,17 @@ export function patchFetch({ ? ` ${staticGenerationStore.urlPathname}` : '' }` - const err = new DynamicServerError(dynamicUsageReason) - staticGenerationStore.dynamicUsageErr = err - staticGenerationStore.dynamicUsageStack = err.stack - staticGenerationStore.dynamicUsageDescription = dynamicUsageReason // If enabled, we should bail out of static generation. - maybePostpone(staticGenerationStore, dynamicUsageReason) + staticGenerationStore.postpone?.(dynamicUsageReason) // PPR is not enabled, or React postpone is not available, we // should set the revalidate to 0. staticGenerationStore.revalidate = 0 + + const err = new DynamicServerError(dynamicUsageReason) + staticGenerationStore.dynamicUsageErr = err + staticGenerationStore.dynamicUsageDescription = dynamicUsageReason } const hasNextConfig = 'next' in init @@ -623,13 +626,13 @@ export function patchFetch({ ? ` ${staticGenerationStore.urlPathname}` : '' }` + + // If enabled, we should bail out of static generation. + staticGenerationStore.postpone?.(dynamicUsageReason) + const err = new DynamicServerError(dynamicUsageReason) staticGenerationStore.dynamicUsageErr = err - staticGenerationStore.dynamicUsageStack = err.stack staticGenerationStore.dynamicUsageDescription = dynamicUsageReason - - // If enabled, we should bail out of static generation. - maybePostpone(staticGenerationStore, dynamicUsageReason) } if (!forceDynamic || next.revalidate !== 0) { diff --git a/packages/next/src/server/render-result.ts b/packages/next/src/server/render-result.ts index 6f9f87d0f6f50..2e8b1379b35c6 100644 --- a/packages/next/src/server/render-result.ts +++ b/packages/next/src/server/render-result.ts @@ -204,22 +204,42 @@ export default class RenderResult< /** * Pipes the response to a writable stream. This will close/cancel the - * writable stream if an error is encountered. + * writable stream if an error is encountered. If this doesn't throw, then + * the writable stream will be closed or aborted. * * @param writable Writable stream to pipe the response to */ public async pipeTo(writable: WritableStream): Promise { try { - await this.readable.pipeTo(writable) + await this.readable.pipeTo(writable, { + // We want to close the writable stream ourselves so that we can wait + // for the waitUntil promise to resolve before closing it. If an error + // is encountered, we'll abort the writable stream if we swallowed the + // error. + preventClose: true, + }) + + // If there is a waitUntil promise, wait for it to resolve before + // closing the writable stream. + if (this.waitUntil) await this.waitUntil + + // Close the writable stream. + await writable.close() } catch (err) { - // If this isn't a client abort, then re-throw the error. - if (!isAbortError(err)) { - throw err - } - } finally { - if (this.waitUntil) { - await this.waitUntil + // If this is an abort error, we should abort the writable stream (as we + // took ownership of it when we started piping). We don't need to re-throw + // because we handled the error. + if (isAbortError(err)) { + // Abort the writable stream if an error is encountered. + await writable.abort(err) + + return } + + // We're not aborting the writer here as when this method throws it's not + // clear as to how so the caller should assume it's their responsibility + // to clean up the writer. + throw err } } diff --git a/packages/next/src/server/web/spec-extension/unstable-cache.ts b/packages/next/src/server/web/spec-extension/unstable-cache.ts index 237bdf1688a28..5ac1d458bd322 100644 --- a/packages/next/src/server/web/spec-extension/unstable-cache.ts +++ b/packages/next/src/server/web/spec-extension/unstable-cache.ts @@ -1,8 +1,8 @@ -import { maybePostpone } from '../../../client/components/maybe-postpone' import type { StaticGenerationStore, StaticGenerationAsyncStorage, } from '../../../client/components/static-generation-async-storage.external' + import { staticGenerationAsyncStorage as _staticGenerationAsyncStorage } from '../../../client/components/static-generation-async-storage.external' import { CACHE_ONE_YEAR } from '../../../lib/constants' import { addImplicitTags, validateTags } from '../../lib/patch-fetch' @@ -33,7 +33,9 @@ export function unstable_cache( if (store && typeof options.revalidate === 'number') { // Revalidate 0 is a special case, it means opt-out of static generation. if (options.revalidate === 0) { - maybePostpone(store, 'revalidate: 0') + // If postpone is supported we should postpone the render. + store.postpone?.('revalidate: 0') + // Set during dynamic rendering store.revalidate = 0 // If revalidate was already set in the store before we should check if the new value is lower, set it to the lowest of the two. @@ -75,9 +77,7 @@ export function unstable_cache( urlPathname: store?.urlPathname || '/', isUnstableCacheCallback: true, isStaticGeneration: store?.isStaticGeneration === true, - experimental: { - ppr: store?.experimental?.ppr === true, - }, + postpone: store?.postpone, }, async () => { const tags = validateTags( diff --git a/test/e2e/app-dir/app-static/app-static.test.ts b/test/e2e/app-dir/app-static/app-static.test.ts index 6ab4bf5267757..a2efc37dee287 100644 --- a/test/e2e/app-dir/app-static/app-static.test.ts +++ b/test/e2e/app-dir/app-static/app-static.test.ts @@ -1705,35 +1705,38 @@ createNextDescribe( { path: '/stale-cache-serving-edge/app-page' }, { path: '/stale-cache-serving-edge/route-handler' }, ])('should stream properly for $path', async ({ path }) => { - // prime cache initially - await next.fetch(path) + // Prime the cache. + let res = await next.fetch(path) + expect(res.status).toBe(200) + + // Consume the cache, the revalidations are completed on the end of the + // stream so we need to wait for that to complete. + await res.text() for (let i = 0; i < 6; i++) { await waitFor(1000) - const start = Date.now() - let streamStart = 0 - const res = await next.fetch(path) - const chunks: any[] = [] - await new Promise((bodyResolve) => { - res.body.on('data', (chunk) => { - if (!streamStart) { - streamStart = Date.now() + const timings = { + start: Date.now(), + startedStreaming: 0, + } + + res = await next.fetch(path) + + // eslint-disable-next-line no-loop-func + await new Promise((resolve) => { + res.body.on('data', () => { + if (!timings.startedStreaming) { + timings.startedStreaming = Date.now() } - chunks.push(chunk) }) res.body.on('end', () => { - bodyResolve() + resolve() }) }) - require('console').log({ - start, - duration: Date.now() - start, - streamStart, - startDuration: streamStart - start, - }) - expect(streamStart - start).toBeLessThan(3000) + + expect(timings.startedStreaming - timings.start).toBeLessThan(3000) } }) diff --git a/test/e2e/app-dir/app-static/app/gen-params-dynamic-revalidate/[slug]/page.js b/test/e2e/app-dir/app-static/app/gen-params-dynamic-revalidate/[slug]/page.js index 7476245fbf597..23b94efed6e8c 100644 --- a/test/e2e/app-dir/app-static/app/gen-params-dynamic-revalidate/[slug]/page.js +++ b/test/e2e/app-dir/app-static/app/gen-params-dynamic-revalidate/[slug]/page.js @@ -1,22 +1,11 @@ +import { fetchRetry } from '../../../lib/fetch-retry' + export const revalidate = 3 export async function generateStaticParams() { return [{ slug: 'one' }] } -const fetchRetry = async (url, init) => { - for (let i = 0; i < 5; i++) { - try { - return await fetch(url, init) - } catch (err) { - if (i === 4) { - throw err - } - console.log(`Failed to fetch`, err, `retrying...`) - } - } -} - export default async function page({ params }) { const { slug } = params let data diff --git a/test/e2e/app-dir/app-static/app/gen-params-dynamic/[slug]/page.js b/test/e2e/app-dir/app-static/app/gen-params-dynamic/[slug]/page.js index a2877f298b44e..f9d5366ea389b 100644 --- a/test/e2e/app-dir/app-static/app/gen-params-dynamic/[slug]/page.js +++ b/test/e2e/app-dir/app-static/app/gen-params-dynamic/[slug]/page.js @@ -1,20 +1,9 @@ +import { fetchRetry } from '../../../lib/fetch-retry' + export async function generateStaticParams() { return [{ slug: 'one' }] } -const fetchRetry = async (url, init) => { - for (let i = 0; i < 5; i++) { - try { - return await fetch(url, init) - } catch (err) { - if (i === 4) { - throw err - } - console.log(`Failed to fetch`, err, `retrying...`) - } - } -} - export default async function page({ params }) { const { slug } = params const data = await fetchRetry( diff --git a/test/e2e/app-dir/app-static/app/variable-revalidate-edge/post-method/page.js b/test/e2e/app-dir/app-static/app/variable-revalidate-edge/post-method/page.js index d8ae4909afa4b..0ca937144c965 100644 --- a/test/e2e/app-dir/app-static/app/variable-revalidate-edge/post-method/page.js +++ b/test/e2e/app-dir/app-static/app/variable-revalidate-edge/post-method/page.js @@ -1,17 +1,6 @@ -export const runtime = 'experimental-edge' +import { fetchRetry } from '../../../lib/fetch-retry' -const fetchRetry = async (url, init) => { - for (let i = 0; i < 5; i++) { - try { - return await fetch(url, init) - } catch (err) { - if (i === 4) { - throw err - } - console.log(`Failed to fetch`, err, `retrying...`) - } - } -} +export const runtime = 'experimental-edge' export default async function Page() { const data = await fetchRetry( diff --git a/test/e2e/app-dir/app-static/app/variable-revalidate/headers-instance/page.js b/test/e2e/app-dir/app-static/app/variable-revalidate/headers-instance/page.js index 0798d79dd6d74..870fc9f6b4477 100644 --- a/test/e2e/app-dir/app-static/app/variable-revalidate/headers-instance/page.js +++ b/test/e2e/app-dir/app-static/app/variable-revalidate/headers-instance/page.js @@ -1,15 +1,4 @@ -const fetchRetry = async (url, init) => { - for (let i = 0; i < 5; i++) { - try { - return await fetch(url, init) - } catch (err) { - if (i === 4) { - throw err - } - console.log(`Failed to fetch`, err, `retrying...`) - } - } -} +import { fetchRetry } from '../../../lib/fetch-retry' export default async function Page() { const data = await fetchRetry( diff --git a/test/e2e/app-dir/app-static/app/variable-revalidate/post-method/page.js b/test/e2e/app-dir/app-static/app/variable-revalidate/post-method/page.js index ffb942c08bf56..72637db68c414 100644 --- a/test/e2e/app-dir/app-static/app/variable-revalidate/post-method/page.js +++ b/test/e2e/app-dir/app-static/app/variable-revalidate/post-method/page.js @@ -1,15 +1,4 @@ -const fetchRetry = async (url, init) => { - for (let i = 0; i < 5; i++) { - try { - return await fetch(url, init) - } catch (err) { - if (i === 4) { - throw err - } - console.log(`Failed to fetch`, err, `retrying...`) - } - } -} +import { fetchRetry } from '../../../lib/fetch-retry' export default async function Page() { const data = await fetchRetry( diff --git a/test/e2e/app-dir/app-static/app/variable-revalidate/status-code/page.js b/test/e2e/app-dir/app-static/app/variable-revalidate/status-code/page.js index 884a6c3da6eee..89a380f33b46d 100644 --- a/test/e2e/app-dir/app-static/app/variable-revalidate/status-code/page.js +++ b/test/e2e/app-dir/app-static/app/variable-revalidate/status-code/page.js @@ -1,17 +1,6 @@ -export const revalidate = 0 +import { fetchRetry } from '../../../lib/fetch-retry' -const fetchRetry = async (url, init) => { - for (let i = 0; i < 5; i++) { - try { - return await fetch(url, init) - } catch (err) { - if (i === 4) { - throw err - } - console.log(`Failed to fetch`, err, `retrying...`) - } - } -} +export const revalidate = 0 export default async function Page() { const data = await fetchRetry( diff --git a/test/e2e/app-dir/app-static/lib/fetch-retry.js b/test/e2e/app-dir/app-static/lib/fetch-retry.js new file mode 100644 index 0000000000000..3f83f558f5df7 --- /dev/null +++ b/test/e2e/app-dir/app-static/lib/fetch-retry.js @@ -0,0 +1,22 @@ +const MAX_ATTEMPTS = 5 + +export const fetchRetry = async (url, init) => { + for (let i = 0; i < MAX_ATTEMPTS; i++) { + try { + return await fetch(url, init) + } catch (err) { + // FIXME: (PPR) this is a workaround until we have a way to detect postpone errors + // For PPR, we need to detect if this is a postpone error so we can + // re-throw it. + if (err.$$typeof === Symbol.for('react.postpone')) { + throw err + } + + if (i === MAX_ATTEMPTS - 1) { + throw err + } + + console.log(`Failed to fetch`, err, `retrying...`) + } + } +} diff --git a/test/ppr-tests-manifest.json b/test/ppr-tests-manifest.json index faaa19186704e..245e69a789749 100644 --- a/test/ppr-tests-manifest.json +++ b/test/ppr-tests-manifest.json @@ -1,6 +1,14 @@ { "version": 2, "suites": { + "test/e2e/app-dir/app-static/app-static.test.ts": { + "failed": [ + "app-dir static/dynamic handling usePathname should have values from canonical url on rewrite", + "app-dir static/dynamic handling should have correct prerender-manifest entries", + "app-dir static/dynamic handling should output HTML/RSC files for static paths", + "app-dir static/dynamic handling should output debug info for static bailouts" + ] + }, "test/e2e/app-dir/app-client-cache/client-cache.test.ts": { "failed": [ "app dir client cache semantics prefetch={undefined} - default should re-use the full cache for only 30 seconds", @@ -37,6 +45,22 @@ "app dir - rsc basics should render server components correctly" ] }, + "test/e2e/app-dir/navigation/navigation.test.ts": { + "failed": [ + "app dir - navigation redirect status code should respond with 308 status code if permanent flag is set", + "app dir - navigation redirect status code should respond with 307 status code in client component", + "app dir - navigation redirect status code should respond with 307 status code in server component", + "app dir - navigation bots should block rendering for bots and return 404 status", + "app dir - navigation navigation between pages and app should not continously initiate a mpa navigation to the same URL when router state changes" + ] + }, + "test/e2e/app-dir/app-static/app-static-custom-handler.test.ts": { + "failed": [ + "app-dir static/dynamic handling should output debug info for static bailouts", + "app-dir static/dynamic handling should have correct prerender-manifest entries", + "app-dir static/dynamic handling should output HTML/RSC files for static paths" + ] + }, "test/production/app-dir/unexpected-error/unexpected-error.test.ts": { "failed": [ "unexpected-error should set response status to 500 for unexpected errors in ssr app route", @@ -57,11 +81,7 @@ "test/e2e/app-dir/ppr/**/*", "test/e2e/app-dir/app-prefetch*/**/*", "test/e2e/app-dir/interception-middleware-rewrite/interception-middleware-rewrite.test.ts", - "test/e2e/app-dir/searchparams-static-bailout/searchparams-static-bailout.test.ts", - "test/e2e/app-dir/app-static/app-static-custom-handler.test.ts", - "test/e2e/app-dir/app-static/app-static.test.ts", - "test/e2e/app-dir/app-static/app-static-custom-cache-handler-esm.test.ts", - "test/e2e/app-dir/navigation/navigation.test.ts" + "test/e2e/app-dir/searchparams-static-bailout/searchparams-static-bailout.test.ts" ] } } From 873bd82ff96b60e84d2a419d43f0428a0a8e0cda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mustafa=20=C3=87or?= Date: Wed, 6 Dec 2023 06:21:56 +0300 Subject: [PATCH 180/481] docs: Server Action example (#59159) --- .../02-api-reference/04-functions/revalidateTag.mdx | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/docs/02-app/02-api-reference/04-functions/revalidateTag.mdx b/docs/02-app/02-api-reference/04-functions/revalidateTag.mdx index 2af2cb5a06fb3..5174116dcdbd2 100644 --- a/docs/02-app/02-api-reference/04-functions/revalidateTag.mdx +++ b/docs/02-app/02-api-reference/04-functions/revalidateTag.mdx @@ -43,6 +43,17 @@ export default async function submit() { } ``` +```js filename="app/actions.js" switcher +'use server' + +import { revalidateTag } from 'next/cache' + +export default async function submit() { + await addPost() + revalidateTag('posts') +} +``` + ### Route Handler ```ts filename="app/api/revalidate/route.ts" switcher From caa05b4753685b3e8dbb79781d6137a8c8bfbe17 Mon Sep 17 00:00:00 2001 From: Jiwon Choi Date: Wed, 6 Dec 2023 12:30:27 +0900 Subject: [PATCH 181/481] docs: Remove invalid URL (#58823) This PR removes guidance to invalid URL --- .../01-building-your-application/05-optimizing/10-testing.mdx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/docs/03-pages/01-building-your-application/05-optimizing/10-testing.mdx b/docs/03-pages/01-building-your-application/05-optimizing/10-testing.mdx index 80f3345e90338..b5dbf85eb8384 100644 --- a/docs/03-pages/01-building-your-application/05-optimizing/10-testing.mdx +++ b/docs/03-pages/01-building-your-application/05-optimizing/10-testing.mdx @@ -535,7 +535,3 @@ The Next.js community has created packages and articles you may find helpful: - [next-router-mock](https://github.com/scottrippey/next-router-mock) for Storybook. - [Test Preview Vercel Deploys with Cypress](https://glebbahmutov.com/blog/develop-preview-test/) by Gleb Bahmutov. - -For more information on what to read next, we recommend: - - - pages/basic-features/environment-variables#test-environment-variables From 75975dd5e4f85be24e19b689dc1a16213b1f59d1 Mon Sep 17 00:00:00 2001 From: Willem-Jaap <67187467+Willem-Jaap@users.noreply.github.com> Date: Wed, 6 Dec 2023 04:31:58 +0100 Subject: [PATCH 182/481] docs: Fix incorrect prop name in client component (#58591) `updateItem` is the name of the action, not the passed prop. The correct property name is `myAction`. --- docs/02-app/02-api-reference/04-functions/server-actions.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/02-app/02-api-reference/04-functions/server-actions.mdx b/docs/02-app/02-api-reference/04-functions/server-actions.mdx index 01c275d6c3ead..bd29d63003315 100644 --- a/docs/02-app/02-api-reference/04-functions/server-actions.mdx +++ b/docs/02-app/02-api-reference/04-functions/server-actions.mdx @@ -76,9 +76,9 @@ In some cases, you might want to pass down a Server Action to a Client Component ```jsx filename="app/client-component.jsx" 'use client' -export default function ClientComponent({ updateItem }) { +export default function ClientComponent({ myAction }) { return ( -
+
From d0159160dca04e6c801c82fde38bc7e932fa577d Mon Sep 17 00:00:00 2001 From: Jackie <102015496+JackieLi565@users.noreply.github.com> Date: Tue, 5 Dec 2023 22:33:14 -0500 Subject: [PATCH 183/481] docs: update Firebase link to `with-firebase` example (#58621) --- .../01-routing/09-authenticating.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/03-pages/01-building-your-application/01-routing/09-authenticating.mdx b/docs/03-pages/01-building-your-application/01-routing/09-authenticating.mdx index 4995c92433564..3d904406955db 100644 --- a/docs/03-pages/01-building-your-application/01-routing/09-authenticating.mdx +++ b/docs/03-pages/01-building-your-application/01-routing/09-authenticating.mdx @@ -130,7 +130,7 @@ To see examples with other authentication providers, check out the [examples fol - [Auth0](https://github.com/vercel/next.js/tree/canary/examples/auth0) - [Clerk](https://github.com/vercel/next.js/tree/canary/examples/with-clerk) -- [Firebase](https://github.com/vercel/next.js/tree/canary/examples/with-firebase-authentication) +- [Firebase](https://github.com/vercel/next.js/tree/canary/examples/with-firebase) - [Magic](https://github.com/vercel/next.js/tree/canary/examples/with-magic) - [Nhost](https://github.com/vercel/next.js/tree/canary/examples/with-nhost-auth-realtime-graphql) - [Ory](https://github.com/vercel/examples/tree/main/solutions/auth-with-ory) From 3caa2891c786e9c909c917789f8bac7e9fbc2ec8 Mon Sep 17 00:00:00 2001 From: Thoushif Aazam Shaik Date: Tue, 5 Dec 2023 21:33:47 -0600 Subject: [PATCH 184/481] docs: added missing comma to the props list (#58596) --- docs/02-app/02-api-reference/02-file-conventions/page.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/02-app/02-api-reference/02-file-conventions/page.mdx b/docs/02-app/02-api-reference/02-file-conventions/page.mdx index e1cfa04de45b0..f32a65caeff66 100644 --- a/docs/02-app/02-api-reference/02-file-conventions/page.mdx +++ b/docs/02-app/02-api-reference/02-file-conventions/page.mdx @@ -10,7 +10,7 @@ export default function Page({ params, searchParams, }: { - params: { slug: string } + params: { slug: string }, searchParams: { [key: string]: string | string[] | undefined } }) { return

My Page

From 4a5226890746174c60146d1d7e5e5227d8b224ef Mon Sep 17 00:00:00 2001 From: Peter Kellner Date: Tue, 5 Dec 2023 19:34:19 -0800 Subject: [PATCH 185/481] docs: Update route handles TS code snippets (#59021) --- .../01-routing/10-route-handlers.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/02-app/01-building-your-application/01-routing/10-route-handlers.mdx b/docs/02-app/01-building-your-application/01-routing/10-route-handlers.mdx index 3da9d0cb5a2e0..a79988e1bf5a9 100644 --- a/docs/02-app/01-building-your-application/01-routing/10-route-handlers.mdx +++ b/docs/02-app/01-building-your-application/01-routing/10-route-handlers.mdx @@ -99,7 +99,7 @@ export async function GET(request: Request) { const res = await fetch(`https://data.mongodb-api.com/product/${id}`, { headers: { 'Content-Type': 'application/json', - 'API-Key': process.env.DATA_API_KEY, + 'API-Key': process.env.DATA_API_KEY!, }, }) const product = await res.json() @@ -132,7 +132,7 @@ export async function POST() { method: 'POST', headers: { 'Content-Type': 'application/json', - 'API-Key': process.env.DATA_API_KEY, + 'API-Key': process.env.DATA_API_KEY!, }, body: JSON.stringify({ time: new Date().toISOString() }), }) From 3f20b46b59c6a91fed562cffc842e1db79727539 Mon Sep 17 00:00:00 2001 From: Justin Pfifer <61801015+jpfifer@users.noreply.github.com> Date: Tue, 5 Dec 2023 20:34:37 -0700 Subject: [PATCH 186/481] docs: Add note about middleware and runtimes (#58873) Co-authored-by: Justin Pfifer Co-authored-by: Lee Robinson --- .../01-building-your-application/01-routing/11-middleware.mdx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/02-app/01-building-your-application/01-routing/11-middleware.mdx b/docs/02-app/01-building-your-application/01-routing/11-middleware.mdx index b15fa22d81922..429ecd008b833 100644 --- a/docs/02-app/01-building-your-application/01-routing/11-middleware.mdx +++ b/docs/02-app/01-building-your-application/01-routing/11-middleware.mdx @@ -388,6 +388,10 @@ export default async function middleware(req) { } ``` +## Runtime + +Middleware currently only supports the [Edge runtime](/docs/app/building-your-application/rendering/edge-and-nodejs-runtimes). The Node.js runtime can not be used. + ## Version History | Version | Changes | From f431600ce4067b00724dbcf0727caaddd90a73c1 Mon Sep 17 00:00:00 2001 From: Zack Tanner Date: Tue, 5 Dec 2023 20:39:45 -0800 Subject: [PATCH 187/481] Revert "added comma to the props list" (#59314) Reverts vercel/next.js#58596 This is failing lint checks [x-ref](https://github.com/vercel/next.js/actions/runs/7109843046/job/19355454595) --- docs/02-app/02-api-reference/02-file-conventions/page.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/02-app/02-api-reference/02-file-conventions/page.mdx b/docs/02-app/02-api-reference/02-file-conventions/page.mdx index f32a65caeff66..e1cfa04de45b0 100644 --- a/docs/02-app/02-api-reference/02-file-conventions/page.mdx +++ b/docs/02-app/02-api-reference/02-file-conventions/page.mdx @@ -10,7 +10,7 @@ export default function Page({ params, searchParams, }: { - params: { slug: string }, + params: { slug: string } searchParams: { [key: string]: string | string[] | undefined } }) { return

My Page

From 59f7ca85c2efce459b906a235ef6ccc1b0e537fc Mon Sep 17 00:00:00 2001 From: Zack Tanner Date: Tue, 5 Dec 2023 21:29:23 -0800 Subject: [PATCH 188/481] remove additional static prefetch code (#59313) This is a continuation from https://github.com/vercel/next.js/pull/58783 to remove the remaining code related to static prefetching. --- ...tatic-generation-async-storage.external.ts | 1 - .../components/static-generation-bailout.ts | 6 -- packages/next/src/server/base-server.ts | 24 -------- .../app-dir/app-prefetch/prefetching.test.ts | 18 ------ .../e2e/app-dir/app-static/app-static.test.ts | 17 ------ test/e2e/app-dir/app/index.test.ts | 56 ------------------- 6 files changed, 122 deletions(-) diff --git a/packages/next/src/client/components/static-generation-async-storage.external.ts b/packages/next/src/client/components/static-generation-async-storage.external.ts index 205143ad7b66a..1ea0a0130a3f9 100644 --- a/packages/next/src/client/components/static-generation-async-storage.external.ts +++ b/packages/next/src/client/components/static-generation-async-storage.external.ts @@ -41,7 +41,6 @@ export interface StaticGenerationStore { dynamicUsageDescription?: string dynamicUsageStack?: string dynamicUsageErr?: DynamicServerError - staticPrefetchBailout?: boolean nextFetchId?: number pathWasRevalidated?: boolean diff --git a/packages/next/src/client/components/static-generation-bailout.ts b/packages/next/src/client/components/static-generation-bailout.ts index df9df4123d085..204ed3c843cdc 100644 --- a/packages/next/src/client/components/static-generation-bailout.ts +++ b/packages/next/src/client/components/static-generation-bailout.ts @@ -53,12 +53,6 @@ export const staticGenerationBailout: StaticGenerationBailout = ( // to 0. staticGenerationStore.revalidate = 0 - if (!dynamic) { - // we can statically prefetch pages that opt into dynamic, - // but not things like headers/cookies - staticGenerationStore.staticPrefetchBailout = true - } - if (staticGenerationStore.isStaticGeneration) { const err = new DynamicServerError(message) staticGenerationStore.dynamicUsageDescription = reason diff --git a/packages/next/src/server/base-server.ts b/packages/next/src/server/base-server.ts index 2e3933245e84c..a06bc4ab55879 100644 --- a/packages/next/src/server/base-server.ts +++ b/packages/next/src/server/base-server.ts @@ -2314,30 +2314,6 @@ export default abstract class Server { { page: pathname, params: opts.params, query, renderOpts } ) } else if (isAppPageRouteModule(routeModule)) { - // TODO: Re-enable once static prefetches re-land - // if ( - // !opts.experimental.ppr && - // isPrefetchRSCRequest && - // process.env.NODE_ENV === 'production' && - // !this.minimalMode - // ) { - // try { - // const prefetchRsc = await this.getPrefetchRsc(resolvedUrlPathname) - // if (prefetchRsc) { - // res.setHeader( - // 'cache-control', - // 'private, no-cache, no-store, max-age=0, must-revalidate' - // ) - // res.setHeader('content-type', RSC_CONTENT_TYPE_HEADER) - // res.body(prefetchRsc).send() - // return null - // } - // } catch { - // // We fallback to invoking the function if prefetch data is not - // // available. - // } - // } - const module = components.routeModule as AppPageRouteModule // Due to the way we pass data by mutating `renderOpts`, we can't extend the diff --git a/test/e2e/app-dir/app-prefetch/prefetching.test.ts b/test/e2e/app-dir/app-prefetch/prefetching.test.ts index 63fb9d55cdd81..b6143f9bfd16e 100644 --- a/test/e2e/app-dir/app-prefetch/prefetching.test.ts +++ b/test/e2e/app-dir/app-prefetch/prefetching.test.ts @@ -302,24 +302,6 @@ createNextDescribe( }) describe('dynamic rendering', () => { - async function hasStaticPrefetch(filePath: string): Promise { - try { - await next.readFile(`.next/server/app${filePath}`) - return true - } catch { - return false - } - } - it('should not generate a static prefetch for layouts that use cookies/headers', async () => { - expect( - await hasStaticPrefetch('/prefetch-dynamic-usage/foo.prefetch.rsc') - ).toBe(false) - - expect( - await hasStaticPrefetch('/prefetch-dynamic-usage/bar.prefetch.rsc') - ).toBe(false) - }) - describe.each(['/force-dynamic', '/revalidate-0'])('%s', (basePath) => { it('should not re-render layout when navigating between sub-pages', async () => { const logStartIndex = next.cliOutput.length diff --git a/test/e2e/app-dir/app-static/app-static.test.ts b/test/e2e/app-dir/app-static/app-static.test.ts index a2efc37dee287..d5259853cf5a3 100644 --- a/test/e2e/app-dir/app-static/app-static.test.ts +++ b/test/e2e/app-dir/app-static/app-static.test.ts @@ -507,7 +507,6 @@ createNextDescribe( 'ssg-draft-mode.rsc', 'ssr-forced/page.js', 'articles/works.rsc', - // 'custom.prefetch.rsc', 'force-cache/page.js', 'ssg-draft-mode.html', 'articles/works.html', @@ -526,7 +525,6 @@ createNextDescribe( 'force-static/first.html', 'force-static/second.rsc', 'ssg-draft-mode/test.rsc', - // 'ssr-forced.prefetch.rsc', 'isr-error-handling.html', 'articles/[slug]/page.js', 'no-store/static/page.js', @@ -537,15 +535,11 @@ createNextDescribe( 'no-store/dynamic/page.js', 'blog/seb/second-post.html', 'ssg-draft-mode/test-2.rsc', - // 'response-url.prefetch.rsc', 'blog/styfle/first-post.rsc', - // 'default-cache.prefetch.rsc', 'dynamic-error/[id]/page.js', 'ssg-draft-mode/test-2.html', 'blog/styfle/first-post.html', 'blog/styfle/second-post.rsc', - // 'fetch-no-cache.prefetch.rsc', - // 'force-no-store.prefetch.rsc', 'force-static/[slug]/page.js', 'hooks/use-pathname/slug.rsc', 'hooks/use-search-params.rsc', @@ -571,12 +565,10 @@ createNextDescribe( 'react-fetch-deduping-node/page.js', 'variable-revalidate/encoding.html', 'variable-revalidate/cookie/page.js', - // 'gen-params-dynamic/one.prefetch.rsc', 'ssg-draft-mode/[[...route]]/page.js', 'variable-revalidate/post-method.rsc', 'stale-cache-serving/app-page/page.js', 'dynamic-no-gen-params/[slug]/page.js', - // 'ssr-auto/cache-no-store.prefetch.rsc', 'static-to-dynamic-error/[id]/page.js', 'variable-revalidate/encoding/page.js', 'variable-revalidate/no-store/page.js', @@ -590,7 +582,6 @@ createNextDescribe( 'variable-revalidate/revalidate-3.html', 'force-dynamic-prerender/[slug]/page.js', 'gen-params-dynamic-revalidate/one.html', - // 'react-fetch-deduping-node.prefetch.rsc', 'ssr-auto/fetch-revalidate-zero/page.js', 'variable-revalidate/authorization.html', '_not-found_client-reference-manifest.js', @@ -603,8 +594,6 @@ createNextDescribe( 'variable-revalidate/headers-instance.rsc', 'variable-revalidate/revalidate-3/page.js', 'stale-cache-serving-edge/app-page/page.js', - // 'stale-cache-serving/app-page.prefetch.rsc', - // 'force-dynamic-catch-all/slug.prefetch.rsc', 'hooks/use-search-params/force-static.html', 'hooks/use-search-params/with-suspense.rsc', 'route-handler/revalidate-360-isr/route.js', @@ -612,13 +601,11 @@ createNextDescribe( 'variable-revalidate-edge/no-store/page.js', 'variable-revalidate/authorization/page.js', 'variable-revalidate/headers-instance.html', - // 'variable-revalidate/no-store.prefetch.rsc', 'stale-cache-serving/route-handler/route.js', 'hooks/use-search-params/with-suspense.html', 'route-handler-edge/revalidate-360/route.js', 'variable-revalidate/revalidate-360-isr.rsc', 'variable-revalidate/revalidate-360/page.js', - // 'ssr-auto/fetch-revalidate-zero.prefetch.rsc', 'static-to-dynamic-error-forced/[id]/page.js', 'variable-config-revalidate/revalidate-3.rsc', 'variable-revalidate/revalidate-360-isr.html', @@ -629,7 +616,6 @@ createNextDescribe( 'variable-config-revalidate/revalidate-3.html', 'variable-revalidate-edge/post-method/page.js', 'variable-revalidate/headers-instance/page.js', - // 'variable-revalidate/status-code.prefetch.rsc', 'force-cache/page_client-reference-manifest.js', 'hooks/use-search-params/with-suspense/page.js', 'variable-revalidate-edge/revalidate-3/page.js', @@ -640,10 +626,8 @@ createNextDescribe( 'stale-cache-serving-edge/route-handler/route.js', 'blog/[author]/page_client-reference-manifest.js', 'default-cache/page_client-reference-manifest.js', - // 'force-dynamic-prerender/frameworks.prefetch.rsc', 'variable-config-revalidate/revalidate-3/page.js', 'variable-revalidate/post-method-request/page.js', - // 'variable-revalidate/revalidate-360.prefetch.rsc', 'fetch-no-cache/page_client-reference-manifest.js', 'force-dynamic-catch-all/[slug]/[[...id]]/page.js', 'force-no-store/page_client-reference-manifest.js', @@ -675,7 +659,6 @@ createNextDescribe( 'partial-gen-params-no-additional-lang/fr/second.html', 'partial-gen-params-no-additional-slug/en/second.html', 'partial-gen-params-no-additional-slug/fr/second.html', - // 'variable-revalidate/post-method-request.prefetch.rsc', 'variable-revalidate-edge/post-method-request/page.js', 'force-static/[slug]/page_client-reference-manifest.js', 'blog/[author]/[slug]/page_client-reference-manifest.js', diff --git a/test/e2e/app-dir/app/index.test.ts b/test/e2e/app-dir/app/index.test.ts index fa9bca3d9e514..bef69d621e64e 100644 --- a/test/e2e/app-dir/app/index.test.ts +++ b/test/e2e/app-dir/app/index.test.ts @@ -2,8 +2,6 @@ import { createNextDescribe } from 'e2e-utils' import { check, getRedboxHeader, hasRedbox, waitFor } from 'next-test-utils' import cheerio from 'cheerio' import stripAnsi from 'strip-ansi' -import { BrowserInterface } from 'test/lib/browsers/base' -import { Request } from 'playwright-core' createNextDescribe( 'app dir - basic', @@ -37,60 +35,6 @@ createNextDescribe( ) }) - // TODO: Re-enable once static prefetches re-land - it.skip('should use RSC prefetch data from build', async () => { - expect( - await next.readFile('.next/server/app/linking.prefetch.rsc') - ).toBeTruthy() - expect( - await next.readFile('.next/server/app/linking/about.prefetch.rsc') - ).toContain('About loading...') - expect( - await next.readFile( - '.next/server/app/dashboard/deployments/breakdown.prefetch.rsc' - ) - ).toBeTruthy() - expect( - await next - .readFile( - '.next/server/app/dashboard/deployments/[id].prefetch.rsc' - ) - .catch(() => false) - ).toBeFalsy() - - const outputStart = next.cliOutput.length - const browser: BrowserInterface = await next.browser('/') - const rscReqs = [] - - browser.on('request', (req: Request) => { - if (req.headers()['rsc']) { - rscReqs.push(req.url()) - } - }) - - await browser.eval('window.location.href = "/linking"') - - await check(async () => { - return rscReqs.length > 3 ? 'success' : JSON.stringify(rscReqs) - }, 'success') - - const trimmedOutput = next.cliOutput.substring(outputStart) - - expect(trimmedOutput).not.toContain( - 'rendering dashboard/(custom)/deployments/breakdown' - ) - expect(trimmedOutput).not.toContain( - 'rendering /dashboard/deployments/[id]' - ) - expect(trimmedOutput).not.toContain('rendering linking about page') - - await browser.elementByCss('#breakdown').click() - await check( - () => next.cliOutput.substring(outputStart), - /rendering .*breakdown/ - ) - }) - if (!process.env.NEXT_EXPERIMENTAL_COMPILE) { it('should have correct size in build output', async () => { expect(next.cliOutput).toMatch( From 06cf74a66a1d8531413f3965fabcac9dd6f7d123 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Wed, 6 Dec 2023 07:57:13 +0100 Subject: [PATCH 189/481] add module tracing for client reference and next/dynamic walking (#59306) ### What? add tracing to the module graph walking Closes PACK-2090 --- .../visit_client_reference.rs | 61 +++++++++++++------ .../src/next_dynamic/visit_dynamic.rs | 42 +++++++++---- 2 files changed, 74 insertions(+), 29 deletions(-) diff --git a/packages/next-swc/crates/next-core/src/next_client_reference/visit_client_reference.rs b/packages/next-swc/crates/next-core/src/next_client_reference/visit_client_reference.rs index e2f22bd390360..f4bf3c0a64a9f 100644 --- a/packages/next-swc/crates/next-core/src/next_client_reference/visit_client_reference.rs +++ b/packages/next-swc/crates/next-core/src/next_client_reference/visit_client_reference.rs @@ -8,7 +8,7 @@ use turbo_tasks::{ debug::ValueDebugFormat, graph::{AdjacencyMap, GraphTraversal, Visit, VisitControlFlow}, trace::TraceRawVcs, - TryJoinIterExt, Vc, + ReadRef, TryJoinIterExt, ValueToString, Vc, }; use turbopack_binding::turbopack::core::{ module::{Module, Modules}, @@ -71,11 +71,17 @@ impl ClientReferenceGraph { entries .iter() .copied() - .map(|module| VisitClientReferenceNode { - server_component: None, - ty: VisitClientReferenceNodeType::Internal(module), + .map(|module| async move { + Ok(VisitClientReferenceNode { + server_component: None, + ty: VisitClientReferenceNodeType::Internal( + module, + module.ident().to_string().await?, + ), + }) }) - .collect::>(), + .try_join() + .await?, VisitClientReference, ) .await @@ -95,11 +101,11 @@ impl ClientReferenceGraph { for node in this.graph.reverse_topological() { match &node.ty { - VisitClientReferenceNodeType::Internal(_asset) => { + VisitClientReferenceNodeType::Internal(_asset, _) => { // No-op. These nodes are only useful during graph // traversal. } - VisitClientReferenceNodeType::ClientReference(client_reference) => { + VisitClientReferenceNodeType::ClientReference(client_reference, _) => { client_reference_types.insert(*client_reference.ty()); } } @@ -117,15 +123,15 @@ impl ClientReferenceGraph { .graph .reverse_topological_from_node(&VisitClientReferenceNode { server_component: None, - ty: VisitClientReferenceNodeType::Internal(entry), + ty: VisitClientReferenceNodeType::Internal(entry, entry.ident().to_string().await?), }) { match &node.ty { - VisitClientReferenceNodeType::Internal(_asset) => { + VisitClientReferenceNodeType::Internal(_asset, _) => { // No-op. These nodes are only useful during graph // traversal. } - VisitClientReferenceNodeType::ClientReference(client_reference) => { + VisitClientReferenceNodeType::ClientReference(client_reference, _) => { entry_client_references.push(*client_reference); } } @@ -149,8 +155,8 @@ struct VisitClientReferenceNode { Clone, Eq, PartialEq, Hash, Serialize, Deserialize, Debug, ValueDebugFormat, TraceRawVcs, )] enum VisitClientReferenceNodeType { - ClientReference(ClientReference), - Internal(Vc>), + ClientReference(ClientReference, ReadRef), + Internal(Vc>, ReadRef), } impl Visit for VisitClientReference { @@ -160,8 +166,8 @@ impl Visit for VisitClientReference { fn visit(&mut self, edge: Self::Edge) -> VisitControlFlow { match edge.ty { - VisitClientReferenceNodeType::ClientReference(_) => VisitControlFlow::Skip(edge), - VisitClientReferenceNodeType::Internal(_) => VisitControlFlow::Continue(edge), + VisitClientReferenceNodeType::ClientReference(..) => VisitControlFlow::Skip(edge), + VisitClientReferenceNodeType::Internal(..) => VisitControlFlow::Continue(edge), } } @@ -171,8 +177,8 @@ impl Visit for VisitClientReference { match node.ty { // This should never occur since we always skip visiting these // nodes' edges. - VisitClientReferenceNodeType::ClientReference(_) => Ok(vec![]), - VisitClientReferenceNodeType::Internal(module) => { + VisitClientReferenceNodeType::ClientReference(..) => Ok(vec![]), + VisitClientReferenceNodeType::Internal(module, _) => { let references = module.references().await?; let referenced_modules = references @@ -202,6 +208,7 @@ impl Visit for VisitClientReference { client_reference_module, ), }, + client_reference_module.ident().to_string().await?, ), }); } @@ -219,6 +226,7 @@ impl Visit for VisitClientReference { css_client_reference_asset, ), }, + css_client_reference_asset.ident().to_string().await?, ), }); } @@ -229,13 +237,19 @@ impl Visit for VisitClientReference { { return Ok(VisitClientReferenceNode { server_component: Some(server_component_asset), - ty: VisitClientReferenceNodeType::Internal(module), + ty: VisitClientReferenceNodeType::Internal( + module, + module.ident().to_string().await?, + ), }); } Ok(VisitClientReferenceNode { server_component: node.server_component, - ty: VisitClientReferenceNodeType::Internal(module), + ty: VisitClientReferenceNodeType::Internal( + module, + module.ident().to_string().await?, + ), }) }); @@ -246,4 +260,15 @@ impl Visit for VisitClientReference { } } } + + fn span(&mut self, node: &VisitClientReferenceNode) -> tracing::Span { + match &node.ty { + VisitClientReferenceNodeType::ClientReference(_, name) => { + tracing::info_span!("client reference", name = **name) + } + VisitClientReferenceNodeType::Internal(_, name) => { + tracing::info_span!("module", name = **name) + } + } + } } diff --git a/packages/next-swc/crates/next-core/src/next_dynamic/visit_dynamic.rs b/packages/next-swc/crates/next-core/src/next_dynamic/visit_dynamic.rs index 3cdfef6f215d9..6b89f807b2664 100644 --- a/packages/next-swc/crates/next-core/src/next_dynamic/visit_dynamic.rs +++ b/packages/next-swc/crates/next-core/src/next_dynamic/visit_dynamic.rs @@ -4,7 +4,7 @@ use anyhow::Result; use tracing::Instrument; use turbo_tasks::{ graph::{AdjacencyMap, GraphTraversal, Visit, VisitControlFlow}, - TryJoinIterExt, Vc, + ReadRef, TryJoinIterExt, ValueToString, Vc, }; use turbopack_binding::turbopack::core::{ module::{Module, Modules}, @@ -28,8 +28,11 @@ impl NextDynamicEntries { .await? .iter() .copied() - .map(VisitDynamicNode::Internal) - .collect::>(), + .map(|m| async move { + Ok(VisitDynamicNode::Internal(m, m.ident().to_string().await?)) + }) + .try_join() + .await?, VisitDynamic, ) .await @@ -42,11 +45,11 @@ impl NextDynamicEntries { for node in nodes { match node { - VisitDynamicNode::Internal(_asset) => { + VisitDynamicNode::Internal(_asset, _) => { // No-op. These nodes are only useful during graph // traversal. } - VisitDynamicNode::Dynamic(dynamic_asset) => { + VisitDynamicNode::Dynamic(dynamic_asset, _) => { next_dynamics.push(dynamic_asset); } } @@ -63,8 +66,8 @@ struct VisitDynamic; #[derive(Clone, Eq, PartialEq, Hash)] enum VisitDynamicNode { - Dynamic(Vc), - Internal(Vc>), + Dynamic(Vc, ReadRef), + Internal(Vc>, ReadRef), } impl Visit for VisitDynamic { @@ -82,8 +85,8 @@ impl Visit for VisitDynamic { let node = node.clone(); async move { let module = match node { - VisitDynamicNode::Dynamic(dynamic_module) => Vc::upcast(dynamic_module), - VisitDynamicNode::Internal(module) => module, + VisitDynamicNode::Dynamic(dynamic_module, _) => Vc::upcast(dynamic_module), + VisitDynamicNode::Internal(module, _) => module, }; let references = module.references().await?; @@ -105,10 +108,16 @@ impl Visit for VisitDynamic { if let Some(next_dynamic_module) = Vc::try_resolve_downcast_type::(module).await? { - return Ok(VisitDynamicNode::Dynamic(next_dynamic_module)); + return Ok(VisitDynamicNode::Dynamic( + next_dynamic_module, + next_dynamic_module.ident().to_string().await?, + )); } - Ok(VisitDynamicNode::Internal(module)) + Ok(VisitDynamicNode::Internal( + module, + module.ident().to_string().await?, + )) }); let nodes = referenced_modules.try_join().await?; @@ -116,4 +125,15 @@ impl Visit for VisitDynamic { Ok(nodes) } } + + fn span(&mut self, node: &VisitDynamicNode) -> tracing::Span { + match node { + VisitDynamicNode::Dynamic(_, name) => { + tracing::info_span!("dynamic module", name = **name) + } + VisitDynamicNode::Internal(_, name) => { + tracing::info_span!("module", name = **name) + } + } + } } From 0082d54893893b71b4be50b1ace748015781c0dc Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Wed, 6 Dec 2023 09:23:46 +0100 Subject: [PATCH 190/481] side effects optimization (#58972) ### What? Code update for refactoring in https://github.com/vercel/turbo/pull/6590 Closes PACK-2043 --- Cargo.lock | 69 ++++++++++--------- Cargo.toml | 6 +- packages/next-swc/crates/next-api/src/app.rs | 8 +-- .../crates/next-api/src/instrumentation.rs | 28 ++++++-- .../crates/next-api/src/middleware.rs | 39 +++++++---- .../next-swc/crates/next-api/src/pages.rs | 10 +-- .../next-swc/crates/next-api/src/project.rs | 20 ++---- .../crates/next-api/src/server_actions.rs | 24 ++++--- .../crates/next-core/src/bootstrap.rs | 52 +++++++------- .../crates/next-core/src/loader_tree.rs | 29 ++++---- .../crates/next-core/src/middleware.rs | 10 +-- .../next-core/src/next_app/app_page_entry.rs | 20 +++--- .../next-core/src/next_app/app_route_entry.rs | 30 ++++---- .../next-core/src/next_app/metadata/image.rs | 16 +++-- .../next-core/src/next_client/context.rs | 3 +- .../css_client_reference_module.rs | 16 ++--- .../css_client_reference_module_type.rs | 13 ++-- ...cmascript_client_reference_proxy_module.rs | 11 +-- .../ecmascript_client_reference_transition.rs | 53 ++++++++------ .../crates/next-core/src/next_config.rs | 33 +++++---- .../src/next_dynamic/dynamic_transition.rs | 20 ++++-- .../crates/next-core/src/next_edge/entry.rs | 11 +-- .../next-core/src/next_font/google/mod.rs | 35 +++++----- .../crates/next-core/src/next_image/module.rs | 41 ++++++----- .../next-core/src/next_pages/page_entry.rs | 28 +++++--- .../next-core/src/next_server/context.rs | 8 ++- .../next-core/src/next_server/resolve.rs | 24 ++++--- .../transforms/swc_ecma_transform_plugins.rs | 9 +-- .../crates/next-core/src/page_loader.rs | 25 ++++--- packages/next/package.json | 2 +- .../react-refresh-utils/internal/helpers.ts | 21 +++++- pnpm-lock.yaml | 10 +-- 32 files changed, 426 insertions(+), 298 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 621eb73e4c0cd..6ae5ea955e73a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -322,7 +322,7 @@ dependencies = [ [[package]] name = "auto-hash-map" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231205.2#8cb1c34181948ea6e85584d05eb9f69e86e11859" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" dependencies = [ "serde", "smallvec", @@ -3549,7 +3549,7 @@ dependencies = [ [[package]] name = "node-file-trace" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231205.2#8cb1c34181948ea6e85584d05eb9f69e86e11859" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" dependencies = [ "anyhow", "serde", @@ -7678,7 +7678,7 @@ dependencies = [ [[package]] name = "turbo-tasks" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231205.2#8cb1c34181948ea6e85584d05eb9f69e86e11859" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" dependencies = [ "anyhow", "async-trait", @@ -7710,7 +7710,7 @@ dependencies = [ [[package]] name = "turbo-tasks-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231205.2#8cb1c34181948ea6e85584d05eb9f69e86e11859" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" dependencies = [ "anyhow", "cargo-lock", @@ -7722,7 +7722,7 @@ dependencies = [ [[package]] name = "turbo-tasks-bytes" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231205.2#8cb1c34181948ea6e85584d05eb9f69e86e11859" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" dependencies = [ "anyhow", "bytes", @@ -7737,7 +7737,7 @@ dependencies = [ [[package]] name = "turbo-tasks-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231205.2#8cb1c34181948ea6e85584d05eb9f69e86e11859" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" dependencies = [ "anyhow", "dotenvs", @@ -7751,7 +7751,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fetch" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231205.2#8cb1c34181948ea6e85584d05eb9f69e86e11859" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7768,7 +7768,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fs" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231205.2#8cb1c34181948ea6e85584d05eb9f69e86e11859" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" dependencies = [ "anyhow", "auto-hash-map", @@ -7799,7 +7799,7 @@ dependencies = [ [[package]] name = "turbo-tasks-hash" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231205.2#8cb1c34181948ea6e85584d05eb9f69e86e11859" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" dependencies = [ "base16", "hex", @@ -7811,7 +7811,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231205.2#8cb1c34181948ea6e85584d05eb9f69e86e11859" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" dependencies = [ "anyhow", "convert_case 0.6.0", @@ -7825,7 +7825,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros-shared" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231205.2#8cb1c34181948ea6e85584d05eb9f69e86e11859" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" dependencies = [ "proc-macro2", "quote", @@ -7835,7 +7835,7 @@ dependencies = [ [[package]] name = "turbo-tasks-malloc" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231205.2#8cb1c34181948ea6e85584d05eb9f69e86e11859" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" dependencies = [ "mimalloc", ] @@ -7843,7 +7843,7 @@ dependencies = [ [[package]] name = "turbo-tasks-memory" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231205.2#8cb1c34181948ea6e85584d05eb9f69e86e11859" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" dependencies = [ "anyhow", "auto-hash-map", @@ -7868,7 +7868,7 @@ dependencies = [ [[package]] name = "turbopack" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231205.2#8cb1c34181948ea6e85584d05eb9f69e86e11859" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" dependencies = [ "anyhow", "async-recursion", @@ -7900,7 +7900,7 @@ dependencies = [ [[package]] name = "turbopack-binding" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231205.2#8cb1c34181948ea6e85584d05eb9f69e86e11859" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" dependencies = [ "auto-hash-map", "mdxjs", @@ -7941,7 +7941,7 @@ dependencies = [ [[package]] name = "turbopack-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231205.2#8cb1c34181948ea6e85584d05eb9f69e86e11859" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7965,7 +7965,7 @@ dependencies = [ [[package]] name = "turbopack-cli-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231205.2#8cb1c34181948ea6e85584d05eb9f69e86e11859" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" dependencies = [ "anyhow", "clap 4.4.2", @@ -7983,7 +7983,7 @@ dependencies = [ [[package]] name = "turbopack-core" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231205.2#8cb1c34181948ea6e85584d05eb9f69e86e11859" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" dependencies = [ "anyhow", "async-recursion", @@ -8013,7 +8013,7 @@ dependencies = [ [[package]] name = "turbopack-css" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231205.2#8cb1c34181948ea6e85584d05eb9f69e86e11859" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" dependencies = [ "anyhow", "async-trait", @@ -8027,6 +8027,7 @@ dependencies = [ "serde", "smallvec", "swc_core", + "tracing", "turbo-tasks", "turbo-tasks-build", "turbo-tasks-fs", @@ -8039,7 +8040,7 @@ dependencies = [ [[package]] name = "turbopack-dev" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231205.2#8cb1c34181948ea6e85584d05eb9f69e86e11859" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -8063,7 +8064,7 @@ dependencies = [ [[package]] name = "turbopack-dev-server" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231205.2#8cb1c34181948ea6e85584d05eb9f69e86e11859" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" dependencies = [ "anyhow", "async-compression", @@ -8100,7 +8101,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231205.2#8cb1c34181948ea6e85584d05eb9f69e86e11859" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" dependencies = [ "anyhow", "async-trait", @@ -8134,7 +8135,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-hmr-protocol" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231205.2#8cb1c34181948ea6e85584d05eb9f69e86e11859" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" dependencies = [ "serde", "serde_json", @@ -8145,7 +8146,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-plugins" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231205.2#8cb1c34181948ea6e85584d05eb9f69e86e11859" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" dependencies = [ "anyhow", "async-trait", @@ -8168,7 +8169,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-runtime" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231205.2#8cb1c34181948ea6e85584d05eb9f69e86e11859" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" dependencies = [ "anyhow", "indoc", @@ -8185,7 +8186,7 @@ dependencies = [ [[package]] name = "turbopack-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231205.2#8cb1c34181948ea6e85584d05eb9f69e86e11859" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -8201,7 +8202,7 @@ dependencies = [ [[package]] name = "turbopack-image" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231205.2#8cb1c34181948ea6e85584d05eb9f69e86e11859" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" dependencies = [ "anyhow", "base64 0.21.4", @@ -8221,7 +8222,7 @@ dependencies = [ [[package]] name = "turbopack-json" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231205.2#8cb1c34181948ea6e85584d05eb9f69e86e11859" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" dependencies = [ "anyhow", "serde", @@ -8236,7 +8237,7 @@ dependencies = [ [[package]] name = "turbopack-mdx" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231205.2#8cb1c34181948ea6e85584d05eb9f69e86e11859" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" dependencies = [ "anyhow", "mdxjs", @@ -8251,7 +8252,7 @@ dependencies = [ [[package]] name = "turbopack-node" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231205.2#8cb1c34181948ea6e85584d05eb9f69e86e11859" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" dependencies = [ "anyhow", "async-stream", @@ -8286,7 +8287,7 @@ dependencies = [ [[package]] name = "turbopack-static" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231205.2#8cb1c34181948ea6e85584d05eb9f69e86e11859" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" dependencies = [ "anyhow", "serde", @@ -8302,7 +8303,7 @@ dependencies = [ [[package]] name = "turbopack-swc-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231205.2#8cb1c34181948ea6e85584d05eb9f69e86e11859" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" dependencies = [ "swc_core", "turbo-tasks", @@ -8313,7 +8314,7 @@ dependencies = [ [[package]] name = "turbopack-trace-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231205.2#8cb1c34181948ea6e85584d05eb9f69e86e11859" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" dependencies = [ "anyhow", "crossbeam-channel", @@ -8328,7 +8329,7 @@ dependencies = [ [[package]] name = "turbopack-wasm" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231205.2#8cb1c34181948ea6e85584d05eb9f69e86e11859" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" dependencies = [ "anyhow", "indexmap 1.9.3", diff --git a/Cargo.toml b/Cargo.toml index 51f53646dd088..6cc2e8c07e971 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,11 +43,11 @@ swc_core = { version = "0.86.81", features = [ testing = { version = "0.35.11" } # Turbo crates -turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231205.2" } +turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231206.2" } # [TODO]: need to refactor embed_directory! macro usages, as well as resolving turbo_tasks::function, macros.. -turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231205.2" } +turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231206.2" } # [TODO]: need to refactor embed_directory! macro usage in next-core -turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231205.2" } +turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231206.2" } # General Deps diff --git a/packages/next-swc/crates/next-api/src/app.rs b/packages/next-swc/crates/next-api/src/app.rs index 0baadc9a7fe75..1f4c52511d754 100644 --- a/packages/next-swc/crates/next-api/src/app.rs +++ b/packages/next-swc/crates/next-api/src/app.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use anyhow::{bail, Context, Result}; +use anyhow::{Context, Result}; use indexmap::IndexSet; use next_core::{ all_assets_from_entries, @@ -822,9 +822,9 @@ impl AppEndpoint { .edge_rsc_runtime_entries() .await? .clone_value(); - let Some(evaluatable) = Vc::try_resolve_sidecast(app_entry.rsc_entry).await? else { - bail!("Entry module must be evaluatable"); - }; + let evaluatable = Vc::try_resolve_sidecast(app_entry.rsc_entry) + .await? + .context("Entry module must be evaluatable")?; evaluatable_assets.push(evaluatable); let (loader, manifest) = create_server_actions_manifest( diff --git a/packages/next-swc/crates/next-api/src/instrumentation.rs b/packages/next-swc/crates/next-api/src/instrumentation.rs index 1871334d018c6..97df566479e71 100644 --- a/packages/next-swc/crates/next-api/src/instrumentation.rs +++ b/packages/next-swc/crates/next-api/src/instrumentation.rs @@ -17,6 +17,8 @@ use turbopack_binding::{ context::AssetContext, module::Module, output::{OutputAsset, OutputAssets}, + reference_type::{EntryReferenceSubType, ReferenceType}, + source::Source, virtual_output::VirtualOutputAsset, }, ecmascript::chunk::EcmascriptChunkPlaceable, @@ -34,7 +36,7 @@ use crate::{ pub struct InstrumentationEndpoint { project: Vc, context: Vc>, - userland_module: Vc>, + source: Vc>, is_edge: bool, } @@ -44,13 +46,13 @@ impl InstrumentationEndpoint { pub fn new( project: Vc, context: Vc>, - userland_module: Vc>, + source: Vc>, is_edge: bool, ) -> Vc { Self { project, context, - userland_module, + source, is_edge, } .cell() @@ -58,10 +60,18 @@ impl InstrumentationEndpoint { #[turbo_tasks::function] async fn edge_files(&self) -> Result> { + let userland_module = self + .context + .process( + self.source, + Value::new(ReferenceType::Entry(EntryReferenceSubType::Instrumentation)), + ) + .module(); + let module = wrap_edge_entry( self.context, self.project.project_path(), - self.userland_module, + userland_module, "instrumentation".to_string(), ); @@ -102,7 +112,15 @@ impl InstrumentationEndpoint { self.project.server_compile_time_info().environment(), ); - let Some(module) = Vc::try_resolve_downcast(self.userland_module).await? else { + let userland_module = self + .context + .process( + self.source, + Value::new(ReferenceType::Entry(EntryReferenceSubType::Instrumentation)), + ) + .module(); + + let Some(module) = Vc::try_resolve_downcast(userland_module).await? else { bail!("Entry module must be evaluatable"); }; diff --git a/packages/next-swc/crates/next-api/src/middleware.rs b/packages/next-swc/crates/next-api/src/middleware.rs index a87b9d4a4205b..8472b4876f5b3 100644 --- a/packages/next-swc/crates/next-api/src/middleware.rs +++ b/packages/next-swc/crates/next-api/src/middleware.rs @@ -21,6 +21,8 @@ use turbopack_binding::{ context::AssetContext, module::Module, output::{OutputAsset, OutputAssets}, + reference_type::{EntryReferenceSubType, ReferenceType}, + source::Source, virtual_output::VirtualOutputAsset, }, ecmascript::chunk::EcmascriptChunkPlaceable, @@ -37,7 +39,7 @@ use crate::{ pub struct MiddlewareEndpoint { project: Vc, context: Vc>, - userland_module: Vc>, + source: Vc>, } #[turbo_tasks::value_impl] @@ -46,23 +48,28 @@ impl MiddlewareEndpoint { pub fn new( project: Vc, context: Vc>, - userland_module: Vc>, + source: Vc>, ) -> Vc { Self { project, context, - userland_module, + source, } .cell() } #[turbo_tasks::function] async fn edge_files(&self) -> Result> { - let module = get_middleware_module( - self.context, - self.project.project_path(), - self.userland_module, - ); + let userland_module = self + .context + .process( + self.source, + Value::new(ReferenceType::Entry(EntryReferenceSubType::Middleware)), + ) + .module(); + + let module = + get_middleware_module(self.context, self.project.project_path(), userland_module); let module = wrap_edge_entry( self.context, @@ -85,9 +92,9 @@ impl MiddlewareEndpoint { bail!("Entry module must be evaluatable"); }; - let Some(evaluatable) = Vc::try_resolve_sidecast(module).await? else { - bail!("Entry module must be evaluatable"); - }; + let evaluatable = Vc::try_resolve_sidecast(module) + .await? + .context("Entry module must be evaluatable")?; evaluatable_assets.push(evaluatable); let edge_chunking_context = self.project.edge_chunking_context(); @@ -102,7 +109,15 @@ impl MiddlewareEndpoint { async fn output_assets(self: Vc) -> Result> { let this = self.await?; - let config = parse_config_from_source(this.userland_module); + let userland_module = this + .context + .process( + this.source, + Value::new(ReferenceType::Entry(EntryReferenceSubType::Middleware)), + ) + .module(); + + let config = parse_config_from_source(userland_module); let edge_files = self.edge_files(); let mut output_assets = edge_files.await?.clone_value(); diff --git a/packages/next-swc/crates/next-api/src/pages.rs b/packages/next-swc/crates/next-api/src/pages.rs index a9ddba24fb99b..84c8bfd79401d 100644 --- a/packages/next-swc/crates/next-api/src/pages.rs +++ b/packages/next-swc/crates/next-api/src/pages.rs @@ -645,7 +645,9 @@ impl PageEndpoint { async move { let this = self.await?; - let ssr_module = module_context.process(self.source(), reference_type.clone()); + let ssr_module = module_context + .process(self.source(), reference_type.clone()) + .module(); let config = parse_config_from_source(ssr_module).await?; let is_edge = matches!(config.runtime, NextRuntime::Edge); @@ -663,9 +665,9 @@ impl PageEndpoint { ); let mut evaluatable_assets = edge_runtime_entries.await?.clone_value(); - let Some(evaluatable) = Vc::try_resolve_sidecast(ssr_module).await? else { - bail!("Entry module must be evaluatable"); - }; + let evaluatable = Vc::try_resolve_sidecast(ssr_module) + .await? + .context("could not process page loader entry module")?; evaluatable_assets.push(evaluatable); let edge_files = edge_chunking_context.evaluated_chunk_group( diff --git a/packages/next-swc/crates/next-api/src/project.rs b/packages/next-swc/crates/next-api/src/project.rs index a1e42a312ab7c..a913a38f660dd 100644 --- a/packages/next-swc/crates/next-api/src/project.rs +++ b/packages/next-swc/crates/next-api/src/project.rs @@ -42,7 +42,6 @@ use turbopack_binding::{ environment::ServerAddr, file_source::FileSource, output::{OutputAsset, OutputAssets}, - reference_type::{EntryReferenceSubType, ReferenceType}, resolve::{find_context_file, FindContextFileResult}, source::Source, version::{Update, Version, VersionState, VersionedContent}, @@ -729,15 +728,13 @@ impl Project { } #[turbo_tasks::function] - fn middleware_endpoint(self: Vc, source: Vc>) -> Vc { + async fn middleware_endpoint( + self: Vc, + source: Vc>, + ) -> Result> { let context = self.middleware_context(); - let module = context.process( - source, - Value::new(ReferenceType::Entry(EntryReferenceSubType::Middleware)), - ); - - MiddlewareEndpoint::new(self, context, module) + Ok(MiddlewareEndpoint::new(self, context, source)) } #[turbo_tasks::function] @@ -775,12 +772,7 @@ impl Project { self.node_instrumentation_context() }; - let module = context.process( - source, - Value::new(ReferenceType::Entry(EntryReferenceSubType::Undefined)), - ); - - InstrumentationEndpoint::new(self, context, module, is_edge) + InstrumentationEndpoint::new(self, context, source, is_edge) } #[turbo_tasks::function] diff --git a/packages/next-swc/crates/next-api/src/server_actions.rs b/packages/next-swc/crates/next-api/src/server_actions.rs index dee4e5fd10e79..c2cb352135564 100644 --- a/packages/next-swc/crates/next-api/src/server_actions.rs +++ b/packages/next-swc/crates/next-api/src/server_actions.rs @@ -1,6 +1,6 @@ use std::{io::Write, iter::once}; -use anyhow::{bail, Result}; +use anyhow::{bail, Context, Result}; use indexmap::{map::Entry, IndexMap}; use next_core::{ next_manifests::{ActionLayer, ActionManifestWorkerEntry, ServerReferenceManifest}, @@ -57,10 +57,9 @@ pub(crate) async fn create_server_actions_manifest( let actions = get_actions(rsc_entry, server_reference_modules, asset_context); let loader = build_server_actions_loader(project_path, page_name, actions, asset_context).await?; - let Some(evaluable) = Vc::try_resolve_sidecast::>(loader).await? - else { - bail!("loader module must be evaluatable"); - }; + let evaluable = Vc::try_resolve_sidecast::>(loader) + .await? + .context("loader module must be evaluatable")?; let loader_id = loader .as_chunk_item(Vc::upcast(chunking_context)) @@ -108,10 +107,12 @@ async fn build_server_actions_loader( let file = File::from(contents.build()); let source = VirtualSource::new(output_path, AssetContent::file(file.into())); let import_map = import_map.into_iter().map(|(k, v)| (v, k)).collect(); - let module = asset_context.process( - Vc::upcast(source), - Value::new(ReferenceType::Internal(Vc::cell(import_map))), - ); + let module = asset_context + .process( + Vc::upcast(source), + Value::new(ReferenceType::Internal(Vc::cell(import_map))), + ) + .module(); let Some(placeable) = Vc::try_resolve_sidecast::>(module).await? @@ -249,7 +250,10 @@ async fn to_rsc_context( } else { ReferenceType::TypeScript(TypeScriptReferenceSubType::Undefined) }; - Ok(asset_context.process(Vc::upcast(source), Value::new(ty))) + let module = asset_context + .process(Vc::upcast(source), Value::new(ty)) + .module(); + Ok(module) } /// Our graph traversal visitor, which finds the primary modules directly diff --git a/packages/next-swc/crates/next-core/src/bootstrap.rs b/packages/next-swc/crates/next-core/src/bootstrap.rs index ed33404956ed5..d5645e2829699 100644 --- a/packages/next-swc/crates/next-core/src/bootstrap.rs +++ b/packages/next-swc/crates/next-core/src/bootstrap.rs @@ -1,4 +1,4 @@ -use anyhow::{bail, Result}; +use anyhow::{bail, Context, Result}; use indexmap::IndexMap; use turbo_tasks::{Value, ValueToString, Vc}; use turbo_tasks_fs::{File, FileSystemPath}; @@ -77,35 +77,39 @@ pub async fn bootstrap( config.insert("PAGE".to_string(), path.to_string()); config.insert("PATHNAME".to_string(), pathname); - let config_asset = context.process( - Vc::upcast(VirtualSource::new( - asset.ident().path().join("bootstrap-config.ts".to_string()), - AssetContent::file( - File::from( - config - .iter() - .map(|(k, v)| format!("export const {} = {};\n", k, StringifyJs(v))) - .collect::>() - .join(""), - ) - .into(), - ), - )), - Value::new(ReferenceType::Internal(InnerAssets::empty())), - ); + let config_asset = context + .process( + Vc::upcast(VirtualSource::new( + asset.ident().path().join("bootstrap-config.ts".to_string()), + AssetContent::file( + File::from( + config + .iter() + .map(|(k, v)| format!("export const {} = {};\n", k, StringifyJs(v))) + .collect::>() + .join(""), + ) + .into(), + ), + )), + Value::new(ReferenceType::Internal(InnerAssets::empty())), + ) + .module(); let mut inner_assets = inner_assets.await?.clone_value(); inner_assets.insert("ENTRY".to_string(), asset); inner_assets.insert("BOOTSTRAP_CONFIG".to_string(), config_asset); - let asset = context.process( - bootstrap_asset, - Value::new(ReferenceType::Internal(Vc::cell(inner_assets))), - ); + let asset = context + .process( + bootstrap_asset, + Value::new(ReferenceType::Internal(Vc::cell(inner_assets))), + ) + .module(); - let Some(asset) = Vc::try_resolve_sidecast::>(asset).await? else { - bail!("internal module must be evaluatable"); - }; + let asset = Vc::try_resolve_sidecast::>(asset) + .await? + .context("internal module must be evaluatable")?; Ok(asset) } diff --git a/packages/next-swc/crates/next-core/src/loader_tree.rs b/packages/next-swc/crates/next-core/src/loader_tree.rs index 5c471de68ef71..50248ca51461e 100644 --- a/packages/next-swc/crates/next-core/src/loader_tree.rs +++ b/packages/next-swc/crates/next-core/src/loader_tree.rs @@ -146,9 +146,10 @@ impl LoaderTreeBuilder { EcmaScriptModulesReferenceSubType::Undefined, )); - let module = - self.server_component_transition - .process(source, self.context, reference_ty); + let module = self + .server_component_transition + .process(source, self.context, reference_ty) + .module(); self.inner_assets.insert(format!("COMPONENT_{i}"), module); } @@ -268,15 +269,16 @@ impl LoaderTreeBuilder { app_page.clone(), ); - self.inner_assets.insert( - inner_module_id, - self.context.process( + let module = self + .context + .process( source, Value::new(ReferenceType::EcmaScriptModules( EcmaScriptModulesReferenceSubType::Undefined, )), - ), - ); + ) + .module(); + self.inner_assets.insert(inner_module_id, module); let s = " "; writeln!(self.loader_tree_code, "{s}{identifier},")?; @@ -346,15 +348,16 @@ impl LoaderTreeBuilder { let inner_module_id = format!("METADATA_ALT_{i}"); self.imports .push(format!("import {identifier} from \"{inner_module_id}\";")); - self.inner_assets.insert( - inner_module_id, - self.context.process( + let module = self + .context + .process( Vc::upcast(TextContentFileSource::new(Vc::upcast(FileSource::new( alt_path, )))), Value::new(ReferenceType::Internal(InnerAssets::empty())), - ), - ); + ) + .module(); + self.inner_assets.insert(inner_module_id, module); writeln!(self.loader_tree_code, "{s} alt: {identifier},")?; } diff --git a/packages/next-swc/crates/next-core/src/middleware.rs b/packages/next-swc/crates/next-core/src/middleware.rs index 643aa2dcb2019..92ff48c07dfb8 100644 --- a/packages/next-swc/crates/next-core/src/middleware.rs +++ b/packages/next-swc/crates/next-core/src/middleware.rs @@ -47,10 +47,12 @@ pub async fn get_middleware_module( INNER.to_string() => userland_module }; - let module = context.process( - source, - Value::new(ReferenceType::Internal(Vc::cell(inner_assets))), - ); + let module = context + .process( + source, + Value::new(ReferenceType::Internal(Vc::cell(inner_assets))), + ) + .module(); Ok(module) } diff --git a/packages/next-swc/crates/next-core/src/next_app/app_page_entry.rs b/packages/next-swc/crates/next-core/src/next_app/app_page_entry.rs index 640e7a70ccb23..0ad5161f4f194 100644 --- a/packages/next-swc/crates/next-core/src/next_app/app_page_entry.rs +++ b/packages/next-swc/crates/next-core/src/next_app/app_page_entry.rs @@ -106,10 +106,12 @@ pub async fn get_app_page_entry( let file = File::from(result.build()); let source = VirtualSource::new(source.ident().path(), AssetContent::file(file.into())); - let mut rsc_entry = context.process( - Vc::upcast(source), - Value::new(ReferenceType::Internal(Vc::cell(inner_assets))), - ); + let mut rsc_entry = context + .process( + Vc::upcast(source), + Value::new(ReferenceType::Internal(Vc::cell(inner_assets))), + ) + .module(); if is_edge { rsc_entry = wrap_edge_page( @@ -190,10 +192,12 @@ async fn wrap_edge_page( INNER.to_string() => entry }; - let wrapped = context.process( - Vc::upcast(source), - Value::new(ReferenceType::Internal(Vc::cell(inner_assets))), - ); + let wrapped = context + .process( + Vc::upcast(source), + Value::new(ReferenceType::Internal(Vc::cell(inner_assets))), + ) + .module(); Ok(wrap_edge_entry( context, diff --git a/packages/next-swc/crates/next-core/src/next_app/app_route_entry.rs b/packages/next-swc/crates/next-core/src/next_app/app_route_entry.rs index dd5db449f6bc4..5cf997000e6dd 100644 --- a/packages/next-swc/crates/next-core/src/next_app/app_route_entry.rs +++ b/packages/next-swc/crates/next-core/src/next_app/app_route_entry.rs @@ -67,19 +67,23 @@ pub async fn get_app_route_entry( ) .await?; - let userland_module = context.process( - source, - Value::new(ReferenceType::Entry(EntryReferenceSubType::AppRoute)), - ); + let userland_module = context + .process( + source, + Value::new(ReferenceType::Entry(EntryReferenceSubType::AppRoute)), + ) + .module(); let inner_assets = indexmap! { INNER.to_string() => userland_module }; - let mut rsc_entry = context.process( - Vc::upcast(virtual_source), - Value::new(ReferenceType::Internal(Vc::cell(inner_assets))), - ); + let mut rsc_entry = context + .process( + Vc::upcast(virtual_source), + Value::new(ReferenceType::Internal(Vc::cell(inner_assets))), + ) + .module(); if is_edge { rsc_entry = wrap_edge_route( @@ -129,10 +133,12 @@ async fn wrap_edge_route( INNER.to_string() => entry }; - let wrapped = context.process( - Vc::upcast(source), - Value::new(ReferenceType::Internal(Vc::cell(inner_assets))), - ); + let wrapped = context + .process( + Vc::upcast(source), + Value::new(ReferenceType::Internal(Vc::cell(inner_assets))), + ) + .module(); Ok(wrap_edge_entry(context, project_root, wrapped, pathname)) } diff --git a/packages/next-swc/crates/next-core/src/next_app/metadata/image.rs b/packages/next-swc/crates/next-core/src/next_app/metadata/image.rs index 68e8a7c6677dd..888252b8623ea 100644 --- a/packages/next-swc/crates/next-core/src/next_app/metadata/image.rs +++ b/packages/next-swc/crates/next-core/src/next_app/metadata/image.rs @@ -63,13 +63,15 @@ pub async fn dynamic_image_metadata_source( }; let source = Vc::upcast(FileSource::new(path)); - let exports = &*collect_direct_exports(asset_context.process( - source, - turbo_tasks::Value::new(ReferenceType::EcmaScriptModules( - EcmaScriptModulesReferenceSubType::Undefined, - )), - )) - .await?; + let module = asset_context + .process( + source, + turbo_tasks::Value::new(ReferenceType::EcmaScriptModules( + EcmaScriptModulesReferenceSubType::Undefined, + )), + ) + .module(); + let exports = &*collect_direct_exports(module).await?; let exported_fields_excluding_default = exports .iter() .filter(|e| *e != "default") diff --git a/packages/next-swc/crates/next-core/src/next_client/context.rs b/packages/next-swc/crates/next-core/src/next_client/context.rs index fd63edfcc0ee0..43e32b2435674 100644 --- a/packages/next-swc/crates/next-core/src/next_client/context.rs +++ b/packages/next-swc/crates/next-core/src/next_client/context.rs @@ -17,7 +17,7 @@ use turbopack_binding::{ resolve::{parse::Request, pattern::Pattern}, }, dev::{react_refresh::assert_can_resolve_react_refresh, DevChunkingContext}, - ecmascript::chunk::EcmascriptChunkingContext, + ecmascript::{chunk::EcmascriptChunkingContext, TreeShakingMode}, node::execution_context::ExecutionContext, turbopack::{ condition::ContextCondition, @@ -267,6 +267,7 @@ pub async fn get_client_module_options_context( preset_env_versions: Some(env), execution_context: Some(execution_context), custom_ecma_transform_plugins, + tree_shaking_mode: Some(TreeShakingMode::ReexportsOnly), ..Default::default() }; diff --git a/packages/next-swc/crates/next-core/src/next_client_reference/css_client_reference/css_client_reference_module.rs b/packages/next-swc/crates/next-core/src/next_client_reference/css_client_reference/css_client_reference_module.rs index 8a3f6fc73cbd6..ab14d203d9bbe 100644 --- a/packages/next-swc/crates/next-core/src/next_client_reference/css_client_reference/css_client_reference_module.rs +++ b/packages/next-swc/crates/next-core/src/next_client_reference/css_client_reference/css_client_reference_module.rs @@ -1,4 +1,4 @@ -use anyhow::{bail, Result}; +use anyhow::{bail, Context, Result}; use turbo_tasks::Vc; use turbopack_binding::turbopack::{ core::{ @@ -72,10 +72,9 @@ impl ParseCss for CssClientReferenceModule { impl ProcessCss for CssClientReferenceModule { #[turbo_tasks::function] async fn get_css_with_placeholder(&self) -> Result> { - let Some(imp) = Vc::try_resolve_sidecast::>(self.client_module).await? - else { - bail!("CSS client reference client module must be CSS processable"); - }; + let imp = Vc::try_resolve_sidecast::>(self.client_module) + .await? + .context("CSS client reference client module must be CSS processable")?; Ok(imp.get_css_with_placeholder()) } @@ -85,10 +84,9 @@ impl ProcessCss for CssClientReferenceModule { &self, chunking_context: Vc>, ) -> Result> { - let Some(imp) = Vc::try_resolve_sidecast::>(self.client_module).await? - else { - bail!("CSS client reference client module must be CSS processable"); - }; + let imp = Vc::try_resolve_sidecast::>(self.client_module) + .await? + .context("CSS client reference client module must be CSS processable")?; Ok(imp.finalize_css(chunking_context)) } diff --git a/packages/next-swc/crates/next-core/src/next_client_reference/css_client_reference/css_client_reference_module_type.rs b/packages/next-swc/crates/next-core/src/next_client_reference/css_client_reference/css_client_reference_module_type.rs index cc9f4b343df0e..029fc68060560 100644 --- a/packages/next-swc/crates/next-core/src/next_client_reference/css_client_reference/css_client_reference_module_type.rs +++ b/packages/next-swc/crates/next-core/src/next_client_reference/css_client_reference/css_client_reference_module_type.rs @@ -39,11 +39,14 @@ impl CustomModuleType for CssClientReferenceModuleType { context: Vc, _part: Option>, ) -> Result>> { - let client_module = self.client_transition.process( - source, - context, - Value::new(ReferenceType::Css(CssReferenceSubType::Internal)), - ); + let client_module = self + .client_transition + .process( + source, + context, + Value::new(ReferenceType::Css(CssReferenceSubType::Internal)), + ) + .module(); let Some(client_module) = Vc::try_resolve_sidecast::>(client_module).await? diff --git a/packages/next-swc/crates/next-core/src/next_client_reference/ecmascript_client_reference/ecmascript_client_reference_proxy_module.rs b/packages/next-swc/crates/next-core/src/next_client_reference/ecmascript_client_reference/ecmascript_client_reference_proxy_module.rs index 61b52dba9874c..d9f0b8784f6ee 100644 --- a/packages/next-swc/crates/next-core/src/next_client_reference/ecmascript_client_reference/ecmascript_client_reference_proxy_module.rs +++ b/packages/next-swc/crates/next-core/src/next_client_reference/ecmascript_client_reference/ecmascript_client_reference_proxy_module.rs @@ -99,10 +99,13 @@ impl EcmascriptClientReferenceProxyModule { proxy_module_content, ); - let proxy_module = this.server_asset_context.process( - Vc::upcast(proxy_source), - Value::new(ReferenceType::Undefined), - ); + let proxy_module = this + .server_asset_context + .process( + Vc::upcast(proxy_source), + Value::new(ReferenceType::Undefined), + ) + .module(); let Some(proxy_module) = Vc::try_resolve_downcast_type::(proxy_module).await? diff --git a/packages/next-swc/crates/next-core/src/next_client_reference/ecmascript_client_reference/ecmascript_client_reference_transition.rs b/packages/next-swc/crates/next-core/src/next_client_reference/ecmascript_client_reference/ecmascript_client_reference_transition.rs index 32a72b0fb609f..c2c38ffa5e209 100644 --- a/packages/next-swc/crates/next-core/src/next_client_reference/ecmascript_client_reference/ecmascript_client_reference_transition.rs +++ b/packages/next-swc/crates/next-core/src/next_client_reference/ecmascript_client_reference/ecmascript_client_reference_transition.rs @@ -2,8 +2,8 @@ use anyhow::{bail, Result}; use turbo_tasks::{Value, Vc}; use turbopack_binding::turbopack::{ core::{ + context::ProcessResult, file_source::FileSource, - module::Module, reference_type::{EntryReferenceSubType, ReferenceType}, source::Source, }, @@ -50,7 +50,7 @@ impl Transition for NextEcmascriptClientReferenceTransition { source: Vc>, context: Vc, _reference_type: Value, - ) -> Result>> { + ) -> Result> { let context = self.process_context(context); let this = self.await?; @@ -66,21 +66,27 @@ impl Transition for NextEcmascriptClientReferenceTransition { } else { source }; - let client_module = this.client_transition.process( - client_source, - context, - Value::new(ReferenceType::Entry( - EntryReferenceSubType::AppClientComponent, - )), - ); + let client_module = this + .client_transition + .process( + client_source, + context, + Value::new(ReferenceType::Entry( + EntryReferenceSubType::AppClientComponent, + )), + ) + .module(); - let ssr_module = this.ssr_transition.process( - source, - context, - Value::new(ReferenceType::Entry( - EntryReferenceSubType::AppClientComponent, - )), - ); + let ssr_module = this + .ssr_transition + .process( + source, + context, + Value::new(ReferenceType::Entry( + EntryReferenceSubType::AppClientComponent, + )), + ) + .module(); let Some(client_module) = Vc::try_resolve_sidecast::>(client_module).await? @@ -105,11 +111,14 @@ impl Transition for NextEcmascriptClientReferenceTransition { context.layer, ); - Ok(Vc::upcast(EcmascriptClientReferenceProxyModule::new( - source.ident(), - Vc::upcast(server_context), - client_module, - ssr_module, - ))) + Ok( + ProcessResult::Module(Vc::upcast(EcmascriptClientReferenceProxyModule::new( + source.ident(), + Vc::upcast(server_context), + client_module, + ssr_module, + ))) + .cell(), + ) } } diff --git a/packages/next-swc/crates/next-core/src/next_config.rs b/packages/next-swc/crates/next-core/src/next_config.rs index 9c012d17bb6ef..63a202b74af25 100644 --- a/packages/next-swc/crates/next-core/src/next_config.rs +++ b/packages/next-swc/crates/next-core/src/next_config.rs @@ -9,7 +9,7 @@ use turbopack_binding::{ turbopack::{ core::{ changed::any_content_changed_of_module, - context::AssetContext, + context::{AssetContext, ProcessResult}, file_source::FileSource, ident::AssetIdent, issue::{ @@ -849,19 +849,28 @@ async fn load_next_config_and_custom_routes_internal( ); let config_asset = config_file.map(FileSource::new); - let config_changed = config_asset.map_or_else(Completion::immutable, |config_asset| { + let config_changed = if let Some(config_asset) = config_asset { // This invalidates the execution when anything referenced by the config file // changes - let config_asset = context.process( - Vc::upcast(config_asset), - Value::new(ReferenceType::Internal(InnerAssets::empty())), - ); - any_content_changed_of_module(config_asset) - }); - let load_next_config_asset = context.process( - next_asset("entry/config/next.js".to_string()), - Value::new(ReferenceType::Entry(EntryReferenceSubType::Undefined)), - ); + match *context + .process( + Vc::upcast(config_asset), + Value::new(ReferenceType::Internal(InnerAssets::empty())), + ) + .await? + { + ProcessResult::Module(module) => any_content_changed_of_module(module), + ProcessResult::Ignore => Completion::immutable(), + } + } else { + Completion::immutable() + }; + let load_next_config_asset = context + .process( + next_asset("entry/config/next.js".to_string()), + Value::new(ReferenceType::Entry(EntryReferenceSubType::Undefined)), + ) + .module(); let config_value = evaluate( load_next_config_asset, project_path, diff --git a/packages/next-swc/crates/next-core/src/next_dynamic/dynamic_transition.rs b/packages/next-swc/crates/next-core/src/next_dynamic/dynamic_transition.rs index 3f82dfe025375..6ff27e070812b 100644 --- a/packages/next-swc/crates/next-core/src/next_dynamic/dynamic_transition.rs +++ b/packages/next-swc/crates/next-core/src/next_dynamic/dynamic_transition.rs @@ -1,7 +1,7 @@ use anyhow::Result; use turbo_tasks::{Value, Vc}; use turbopack_binding::turbopack::{ - core::{module::Module, reference_type::ReferenceType, source::Source}, + core::{context::ProcessResult, reference_type::ReferenceType, source::Source}, turbopack::{ transition::{ContextTransition, Transition}, ModuleAssetContext, @@ -39,15 +39,21 @@ impl Transition for NextDynamicTransition { source: Vc>, context: Vc, _reference_type: Value, - ) -> Result>> { + ) -> Result> { let context = self.process_context(context); let this = self.await?; - let client_module = - this.client_transition - .process(source, context, Value::new(ReferenceType::Undefined)); - - Ok(Vc::upcast(NextDynamicEntryModule::new(client_module))) + Ok(match *this + .client_transition + .process(source, context, Value::new(ReferenceType::Undefined)) + .await? + { + ProcessResult::Module(client_module) => { + ProcessResult::Module(Vc::upcast(NextDynamicEntryModule::new(client_module))) + } + ProcessResult::Ignore => ProcessResult::Ignore, + } + .cell()) } } diff --git a/packages/next-swc/crates/next-core/src/next_edge/entry.rs b/packages/next-swc/crates/next-core/src/next_edge/entry.rs index 62b0833d0fc52..87adebc2bcfdf 100644 --- a/packages/next-swc/crates/next-core/src/next_edge/entry.rs +++ b/packages/next-swc/crates/next-core/src/next_edge/entry.rs @@ -39,8 +39,11 @@ pub async fn wrap_edge_entry( "MODULE".to_string() => entry }; - Ok(context.process( - Vc::upcast(virtual_source), - Value::new(ReferenceType::Internal(Vc::cell(inner_assets))), - )) + let module = context + .process( + Vc::upcast(virtual_source), + Value::new(ReferenceType::Internal(Vc::cell(inner_assets))), + ) + .module(); + Ok(module) } diff --git a/packages/next-swc/crates/next-core/src/next_font/google/mod.rs b/packages/next-swc/crates/next-core/src/next_font/google/mod.rs index 094833ceca549..ece90cfc8fc1d 100644 --- a/packages/next-swc/crates/next-core/src/next_font/google/mod.rs +++ b/packages/next-swc/crates/next-core/src/next_font/google/mod.rs @@ -446,22 +446,25 @@ async fn get_mock_stylesheet( let context = node_evaluate_asset_context(execution_context, None, None, "next_font".to_string()); let loader_path = mock_fs.root().join("loader.js".to_string()); - let mocked_response_asset = context.process( - Vc::upcast(VirtualSource::new( - loader_path, - AssetContent::file( - File::from(format!( - "import data from './{}'; export default function load() {{ return data; }};", - response_path - .file_name() - .context("Must exist")? - .to_string_lossy(), - )) - .into(), - ), - )), - Value::new(ReferenceType::Internal(InnerAssets::empty())), - ); + let mocked_response_asset = context + .process( + Vc::upcast(VirtualSource::new( + loader_path, + AssetContent::file( + File::from(format!( + "import data from './{}'; export default function load() {{ return data; \ + }};", + response_path + .file_name() + .context("Must exist")? + .to_string_lossy(), + )) + .into(), + ), + )), + Value::new(ReferenceType::Internal(InnerAssets::empty())), + ) + .module(); let root = mock_fs.root(); let val = evaluate( diff --git a/packages/next-swc/crates/next-core/src/next_image/module.rs b/packages/next-swc/crates/next-core/src/next_image/module.rs index 72369f3cec3df..459c6517cc6aa 100644 --- a/packages/next-swc/crates/next-core/src/next_image/module.rs +++ b/packages/next-swc/crates/next-core/src/next_image/module.rs @@ -1,5 +1,6 @@ +use anyhow::Result; use indexmap::indexmap; -use turbo_tasks::Vc; +use turbo_tasks::{TaskInput, Vc}; use turbopack_binding::{ turbo::tasks::Value, turbopack::{ @@ -15,7 +16,7 @@ use turbopack_binding::{ use super::source_asset::StructuredImageFileSource; #[turbo_tasks::value(serialization = "auto_for_input")] -#[derive(Clone, Copy, Debug, PartialOrd, Ord, Hash)] +#[derive(Clone, Copy, Debug, PartialOrd, Ord, Hash, TaskInput)] pub enum BlurPlaceholderMode { /// Do not generate a blur placeholder at all. None, @@ -37,30 +38,32 @@ pub struct StructuredImageModuleType { pub blur_placeholder_mode: BlurPlaceholderMode, } +#[turbo_tasks::value_impl] impl StructuredImageModuleType { - pub(crate) fn create_module( + #[turbo_tasks::function] + pub(crate) async fn create_module( source: Vc>, blur_placeholder_mode: BlurPlaceholderMode, context: Vc, - ) -> Vc> { + ) -> Result>> { let static_asset = StaticModuleAsset::new(source, Vc::upcast(context)); - context.process( - Vc::upcast( - StructuredImageFileSource { - image: source, - blur_placeholder_mode, - } - .cell(), - ), - Value::new(ReferenceType::Internal(Vc::cell(indexmap!( - "IMAGE".to_string() => Vc::upcast(static_asset) - )))), - ) + let module = context + .process( + Vc::upcast( + StructuredImageFileSource { + image: source, + blur_placeholder_mode, + } + .cell(), + ), + Value::new(ReferenceType::Internal(Vc::cell(indexmap!( + "IMAGE".to_string() => Vc::upcast(static_asset) + )))), + ) + .module(); + Ok(module) } -} -#[turbo_tasks::value_impl] -impl StructuredImageModuleType { #[turbo_tasks::function] pub fn new(blur_placeholder_mode: Value) -> Vc { StructuredImageModuleType::cell(StructuredImageModuleType { diff --git a/packages/next-swc/crates/next-core/src/next_pages/page_entry.rs b/packages/next-swc/crates/next-core/src/next_pages/page_entry.rs index be587ac651108..ef20616bcc540 100644 --- a/packages/next-swc/crates/next-core/src/next_pages/page_entry.rs +++ b/packages/next-swc/crates/next-core/src/next_pages/page_entry.rs @@ -43,7 +43,9 @@ pub async fn create_page_ssr_entry_module( let definition_page = &*next_original_name.await?; let definition_pathname = &*pathname.await?; - let ssr_module = ssr_module_context.process(source, reference_type.clone()); + let ssr_module = ssr_module_context + .process(source, reference_type.clone()) + .module(); let reference_type = reference_type.into_value(); @@ -116,12 +118,14 @@ pub async fn create_page_ssr_entry_module( )); } - let mut ssr_module = ssr_module_context.process( - source, - Value::new(ReferenceType::Internal(Vc::cell(indexmap! { - INNER.to_string() => ssr_module, - }))), - ); + let mut ssr_module = ssr_module_context + .process( + source, + Value::new(ReferenceType::Internal(Vc::cell(indexmap! { + INNER.to_string() => ssr_module, + }))), + ) + .module(); if matches!(runtime, NextRuntime::Edge) { if reference_type == ReferenceType::Entry(EntryReferenceSubType::Page) { @@ -209,10 +213,12 @@ async fn wrap_edge_page( INNER.to_string() => entry }; - let wrapped = context.process( - Vc::upcast(source), - Value::new(ReferenceType::Internal(Vc::cell(inner_assets))), - ); + let wrapped = context + .process( + Vc::upcast(source), + Value::new(ReferenceType::Internal(Vc::cell(inner_assets))), + ) + .module(); Ok(wrap_edge_entry( context, diff --git a/packages/next-swc/crates/next-core/src/next_server/context.rs b/packages/next-swc/crates/next-core/src/next_server/context.rs index 41efaa11ecba1..4b2f34a4827f7 100644 --- a/packages/next-swc/crates/next-core/src/next_server/context.rs +++ b/packages/next-swc/crates/next-core/src/next_server/context.rs @@ -17,7 +17,7 @@ use turbopack_binding::{ free_var_references, resolve::{parse::Request, pattern::Pattern}, }, - ecmascript::{references::esm::UrlRewriteBehavior, TransformPlugin}, + ecmascript::{references::esm::UrlRewriteBehavior, TransformPlugin, TreeShakingMode}, ecmascript_plugin::transform::directives::client::ClientDirectiveTransformer, node::execution_context::ExecutionContext, turbopack::{ @@ -389,6 +389,7 @@ pub async fn get_server_module_options_context( execution_context: Some(execution_context), esm_url_rewrite_behavior: url_rewrite_behavior, use_lightningcss, + tree_shaking_mode: Some(TreeShakingMode::ReexportsOnly), ..Default::default() }; @@ -458,6 +459,7 @@ pub async fn get_server_module_options_context( custom_ecma_transform_plugins: base_ecma_transform_plugins, execution_context: Some(execution_context), use_lightningcss, + tree_shaking_mode: Some(TreeShakingMode::ReexportsOnly), ..Default::default() }; let foreign_code_module_options_context = ModuleOptionsContext { @@ -543,6 +545,7 @@ pub async fn get_server_module_options_context( custom_ecma_transform_plugins: base_ecma_transform_plugins, execution_context: Some(execution_context), use_lightningcss, + tree_shaking_mode: Some(TreeShakingMode::ReexportsOnly), ..Default::default() }; let foreign_code_module_options_context = ModuleOptionsContext { @@ -582,6 +585,7 @@ pub async fn get_server_module_options_context( ServerContextType::AppRoute { .. } => { let module_options_context = ModuleOptionsContext { execution_context: Some(execution_context), + tree_shaking_mode: Some(TreeShakingMode::ReexportsOnly), ..Default::default() }; let internal_module_options_context = ModuleOptionsContext { @@ -630,6 +634,7 @@ pub async fn get_server_module_options_context( let module_options_context = ModuleOptionsContext { execution_context: Some(execution_context), + tree_shaking_mode: Some(TreeShakingMode::ReexportsOnly), ..Default::default() }; let internal_module_options_context = ModuleOptionsContext { @@ -669,6 +674,7 @@ pub async fn get_server_module_options_context( pub fn get_build_module_options_context() -> Vc { ModuleOptionsContext { enable_typescript_transform: Some(Default::default()), + tree_shaking_mode: Some(TreeShakingMode::ReexportsOnly), ..Default::default() } .cell() diff --git a/packages/next-swc/crates/next-core/src/next_server/resolve.rs b/packages/next-swc/crates/next-core/src/next_server/resolve.rs index 411030c757ed1..985d8e952501e 100644 --- a/packages/next-swc/crates/next-core/src/next_server/resolve.rs +++ b/packages/next-swc/crates/next-core/src/next_server/resolve.rs @@ -187,17 +187,19 @@ impl ResolvePlugin for ExternalCjsModulesResolvePlugin { // unsupported file type, bundle it Ok(ResolveResultOption::none()) } - (FileType::CommonJs, _) => { - // mark as external - Ok(ResolveResultOption::some( - ResolveResult::primary(ResolveResultItem::OriginalReferenceExternal).cell(), - )) - } - (FileType::EcmaScriptModule, true) => { - // mark as external - Ok(ResolveResultOption::some( - ResolveResult::primary(ResolveResultItem::OriginalReferenceExternal).cell(), - )) + (FileType::CommonJs, _) | (FileType::EcmaScriptModule, true) => { + if let Some(request) = request.await?.request() { + // mark as external + Ok(ResolveResultOption::some( + ResolveResult::primary(ResolveResultItem::OriginalReferenceTypeExternal( + request, + )) + .cell(), + )) + } else { + // unsupported request, bundle it + Ok(ResolveResultOption::none()) + } } (FileType::EcmaScriptModule, false) => { // even with require() this resolves to a ESM, diff --git a/packages/next-swc/crates/next-core/src/next_shared/transforms/swc_ecma_transform_plugins.rs b/packages/next-swc/crates/next-core/src/next_shared/transforms/swc_ecma_transform_plugins.rs index 8346d11d01147..1148fcc97c326 100644 --- a/packages/next-swc/crates/next-core/src/next_shared/transforms/swc_ecma_transform_plugins.rs +++ b/packages/next-swc/crates/next-core/src/next_shared/transforms/swc_ecma_transform_plugins.rs @@ -33,7 +33,7 @@ pub async fn get_swc_ecma_transform_plugin_impl( project_path: Vc, plugin_configs: &[(String, serde_json::Value)], ) -> Result> { - use anyhow::bail; + use anyhow::{bail, Context}; use turbo_tasks::Value; use turbo_tasks_fs::FileContent; use turbopack_binding::turbopack::{ @@ -83,9 +83,10 @@ pub async fn get_swc_ecma_transform_plugin_impl( None, ) .await?; - let Some(plugin_module) = *plugin_wasm_module_resolve_result.first_module().await? else { - bail!("Expected to find module"); - }; + let plugin_module = plugin_wasm_module_resolve_result + .first_module() + .await? + .context("Expected to find module")?; let content = &*plugin_module.content().file_content().await?; diff --git a/packages/next-swc/crates/next-core/src/page_loader.rs b/packages/next-swc/crates/next-core/src/page_loader.rs index a8b2f2a907560..aa6a6221246b4 100644 --- a/packages/next-swc/crates/next-core/src/page_loader.rs +++ b/packages/next-swc/crates/next-core/src/page_loader.rs @@ -53,15 +53,22 @@ pub async fn create_page_loader_entry_module( AssetContent::file(file.into()), )); - Ok(client_context.process( - virtual_source, - Value::new(ReferenceType::Internal(Vc::cell(indexmap! { - "PAGE".to_string() => client_context.process( - entry_asset, - Value::new(ReferenceType::Entry(EntryReferenceSubType::Page)) - ), - }))), - )) + let module = client_context + .process( + entry_asset, + Value::new(ReferenceType::Entry(EntryReferenceSubType::Page)), + ) + .module(); + + let module = client_context + .process( + virtual_source, + Value::new(ReferenceType::Internal(Vc::cell(indexmap! { + "PAGE".to_string() => module, + }))), + ) + .module(); + Ok(module) } #[turbo_tasks::value(shared)] diff --git a/packages/next/package.json b/packages/next/package.json index 41d7aa76bec0b..beec68c485535 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -195,7 +195,7 @@ "@types/ws": "8.2.0", "@vercel/ncc": "0.34.0", "@vercel/nft": "0.24.4", - "@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231205.2", + "@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231206.2", "acorn": "8.5.0", "amphtml-validator": "1.0.35", "anser": "1.4.9", diff --git a/packages/react-refresh-utils/internal/helpers.ts b/packages/react-refresh-utils/internal/helpers.ts index 3b6aabc39a80b..fd26cc05994ee 100644 --- a/packages/react-refresh-utils/internal/helpers.ts +++ b/packages/react-refresh-utils/internal/helpers.ts @@ -73,7 +73,12 @@ function registerExportsForReactRefresh( if (isSafeExport(key)) { continue } - var exportValue = moduleExports[key] + try { + var exportValue = moduleExports[key] + } catch { + // This might fail due to circular dependencies + continue + } var typeID = moduleID + ' %exports% ' + key RefreshRuntime.register(exportValue, typeID) } @@ -91,7 +96,12 @@ function getRefreshBoundarySignature(moduleExports: unknown): Array { if (isSafeExport(key)) { continue } - var exportValue = moduleExports[key] + try { + var exportValue = moduleExports[key] + } catch { + // This might fail due to circular dependencies + continue + } signature.push(key) signature.push(RefreshRuntime.getFamilyByType(exportValue)) } @@ -113,7 +123,12 @@ function isReactRefreshBoundary(moduleExports: unknown): boolean { if (isSafeExport(key)) { continue } - var exportValue = moduleExports[key] + try { + var exportValue = moduleExports[key] + } catch { + // This might fail due to circular dependencies + return false + } if (!RefreshRuntime.isLikelyComponentType(exportValue)) { areAllExportsComponents = false } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 513a8290d8328..7aed958b5a1a2 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1077,8 +1077,8 @@ importers: specifier: 0.24.4 version: 0.24.4 '@vercel/turbopack-ecmascript-runtime': - specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231205.2 - version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231205.2(react-refresh@0.12.0)(webpack@5.86.0)' + specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231206.2 + version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231206.2(react-refresh@0.12.0)(webpack@5.86.0)' acorn: specifier: 8.5.0 version: 8.5.0 @@ -24647,9 +24647,9 @@ packages: /zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} - '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231205.2(react-refresh@0.12.0)(webpack@5.86.0)': - resolution: {registry: https://registry.npmjs.org/, tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231205.2} - id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231205.2' + '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231206.2(react-refresh@0.12.0)(webpack@5.86.0)': + resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231206.2} + id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231206.2' name: '@vercel/turbopack-ecmascript-runtime' version: 0.0.0 dependencies: From 50d4578791e40a0113ac134caf49478738cf2717 Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Wed, 6 Dec 2023 08:50:05 +0000 Subject: [PATCH 191/481] v14.0.4-canary.44 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 18 +++++++++--------- 18 files changed, 34 insertions(+), 34 deletions(-) diff --git a/lerna.json b/lerna.json index 5e136c52b67bb..7de42c5f25026 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.43" + "version": "14.0.4-canary.44" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index f2e42be16b65c..e298e661af4bc 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.43", + "version": "14.0.4-canary.44", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index bd56c4f074b44..aa2465e4fbe99 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.43", + "version": "14.0.4-canary.44", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.43", + "@next/eslint-plugin-next": "14.0.4-canary.44", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index a115145aab69c..9a82a04ba9954 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.43", + "version": "14.0.4-canary.44", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index ba174df65a3dd..ae2d88cd24309 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.43", + "version": "14.0.4-canary.44", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index f4b871687d792..0a328bf7873b8 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.43", + "version": "14.0.4-canary.44", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 47764b7a10c52..e8b5383efeddd 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.43", + "version": "14.0.4-canary.44", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index f7535b5c80964..1987ee70ed2e4 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.43", + "version": "14.0.4-canary.44", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 93d3330593541..b1d7c8fcbd139 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.43", + "version": "14.0.4-canary.44", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 5cca06057f3d7..da70d85fc8fdc 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.43", + "version": "14.0.4-canary.44", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index 204c4a38832b3..efea237dded56 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.43", + "version": "14.0.4-canary.44", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index 212b0ac961f37..f9e1cacbd07a9 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.43", + "version": "14.0.4-canary.44", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index 648665cdf944d..228168475b58d 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.43", + "version": "14.0.4-canary.44", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index beec68c485535..1f740eea86bdb 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.43", + "version": "14.0.4-canary.44", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.43", + "@next/env": "14.0.4-canary.44", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -147,11 +147,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.43", - "@next/polyfill-nomodule": "14.0.4-canary.43", - "@next/react-dev-overlay": "14.0.4-canary.43", - "@next/react-refresh-utils": "14.0.4-canary.43", - "@next/swc": "14.0.4-canary.43", + "@next/polyfill-module": "14.0.4-canary.44", + "@next/polyfill-nomodule": "14.0.4-canary.44", + "@next/react-dev-overlay": "14.0.4-canary.44", + "@next/react-refresh-utils": "14.0.4-canary.44", + "@next/swc": "14.0.4-canary.44", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index 94b480d735c1b..749402c5082cb 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.43", + "version": "14.0.4-canary.44", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index 5909160ebaa1d..ad336d5f5bebf 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.43", + "version": "14.0.4-canary.44", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index 1c38eb47ab223..7c30590156baa 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.43", + "version": "14.0.4-canary.44", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -25,7 +25,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.43", + "next": "14.0.4-canary.44", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7aed958b5a1a2..1ccd49d6c84cc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -741,7 +741,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.43 + specifier: 14.0.4-canary.44 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -806,7 +806,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.43 + specifier: 14.0.4-canary.44 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -933,19 +933,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.43 + specifier: 14.0.4-canary.44 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.43 + specifier: 14.0.4-canary.44 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.43 + specifier: 14.0.4-canary.44 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.43 + specifier: 14.0.4-canary.44 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.43 + specifier: 14.0.4-canary.44 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1599,7 +1599,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.43 + specifier: 14.0.4-canary.44 version: link:../next outdent: specifier: 0.8.0 @@ -24648,7 +24648,7 @@ packages: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231206.2(react-refresh@0.12.0)(webpack@5.86.0)': - resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231206.2} + resolution: {registry: https://registry.npmjs.org/, tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231206.2} id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231206.2' name: '@vercel/turbopack-ecmascript-runtime' version: 0.0.0 From 4f67cbfe4a26436cf2f82e31c8de24b6ff031090 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Wed, 6 Dec 2023 12:07:33 +0100 Subject: [PATCH 192/481] Move App Router client-side constants to separate file (#59239) ## What? Noticed constants.js was included in the client-side bundle. This ensures only the needed constants are included. ## How? Created a separate file for client-side constants. Closes NEXT-1789 --- packages/next/src/build/index.ts | 2 +- packages/next/src/client/components/app-router-headers.ts | 2 ++ packages/next/src/client/components/redirect-status-code.ts | 5 +++++ packages/next/src/client/components/redirect.ts | 2 +- .../components/router-reducer/fetch-server-response.ts | 2 +- packages/next/src/lib/constants.ts | 2 -- packages/next/src/lib/redirect-status.ts | 2 +- .../src/server/app-render/make-get-server-inserted-html.tsx | 2 +- packages/next/src/server/base-http/index.ts | 2 +- packages/next/src/server/base-server.ts | 4 ++-- packages/next/src/server/lib/router-server.ts | 2 +- packages/next/src/shared/lib/constants.ts | 6 ------ 12 files changed, 16 insertions(+), 17 deletions(-) create mode 100644 packages/next/src/client/components/redirect-status-code.ts diff --git a/packages/next/src/build/index.ts b/packages/next/src/build/index.ts index 23a2a852acf69..a8e3a0b821dfe 100644 --- a/packages/next/src/build/index.ts +++ b/packages/next/src/build/index.ts @@ -28,7 +28,6 @@ import { MIDDLEWARE_FILENAME, PAGES_DIR_ALIAS, INSTRUMENTATION_HOOK_FILENAME, - NEXT_DID_POSTPONE_HEADER, RSC_PREFETCH_SUFFIX, RSC_SUFFIX, } from '../lib/constants' @@ -142,6 +141,7 @@ import { RSC_HEADER, RSC_CONTENT_TYPE_HEADER, RSC_VARY_HEADER, + NEXT_DID_POSTPONE_HEADER, } from '../client/components/app-router-headers' import { webpackBuild } from './webpack-build' import { NextBuildContext } from './build-context' diff --git a/packages/next/src/client/components/app-router-headers.ts b/packages/next/src/client/components/app-router-headers.ts index 9bf9c9685347c..41bb97d1afd89 100644 --- a/packages/next/src/client/components/app-router-headers.ts +++ b/packages/next/src/client/components/app-router-headers.ts @@ -15,3 +15,5 @@ export const FLIGHT_PARAMETERS = [ ] as const export const NEXT_RSC_UNION_QUERY = '_rsc' as const + +export const NEXT_DID_POSTPONE_HEADER = 'x-nextjs-postponed' as const diff --git a/packages/next/src/client/components/redirect-status-code.ts b/packages/next/src/client/components/redirect-status-code.ts new file mode 100644 index 0000000000000..2312fcdcd7f44 --- /dev/null +++ b/packages/next/src/client/components/redirect-status-code.ts @@ -0,0 +1,5 @@ +export enum RedirectStatusCode { + SeeOther = 303, + TemporaryRedirect = 307, + PermanentRedirect = 308, +} diff --git a/packages/next/src/client/components/redirect.ts b/packages/next/src/client/components/redirect.ts index 28ad8f0fafad8..d349ee438f507 100644 --- a/packages/next/src/client/components/redirect.ts +++ b/packages/next/src/client/components/redirect.ts @@ -1,7 +1,7 @@ import { requestAsyncStorage } from './request-async-storage.external' import type { ResponseCookies } from '../../server/web/spec-extension/cookies' import { actionAsyncStorage } from './action-async-storage.external' -import { RedirectStatusCode } from '../../shared/lib/constants' +import { RedirectStatusCode } from './redirect-status-code' const REDIRECT_ERROR_CODE = 'NEXT_REDIRECT' diff --git a/packages/next/src/client/components/router-reducer/fetch-server-response.ts b/packages/next/src/client/components/router-reducer/fetch-server-response.ts index e6a7a2b87775b..b6cb4d43bb4fb 100644 --- a/packages/next/src/client/components/router-reducer/fetch-server-response.ts +++ b/packages/next/src/client/components/router-reducer/fetch-server-response.ts @@ -23,12 +23,12 @@ import { NEXT_URL, RSC_HEADER, RSC_CONTENT_TYPE_HEADER, + NEXT_DID_POSTPONE_HEADER, } from '../app-router-headers' import { urlToUrlWithoutFlightMarker } from '../app-router' import { callServer } from '../../app-call-server' import { PrefetchKind } from './router-reducer-types' import { hexHash } from '../../../shared/lib/hash' -import { NEXT_DID_POSTPONE_HEADER } from '../../../lib/constants' export type FetchServerResponseResult = [ flightData: FlightData, diff --git a/packages/next/src/lib/constants.ts b/packages/next/src/lib/constants.ts index 10e1793f5d952..707b970a7b3e8 100644 --- a/packages/next/src/lib/constants.ts +++ b/packages/next/src/lib/constants.ts @@ -6,8 +6,6 @@ export const PRERENDER_REVALIDATE_HEADER = 'x-prerender-revalidate' export const PRERENDER_REVALIDATE_ONLY_GENERATED_HEADER = 'x-prerender-revalidate-if-generated' -export const NEXT_DID_POSTPONE_HEADER = 'x-nextjs-postponed' - export const RSC_PREFETCH_SUFFIX = '.prefetch.rsc' export const RSC_SUFFIX = '.rsc' export const NEXT_DATA_SUFFIX = '.json' diff --git a/packages/next/src/lib/redirect-status.ts b/packages/next/src/lib/redirect-status.ts index d4fd5740edfd2..95a18b00ee584 100644 --- a/packages/next/src/lib/redirect-status.ts +++ b/packages/next/src/lib/redirect-status.ts @@ -1,4 +1,4 @@ -import { RedirectStatusCode } from '../shared/lib/constants' +import { RedirectStatusCode } from '../client/components/redirect-status-code' export const allowedStatusCodes = new Set([301, 302, 303, 307, 308]) diff --git a/packages/next/src/server/app-render/make-get-server-inserted-html.tsx b/packages/next/src/server/app-render/make-get-server-inserted-html.tsx index 11c8e7ec46298..64b8a55cd4720 100644 --- a/packages/next/src/server/app-render/make-get-server-inserted-html.tsx +++ b/packages/next/src/server/app-render/make-get-server-inserted-html.tsx @@ -7,7 +7,7 @@ import { } from '../../client/components/redirect' import { renderToReadableStream } from 'react-dom/server.edge' import { streamToString } from '../stream-utils/node-web-streams-helper' -import { RedirectStatusCode } from '../../shared/lib/constants' +import { RedirectStatusCode } from '../../client/components/redirect-status-code' export function makeGetServerInsertedHTML({ polyfills, diff --git a/packages/next/src/server/base-http/index.ts b/packages/next/src/server/base-http/index.ts index 63c5035f13384..ad3454bd67463 100644 --- a/packages/next/src/server/base-http/index.ts +++ b/packages/next/src/server/base-http/index.ts @@ -1,7 +1,7 @@ import type { IncomingHttpHeaders, OutgoingHttpHeaders } from 'http' import type { I18NConfig } from '../config-shared' -import { RedirectStatusCode } from '../../shared/lib/constants' +import { RedirectStatusCode } from '../../client/components/redirect-status-code' import type { NextApiRequestCookies } from '../api-utils' import { getCookieParser } from '../api-utils/get-cookie-parser' diff --git a/packages/next/src/server/base-server.ts b/packages/next/src/server/base-server.ts index a06bc4ab55879..aa586d8a9ab36 100644 --- a/packages/next/src/server/base-server.ts +++ b/packages/next/src/server/base-server.ts @@ -50,9 +50,9 @@ import { APP_PATHS_MANIFEST, NEXT_BUILTIN_DOCUMENT, PAGES_MANIFEST, - RedirectStatusCode, STATIC_STATUS_PAGES, } from '../shared/lib/constants' +import { RedirectStatusCode } from '../client/components/redirect-status-code' import { isDynamicRoute } from '../shared/lib/router/utils' import { checkIsOnDemandRevalidate } from './api-utils' import { setConfig } from '../shared/lib/runtime-config.external' @@ -83,6 +83,7 @@ import { RSC_VARY_HEADER, NEXT_RSC_UNION_QUERY, NEXT_ROUTER_PREFETCH_HEADER, + NEXT_DID_POSTPONE_HEADER, } from '../client/components/app-router-headers' import type { MatchOptions, @@ -107,7 +108,6 @@ import { import { CACHE_ONE_YEAR, NEXT_CACHE_TAGS_HEADER, - NEXT_DID_POSTPONE_HEADER, NEXT_QUERY_PARAM_PREFIX, } from '../lib/constants' import { normalizeLocalePath } from '../shared/lib/i18n/normalize-locale-path' diff --git a/packages/next/src/server/lib/router-server.ts b/packages/next/src/server/lib/router-server.ts index d3dbc5eeb3ee7..2163dbdf7d268 100644 --- a/packages/next/src/server/lib/router-server.ts +++ b/packages/next/src/server/lib/router-server.ts @@ -29,8 +29,8 @@ import { isPostpone } from './router-utils/is-postpone' import { PHASE_PRODUCTION_SERVER, PHASE_DEVELOPMENT_SERVER, - RedirectStatusCode, } from '../../shared/lib/constants' +import { RedirectStatusCode } from '../../client/components/redirect-status-code' import { DevBundlerService } from './dev-bundler-service' import { type Span, trace } from '../../trace' diff --git a/packages/next/src/shared/lib/constants.ts b/packages/next/src/shared/lib/constants.ts index d02e14896c7ac..a803579c59671 100644 --- a/packages/next/src/shared/lib/constants.ts +++ b/packages/next/src/shared/lib/constants.ts @@ -154,9 +154,3 @@ export const SYSTEM_ENTRYPOINTS = new Set([ CLIENT_STATIC_FILES_RUNTIME_AMP, CLIENT_STATIC_FILES_RUNTIME_MAIN_APP, ]) - -export enum RedirectStatusCode { - SeeOther = 303, - TemporaryRedirect = 307, - PermanentRedirect = 308, -} From f6ebc2be771fbe67ce2172c6e71cec24def29689 Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Wed, 6 Dec 2023 11:10:39 +0000 Subject: [PATCH 193/481] v14.0.4-canary.45 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 16 ++++++++-------- 18 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lerna.json b/lerna.json index 7de42c5f25026..755cac8639689 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.44" + "version": "14.0.4-canary.45" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index e298e661af4bc..571ee41689535 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.44", + "version": "14.0.4-canary.45", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index aa2465e4fbe99..2c18fb540d554 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.44", + "version": "14.0.4-canary.45", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.44", + "@next/eslint-plugin-next": "14.0.4-canary.45", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 9a82a04ba9954..613222dc0100d 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.44", + "version": "14.0.4-canary.45", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index ae2d88cd24309..ee7d68ba10e71 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.44", + "version": "14.0.4-canary.45", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 0a328bf7873b8..848610f7d3f92 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.44", + "version": "14.0.4-canary.45", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index e8b5383efeddd..0d1600b0e60b5 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.44", + "version": "14.0.4-canary.45", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 1987ee70ed2e4..6d37cc7afd926 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.44", + "version": "14.0.4-canary.45", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index b1d7c8fcbd139..cb154dd084af2 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.44", + "version": "14.0.4-canary.45", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index da70d85fc8fdc..1ac5536401946 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.44", + "version": "14.0.4-canary.45", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index efea237dded56..0d7a8496c2481 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.44", + "version": "14.0.4-canary.45", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index f9e1cacbd07a9..975a05a6249ce 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.44", + "version": "14.0.4-canary.45", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index 228168475b58d..048dd671f77b4 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.44", + "version": "14.0.4-canary.45", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index 1f740eea86bdb..50c07ff4af078 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.44", + "version": "14.0.4-canary.45", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.44", + "@next/env": "14.0.4-canary.45", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -147,11 +147,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.44", - "@next/polyfill-nomodule": "14.0.4-canary.44", - "@next/react-dev-overlay": "14.0.4-canary.44", - "@next/react-refresh-utils": "14.0.4-canary.44", - "@next/swc": "14.0.4-canary.44", + "@next/polyfill-module": "14.0.4-canary.45", + "@next/polyfill-nomodule": "14.0.4-canary.45", + "@next/react-dev-overlay": "14.0.4-canary.45", + "@next/react-refresh-utils": "14.0.4-canary.45", + "@next/swc": "14.0.4-canary.45", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index 749402c5082cb..3d569e5abb7d5 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.44", + "version": "14.0.4-canary.45", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index ad336d5f5bebf..71284d41a73a3 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.44", + "version": "14.0.4-canary.45", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index 7c30590156baa..a3aa45b2ddc97 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.44", + "version": "14.0.4-canary.45", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -25,7 +25,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.44", + "next": "14.0.4-canary.45", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1ccd49d6c84cc..c7914d41ce211 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -741,7 +741,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.44 + specifier: 14.0.4-canary.45 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -806,7 +806,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.44 + specifier: 14.0.4-canary.45 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -933,19 +933,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.44 + specifier: 14.0.4-canary.45 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.44 + specifier: 14.0.4-canary.45 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.44 + specifier: 14.0.4-canary.45 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.44 + specifier: 14.0.4-canary.45 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.44 + specifier: 14.0.4-canary.45 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1599,7 +1599,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.44 + specifier: 14.0.4-canary.45 version: link:../next outdent: specifier: 0.8.0 From 182a4b44f4930108e969e7232e09aea7d5b66e8a Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Wed, 6 Dec 2023 14:48:05 +0100 Subject: [PATCH 194/481] reduce function calls in walk (#59332) ### What? Reduce the number of function calls ### Why? Performance on incremental builds ### How? Closes PACK-2104 --- .../visit_client_reference.rs | 18 +++-------------- .../src/next_dynamic/visit_dynamic.rs | 20 ++++--------------- 2 files changed, 7 insertions(+), 31 deletions(-) diff --git a/packages/next-swc/crates/next-core/src/next_client_reference/visit_client_reference.rs b/packages/next-swc/crates/next-core/src/next_client_reference/visit_client_reference.rs index f4bf3c0a64a9f..5c47b1e94c719 100644 --- a/packages/next-swc/crates/next-core/src/next_client_reference/visit_client_reference.rs +++ b/packages/next-swc/crates/next-core/src/next_client_reference/visit_client_reference.rs @@ -12,7 +12,7 @@ use turbo_tasks::{ }; use turbopack_binding::turbopack::core::{ module::{Module, Modules}, - reference::ModuleReference, + reference::primary_referenced_modules, }; use super::{ @@ -179,21 +179,9 @@ impl Visit for VisitClientReference { // nodes' edges. VisitClientReferenceNodeType::ClientReference(..) => Ok(vec![]), VisitClientReferenceNodeType::Internal(module, _) => { - let references = module.references().await?; + let referenced_modules = primary_referenced_modules(module).await?; - let referenced_modules = references - .iter() - .copied() - .map(|reference| async move { - let resolve_result = reference.resolve_reference(); - let assets = resolve_result.primary_modules().await?; - Ok(assets.clone_value()) - }) - .try_join() - .await?; - let referenced_modules = referenced_modules.into_iter().flatten(); - - let referenced_modules = referenced_modules.map(|module| async move { + let referenced_modules = referenced_modules.iter().map(|module| async move { let module = module.resolve().await?; if let Some(client_reference_module) = Vc::try_resolve_downcast_type::(module) diff --git a/packages/next-swc/crates/next-core/src/next_dynamic/visit_dynamic.rs b/packages/next-swc/crates/next-core/src/next_dynamic/visit_dynamic.rs index 6b89f807b2664..486dfb4dc5f82 100644 --- a/packages/next-swc/crates/next-core/src/next_dynamic/visit_dynamic.rs +++ b/packages/next-swc/crates/next-core/src/next_dynamic/visit_dynamic.rs @@ -8,7 +8,7 @@ use turbo_tasks::{ }; use turbopack_binding::turbopack::core::{ module::{Module, Modules}, - reference::ModuleReference, + reference::primary_referenced_modules, }; use super::NextDynamicEntryModule; @@ -89,21 +89,9 @@ impl Visit for VisitDynamic { VisitDynamicNode::Internal(module, _) => module, }; - let references = module.references().await?; - - let referenced_modules = references - .iter() - .copied() - .map(|reference| async move { - let resolve_result = reference.resolve_reference(); - let assets = resolve_result.primary_modules().await?; - Ok(assets.clone_value()) - }) - .try_join() - .await?; - let referenced_modules = referenced_modules.into_iter().flatten(); - - let referenced_modules = referenced_modules.map(|module| async move { + let referenced_modules = primary_referenced_modules(module).await?; + + let referenced_modules = referenced_modules.iter().map(|module| async move { let module = module.resolve().await?; if let Some(next_dynamic_module) = Vc::try_resolve_downcast_type::(module).await? From 8db04a8332daacdabf6c4a3378613102d6e401c9 Mon Sep 17 00:00:00 2001 From: Vercel Release Bot <88769842+vercel-release-bot@users.noreply.github.com> Date: Wed, 6 Dec 2023 08:49:58 -0500 Subject: [PATCH 195/481] Update Turbopack test manifest (#59326) This auto-generated PR updates the integration test manifest used when testing Turbopack. --- test/turbopack-tests-manifest.json | 191 +++++++++++++++++------------ 1 file changed, 112 insertions(+), 79 deletions(-) diff --git a/test/turbopack-tests-manifest.json b/test/turbopack-tests-manifest.json index 5bc1830d28c67..6a152e9827840 100644 --- a/test/turbopack-tests-manifest.json +++ b/test/turbopack-tests-manifest.json @@ -338,7 +338,6 @@ "packages/next/src/client/components/router-reducer/reducers/server-patch-reducer.test.tsx": { "passed": [ "serverPatchReducer should apply server patch", - "serverPatchReducer should apply server patch (concurrent)", "serverPatchReducer should apply server patch without affecting focusAndScrollRef" ], "failed": [], @@ -828,7 +827,8 @@ "getNamedRouteRegex should handle interception markers not adjacent to dynamic path segments", "getNamedRouteRegex should handle multi-level interception markers", "getNamedRouteRegex should handle optional catch-all dynamic path segments", - "getNamedRouteRegex should handle optional dynamic path segments" + "getNamedRouteRegex should handle optional dynamic path segments", + "getNamedRouteRegex should match named routes correctly when interception markers are adjacent to dynamic segments" ], "failed": [], "pending": [], @@ -1459,8 +1459,8 @@ "optimizePackageImports app - should render the icons correctly without creating all the modules", "optimizePackageImports pages - should optimize recursive wildcard export mapping", "optimizePackageImports pages - should render the icons correctly without creating all the modules", - "optimizePackageImports should support visx", - "optimizePackageImports should support MUI" + "optimizePackageImports should support MUI", + "optimizePackageImports should support visx" ], "pending": [], "flakey": [], @@ -1604,6 +1604,7 @@ "basic next/dynamic usage, basePath: \"\" with \"document.getInitialProps\" compiler document.getInitialProps Dynamic import default behavior should render dynamic import components using a function as first parameter", "basic next/dynamic usage, basePath: \"\" with \"document.getInitialProps\" compiler document.getInitialProps Dynamic import default behavior should render even there are no physical chunk exists", "basic next/dynamic usage, basePath: \"\" with \"document.getInitialProps\" compiler document.getInitialProps Dynamic import default behavior should render the component Head content", + "basic next/dynamic usage, basePath: \"\" with \"document.getInitialProps\" compiler document.getInitialProps Dynamic import ssr:false option should import and render the ESM module correctly on client side", "basic next/dynamic usage, basePath: \"\" with \"document.getInitialProps\" compiler document.getInitialProps Dynamic import ssr:false option should not render loading on the server side", "basic next/dynamic usage, basePath: \"\" with \"document.getInitialProps\" compiler document.getInitialProps Dynamic import ssr:false option should render the component on client side", "basic next/dynamic usage, basePath: \"\" with \"document.getInitialProps\" compiler document.getInitialProps Dynamic import ssr:true option Should render the component on the server side", @@ -1616,6 +1617,7 @@ "basic next/dynamic usage, basePath: \"\" with \"swc\" compiler swc Dynamic import default behavior should render dynamic import components using a function as first parameter", "basic next/dynamic usage, basePath: \"\" with \"swc\" compiler swc Dynamic import default behavior should render even there are no physical chunk exists", "basic next/dynamic usage, basePath: \"\" with \"swc\" compiler swc Dynamic import default behavior should render the component Head content", + "basic next/dynamic usage, basePath: \"\" with \"swc\" compiler swc Dynamic import ssr:false option should import and render the ESM module correctly on client side", "basic next/dynamic usage, basePath: \"\" with \"swc\" compiler swc Dynamic import ssr:false option should not render loading on the server side", "basic next/dynamic usage, basePath: \"\" with \"swc\" compiler swc Dynamic import ssr:false option should render the component on client side", "basic next/dynamic usage, basePath: \"\" with \"swc\" compiler swc Dynamic import ssr:true option Should render the component on the server side", @@ -1628,6 +1630,7 @@ "basic next/dynamic usage, basePath: \"/docs\" with \"swc\" compiler swc Dynamic import default behavior should render dynamic import components using a function as first parameter", "basic next/dynamic usage, basePath: \"/docs\" with \"swc\" compiler swc Dynamic import default behavior should render even there are no physical chunk exists", "basic next/dynamic usage, basePath: \"/docs\" with \"swc\" compiler swc Dynamic import default behavior should render the component Head content", + "basic next/dynamic usage, basePath: \"/docs\" with \"swc\" compiler swc Dynamic import ssr:false option should import and render the ESM module correctly on client side", "basic next/dynamic usage, basePath: \"/docs\" with \"swc\" compiler swc Dynamic import ssr:false option should not render loading on the server side", "basic next/dynamic usage, basePath: \"/docs\" with \"swc\" compiler swc Dynamic import ssr:false option should render the component on client side", "basic next/dynamic usage, basePath: \"/docs\" with \"swc\" compiler swc Dynamic import ssr:true option Should render the component on the server side", @@ -1648,6 +1651,7 @@ "basic next/dynamic usage, basePath: \"\" with \"babel\" compiler babel Dynamic import default behavior should render dynamic import components using a function as first parameter", "basic next/dynamic usage, basePath: \"\" with \"babel\" compiler babel Dynamic import default behavior should render even there are no physical chunk exists", "basic next/dynamic usage, basePath: \"\" with \"babel\" compiler babel Dynamic import default behavior should render the component Head content", + "basic next/dynamic usage, basePath: \"\" with \"babel\" compiler babel Dynamic import ssr:false option should import and render the ESM module correctly on client side", "basic next/dynamic usage, basePath: \"\" with \"babel\" compiler babel Dynamic import ssr:false option should not render loading on the server side", "basic next/dynamic usage, basePath: \"\" with \"babel\" compiler babel Dynamic import ssr:false option should render the component on client side", "basic next/dynamic usage, basePath: \"\" with \"babel\" compiler babel Dynamic import ssr:true option Should render the component on the server side", @@ -2271,7 +2275,8 @@ "app-dir action handling should support notFound (javascript disabled)", "app-dir action handling should support setting cookies in route handlers with the correct overrides", "app-dir action handling should support uploading files", - "app-dir action handling should trigger a refresh for a server action that gets discarded due to a navigation" + "app-dir action handling should trigger a refresh for a server action that gets discarded due to a navigation", + "app-dir action handling should work with interception routes" ], "failed": [], "pending": [ @@ -2430,6 +2435,8 @@ }, "test/e2e/app-dir/app-external/app-external.test.ts": { "passed": [ + "app dir - external dependency mixed syntax external modules should handle mixed module in server and client components", + "app dir - external dependency mixed syntax external modules should handle mixed module with next/dynamic", "app dir - external dependency react in external esm packages should use the same react in client app", "app dir - external dependency react in external esm packages should use the same react in edge server app", "app dir - external dependency react in external esm packages should use the same react in pages", @@ -2938,6 +2945,7 @@ "app dir - basic should not serve when layout is provided but no folder index", "app dir - basic should not share edge workers", "app dir - basic should pass props from getServerSideProps in root layout", + "app dir - basic should return normalized dynamic route params for catch-all edge page", "app dir - basic should return the `vary` header from edge runtime", "app dir - basic should return the `vary` header from pages for flight requests", "app dir - basic should serve /index as separate page", @@ -3317,8 +3325,18 @@ "flakey": [], "runtimeError": false }, + "test/e2e/app-dir/interception-dynamic-segment/interception-dynamic-segment.test.ts": { + "passed": [ + "interception-dynamic-segment should work when interception route is paired with a dynamic segment" + ], + "failed": [], + "pending": [], + "flakey": [], + "runtimeError": false + }, "test/e2e/app-dir/interception-middleware-rewrite/interception-middleware-rewrite.test.ts": { "passed": [ + "interception-middleware-rewrite should continue to show the intercepted page when revisiting it", "interception-middleware-rewrite should continue to work after using browser back button and following another intercepting route", "interception-middleware-rewrite should support intercepting routes with a middleware rewrite" ], @@ -3597,20 +3615,20 @@ "test/e2e/app-dir/next-font/next-font.test.ts": { "passed": [], "failed": [ - "app app dir - next-font Dev errors should recover on font loader error", - "app app dir - next-font computed styles should have correct styles at /", - "app app dir - next-font computed styles should have correct styles at /client", - "app app dir - next-font import values should have correct values at /", - "app app dir - next-font import values should have correct values at /client", - "app app dir - next-font import values should transform code in node_modules", - "app app dir - next-font navigation should not have duplicate preload tags on navigation", - "app-old app dir - next-font Dev errors should recover on font loader error", - "app-old app dir - next-font computed styles should have correct styles at /", - "app-old app dir - next-font computed styles should have correct styles at /client", - "app-old app dir - next-font import values should have correct values at /", - "app-old app dir - next-font import values should have correct values at /client", - "app-old app dir - next-font import values should transform code in node_modules", - "app-old app dir - next-font navigation should not have duplicate preload tags on navigation" + "app dir - next/font app app dir - next-font Dev errors should recover on font loader error", + "app dir - next/font app app dir - next-font computed styles should have correct styles at /", + "app dir - next/font app app dir - next-font computed styles should have correct styles at /client", + "app dir - next/font app app dir - next-font import values should have correct values at /", + "app dir - next/font app app dir - next-font import values should have correct values at /client", + "app dir - next/font app app dir - next-font import values should transform code in node_modules", + "app dir - next/font app app dir - next-font navigation should not have duplicate preload tags on navigation", + "app dir - next/font app-old app dir - next-font Dev errors should recover on font loader error", + "app dir - next/font app-old app dir - next-font computed styles should have correct styles at /", + "app dir - next/font app-old app dir - next-font computed styles should have correct styles at /client", + "app dir - next/font app-old app dir - next-font import values should have correct values at /", + "app dir - next/font app-old app dir - next-font import values should have correct values at /client", + "app dir - next/font app-old app dir - next-font import values should transform code in node_modules", + "app dir - next/font app-old app dir - next-font navigation should not have duplicate preload tags on navigation" ], "pending": [], "flakey": [], @@ -3791,17 +3809,17 @@ "runtimeError": false }, "test/e2e/app-dir/ppr-errors/ppr-errors.test.ts": { - "passed": [ - "ppr build errors outside of a suspense boundary should fail the build for uncaught errors", - "ppr build errors outside of a suspense boundary when a postpone call was made but missing postpone data should fail the build", - "ppr build errors outside of a suspense boundary when a postpone call was made but missing postpone data should fail the build & surface any errors that were thrown by user code", - "ppr build errors when a postpone call is caught and logged it should should include a message telling why", - "ppr build errors within a suspense boundary should fail the build for uncaught prerender errors", - "ppr build errors within a suspense boundary when a postpone call was made but missing postpone data should fail the build", - "ppr build errors within a suspense boundary when a postpone call was made but missing postpone data should fail the build & surface any errors that were thrown by user code" - ], + "passed": [], "failed": [], - "pending": [], + "pending": [ + "ppr build errors production mode outside of a suspense boundary should fail the build for uncaught errors", + "ppr build errors production mode outside of a suspense boundary when a postpone call was made but missing postpone data should fail the build", + "ppr build errors production mode outside of a suspense boundary when a postpone call was made but missing postpone data should fail the build & surface any errors that were thrown by user code", + "ppr build errors production mode when a postpone call is caught and logged it should should include a message telling why", + "ppr build errors production mode within a suspense boundary should fail the build for uncaught prerender errors", + "ppr build errors production mode within a suspense boundary when a postpone call was made but missing postpone data should fail the build", + "ppr build errors production mode within a suspense boundary when a postpone call was made but missing postpone data should fail the build & surface any errors that were thrown by user code" + ], "flakey": [], "runtimeError": false }, @@ -5013,6 +5031,7 @@ "Middleware Runtime with i18n allows to access env variables", "Middleware Runtime with i18n hard-navigates when the data request failed", "Middleware Runtime with i18n passes search params with rewrites", + "Middleware Runtime with i18n refreshes the page when middleware changes ", "Middleware Runtime with i18n should accept a URL instance for fetch", "Middleware Runtime with i18n should add a rewrite header on data requests for rewrites", "Middleware Runtime with i18n should allow to abort a fetch request", @@ -5050,6 +5069,7 @@ "Middleware Runtime without i18n allows to access env variables", "Middleware Runtime without i18n hard-navigates when the data request failed", "Middleware Runtime without i18n passes search params with rewrites", + "Middleware Runtime without i18n refreshes the page when middleware changes ", "Middleware Runtime without i18n should accept a URL instance for fetch", "Middleware Runtime without i18n should add a rewrite header on data requests for rewrites", "Middleware Runtime without i18n should allow to abort a fetch request", @@ -5062,6 +5082,7 @@ "Middleware Runtime without i18n should have correct route params for chained rewrite from middleware to config rewrite", "Middleware Runtime without i18n should have correct route params for rewrite from config dynamic route", "Middleware Runtime without i18n should have correct route params for rewrite from config non-dynamic route", + "Middleware Runtime without i18n should have init header for NextResponse.redirect", "Middleware Runtime without i18n should keep non data requests in their original shape", "Middleware Runtime without i18n should normalize data requests into page requests", "Middleware Runtime without i18n should only contain middleware route in dev middleware manifest", @@ -5081,11 +5102,7 @@ "Middleware Runtime without i18n should warn when using Response.redirect with a relative URL", "Middleware Runtime without i18n should work with notFound: true correctly" ], - "failed": [ - "Middleware Runtime with i18n refreshes the page when middleware changes ", - "Middleware Runtime without i18n refreshes the page when middleware changes ", - "Middleware Runtime without i18n should have init header for NextResponse.redirect" - ], + "failed": [], "pending": [], "flakey": [], "runtimeError": false @@ -5273,9 +5290,11 @@ "test/e2e/middleware-trailing-slash/test/index.test.ts": { "passed": [ "Middleware Runtime trailing slash allows shallow linking with middleware", + "Middleware Runtime trailing slash refreshes the page when middleware changes ", "Middleware Runtime trailing slash should add a rewrite header on data requests for rewrites", "Middleware Runtime trailing slash should have correct dynamic route params for middleware rewrite to dynamic route", "Middleware Runtime trailing slash should have correct dynamic route params on client-transition to dynamic route", + "Middleware Runtime trailing slash should have correct query values for rewrite to ssg page", "Middleware Runtime trailing slash should have correct route params for chained rewrite from middleware to config rewrite", "Middleware Runtime trailing slash should have correct route params for rewrite from config dynamic route", "Middleware Runtime trailing slash should have correct route params for rewrite from config non-dynamic route", @@ -5295,10 +5314,7 @@ "Middleware Runtime trailing slash without .html extension should work when navigating", "Middleware Runtime trailing slash without .html extension should work when requesting the page directly" ], - "failed": [ - "Middleware Runtime trailing slash refreshes the page when middleware changes ", - "Middleware Runtime trailing slash should have correct query values for rewrite to ssg page" - ], + "failed": [], "pending": [], "flakey": [], "runtimeError": false @@ -5862,6 +5878,26 @@ "flakey": [], "runtimeError": false }, + "test/e2e/testmode/testmode.test.ts": { + "passed": [ + "testmode app router should handle API with fetch in edge function", + "testmode app router should handle API with fetch in serverless function", + "testmode app router should handle API with http.get in serverless function", + "testmode app router should handle RSC with fetch in edge function", + "testmode app router should handle RSC with fetch in serverless function", + "testmode app router should handle RSC with http.get in serverless function", + "testmode middleware should intercept fetchs in middleware", + "testmode page router should handle API with fetch", + "testmode page router should handle API with http.get", + "testmode page router should handle getServerSideProps with fetch", + "testmode page router should handle getServerSideProps with http.get", + "testmode rewrites should handle rewrites" + ], + "failed": [], + "pending": [], + "flakey": [], + "runtimeError": false + }, "test/e2e/third-parties/index.test.ts": { "passed": [ "@next/third-parties basic usage renders GTM", @@ -6797,11 +6833,10 @@ "runtimeError": false }, "test/integration/clean-distdir/test/index.test.js": { - "passed": [ - "Cleaning distDir disabled write should not clean up .next before build start" - ], + "passed": [], "failed": [], "pending": [ + "Cleaning distDir production mode disabled write should not clean up .next before build start", "Cleaning distDir production mode should clean up .next before build start" ], "flakey": [], @@ -6809,13 +6844,6 @@ }, "test/integration/cli/test/index.test.js": { "passed": [ - "CLI Usage build --help", - "CLI Usage build -h", - "CLI Usage build invalid directory", - "CLI Usage build should exit when SIGINT is signalled", - "CLI Usage build should exit when SIGTERM is signalled", - "CLI Usage build should not throw UnhandledPromiseRejectionWarning", - "CLI Usage build should warn when unknown argument provided", "CLI Usage dev --experimental-https", "CLI Usage dev --experimental-https with provided key/cert", "CLI Usage dev --help", @@ -6850,6 +6878,13 @@ ], "failed": [], "pending": [ + "CLI Usage production mode build --help", + "CLI Usage production mode build -h", + "CLI Usage production mode build invalid directory", + "CLI Usage production mode build should exit when SIGINT is signalled", + "CLI Usage production mode build should exit when SIGTERM is signalled", + "CLI Usage production mode build should not throw UnhandledPromiseRejectionWarning", + "CLI Usage production mode build should warn when unknown argument provided", "CLI Usage production mode start --help", "CLI Usage production mode start --keepAliveTimeout Infinity", "CLI Usage production mode start --keepAliveTimeout happy path", @@ -6932,18 +6967,19 @@ }, "test/integration/config-experimental-warning/test/index.test.js": { "passed": [ - "Config Experimental Warning should not show next app info in next start", "Config Experimental Warning should not show warning with config from object", "Config Experimental Warning should not show warning with default config from function", "Config Experimental Warning should not show warning with default value", - "Config Experimental Warning should show next app info with all experimental features in next build", - "Config Experimental Warning should show unrecognized experimental features in warning but not in start log experiments section", "Config Experimental Warning should show warning with config from function with experimental", "Config Experimental Warning should show warning with config from object with experimental", "Config Experimental Warning should show warning with config from object with experimental and multiple keys" ], "failed": [], - "pending": [], + "pending": [ + "Config Experimental Warning production mode should not show next app info in next start", + "Config Experimental Warning production mode should show next app info with all experimental features in next build", + "Config Experimental Warning production mode should show unrecognized experimental features in warning but not in start log experiments section" + ], "flakey": [], "runtimeError": false }, @@ -7340,14 +7376,14 @@ }, "test/integration/css/test/css-modules.test.js": { "passed": [ + "CSS Modules Composes Ordering Development Mode should have correct color on index page (on hover)", + "CSS Modules Composes Ordering Development Mode should have correct color on index page (on load)", "Ordering with Global CSS and Modules (dev) should not execute scripts in any order" ], "failed": [ "Basic CSS Modules Ordering Development Mode should have correct color on index page (on hover)", "Basic CSS Modules Ordering Development Mode should have correct color on index page (on load)", "Basic CSS Modules Ordering Development Mode should have correct color on index page (on nav)", - "CSS Modules Composes Ordering Development Mode should have correct color on index page (on hover)", - "CSS Modules Composes Ordering Development Mode should have correct color on index page (on load)", "Ordering with Global CSS and Modules (dev) should have the correct color (css ordering)", "Ordering with Global CSS and Modules (dev) should have the correct color (css ordering) during hot reloads" ], @@ -13410,15 +13446,14 @@ "runtimeError": false }, "test/integration/page-extensions/test/index.test.js": { - "passed": [ - "Page Extensions should throw if pageExtensions has invalid extensions", - "Page Extensions should throw if pageExtensions is an empty array" - ], - "failed": [ - "Page Extensions should not throw if .d.ts file inside the pages folder", - "Page Extensions should use the default pageExtensions if set to undefined" + "passed": [], + "failed": [], + "pending": [ + "Page Extensions production mode should not throw if .d.ts file inside the pages folder", + "Page Extensions production mode should throw if pageExtensions has invalid extensions", + "Page Extensions production mode should throw if pageExtensions is an empty array", + "Page Extensions production mode should use the default pageExtensions if set to undefined" ], - "pending": [], "flakey": [], "runtimeError": false }, @@ -13736,15 +13771,14 @@ "Basics default setting with react 18 dev should contain dynamicIds in next data for dynamic imports", "Basics default setting with react 18 dev should only render once in SSR", "Basics default setting with react 18 dev useId() values should match on hydration", + "Concurrent mode in the experimental-edge runtime dev should not have the initial route announced", "Concurrent mode in the experimental-edge runtime dev flushes styled-jsx styles as the page renders", "Concurrent mode in the experimental-edge runtime dev should not have invalid config warning", "Concurrent mode in the nodejs runtime dev should not have the initial route announced", "Concurrent mode in the nodejs runtime dev flushes styled-jsx styles as the page renders", "Concurrent mode in the nodejs runtime dev should not have invalid config warning" ], - "failed": [ - "Concurrent mode in the experimental-edge runtime dev should not have the initial route announced" - ], + "failed": [], "pending": [ "Basics production mode default setting with react 18 prod hydrates correctly for normal page", "Basics production mode default setting with react 18 prod no warnings for image related link props", @@ -14597,23 +14631,22 @@ "Telemetry CLI can print telemetry status", "Telemetry CLI can re-disable telemetry", "Telemetry CLI can re-enable telemetry", - "Telemetry CLI cli session: babel tooling config", - "Telemetry CLI cli session: custom babel config (plugin)", - "Telemetry CLI cli session: custom babel config (preset)", - "Telemetry CLI cli session: next config with webpack", - "Telemetry CLI cli session: package.json custom babel config (plugin)", - "Telemetry CLI detects correct cli session defaults", - "Telemetry CLI detects isSrcDir dir correctly for `next dev`", - "Telemetry CLI emits event when swc fails to load" - ], - "failed": [ - "Telemetry CLI detects isSrcDir dir correctly for `next build`", - "Telemetry CLI detects tests correctly for `next build`", - "Telemetry CLI logs completed `next build` with warnings" + "Telemetry CLI detects isSrcDir dir correctly for `next dev`" ], + "failed": [], "pending": [ + "Telemetry CLI production mode cli session: babel tooling config", + "Telemetry CLI production mode cli session: custom babel config (plugin)", + "Telemetry CLI production mode cli session: custom babel config (preset)", + "Telemetry CLI production mode cli session: next config with webpack", + "Telemetry CLI production mode cli session: package.json custom babel config (plugin)", "Telemetry CLI production mode detect page counts correctly for `next build`", - "Telemetry CLI production mode detect static 404 correctly for `next build`" + "Telemetry CLI production mode detect static 404 correctly for `next build`", + "Telemetry CLI production mode detects correct cli session defaults", + "Telemetry CLI production mode detects isSrcDir dir correctly for `next build`", + "Telemetry CLI production mode detects tests correctly for `next build`", + "Telemetry CLI production mode emits event when swc fails to load", + "Telemetry CLI production mode logs completed `next build` with warnings" ], "flakey": [], "runtimeError": false From 34e9d65d29dc08f35ee39dc221fd1f9104b59990 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Wed, 6 Dec 2023 17:20:52 +0100 Subject: [PATCH 196/481] update turbopack (#59334) * https://github.com/vercel/turbo/pull/6716 * https://github.com/vercel/turbo/pull/6718 --- Cargo.lock | 68 +++++++++++++++++++------------------- Cargo.toml | 6 ++-- packages/next/package.json | 2 +- pnpm-lock.yaml | 10 +++--- 4 files changed, 43 insertions(+), 43 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6ae5ea955e73a..7aaa83880d4fb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -322,7 +322,7 @@ dependencies = [ [[package]] name = "auto-hash-map" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.4#f99cd2550f9f4c2b89e173532cc72797d613b82f" dependencies = [ "serde", "smallvec", @@ -3549,7 +3549,7 @@ dependencies = [ [[package]] name = "node-file-trace" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.4#f99cd2550f9f4c2b89e173532cc72797d613b82f" dependencies = [ "anyhow", "serde", @@ -7678,7 +7678,7 @@ dependencies = [ [[package]] name = "turbo-tasks" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.4#f99cd2550f9f4c2b89e173532cc72797d613b82f" dependencies = [ "anyhow", "async-trait", @@ -7710,7 +7710,7 @@ dependencies = [ [[package]] name = "turbo-tasks-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.4#f99cd2550f9f4c2b89e173532cc72797d613b82f" dependencies = [ "anyhow", "cargo-lock", @@ -7722,7 +7722,7 @@ dependencies = [ [[package]] name = "turbo-tasks-bytes" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.4#f99cd2550f9f4c2b89e173532cc72797d613b82f" dependencies = [ "anyhow", "bytes", @@ -7737,7 +7737,7 @@ dependencies = [ [[package]] name = "turbo-tasks-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.4#f99cd2550f9f4c2b89e173532cc72797d613b82f" dependencies = [ "anyhow", "dotenvs", @@ -7751,7 +7751,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fetch" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.4#f99cd2550f9f4c2b89e173532cc72797d613b82f" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7768,7 +7768,7 @@ dependencies = [ [[package]] name = "turbo-tasks-fs" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.4#f99cd2550f9f4c2b89e173532cc72797d613b82f" dependencies = [ "anyhow", "auto-hash-map", @@ -7799,7 +7799,7 @@ dependencies = [ [[package]] name = "turbo-tasks-hash" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.4#f99cd2550f9f4c2b89e173532cc72797d613b82f" dependencies = [ "base16", "hex", @@ -7811,7 +7811,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.4#f99cd2550f9f4c2b89e173532cc72797d613b82f" dependencies = [ "anyhow", "convert_case 0.6.0", @@ -7825,7 +7825,7 @@ dependencies = [ [[package]] name = "turbo-tasks-macros-shared" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.4#f99cd2550f9f4c2b89e173532cc72797d613b82f" dependencies = [ "proc-macro2", "quote", @@ -7835,7 +7835,7 @@ dependencies = [ [[package]] name = "turbo-tasks-malloc" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.4#f99cd2550f9f4c2b89e173532cc72797d613b82f" dependencies = [ "mimalloc", ] @@ -7843,7 +7843,7 @@ dependencies = [ [[package]] name = "turbo-tasks-memory" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.4#f99cd2550f9f4c2b89e173532cc72797d613b82f" dependencies = [ "anyhow", "auto-hash-map", @@ -7868,7 +7868,7 @@ dependencies = [ [[package]] name = "turbopack" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.4#f99cd2550f9f4c2b89e173532cc72797d613b82f" dependencies = [ "anyhow", "async-recursion", @@ -7900,7 +7900,7 @@ dependencies = [ [[package]] name = "turbopack-binding" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.4#f99cd2550f9f4c2b89e173532cc72797d613b82f" dependencies = [ "auto-hash-map", "mdxjs", @@ -7941,7 +7941,7 @@ dependencies = [ [[package]] name = "turbopack-build" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.4#f99cd2550f9f4c2b89e173532cc72797d613b82f" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -7965,7 +7965,7 @@ dependencies = [ [[package]] name = "turbopack-cli-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.4#f99cd2550f9f4c2b89e173532cc72797d613b82f" dependencies = [ "anyhow", "clap 4.4.2", @@ -7983,7 +7983,7 @@ dependencies = [ [[package]] name = "turbopack-core" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.4#f99cd2550f9f4c2b89e173532cc72797d613b82f" dependencies = [ "anyhow", "async-recursion", @@ -8013,7 +8013,7 @@ dependencies = [ [[package]] name = "turbopack-css" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.4#f99cd2550f9f4c2b89e173532cc72797d613b82f" dependencies = [ "anyhow", "async-trait", @@ -8040,7 +8040,7 @@ dependencies = [ [[package]] name = "turbopack-dev" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.4#f99cd2550f9f4c2b89e173532cc72797d613b82f" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -8064,7 +8064,7 @@ dependencies = [ [[package]] name = "turbopack-dev-server" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.4#f99cd2550f9f4c2b89e173532cc72797d613b82f" dependencies = [ "anyhow", "async-compression", @@ -8101,7 +8101,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.4#f99cd2550f9f4c2b89e173532cc72797d613b82f" dependencies = [ "anyhow", "async-trait", @@ -8135,7 +8135,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-hmr-protocol" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.4#f99cd2550f9f4c2b89e173532cc72797d613b82f" dependencies = [ "serde", "serde_json", @@ -8146,7 +8146,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-plugins" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.4#f99cd2550f9f4c2b89e173532cc72797d613b82f" dependencies = [ "anyhow", "async-trait", @@ -8169,7 +8169,7 @@ dependencies = [ [[package]] name = "turbopack-ecmascript-runtime" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.4#f99cd2550f9f4c2b89e173532cc72797d613b82f" dependencies = [ "anyhow", "indoc", @@ -8186,7 +8186,7 @@ dependencies = [ [[package]] name = "turbopack-env" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.4#f99cd2550f9f4c2b89e173532cc72797d613b82f" dependencies = [ "anyhow", "indexmap 1.9.3", @@ -8202,7 +8202,7 @@ dependencies = [ [[package]] name = "turbopack-image" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.4#f99cd2550f9f4c2b89e173532cc72797d613b82f" dependencies = [ "anyhow", "base64 0.21.4", @@ -8222,7 +8222,7 @@ dependencies = [ [[package]] name = "turbopack-json" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.4#f99cd2550f9f4c2b89e173532cc72797d613b82f" dependencies = [ "anyhow", "serde", @@ -8237,7 +8237,7 @@ dependencies = [ [[package]] name = "turbopack-mdx" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.4#f99cd2550f9f4c2b89e173532cc72797d613b82f" dependencies = [ "anyhow", "mdxjs", @@ -8252,7 +8252,7 @@ dependencies = [ [[package]] name = "turbopack-node" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.4#f99cd2550f9f4c2b89e173532cc72797d613b82f" dependencies = [ "anyhow", "async-stream", @@ -8287,7 +8287,7 @@ dependencies = [ [[package]] name = "turbopack-static" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.4#f99cd2550f9f4c2b89e173532cc72797d613b82f" dependencies = [ "anyhow", "serde", @@ -8303,7 +8303,7 @@ dependencies = [ [[package]] name = "turbopack-swc-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.4#f99cd2550f9f4c2b89e173532cc72797d613b82f" dependencies = [ "swc_core", "turbo-tasks", @@ -8314,7 +8314,7 @@ dependencies = [ [[package]] name = "turbopack-trace-utils" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.4#f99cd2550f9f4c2b89e173532cc72797d613b82f" dependencies = [ "anyhow", "crossbeam-channel", @@ -8329,7 +8329,7 @@ dependencies = [ [[package]] name = "turbopack-wasm" version = "0.1.0" -source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.2#16bbf81a2a45b85737e569312b1ee76eec6c388c" +source = "git+https://github.com/vercel/turbo.git?tag=turbopack-231206.4#f99cd2550f9f4c2b89e173532cc72797d613b82f" dependencies = [ "anyhow", "indexmap 1.9.3", diff --git a/Cargo.toml b/Cargo.toml index 6cc2e8c07e971..acfb04cae500b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,11 +43,11 @@ swc_core = { version = "0.86.81", features = [ testing = { version = "0.35.11" } # Turbo crates -turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231206.2" } +turbopack-binding = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231206.4" } # [TODO]: need to refactor embed_directory! macro usages, as well as resolving turbo_tasks::function, macros.. -turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231206.2" } +turbo-tasks = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231206.4" } # [TODO]: need to refactor embed_directory! macro usage in next-core -turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231206.2" } +turbo-tasks-fs = { git = "https://github.com/vercel/turbo.git", tag = "turbopack-231206.4" } # General Deps diff --git a/packages/next/package.json b/packages/next/package.json index 50c07ff4af078..cdfad7f848dbb 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -195,7 +195,7 @@ "@types/ws": "8.2.0", "@vercel/ncc": "0.34.0", "@vercel/nft": "0.24.4", - "@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231206.2", + "@vercel/turbopack-ecmascript-runtime": "https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231206.4", "acorn": "8.5.0", "amphtml-validator": "1.0.35", "anser": "1.4.9", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c7914d41ce211..6af67e9323cb7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1077,8 +1077,8 @@ importers: specifier: 0.24.4 version: 0.24.4 '@vercel/turbopack-ecmascript-runtime': - specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231206.2 - version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231206.2(react-refresh@0.12.0)(webpack@5.86.0)' + specifier: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231206.4 + version: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231206.4(react-refresh@0.12.0)(webpack@5.86.0)' acorn: specifier: 8.5.0 version: 8.5.0 @@ -24647,9 +24647,9 @@ packages: /zwitch@2.0.4: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} - '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231206.2(react-refresh@0.12.0)(webpack@5.86.0)': - resolution: {registry: https://registry.npmjs.org/, tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231206.2} - id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231206.2' + '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231206.4(react-refresh@0.12.0)(webpack@5.86.0)': + resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231206.4} + id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231206.4' name: '@vercel/turbopack-ecmascript-runtime' version: 0.0.0 dependencies: From 99b9304bf15c630d5811285c2383a25b09fbf516 Mon Sep 17 00:00:00 2001 From: Tobias Koppers Date: Wed, 6 Dec 2023 17:34:06 +0100 Subject: [PATCH 197/481] disable unused next/dynamic walking in app dir (#59338) ### What? remove expensive unused code Closes PACK-2108 --- packages/next-swc/crates/next-api/src/app.rs | 49 ++++++++++---------- 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/packages/next-swc/crates/next-api/src/app.rs b/packages/next-swc/crates/next-api/src/app.rs index 1f4c52511d754..10a0c8f539942 100644 --- a/packages/next-swc/crates/next-api/src/app.rs +++ b/packages/next-swc/crates/next-api/src/app.rs @@ -22,7 +22,7 @@ use next_core::{ next_client_reference::{ ClientReferenceGraph, ClientReferenceType, NextEcmascriptClientReferenceTransition, }, - next_dynamic::{NextDynamicEntries, NextDynamicTransition}, + next_dynamic::NextDynamicTransition, next_edge::route_regex::get_named_middleware_regex, next_manifests::{ AppBuildManifest, AppPathsManifest, BuildManifest, ClientReferenceManifest, @@ -584,30 +584,31 @@ impl AppEndpoint { let client_reference_types = client_reference_graph.types(); let client_references = client_reference_graph.entry(rsc_entry_asset); - let app_ssr_entries: Vec<_> = client_reference_types - .await? - .iter() - .map(|client_reference_ty| async move { - let ClientReferenceType::EcmascriptClientReference(entry) = client_reference_ty - else { - return Ok(None); - }; - - Ok(Some(entry.await?.ssr_module)) - }) - .try_join() - .await? - .into_iter() - .flatten() - .collect(); - - let app_node_entries: Vec<_> = app_ssr_entries.iter().copied().chain([rsc_entry]).collect(); - // TODO(alexkirsz) Handle dynamic entries and dynamic chunks. - let _dynamic_entries = NextDynamicEntries::from_entries(Vc::cell( - app_node_entries.iter().copied().map(Vc::upcast).collect(), - )) - .await?; + // let app_ssr_entries: Vec<_> = client_reference_types + // .await? + // .iter() + // .map(|client_reference_ty| async move { + // let ClientReferenceType::EcmascriptClientReference(entry) = + // client_reference_ty else { + // return Ok(None); + // }; + + // Ok(Some(entry.await?.ssr_module)) + // }) + // .try_join() + // .await? + // .into_iter() + // .flatten() + // .collect(); + + // let app_node_entries: Vec<_> = + // app_ssr_entries.iter().copied().chain([rsc_entry]).collect(); + + // let _dynamic_entries = NextDynamicEntries::from_entries(Vc::cell( + // app_node_entries.iter().copied().map(Vc::upcast).collect(), + // )) + // .await?; let app_entry_client_references = client_reference_graph .entry(Vc::upcast(app_entry.rsc_entry)) From 1f6defd4b097fb24d1fcf75a12cb77f082ed9706 Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Wed, 6 Dec 2023 16:37:29 +0000 Subject: [PATCH 198/481] v14.0.4-canary.46 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 18 +++++++++--------- 18 files changed, 34 insertions(+), 34 deletions(-) diff --git a/lerna.json b/lerna.json index 755cac8639689..ba2666e19d14d 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.45" + "version": "14.0.4-canary.46" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 571ee41689535..e384c0242931c 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.45", + "version": "14.0.4-canary.46", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 2c18fb540d554..21110002b3edb 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.45", + "version": "14.0.4-canary.46", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.45", + "@next/eslint-plugin-next": "14.0.4-canary.46", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 613222dc0100d..ac6600bbc3345 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.45", + "version": "14.0.4-canary.46", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index ee7d68ba10e71..73dbe283d253c 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.45", + "version": "14.0.4-canary.46", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 848610f7d3f92..03aa0956b44a4 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.45", + "version": "14.0.4-canary.46", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 0d1600b0e60b5..093e26f0cc5d7 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.45", + "version": "14.0.4-canary.46", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 6d37cc7afd926..ac5d40d86655c 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.45", + "version": "14.0.4-canary.46", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index cb154dd084af2..ffb1175430b2e 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.45", + "version": "14.0.4-canary.46", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 1ac5536401946..47430fba9aa68 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.45", + "version": "14.0.4-canary.46", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index 0d7a8496c2481..e68210c6214f3 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.45", + "version": "14.0.4-canary.46", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index 975a05a6249ce..cbc0a0bae9cbe 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.45", + "version": "14.0.4-canary.46", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index 048dd671f77b4..abdbb77de5a33 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.45", + "version": "14.0.4-canary.46", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index cdfad7f848dbb..0d45846a239e0 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.45", + "version": "14.0.4-canary.46", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.45", + "@next/env": "14.0.4-canary.46", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -147,11 +147,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.45", - "@next/polyfill-nomodule": "14.0.4-canary.45", - "@next/react-dev-overlay": "14.0.4-canary.45", - "@next/react-refresh-utils": "14.0.4-canary.45", - "@next/swc": "14.0.4-canary.45", + "@next/polyfill-module": "14.0.4-canary.46", + "@next/polyfill-nomodule": "14.0.4-canary.46", + "@next/react-dev-overlay": "14.0.4-canary.46", + "@next/react-refresh-utils": "14.0.4-canary.46", + "@next/swc": "14.0.4-canary.46", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index 3d569e5abb7d5..3c77e469d6a67 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.45", + "version": "14.0.4-canary.46", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index 71284d41a73a3..d4efe7f8f84aa 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.45", + "version": "14.0.4-canary.46", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index a3aa45b2ddc97..497b226d4ff36 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.45", + "version": "14.0.4-canary.46", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -25,7 +25,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.45", + "next": "14.0.4-canary.46", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6af67e9323cb7..51dbbb3340018 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -741,7 +741,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.45 + specifier: 14.0.4-canary.46 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -806,7 +806,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.45 + specifier: 14.0.4-canary.46 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -933,19 +933,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.45 + specifier: 14.0.4-canary.46 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.45 + specifier: 14.0.4-canary.46 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.45 + specifier: 14.0.4-canary.46 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.45 + specifier: 14.0.4-canary.46 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.45 + specifier: 14.0.4-canary.46 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1599,7 +1599,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.45 + specifier: 14.0.4-canary.46 version: link:../next outdent: specifier: 0.8.0 @@ -24648,7 +24648,7 @@ packages: resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231206.4(react-refresh@0.12.0)(webpack@5.86.0)': - resolution: {tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231206.4} + resolution: {registry: https://registry.npmjs.org/, tarball: https://gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231206.4} id: '@gitpkg-fork.vercel.sh/vercel/turbo/crates/turbopack-ecmascript-runtime/js?turbopack-231206.4' name: '@vercel/turbopack-ecmascript-runtime' version: 0.0.0 From 61b825be3937dc1f095cde942d623c79559b2c53 Mon Sep 17 00:00:00 2001 From: Zack Tanner Date: Wed, 6 Dec 2023 12:15:42 -0800 Subject: [PATCH 199/481] fix hmr in multi-zone handling (#59307) ### What? When running a [multi-zone](https://github.com/vercel/next.js/tree/canary/examples/with-zones) app in dev, app pages would infinitely reload ### Why? The HMR upgrade request would fail and get caught into a retry loop. In the multi-zone case, they fail because the upgrade request would be sent again for a request that had already been upgraded. This resulted in a "server.handleUpgrade() was called more than once with the same socket" error, causing the upgrade request to fail. Every time a retry occurred, the page would trigger a full refresh since certain HMR errors cause the browser to reload. ### How? This ensures the upgrade handler only responds to requests that match the configured basePath. Closes NEXT-1797 Fixes #59161 Fixes #56615 Fixes #54454 --- packages/next/src/server/lib/router-server.ts | 10 ++++- .../multi-zone/app/apps/first/pages/index.tsx | 10 ++++- .../app/apps/second/pages/index.tsx | 10 ++++- test/e2e/multi-zone/multi-zone.test.ts | 43 ++++++++++++++++++- 4 files changed, 68 insertions(+), 5 deletions(-) diff --git a/packages/next/src/server/lib/router-server.ts b/packages/next/src/server/lib/router-server.ts index 2163dbdf7d268..70fdcfdb38778 100644 --- a/packages/next/src/server/lib/router-server.ts +++ b/packages/next/src/server/lib/router-server.ts @@ -582,8 +582,14 @@ export async function initialize(opts: { // console.error(_err); }) - if (opts.dev && developmentBundler) { - if (req.url?.includes(`/_next/webpack-hmr`)) { + if (opts.dev && developmentBundler && req.url) { + const isHMRRequest = req.url.includes('/_next/webpack-hmr') + // only handle HMR requests if the basePath in the request + // matches the basePath for the handler responding to the request + const isRequestForCurrentBasepath = + !config.basePath || pathHasPrefix(req.url, config.basePath) + + if (isHMRRequest && isRequestForCurrentBasepath) { return developmentBundler.hotReloader.onHMR(req, socket, head) } } diff --git a/test/e2e/multi-zone/app/apps/first/pages/index.tsx b/test/e2e/multi-zone/app/apps/first/pages/index.tsx index f705a52cfdb5c..12430c178e674 100644 --- a/test/e2e/multi-zone/app/apps/first/pages/index.tsx +++ b/test/e2e/multi-zone/app/apps/first/pages/index.tsx @@ -1,3 +1,11 @@ export default function Page() { - return

hello from first app

+ // this variable is edited by the test to verify HMR + const editedContent = '' + return ( + <> +

hello from first app

+
{editedContent}
+
{Date.now()}
+ + ) } diff --git a/test/e2e/multi-zone/app/apps/second/pages/index.tsx b/test/e2e/multi-zone/app/apps/second/pages/index.tsx index bba3728179bd4..873638c0898b3 100644 --- a/test/e2e/multi-zone/app/apps/second/pages/index.tsx +++ b/test/e2e/multi-zone/app/apps/second/pages/index.tsx @@ -1,3 +1,11 @@ export default function Page() { - return

hello from second app

+ // this variable is edited by the test to verify HMR + const editedContent = '' + return ( + <> +

hello from second app

+
{editedContent}
+
{Date.now()}
+ + ) } diff --git a/test/e2e/multi-zone/multi-zone.test.ts b/test/e2e/multi-zone/multi-zone.test.ts index 50a992399ca39..79b1e6561a812 100644 --- a/test/e2e/multi-zone/multi-zone.test.ts +++ b/test/e2e/multi-zone/multi-zone.test.ts @@ -1,4 +1,5 @@ import { createNextDescribe } from 'e2e-utils' +import { check, waitFor } from 'next-test-utils' import path from 'path' createNextDescribe( @@ -14,7 +15,7 @@ createNextDescribe( }, }, }, - ({ next }) => { + ({ next, isNextDev }) => { it.each([ { pathname: '/first', content: ['hello from first app'] }, { pathname: '/second', content: ['hello from second app'] }, @@ -45,5 +46,45 @@ createNextDescribe( } } ) + + if (isNextDev) { + async function runHMRTest(app: string) { + const browser = await next.browser(`/${app}`) + expect(await browser.elementByCss('body').text()).toContain( + `hello from ${app} app` + ) + const initialTimestamp = await browser.elementById('now').text() + + expect(await browser.elementByCss('body').text()).not.toContain( + 'hmr content' + ) + + await waitFor(1000) + + // verify that the page isn't unexpectedly reloading in the background + const newTimestamp = await browser.elementById('now').text() + expect(newTimestamp).toBe(initialTimestamp) + + // trigger HMR + const filePath = `apps/${app}/pages/index.tsx` + const content = await next.readFile(filePath) + + const patchedContent = content.replace( + `const editedContent = ''`, + `const editedContent = 'hmr content'` + ) + await next.patchFile(filePath, patchedContent) + + await check(() => browser.elementByCss('body').text(), /hmr content/) + + // restore original content + await next.patchFile(filePath, content) + } + + it('should support HMR in both apps', async () => { + await runHMRTest('first') + await runHMRTest('second') + }) + } } ) From 7a733dfd3440ac121ea3c5ff277ee732539e39ed Mon Sep 17 00:00:00 2001 From: Zack Tanner Date: Wed, 6 Dec 2023 12:21:28 -0800 Subject: [PATCH 200/481] fix edge route catch-all param parsing (#59343) ### What? Visiting an edge catch-all route incorrectly truncates multiple parameters ### Why? The params are currently coerced into a `ParsedURLQuery`-like format by calling `Object.fromEntries` on `searchParams`, but this doesn't consider multiple param values assigned to the same key ### How? Rather than use `fromEntries`, this uses an existing util to get the path into `ParsedURLQuery` format. Closes NEXT-1814 Fixes #59333 --- .../server/web/edge-route-module-wrapper.ts | 3 ++- .../app/edge/[[...slug]]/route.ts | 13 +++++++++++ .../edge-route-catchall/app/layout.tsx | 16 +++++++++++++ .../edge-route-catchall.test.ts | 23 +++++++++++++++++++ .../edge-route-catchall/next.config.js | 6 +++++ 5 files changed, 60 insertions(+), 1 deletion(-) create mode 100644 test/e2e/app-dir/edge-route-catchall/app/edge/[[...slug]]/route.ts create mode 100644 test/e2e/app-dir/edge-route-catchall/app/layout.tsx create mode 100644 test/e2e/app-dir/edge-route-catchall/edge-route-catchall.test.ts create mode 100644 test/e2e/app-dir/edge-route-catchall/next.config.js diff --git a/packages/next/src/server/web/edge-route-module-wrapper.ts b/packages/next/src/server/web/edge-route-module-wrapper.ts index 7877c234cf974..68a14fc80d0e2 100644 --- a/packages/next/src/server/web/edge-route-module-wrapper.ts +++ b/packages/next/src/server/web/edge-route-module-wrapper.ts @@ -13,6 +13,7 @@ import { RouteMatcher } from '../future/route-matchers/route-matcher' import type { NextFetchEvent } from './spec-extension/fetch-event' import { internal_getCurrentFunctionWaitUntil } from './internal-edge-wait-until' import { getUtils } from '../server-utils' +import { searchParamsToUrlQuery } from '../../shared/lib/router/utils/querystring' type WrapOptions = Partial> @@ -78,7 +79,7 @@ export class EdgeRouteModuleWrapper { }) const { params } = utils.normalizeDynamicRouteParams( - Object.fromEntries(request.nextUrl.searchParams) + searchParamsToUrlQuery(request.nextUrl.searchParams) ) const prerenderManifest: PrerenderManifest | undefined = diff --git a/test/e2e/app-dir/edge-route-catchall/app/edge/[[...slug]]/route.ts b/test/e2e/app-dir/edge-route-catchall/app/edge/[[...slug]]/route.ts new file mode 100644 index 0000000000000..74f20092b782b --- /dev/null +++ b/test/e2e/app-dir/edge-route-catchall/app/edge/[[...slug]]/route.ts @@ -0,0 +1,13 @@ +import { NextRequest, NextResponse } from 'next/server' + +export const runtime = 'edge' + +type Context = { + params: { + slug: string[] + } +} + +export const GET = async (req: NextRequest, { params }: Context) => { + return NextResponse.json(params) +} diff --git a/test/e2e/app-dir/edge-route-catchall/app/layout.tsx b/test/e2e/app-dir/edge-route-catchall/app/layout.tsx new file mode 100644 index 0000000000000..a14e64fcd5e33 --- /dev/null +++ b/test/e2e/app-dir/edge-route-catchall/app/layout.tsx @@ -0,0 +1,16 @@ +export const metadata = { + title: 'Next.js', + description: 'Generated by Next.js', +} + +export default function RootLayout({ + children, +}: { + children: React.ReactNode +}) { + return ( + + {children} + + ) +} diff --git a/test/e2e/app-dir/edge-route-catchall/edge-route-catchall.test.ts b/test/e2e/app-dir/edge-route-catchall/edge-route-catchall.test.ts new file mode 100644 index 0000000000000..857b18fe9fb39 --- /dev/null +++ b/test/e2e/app-dir/edge-route-catchall/edge-route-catchall.test.ts @@ -0,0 +1,23 @@ +import { createNextDescribe } from 'e2e-utils' + +createNextDescribe( + 'edge-route-catchall', + { + files: __dirname, + }, + ({ next }) => { + it('should correctly normalize edge route catch-all with a single param', async () => { + const result = await next.fetch('/edge/one') + + expect(await result.text()).toBe(JSON.stringify({ slug: ['one'] })) + }) + + it('should correctly normalize edge route catch-all with multiple params', async () => { + const result = await next.fetch('/edge/one/two/three') + + expect(await result.text()).toBe( + JSON.stringify({ slug: ['one', 'two', 'three'] }) + ) + }) + } +) diff --git a/test/e2e/app-dir/edge-route-catchall/next.config.js b/test/e2e/app-dir/edge-route-catchall/next.config.js new file mode 100644 index 0000000000000..807126e4cf0bf --- /dev/null +++ b/test/e2e/app-dir/edge-route-catchall/next.config.js @@ -0,0 +1,6 @@ +/** + * @type {import('next').NextConfig} + */ +const nextConfig = {} + +module.exports = nextConfig From 19fa1fa579fa3fd8e799af954b91bf3610503b02 Mon Sep 17 00:00:00 2001 From: "quisi.do" Date: Wed, 6 Dec 2023 14:21:23 -0800 Subject: [PATCH 201/481] add `logLevel` support to `@next/bundle-analyzer` (#59228) Co-authored-by: Jiachi Liu --- packages/next-bundle-analyzer/index.d.ts | 6 ++++++ packages/next-bundle-analyzer/index.js | 3 ++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/next-bundle-analyzer/index.d.ts b/packages/next-bundle-analyzer/index.d.ts index d76b617c1f4fe..f34cc32494f03 100644 --- a/packages/next-bundle-analyzer/index.d.ts +++ b/packages/next-bundle-analyzer/index.d.ts @@ -4,6 +4,12 @@ declare function NextBundleAnalyzer(options?: { enabled?: boolean openAnalyzer?: boolean analyzerMode?: 'json' | 'static' + + /** + * Log level. Can be 'info', 'warn', 'error' or 'silent'. + * @default 'info' + */ + logLevel?: 'info' | 'warn' | 'error' | 'silent' | undefined }): (config?: NextConfig) => NextConfig export = NextBundleAnalyzer diff --git a/packages/next-bundle-analyzer/index.js b/packages/next-bundle-analyzer/index.js index e44e2ccf5c82a..855843aec69ac 100644 --- a/packages/next-bundle-analyzer/index.js +++ b/packages/next-bundle-analyzer/index.js @@ -1,5 +1,5 @@ module.exports = - ({ enabled = true, openAnalyzer, analyzerMode } = {}) => + ({ enabled = true, logLevel, openAnalyzer, analyzerMode } = {}) => (nextConfig = {}) => { return Object.assign({}, nextConfig, { webpack(config, options) { @@ -8,6 +8,7 @@ module.exports = config.plugins.push( new BundleAnalyzerPlugin({ analyzerMode: analyzerMode || 'static', + logLevel, openAnalyzer, reportFilename: !options.nextRuntime ? `./analyze/client.html` From d4d9dc40facff846582de9192f89b5b59c682edf Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Wed, 6 Dec 2023 23:22:10 +0000 Subject: [PATCH 202/481] v14.0.4-canary.47 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 16 ++++++++-------- 18 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lerna.json b/lerna.json index ba2666e19d14d..04712bf98e4b3 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.46" + "version": "14.0.4-canary.47" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index e384c0242931c..57d95edd97fa2 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.46", + "version": "14.0.4-canary.47", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index 21110002b3edb..b90277ff5b670 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.46", + "version": "14.0.4-canary.47", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.46", + "@next/eslint-plugin-next": "14.0.4-canary.47", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index ac6600bbc3345..3de9b1693de6a 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.46", + "version": "14.0.4-canary.47", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index 73dbe283d253c..bef4c19bfa7a4 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.46", + "version": "14.0.4-canary.47", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 03aa0956b44a4..7335c1d9d665b 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.46", + "version": "14.0.4-canary.47", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 093e26f0cc5d7..45f369091eaab 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.46", + "version": "14.0.4-canary.47", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index ac5d40d86655c..0ee1119ad209f 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.46", + "version": "14.0.4-canary.47", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index ffb1175430b2e..184d70453b097 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.46", + "version": "14.0.4-canary.47", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 47430fba9aa68..80f95a60164a3 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.46", + "version": "14.0.4-canary.47", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index e68210c6214f3..6f53706a44450 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.46", + "version": "14.0.4-canary.47", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index cbc0a0bae9cbe..28daf434c3553 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.46", + "version": "14.0.4-canary.47", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index abdbb77de5a33..147ed79dacda2 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.46", + "version": "14.0.4-canary.47", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index 0d45846a239e0..8d1a5597d86db 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.46", + "version": "14.0.4-canary.47", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.46", + "@next/env": "14.0.4-canary.47", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -147,11 +147,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.46", - "@next/polyfill-nomodule": "14.0.4-canary.46", - "@next/react-dev-overlay": "14.0.4-canary.46", - "@next/react-refresh-utils": "14.0.4-canary.46", - "@next/swc": "14.0.4-canary.46", + "@next/polyfill-module": "14.0.4-canary.47", + "@next/polyfill-nomodule": "14.0.4-canary.47", + "@next/react-dev-overlay": "14.0.4-canary.47", + "@next/react-refresh-utils": "14.0.4-canary.47", + "@next/swc": "14.0.4-canary.47", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index 3c77e469d6a67..954768e6dc427 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.46", + "version": "14.0.4-canary.47", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index d4efe7f8f84aa..7319b304816be 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.46", + "version": "14.0.4-canary.47", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index 497b226d4ff36..5c0e890d5a9d3 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.46", + "version": "14.0.4-canary.47", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -25,7 +25,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.46", + "next": "14.0.4-canary.47", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 51dbbb3340018..bccb753d7e5f5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -741,7 +741,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.46 + specifier: 14.0.4-canary.47 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -806,7 +806,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.46 + specifier: 14.0.4-canary.47 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -933,19 +933,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.46 + specifier: 14.0.4-canary.47 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.46 + specifier: 14.0.4-canary.47 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.46 + specifier: 14.0.4-canary.47 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.46 + specifier: 14.0.4-canary.47 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.46 + specifier: 14.0.4-canary.47 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1599,7 +1599,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.46 + specifier: 14.0.4-canary.47 version: link:../next outdent: specifier: 0.8.0 From 0925de117ea84e477789b93395212ae902015ad2 Mon Sep 17 00:00:00 2001 From: Tim Neutkens Date: Thu, 7 Dec 2023 15:03:44 +0100 Subject: [PATCH 203/481] Update tests for Turbopack (#59354) ## What? - Add support for `experimental.externalDir` -- Was already supported, just makes Turbopack not fail on that config option - Skipped `with-babel` test because it tests Babel - Skipped `swc-warnings` test because it tests Babel - Skipped `config-resolve-alias` as it tests webpack config - Skipped `undefined-webpack-config` as it tests webpack config Closes NEXT-1817 --- packages/next/src/lib/turbopack-warning.ts | 2 +- .../e2e/app-dir/with-babel/with-babel.test.ts | 41 +++++++------- test/e2e/swc-warnings/index.test.ts | 40 +++++++------- .../config-resolve-alias/test/index.test.js | 27 ++++++---- .../test/index.test.js | 53 +++++++++++-------- 5 files changed, 92 insertions(+), 71 deletions(-) diff --git a/packages/next/src/lib/turbopack-warning.ts b/packages/next/src/lib/turbopack-warning.ts index ff163f194bf8e..b83cc3a114dff 100644 --- a/packages/next/src/lib/turbopack-warning.ts +++ b/packages/next/src/lib/turbopack-warning.ts @@ -69,6 +69,7 @@ const supportedTurbopackNextConfigOptions = [ 'experimental.useLightningcss', 'experimental.windowHistorySupport', 'experimental.instrumentationHook', + 'experimental.externalDir', // Experimental options that don't affect compilation 'experimental.ppr', @@ -131,7 +132,6 @@ const supportedTurbopackNextConfigOptions = [ // 'experimental.craCompat', // 'experimental.disablePostcssPresetEnv', // 'experimental.esmExternals', - // 'experimental.externalDir', // This is used to force swc-loader to run regardless of finding Babel. // 'experimental.forceSwcTransforms', // 'experimental.fullySpecified', diff --git a/test/e2e/app-dir/with-babel/with-babel.test.ts b/test/e2e/app-dir/with-babel/with-babel.test.ts index 6b1a8c1c2feff..9ec962d5aca51 100644 --- a/test/e2e/app-dir/with-babel/with-babel.test.ts +++ b/test/e2e/app-dir/with-babel/with-babel.test.ts @@ -1,23 +1,26 @@ import { createNextDescribe } from 'e2e-utils' -createNextDescribe( - 'with babel', - { - files: __dirname, - skipDeployment: true, - }, - ({ next, isNextStart }) => { - it('should support babel in app dir', async () => { - const $ = await next.render$('/') - expect($('h1').text()).toBe('hello') - }) - - if (isNextStart) { - it('should contain og package files in middleware', async () => { - const middleware = await next.readFile('.next/server/middleware.js') - // @vercel/og default font should be bundled - expect(middleware).not.toContain('noto-sans-v27-latin-regular.ttf') +// Tests Babel, not needed for Turbopack +;(process.env.TURBOPACK ? describe.skip : describe)('with babel', () => { + createNextDescribe( + 'with babel', + { + files: __dirname, + skipDeployment: true, + }, + ({ next, isNextStart }) => { + it('should support babel in app dir', async () => { + const $ = await next.render$('/') + expect($('h1').text()).toBe('hello') }) + + if (isNextStart) { + it('should contain og package files in middleware', async () => { + const middleware = await next.readFile('.next/server/middleware.js') + // @vercel/og default font should be bundled + expect(middleware).not.toContain('noto-sans-v27-latin-regular.ttf') + }) + } } - } -) + ) +}) diff --git a/test/e2e/swc-warnings/index.test.ts b/test/e2e/swc-warnings/index.test.ts index 018e7b81137e9..4e82fa9f31516 100644 --- a/test/e2e/swc-warnings/index.test.ts +++ b/test/e2e/swc-warnings/index.test.ts @@ -2,35 +2,39 @@ import { createNext } from 'e2e-utils' import { NextInstance } from 'test/lib/next-modes/base' import { renderViaHTTP } from 'next-test-utils' -describe('swc warnings by default', () => { - let next: NextInstance +// Tests Babel, not needed for Turbopack +;(process.env.TURBOPACK ? describe.skip : describe)( + 'swc warnings by default', + () => { + let next: NextInstance - beforeAll(async () => { - next = await createNext({ - files: { - 'pages/index.js': ` + beforeAll(async () => { + next = await createNext({ + files: { + 'pages/index.js': ` export default function Page() { return

hello world

} `, - '.babelrc': ` + '.babelrc': ` { "presets": ["next/babel"] } `, - }, - dependencies: {}, + }, + dependencies: {}, + }) }) - }) - afterAll(() => next.destroy()) + afterAll(() => next.destroy()) - it('should have warning', async () => { - await renderViaHTTP(next.url, '/') - expect(next.cliOutput).toContain( - 'Disabled SWC as replacement for Babel because of custom Babel configuration' - ) - }) -}) + it('should have warning', async () => { + await renderViaHTTP(next.url, '/') + expect(next.cliOutput).toContain( + 'Disabled SWC as replacement for Babel because of custom Babel configuration' + ) + }) + } +) describe('can force swc', () => { let next: NextInstance diff --git a/test/integration/config-resolve-alias/test/index.test.js b/test/integration/config-resolve-alias/test/index.test.js index f67e5000a9854..4694debddc061 100644 --- a/test/integration/config-resolve-alias/test/index.test.js +++ b/test/integration/config-resolve-alias/test/index.test.js @@ -3,14 +3,21 @@ import { join } from 'path' import { runNextCommand } from 'next-test-utils' -describe('Invalid resolve alias', () => { - it('should show relevant error when webpack resolve alias is wrong', async () => { - const { stderr } = await runNextCommand(['build', join(__dirname, '..')], { - stderr: true, - }) +// Skip in Turbopack as it does not support `config.resolve.alias` from webpack. +;(process.env.TURBOPACK ? describe.skip : describe)( + 'Invalid resolve alias', + () => { + it('should show relevant error when webpack resolve alias is wrong', async () => { + const { stderr } = await runNextCommand( + ['build', join(__dirname, '..')], + { + stderr: true, + } + ) - expect(stderr).toMatch( - 'webpack config.resolve.alias was incorrectly overridden. https://' - ) - }) -}) + expect(stderr).toMatch( + 'webpack config.resolve.alias was incorrectly overridden. https://' + ) + }) + } +) diff --git a/test/integration/undefined-webpack-config/test/index.test.js b/test/integration/undefined-webpack-config/test/index.test.js index 5556ad5ae469e..9e1abf0f11df7 100644 --- a/test/integration/undefined-webpack-config/test/index.test.js +++ b/test/integration/undefined-webpack-config/test/index.test.js @@ -7,29 +7,36 @@ const appDir = join(__dirname, '../') const expectedErr = /Webpack config is undefined. You may have forgot to return properly from within the "webpack" method of your next.config.js/ -describe('undefined webpack config error', () => { - ;(process.env.TURBOPACK ? describe.skip : describe)('production mode', () => { - it.skip('should show in production mode', async () => { - const result = await nextBuild(appDir, [], { - stdout: true, - stderr: true, - }) - expect(result.stderr || '' + result.stdout || '').toMatch(expectedErr) - }) - }) +// Tests webpack, not needed for Turbopack +;(process.env.TURBOPACK ? describe.skip : describe)( + 'undefined webpack config error', + () => { + ;(process.env.TURBOPACK ? describe.skip : describe)( + 'production mode', + () => { + it.skip('should show in production mode', async () => { + const result = await nextBuild(appDir, [], { + stdout: true, + stderr: true, + }) + expect(result.stderr || '' + result.stdout || '').toMatch(expectedErr) + }) + } + ) - it('should show in dev mode', async () => { - let output = '' + it('should show in dev mode', async () => { + let output = '' - await launchApp(appDir, await findPort(), { - onStderr(msg) { - output += msg || '' - }, - ontStdout(msg) { - output += msg || '' - }, - }) + await launchApp(appDir, await findPort(), { + onStderr(msg) { + output += msg || '' + }, + ontStdout(msg) { + output += msg || '' + }, + }) - expect(output).toMatch(expectedErr) - }) -}) + expect(output).toMatch(expectedErr) + }) + } +) From 42ec6c89bb21cd33d891e3351fe4aa61562f39d0 Mon Sep 17 00:00:00 2001 From: Vercel Release Bot <88769842+vercel-release-bot@users.noreply.github.com> Date: Thu, 7 Dec 2023 09:51:45 -0500 Subject: [PATCH 204/481] Update Turbopack test manifest (#59356) This auto-generated PR updates the integration test manifest used when testing Turbopack. --- test/turbopack-tests-manifest.json | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/test/turbopack-tests-manifest.json b/test/turbopack-tests-manifest.json index 6a152e9827840..dca09102fcfbe 100644 --- a/test/turbopack-tests-manifest.json +++ b/test/turbopack-tests-manifest.json @@ -3133,6 +3133,16 @@ "flakey": [], "runtimeError": false }, + "test/e2e/app-dir/edge-route-catchall/edge-route-catchall.test.ts": { + "passed": [ + "edge-route-catchall should correctly normalize edge route catch-all with a single param", + "edge-route-catchall should correctly normalize edge route catch-all with multiple params" + ], + "failed": [], + "pending": [], + "flakey": [], + "runtimeError": false + }, "test/e2e/app-dir/edge-route-rewrite/edge-route-rewrite.test.ts": { "passed": [ "edge-route-rewrite it should support a rewrite to a dynamic edge route", @@ -5335,7 +5345,8 @@ "multi-zone should correctly respond for /first/blog/post-1", "multi-zone should correctly respond for /second", "multi-zone should correctly respond for /second/another/post-1", - "multi-zone should correctly respond for /second/blog/post-1" + "multi-zone should correctly respond for /second/blog/post-1", + "multi-zone should support HMR in both apps" ], "failed": [], "pending": [], From 2874bc0656df9031d10eea7beee36ce70e53acef Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Thu, 7 Dec 2023 18:11:11 +0100 Subject: [PATCH 205/481] Fix server output bundling packages module resolving (#59369) --- packages/next/src/build/handle-externals.ts | 16 +++++++++++++-- packages/next/src/build/webpack-config.ts | 4 ++++ .../plugins/next-trace-entrypoints-plugin.ts | 5 +++++ .../app-dir/app-external/app-external.test.ts | 19 +++++++++++++++++- .../app-external/app/optout/action/actions.js | 7 +++++++ .../app-external/app/optout/action/page.js | 20 +++++++++++++++++++ test/e2e/app-dir/app-external/next.config.js | 5 ++++- .../dual-pkg-optout/index.cjs | 1 + .../dual-pkg-optout/index.mjs | 1 + .../dual-pkg-optout/package.json | 6 ++++++ 10 files changed, 80 insertions(+), 4 deletions(-) create mode 100644 test/e2e/app-dir/app-external/app/optout/action/actions.js create mode 100644 test/e2e/app-dir/app-external/app/optout/action/page.js create mode 100644 test/e2e/app-dir/app-external/node_modules_bak/dual-pkg-optout/index.cjs create mode 100644 test/e2e/app-dir/app-external/node_modules_bak/dual-pkg-optout/index.mjs create mode 100644 test/e2e/app-dir/app-external/node_modules_bak/dual-pkg-optout/package.json diff --git a/packages/next/src/build/handle-externals.ts b/packages/next/src/build/handle-externals.ts index 8c7f4ccc55ce7..8a26dd4042ba4 100644 --- a/packages/next/src/build/handle-externals.ts +++ b/packages/next/src/build/handle-externals.ts @@ -47,6 +47,7 @@ export async function resolveExternal( context: string, request: string, isEsmRequested: boolean, + optOutBundlingPackages: string[], getResolve: ( options: any ) => ( @@ -66,8 +67,15 @@ export async function resolveExternal( let res: string | null = null let isEsm: boolean = false - let preferEsmOptions = - esmExternals && isEsmRequested ? [true, false] : [false] + const preferEsmOptions = + esmExternals && + isEsmRequested && + // For package that marked as externals that should be not bundled, + // we don't resolve them as ESM since it could be resolved as async module, + // such as `import(external package)` in the bundle, valued as a `Promise`. + !optOutBundlingPackages.some((optOut) => request.startsWith(optOut)) + ? [true, false] + : [false] for (const preferEsm of preferEsmOptions) { const resolve = getResolve( @@ -131,10 +139,12 @@ export async function resolveExternal( export function makeExternalHandler({ config, + optOutBundlingPackages, optOutBundlingPackageRegex, dir, }: { config: NextConfigComplete + optOutBundlingPackages: string[] optOutBundlingPackageRegex: RegExp dir: string }) { @@ -289,6 +299,7 @@ export function makeExternalHandler({ context, request, isEsmRequested, + optOutBundlingPackages, getResolve, isLocal ? resolveNextExternal : undefined ) @@ -349,6 +360,7 @@ export function makeExternalHandler({ context, pkg + '/package.json', isEsmRequested, + optOutBundlingPackages, getResolve, isLocal ? resolveNextExternal : undefined ) diff --git a/packages/next/src/build/webpack-config.ts b/packages/next/src/build/webpack-config.ts index 60dde7bbc8ab5..75b0ebdd46141 100644 --- a/packages/next/src/build/webpack-config.ts +++ b/packages/next/src/build/webpack-config.ts @@ -727,9 +727,11 @@ export default async function getBaseWebpackConfig( const crossOrigin = config.crossOrigin + // For original request, such as `package name` const optOutBundlingPackages = EXTERNAL_PACKAGES.concat( ...(config.experimental.serverComponentsExternalPackages || []) ) + // For resolved request, such as `absolute path/package name/foo/bar.js` const optOutBundlingPackageRegex = new RegExp( `[/\\\\]node_modules[/\\\\](${optOutBundlingPackages .map((p) => p.replace(/\//g, '[/\\\\]')) @@ -738,6 +740,7 @@ export default async function getBaseWebpackConfig( const handleExternals = makeExternalHandler({ config, + optOutBundlingPackages, optOutBundlingPackageRegex, dir, }) @@ -1662,6 +1665,7 @@ export default async function getBaseWebpackConfig( outputFileTracingRoot: config.experimental.outputFileTracingRoot, appDirEnabled: hasAppDir, turbotrace: config.experimental.turbotrace, + optOutBundlingPackages, traceIgnores: config.experimental.outputFileTracingIgnores || [], } ), diff --git a/packages/next/src/build/webpack/plugins/next-trace-entrypoints-plugin.ts b/packages/next/src/build/webpack/plugins/next-trace-entrypoints-plugin.ts index 5ea193152a283..669d3c6f6afef 100644 --- a/packages/next/src/build/webpack/plugins/next-trace-entrypoints-plugin.ts +++ b/packages/next/src/build/webpack/plugins/next-trace-entrypoints-plugin.ts @@ -133,6 +133,7 @@ export class TraceEntryPointsPlugin implements webpack.WebpackPluginInstance { private rootDir: string private appDir: string | undefined private pagesDir: string | undefined + private optOutBundlingPackages: string[] private appDirEnabled?: boolean private tracingRoot: string private entryTraces: Map> @@ -144,6 +145,7 @@ export class TraceEntryPointsPlugin implements webpack.WebpackPluginInstance { rootDir, appDir, pagesDir, + optOutBundlingPackages, appDirEnabled, traceIgnores, esmExternals, @@ -153,6 +155,7 @@ export class TraceEntryPointsPlugin implements webpack.WebpackPluginInstance { rootDir: string appDir: string | undefined pagesDir: string | undefined + optOutBundlingPackages: string[] appDirEnabled?: boolean traceIgnores?: string[] outputFileTracingRoot?: string @@ -168,6 +171,7 @@ export class TraceEntryPointsPlugin implements webpack.WebpackPluginInstance { this.traceIgnores = traceIgnores || [] this.tracingRoot = outputFileTracingRoot || rootDir this.turbotrace = turbotrace + this.optOutBundlingPackages = optOutBundlingPackages } // Here we output all traced assets and webpack chunks to a @@ -743,6 +747,7 @@ export class TraceEntryPointsPlugin implements webpack.WebpackPluginInstance { context, request, isEsmRequested, + this.optOutBundlingPackages, (options) => (_: string, resRequest: string) => { return getResolve(options)(parent, resRequest, job) }, diff --git a/test/e2e/app-dir/app-external/app-external.test.ts b/test/e2e/app-dir/app-external/app-external.test.ts index c458ab3397da9..b734f53bcc358 100644 --- a/test/e2e/app-dir/app-external/app-external.test.ts +++ b/test/e2e/app-dir/app-external/app-external.test.ts @@ -1,5 +1,5 @@ import { createNextDescribe } from 'e2e-utils' -import { shouldRunTurboDevTest } from '../../../lib/next-test-utils' +import { check, shouldRunTurboDevTest } from 'next-test-utils' async function resolveStreamResponse(response: any, onData?: any) { let result = '' @@ -250,5 +250,22 @@ createNextDescribe( const html = await next.render('/async-storage') expect(html).toContain('success') }) + + it('should not prefer to resolve esm over cjs for bundling optout packages', async () => { + const browser = await next.browser('/optout/action') + expect(await browser.elementByCss('#dual-pkg-outout p').text()).toBe('') + + browser.elementByCss('#dual-pkg-outout button').click() + await check(async () => { + const text = await browser.elementByCss('#dual-pkg-outout p').text() + if (process.env.TURBOPACK) { + // The prefer esm won't effect turbopack resolving + expect(text).toBe('dual-pkg-optout:mjs') + } else { + expect(text).toBe('dual-pkg-optout:cjs') + } + return 'success' + }, /success/) + }) } ) diff --git a/test/e2e/app-dir/app-external/app/optout/action/actions.js b/test/e2e/app-dir/app-external/app/optout/action/actions.js new file mode 100644 index 0000000000000..b6c9a47131f15 --- /dev/null +++ b/test/e2e/app-dir/app-external/app/optout/action/actions.js @@ -0,0 +1,7 @@ +'use server' + +import { value as dualPkgOptoutValue } from 'dual-pkg-optout' + +export async function getDualOptoutValue() { + return dualPkgOptoutValue +} diff --git a/test/e2e/app-dir/app-external/app/optout/action/page.js b/test/e2e/app-dir/app-external/app/optout/action/page.js new file mode 100644 index 0000000000000..0d339c7c39262 --- /dev/null +++ b/test/e2e/app-dir/app-external/app/optout/action/page.js @@ -0,0 +1,20 @@ +'use client' + +import { useState } from 'react' +import { getDualOptoutValue } from './actions' + +export default function Page() { + const [optoutDisplayValue, setOptoutDisplayValue] = useState('') + return ( +
+

{optoutDisplayValue}

+ +
+ ) +} diff --git a/test/e2e/app-dir/app-external/next.config.js b/test/e2e/app-dir/app-external/next.config.js index 82662490484e9..4b1cb6524d198 100644 --- a/test/e2e/app-dir/app-external/next.config.js +++ b/test/e2e/app-dir/app-external/next.config.js @@ -2,6 +2,9 @@ module.exports = { reactStrictMode: true, transpilePackages: ['untranspiled-module', 'css', 'font'], experimental: { - serverComponentsExternalPackages: ['conditional-exports-optout'], + serverComponentsExternalPackages: [ + 'conditional-exports-optout', + 'dual-pkg-optout', + ], }, } diff --git a/test/e2e/app-dir/app-external/node_modules_bak/dual-pkg-optout/index.cjs b/test/e2e/app-dir/app-external/node_modules_bak/dual-pkg-optout/index.cjs new file mode 100644 index 0000000000000..a6764e05e13dd --- /dev/null +++ b/test/e2e/app-dir/app-external/node_modules_bak/dual-pkg-optout/index.cjs @@ -0,0 +1 @@ +exports.value = 'dual-pkg-optout:cjs' diff --git a/test/e2e/app-dir/app-external/node_modules_bak/dual-pkg-optout/index.mjs b/test/e2e/app-dir/app-external/node_modules_bak/dual-pkg-optout/index.mjs new file mode 100644 index 0000000000000..1f257f74e95bd --- /dev/null +++ b/test/e2e/app-dir/app-external/node_modules_bak/dual-pkg-optout/index.mjs @@ -0,0 +1 @@ +export const value = 'dual-pkg-optout:mjs' diff --git a/test/e2e/app-dir/app-external/node_modules_bak/dual-pkg-optout/package.json b/test/e2e/app-dir/app-external/node_modules_bak/dual-pkg-optout/package.json new file mode 100644 index 0000000000000..3646ad4bdb5f5 --- /dev/null +++ b/test/e2e/app-dir/app-external/node_modules_bak/dual-pkg-optout/package.json @@ -0,0 +1,6 @@ +{ + "exports": { + "import": "./index.mjs", + "require": "./index.cjs" + } +} From a578cc8192fa3f9182d4fa70f18760f7ae1490bb Mon Sep 17 00:00:00 2001 From: Zack Tanner Date: Thu, 7 Dec 2023 11:17:15 -0800 Subject: [PATCH 206/481] fix inconsistent scroll restoration behavior (#59366) ### What? While scrolled on a page, and when following a link to a new page and clicking the browser back button or using `router.back()`, the scroll position would sometimes restore scroll to the incorrect spot (in the case of the test added in this PR, it'd scroll you back to the top of the list) ### Why? The refactor in #56497 changed the way router actions are processed: specifically, all actions were assumed to be async, even if they could be handled synchronously. For most actions this is fine, as most are currently async. However, `ACTION_RESTORE` (triggered when the `popstate` event occurs) isn't async, and introducing a small amount of delay in the handling of this action can cause the browser to not properly restore the scroll position ### How? This special-cases `ACTION_RESTORE` to synchronously process the action and call `setState` when it's received, rather than creating a promise. To consistently reproduce this behavior, I added an option to our browser interface that'll allow us to programmatically trigger a CPU slowdown. h/t to @alvarlagerlof for isolating the offending commit and sharing a minimal reproduction. Closes NEXT-1819 Likely addresses #58899 but the reproduction was too complex to verify. --- .../src/shared/lib/router/action-queue.ts | 33 +++++++++++-------- .../app/scroll-restoration/context.ts | 10 ++++++ .../app/scroll-restoration/layout.tsx | 27 +++++++++++++++ .../app/scroll-restoration/other/page.tsx | 13 ++++++++ .../app/scroll-restoration/page.tsx | 23 +++++++++++++ .../e2e/app-dir/navigation/navigation.test.ts | 29 ++++++++++++++++ test/lib/browsers/base.ts | 10 +++++- test/lib/browsers/playwright.ts | 14 +++++++- test/lib/next-webdriver.ts | 8 ++++- 9 files changed, 151 insertions(+), 16 deletions(-) create mode 100644 test/e2e/app-dir/navigation/app/scroll-restoration/context.ts create mode 100644 test/e2e/app-dir/navigation/app/scroll-restoration/layout.tsx create mode 100644 test/e2e/app-dir/navigation/app/scroll-restoration/other/page.tsx create mode 100644 test/e2e/app-dir/navigation/app/scroll-restoration/page.tsx diff --git a/packages/next/src/shared/lib/router/action-queue.ts b/packages/next/src/shared/lib/router/action-queue.ts index 54e57c76e6248..03ce7accb2097 100644 --- a/packages/next/src/shared/lib/router/action-queue.ts +++ b/packages/next/src/shared/lib/router/action-queue.ts @@ -6,6 +6,7 @@ import { ACTION_REFRESH, ACTION_SERVER_ACTION, ACTION_NAVIGATE, + ACTION_RESTORE, } from '../../../client/components/router-reducer/router-reducer-types' import type { ReduxDevToolsInstance } from '../../../client/components/use-reducer-with-devtools' import { reducer } from '../../../client/components/router-reducer/router-reducer' @@ -26,7 +27,7 @@ export type AppRouterActionQueue = { export type ActionQueueNode = { payload: ReducerActions next: ActionQueueNode | null - resolve: (value: PromiseLike | AppRouterState) => void + resolve: (value: ReducerState) => void reject: (err: Error) => void discarded?: boolean } @@ -115,14 +116,26 @@ function dispatchAction( setState: DispatchStatePromise ) { let resolvers: { - resolve: (value: AppRouterState | PromiseLike) => void + resolve: (value: ReducerState) => void reject: (reason: any) => void - } + } = { resolve: setState, reject: () => {} } + + // most of the action types are async with the exception of restore + // it's important that restore is handled quickly since it's fired on the popstate event + // and we don't want to add any delay on a back/forward nav + // this only creates a promise for the async actions + if (payload.type !== ACTION_RESTORE) { + // Create the promise and assign the resolvers to the object. + const deferredPromise = new Promise((resolve, reject) => { + resolvers = { resolve, reject } + }) - // Create the promise and assign the resolvers to the object. - const deferredPromise = new Promise((resolve, reject) => { - resolvers = { resolve, reject } - }) + startTransition(() => { + // we immediately notify React of the pending promise -- the resolver is attached to the action node + // and will be called when the associated action promise resolves + setState(deferredPromise) + }) + } const newAction: ActionQueueNode = { payload, @@ -131,12 +144,6 @@ function dispatchAction( reject: resolvers!.reject, } - startTransition(() => { - // we immediately notify React of the pending promise -- the resolver is attached to the action node - // and will be called when the associated action promise resolves - setState(deferredPromise) - }) - // Check if the queue is empty if (actionQueue.pending === null) { // The queue is empty, so add the action and start it immediately diff --git a/test/e2e/app-dir/navigation/app/scroll-restoration/context.ts b/test/e2e/app-dir/navigation/app/scroll-restoration/context.ts new file mode 100644 index 0000000000000..ee51ff9835aae --- /dev/null +++ b/test/e2e/app-dir/navigation/app/scroll-restoration/context.ts @@ -0,0 +1,10 @@ +import { createContext } from 'react' + +export interface Item { + id: number +} + +export const ItemsContext = createContext<{ + items: Item[] + loadMoreItems: () => void +}>({ items: [], loadMoreItems: () => {} }) diff --git a/test/e2e/app-dir/navigation/app/scroll-restoration/layout.tsx b/test/e2e/app-dir/navigation/app/scroll-restoration/layout.tsx new file mode 100644 index 0000000000000..eef2c2f88c4b5 --- /dev/null +++ b/test/e2e/app-dir/navigation/app/scroll-restoration/layout.tsx @@ -0,0 +1,27 @@ +'use client' +import { useState } from 'react' +import { ItemsContext, type Item } from './context' + +const createItems = (start: number, end: number): Item[] => { + const items: Item[] = [] + for (let i = start; i <= end; i++) { + items.push({ id: i }) + } + return items +} + +export default function Layout({ children }: { children: React.ReactNode }) { + const [items, setItems] = useState(createItems(1, 50)) + + const loadMoreItems = () => { + const start = items.length + 1 + const end = start + 50 - 1 + setItems((prevItems) => [...prevItems, ...createItems(start, end)]) + } + + return ( + + {children} + + ) +} diff --git a/test/e2e/app-dir/navigation/app/scroll-restoration/other/page.tsx b/test/e2e/app-dir/navigation/app/scroll-restoration/other/page.tsx new file mode 100644 index 0000000000000..dcc5babec8616 --- /dev/null +++ b/test/e2e/app-dir/navigation/app/scroll-restoration/other/page.tsx @@ -0,0 +1,13 @@ +'use client' +import { useRouter } from 'next/navigation' + +export default function Page() { + const router = useRouter() + return ( +
+ +
+ ) +} diff --git a/test/e2e/app-dir/navigation/app/scroll-restoration/page.tsx b/test/e2e/app-dir/navigation/app/scroll-restoration/page.tsx new file mode 100644 index 0000000000000..34a0ffa0bc861 --- /dev/null +++ b/test/e2e/app-dir/navigation/app/scroll-restoration/page.tsx @@ -0,0 +1,23 @@ +'use client' +import Link from 'next/link' +import React, { useContext } from 'react' +import { ItemsContext } from './context' + +export default function Page() { + const { items, loadMoreItems } = useContext(ItemsContext) + + return ( +
+

Page

+
    + {items.map((item) => ( +
  • Item {item.id}
  • + ))} +
+ + Go to Other +
+ ) +} diff --git a/test/e2e/app-dir/navigation/navigation.test.ts b/test/e2e/app-dir/navigation/navigation.test.ts index 4a568331ca0f6..73986d6f1d6d9 100644 --- a/test/e2e/app-dir/navigation/navigation.test.ts +++ b/test/e2e/app-dir/navigation/navigation.test.ts @@ -732,5 +732,34 @@ createNextDescribe( } }) }) + + describe('scroll restoration', () => { + it('should restore original scroll position when navigating back', async () => { + const browser = await next.browser('/scroll-restoration', { + // throttling the CPU to rule out flakiness based on how quickly the page loads + cpuThrottleRate: 6, + }) + const body = await browser.elementByCss('body') + expect(await body.text()).toContain('Item 50') + await browser.elementById('load-more').click() + await browser.elementById('load-more').click() + await browser.elementById('load-more').click() + expect(await body.text()).toContain('Item 200') + + // scroll to the bottom of the page + await browser.eval('window.scrollTo(0, document.body.scrollHeight)') + + // grab the current position + const scrollPosition = await browser.eval('window.pageYOffset') + + await browser.elementByCss("[href='/scroll-restoration/other']").click() + await browser.elementById('back-button').click() + + const newScrollPosition = await browser.eval('window.pageYOffset') + + // confirm that the scroll position was restored + await check(() => scrollPosition === newScrollPosition, true) + }) + }) } ) diff --git a/test/lib/browsers/base.ts b/test/lib/browsers/base.ts index 3b7b2c6def90a..5788010a4f087 100644 --- a/test/lib/browsers/base.ts +++ b/test/lib/browsers/base.ts @@ -125,7 +125,15 @@ export abstract class BrowserInterface implements PromiseLike { off(event: Event, cb: (...args: any[]) => void) {} async loadPage( url: string, - { disableCache: boolean, beforePageLoad: Function } + { + disableCache, + cpuThrottleRate, + beforePageLoad, + }: { + disableCache?: boolean + cpuThrottleRate?: number + beforePageLoad?: Function + } ): Promise {} async get(url: string): Promise {} diff --git a/test/lib/browsers/playwright.ts b/test/lib/browsers/playwright.ts index 7f3106df6169b..f742a95cc6d58 100644 --- a/test/lib/browsers/playwright.ts +++ b/test/lib/browsers/playwright.ts @@ -128,7 +128,11 @@ export class Playwright extends BrowserInterface { async loadPage( url: string, - opts?: { disableCache: boolean; beforePageLoad?: (...args: any[]) => void } + opts?: { + disableCache: boolean + cpuThrottleRate: number + beforePageLoad?: (...args: any[]) => void + } ) { if (this.activeTrace) { const traceDir = path.join(__dirname, '../../traces') @@ -182,6 +186,14 @@ export class Playwright extends BrowserInterface { session.send('Network.setCacheDisabled', { cacheDisabled: true }) } + if (opts?.cpuThrottleRate) { + const session = await context.newCDPSession(page) + // https://chromedevtools.github.io/devtools-protocol/tot/Emulation/#method-setCPUThrottlingRate + session.send('Emulation.setCPUThrottlingRate', { + rate: opts.cpuThrottleRate, + }) + } + page.on('websocket', (ws) => { if (tracePlaywright) { page diff --git a/test/lib/next-webdriver.ts b/test/lib/next-webdriver.ts index d9f9e9cfd27ca..cd0b7bc9e1d66 100644 --- a/test/lib/next-webdriver.ts +++ b/test/lib/next-webdriver.ts @@ -68,6 +68,7 @@ export default async function webdriver( disableJavaScript?: boolean headless?: boolean ignoreHTTPSErrors?: boolean + cpuThrottleRate?: number } ): Promise { let CurrentInterface: new () => BrowserInterface @@ -87,6 +88,7 @@ export default async function webdriver( disableJavaScript, ignoreHTTPSErrors, headless, + cpuThrottleRate, } = options // we import only the needed interface @@ -124,7 +126,11 @@ export default async function webdriver( console.log(`\n> Loading browser with ${fullUrl}\n`) - await browser.loadPage(fullUrl, { disableCache, beforePageLoad }) + await browser.loadPage(fullUrl, { + disableCache, + cpuThrottleRate, + beforePageLoad, + }) console.log(`\n> Loaded browser with ${fullUrl}\n`) // Wait for application to hydrate From e1fe0c9a14266b1c216306b7392c0006166b113e Mon Sep 17 00:00:00 2001 From: Tomas Fagerbekk Date: Thu, 7 Dec 2023 20:20:07 +0100 Subject: [PATCH 207/481] test: ability to use node debugger (#56277) Fixes ability to run `NODE_OPTIONS='--inspect' next dev` as described in [docs](https://nextjs.org/docs/pages/building-your-application/configuring/debugging), by removing inspect option from NODE_OPTIONS arg passed to worker process. This bug seem to have been introduced in 7d93808c435d6d74f93e045711b1639dc1fc05b3 as a part of a some refactoring. See how `getNodeOptionsWithoutInspect` is no longer used. Fixes #55862 --------- Co-authored-by: Jiachi Liu --- test/integration/cli/test/index.test.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/integration/cli/test/index.test.js b/test/integration/cli/test/index.test.js index e316bde63eaa6..34c89f7b7fd68 100644 --- a/test/integration/cli/test/index.test.js +++ b/test/integration/cli/test/index.test.js @@ -530,6 +530,7 @@ describe('CLI Usage', () => { test("NODE_OPTIONS='--inspect'", async () => { const port = await findPort() let output = '' + let errOutput = '' const app = await runNextCommandDev( [dirBasic, '--port', port], undefined, @@ -537,11 +538,16 @@ describe('CLI Usage', () => { onStdout(msg) { output += stripAnsi(msg) }, + onStderr(msg) { + errOutput += stripAnsi(msg) + }, env: { NODE_OPTIONS: '--inspect' }, } ) try { await check(() => output, new RegExp(`http://localhost:${port}`)) + await check(() => errOutput, /Debugger listening on/) + expect(errOutput).not.toContain('address already in use') } finally { await killApp(app) } From d07a370dfa26e5c16ba8af0583b7a2f2f82475cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Badia?= <1901628+raphaelbadia@users.noreply.github.com> Date: Thu, 7 Dec 2023 20:54:34 +0100 Subject: [PATCH 208/481] fixes the logging by showing full URLs only on demand (#58088) fixes #58087 Currently in Next 14, everyone has fullURL flag turned to true, this PR reverts the condition. --------- Co-authored-by: Jiachi Liu --- packages/next/src/build/output/index.ts | 11 ----- packages/next/src/build/output/store.ts | 16 ++++++- packages/next/src/server/next-server.ts | 2 +- .../e2e/app-dir/logging/fetch-logging.test.ts | 46 +++++++++++++++++-- 4 files changed, 57 insertions(+), 18 deletions(-) diff --git a/packages/next/src/build/output/index.ts b/packages/next/src/build/output/index.ts index a304daa454b46..10745f2e1ae28 100644 --- a/packages/next/src/build/output/index.ts +++ b/packages/next/src/build/output/index.ts @@ -322,18 +322,7 @@ export function watchCompilers( }) } -const internalSegments = ['[[...__metadata_id__]]', '[__metadata_id__]'] export function reportTrigger(trigger: string, url?: string) { - for (const segment of internalSegments) { - if (trigger.includes(segment)) { - trigger = trigger.replace(segment, '') - } - } - - if (trigger.length > 1 && trigger.endsWith('/')) { - trigger = trigger.slice(0, -1) - } - buildStore.setState({ trigger, url, diff --git a/packages/next/src/build/output/store.ts b/packages/next/src/build/output/store.ts index e15d566c5e8de..3b25d0557f463 100644 --- a/packages/next/src/build/output/store.ts +++ b/packages/next/src/build/output/store.ts @@ -28,6 +28,19 @@ export type OutputState = } )) +const internalSegments = ['[[...__metadata_id__]]', '[__metadata_id__]'] +export function formatTrigger(trigger: string) { + for (const segment of internalSegments) { + if (trigger.includes(segment)) { + trigger = trigger.replace(segment, '') + } + } + if (trigger.length > 1 && trigger.endsWith('/')) { + trigger = trigger.slice(0, -1) + } + return trigger +} + export const store = createStore({ appUrl: null, bindAddr: null, @@ -67,7 +80,8 @@ store.subscribe((state) => { if (state.loading) { if (state.trigger) { - trigger = state.trigger + trigger = formatTrigger(state.trigger) + console.log('trigger', trigger) triggerUrl = state.url if (trigger !== 'initial') { traceSpan = trace('compile-path', undefined, { diff --git a/packages/next/src/server/next-server.ts b/packages/next/src/server/next-server.ts index acb6abf0c95c7..c02af8fd254eb 100644 --- a/packages/next/src/server/next-server.ts +++ b/packages/next/src/server/next-server.ts @@ -1061,7 +1061,7 @@ export default class NextNodeServer extends BaseServer { const loggingFetchesConfig = this.nextConfig.logging?.fetches const enabledVerboseLogging = !!loggingFetchesConfig - const shouldTruncateUrl = loggingFetchesConfig?.fullUrl + const shouldTruncateUrl = !loggingFetchesConfig?.fullUrl if (this.renderOpts.dev) { const { bold, green, yellow, red, gray, white } = diff --git a/test/e2e/app-dir/logging/fetch-logging.test.ts b/test/e2e/app-dir/logging/fetch-logging.test.ts index 885fd61241ab3..8402bc50868d8 100644 --- a/test/e2e/app-dir/logging/fetch-logging.test.ts +++ b/test/e2e/app-dir/logging/fetch-logging.test.ts @@ -1,3 +1,5 @@ +import path from 'path' +import fs from 'fs' import stripAnsi from 'strip-ansi' import { check } from 'next-test-utils' import { createNextDescribe } from 'e2e-utils' @@ -42,7 +44,13 @@ createNextDescribe( files: __dirname, }, ({ next, isNextDev }) => { - function runTests({ withFetchesLogging }: { withFetchesLogging: boolean }) { + function runTests({ + withFetchesLogging, + withFullUrlFetches = false, + }: { + withFetchesLogging: boolean + withFullUrlFetches?: boolean + }) { if (withFetchesLogging) { it('should only log requests in dev mode', async () => { const outputIndex = next.cliOutput.length @@ -74,8 +82,9 @@ createNextDescribe( log.url.includes('api/random?no-cache') ) - // expend full url - expect(logs.every((log) => log.url.includes('..'))).toBe(false) + expect(logs.some((log) => log.url.includes('..'))).toBe( + !withFullUrlFetches + ) if (logEntry?.cache === 'cache: no-cache') { return 'success' @@ -184,8 +193,28 @@ createNextDescribe( } } - describe('with verbose logging', () => { - runTests({ withFetchesLogging: true }) + describe('with fetches verbose logging', () => { + runTests({ withFetchesLogging: true, withFullUrlFetches: true }) + }) + + describe('with fetches default logging', () => { + const curNextConfig = fs.readFileSync( + path.join(__dirname, 'next.config.js'), + { encoding: 'utf-8' } + ) + beforeAll(async () => { + await next.stop() + await next.patchFile( + 'next.config.js', + curNextConfig.replace('fullUrl: true', 'fullUrl: false') + ) + await next.start() + }) + afterAll(async () => { + await next.patchFile('next.config.js', curNextConfig) + }) + + runTests({ withFetchesLogging: true, withFullUrlFetches: false }) }) describe('with verbose logging for edge runtime', () => { @@ -203,11 +232,18 @@ createNextDescribe( }) describe('with default logging', () => { + const curNextConfig = fs.readFileSync( + path.join(__dirname, 'next.config.js'), + { encoding: 'utf-8' } + ) beforeAll(async () => { await next.stop() await next.deleteFile('next.config.js') await next.start() }) + afterAll(async () => { + await next.patchFile('next.config.js', curNextConfig) + }) runTests({ withFetchesLogging: false }) }) From 37c6a10a8917d3bc1389ff6c2a6b3b06fe58e8b5 Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Thu, 7 Dec 2023 19:57:49 +0000 Subject: [PATCH 209/481] v14.0.4-canary.48 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 16 ++++++++-------- 18 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lerna.json b/lerna.json index 04712bf98e4b3..d0e046e2789e8 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.47" + "version": "14.0.4-canary.48" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 57d95edd97fa2..5a46ca9dcd767 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.47", + "version": "14.0.4-canary.48", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index b90277ff5b670..de6bd4305a3cc 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.47", + "version": "14.0.4-canary.48", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.47", + "@next/eslint-plugin-next": "14.0.4-canary.48", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index 3de9b1693de6a..ec4f430985b29 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.47", + "version": "14.0.4-canary.48", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index bef4c19bfa7a4..4fc61eed715a4 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.47", + "version": "14.0.4-canary.48", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index 7335c1d9d665b..fd6d34b8a5f5d 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.47", + "version": "14.0.4-canary.48", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 45f369091eaab..f30a2f9539b14 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.47", + "version": "14.0.4-canary.48", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 0ee1119ad209f..0b4921c0593a3 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.47", + "version": "14.0.4-canary.48", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 184d70453b097..05856f3a96110 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.47", + "version": "14.0.4-canary.48", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 80f95a60164a3..9592a88613a53 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.47", + "version": "14.0.4-canary.48", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index 6f53706a44450..841eb8194241b 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.47", + "version": "14.0.4-canary.48", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index 28daf434c3553..e406b5bd50df1 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.47", + "version": "14.0.4-canary.48", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index 147ed79dacda2..bd4e5c6a77be4 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.47", + "version": "14.0.4-canary.48", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index 8d1a5597d86db..d7d155c14938b 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.47", + "version": "14.0.4-canary.48", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.47", + "@next/env": "14.0.4-canary.48", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -147,11 +147,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.47", - "@next/polyfill-nomodule": "14.0.4-canary.47", - "@next/react-dev-overlay": "14.0.4-canary.47", - "@next/react-refresh-utils": "14.0.4-canary.47", - "@next/swc": "14.0.4-canary.47", + "@next/polyfill-module": "14.0.4-canary.48", + "@next/polyfill-nomodule": "14.0.4-canary.48", + "@next/react-dev-overlay": "14.0.4-canary.48", + "@next/react-refresh-utils": "14.0.4-canary.48", + "@next/swc": "14.0.4-canary.48", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index 954768e6dc427..9a11469464673 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.47", + "version": "14.0.4-canary.48", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index 7319b304816be..5ce9dcc126954 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.47", + "version": "14.0.4-canary.48", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index 5c0e890d5a9d3..a0e3f00d4998f 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.47", + "version": "14.0.4-canary.48", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -25,7 +25,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.47", + "next": "14.0.4-canary.48", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index bccb753d7e5f5..688392c9b3b61 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -741,7 +741,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.47 + specifier: 14.0.4-canary.48 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -806,7 +806,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.47 + specifier: 14.0.4-canary.48 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -933,19 +933,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.47 + specifier: 14.0.4-canary.48 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.47 + specifier: 14.0.4-canary.48 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.47 + specifier: 14.0.4-canary.48 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.47 + specifier: 14.0.4-canary.48 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.47 + specifier: 14.0.4-canary.48 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1599,7 +1599,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.47 + specifier: 14.0.4-canary.48 version: link:../next outdent: specifier: 0.8.0 From aa08c49d7269d3f7c3ed96b77068d1690eea3587 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Thu, 7 Dec 2023 21:02:52 +0100 Subject: [PATCH 210/481] rm console.log (#59381) --- packages/next/src/build/output/store.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/next/src/build/output/store.ts b/packages/next/src/build/output/store.ts index 3b25d0557f463..5ad6197f82244 100644 --- a/packages/next/src/build/output/store.ts +++ b/packages/next/src/build/output/store.ts @@ -81,7 +81,6 @@ store.subscribe((state) => { if (state.loading) { if (state.trigger) { trigger = formatTrigger(state.trigger) - console.log('trigger', trigger) triggerUrl = state.url if (trigger !== 'initial') { traceSpan = trace('compile-path', undefined, { From 77dc763807c31a52278db95a8b71e989d467d95f Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Thu, 7 Dec 2023 20:06:40 +0000 Subject: [PATCH 211/481] v14.0.4-canary.49 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 16 ++++++++-------- 18 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lerna.json b/lerna.json index d0e046e2789e8..05e774c5e2575 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.48" + "version": "14.0.4-canary.49" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index 5a46ca9dcd767..ef49283b512d3 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.48", + "version": "14.0.4-canary.49", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index de6bd4305a3cc..e5f722fc939b2 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.48", + "version": "14.0.4-canary.49", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.48", + "@next/eslint-plugin-next": "14.0.4-canary.49", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index ec4f430985b29..af7079e91ad89 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.48", + "version": "14.0.4-canary.49", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index 4fc61eed715a4..4d9c18db28ba4 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.48", + "version": "14.0.4-canary.49", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index fd6d34b8a5f5d..c3a20553d9f2b 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.48", + "version": "14.0.4-canary.49", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index f30a2f9539b14..2bb172894b0d1 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.48", + "version": "14.0.4-canary.49", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index 0b4921c0593a3..d6f21c9518db9 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.48", + "version": "14.0.4-canary.49", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 05856f3a96110..69dd792eb7930 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.48", + "version": "14.0.4-canary.49", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 9592a88613a53..0c9af6950b4ad 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.48", + "version": "14.0.4-canary.49", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index 841eb8194241b..32f28d21f2f9b 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.48", + "version": "14.0.4-canary.49", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index e406b5bd50df1..fbf696b7596bc 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.48", + "version": "14.0.4-canary.49", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index bd4e5c6a77be4..44c5eb2c19339 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.48", + "version": "14.0.4-canary.49", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index d7d155c14938b..92f0f315ff7be 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.48", + "version": "14.0.4-canary.49", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.48", + "@next/env": "14.0.4-canary.49", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -147,11 +147,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.48", - "@next/polyfill-nomodule": "14.0.4-canary.48", - "@next/react-dev-overlay": "14.0.4-canary.48", - "@next/react-refresh-utils": "14.0.4-canary.48", - "@next/swc": "14.0.4-canary.48", + "@next/polyfill-module": "14.0.4-canary.49", + "@next/polyfill-nomodule": "14.0.4-canary.49", + "@next/react-dev-overlay": "14.0.4-canary.49", + "@next/react-refresh-utils": "14.0.4-canary.49", + "@next/swc": "14.0.4-canary.49", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index 9a11469464673..b300d98b6c85b 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.48", + "version": "14.0.4-canary.49", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index 5ce9dcc126954..888afb2301038 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.48", + "version": "14.0.4-canary.49", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index a0e3f00d4998f..94878f173605c 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.48", + "version": "14.0.4-canary.49", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -25,7 +25,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.48", + "next": "14.0.4-canary.49", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 688392c9b3b61..219b8eefaa9ce 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -741,7 +741,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.48 + specifier: 14.0.4-canary.49 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -806,7 +806,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.48 + specifier: 14.0.4-canary.49 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -933,19 +933,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.48 + specifier: 14.0.4-canary.49 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.48 + specifier: 14.0.4-canary.49 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.48 + specifier: 14.0.4-canary.49 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.48 + specifier: 14.0.4-canary.49 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.48 + specifier: 14.0.4-canary.49 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1599,7 +1599,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.48 + specifier: 14.0.4-canary.49 version: link:../next outdent: specifier: 0.8.0 From eaa0e7c1ba28c516aa1397f69187f719db763bb0 Mon Sep 17 00:00:00 2001 From: Jiachi Liu Date: Thu, 7 Dec 2023 22:08:02 +0100 Subject: [PATCH 212/481] Skip latest commit check for stable release (#59383) --- .github/workflows/trigger_release.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/trigger_release.yml b/.github/workflows/trigger_release.yml index 286b896da6ff6..6b7acd05f8c3f 100644 --- a/.github/workflows/trigger_release.yml +++ b/.github/workflows/trigger_release.yml @@ -54,15 +54,15 @@ jobs: - name: Get commit of the latest tag run: echo "LATEST_TAG_COMMIT=$(git rev-list -n 1 $(git describe --tags --abbrev=0))" >> $GITHUB_ENV - - name: Get latest commit - run: echo "LATEST_COMMIT=$(git rev-parse HEAD)" >> $GITHUB_ENV - - - name: Check if new commits since last tag - run: | - if [ "$LATEST_TAG_COMMIT" = "$LATEST_COMMIT" ]; then - echo "No new commits. Exiting..." - exit 1 - fi + # - name: Get latest commit + # run: echo "LATEST_COMMIT=$(git rev-parse HEAD)" >> $GITHUB_ENV + + # - name: Check if new commits since last tag + # run: | + # if [ "$LATEST_TAG_COMMIT" = "$LATEST_COMMIT" ]; then + # echo "No new commits. Exiting..." + # exit 1 + # fi # https://github.com/actions/virtual-environments/issues/1187 - name: tune linux network From c9f859e6bea4a547d3946e99c5242bb419155598 Mon Sep 17 00:00:00 2001 From: vercel-release-bot Date: Thu, 7 Dec 2023 21:11:20 +0000 Subject: [PATCH 213/481] v14.0.4 --- lerna.json | 2 +- packages/create-next-app/package.json | 2 +- packages/eslint-config-next/package.json | 4 ++-- packages/eslint-plugin-next/package.json | 2 +- packages/font/package.json | 2 +- packages/next-bundle-analyzer/package.json | 2 +- packages/next-codemod/package.json | 2 +- packages/next-env/package.json | 2 +- packages/next-mdx/package.json | 2 +- packages/next-plugin-storybook/package.json | 2 +- packages/next-polyfill-module/package.json | 2 +- packages/next-polyfill-nomodule/package.json | 2 +- packages/next-swc/package.json | 2 +- packages/next/package.json | 14 +++++++------- packages/react-dev-overlay/package.json | 2 +- packages/react-refresh-utils/package.json | 2 +- packages/third-parties/package.json | 4 ++-- pnpm-lock.yaml | 16 ++++++++-------- 18 files changed, 33 insertions(+), 33 deletions(-) diff --git a/lerna.json b/lerna.json index 05e774c5e2575..bcfd879b680d6 100644 --- a/lerna.json +++ b/lerna.json @@ -16,5 +16,5 @@ "registry": "https://registry.npmjs.org/" } }, - "version": "14.0.4-canary.49" + "version": "14.0.4" } diff --git a/packages/create-next-app/package.json b/packages/create-next-app/package.json index ef49283b512d3..1be5d6cc21dae 100644 --- a/packages/create-next-app/package.json +++ b/packages/create-next-app/package.json @@ -1,6 +1,6 @@ { "name": "create-next-app", - "version": "14.0.4-canary.49", + "version": "14.0.4", "keywords": [ "react", "next", diff --git a/packages/eslint-config-next/package.json b/packages/eslint-config-next/package.json index e5f722fc939b2..d45d18c998afa 100644 --- a/packages/eslint-config-next/package.json +++ b/packages/eslint-config-next/package.json @@ -1,6 +1,6 @@ { "name": "eslint-config-next", - "version": "14.0.4-canary.49", + "version": "14.0.4", "description": "ESLint configuration used by Next.js.", "main": "index.js", "license": "MIT", @@ -10,7 +10,7 @@ }, "homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config", "dependencies": { - "@next/eslint-plugin-next": "14.0.4-canary.49", + "@next/eslint-plugin-next": "14.0.4", "@rushstack/eslint-patch": "^1.3.3", "@typescript-eslint/parser": "^5.4.2 || ^6.0.0", "eslint-import-resolver-node": "^0.3.6", diff --git a/packages/eslint-plugin-next/package.json b/packages/eslint-plugin-next/package.json index af7079e91ad89..d14085eb250c2 100644 --- a/packages/eslint-plugin-next/package.json +++ b/packages/eslint-plugin-next/package.json @@ -1,6 +1,6 @@ { "name": "@next/eslint-plugin-next", - "version": "14.0.4-canary.49", + "version": "14.0.4", "description": "ESLint plugin for Next.js.", "main": "dist/index.js", "license": "MIT", diff --git a/packages/font/package.json b/packages/font/package.json index 4d9c18db28ba4..c5b24cca4d985 100644 --- a/packages/font/package.json +++ b/packages/font/package.json @@ -1,6 +1,6 @@ { "name": "@next/font", - "version": "14.0.4-canary.49", + "version": "14.0.4", "repository": { "url": "vercel/next.js", "directory": "packages/font" diff --git a/packages/next-bundle-analyzer/package.json b/packages/next-bundle-analyzer/package.json index c3a20553d9f2b..2790b971a7480 100644 --- a/packages/next-bundle-analyzer/package.json +++ b/packages/next-bundle-analyzer/package.json @@ -1,6 +1,6 @@ { "name": "@next/bundle-analyzer", - "version": "14.0.4-canary.49", + "version": "14.0.4", "main": "index.js", "types": "index.d.ts", "license": "MIT", diff --git a/packages/next-codemod/package.json b/packages/next-codemod/package.json index 2bb172894b0d1..0f1d6e94ff7e0 100644 --- a/packages/next-codemod/package.json +++ b/packages/next-codemod/package.json @@ -1,6 +1,6 @@ { "name": "@next/codemod", - "version": "14.0.4-canary.49", + "version": "14.0.4", "license": "MIT", "repository": { "type": "git", diff --git a/packages/next-env/package.json b/packages/next-env/package.json index d6f21c9518db9..910a8841f6afc 100644 --- a/packages/next-env/package.json +++ b/packages/next-env/package.json @@ -1,6 +1,6 @@ { "name": "@next/env", - "version": "14.0.4-canary.49", + "version": "14.0.4", "keywords": [ "react", "next", diff --git a/packages/next-mdx/package.json b/packages/next-mdx/package.json index 69dd792eb7930..f64e4917cd127 100644 --- a/packages/next-mdx/package.json +++ b/packages/next-mdx/package.json @@ -1,6 +1,6 @@ { "name": "@next/mdx", - "version": "14.0.4-canary.49", + "version": "14.0.4", "main": "index.js", "license": "MIT", "repository": { diff --git a/packages/next-plugin-storybook/package.json b/packages/next-plugin-storybook/package.json index 0c9af6950b4ad..f175347080ced 100644 --- a/packages/next-plugin-storybook/package.json +++ b/packages/next-plugin-storybook/package.json @@ -1,6 +1,6 @@ { "name": "@next/plugin-storybook", - "version": "14.0.4-canary.49", + "version": "14.0.4", "repository": { "url": "vercel/next.js", "directory": "packages/next-plugin-storybook" diff --git a/packages/next-polyfill-module/package.json b/packages/next-polyfill-module/package.json index 32f28d21f2f9b..637795a23ead6 100644 --- a/packages/next-polyfill-module/package.json +++ b/packages/next-polyfill-module/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-module", - "version": "14.0.4-canary.49", + "version": "14.0.4", "description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)", "main": "dist/polyfill-module.js", "license": "MIT", diff --git a/packages/next-polyfill-nomodule/package.json b/packages/next-polyfill-nomodule/package.json index fbf696b7596bc..146e9a0396fd3 100644 --- a/packages/next-polyfill-nomodule/package.json +++ b/packages/next-polyfill-nomodule/package.json @@ -1,6 +1,6 @@ { "name": "@next/polyfill-nomodule", - "version": "14.0.4-canary.49", + "version": "14.0.4", "description": "A polyfill for non-dead, nomodule browsers.", "main": "dist/polyfill-nomodule.js", "license": "MIT", diff --git a/packages/next-swc/package.json b/packages/next-swc/package.json index 44c5eb2c19339..300f2528fb909 100644 --- a/packages/next-swc/package.json +++ b/packages/next-swc/package.json @@ -1,6 +1,6 @@ { "name": "@next/swc", - "version": "14.0.4-canary.49", + "version": "14.0.4", "private": true, "scripts": { "clean": "node ../../scripts/rm.mjs native", diff --git a/packages/next/package.json b/packages/next/package.json index 92f0f315ff7be..f2f69d0a5c38a 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -1,6 +1,6 @@ { "name": "next", - "version": "14.0.4-canary.49", + "version": "14.0.4", "description": "The React Framework", "main": "./dist/server/next.js", "license": "MIT", @@ -92,7 +92,7 @@ ] }, "dependencies": { - "@next/env": "14.0.4-canary.49", + "@next/env": "14.0.4", "@swc/helpers": "0.5.2", "busboy": "1.6.0", "caniuse-lite": "^1.0.30001406", @@ -147,11 +147,11 @@ "@mswjs/interceptors": "0.23.0", "@napi-rs/cli": "2.16.2", "@napi-rs/triples": "1.1.0", - "@next/polyfill-module": "14.0.4-canary.49", - "@next/polyfill-nomodule": "14.0.4-canary.49", - "@next/react-dev-overlay": "14.0.4-canary.49", - "@next/react-refresh-utils": "14.0.4-canary.49", - "@next/swc": "14.0.4-canary.49", + "@next/polyfill-module": "14.0.4", + "@next/polyfill-nomodule": "14.0.4", + "@next/react-dev-overlay": "14.0.4", + "@next/react-refresh-utils": "14.0.4", + "@next/swc": "14.0.4", "@opentelemetry/api": "1.6.0", "@playwright/test": "^1.35.1", "@taskr/clear": "1.1.0", diff --git a/packages/react-dev-overlay/package.json b/packages/react-dev-overlay/package.json index b300d98b6c85b..f4acdb2db16f1 100644 --- a/packages/react-dev-overlay/package.json +++ b/packages/react-dev-overlay/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-dev-overlay", - "version": "14.0.4-canary.49", + "version": "14.0.4", "description": "A development-only overlay for developing React applications.", "repository": { "url": "vercel/next.js", diff --git a/packages/react-refresh-utils/package.json b/packages/react-refresh-utils/package.json index 888afb2301038..2bce118fb87a5 100644 --- a/packages/react-refresh-utils/package.json +++ b/packages/react-refresh-utils/package.json @@ -1,6 +1,6 @@ { "name": "@next/react-refresh-utils", - "version": "14.0.4-canary.49", + "version": "14.0.4", "description": "An experimental package providing utilities for React Refresh.", "repository": { "url": "vercel/next.js", diff --git a/packages/third-parties/package.json b/packages/third-parties/package.json index 94878f173605c..e30fb7d7ce72d 100644 --- a/packages/third-parties/package.json +++ b/packages/third-parties/package.json @@ -1,6 +1,6 @@ { "name": "@next/third-parties", - "version": "14.0.4-canary.49", + "version": "14.0.4", "repository": { "url": "vercel/next.js", "directory": "packages/third-parties" @@ -25,7 +25,7 @@ "third-party-capital": "1.0.20" }, "devDependencies": { - "next": "14.0.4-canary.49", + "next": "14.0.4", "outdent": "0.8.0", "prettier": "2.5.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 219b8eefaa9ce..e0a2b9ee25deb 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -741,7 +741,7 @@ importers: packages/eslint-config-next: dependencies: '@next/eslint-plugin-next': - specifier: 14.0.4-canary.49 + specifier: 14.0.4 version: link:../eslint-plugin-next '@rushstack/eslint-patch': specifier: ^1.3.3 @@ -806,7 +806,7 @@ importers: packages/next: dependencies: '@next/env': - specifier: 14.0.4-canary.49 + specifier: 14.0.4 version: link:../next-env '@swc/helpers': specifier: 0.5.2 @@ -933,19 +933,19 @@ importers: specifier: 1.1.0 version: 1.1.0 '@next/polyfill-module': - specifier: 14.0.4-canary.49 + specifier: 14.0.4 version: link:../next-polyfill-module '@next/polyfill-nomodule': - specifier: 14.0.4-canary.49 + specifier: 14.0.4 version: link:../next-polyfill-nomodule '@next/react-dev-overlay': - specifier: 14.0.4-canary.49 + specifier: 14.0.4 version: link:../react-dev-overlay '@next/react-refresh-utils': - specifier: 14.0.4-canary.49 + specifier: 14.0.4 version: link:../react-refresh-utils '@next/swc': - specifier: 14.0.4-canary.49 + specifier: 14.0.4 version: link:../next-swc '@opentelemetry/api': specifier: 1.6.0 @@ -1599,7 +1599,7 @@ importers: version: 1.0.20 devDependencies: next: - specifier: 14.0.4-canary.49 + specifier: 14.0.4 version: link:../next outdent: specifier: 0.8.0 From d5836a30384695e46437a455aaab8e45d1f60765 Mon Sep 17 00:00:00 2001 From: Delba de Oliveira <32464864+delbaoliveira@users.noreply.github.com> Date: Thu, 7 Dec 2023 21:12:25 +0000 Subject: [PATCH 214/481] Docs: Update Server Actions Docs (#59080) - [x] Rename page from `forms-and-mutations` to `server-actions-and-mutations` to account for examples that don't use forms. - [x] Split `/pages` and `/app` content to make easier to edit - [x] Add Security Section - [x] Recommend tainting - [x] Closures and encryption - [x] Overwriting encryption keys - [x] CSRF protection | Allowed Origins - [x] Add examples for Server Actions being called outside forms - [x] `useEffect` - [x] Event handlers - [ ] ~3rd party libraries~ - [x] More form examples - [x] Add note on calling actions in ` + + ) +} +``` + +`updateUser` Server Action will always receive the `userId` argument, in addition to the form data: + +```js filename="app/actions.js" +'use server' + +export async function updateUser(userId, formData) { + // ... +} +``` + +> **Good to know**: +> +> - An alternative is to pass arguments as hidden input fields in the form (e.g. ``). However, the value will be part of the rendered HTML and will not be encoded. +> - `.bind` of a Server Action works in both Server and Client Components. It also supports progressive enhancement. + +#### Pending states + +You can use the React [`useFormStatus`](https://react.dev/reference/react-dom/hooks/useFormStatus) hook to show a pending state while the form is being submitted. + +- `useFormStatus` returns the status for a specific `
`, so it **must be defined as a child of the `` element**. +- `useFormStatus` is a React hook and therefore must be used in a Client Component. + +```tsx filename="app/submit-button.tsx" switcher +'use client' + +import { useFormStatus } from 'react-dom' + +export function SubmitButton() { + const { pending } = useFormStatus() + + return ( + + ) +} +``` + +```jsx filename="app/submit-button.jsx" switcher +'use client' + +import { useFormStatus } from 'react-dom' + +export function SubmitButton() { + const { pending } = useFormStatus() + + return ( + + ) +} +``` + +`` can then be nested in any form: + +```tsx filename="app/page.tsx" switcher +import { SubmitButton } from '@/app/submit-button' +import { createItem } from '@/app/actions' + +export default async function Home() { + return ( + + + + + ) +} +``` + +```jsx filename="app/page.jsx" switcher +import { SubmitButton } from '@/app/submit-button' +import { createItem } from '@/app/actions' + +export default async function Home() { + return ( +
+ + + + ) +} +``` + +#### Server-side validation and error handling + +We recommend using HTML validation like `required` and `type="email"` for basic client-side validation. + +For more advanced server-side validation, you can use a library like [zod](https://zod.dev/) to validate the form fields before mutating the data: + +```tsx filename="app/actions.ts" switcher +'use server' + +import { z } from 'zod' + +const schema = z.object({ + email: z.string({ + invalid_type_error: 'Invalid Email', + }), +}) + +export default async function createUser(formData: FormData) { + const validatedFields = schema.safeParse({ + email: formData.get('email'), + }) + + // Return early if the form data is invalid + if (!validatedFields.success) { + return { + errors: validatedFields.error.flatten().fieldErrors, + } + } + + // Mutate data +} +``` + +```jsx filename="app/actions.js" switcher +'use server' + +import { z } from 'zod' + +const schema = z.object({ + email: z.string({ + invalid_type_error: 'Invalid Email', + }), +}) + +export default async function createsUser(formData) { + const validatedFields = schema.safeParse({ + email: formData.get('email'), + }) + + // Return early if the form data is invalid + if (!validatedFields.success) { + return { + errors: validatedFields.error.flatten().fieldErrors, + } + } + + // Mutate data +} +``` + +> **Good to know:** +> +> - Before mutating data, you should always ensure a user is also authorized to perform the action. See [Authentication and Authorization](#authentication-and-authorization). +> - Refer to the [Zod documentation](https://zod.dev/) for more information. + +Once the fields have been validated on the server, you can return a serializable object in your action and use the React [`useFormState`](https://react.dev/reference/react-dom/hooks/useFormState) hook to show a message to the user. + +- By passing the action to `useFormState`, the action's function signature changes to receive a new `prevState` or `initialState` parameter as its first argument. +- `useFormState` is a React hook and therefore must be used in a Client Component. + +```tsx filename="app/actions.ts" switcher +'use server' + +export async function createUser(prevState: any, formData: FormData) { + // ... + return { + message: 'Please enter a valid email', + } +} +``` + +```jsx filename="app/actions.js" switcher +'use server' + +export async function createUser(prevState, formData) { + // ... + return { + message: 'Please enter a valid email', + } +} +``` + +Then, you can pass your action to the `useFormState` hook and use the returned `state` to display an error message. + +```tsx filename="app/ui/signup.tsx" switcher +'use client' + +import { useFormState } from 'react-dom' +import { createUser } from '@/app/actions' + +const initialState = { + message: null, +} + +export function Signup() { + const [state, formAction] = useFormState(createUser, initialState) + + return ( +
+ + + {/* ... */} +

+ {state?.message} +

+ +
+ ) +} +``` + +```jsx filename="app/ui/signup.js" switcher +'use client' + +import { useFormState } from 'react-dom' +import { createUser } from '@/app/actions' + +const initialState = { + message: null, +} + +export function Signup() { + const [state, formAction] = useFormState(createUser, initialState) + + return ( +
+ + + {/* ... */} +

+ {state?.message} +

+ +
+ ) +} +``` + +#### Optimistic updates + +You can use the React [`useOptimistic`](https://react.dev/reference/react/useOptimistic) hook to optimistically update the UI before the Server Action finishes, rather than waiting for the response: + +```tsx filename="app/page.tsx" switcher +'use client' + +import { useOptimistic } from 'react' +import { send } from './actions' + +type Message = { + message: string +} + +export function Thread({ messages }: { messages: Message[] }) { + const [optimisticMessages, addOptimisticMessage] = useOptimistic( + messages, + (state: Message[], newMessage: string) => [ + ...state, + { message: newMessage }, + ] + ) + + return ( +
+ {optimisticMessages.map((m, k) => ( +
{m.message}
+ ))} +
{ + const message = formData.get('message') + addOptimisticMessage(message) + await send(message) + }} + > + + +
+
+ ) +} +``` + +```jsx filename="app/page.jsx" switcher +'use client' + +import { useOptimistic } from 'react' +import { send } from './actions' + +export function Thread({ messages }) { + const [optimisticMessages, addOptimisticMessage] = useOptimistic( + messages, + (state, newMessage) => [...state, { message: newMessage }] + ) + + return ( +
+ {optimisticMessages.map((m) => ( +
{m.message}
+ ))} +
{ + const message = formData.get('message') + addOptimisticMessage(message) + await send(message) + }} + > + + +
+
+ ) +} +``` + +#### ` + + ) +} +``` + +To improve the user experience, we recommend using other React APIs like [`useOptimistic`](https://react.dev/reference/react/useOptimistic) and [`useTransition`](https://react.dev/reference/react/useTransition) to update the UI before the Server Action finishes executing on the server, or to show a pending state. + +You can also add event handlers to form elements, for example, to save a form field `onChange`: + +```tsx filename="app/ui/edit-post.tsx" +'use client' + +import { publishPost, saveDraft } from './actions' + +export default function EditPost() { + return ( + +