From 43d896a3ffa137584398b411b31f8bc0f01671d9 Mon Sep 17 00:00:00 2001 From: Shu Ding Date: Wed, 14 Feb 2024 14:28:46 +0100 Subject: [PATCH] support nested action definitions in file level --- .../src/transforms/server_actions.rs | 9 ++-- .../fixture/server-actions/client/5/input.js | 26 +++++++++++ .../fixture/server-actions/client/5/output.js | 2 + .../fixture/server-actions/server/30/input.js | 26 +++++++++++ .../server-actions/server/30/output.js | 46 +++++++++++++++++++ .../fixture/server-actions/server/4/output.js | 5 +- 6 files changed, 109 insertions(+), 5 deletions(-) create mode 100644 packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/client/5/input.js create mode 100644 packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/client/5/output.js create mode 100644 packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/server/30/input.js create mode 100644 packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/server/30/output.js diff --git a/packages/next-swc/crates/next-custom-transforms/src/transforms/server_actions.rs b/packages/next-swc/crates/next-custom-transforms/src/transforms/server_actions.rs index db960d912e2c5..d3521e6fa04b3 100644 --- a/packages/next-swc/crates/next-custom-transforms/src/transforms/server_actions.rs +++ b/packages/next-swc/crates/next-custom-transforms/src/transforms/server_actions.rs @@ -132,7 +132,7 @@ impl ServerActions { self.config.enabled, ); - if is_action_fn && !self.config.is_react_server_layer { + if is_action_fn && !self.config.is_react_server_layer && !self.in_action_file { HANDLER.with(|handler| { handler .struct_span_err( @@ -459,7 +459,8 @@ impl VisitMut for ServerActions { }); } - if !self.in_action_file { + if !(self.in_action_file && self.in_export_decl) { + // It's an action function. If it doesn't have a name, give it one. match f.ident.as_mut() { None => { let action_name = gen_ident(&mut self.action_cnt); @@ -541,7 +542,7 @@ impl VisitMut for ServerActions { }); } - if !self.in_action_file { + if !(self.in_action_file && self.in_export_decl) { // Collect all the identifiers defined inside the closure and used // in the action function. With deduplication. retain_names_from_declared_idents(&mut child_names, ¤t_declared_idents); @@ -1024,6 +1025,8 @@ impl VisitMut for ServerActions { if self.has_action { let mut actions = self.export_actions.clone(); + + // All exported values are considered as actions if the file is an action file. if self.in_action_file { actions.extend(self.exported_idents.iter().map(|e| e.1.clone())); }; diff --git a/packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/client/5/input.js b/packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/client/5/input.js new file mode 100644 index 0000000000000..e1b3b4b5162e1 --- /dev/null +++ b/packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/client/5/input.js @@ -0,0 +1,26 @@ +'use server' + +let a, f + +export async function action0(b, c, ...g) { + return async function action1(d) { + 'use server' + let f + console.log(...window, { window }) + console.log(a, b, action2) + + async function action2(e) { + 'use server' + console.log(a, c, d, e, f, g) + } + + return [ + action2, + async function action3(e) { + 'use server' + action2(e) + console.log(a, c, d, e) + }, + ] + } +} diff --git a/packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/client/5/output.js b/packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/client/5/output.js new file mode 100644 index 0000000000000..9ec2f8eb26a0b --- /dev/null +++ b/packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/client/5/output.js @@ -0,0 +1,2 @@ +/* __next_internal_action_entry_do_not_use__ {"0090eaf4e1f08a2d94f6be401e54a2ded399b87c":"action0","188d5d945750dc32e2c842b93c75a65763d4a922":"$$ACTION_1","6d53ce510b2e36499b8f56038817b9bad86cabb4":"$$ACTION_0","9878bfa39811ca7650992850a8751f9591b6a557":"$$ACTION_2"} */ export var action0 = createServerReference("0090eaf4e1f08a2d94f6be401e54a2ded399b87c"); +import { createServerReference } from "private-next-rsc-action-client-wrapper"; diff --git a/packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/server/30/input.js b/packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/server/30/input.js new file mode 100644 index 0000000000000..e1b3b4b5162e1 --- /dev/null +++ b/packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/server/30/input.js @@ -0,0 +1,26 @@ +'use server' + +let a, f + +export async function action0(b, c, ...g) { + return async function action1(d) { + 'use server' + let f + console.log(...window, { window }) + console.log(a, b, action2) + + async function action2(e) { + 'use server' + console.log(a, c, d, e, f, g) + } + + return [ + action2, + async function action3(e) { + 'use server' + action2(e) + console.log(a, c, d, e) + }, + ] + } +} diff --git a/packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/server/30/output.js b/packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/server/30/output.js new file mode 100644 index 0000000000000..00a9da2312c07 --- /dev/null +++ b/packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/server/30/output.js @@ -0,0 +1,46 @@ +/* __next_internal_action_entry_do_not_use__ {"0090eaf4e1f08a2d94f6be401e54a2ded399b87c":"action0","188d5d945750dc32e2c842b93c75a65763d4a922":"$$ACTION_1","6d53ce510b2e36499b8f56038817b9bad86cabb4":"$$ACTION_0","9878bfa39811ca7650992850a8751f9591b6a557":"$$ACTION_2"} */ import { createActionProxy } from "private-next-rsc-action-proxy"; +import { encryptActionBoundArgs, decryptActionBoundArgs } from "private-next-rsc-action-encryption"; +let a, f; +export async function action0(b, c, ...g) { + return createActionProxy("9878bfa39811ca7650992850a8751f9591b6a557", $$ACTION_2).bind(null, encryptActionBoundArgs("9878bfa39811ca7650992850a8751f9591b6a557", [ + c, + g, + b + ])); +} +export async function $$ACTION_0($$ACTION_CLOSURE_BOUND, e) { + var [$$ACTION_ARG_0, $$ACTION_ARG_1, $$ACTION_ARG_2, $$ACTION_ARG_3] = await decryptActionBoundArgs("6d53ce510b2e36499b8f56038817b9bad86cabb4", $$ACTION_CLOSURE_BOUND); + console.log(a, $$ACTION_ARG_0, $$ACTION_ARG_1, e, $$ACTION_ARG_2, $$ACTION_ARG_3); +} +export async function $$ACTION_1($$ACTION_CLOSURE_BOUND, e) { + var [$$ACTION_ARG_0, $$ACTION_ARG_1, $$ACTION_ARG_2] = await decryptActionBoundArgs("188d5d945750dc32e2c842b93c75a65763d4a922", $$ACTION_CLOSURE_BOUND); + $$ACTION_ARG_0(e); + console.log(a, $$ACTION_ARG_1, $$ACTION_ARG_2, e); +} +export async function $$ACTION_2($$ACTION_CLOSURE_BOUND, d) { + var [$$ACTION_ARG_0, $$ACTION_ARG_1, $$ACTION_ARG_2] = await decryptActionBoundArgs("9878bfa39811ca7650992850a8751f9591b6a557", $$ACTION_CLOSURE_BOUND); + let f; + console.log(...window, { + window + }); + console.log(a, $$ACTION_ARG_2, action2); + var action2 = createActionProxy("6d53ce510b2e36499b8f56038817b9bad86cabb4", $$ACTION_0).bind(null, encryptActionBoundArgs("6d53ce510b2e36499b8f56038817b9bad86cabb4", [ + $$ACTION_ARG_0, + d, + f, + $$ACTION_ARG_1 + ])); + return [ + action2, + createActionProxy("188d5d945750dc32e2c842b93c75a65763d4a922", $$ACTION_1).bind(null, encryptActionBoundArgs("188d5d945750dc32e2c842b93c75a65763d4a922", [ + action2, + $$ACTION_ARG_0, + d + ])) + ]; +} +import { ensureServerEntryExports } from "private-next-rsc-action-validate"; +ensureServerEntryExports([ + action0 +]); +createActionProxy("0090eaf4e1f08a2d94f6be401e54a2ded399b87c", action0); diff --git a/packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/server/4/output.js b/packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/server/4/output.js index 06a5bfa7ac9a6..339f67e2eea29 100644 --- a/packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/server/4/output.js +++ b/packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/server/4/output.js @@ -1,12 +1,13 @@ -/* __next_internal_action_entry_do_not_use__ {"1ab723c80dcca470e0410b4b2a2fc2bf21f41476":"c","6e7bc104e4d6e7fda190c4a51be969cfd0be6d6d":"a","d1f7eb64271d7c601dfef7d4d7053de1c2ca4338":"b"} */ import { createActionProxy } from "private-next-rsc-action-proxy"; +/* __next_internal_action_entry_do_not_use__ {"1ab723c80dcca470e0410b4b2a2fc2bf21f41476":"c","6d53ce510b2e36499b8f56038817b9bad86cabb4":"$$ACTION_0","6e7bc104e4d6e7fda190c4a51be969cfd0be6d6d":"a","d1f7eb64271d7c601dfef7d4d7053de1c2ca4338":"b"} */ import { createActionProxy } from "private-next-rsc-action-proxy"; import { encryptActionBoundArgs, decryptActionBoundArgs } from "private-next-rsc-action-encryption"; export async function a() {} export async function b() {} export async function c() {} function d() {} function Foo() { - async function e() {} + var e = createActionProxy("6d53ce510b2e36499b8f56038817b9bad86cabb4", $$ACTION_0); } +export async function $$ACTION_0() {} import { ensureServerEntryExports } from "private-next-rsc-action-validate"; ensureServerEntryExports([ a,