Compare commits

...

9 Commits

Author SHA1 Message Date
Vercel Release Bot
809740b385 Version Packages (#11570)
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @vercel/functions@1.0.2

### Patch Changes

- Convert package to CommonJS
([#11569](https://github.com/vercel/vercel/pull/11569))

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-05-09 18:12:02 -07:00
Nathan Rajlich
bf9acd023d [functions] Convert to CommonJS (#11569)
The package was not working because it is using ESM syntax, but the
`package.json` did not have `"type": "module"`.

Anyways, for broader compatibility, let's use CommonJS.
2024-05-09 18:10:39 -07:00
Vercel Release Bot
f4ba9cdcf8 Version Packages (#11564)
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## vercel@34.1.10

### Patch Changes

- Updated dependencies
\[[`119f80e96`](119f80e961),
[`11584b0e9`](11584b0e9b),
[`3023122d4`](3023122d4e),
[`0e774b6be`](0e774b6be0)]:
    -   @vercel/next@4.2.9
    -   @vercel/static-build@2.5.4

## @vercel/next@4.2.9

### Patch Changes

- Support incremental partial prerendering
([#11560](https://github.com/vercel/vercel/pull/11560))

- ensure `.action` outputs are created for edge functions
([#11568](https://github.com/vercel/vercel/pull/11568))

-   ([#11566](https://github.com/vercel/vercel/pull/11566))

## @vercel/static-build@2.5.4

### Patch Changes

- Fix `Cannot read properties of null` error
([#11559](https://github.com/vercel/vercel/pull/11559))

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-05-09 10:03:52 -07:00
Zack Tanner
11584b0e9b [next] ensure action outputs are created for edge functions (#11568)
Since we're rewriting `next-action` requests to `.action` outputs, we need to ensure that we also duplicate the edge function handler for it. 

This runs all of the existing Node runtime tests in the Edge runtime as well. However, there's a discrepancy in how `x-vercel-cache` is returned, so for now we instead validate that its responding with `x-edge-runtime`.
2024-05-09 01:39:08 +00:00
JJ Kasper
3023122d4e [next] Update react version in next fixtures (#11566)
We are locking the peerDependency to react v19 beta on canary so we need to update these fixtures to tolerate that. 

x-ref: [slack thread](https://vercel.slack.com/archives/C048KLPEEH1/p1715191372631389)
x-ref: https://github.com/vercel/next.js/pull/65058
2024-05-08 23:33:24 +00:00
Nathan Rajlich
0e774b6be0 [static-build] Fix Cannot read properties of null error (#11559)
A bug was introduced in #11529 that causes the build to fail if `ruby`
is not installed. The fix here accounts for that scenario.

Closes #11547.
2024-05-08 11:44:49 -07:00
Wyatt Johnson
119f80e961 [next] Support Incremental Partial Prerendering (#11560)
This fixes the logic that detects if partial prerendering (PPR) has been
enabled for a project. The new incremental adoption pathway allows
setting the `experimental.ppr = 'incremental'` which the previous code
did not support.
2024-05-08 08:13:39 -06:00
Vercel Release Bot
9fe92d7de0 Version Packages (#11558)
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @vercel/functions@1.0.1

### Patch Changes

- Don't throw error if context is missing
([`0817527f9`](0817527f9e))

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-05-07 17:13:10 +02:00
Kiko Beats
0817527f9e [@vercel/functions]: don't throw error if context is missing (#11557)
making `waituntil` a noop
2024-05-07 17:02:23 +02:00
139 changed files with 773 additions and 370 deletions

View File

@@ -1,5 +1,13 @@
# vercel # vercel
## 34.1.10
### Patch Changes
- Updated dependencies [[`119f80e96`](https://github.com/vercel/vercel/commit/119f80e9611a7a5a755aa689502dcdab323194aa), [`11584b0e9`](https://github.com/vercel/vercel/commit/11584b0e9b55f312f34d0d6467ab498e472ac9df), [`3023122d4`](https://github.com/vercel/vercel/commit/3023122d4e0dd292340d9e9e61ef232baf6e610d), [`0e774b6be`](https://github.com/vercel/vercel/commit/0e774b6be0c832213a64124e1f4fc6d150e87d9f)]:
- @vercel/next@4.2.9
- @vercel/static-build@2.5.4
## 34.1.9 ## 34.1.9
### Patch Changes ### Patch Changes

View File

@@ -1,6 +1,6 @@
{ {
"name": "vercel", "name": "vercel",
"version": "34.1.9", "version": "34.1.10",
"preferGlobal": true, "preferGlobal": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"description": "The command-line interface for Vercel", "description": "The command-line interface for Vercel",
@@ -36,13 +36,13 @@
"@vercel/fun": "1.1.0", "@vercel/fun": "1.1.0",
"@vercel/go": "3.1.1", "@vercel/go": "3.1.1",
"@vercel/hydrogen": "1.0.2", "@vercel/hydrogen": "1.0.2",
"@vercel/next": "4.2.8", "@vercel/next": "4.2.9",
"@vercel/node": "3.1.0", "@vercel/node": "3.1.0",
"@vercel/python": "4.2.0", "@vercel/python": "4.2.0",
"@vercel/redwood": "2.0.8", "@vercel/redwood": "2.0.8",
"@vercel/remix-builder": "2.1.5", "@vercel/remix-builder": "2.1.5",
"@vercel/ruby": "2.1.0", "@vercel/ruby": "2.1.0",
"@vercel/static-build": "2.5.3", "@vercel/static-build": "2.5.4",
"chokidar": "3.3.1" "chokidar": "3.3.1"
}, },
"devDependencies": { "devDependencies": {

View File

@@ -1,5 +1,17 @@
# @vercel/functions # @vercel/functions
## 1.0.2
### Patch Changes
- Convert package to CommonJS ([#11569](https://github.com/vercel/vercel/pull/11569))
## 1.0.1
### Patch Changes
- Don't throw error if context is missing ([`0817527f9`](https://github.com/vercel/vercel/commit/0817527f9e9d0d5fceb73f21e695089349a96d3e))
## 1.0.0 ## 1.0.0
### Major Changes ### Major Changes

View File

@@ -14,4 +14,4 @@
* } * }
* ``` * ```
*/ */
export const waitUntil: (promise: Promise<unknown>) => void; export function waitUntil(promise: Promise<unknown>): void;

View File

@@ -1,8 +1,7 @@
/* global globalThis */ /* global globalThis */
export const waitUntil = promise => { exports.waitUntil = promise => {
if ( if (
promise instanceof Promise === false ||
promise === null || promise === null ||
typeof promise !== 'object' || typeof promise !== 'object' ||
typeof promise.then !== 'function' typeof promise.then !== 'function'
@@ -13,12 +12,5 @@ export const waitUntil = promise => {
} }
const ctx = globalThis[Symbol.for('@vercel/request-context')]?.get?.() ?? {}; const ctx = globalThis[Symbol.for('@vercel/request-context')]?.get?.() ?? {};
ctx.waitUntil?.(promise);
if (!ctx.waitUntil) {
throw new Error(
'failed to get waitUntil function for this request context'
);
}
ctx.waitUntil(promise);
}; };

View File

@@ -23,14 +23,11 @@ test.each([
}); });
test.each([null, undefined, {}])( test.each([null, undefined, {}])(
'waitUntil throws when context is %s', 'waitUntil does not throw an error when context is %s',
input => { input => {
const promise = Promise.resolve(); const promise = Promise.resolve();
globalThis[Symbol.for('@vercel/request-context')] = input; globalThis[Symbol.for('@vercel/request-context')] = input;
expect(() => waitUntil(promise)).toThrow(Error); expect(() => waitUntil(promise)).not.toThrow();
expect(() => waitUntil(promise)).toThrow(
'failed to get waitUntil function for this request context'
);
} }
); );

View File

@@ -2,7 +2,7 @@
"name": "@vercel/functions", "name": "@vercel/functions",
"description": "Runtime functions to be used with your Vercel Functions", "description": "Runtime functions to be used with your Vercel Functions",
"homepage": "https://vercel.com", "homepage": "https://vercel.com",
"version": "1.0.0", "version": "1.0.2",
"types": "index.d.ts", "types": "index.d.ts",
"main": "index.js", "main": "index.js",
"repository": { "repository": {

View File

@@ -1,5 +1,15 @@
# @vercel/next # @vercel/next
## 4.2.9
### Patch Changes
- Support incremental partial prerendering ([#11560](https://github.com/vercel/vercel/pull/11560))
- ensure `.action` outputs are created for edge functions ([#11568](https://github.com/vercel/vercel/pull/11568))
- ([#11566](https://github.com/vercel/vercel/pull/11566))
## 4.2.8 ## 4.2.8
### Patch Changes ### Patch Changes

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/next", "name": "@vercel/next",
"version": "4.2.8", "version": "4.2.9",
"license": "Apache-2.0", "license": "Apache-2.0",
"main": "./dist/index", "main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/next-js", "homepage": "https://vercel.com/docs/runtimes#official-runtimes/next-js",

View File

@@ -218,7 +218,9 @@ export async function serverBuild({
} }
const experimental = { const experimental = {
ppr: requiredServerFilesManifest.config.experimental?.ppr === true, ppr:
requiredServerFilesManifest.config.experimental?.ppr === true ||
requiredServerFilesManifest.config.experimental?.ppr === 'incremental',
}; };
let appRscPrefetches: UnwrapPromise<ReturnType<typeof glob>> = {}; let appRscPrefetches: UnwrapPromise<ReturnType<typeof glob>> = {};
@@ -228,8 +230,6 @@ export async function serverBuild({
if (appPathRoutesManifest) { if (appPathRoutesManifest) {
appDir = path.join(pagesDir, '../app'); appDir = path.join(pagesDir, '../app');
appBuildTraces = await glob('**/*.js.nft.json', appDir); appBuildTraces = await glob('**/*.js.nft.json', appDir);
// TODO: maybe?
appRscPrefetches = experimental.ppr appRscPrefetches = experimental.ppr
? {} ? {}
: await glob(`**/*${RSC_PREFETCH_SUFFIX}`, appDir); : await glob(`**/*${RSC_PREFETCH_SUFFIX}`, appDir);
@@ -1601,6 +1601,10 @@ export async function serverBuild({
edgeFunctions[`${pathname}${RSC_PREFETCH_SUFFIX}`] = edgeFunctions[`${pathname}${RSC_PREFETCH_SUFFIX}`] =
edgeFunctions[pathname]; edgeFunctions[pathname];
} }
if (hasActionOutputSupport) {
edgeFunctions[`${pathname}.action`] = edgeFunctions[pathname];
}
} }
} }
} }

View File

@@ -0,0 +1,19 @@
'use client';
import { useState } from 'react';
import { increment } from '../../../../actions';
export default function Page() {
const [count, setCount] = useState(0);
async function updateCount() {
const newCount = await increment(count);
setCount(newCount);
}
return (
<form action={updateCount}>
<div id="count">{count}</div>
<button>Submit</button>
</form>
);
}

View File

@@ -0,0 +1,5 @@
export const dynamic = 'force-dynamic';
export default function Layout({ children }) {
return children;
}

View File

@@ -0,0 +1,19 @@
'use client';
import { useState } from 'react';
import { increment } from '../../../../actions';
export default function Page() {
const [count, setCount] = useState(0);
async function updateCount() {
const newCount = await increment(count);
setCount(newCount);
}
return (
<form action={updateCount}>
<div id="count">{count}</div>
<button>Submit</button>
</form>
);
}

View File

@@ -0,0 +1,5 @@
export const dynamic = 'force-static';
export default function Layout({ children }) {
return children;
}

View File

@@ -0,0 +1,19 @@
'use client';
import { useState } from 'react';
import { increment } from '../../../actions';
export default function Page() {
const [count, setCount] = useState(0);
async function updateCount() {
const newCount = await increment(count);
setCount(newCount);
}
return (
<form action={updateCount}>
<div id="count">{count}</div>
<button>Submit</button>
</form>
);
}

View File

@@ -0,0 +1,5 @@
export const runtime = 'edge';
export default function Layout({ children }) {
return <div>{children}</div>;
}

View File

@@ -0,0 +1,45 @@
'use client';
// @ts-ignore
import { useCallback, useState } from 'react';
function request(method) {
return fetch('/api/test', {
method,
headers: {
'content-type': 'multipart/form-data;.*',
},
});
}
export default function Home() {
const [result, setResult] = useState('Press submit');
const onClick = useCallback(async method => {
const res = await request(method);
const text = await res.text();
setResult(res.ok ? `${method} ${text}` : 'Error: ' + res.status);
}, []);
return (
<>
<div className="flex flex-col items-center justify-center h-screen">
<div className="flex flex-row space-x-2 items-center justify-center">
<button
className="border border-white rounded-sm p-4 mb-4"
onClick={() => onClick('GET')}
>
Submit GET
</button>
<button
className="border border-white rounded-sm p-4 mb-4"
onClick={() => onClick('POST')}
>
Submit POST
</button>
</div>
<div className="text-white">{result}</div>
</div>
</>
);
}

View File

@@ -0,0 +1,5 @@
export const dynamic = 'force-dynamic';
export default function Layout({ children }) {
return children;
}

View File

@@ -0,0 +1,15 @@
import { revalidatePath } from 'next/cache';
export default async function Page() {
async function serverAction() {
'use server';
await new Promise(resolve => setTimeout(resolve, 1000));
revalidatePath('/dynamic');
}
return (
<form action={serverAction}>
<button>Submit</button>
</form>
);
}

View File

@@ -0,0 +1,15 @@
import { revalidatePath } from 'next/cache';
export default async function Page() {
async function serverAction() {
'use server';
await new Promise(resolve => setTimeout(resolve, 1000));
revalidatePath('/dynamic');
}
return (
<form action={serverAction}>
<button>Submit</button>
</form>
);
}

View File

@@ -0,0 +1,19 @@
import { revalidatePath } from 'next/cache';
export default async function Page() {
async function serverAction() {
'use server';
await new Promise(resolve => setTimeout(resolve, 1000));
revalidatePath('/dynamic');
}
return (
<form action={serverAction}>
<button>Submit</button>
</form>
);
}
export function generateStaticParams() {
return [{ slug: 'pre-generated' }];
}

View File

@@ -0,0 +1,5 @@
export const dynamic = 'force-static';
export default function Layout({ children }) {
return children;
}

View File

@@ -0,0 +1,15 @@
import { revalidatePath } from 'next/cache'
export default async function Page() {
async function serverAction() {
'use server';
await new Promise((resolve) => setTimeout(resolve, 1000));
revalidatePath('/dynamic');
}
return (
<form action={serverAction}>
<button>Submit</button>
</form>
);
}

View File

@@ -5,10 +5,12 @@ const fetch = require('../../../../../test/lib/deployment/fetch-retry');
const ctx = {}; const ctx = {};
function findActionId(page) { function findActionId(page, runtime) {
page = `app${page}/page`; // add /app prefix and /page suffix page = `app${page}/page`; // add /app prefix and /page suffix
for (const [actionId, details] of Object.entries(ctx.actionManifest.node)) { for (const [actionId, details] of Object.entries(
ctx.actionManifest[runtime]
)) {
if (details.workers[page]) { if (details.workers[page]) {
return actionId; return actionId;
} }
@@ -41,141 +43,115 @@ describe(`${__dirname.split(path.sep).pop()}`, () => {
Object.assign(ctx, info); Object.assign(ctx, info);
}); });
describe('client component', () => { describe.each(['node', 'edge'])('runtime: %s', runtime => {
it('should bypass the static cache for a server action', async () => { const basePath = runtime === 'edge' ? '/edge' : '';
const path = '/client/static'; describe('client component', () => {
const actionId = findActionId(path); it('should bypass the static cache for a server action', async () => {
const path = `${basePath}/client/static`;
const actionId = findActionId(path, runtime);
const res = await fetch(`${ctx.deploymentUrl}${path}`, { const res = await fetch(`${ctx.deploymentUrl}${path}`, {
method: 'POST', method: 'POST',
body: JSON.stringify([1337]), body: JSON.stringify([1337]),
headers: { headers: {
'Content-Type': 'text/plain;charset=UTF-8', 'Content-Type': 'text/plain;charset=UTF-8',
'Next-Action': actionId, 'Next-Action': actionId,
}, },
});
expect(res.status).toEqual(200);
const body = await res.text();
expect(body).toContain('1338');
expect(res.headers.get('x-matched-path')).toBe(path + '.action');
if (runtime === 'node') {
expect(res.headers.get('x-vercel-cache')).toBe('MISS');
} else {
// in edge runtime, x-vercel-cache is not returned on MISSes for some reason.
// this checks to ensure it was routed to the edge function instead.
expect(res.headers.get('x-edge-runtime')).toBe('1');
}
}); });
expect(res.status).toEqual(200); it('should bypass the static cache for a server action on a page with dynamic params', async () => {
const body = await res.text(); const path = `${basePath}/client/static/[dynamic-static]`;
expect(body).toContain('1338'); const actionId = findActionId(path, runtime);
expect(res.headers.get('x-matched-path')).toBe(path + '.action');
expect(res.headers.get('x-vercel-cache')).toBe('MISS');
});
it('should bypass the static cache for a server action on a page with dynamic params', async () => { const res = await fetch(`${ctx.deploymentUrl}${path}`, {
const path = '/client/static/[dynamic-static]'; method: 'POST',
const actionId = findActionId(path); body: JSON.stringify([1337]),
headers: {
'Content-Type': 'text/plain;charset=UTF-8',
'Next-Action': actionId,
},
});
const res = await fetch(`${ctx.deploymentUrl}${path}`, { expect(res.status).toEqual(200);
method: 'POST', const body = await res.text();
body: JSON.stringify([1337]), expect(body).toContain('1338');
headers: { expect(res.headers.get('x-matched-path')).toBe(path + '.action');
'Content-Type': 'text/plain;charset=UTF-8', if (runtime === 'node') {
'Next-Action': actionId, expect(res.headers.get('x-vercel-cache')).toBe('MISS');
}, } else {
expect(res.headers.get('x-edge-runtime')).toBe('1');
}
}); });
expect(res.status).toEqual(200); it('should bypass the static cache for a multipart request (no action header)', async () => {
const body = await res.text(); const path = `${basePath}/client/static`;
expect(body).toContain('1338'); const actionId = findActionId(path, runtime);
expect(res.headers.get('x-matched-path')).toBe(path + '.action');
expect(res.headers.get('x-vercel-cache')).toBe('MISS');
});
it('should bypass the static cache for a multipart request (no action header)', async () => { const res = await fetch(`${ctx.deploymentUrl}${path}`, {
const path = '/client/static'; method: 'POST',
const actionId = findActionId(path); body: `------WebKitFormBoundaryHcVuFa30AN0QV3uZ\r\nContent-Disposition: form-data; name=\"1_$ACTION_ID_${actionId}\"\r\n\r\n\r\n------WebKitFormBoundaryHcVuFa30AN0QV3uZ\r\nContent-Disposition: form-data; name=\"0\"\r\n\r\n[\"$K1\"]\r\n------WebKitFormBoundaryHcVuFa30AN0QV3uZ--\r\n`,
headers: {
'Content-Type':
'multipart/form-data; boundary=----WebKitFormBoundaryHcVuFa30AN0QV3uZ',
},
});
const res = await fetch(`${ctx.deploymentUrl}${path}`, { expect(res.status).toEqual(200);
method: 'POST', expect(res.headers.get('content-type')).toBe(
body: `------WebKitFormBoundaryHcVuFa30AN0QV3uZ\r\nContent-Disposition: form-data; name=\"1_$ACTION_ID_${actionId}\"\r\n\r\n\r\n------WebKitFormBoundaryHcVuFa30AN0QV3uZ\r\nContent-Disposition: form-data; name=\"0\"\r\n\r\n[\"$K1\"]\r\n------WebKitFormBoundaryHcVuFa30AN0QV3uZ--\r\n`, 'text/html; charset=utf-8'
headers: {
'Content-Type':
'multipart/form-data; boundary=----WebKitFormBoundaryHcVuFa30AN0QV3uZ',
},
});
expect(res.status).toEqual(200);
expect(res.headers.get('content-type')).toBe('text/html; charset=utf-8');
// This is a "BYPASS" because no action ID was provided, so it'll fall back to
// `experimentalBypassFor` handling.
expect(res.headers.get('x-vercel-cache')).toBe('BYPASS');
expect(res.headers.get('x-matched-path')).toBe(path);
});
it('should properly invoke the action on a dynamic page', async () => {
const path = '/client/dynamic/[id]';
const actionId = findActionId(path);
const res = await fetch(`${ctx.deploymentUrl}${path}`, {
method: 'POST',
body: JSON.stringify([1337]),
headers: {
'Content-Type': 'text/plain;charset=UTF-8',
'Next-Action': actionId,
},
});
expect(res.status).toEqual(200);
const body = await res.text();
expect(body).toContain('1338');
expect(res.headers.get('x-matched-path')).toBe(path + '.action');
expect(res.headers.get('x-vercel-cache')).toBe('MISS');
});
});
describe('server component', () => {
it('should bypass the static cache for a server action', async () => {
const path = '/rsc/static';
const actionId = findActionId(path);
const res = await fetch(
`${ctx.deploymentUrl}${path}`,
generateFormDataPayload(actionId)
);
expect(res.status).toEqual(200);
expect(res.headers.get('x-matched-path')).toBe(path + '.action');
expect(res.headers.get('content-type')).toBe('text/x-component');
expect(res.headers.get('x-vercel-cache')).toBe('MISS');
});
it('should bypass the static cache for a server action on a page with dynamic params', async () => {
const path = '/rsc/static/[dynamic-static]';
const actionId = findActionId(path);
const res = await fetch(
`${ctx.deploymentUrl}${path}`,
generateFormDataPayload(actionId)
);
expect(res.status).toEqual(200);
expect(res.headers.get('x-matched-path')).toBe(path + '.action');
expect(res.headers.get('content-type')).toBe('text/x-component');
expect(res.headers.get('x-vercel-cache')).toBe('MISS');
});
it('should properly invoke the action on a dynamic page', async () => {
const path = '/rsc/dynamic';
const actionId = findActionId(path);
const res = await fetch(
`${ctx.deploymentUrl}${path}`,
generateFormDataPayload(actionId)
);
expect(res.status).toEqual(200);
expect(res.headers.get('x-matched-path')).toBe(path + '.action');
expect(res.headers.get('content-type')).toBe('text/x-component');
expect(res.headers.get('x-vercel-cache')).toBe('MISS');
});
describe('generateStaticParams', () => {
it('should bypass the static cache for a server action when pre-generated', async () => {
const path = '/rsc/static/generate-static-params/pre-generated';
const actionId = findActionId(
'/rsc/static/generate-static-params/[slug]'
); );
if (runtime === 'node') {
// This is a "BYPASS" because no action ID was provided, so it'll fall back to
// `experimentalBypassFor` handling.
expect(res.headers.get('x-vercel-cache')).toBe('BYPASS');
} else {
expect(res.headers.get('x-edge-runtime')).toBe('1');
}
expect(res.headers.get('x-matched-path')).toBe(path);
});
it('should properly invoke the action on a dynamic page', async () => {
const path = `${basePath}/client/dynamic/[id]`;
const actionId = findActionId(path, runtime);
const res = await fetch(`${ctx.deploymentUrl}${path}`, {
method: 'POST',
body: JSON.stringify([1337]),
headers: {
'Content-Type': 'text/plain;charset=UTF-8',
'Next-Action': actionId,
},
});
expect(res.status).toEqual(200);
const body = await res.text();
expect(body).toContain('1338');
expect(res.headers.get('x-matched-path')).toBe(path + '.action');
if (runtime === 'node') {
expect(res.headers.get('x-vercel-cache')).toBe('MISS');
} else {
expect(res.headers.get('x-edge-runtime')).toBe('1');
}
});
});
describe('server component', () => {
it('should bypass the static cache for a server action', async () => {
const path = `${basePath}/rsc/static`;
const actionId = findActionId(path, runtime);
const res = await fetch( const res = await fetch(
`${ctx.deploymentUrl}${path}`, `${ctx.deploymentUrl}${path}`,
@@ -183,26 +159,94 @@ describe(`${__dirname.split(path.sep).pop()}`, () => {
); );
expect(res.status).toEqual(200); expect(res.status).toEqual(200);
expect(res.headers.get('x-matched-path')).toBe( expect(res.headers.get('x-matched-path')).toBe(path + '.action');
'/rsc/static/generate-static-params/[slug].action'
);
expect(res.headers.get('content-type')).toBe('text/x-component'); expect(res.headers.get('content-type')).toBe('text/x-component');
expect(res.headers.get('x-vercel-cache')).toBe('MISS'); if (runtime === 'node') {
expect(res.headers.get('x-vercel-cache')).toBe('MISS');
} else {
expect(res.headers.get('x-edge-runtime')).toBe('1');
}
}); });
it('should bypass the static cache for a server action when not pre-generated', async () => { it('should bypass the static cache for a server action on a page with dynamic params', async () => {
const page = '/rsc/static/generate-static-params/[slug]'; const path = `${basePath}/rsc/static/[dynamic-static]`;
const actionId = findActionId(page); const actionId = findActionId(path, runtime);
const res = await fetch( const res = await fetch(
`${ctx.deploymentUrl}/rsc/static/generate-static-params/not-pre-generated`, `${ctx.deploymentUrl}${path}`,
generateFormDataPayload(actionId) generateFormDataPayload(actionId)
); );
expect(res.status).toEqual(200); expect(res.status).toEqual(200);
expect(res.headers.get('x-matched-path')).toBe(page + '.action'); expect(res.headers.get('x-matched-path')).toBe(path + '.action');
expect(res.headers.get('content-type')).toBe('text/x-component'); expect(res.headers.get('content-type')).toBe('text/x-component');
expect(res.headers.get('x-vercel-cache')).toBe('MISS'); if (runtime === 'node') {
expect(res.headers.get('x-vercel-cache')).toBe('MISS');
} else {
expect(res.headers.get('x-edge-runtime')).toBe('1');
}
});
it('should properly invoke the action on a dynamic page', async () => {
const path = `${basePath}/rsc/dynamic`;
const actionId = findActionId(path, runtime);
const res = await fetch(
`${ctx.deploymentUrl}${path}`,
generateFormDataPayload(actionId)
);
expect(res.status).toEqual(200);
expect(res.headers.get('x-matched-path')).toBe(path + '.action');
expect(res.headers.get('content-type')).toBe('text/x-component');
if (runtime === 'node') {
expect(res.headers.get('x-vercel-cache')).toBe('MISS');
} else {
expect(res.headers.get('x-edge-runtime')).toBe('1');
}
});
describe('generateStaticParams', () => {
it('should bypass the static cache for a server action when pre-generated', async () => {
const path = `${basePath}/rsc/static/generate-static-params/pre-generated`;
const dynamicPath = `${basePath}/rsc/static/generate-static-params/[slug]`;
const actionId = findActionId(dynamicPath, runtime);
const res = await fetch(
`${ctx.deploymentUrl}${path}`,
generateFormDataPayload(actionId)
);
expect(res.status).toEqual(200);
expect(res.headers.get('x-matched-path')).toBe(
dynamicPath + '.action'
);
expect(res.headers.get('content-type')).toBe('text/x-component');
if (runtime === 'node') {
expect(res.headers.get('x-vercel-cache')).toBe('MISS');
} else {
expect(res.headers.get('x-edge-runtime')).toBe('1');
}
});
it('should bypass the static cache for a server action when not pre-generated', async () => {
const page = `${basePath}/rsc/static/generate-static-params/[slug]`;
const actionId = findActionId(page, runtime);
const res = await fetch(
`${ctx.deploymentUrl}/${basePath}/rsc/static/generate-static-params/not-pre-generated`,
generateFormDataPayload(actionId)
);
expect(res.status).toEqual(200);
expect(res.headers.get('x-matched-path')).toBe(page + '.action');
expect(res.headers.get('content-type')).toBe('text/x-component');
if (runtime === 'node') {
expect(res.headers.get('x-vercel-cache')).toBe('MISS');
} else {
expect(res.headers.get('x-edge-runtime')).toBe('1');
}
});
}); });
}); });
}); });

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "experimental", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "experimental" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "experimental", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "experimental" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true, "ignoreNextjsUpdates": true,
"scripts": { "scripts": {

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "experimental", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "experimental" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "experimental", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "experimental" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -7,8 +7,8 @@
}, },
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "experimental", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "experimental" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -0,0 +1,3 @@
export { default } from '../page';
export const experimental_ppr = false;

View File

@@ -0,0 +1,7 @@
export default function Layout({ children }) {
return (
<html>
<body>{children}</body>
</html>
);
}

View File

@@ -0,0 +1,17 @@
import { unstable_noStore } from 'next/cache';
import { Suspense } from 'react';
export const experimental_ppr = true;
function Dynamic() {
unstable_noStore();
return <div id="sentinel:dynamic">Dynamic</div>;
}
export default function Page() {
return (
<Suspense fallback={<div id="sentinel:loading">Loading...</div>}>
<Dynamic />
</Suspense>
);
}

View File

@@ -0,0 +1,13 @@
/* eslint-env jest */
const path = require('path');
const { deployAndTest } = require('../../utils');
const ctx = {};
// TODO: investigate invariant
describe.skip(`${__dirname.split(path.sep).pop()}`, () => {
it('should deploy and pass probe checks', async () => {
const info = await deployAndTest(__dirname);
Object.assign(ctx, info);
});
});

View File

@@ -0,0 +1,5 @@
module.exports = {
experimental: {
ppr: 'incremental',
},
};

View File

@@ -0,0 +1,8 @@
{
"dependencies": {
"next": "canary",
"react": "19.0.0-beta-4508873393-20240430",
"react-dom": "19.0.0-beta-4508873393-20240430"
},
"ignoreNextjsUpdates": true
}

View File

@@ -0,0 +1,77 @@
{
"builds": [
{
"src": "package.json",
"use": "@vercel/next",
"config": {
"functions": {
"app/**/*": {
"maxDuration": 5,
"memory": 512
},
"pages/api/**/*": {
"maxDuration": 5,
"memory": 512
}
}
}
}
],
"probes": [
{
"path": "/",
"status": 200,
"mustContain": "sentinel:loading"
},
{
"path": "/",
"status": 200,
"mustContain": "sentinel:dynamic"
},
{
"path": "/",
"headers": {
"RSC": "1",
"Next-Router-Prefetch": "1"
},
"status": 200,
"mustContain": "sentinel:loading",
"mustNotContain": "sentinel:dynamic"
},
{
"path": "/",
"headers": {
"RSC": "1"
},
"status": 200,
"mustContain": "sentinel:dynamic"
},
{
"path": "/disabled",
"status": 200,
"mustContain": "sentinel:loading"
},
{
"path": "/disabled",
"status": 200,
"mustContain": "sentinel:dynamic"
},
{
"path": "/disabled",
"headers": {
"RSC": "1",
"Next-Router-Prefetch": "1"
},
"status": 200,
"mustContain": "sentinel:dynamic"
},
{
"path": "/disabled",
"headers": {
"RSC": "1"
},
"status": 200,
"mustContain": "sentinel:dynamic"
}
]
}

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "experimental", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "experimental" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "experimental", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "experimental" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -7,8 +7,8 @@
}, },
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "^18.2.0", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "^18.2.0" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"devDependencies": { "devDependencies": {
"@types/node": "20.4.5", "@types/node": "20.4.5",

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "18.2.0", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "18.2.0" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "experimental", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "experimental" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "experimental", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "experimental" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "experimental", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "experimental" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "experimental", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "experimental" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "experimental", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "experimental" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -10,8 +10,8 @@
}, },
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -5,8 +5,8 @@
}, },
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -6,8 +6,8 @@
}, },
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -9,8 +9,8 @@
}, },
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -8,8 +8,8 @@
}, },
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -8,8 +8,8 @@
}, },
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -8,8 +8,8 @@
}, },
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest", "react-dom": "19.0.0-beta-4508873393-20240430",
"typescript": "4.9.5" "typescript": "4.9.5"
}, },
"devDependencies": { "devDependencies": {

View File

@@ -5,8 +5,8 @@
}, },
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -5,8 +5,8 @@
}, },
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -5,8 +5,8 @@
}, },
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"scripts": { "scripts": {
"dev": "next dev", "dev": "next dev",

View File

@@ -4,8 +4,8 @@
}, },
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -3,8 +3,8 @@
"private": true, "private": true,
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"scripts": { "scripts": {
"build": "next build website-preview" "build": "next build website-preview"

View File

@@ -3,7 +3,7 @@
"private": true, "private": true,
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
} }
} }

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -4,8 +4,8 @@
}, },
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -4,5 +4,9 @@
"packages": [ "packages": [
"packages/*" "packages/*"
] ]
},
"overrides": {
"react": "19.0.0-beta-4508873393-20240430",
"react-dom": "19.0.0-beta-4508873393-20240430"
} }
} }

View File

@@ -8,7 +8,7 @@
}, },
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
} }
} }

