From dff03dc6bb31ab672c1b1e520a0a2025741f3d86 Mon Sep 17 00:00:00 2001 From: Shu Ding Date: Fri, 26 Jan 2024 23:00:56 -0800 Subject: [PATCH 1/2] fix server action double registring --- .../src/transforms/server_actions.rs | 8 ++++---- .../fixture/server-actions/server/15/output.js | 2 +- .../fixture/server-actions/server/17/output.js | 2 +- .../fixture/server-actions/server/22/output.js | 2 +- .../fixture/server-actions/server/29/input.js | 8 ++++++++ .../fixture/server-actions/server/29/output.js | 15 +++++++++++++++ .../loaders/next-flight-loader/action-proxy.ts | 11 +++++++++++ test/e2e/app-dir/actions/app/server/actions.js | 8 +++++++- 8 files changed, 48 insertions(+), 8 deletions(-) create mode 100644 packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/server/29/input.js create mode 100644 packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/server/29/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 56ceb657b0f3f..41bacc208c6eb 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 @@ -1021,11 +1021,11 @@ impl VisitMut for ServerActions { } if self.has_action { - let actions = if self.in_action_file { - self.exported_idents.iter().map(|e| e.1.clone()).collect() - } else { - self.export_actions.clone() + let mut actions = self.export_actions.clone(); + if self.in_action_file { + actions.extend(self.exported_idents.iter().map(|e| e.1.clone())); }; + let actions = actions .into_iter() .map(|name| (generate_action_id(&self.file_name, &name), name)) diff --git a/packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/server/15/output.js b/packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/server/15/output.js index 3d6f28013d537..6f9c9865c243e 100644 --- a/packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/server/15/output.js +++ b/packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/server/15/output.js @@ -1,4 +1,4 @@ -/* __next_internal_action_entry_do_not_use__ {"c18c215a6b7cdc64bf709f3a714ffdef1bf9651d":"default"} */ import { createActionProxy } from "private-next-rsc-action-proxy"; +/* __next_internal_action_entry_do_not_use__ {"188d5d945750dc32e2c842b93c75a65763d4a922":"$$ACTION_1","c18c215a6b7cdc64bf709f3a714ffdef1bf9651d":"default"} */ import { createActionProxy } from "private-next-rsc-action-proxy"; import { encryptActionBoundArgs, decryptActionBoundArgs } from "private-next-rsc-action-encryption"; export default $$ACTION_0 = createActionProxy("188d5d945750dc32e2c842b93c75a65763d4a922", $$ACTION_1); var $$ACTION_0; diff --git a/packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/server/17/output.js b/packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/server/17/output.js index 6ed57d551917a..740fbdfab43fd 100644 --- a/packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/server/17/output.js +++ b/packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/server/17/output.js @@ -1,4 +1,4 @@ -/* __next_internal_action_entry_do_not_use__ {"ab21efdafbe611287bc25c0462b1e0510d13e48b":"foo","ac840dcaf5e8197cb02b7f3a43c119b7a770b272":"bar"} */ import { createActionProxy } from "private-next-rsc-action-proxy"; +/* __next_internal_action_entry_do_not_use__ {"6d53ce510b2e36499b8f56038817b9bad86cabb4":"$$ACTION_0","ab21efdafbe611287bc25c0462b1e0510d13e48b":"foo","ac840dcaf5e8197cb02b7f3a43c119b7a770b272":"bar"} */ import { createActionProxy } from "private-next-rsc-action-proxy"; import { encryptActionBoundArgs, decryptActionBoundArgs } from "private-next-rsc-action-encryption"; export const foo = createActionProxy("6d53ce510b2e36499b8f56038817b9bad86cabb4", $$ACTION_0); export async function $$ACTION_0() {} diff --git a/packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/server/22/output.js b/packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/server/22/output.js index 5d7eaff021748..084fe21f6f201 100644 --- a/packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/server/22/output.js +++ b/packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/server/22/output.js @@ -1,4 +1,4 @@ -/* __next_internal_action_entry_do_not_use__ {"c18c215a6b7cdc64bf709f3a714ffdef1bf9651d":"default","f14702b5a021dd117f7ec7a3c838f397c2046d3b":"action"} */ import { createActionProxy } from "private-next-rsc-action-proxy"; +/* __next_internal_action_entry_do_not_use__ {"6d53ce510b2e36499b8f56038817b9bad86cabb4":"$$ACTION_0","9878bfa39811ca7650992850a8751f9591b6a557":"$$ACTION_2","c18c215a6b7cdc64bf709f3a714ffdef1bf9651d":"default","f14702b5a021dd117f7ec7a3c838f397c2046d3b":"action"} */ import { createActionProxy } from "private-next-rsc-action-proxy"; import { encryptActionBoundArgs, decryptActionBoundArgs } from "private-next-rsc-action-encryption"; import { validator } from 'auth'; export const action = validator(createActionProxy("6d53ce510b2e36499b8f56038817b9bad86cabb4", $$ACTION_0)); diff --git a/packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/server/29/input.js b/packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/server/29/input.js new file mode 100644 index 0000000000000..42024ee44afbe --- /dev/null +++ b/packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/server/29/input.js @@ -0,0 +1,8 @@ +'use server' + +export const dec = async (value) => { + return value - 1 +} + +// Test case for https://github.com/vercel/next.js/issues/54655 +export default dec diff --git a/packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/server/29/output.js b/packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/server/29/output.js new file mode 100644 index 0000000000000..4addc633d84a5 --- /dev/null +++ b/packages/next-swc/crates/next-custom-transforms/tests/fixture/server-actions/server/29/output.js @@ -0,0 +1,15 @@ +/* __next_internal_action_entry_do_not_use__ {"28baf972d345b86b747ad0df73d75a0088a42214":"dec","6d53ce510b2e36499b8f56038817b9bad86cabb4":"$$ACTION_0","c18c215a6b7cdc64bf709f3a714ffdef1bf9651d":"default"} */ import { createActionProxy } from "private-next-rsc-action-proxy"; +import { encryptActionBoundArgs, decryptActionBoundArgs } from "private-next-rsc-action-encryption"; +export const dec = createActionProxy("6d53ce510b2e36499b8f56038817b9bad86cabb4", $$ACTION_0); +export async function $$ACTION_0(value) { + return value - 1; +} +// Test case for https://github.com/vercel/next.js/issues/54655 +export default dec; +import { ensureServerEntryExports } from "private-next-rsc-action-validate"; +ensureServerEntryExports([ + dec, + dec +]); +createActionProxy("28baf972d345b86b747ad0df73d75a0088a42214", dec); +createActionProxy("c18c215a6b7cdc64bf709f3a714ffdef1bf9651d", dec); \ No newline at end of file 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 0975e2fcc7080..9e442cfa4effc 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,6 +1,17 @@ /* eslint-disable import/no-extraneous-dependencies */ import { registerServerReference } from 'react-server-dom-webpack/server.edge' +const SERVER_REFERENCE_TAG = Symbol.for('react.server.reference') + +function isServerReference(reference: any) { + return reference && reference.$$typeof === SERVER_REFERENCE_TAG +} + export function createActionProxy(id: string, action: any) { + // Avoid registering the same action twice + if (isServerReference(action)) { + return action + } + return registerServerReference(action, id, null) } diff --git a/test/e2e/app-dir/actions/app/server/actions.js b/test/e2e/app-dir/actions/app/server/actions.js index f6f54112a944d..4b350ab41eebd 100644 --- a/test/e2e/app-dir/actions/app/server/actions.js +++ b/test/e2e/app-dir/actions/app/server/actions.js @@ -7,10 +7,13 @@ export async function slowInc(value) { return value + 1 } -export default async function dec(value) { +export const dec = async (value) => { return value - 1 } +// Test case for https://github.com/vercel/next.js/issues/54655 +export default dec + export async function redirectAction(formData) { 'use server' redirect( @@ -20,3 +23,6 @@ export async function redirectAction(formData) { formData.get('hidden-info') ) } + +// Test case for https://github.com/vercel/next.js/issues/61183 +export const dummyServerAction = () => new Promise((r) => setTimeout(r, 2000)) From dc0a99f5dfd5b1b933b51c2fc4a8bc43fd99e589 Mon Sep 17 00:00:00 2001 From: Shu Ding Date: Fri, 26 Jan 2024 23:30:32 -0800 Subject: [PATCH 2/2] fix update test --- .../tests/errors/server-actions/server-graph/6/output.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/next-swc/crates/next-custom-transforms/tests/errors/server-actions/server-graph/6/output.js b/packages/next-swc/crates/next-custom-transforms/tests/errors/server-actions/server-graph/6/output.js index 0e36704ddd70f..3b12261603df4 100644 --- a/packages/next-swc/crates/next-custom-transforms/tests/errors/server-actions/server-graph/6/output.js +++ b/packages/next-swc/crates/next-custom-transforms/tests/errors/server-actions/server-graph/6/output.js @@ -1,4 +1,4 @@ -/* __next_internal_action_entry_do_not_use__ {} */ import { createActionProxy } from "private-next-rsc-action-proxy"; +/* __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 createActionProxy("6d53ce510b2e36499b8f56038817b9bad86cabb4", $$ACTION_0); export async function $$ACTION_0() {}