Compare commits

..

15 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
Vercel Release Bot
6476f4f786 Version Packages (#11551)
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.0

### Major Changes

- Initial release
([#11553](https://github.com/vercel/vercel/pull/11553))

## @vercel/node@3.1.0

### Minor Changes

- Make waitUntil consistent for Node.js & Edge
([#11553](https://github.com/vercel/vercel/pull/11553))

## vercel@34.1.9

### Patch Changes

- Updated dependencies
\[[`5a532a5b9`](5a532a5b94),
[`50fc27ba5`](50fc27ba57),
[`c1d852295`](c1d8522950),
[`a5ea04154`](a5ea04154b)]:
    -   @vercel/next@4.2.8
    -   @vercel/node@3.1.0

## @vercel/next@4.2.8

### Patch Changes

- Fix missing initial RSC headers
([#11552](https://github.com/vercel/vercel/pull/11552))

- Remove .prefetch.rsc rewrites for non-PPR
([#11540](https://github.com/vercel/vercel/pull/11540))

- [next] rename middleware manifest env
([#11549](https://github.com/vercel/vercel/pull/11549))

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-05-07 15:40:37 +02:00
Kiko Beats
a5ea04154b Make waitUntil consistent for Node.js & Edge (#11553)
This PR makes `waitUntil` consistent when interacting with it via `vc
dev`. That includes:

**be possible to call `waitUntil` from the context second argument in
web handlers functions (Node.js & Edge)**:

```js
export function GET(request, { waitUntil }) {
  waitUntil(fetch('https://vercel.com'));
  return new Response('OK');
}
```

**be possible to call `waitUntil` imported from `@vercel/functions`**
(Node.js & Edge):

```js
import { waitUntil } from '@vercel/functions';

export function GET(request) {
  waitUntil(fetch('https://vercel.com'));
  return new Response('OK');
}
```

Additionally, `@vercel/functions` can be adopted for other framework to
take advantage of this pattern at Vercel.

---------

Co-authored-by: Javi Velasco <javier.velasco86@gmail.com>
2024-05-07 15:36:43 +02:00
JJ Kasper
5a532a5b94 [next] Fix missing initial RSC headers (#11552)
While investigating https://github.com/vercel/next.js/issues/59883 we noticed the RSC Prerender did not have all the expected headers like the HTML Prerender which caused unexpected revalidation behavior specifically on client-transition as some of these headers are used to detect if a revalidated tag is associated with specific outputs. 

x-ref: https://github.com/vercel/next.js/issues/59883
2024-05-07 07:43:00 +00:00
Jiachi Liu
c1d8522950 [next] rename middleware manifest env (#11549)
Rename `environment` property to `env` from middleware manifest added in
#11390.
Align with https://github.com/vercel/next.js/pull/64521

The `environments` property wasn't working properly before due to
unfinished next.js changes, it should work now after testing with next
build from https://github.com/vercel/next.js/pull/64521. We change it to
a better naming word `env`.
2024-05-06 21:32:07 +02:00
JJ Kasper
50fc27ba57 [next] Remove .prefetch.rsc rewrites for non-PPR (#11540)
Removes .prefetch.rsc rewrites rules for non-PPR, as Next.js doesn't emit any static prefetches otherwise
2024-05-06 18:17:22 +00:00
Joel Henningsen
3101d2497f Fix broken link to Code of Conduct in README (#11544)
### Purpose of the Pull Request

This PR addresses a broken link in the README.md file that is supposed
to direct readers to the Code of Conduct. Previously, the link pointed
to `CODE_OF_CONDUCT.md`, which does not exist in the repository's main
directory. The corrected link points to the actual location of the file
in the `.github` directory.

### Changes Made

- Updated the link to the Code of Conduct from `[Code of
Conduct](CODE_OF_CONDUCT.md)` to `[Code of
Conduct](./.github/CODE_OF_CONDUCT.md)` to reflect the correct path.

### Additional Information

I previously opened discussion #11498 regarding this issue with the goal
of following the [Contribuing
Guidelines](https://github.com/vercel/vercel?tab=readme-ov-file#contributing),
but did not receive any feedback over the past week. Given the nature of
the change (a simple documentation fix), I proceeded with this pull
request to ensure the documentation remains useful and accurate for all
users.

### Impact

This change will help ensure that new contributors and users can easily
access the Code of Conduct, fostering better community interactions and
adherence to project standards.

Thank you for considering this pull request. I am open to any further
suggestions or requirements needed to merge this change.
2024-05-04 17:28:21 -07:00
160 changed files with 1527 additions and 925 deletions

View File

@@ -37,7 +37,7 @@ You can use the `dev` script to run local changes as if you were invoking Vercel
When contributing to this repository, please first discuss the change you wish to make via [GitHub Discussions](https://github.com/vercel/vercel/discussions/new) with the owners of this repository before submitting a Pull Request.
Please read our [Code of Conduct](CODE_OF_CONDUCT.md) and follow it in all your interactions with the project.
Please read our [Code of Conduct](./.github/CODE_OF_CONDUCT.md) and follow it in all your interactions with the project.
### Local development

View File

@@ -1,5 +1,21 @@
# 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
### Patch Changes
- Updated dependencies [[`5a532a5b9`](https://github.com/vercel/vercel/commit/5a532a5b948994ba04783ac560357eed9f94a3f3), [`50fc27ba5`](https://github.com/vercel/vercel/commit/50fc27ba5773870956300bbbaffbe387d549bc12), [`c1d852295`](https://github.com/vercel/vercel/commit/c1d85229509dd319a1f11beb940a759113564d33), [`a5ea04154`](https://github.com/vercel/vercel/commit/a5ea04154ba26ee4e635d8953aa4f0d9d82d3a96)]:
- @vercel/next@4.2.8
- @vercel/node@3.1.0
## 34.1.8
### Patch Changes

View File

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

View File

@@ -0,0 +1,19 @@
# @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
### Major Changes
- Initial release ([#11553](https://github.com/vercel/vercel/pull/11553))

17
packages/functions/index.d.ts vendored Normal file
View File

@@ -0,0 +1,17 @@
/**
* Extends the lifetime of the request handler for the lifetime of the given {@link Promise}
* @see https://developer.mozilla.org/en-US/docs/Web/API/ExtendableEvent/waitUntil
*
* @param promise The promise to wait for.
* @example
*
* ```
* import { waitUntil } from '@vercel/functions';
*
* export function GET(request) {
* waitUntil(fetch('https://vercel.com'));
* return new Response('OK');
* }
* ```
*/
export function waitUntil(promise: Promise<unknown>): void;

View File

@@ -0,0 +1,16 @@
/* global globalThis */
exports.waitUntil = promise => {
if (
promise === null ||
typeof promise !== 'object' ||
typeof promise.then !== 'function'
) {
throw new TypeError(
`waitUntil can only be called with a Promise, got ${typeof promise}`
);
}
const ctx = globalThis[Symbol.for('@vercel/request-context')]?.get?.() ?? {};
ctx.waitUntil?.(promise);
};

View File

@@ -0,0 +1,42 @@
/* global globalThis */
import { vi, expect, test } from 'vitest';
import { waitUntil } from '.';
test.each([
{},
() => {},
function () {},
NaN,
1,
false,
undefined,
null,
[],
'▲',
])('waitUntil throws when called with %s', input => {
expect(() => waitUntil(input)).toThrow(TypeError);
expect(() => waitUntil(input)).toThrow(
`waitUntil can only be called with a Promise, got ${typeof input}`
);
});
test.each([null, undefined, {}])(
'waitUntil does not throw an error when context is %s',
input => {
const promise = Promise.resolve();
globalThis[Symbol.for('@vercel/request-context')] = input;
expect(() => waitUntil(promise)).not.toThrow();
}
);
test('waitUntil calls ctx.waitUntil when available', async () => {
const promise = Promise.resolve();
const waitUntilMock = vi.fn().mockReturnValue(promise);
globalThis[Symbol.for('@vercel/request-context')] = {
get: () => ({ waitUntil: waitUntilMock }),
};
waitUntil(promise);
expect(waitUntilMock).toHaveBeenCalledWith(promise);
});

View File

@@ -0,0 +1,33 @@
{
"name": "@vercel/functions",
"description": "Runtime functions to be used with your Vercel Functions",
"homepage": "https://vercel.com",
"version": "1.0.2",
"types": "index.d.ts",
"main": "index.js",
"repository": {
"directory": "packages/functions",
"type": "git",
"url": "git+https://github.com/vercel/vercel.git"
},
"bugs": {
"url": "https://github.com/vercel/vercel/issues"
},
"devDependencies": {
"vitest": "1.3.1"
},
"engines": {
"node": ">= 16"
},
"files": [
"index.d.ts",
"index.js"
],
"scripts": {
"test": "vitest"
},
"license": "Apache-2.0",
"publishConfig": {
"access": "public"
}
}

View File

@@ -1,5 +1,25 @@
# @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
### Patch Changes
- Fix missing initial RSC headers ([#11552](https://github.com/vercel/vercel/pull/11552))
- Remove .prefetch.rsc rewrites for non-PPR ([#11540](https://github.com/vercel/vercel/pull/11540))
- [next] rename middleware manifest env ([#11549](https://github.com/vercel/vercel/pull/11549))
## 4.2.7
### Patch Changes

View File

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

View File

@@ -218,7 +218,9 @@ export async function serverBuild({
}
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>> = {};
@@ -228,8 +230,6 @@ export async function serverBuild({
if (appPathRoutesManifest) {
appDir = path.join(pagesDir, '../app');
appBuildTraces = await glob('**/*.js.nft.json', appDir);
// TODO: maybe?
appRscPrefetches = experimental.ppr
? {}
: await glob(`**/*${RSC_PREFETCH_SUFFIX}`, appDir);
@@ -251,7 +251,7 @@ export async function serverBuild({
if (rewrite.src && rewrite.dest) {
rewrite.src = rewrite.src.replace(
/\/?\(\?:\/\)\?/,
'(?<rscsuff>(\\.prefetch)?\\.rsc)?(?:/)?'
`(?<rscsuff>${experimental.ppr ? '(\\.prefetch)?' : ''}\\.rsc)?(?:/)?`
);
let destQueryIndex = rewrite.dest.indexOf('?');
@@ -1601,6 +1601,10 @@ export async function serverBuild({
edgeFunctions[`${pathname}${RSC_PREFETCH_SUFFIX}`] =
edgeFunctions[pathname];
}
if (hasActionOutputSupport) {
edgeFunctions[`${pathname}.action`] = edgeFunctions[pathname];
}
}
}
}
@@ -1903,7 +1907,7 @@ export async function serverBuild({
...(appDir
? [
...(rscPrefetchHeader
...(rscPrefetchHeader && experimental.ppr
? [
{
src: `^${path.posix.join('/', entryDirectory, '/')}`,
@@ -2045,47 +2049,6 @@ export async function serverBuild({
]
: []),
...(rscPrefetchHeader && !experimental.ppr
? [
{
src: path.posix.join(
'/',
entryDirectory,
`/__index${RSC_PREFETCH_SUFFIX}`
),
dest: path.posix.join('/', entryDirectory, '/index.rsc'),
has: [
{
type: 'header',
key: rscPrefetchHeader,
},
],
continue: true,
override: true,
},
{
src: `^${path.posix.join(
'/',
entryDirectory,
`/(.+?)${RSC_PREFETCH_SUFFIX}(?:/)?$`
)}`,
dest: path.posix.join(
'/',
entryDirectory,
`/$1${experimental.ppr ? RSC_PREFETCH_SUFFIX : '.rsc'}`
),
has: [
{
type: 'header',
key: rscPrefetchHeader,
},
],
continue: true,
override: true,
},
]
: []),
// These need to come before handle: miss or else they are grouped
// with that routing section
...afterFilesRewrites,

View File

@@ -2465,6 +2465,7 @@ export const onPrerenderRoute =
...(rscEnabled
? {
initialHeaders: {
...initialHeaders,
'content-type': rscContentTypeHeader,
vary: rscVaryHeader,
// If it contains a pre-render, then it was postponed.
@@ -2784,7 +2785,7 @@ interface EdgeFunctionInfoV2 extends BaseEdgeFunctionInfo {
interface EdgeFunctionInfoV3 extends BaseEdgeFunctionInfo {
matchers: EdgeFunctionMatcher[];
environments: Record<string, string>;
env: Record<string, string>;
}
interface EdgeFunctionMatcher {
@@ -3019,7 +3020,7 @@ export async function getMiddlewareBundle({
slug: 'nextjs',
version: nextVersion,
},
environment: edgeFunction.environments,
environment: edgeFunction.env,
});
})(),
routeMatchers: getRouteMatchers(edgeFunction, routesManifest),
@@ -3199,7 +3200,7 @@ export function upgradeMiddlewareManifestV1(
return {
...rest,
matchers: [{ regexp }],
environments: {},
env: {},
};
}
@@ -3227,7 +3228,7 @@ export function upgradeMiddlewareManifestV2(
const { ...rest } = v2Info;
return {
...rest,
environments: {},
env: {},
};
}

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 = {};
function findActionId(page) {
function findActionId(page, runtime) {
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]) {
return actionId;
}
@@ -41,141 +43,115 @@ describe(`${__dirname.split(path.sep).pop()}`, () => {
Object.assign(ctx, info);
});
describe('client component', () => {
it('should bypass the static cache for a server action', async () => {
const path = '/client/static';
const actionId = findActionId(path);
describe.each(['node', 'edge'])('runtime: %s', runtime => {
const basePath = runtime === 'edge' ? '/edge' : '';
describe('client component', () => {
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}`, {
method: 'POST',
body: JSON.stringify([1337]),
headers: {
'Content-Type': 'text/plain;charset=UTF-8',
'Next-Action': actionId,
},
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 {
// 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);
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');
});
it('should bypass the static cache for a server action on a page with dynamic params', async () => {
const path = `${basePath}/client/static/[dynamic-static]`;
const actionId = findActionId(path, runtime);
it('should bypass the static cache for a server action on a page with dynamic params', async () => {
const path = '/client/static/[dynamic-static]';
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,
},
});
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');
}
});
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');
});
it('should bypass the static cache for a multipart request (no action header)', async () => {
const path = `${basePath}/client/static`;
const actionId = findActionId(path, runtime);
it('should bypass the static cache for a multipart request (no action header)', async () => {
const path = '/client/static';
const actionId = findActionId(path);
const res = await fetch(`${ctx.deploymentUrl}${path}`, {
method: 'POST',
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}`, {
method: 'POST',
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',
},
});
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]'
expect(res.status).toEqual(200);
expect(res.headers.get('content-type')).toBe(
'text/html; charset=utf-8'
);
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(
`${ctx.deploymentUrl}${path}`,
@@ -183,26 +159,94 @@ describe(`${__dirname.split(path.sep).pop()}`, () => {
);
expect(res.status).toEqual(200);
expect(res.headers.get('x-matched-path')).toBe(
'/rsc/static/generate-static-params/[slug].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('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 () => {
const page = '/rsc/static/generate-static-params/[slug]';
const actionId = findActionId(page);
it('should bypass the static cache for a server action on a page with dynamic params', async () => {
const path = `${basePath}/rsc/static/[dynamic-static]`;
const actionId = findActionId(path, runtime);
const res = await fetch(
`${ctx.deploymentUrl}/rsc/static/generate-static-params/not-pre-generated`,
`${ctx.deploymentUrl}${path}`,
generateFormDataPayload(actionId)
);
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('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": {
"next": "canary",
"react": "experimental",
"react-dom": "experimental"
"react": "19.0.0-beta-4508873393-20240430",
"react-dom": "19.0.0-beta-4508873393-20240430"
},
"ignoreNextjsUpdates": true
}

View File

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

View File

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

View File

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

View File

@@ -7,8 +7,8 @@
},
"dependencies": {
"next": "canary",
"react": "experimental",
"react-dom": "experimental"
"react": "19.0.0-beta-4508873393-20240430",
"react-dom": "19.0.0-beta-4508873393-20240430"
},
"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": {
"next": "canary",
"react": "experimental",
"react-dom": "experimental"
"react": "19.0.0-beta-4508873393-20240430",
"react-dom": "19.0.0-beta-4508873393-20240430"
},
"ignoreNextjsUpdates": true
}

View File

@@ -0,0 +1,7 @@
export default function Page() {
return (
<>
product page
</>
)
}

View File

@@ -13,6 +13,10 @@ module.exports = {
source: '/rewritten-to-index',
destination: '/?fromRewrite=1',
},
{
source: '/to-product/:productId.html',
destination: '/products/:productId',
},
];
},
};

View File

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

View File

@@ -18,6 +18,30 @@
}
],
"probes": [
{
"path": "/to-product/product-id.html",
"status": 200,
"mustContain": "<html"
},
{
"path": "/to-product/product-id.html",
"status": 200,
"mustNotContain": "<html",
"mustContain": ":",
"headers": {
"RSC": 1
}
},
{
"path": "/to-product/product-id.html",
"status": 200,
"mustNotContain": ".prefetch",
"mustContain": ":",
"headers": {
"RSC": 1,
"Next-Router-Prefetch": 1
}
},
{
"path": "/nested/blog-fallback-false/first",
"status": 200,
@@ -29,7 +53,7 @@
"mustContain": "{}",
"mustNotContain": ":",
"responseHeaders": {
"x-matched-path": "/nested/blog-fallback-false/first.prefetch.rsc"
"x-matched-path": "/nested/blog-fallback-false/first.rsc"
},
"headers": {
"RSC": 1,

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -4,5 +4,9 @@
"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": {
"next": "canary",
"react": "latest",
"react-dom": "latest"
"react": "19.0.0-beta-4508873393-20240430",
"react-dom": "19.0.0-beta-4508873393-20240430"
}
}

View File

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

View File

@@ -4,5 +4,9 @@
"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": {
"next": "canary",
"react": "latest",
"react-dom": "latest"
"react": "19.0.0-beta-4508873393-20240430",
"react-dom": "19.0.0-beta-4508873393-20240430"
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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