View File

@@ -8,7 +8,7 @@
}, },
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
} }
} }

View File

@@ -4,5 +4,9 @@
"packages": [ "packages": [
"packages/*" "packages/*"
] ]
} },
"overrides": {
"react": "19.0.0-beta-4508873393-20240430",
"react-dom": "19.0.0-beta-4508873393-20240430"
}
} }

View File

@@ -8,7 +8,7 @@
}, },
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
} }
} }

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -7,8 +7,8 @@
"chrome-aws-lambda": "8.0.0", "chrome-aws-lambda": "8.0.0",
"firebase": "8.3.0", "firebase": "8.3.0",
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -4,8 +4,8 @@
}, },
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -9,8 +9,8 @@
}, },
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"scripts": { "scripts": {
"vercel-build": "next build" "vercel-build": "next build"

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -4,8 +4,8 @@
"@types/node": "^12.12.56", "@types/node": "^12.12.56",
"@types/react": "^16.9.49", "@types/react": "^16.9.49",
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest", "react-dom": "19.0.0-beta-4508873393-20240430",
"typescript": "4.9.5" "typescript": "4.9.5"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -4,8 +4,8 @@
}, },
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -4,8 +4,8 @@
}, },
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -13,9 +13,6 @@
{ {
"path": "/", "path": "/",
"mustContain": "nextExport\":true" "mustContain": "nextExport\":true"
},
{
"logMustContain": "Notice: detected `next export`, this de-opts some Next.js features"
} }
] ]
} }

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -4,8 +4,8 @@
}, },
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

View File

@@ -1,8 +1,8 @@
{ {
"dependencies": { "dependencies": {
"next": "canary", "next": "canary",
"react": "latest", "react": "19.0.0-beta-4508873393-20240430",
"react-dom": "latest" "react-dom": "19.0.0-beta-4508873393-20240430"
}, },
"ignoreNextjsUpdates": true "ignoreNextjsUpdates": true
} }

Some files were not shown because too many files have changed in this diff Show More