Compare commits

..

25 Commits

Author SHA1 Message Date
Marc Greenstock
5a61bb026b remove build-secret helper 2024-05-24 16:36:18 +02:00
Marc Greenstock
c3438ea5ed Remove secret from ProjectEnvType 2024-05-24 16:36:05 +02:00
Marc Greenstock
699bd6b2e8 remove Secret interface 2024-05-24 16:35:49 +02:00
Marc Greenstock
7fbe60f8cf remove secrets reference from error doc 2024-05-24 16:35:21 +02:00
Marc Greenstock
dadba3b975 Delete env-no-secret.md 2024-05-24 16:35:02 +02:00
Marc Greenstock
125eeecb06 remove secret related known errors 2024-05-23 16:50:14 +02:00
Marc Greenstock
9d6b78b76e delete secrets commands 2024-05-23 16:49:58 +02:00
Marc Greenstock
d0532107dd remove secrets from help 2024-05-23 16:48:30 +02:00
Marc Greenstock
3d58bd8d27 delete integration tests 2024-05-23 16:48:14 +02:00
Vercel Release Bot
6529a9ab9c Version Packages (#11637)
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.2.2

### Patch Changes

- Fix related to erroring when a prefetch route is not provided but the
route is PPR enabled
([#11638](https://github.com/vercel/vercel/pull/11638))

- Updated dependencies
\[[`8e44ef5b9`](8e44ef5b9d),
[`61e6af374`](61e6af3740)]:
    -   @vercel/next@4.2.13

## @vercel/next@4.2.13

### Patch Changes

- Fix static case for detecting when a page supports PPR
([#11635](https://github.com/vercel/vercel/pull/11635))

- Fix related to erroring when a prefetch route is not provided but the
route is PPR enabled
([#11638](https://github.com/vercel/vercel/pull/11638))

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-05-23 10:33:01 +02:00
Wyatt Johnson
61e6af3740 [ppr] Fix for error case involving prefetch data routes (#11638)
Only error when the prefetch data route is present but the route also
has PPR enabled.
2024-05-23 10:28:05 +02:00
Wyatt Johnson
8e44ef5b9d [ppr] Fix static case (#11635)
When PPR is enabled in incremental mode, the previous code used the page information to determine if there was a failure for generating the flight data. This has been moved to the app PPR setting instead.
2024-05-23 05:23:26 +00:00
Wyatt Johnson
fe9e27c459 chore: bump react version (#11636) 2024-05-23 05:14:10 +00:00
Vercel Release Bot
8a6dc204fd Version Packages (#11634)
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.2.1

### Patch Changes

- Support incremental PPR for large applications
([#11625](https://github.com/vercel/vercel/pull/11625))

- Updated dependencies
\[[`73e558913`](73e558913a)]:
    -   @vercel/next@4.2.12

## @vercel/next@4.2.12

### Patch Changes

- Support incremental PPR for large applications
([#11625](https://github.com/vercel/vercel/pull/11625))

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-05-22 21:14:01 -07:00
Wyatt Johnson
73e558913a [ppr] Fix PPR detection for groups (#11625)
Previously, PPR was either all on, or all off. As we've added support for incremental adoption of PPR, the logic for determining if there's a grouping issue had to be adjusted.

This now only considers a group as supporting PPR if a route in the group supports PPR. As we also use this as a grouping key, this still ensures we won't have conflicts.
2024-05-23 04:06:12 +00:00
Wyatt Johnson
464cb26255 chore: bump react versions (#11632) 2024-05-22 19:45:03 -07:00
Zack Tanner
80e0bab0ec [next] Fix Next.js tests (#11610)
Syncs the experimental React dependency to avoid build errors. 

This was updated in:
- https://github.com/vercel/next.js/pull/65864
2024-05-17 22:24:53 +00:00
Trek Glowacki
f900ca8daf [framework-fixtures] add missing dependency to dependabot (#11606)
Hydrogen has a peer-dep on remix.
2024-05-16 20:33:36 -05:00
Nathan Rajlich
9ee7d31957 [cli] Add test for CLI extensions passing through exit code (#11600)
/cc @codybrouwers
2024-05-15 20:02:40 +00:00
Vercel Release Bot
1eb76a3ae7 Version Packages (#11598)
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/build-utils@8.2.0

### Minor Changes

- fix corepack detection for package manager version determination
([#11596](https://github.com/vercel/vercel/pull/11596))

### Patch Changes

- Fix triggering of ignored project settings node version warning
([#11550](https://github.com/vercel/vercel/pull/11550))

## vercel@34.2.0

### Minor Changes

- Stop sending system environment variables in dev
([#11526](https://github.com/vercel/vercel/pull/11526))

### Patch Changes

- Updated dependencies
\[[`d3c1267e2`](d3c1267e24),
[`ccd7eb1fb`](ccd7eb1fb7)]:
    -   @vercel/build-utils@8.2.0
    -   @vercel/node@3.1.5
    -   @vercel/static-build@2.5.9

## @vercel/client@13.2.7

### Patch Changes

- Updated dependencies
\[[`d3c1267e2`](d3c1267e24),
[`ccd7eb1fb`](ccd7eb1fb7)]:
    -   @vercel/build-utils@8.2.0

## @vercel/gatsby-plugin-vercel-builder@2.0.31

### Patch Changes

- Updated dependencies
\[[`d3c1267e2`](d3c1267e24),
[`ccd7eb1fb`](ccd7eb1fb7)]:
    -   @vercel/build-utils@8.2.0

## @vercel/node@3.1.5

### Patch Changes

- Updated dependencies
\[[`d3c1267e2`](d3c1267e24),
[`ccd7eb1fb`](ccd7eb1fb7)]:
    -   @vercel/build-utils@8.2.0

## @vercel/static-build@2.5.9

### Patch Changes

-   Updated dependencies \[]:
    -   @vercel/gatsby-plugin-vercel-builder@2.0.31

## @vercel-internals/types@1.0.36

### Patch Changes

- Updated dependencies
\[[`d3c1267e2`](d3c1267e24),
[`ccd7eb1fb`](ccd7eb1fb7)]:
    -   @vercel/build-utils@8.2.0

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2024-05-15 14:26:56 -05:00
Sean Massa
ccd7eb1fb7 fix corepack detection for package manager version determination (#11596)
The previous logic was checking for the env var `ENABLE_EXPERIMENTAL_COREPACK` to determine if corepack was being used by a project. However, this value only means that the build system should consider corepack, not that it's actively being used.

We need to check that flag AND the existence of a `packageManager` property in the project's `package.json`.
2024-05-15 19:25:01 +00:00
Austin Merrick
41c44d6594 [build-utils] Refactor getNodeVersion (#11599)
Makes variable names more clear and consistent.
2024-05-15 17:17:41 +00:00
Austin Merrick
446ac49e2b [cli] Don't pull system environment vars in dev (#11526)
System environment variables would get set with empty strings in development which breaks some builds. This fixes that by using the v2 of `/env/pull` introduced in https://github.com/vercel/api/pull/27777.
2024-05-15 12:17:47 +00:00
Austin Merrick
d3c1267e24 [build-utils] Fix warn for ignored project settings node version (#11550)
There were scenarios where the warning "Node.js Version defined in your Project Settings ("18.x") will not apply" would not be triggered. For example:

1. Project Setting is 18.x
2. package.json has "engines.node": ">=18.x"
3. semver.intersects('18.x', '>=18.x') // => true (In this [code path](8ea93839cc/packages/build-utils/src/fs/run-user-scripts.ts (L258))) -> No warning message that Node.js Version was changed
4. After the error message we evaluate the latest node Version to use (20.x) in getSupportedNodeVersion()(this [code path](8ea93839cc/packages/build-utils/src/fs/run-user-scripts.ts (L274)))
5. User doesn't get notified that we changed the node version to something different than their project setting

This fixes that scenario by getting the supported node version first.
2024-05-14 23:23:17 +00:00
Sean Massa
b09d7b6130 [tests] allow errors to define retry delay (#11597)
Errors can now define their own retry delay. This is necessary for some
kinds of errors where all retries will run within the same second.
2024-05-14 14:15:31 -05:00
167 changed files with 688 additions and 1218 deletions

View File

@@ -63,16 +63,21 @@ updates:
allow:
- dependency-name: '@remix-run*'
- dependency-name: '@shopify*'
- dependency-name: 'remix*'
ignore:
- dependency-name: '@remix-run*'
update-types:
['version-update:semver-major', 'version-update:semver-patch']
- dependency-name: 'remix*'
update-types:
['version-update:semver-major', 'version-update:semver-patch']
- dependency-name: '@shopify*'
update-types:
['version-update:semver-major', 'version-update:semver-patch']
groups:
core:
patterns:
- 'remix*'
- '@remix-run*'
- '@shopify*'
update-types:

View File

@@ -1,17 +0,0 @@
# Secret Not Found
#### Why This Error Occurred
You specified the `--env` or `-e` flag with the value of a secret. However, the secret doesn't exist in the current scope you're in.
#### Possible Ways to Fix It
Make sure to specify the environment variable and secret like that:
```bash
vercel -e VARIABLE_NAME=@secret-name
```
In addition, ensure that the secret (`@secret-name` in the example above) exists in the current scope (the team or user account that you're using).
You can run `vercel switch` or `--scope` to switch to a different team or user.

View File

@@ -11,9 +11,3 @@ Make sure to set the name and value of the variable like this:
```bash
vercel -e VARIABLE_NAME="VALUE"
```
You can also specify a environment variable that contains a secret:
```bash
vercel -e VARIABLE_NAME=@secret-name
```

View File

@@ -9,7 +9,7 @@
},
"devDependencies": {
"@types/jest": "27.4.1",
"@vercel/build-utils": "8.1.3",
"@vercel/build-utils": "8.2.0",
"@vercel/frameworks": "3.0.2"
},
"version": null

View File

@@ -1,5 +1,12 @@
# @vercel-internals/types
## 1.0.36
### Patch Changes
- Updated dependencies [[`d3c1267e2`](https://github.com/vercel/vercel/commit/d3c1267e24082789ea6382cf6af81dd40df288ff), [`ccd7eb1fb`](https://github.com/vercel/vercel/commit/ccd7eb1fb78f7ac9effdbe1935de3bda82c97fe3)]:
- @vercel/build-utils@8.2.0
## 1.0.35
### Patch Changes

View File

@@ -7,7 +7,6 @@ import { PROJECT_ENV_TARGET } from '@vercel-internals/constants';
export type ProjectEnvTarget = typeof PROJECT_ENV_TARGET[number];
export type ProjectEnvType =
| 'plain'
| 'secret'
| 'encrypted'
| 'system'
| 'sensitive';
@@ -303,17 +302,6 @@ export interface ProjectAliasTarget {
deployment?: Deployment | undefined;
}
export interface Secret {
uid: string;
name: string;
value: string;
teamId?: string;
userId?: string;
projectId?: string;
created: string;
createdAt: number;
}
export interface ProjectEnvVariable {
id: string;
key: string;

View File

@@ -1,7 +1,7 @@
{
"private": true,
"name": "@vercel-internals/types",
"version": "1.0.35",
"version": "1.0.36",
"types": "index.d.ts",
"main": "index.d.ts",
"files": [
@@ -10,7 +10,7 @@
"dependencies": {
"@types/node": "14.14.31",
"@vercel-internals/constants": "1.0.4",
"@vercel/build-utils": "8.1.3",
"@vercel/build-utils": "8.2.0",
"@vercel/routing-utils": "3.1.0"
},
"devDependencies": {

View File

@@ -1,5 +1,15 @@
# @vercel/build-utils
## 8.2.0
### Minor Changes
- fix corepack detection for package manager version determination ([#11596](https://github.com/vercel/vercel/pull/11596))
### Patch Changes
- Fix triggering of ignored project settings node version warning ([#11550](https://github.com/vercel/vercel/pull/11550))
## 8.1.3
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/build-utils",
"version": "8.1.3",
"version": "8.2.0",
"license": "Apache-2.0",
"main": "./dist/index.js",
"types": "./dist/index.d.js",

View File

@@ -240,38 +240,51 @@ export function getSpawnOptions(
export async function getNodeVersion(
destPath: string,
nodeVersionFallback = process.env.VERCEL_PROJECT_SETTINGS_NODE_VERSION,
fallbackVersion = process.env.VERCEL_PROJECT_SETTINGS_NODE_VERSION,
config: Config = {},
meta: Meta = {},
availableVersions = getAvailableNodeVersions()
): Promise<NodeVersion> {
const latest = getLatestNodeVersion(availableVersions);
const latestVersion = getLatestNodeVersion(availableVersions);
if (meta.isDev) {
// Use the system-installed version of `node` in PATH for `vercel dev`
return { ...latest, runtime: 'nodejs' };
return { ...latestVersion, runtime: 'nodejs' };
}
const { packageJson } = await scanParentDirs(destPath, true);
let nodeVersion = config.nodeVersion || nodeVersionFallback;
let isAuto = true;
const configuredVersion = config.nodeVersion || fallbackVersion;
const packageJsonVersion = packageJson?.engines?.node;
const supportedNodeVersion = await getSupportedNodeVersion(
packageJsonVersion || configuredVersion,
!packageJsonVersion,
availableVersions
);
if (packageJson?.engines?.node) {
const { node } = packageJson.engines;
if (nodeVersion && validRange(node) && !intersects(nodeVersion, node)) {
if (
configuredVersion &&
!intersects(configuredVersion, supportedNodeVersion.range)
) {
console.warn(
`Warning: Due to "engines": { "node": "${node}" } in your \`package.json\` file, the Node.js Version defined in your Project Settings ("${nodeVersion}") will not apply. Learn More: http://vercel.link/node-version`
`Warning: Due to "engines": { "node": "${node}" } in your \`package.json\` file, the Node.js Version defined in your Project Settings ("${configuredVersion}") will not apply. Learn More: http://vercel.link/node-version`
);
} else if (coerce(node)?.raw === node) {
}
if (coerce(node)?.raw === node) {
console.warn(
`Warning: Detected "engines": { "node": "${node}" } in your \`package.json\` with major.minor.patch, but only major Node.js Version can be selected. Learn More: http://vercel.link/node-version`
);
} else if (validRange(node) && intersects(`${latest.major + 1}.x`, node)) {
} else if (
validRange(node) &&
intersects(`${latestVersion.major + 1}.x`, node)
) {
console.warn(
`Warning: Detected "engines": { "node": "${node}" } in your \`package.json\` that will automatically upgrade when a new major Node.js Version is released. Learn More: http://vercel.link/node-version`
);
}
nodeVersion = node;
isAuto = false;
}
return getSupportedNodeVersion(nodeVersion, isAuto, availableVersions);
return supportedNodeVersion;
}
export async function scanParentDirs(
@@ -413,9 +426,8 @@ export async function runNpmInstall(
try {
await runNpmInstallSema.acquire();
const { cliType, packageJsonPath, lockfileVersion } = await scanParentDirs(
destPath
);
const { cliType, packageJsonPath, packageJson, lockfileVersion } =
await scanParentDirs(destPath, true);
if (!packageJsonPath) {
debug(
@@ -450,6 +462,7 @@ export async function runNpmInstall(
opts.env = getEnvForPackageManager({
cliType,
lockfileVersion,
packageJsonPackageManager: packageJson?.packageManager,
nodeVersion,
env,
});
@@ -534,14 +547,19 @@ export async function runNpmInstall(
export function getEnvForPackageManager({
cliType,
lockfileVersion,
packageJsonPackageManager,
nodeVersion,
env,
}: {
cliType: CliType;
lockfileVersion: number | undefined;
packageJsonPackageManager?: string | undefined;
nodeVersion: NodeVersion | undefined;
env: { [x: string]: string | undefined };
}) {
const corepackFlagged = env.ENABLE_EXPERIMENTAL_COREPACK === '1';
const corepackEnabled = corepackFlagged && Boolean(packageJsonPackageManager);
const {
detectedLockfile,
detectedPackageManager,
@@ -549,14 +567,19 @@ export function getEnvForPackageManager({
} = getPathOverrideForPackageManager({
cliType,
lockfileVersion,
corepackEnabled,
nodeVersion,
env,
});
const corepackEnabled = env.ENABLE_EXPERIMENTAL_COREPACK === '1';
debug(
`Detected ${detectedPackageManager} given lockfileVersion "${lockfileVersion}", package manager cli "${cliType}", and corepack enabled? ${corepackEnabled}: ${newPath}`
);
if (corepackEnabled) {
debug(
`Detected corepack use for "${packageJsonPackageManager}". Not overriding package manager version.`
);
} else {
debug(
`Detected ${detectedPackageManager}. Added "${newPath}" to path. Based on assumed package manager "${cliType}", lockfile "${detectedLockfile}", and lockfileVersion "${lockfileVersion}"`
);
}
const newEnv: { [x: string]: string | undefined } = {
...env,
@@ -642,13 +665,13 @@ function shouldUseNpm7(
export function getPathOverrideForPackageManager({
cliType,
lockfileVersion,
corepackEnabled,
nodeVersion,
env,
}: {
cliType: CliType;
lockfileVersion: number | undefined;
corepackEnabled: boolean;
nodeVersion: NodeVersion | undefined;
env: { [x: string]: string | undefined };
}): {
/**
* Which lockfile was detected.
@@ -670,8 +693,6 @@ export function getPathOverrideForPackageManager({
path: undefined,
};
const corepackEnabled = env.ENABLE_EXPERIMENTAL_COREPACK === '1';
switch (cliType) {
case 'npm':
switch (true) {
@@ -735,6 +756,7 @@ export function getPathOverrideForPackageManager({
/**
* Helper to get the binary paths that link to the used package manager.
* Note: Make sure it doesn't contain any `console.log` calls.
* @deprecated use `getEnvForPackageManager` instead
*/
export function getPathForPackageManager({
cliType,
@@ -766,11 +788,16 @@ export function getPathForPackageManager({
*/
yarnNodeLinker: string | undefined;
} {
// This is not the correct check for whether or not corepack is being used. For that, you'd have to check
// the package.json's `packageManager` property. However, this deprecated function is keeping it's old,
// broken behavior.
const corepackEnabled = env.ENABLE_EXPERIMENTAL_COREPACK === '1';
const overrides = getPathOverrideForPackageManager({
cliType,
lockfileVersion,
corepackEnabled,
nodeVersion,
env,
});
const alreadyInPath = (newPath: string) => {
@@ -805,10 +832,14 @@ export async function runCustomInstallCommand({
spawnOpts?: SpawnOptions;
}) {
console.log(`Running "install" command: \`${installCommand}\`...`);
const { cliType, lockfileVersion } = await scanParentDirs(destPath);
const { cliType, lockfileVersion, packageJson } = await scanParentDirs(
destPath,
true
);
const env = getEnvForPackageManager({
cliType,
lockfileVersion,
packageJsonPackageManager: packageJson?.packageManager,
nodeVersion,
env: spawnOpts?.env || {},
});
@@ -846,6 +877,7 @@ export async function runPackageJsonScript(
env: getEnvForPackageManager({
cliType,
lockfileVersion,
packageJsonPackageManager: packageJson?.packageManager,
nodeVersion: undefined,
env: cloneEnv(process.env, spawnOpts?.env),
}),

View File

@@ -35,6 +35,7 @@ describe('Test `getEnvForPackageManager()`', () => {
args: {
cliType: 'npm',
nodeVersion: { major: 14, range: '14.x', runtime: 'nodejs14.x' },
packageJsonPackageManager: undefined,
lockfileVersion: 1,
env: {
FOO: 'bar',
@@ -51,6 +52,7 @@ describe('Test `getEnvForPackageManager()`', () => {
args: {
cliType: 'npm',
nodeVersion: { major: 14, range: '14.x', runtime: 'nodejs14.x' },
packageJsonPackageManager: undefined,
lockfileVersion: 2,
env: {
FOO: 'bar',
@@ -69,6 +71,7 @@ describe('Test `getEnvForPackageManager()`', () => {
args: {
cliType: 'npm',
nodeVersion: { major: 14, range: '14.x', runtime: 'nodejs14.x' },
packageJsonPackageManager: 'pnpm@latest',
lockfileVersion: 2,
env: {
FOO: 'bar',
@@ -87,6 +90,7 @@ describe('Test `getEnvForPackageManager()`', () => {
args: {
cliType: 'npm',
nodeVersion: { major: 14, range: '14.x', runtime: 'nodejs14.x' },
packageJsonPackageManager: undefined,
lockfileVersion: 2,
env: {
FOO: 'bar',
@@ -105,6 +109,7 @@ describe('Test `getEnvForPackageManager()`', () => {
args: {
cliType: 'npm',
nodeVersion: { major: 16, range: '16.x', runtime: 'nodejs16.x' },
packageJsonPackageManager: undefined,
lockfileVersion: 2,
env: {
FOO: 'bar',
@@ -123,6 +128,7 @@ describe('Test `getEnvForPackageManager()`', () => {
args: {
cliType: 'yarn',
nodeVersion: { major: 16, range: '16.x', runtime: 'nodejs16.x' },
packageJsonPackageManager: undefined,
lockfileVersion: 2,
env: {
FOO: 'bar',
@@ -140,6 +146,7 @@ describe('Test `getEnvForPackageManager()`', () => {
args: {
cliType: 'yarn',
nodeVersion: { major: 16, range: '16.x', runtime: 'nodejs16.x' },
packageJsonPackageManager: undefined,
lockfileVersion: 2,
env: {
FOO: 'bar',
@@ -158,6 +165,7 @@ describe('Test `getEnvForPackageManager()`', () => {
args: {
cliType: 'pnpm',
nodeVersion: { major: 16, range: '16.x', runtime: 'nodejs16.x' },
packageJsonPackageManager: undefined,
lockfileVersion: 5.4,
env: {
FOO: 'bar',
@@ -177,6 +185,7 @@ describe('Test `getEnvForPackageManager()`', () => {
args: {
cliType: 'pnpm',
nodeVersion: { major: 18, range: '18.x', runtime: 'nodejs18.x' },
packageJsonPackageManager: undefined,
lockfileVersion: 6.0,
env: {
FOO: 'bar',
@@ -196,6 +205,7 @@ describe('Test `getEnvForPackageManager()`', () => {
args: {
cliType: 'pnpm',
nodeVersion: { major: 18, range: '18.x', runtime: 'nodejs18.x' },
packageJsonPackageManager: undefined,
lockfileVersion: 9.0,
env: {
FOO: 'bar',
@@ -215,6 +225,7 @@ describe('Test `getEnvForPackageManager()`', () => {
args: {
cliType: 'bun',
nodeVersion: { major: 18, range: '18.x', runtime: 'nodejs18.x' },
packageJsonPackageManager: undefined,
lockfileVersion: 0,
env: {
FOO: 'bar',
@@ -234,6 +245,7 @@ describe('Test `getEnvForPackageManager()`', () => {
args: {
cliType: 'pnpm',
nodeVersion: { major: 16, range: '16.x', runtime: 'nodejs16.x' },
packageJsonPackageManager: 'npm@latest',
lockfileVersion: 5.4,
env: {
FOO: 'bar',
@@ -252,6 +264,7 @@ describe('Test `getEnvForPackageManager()`', () => {
args: {
cliType: 'pnpm',
nodeVersion: { major: 16, range: '16.x', runtime: 'nodejs16.x' },
packageJsonPackageManager: undefined,
lockfileVersion: 5.4,
env: {
FOO: 'bar',
@@ -270,6 +283,7 @@ describe('Test `getEnvForPackageManager()`', () => {
getEnvForPackageManager({
cliType: args.cliType,
lockfileVersion: args.lockfileVersion,
packageJsonPackageManager: args.packageJsonPackageManager,
nodeVersion: args.nodeVersion,
env: args.env,
})
@@ -302,6 +316,7 @@ describe('Test `getPathOverrideForPackageManager()`', () => {
args: {
cliType: 'npm',
nodeVersion: { major: 14, range: '14.x', runtime: 'nodejs14.x' },
packageJsonPackageManager: undefined,
lockfileVersion: 1,
env: {
FOO: 'bar',
@@ -318,6 +333,7 @@ describe('Test `getPathOverrideForPackageManager()`', () => {
args: {
cliType: 'npm',
nodeVersion: { major: 14, range: '14.x', runtime: 'nodejs14.x' },
packageJsonPackageManager: undefined,
lockfileVersion: 2,
env: {
FOO: 'bar',
@@ -335,6 +351,7 @@ describe('Test `getPathOverrideForPackageManager()`', () => {
args: {
cliType: 'npm',
nodeVersion: { major: 14, range: '14.x', runtime: 'nodejs14.x' },
packageJsonPackageManager: 'pnpm@latest',
lockfileVersion: 2,
env: {
FOO: 'bar',
@@ -353,6 +370,7 @@ describe('Test `getPathOverrideForPackageManager()`', () => {
args: {
cliType: 'npm',
nodeVersion: { major: 16, range: '16.x', runtime: 'nodejs16.x' },
packageJsonPackageManager: undefined,
lockfileVersion: 2,
env: {
FOO: 'bar',
@@ -370,6 +388,7 @@ describe('Test `getPathOverrideForPackageManager()`', () => {
args: {
cliType: 'pnpm',
nodeVersion: { major: 16, range: '16.x', runtime: 'nodejs16.x' },
packageJsonPackageManager: undefined,
lockfileVersion: 5.3, // detects as pnpm@6, which is the default
env: {
FOO: 'bar',
@@ -387,6 +406,7 @@ describe('Test `getPathOverrideForPackageManager()`', () => {
args: {
cliType: 'pnpm',
nodeVersion: { major: 16, range: '16.x', runtime: 'nodejs16.x' },
packageJsonPackageManager: undefined,
lockfileVersion: 5.4,
env: {
FOO: 'bar',
@@ -404,6 +424,7 @@ describe('Test `getPathOverrideForPackageManager()`', () => {
args: {
cliType: 'pnpm',
nodeVersion: { major: 18, range: '18.x', runtime: 'nodejs18.x' },
packageJsonPackageManager: undefined,
lockfileVersion: 6.1,
env: {
FOO: 'bar',
@@ -421,6 +442,7 @@ describe('Test `getPathOverrideForPackageManager()`', () => {
args: {
cliType: 'pnpm',
nodeVersion: { major: 18, range: '18.x', runtime: 'nodejs18.x' },
packageJsonPackageManager: undefined,
lockfileVersion: 7.0,
env: {
FOO: 'bar',
@@ -438,6 +460,7 @@ describe('Test `getPathOverrideForPackageManager()`', () => {
args: {
cliType: 'bun',
nodeVersion: { major: 18, range: '18.x', runtime: 'nodejs18.x' },
packageJsonPackageManager: undefined,
lockfileVersion: 0,
env: {
FOO: 'bar',
@@ -455,6 +478,7 @@ describe('Test `getPathOverrideForPackageManager()`', () => {
args: {
cliType: 'pnpm',
nodeVersion: { major: 16, range: '16.x', runtime: 'nodejs16.x' },
packageJsonPackageManager: 'npm@latest',
lockfileVersion: 5.4,
env: {
FOO: 'bar',
@@ -472,16 +496,18 @@ describe('Test `getPathOverrideForPackageManager()`', () => {
getPathOverrideForPackageManager({
cliType: args.cliType,
lockfileVersion: args.lockfileVersion,
// naive assumption that enabling corepack as a feature means it's used, but this is fine for tests
corepackEnabled: Boolean(args.env.ENABLE_EXPERIMENTAL_COREPACK),
nodeVersion: args.nodeVersion,
env: args.env,
})
).toStrictEqual(want);
});
});
describe('Test `getPathForPackageManager()`', () => {
test.each<{
name: string;
args: Parameters<typeof getEnvForPackageManager>[0];
args: Parameters<typeof getPathForPackageManager>[0];
want: unknown;
}>([
{

View File

@@ -221,6 +221,21 @@ it('should warn when package.json engines is greater than', async () => {
]);
});
it('should warn when project settings gets overrided', async () => {
expect(
await getNodeVersion(
path.join(__dirname, 'pkg-engine-node-greaterthan'),
undefined,
{ nodeVersion: '16.x' },
{}
)
).toHaveProperty('range', '20.x');
expect(warningMessages).toStrictEqual([
'Warning: Due to "engines": { "node": ">=16" } in your `package.json` file, the Node.js Version defined in your Project Settings ("16.x") will not apply. Learn More: http://vercel.link/node-version',
'Warning: Detected "engines": { "node": ">=16" } in your `package.json` that will automatically upgrade when a new major Node.js Version is released. Learn More: http://vercel.link/node-version',
]);
});
it('should not warn when package.json engines matches project setting from config', async () => {
expect(
await getNodeVersion(

View File

@@ -1,5 +1,36 @@
# vercel
## 34.2.2
### Patch Changes
- Fix related to erroring when a prefetch route is not provided but the route is PPR enabled ([#11638](https://github.com/vercel/vercel/pull/11638))
- Updated dependencies [[`8e44ef5b9`](https://github.com/vercel/vercel/commit/8e44ef5b9d2cdbe743c7f1e3534f182465fed9bf), [`61e6af374`](https://github.com/vercel/vercel/commit/61e6af3740296c11015d0c3da84ee205020b0ea6)]:
- @vercel/next@4.2.13
## 34.2.1
### Patch Changes
- Support incremental PPR for large applications ([#11625](https://github.com/vercel/vercel/pull/11625))
- Updated dependencies [[`73e558913`](https://github.com/vercel/vercel/commit/73e558913ab30ba097d7536a12fa8a7c967479f0)]:
- @vercel/next@4.2.12
## 34.2.0
### Minor Changes
- Stop sending system environment variables in dev ([#11526](https://github.com/vercel/vercel/pull/11526))
### Patch Changes
- Updated dependencies [[`d3c1267e2`](https://github.com/vercel/vercel/commit/d3c1267e24082789ea6382cf6af81dd40df288ff), [`ccd7eb1fb`](https://github.com/vercel/vercel/commit/ccd7eb1fb78f7ac9effdbe1935de3bda82c97fe3)]:
- @vercel/build-utils@8.2.0
- @vercel/node@3.1.5
- @vercel/static-build@2.5.9
## 34.1.14
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "vercel",
"version": "34.1.14",
"version": "34.2.2",
"preferGlobal": true,
"license": "Apache-2.0",
"description": "The command-line interface for Vercel",
@@ -32,17 +32,17 @@
"node": ">= 16"
},
"dependencies": {
"@vercel/build-utils": "8.1.3",
"@vercel/build-utils": "8.2.0",
"@vercel/fun": "1.1.0",
"@vercel/go": "3.1.1",
"@vercel/hydrogen": "1.0.2",
"@vercel/next": "4.2.11",
"@vercel/node": "3.1.4",
"@vercel/next": "4.2.13",
"@vercel/node": "3.1.5",
"@vercel/python": "4.2.0",
"@vercel/redwood": "2.0.9",
"@vercel/remix-builder": "2.1.6",
"@vercel/ruby": "2.1.0",
"@vercel/static-build": "2.5.8",
"@vercel/static-build": "2.5.9",
"chokidar": "3.3.1"
},
"devDependencies": {
@@ -92,8 +92,8 @@
"@types/yauzl-promise": "2.1.0",
"@vercel-internals/constants": "1.0.4",
"@vercel-internals/get-package-json": "1.0.0",
"@vercel-internals/types": "1.0.35",
"@vercel/client": "13.2.6",
"@vercel-internals/types": "1.0.36",
"@vercel/client": "13.2.7",
"@vercel/error-utils": "2.0.2",
"@vercel/frameworks": "3.0.2",
"@vercel/fs-detectors": "5.2.3",

View File

@@ -39,7 +39,6 @@ export const help = () => `
logs [url] Displays the logs for a deployment
projects Manages your Projects
rm | remove [id] Removes a deployment
secrets [name] Manages your global Secrets, for use in Environment Variables
teams Manages your teams
whoami Shows the username of the currently logged in user

View File

@@ -32,8 +32,6 @@ export default new Map([
['remove', 'remove'],
['rm', 'remove'],
['rollback', 'rollback'],
['secret', 'secrets'],
['secrets', 'secrets'],
['switch', 'teams'],
['team', 'teams'],
['teams', 'teams'],

View File

@@ -1,101 +0,0 @@
import { packageName, getCommandName } from '../../util/pkg-name';
export const secretsCommand = {
name: 'secrets',
description:
'WARNING: On May 1st, 2024 secrets will be automatically converted to sensitive Environment Variables for Preview and Production environments. Secrets attached to Development environments will not be migrated.\n' +
`The ${getCommandName(
'secrets'
)} command will be deprecated at this time, please use the ${getCommandName(
'env'
)} command instead.\n` +
'See https://vercel.com/changelog/legacy-environment-variable-secrets-are-being-sunset for more information.',
arguments: [
{
name: 'command',
required: false,
},
],
subcommands: [
{
name: 'ls',
description: 'Show all secrets in a list',
arguments: [],
options: [],
examples: [],
},
{
name: 'add',
description: 'Add a new secret',
arguments: [
{
name: 'name',
required: true,
},
{
name: 'value',
required: true,
},
],
options: [],
examples: [],
},
{
name: 'rename',
description: 'Change the name of a secret',
arguments: [
{
name: 'old-name',
required: true,
},
{
name: 'new-name',
required: true,
},
],
options: [],
examples: [],
},
{
name: 'rm',
description: 'Remove a secret',
arguments: [
{
name: 'name',
required: true,
},
],
options: [],
examples: [],
},
],
options: [
{
name: 'next',
description: 'Show next page of results',
argument: 'MS',
shorthand: 'n',
type: 'string',
deprecated: false,
multi: false,
},
],
examples: [
{
name: 'Add a new secret',
value: `${packageName} secrets add my-secret "my value"
- Once added, a secret's value can't be retrieved in plain text anymore
- If the secret's value is more than one word, wrap it in quotes
- When in doubt, always wrap your value in quotes`,
},
{
name: 'Expose a secret as an environment variable (notice the `@` symbol)',
value: `${packageName} -e MY_SECRET=@my-secret`,
},
{
name: 'Paginate results, where 1584722256178 is the time in milliseconds since the UNIX epoch',
value: `$ ${packageName} secrets ls --next 1584722256178`,
},
],
};

View File

@@ -1,309 +0,0 @@
import isErrnoException from '@vercel/error-utils';
import chalk from 'chalk';
import table from '../../util/output/table';
import ms from 'ms';
import { handleError, error } from '../../util/error';
import NowSecrets from '../../util/secrets';
import getScope from '../../util/get-scope';
import confirm from '../../util/input/confirm';
import getCommandFlags from '../../util/get-command-flags';
import { getCommandName } from '../../util/pkg-name';
import getArgs from '../../util/get-args';
import { help } from '../help';
import { secretsCommand } from './command';
// Options
let argv;
let subcommand;
let nextTimestamp;
const main = async client => {
argv = getArgs(client.argv.slice(2), {
'--yes': Boolean,
'--next': Number,
'--test-warning': Boolean,
'-y': '--yes',
'-N': '--next',
});
argv._ = argv._.slice(1);
subcommand = argv._[0];
nextTimestamp = argv.next;
if (argv.help || !subcommand) {
client.output.print(
help(secretsCommand, { columns: client.stderr.columns })
);
return 2;
}
const {
output,
config: { currentTeam },
} = client;
let contextName = null;
try {
({ contextName } = await getScope(client));
} catch (err) {
if (isErrnoException(err)) {
if (err.code === 'NOT_AUTHORIZED' || err.code === 'TEAM_DELETED') {
output.error(err.message);
return 1;
}
}
throw err;
}
return run({ output, contextName, currentTeam, client });
};
export default async client => {
try {
return await main(client);
} catch (err) {
handleError(err);
process.exit(1);
}
};
async function run({ output, contextName, currentTeam, client }) {
const secrets = new NowSecrets({ client, currentTeam });
const args = argv._.slice(1);
const start = Date.now();
const { '--test-warning': testWarningFlag } = argv;
const commandName = getCommandName('secret ' + subcommand);
output.warn(
'On May 1st, 2024 secrets will be automatically converted to sensitive Environment Variables for Preview and Production environments.\n' +
'Secrets attached to Development environments will not be migrated.' +
'See https://vercel.com/changelog/legacy-environment-variable-secrets-are-being-sunset for more information.'
);
if (subcommand === 'ls' || subcommand === 'list') {
output.note(
`The ${getCommandName(
'env ls'
)} command is recommended instead of ${commandName}\n`
);
if (args.length > 1) {
// consider replacing with `output.error`
// eslint-disable-next-line no-console
console.error(
error(
`Invalid number of arguments. Usage: ${chalk.cyan(
`${getCommandName('secret ls')}`
)}`
)
);
return 1;
}
const { secrets: list, pagination } = await secrets.ls(
nextTimestamp,
testWarningFlag
);
const elapsed = ms(Date.now() - start);
output.print(
`${list.length > 0 ? 'Secrets' : 'No secrets'} found under ${chalk.bold(
contextName
)} ${chalk.gray(`[${elapsed}]`)}\n`
);
if (list.length > 0) {
const cur = Date.now();
const header = [['', 'name', 'created'].map(s => chalk.dim(s))];
const out = table(
header.concat(
list.map(secret => [
'',
chalk.bold(secret.name),
chalk.gray(`${ms(cur - new Date(secret.created))} ago`),
])
),
{ hsep: 2 }
);
if (out) {
client.output.print(`\n${out}\n`);
}
}
if (pagination && pagination.count === 20) {
const flags = getCommandFlags(argv, ['_', '--next', '-N', '-d', '-y']);
const nextCmd = `secrets ${subcommand}${flags} --next ${pagination.next}`;
output.log(`To display the next page run ${getCommandName(nextCmd)}`);
}
return secrets.close();
}
if (subcommand === 'rm' || subcommand === 'remove') {
output.note(
`The ${getCommandName(
'env rm'
)} command is recommended instead of ${commandName}\n`
);
if (args.length !== 1) {
// consider replacing with `output.error`
// eslint-disable-next-line no-console
console.error(
error(
`Invalid number of arguments. Usage: ${chalk.cyan(
`${getCommandName('secret rm <name>')}`
)}`
)
);
return 1;
}
const theSecret = await secrets.getSecretByNameOrId(args[0]);
if (theSecret) {
const yes =
argv['--yes'] ||
(await readConfirmation(client, output, theSecret, contextName));
if (!yes) {
output.print(`Canceled. Secret not deleted.\n`);
return 0;
}
} else {
// consider replacing with `output.error`
// eslint-disable-next-line no-console
console.error(
error(
`No secret found by name "${args[0]}" under ${chalk.bold(
contextName
)}`
)
);
return 1;
}
const secret = await secrets.rm(args[0]);
const elapsed = ms(new Date() - start);
output.success(
`Secret ${chalk.bold(secret.name)} under ${chalk.bold(
contextName
)} removed ${chalk.gray(`[${elapsed}]`)}`
);
return secrets.close();
}
if (subcommand === 'rename') {
output.note(
`The ${getCommandName('env rm')} and ${getCommandName(
'env add'
)} commands are recommended instead of ${commandName}\n`
);
if (args.length !== 2) {
// consider replacing with `output.error`
// eslint-disable-next-line no-console
console.error(
error(
`Invalid number of arguments. Usage: ${chalk.cyan(
`${getCommandName('secret rename <old-name> <new-name>')}`
)}`
)
);
return 1;
}
const secret = await secrets.rename(args[0], args[1]);
const elapsed = ms(new Date() - start);
output.success(
`Secret ${chalk.bold(secret.oldName)} renamed to ${chalk.bold(
args[1]
)} under ${chalk.bold(contextName)} ${chalk.gray(`[${elapsed}]`)}`
);
return secrets.close();
}
if (subcommand === 'add' || subcommand === 'set') {
output.note(
`The ${getCommandName(
'env add'
)} command is recommended instead of ${commandName}\n`
);
if (args.length !== 2) {
// consider replacing with `output.error`
// eslint-disable-next-line no-console
console.error(
error(
`Invalid number of arguments. Usage: ${chalk.cyan(
`${getCommandName('secret add <name> <value>')}`
)}`
)
);
if (args.length > 2) {
const example = chalk.cyan(
`$ ${getCommandName('secret add -- "${args[0]}"')}`
);
output.log(
`If your secret has spaces or starts with '-', make sure to terminate command options with double dash and wrap it in quotes. Example: \n ${example} `
);
}
return 1;
}
const [name, value] = args;
if (typeof value === 'boolean') {
const example = chalk.cyan(
`$ ${getCommandName('secret add -- "${name}"')}`
);
output.log(
`If your secret starts with '-', make sure to terminate command options with double dash and wrap it in quotes. Example: \n ${example} `
);
return 1;
}
await secrets.add(name, value);
const elapsed = ms(new Date() - start);
if (name !== name.toLowerCase()) {
output.warn(`Your secret name was converted to lower-case`);
}
output.success(
`Secret ${chalk.bold(name.toLowerCase())} added under ${chalk.bold(
contextName
)} ${chalk.gray(`[${elapsed}]`)}`
);
return secrets.close();
}
// consider replacing with `output.error`
// eslint-disable-next-line no-console
console.error(
error('Please specify a valid subcommand: ls | add | rename | rm')
);
client.output.print(help(secretsCommand, { columns: client.stderr.columns }));
return 2;
}
async function readConfirmation(client, output, secret, contextName) {
const time = chalk.gray(`${ms(new Date() - new Date(secret.created))} ago`);
const tbl = table([[chalk.bold(secret.name), time]], {
align: ['r', 'l'],
hsep: 6,
});
output.print(
`The following secret will be removed permanently from ${chalk.bold(
contextName
)}\n`
);
output.print(` ${tbl}\n`);
return confirm(client, `${chalk.bold.red('Are you sure?')}`, false);
}

View File

@@ -601,9 +601,6 @@ const main = async () => {
case 'rollback':
func = require('./commands/rollback').default;
break;
case 'secrets':
func = require('./commands/secrets').default;
break;
case 'teams':
func = require('./commands/teams').default;
break;

View File

@@ -70,7 +70,7 @@ export async function pullEnvRecords(
);
const query = new URLSearchParams();
let url = `/v1/env/pull/${projectId}`;
let url = `/v2/env/pull/${projectId}`;
if (target) {
url += `/${encodeURIComponent(target)}`;

View File

@@ -4,7 +4,6 @@ const knownErrorsCodes = new Set([
'BAD_REQUEST',
'ENV_ALREADY_EXISTS',
'ENV_CONFLICT',
'ENV_SHOULD_BE_A_SECRET',
'EXISTING_KEY_AND_TARGET',
'FORBIDDEN',
'ID_NOT_FOUND',
@@ -21,7 +20,6 @@ const knownErrorsCodes = new Set([
'MISSING_VALUE',
'NOT_AUTHORIZED',
'NOT_DECRYPTABLE',
'SECRET_MISSING',
'SYSTEM_ENV_WITH_VALUE',
'TEAM_NOT_FOUND',
'TOO_MANY_IDS',

View File

@@ -312,35 +312,6 @@ export default class Now extends EventEmitter {
return new Error(error.message || error.errorMessage);
}
async listSecrets(next?: number, testWarningFlag?: boolean) {
const payload = await this.retry(async bail => {
let secretsUrl = '/v3/now/secrets?limit=20';
if (next) {
secretsUrl += `&until=${next}`;
}
if (testWarningFlag) {
secretsUrl += '&testWarning=1';
}
const res = await this._fetch(secretsUrl);
if (res.status === 200) {
// What we want
return res.json();
}
if (res.status > 200 && res.status < 500) {
// If something is wrong with our request, we don't retry
return bail(await responseError(res, 'Failed to list secrets'));
}
// If something is wrong with the server, we retry
throw await responseError(res, 'Failed to list secrets');
});
return payload;
}
async list(
app?: string,
{ version = 4, meta = {}, nextTimestamp, target }: ListOptions = {},

View File

@@ -1,141 +0,0 @@
import Now from '.';
export default class Secrets extends Now {
ls(next, testWarningFlag) {
return this.listSecrets(next, testWarningFlag);
}
getSecretByNameOrId(nameOrId) {
return this.retry(async (bail, attempt) => {
if (this._debug) {
// eslint-disable-next-line no-console
console.time(`> [debug] #${attempt} GET /secrets/${nameOrId}`);
}
const res = await this._fetch(`/now/secrets/${nameOrId}`, {
method: 'GET',
});
if (this._debug) {
// eslint-disable-next-line no-console
console.timeEnd(`> [debug] #${attempt} GET /secrets/${nameOrId}`);
}
if (res.status === 403) {
return bail(new Error('Unauthorized'));
}
if (res.status === 404) {
return bail(new Error('Not Found'));
}
if (res.status === 400) {
return bail(new Error('Bad Request'));
}
const body = await res.json();
if (res.status !== 200) {
throw new Error(body.error.message);
}
return body;
});
}
rm(nameOrId) {
return this.retry(async (bail, attempt) => {
if (this._debug) {
// eslint-disable-next-line no-console
console.time(`> [debug] #${attempt} DELETE /secrets/${nameOrId}`);
}
const res = await this._fetch(`/now/secrets/${nameOrId}`, {
method: 'DELETE',
});
if (this._debug) {
// eslint-disable-next-line no-console
console.timeEnd(`> [debug] #${attempt} DELETE /secrets/${nameOrId}`);
}
if (res.status === 403) {
return bail(new Error('Unauthorized'));
}
const body = await res.json();
if (res.status !== 200) {
throw new Error(body.error.message);
}
return body;
});
}
add(name, value) {
return this.retry(async (bail, attempt) => {
if (this._debug) {
// eslint-disable-next-line no-console
console.time(`> [debug] #${attempt} POST /secrets`);
}
const res = await this._fetch('/now/secrets', {
method: 'POST',
body: {
name,
value: value.toString(),
},
});
if (this._debug) {
// eslint-disable-next-line no-console
console.timeEnd(`> [debug] #${attempt} POST /secrets`);
}
if (res.status === 403) {
return bail(new Error('Unauthorized'));
}
const body = await res.json();
if (res.status !== 200) {
throw new Error(body.error.message);
}
return body;
});
}
rename(nameOrId, newName) {
return this.retry(async (bail, attempt) => {
if (this._debug) {
// eslint-disable-next-line no-console
console.time(`> [debug] #${attempt} PATCH /secrets/${nameOrId}`);
}
const res = await this._fetch(`/now/secrets/${nameOrId}`, {
method: 'PATCH',
body: {
name: newName,
},
});
if (this._debug) {
// eslint-disable-next-line no-console
console.timeEnd(`> [debug] #${attempt} PATCH /secrets/${nameOrId}`);
}
if (res.status === 403) {
return bail(new Error('Unauthorized'));
}
const body = await res.json();
if (res.status !== 200) {
throw new Error(body.error.message);
}
return body;
});
}
}

View File

@@ -0,0 +1,32 @@
{
"name": "cli-extension-exit-code",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"dependencies": {
"cli-extension-fail": "file:../cli-extension-fail"
}
},
"../cli-extension-fail": {
"bin": {
"vercel-fail": "bin.js"
}
},
"../cli-extension-whoami": {
"extraneous": true,
"bin": {
"vercel-mywhoami": "bin.js"
}
},
"node_modules/cli-extension-fail": {
"resolved": "../cli-extension-fail",
"link": true
}
},
"dependencies": {
"cli-extension-fail": {
"version": "file:../cli-extension-fail"
}
}
}

View File

@@ -0,0 +1,6 @@
{
"private": true,
"dependencies": {
"cli-extension-fail": "file:../cli-extension-fail"
}
}

View File

@@ -0,0 +1,2 @@
#!/usr/bin/env node
process.exit(6);

View File

@@ -0,0 +1,6 @@
{
"name": "cli-extension-fail",
"bin": {
"vercel-fail": "bin.js"
}
}

View File

@@ -205,21 +205,6 @@ module.exports = async function prepare(session, binaryPath, tmpFixturesDir) {
name: 'nested-level',
}),
},
'build-secret': {
'package.json': JSON.stringify({
private: true,
scripts: {
build: 'mkdir public && echo $MY_SECRET > public/index.txt',
},
}),
'now.json': JSON.stringify({
build: {
env: {
MY_SECRET: '@mysecret',
},
},
}),
},
'api-env': {
'api/get-env.js': 'module.exports = (_, res) => res.json(process.env)',
'print.js': 'console.log(JSON.stringify(process.env))',

View File

@@ -757,42 +757,6 @@ test('Deploy `api-env` fixture and test `vercel env` command', async () => {
expect(previewEnvs[0]).toMatch(/Encrypted .* Preview /gm);
}
// we create a "legacy" env variable that contains a decryptable secret
// to check that vc env pull and vc dev work correctly with decryptable secrets
async function createEnvWithDecryptableSecret() {
// eslint-disable-next-line no-console
console.log('creating an env variable with a decryptable secret');
const name = `my-secret${Math.floor(Math.random() * 10000)}`;
const res = await apiFetch('/v2/now/secrets', {
method: 'POST',
body: JSON.stringify({
name,
value: 'decryptable value',
decryptable: true,
}),
});
expect(res.status).toBe(200);
const json = await res.json();
const link = require(path.join(target, '.vercel/project.json'));
const resEnv = await apiFetch(`/v4/projects/${link.projectId}/env`, {
method: 'POST',
body: JSON.stringify({
key: 'MY_DECRYPTABLE_SECRET_ENV',
value: json.uid,
target: ['development'],
type: 'secret',
}),
});
expect(resEnv.status).toBe(200);
}
async function vcEnvPull() {
const { exitCode, stdout, stderr } = await execCli(
binaryPath,
@@ -809,7 +773,6 @@ test('Deploy `api-env` fixture and test `vercel env` command', async () => {
expect(contents).toMatch(/^# Created by Vercel CLI\n/);
expect(contents).toMatch(/MY_NEW_ENV_VAR="my plaintext value"/);
expect(contents).toMatch(/MY_STDIN_VAR="{"expect":"quotes"}"/);
expect(contents).toMatch(/MY_DECRYPTABLE_SECRET_ENV="decryptable value"/);
expect(contents).not.toMatch(/MY_PREVIEW/);
}
@@ -878,14 +841,12 @@ test('Deploy `api-env` fixture and test `vercel env` command', async () => {
const apiJson = await apiRes.json();
expect(apiJson['MY_NEW_ENV_VAR']).toBe('my plaintext value');
expect(apiJson['MY_DECRYPTABLE_SECRET_ENV']).toBe('decryptable value');
const homeUrl = localhost[0];
const homeRes = await fetch(homeUrl);
const homeJson = await homeRes.json();
expect(homeJson['MY_NEW_ENV_VAR']).toBe('my plaintext value');
expect(homeJson['MY_DECRYPTABLE_SECRET_ENV']).toBe('decryptable value');
// sleep before kill, otherwise the dev process doesn't clean up and exit properly
await sleep(100);
@@ -908,18 +869,16 @@ test('Deploy `api-env` fixture and test `vercel env` command', async () => {
const apiJson = await apiRes.json();
expect(apiJson['MY_NEW_ENV_VAR']).toBe('my plaintext value');
expect(apiJson['MY_STDIN_VAR']).toBe('{"expect":"quotes"}');
expect(apiJson['MY_DECRYPTABLE_SECRET_ENV']).toBe('decryptable value');
const homeUrl = localhost[0];
const homeRes = await fetch(homeUrl);
const homeJson = await homeRes.json();
expect(homeJson['MY_NEW_ENV_VAR']).toBe('my plaintext value');
expect(homeJson['MY_STDIN_VAR']).toBe('{"expect":"quotes"}');
expect(homeJson['MY_DECRYPTABLE_SECRET_ENV']).toBe('decryptable value');
// system env vars are automatically exposed
expect(apiJson['VERCEL']).toBe('1');
expect(homeJson['VERCEL']).toBe('1');
// system env vars are hidden in dev
expect(apiJson['VERCEL']).toBeUndefined();
expect(homeJson['VERCEL']).toBeUndefined();
// sleep before kill, otherwise the dev process doesn't clean up and exit properly
await sleep(100);
@@ -949,7 +908,7 @@ test('Deploy `api-env` fixture and test `vercel env` command', async () => {
async function vcEnvPullFetchSystemVars() {
const { exitCode, stdout, stderr } = await execCli(
binaryPath,
['env', 'pull', '-y'],
['env', 'pull', '-y', '--environment', 'production'],
{
cwd: target,
}
@@ -963,7 +922,7 @@ test('Deploy `api-env` fixture and test `vercel env` command', async () => {
expect(lines).toContain('VERCEL="1"');
expect(lines).toContain('VERCEL_URL=""');
expect(lines).toContain('VERCEL_ENV="development"');
expect(lines).toContain('VERCEL_ENV="production"');
expect(lines).toContain('VERCEL_GIT_PROVIDER=""');
expect(lines).toContain('VERCEL_GIT_REPO_SLUG=""');
}
@@ -980,22 +939,24 @@ test('Deploy `api-env` fixture and test `vercel env` command', async () => {
const localhostNoProtocol = localhost[0].slice('http://'.length);
const apiJson = await apiRes.json();
expect(apiJson['VERCEL']).toBe('1');
// environment variables are not set in dev
expect(apiJson['VERCEL']).toBeUndefined();
expect(apiJson['VERCEL_ENV']).toBeUndefined();
expect(apiJson['VERCEL_GIT_PROVIDER']).toBeUndefined();
expect(apiJson['VERCEL_GIT_REPO_SLUG']).toBeUndefined();
// except for these because vc dev
expect(apiJson['VERCEL_URL']).toBe(localhostNoProtocol);
expect(apiJson['VERCEL_ENV']).toBe('development');
expect(apiJson['VERCEL_REGION']).toBe('dev1');
expect(apiJson['VERCEL_GIT_PROVIDER']).toBe('');
expect(apiJson['VERCEL_GIT_REPO_SLUG']).toBe('');
const homeUrl = localhost[0];
const homeRes = await fetch(homeUrl);
const homeJson = await homeRes.json();
expect(homeJson['VERCEL']).toBe('1');
expect(homeJson['VERCEL']).toBeUndefined();
expect(homeJson['VERCEL_URL']).toBe(localhostNoProtocol);
expect(homeJson['VERCEL_ENV']).toBe('development');
expect(homeJson['VERCEL_REGION']).toBe(undefined);
expect(homeJson['VERCEL_GIT_PROVIDER']).toBe('');
expect(homeJson['VERCEL_GIT_REPO_SLUG']).toBe('');
expect(homeJson['VERCEL_ENV']).toBeUndefined();
expect(homeJson['VERCEL_REGION']).toBeUndefined();
expect(homeJson['VERCEL_GIT_PROVIDER']).toBeUndefined();
expect(homeJson['VERCEL_GIT_REPO_SLUG']).toBeUndefined();
// sleep before kill, otherwise the dev process doesn't clean up and exit properly
await sleep(100);
@@ -1058,7 +1019,6 @@ test('Deploy `api-env` fixture and test `vercel env` command', async () => {
async function vcEnvRemoveAll() {
await vcEnvRemoveByName('MY_PREVIEW');
await vcEnvRemoveByName('MY_STDIN_VAR');
await vcEnvRemoveByName('MY_DECRYPTABLE_SECRET_ENV');
await vcEnvRemoveByName('MY_NEW_ENV_VAR');
}
@@ -1071,7 +1031,6 @@ test('Deploy `api-env` fixture and test `vercel env` command', async () => {
await vcEnvAddFromStdinPreview();
await vcEnvAddFromStdinPreviewWithBranch();
await vcEnvLsIncludesVar();
await createEnvWithDecryptableSecret();
await vcEnvPull();
await vcEnvPullOverwrite();
await vcEnvPullConfirm();

View File

@@ -33,7 +33,6 @@ const binaryPath = path.resolve(__dirname, `../scripts/start.js`);
const deployHelpMessage = `${logo} vercel [options] <command | path>`;
let session = 'temp-session';
let secretName: string | undefined;
function fetchTokenInformation(token: string, retries = 3) {
const url = `https://api.vercel.com/v2/user`;
@@ -294,32 +293,6 @@ test('output the version', async () => {
expect(version).toBe(pkg.version);
});
test('should add secret with hyphen prefix', async () => {
const target = await setupE2EFixture('build-secret');
const key = 'mysecret';
const value = '-foo_bar';
let secretCall = await execCli(
binaryPath,
['secrets', 'add', '--', key, value],
{
cwd: target,
}
);
expect(secretCall.exitCode, formatOutput(secretCall)).toBe(0);
let targetCall = await execCli(binaryPath, ['--yes'], {
cwd: target,
});
expect(targetCall.exitCode, formatOutput(targetCall)).toBe(0);
const { host } = new URL(targetCall.stdout);
const response = await fetch(`https://${host}`);
expect(response.status).toBe(200);
expect(await response.text()).toBe(`${value}\n`);
});
test('login with unregistered user', async () => {
const { stdout, stderr, exitCode } = await execCli(binaryPath, [
'login',
@@ -1151,59 +1124,6 @@ test('next unsupported functions config shows warning link', async () => {
);
});
test('vercel secret add', async () => {
secretName = `my-secret-${Date.now().toString(36)}`;
const value = 'https://my-secret-endpoint.com';
const output = await execCli(binaryPath, [
'secret',
'add',
secretName,
value,
]);
expect(output.exitCode, formatOutput(output)).toBe(0);
});
test('vercel secret ls', async () => {
const output = await execCli(binaryPath, ['secret', 'ls']);
expect(output.exitCode, formatOutput(output)).toBe(0);
expect(output.stderr).toMatch(/Secrets found under/gm);
});
test('vercel secret ls --test-warning', async () => {
const output = await execCli(binaryPath, ['secret', 'ls', '--test-warning']);
expect(output.exitCode, formatOutput(output)).toBe(0);
expect(output.stderr).toMatch(/Test warning message./gm);
expect(output.stderr).toMatch(/Learn more: https:\/\/vercel.com/gm);
expect(output.stderr).toMatch(/No secrets found under/gm);
});
test('vercel secret rename', async () => {
if (!secretName) {
throw new Error('Shared state "secretName" not set.');
}
const nextName = `renamed-secret-${Date.now().toString(36)}`;
const output = await execCli(binaryPath, [
'secret',
'rename',
secretName,
nextName,
]);
expect(output.exitCode, formatOutput(output)).toBe(0);
secretName = nextName;
});
test('vercel secret rm', async () => {
if (!secretName) {
throw new Error('Shared state "secretName" not set.');
}
const output = await execCli(binaryPath, ['secret', 'rm', secretName, '-y']);
expect(output.exitCode, formatOutput(output)).toBe(0);
});
test('deploy a Lambda with 128MB of memory', async () => {
const directory = await setupE2EFixture('lambda-with-128-memory');
const output = await execCli(binaryPath, [directory, '--yes']);
@@ -1327,6 +1247,19 @@ test('should invoke CLI extension', async () => {
expect(output.stdout, formatted).toContain(`Username: ${contextName}`);
});
test('should pass through exit code for CLI extension', async () => {
const fixture = path.join(__dirname, 'fixtures/e2e/cli-extension-exit-code');
// Ensure the `.bin` is populated in the fixture
await runNpmInstall(fixture);
const output = await execCli(binaryPath, ['fail'], {
cwd: fixture,
reject: false,
});
expect(output.exitCode).toEqual(6);
});
// NOTE: Order matters here. This must be the last test in the file.
test('default command should prompt login with empty auth.json', async () => {
await clearAuthConfig();

View File

@@ -216,7 +216,7 @@ export function useProject(
res.json(project);
});
client.scenario.get(
`/v1/env/pull/${project.id}/:target?/:gitBranch?`,
`/v2/env/pull/${project.id}/:target?/:gitBranch?`,
(req, res) => {
const target =
typeof req.params.target === 'string'
@@ -390,7 +390,7 @@ function exposeSystemEnvs(
) {
const envs: Env = {};
if (autoExposeSystemEnvs) {
if (autoExposeSystemEnvs && target !== 'development') {
envs['VERCEL'] = '1';
envs['VERCEL_ENV'] = target || 'development';

View File

@@ -1,29 +0,0 @@
import chance from 'chance';
import { client } from './client';
export function useSecrets({
name,
created,
}: {
name: string;
created: number;
}) {
const secret = {
uid: chance().guid(),
name: name || chance().name(),
created: created || chance().timestamp(),
};
client.scenario.get('/v3/now/secrets', (_req, res) => {
res.json({
secrets: [secret],
pagination: {
count: 1,
next: 0,
prev: 0,
},
});
});
return secret;
}

View File

@@ -205,10 +205,17 @@ describe('env', () => {
});
const cwd = setupUnitFixture('vercel-env-pull');
client.cwd = cwd;
client.setArgv('env', 'pull', 'other.env', '--yes');
client.setArgv(
'env',
'pull',
'other.env',
'--yes',
'--environment',
'production'
);
const exitCodePromise = env(client);
await expect(client.stderr).toOutput(
'Downloading `development` Environment Variables for Project vercel-env-pull'
'Downloading `production` Environment Variables for Project vercel-env-pull'
);
await expect(client.stderr).toOutput('Created other.env file');
await expect(client.stderr).not.toOutput('and added it to .gitignore');
@@ -218,10 +225,44 @@ describe('env', () => {
const productionFileHasVercelEnv = rawDevEnv
.toString()
.includes('VERCEL_ENV="development"');
.includes('VERCEL_ENV="production"');
expect(productionFileHasVercelEnv).toBeTruthy();
});
it('should not expose system env variables in dev', async () => {
useUser();
useTeams('team_dummy');
useProject({
...defaultProject,
id: 'vercel-env-pull',
name: 'vercel-env-pull',
autoExposeSystemEnvs: true,
});
const cwd = setupUnitFixture('vercel-env-pull');
client.cwd = cwd;
client.setArgv('env', 'pull', 'other.env', '--yes');
const exitCodePromise = env(client);
await expect(client.stderr).toOutput(
'Downloading `development` Environment Variables for Project vercel-env-pull'
);
await expect(client.stderr).toOutput('Created other.env file');
await expect(client.stderr).not.toOutput('and added it to .gitignore');
await expect(exitCodePromise).resolves.toEqual(0);
const devEnv = (
await fs.readFile(path.join(cwd, 'other.env'))
).toString();
const devFileHasVercelEnv = [
'VERCEL',
'VERCEL_ENV',
'VERCEL_URL',
'VERCEL_REGION',
'VERCEL_DEPLOYMENT_ID',
].some(envVar => devEnv.includes(envVar));
expect(devFileHasVercelEnv).toBeFalsy();
});
it('should show a delta string', async () => {
const cwd = setupUnitFixture('vercel-env-pull-delta');
client.cwd = cwd;

View File

@@ -1,38 +0,0 @@
import { describe, expect, it } from 'vitest';
import { client } from '../../mocks/client';
import secrets from '../../../src/commands/secrets';
import { useSecrets } from '../../mocks/secrets';
import { useUser } from '../../mocks/user';
import { useTeams } from '../../mocks/team';
import ms from 'ms';
describe('secrets', () => {
it('errors when no subcommand is provided', async () => {
client.setArgv('secrets');
const exitCode = await secrets(client);
expect(exitCode).toEqual(2);
});
it('lists secrets with ls subcommand', async () => {
useUser();
useTeams('team_dummy');
const name = 'secret-api-password';
const created = 1519555701;
useSecrets({ name, created });
client.setArgv('secrets', 'ls');
await secrets(client);
const timeAgo = `${ms(
new Date().getTime() - new Date(created).getTime()
)} ago`;
await expect(client.stderr).toOutput(
'> NOTE: The `vercel env ls` command is recommended instead of `vercel secret ls`'
);
const output = client.stderr.read();
await expect(output).toMatch(name);
await expect(output).toMatch(timeAgo);
});
});

View File

@@ -1,5 +1,12 @@
# @vercel/client
## 13.2.7
### Patch Changes
- Updated dependencies [[`d3c1267e2`](https://github.com/vercel/vercel/commit/d3c1267e24082789ea6382cf6af81dd40df288ff), [`ccd7eb1fb`](https://github.com/vercel/vercel/commit/ccd7eb1fb78f7ac9effdbe1935de3bda82c97fe3)]:
- @vercel/build-utils@8.2.0
## 13.2.6
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/client",
"version": "13.2.6",
"version": "13.2.7",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"homepage": "https://vercel.com",
@@ -37,7 +37,7 @@
"typescript": "4.9.5"
},
"dependencies": {
"@vercel/build-utils": "8.1.3",
"@vercel/build-utils": "8.2.0",
"@vercel/error-utils": "2.0.2",
"@vercel/routing-utils": "3.1.0",
"@zeit/fetch": "5.2.0",

View File

@@ -37,7 +37,7 @@
"@types/minimatch": "3.0.5",
"@types/node": "14.18.33",
"@types/semver": "7.3.10",
"@vercel/build-utils": "8.1.3",
"@vercel/build-utils": "8.2.0",
"jest-junit": "16.0.0",
"typescript": "4.9.5"
}

View File

@@ -1,5 +1,12 @@
# @vercel/gatsby-plugin-vercel-builder
## 2.0.31
### Patch Changes
- Updated dependencies [[`d3c1267e2`](https://github.com/vercel/vercel/commit/d3c1267e24082789ea6382cf6af81dd40df288ff), [`ccd7eb1fb`](https://github.com/vercel/vercel/commit/ccd7eb1fb78f7ac9effdbe1935de3bda82c97fe3)]:
- @vercel/build-utils@8.2.0
## 2.0.30
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/gatsby-plugin-vercel-builder",
"version": "2.0.30",
"version": "2.0.31",
"main": "dist/index.js",
"files": [
"dist",
@@ -20,7 +20,7 @@
},
"dependencies": {
"@sinclair/typebox": "0.25.24",
"@vercel/build-utils": "8.1.3",
"@vercel/build-utils": "8.2.0",
"@vercel/routing-utils": "3.1.0",
"esbuild": "0.14.47",
"etag": "1.8.1",

View File

@@ -29,7 +29,7 @@
"@types/node-fetch": "^2.3.0",
"@types/tar": "6.1.5",
"@types/yauzl-promise": "2.1.0",
"@vercel/build-utils": "8.1.3",
"@vercel/build-utils": "8.2.0",
"async-retry": "1.3.3",
"execa": "^1.0.0",
"fs-extra": "^7.0.0",

View File

@@ -26,7 +26,7 @@
"devDependencies": {
"@types/jest": "27.5.1",
"@types/node": "14.18.33",
"@vercel/build-utils": "8.1.3",
"@vercel/build-utils": "8.2.0",
"execa": "3.2.0",
"fs-extra": "11.1.0",
"jest-junit": "16.0.0"

View File

@@ -51,11 +51,15 @@ export const build: BuildV2 = async ({
);
const spawnOpts = getSpawnOptions(meta, nodeVersion);
const { cliType, lockfileVersion } = await scanParentDirs(entrypointDir);
const { cliType, lockfileVersion, packageJson } = await scanParentDirs(
entrypointDir,
true
);
spawnOpts.env = getEnvForPackageManager({
cliType,
lockfileVersion,
packageJsonPackageManager: packageJson?.packageManager,
nodeVersion,
env: spawnOpts.env || {},
});

View File

@@ -1,5 +1,19 @@
# @vercel/next
## 4.2.13
### Patch Changes
- Fix static case for detecting when a page supports PPR ([#11635](https://github.com/vercel/vercel/pull/11635))
- Fix related to erroring when a prefetch route is not provided but the route is PPR enabled ([#11638](https://github.com/vercel/vercel/pull/11638))
## 4.2.12
### Patch Changes
- Support incremental PPR for large applications ([#11625](https://github.com/vercel/vercel/pull/11625))
## 4.2.11
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/next",
"version": "4.2.11",
"version": "4.2.13",
"license": "Apache-2.0",
"main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/next-js",
@@ -40,7 +40,7 @@
"@types/semver": "6.0.0",
"@types/text-table": "0.2.1",
"@types/webpack-sources": "3.2.0",
"@vercel/build-utils": "8.1.3",
"@vercel/build-utils": "8.2.0",
"@vercel/routing-utils": "3.1.0",
"async-sema": "3.0.1",
"buffer-crc32": "0.2.13",

View File

@@ -257,10 +257,15 @@ export const build: BuildV2 = async ({
const nextVersionRange = await getNextVersionRange(entryPath);
const nodeVersion = await getNodeVersion(entryPath, undefined, config, meta);
const spawnOpts = getSpawnOptions(meta, nodeVersion);
const { cliType, lockfileVersion } = await scanParentDirs(entryPath);
const { cliType, lockfileVersion, packageJson } = await scanParentDirs(
entryPath,
true
);
spawnOpts.env = getEnvForPackageManager({
cliType,
lockfileVersion,
packageJsonPackageManager: packageJson?.packageManager,
nodeVersion,
env: spawnOpts.env || {},
});
@@ -1353,6 +1358,11 @@ export const build: BuildV2 = async ({
experimentalPPRRoutes.add(route);
}
const isAppPPREnabled = requiredServerFilesManifest
? requiredServerFilesManifest.config.experimental?.ppr === true ||
requiredServerFilesManifest.config.experimental?.ppr === 'incremental'
: false;
if (requiredServerFilesManifest) {
if (!routesManifest) {
throw new Error(
@@ -1408,6 +1418,7 @@ export const build: BuildV2 = async ({
hasIsr500Page,
variantsManifest,
experimentalPPRRoutes,
isAppPPREnabled,
});
}
@@ -1927,7 +1938,7 @@ export const build: BuildV2 = async ({
canUsePreviewMode,
bypassToken: prerenderManifest.bypassToken || '',
isServerMode,
experimentalPPRRoutes,
isAppPPREnabled: false,
hasActionOutputSupport: false,
}).then(arr =>
localizeDynamicRoutes(
@@ -1958,7 +1969,7 @@ export const build: BuildV2 = async ({
canUsePreviewMode,
bypassToken: prerenderManifest.bypassToken || '',
isServerMode,
experimentalPPRRoutes,
isAppPPREnabled: false,
hasActionOutputSupport: false,
}).then(arr =>
arr.map(route => {
@@ -2157,6 +2168,7 @@ export const build: BuildV2 = async ({
appPathRoutesManifest,
isSharedLambdas,
canUsePreviewMode,
isAppPPREnabled: false,
});
await Promise.all(

View File

@@ -144,6 +144,7 @@ export async function serverBuild({
requiredServerFilesManifest,
variantsManifest,
experimentalPPRRoutes,
isAppPPREnabled,
}: {
appPathRoutesManifest?: Record<string, string>;
dynamicPages: string[];
@@ -185,7 +186,15 @@ export async function serverBuild({
requiredServerFilesManifest: NextRequiredServerFilesManifest;
variantsManifest: VariantsManifest | null;
experimentalPPRRoutes: ReadonlySet<string>;
isAppPPREnabled: boolean;
}): Promise<BuildResult> {
if (isAppPPREnabled) {
debug(
'experimentalPPRRoutes',
JSON.stringify(Array.from(experimentalPPRRoutes))
);
}
lambdaPages = Object.assign({}, lambdaPages, lambdaAppPaths);
const experimentalAllowBundling = Boolean(
@@ -217,12 +226,6 @@ export async function serverBuild({
}
}
const experimental = {
ppr:
requiredServerFilesManifest.config.experimental?.ppr === true ||
requiredServerFilesManifest.config.experimental?.ppr === 'incremental',
};
let appRscPrefetches: UnwrapPromise<ReturnType<typeof glob>> = {};
let appBuildTraces: UnwrapPromise<ReturnType<typeof glob>> = {};
let appDir: string | null = null;
@@ -230,7 +233,7 @@ export async function serverBuild({
if (appPathRoutesManifest) {
appDir = path.join(pagesDir, '../app');
appBuildTraces = await glob('**/*.js.nft.json', appDir);
appRscPrefetches = experimental.ppr
appRscPrefetches = isAppPPREnabled
? {}
: await glob(`**/*${RSC_PREFETCH_SUFFIX}`, appDir);
@@ -251,7 +254,7 @@ export async function serverBuild({
if (rewrite.src && rewrite.dest) {
rewrite.src = rewrite.src.replace(
/\/?\(\?:\/\)\?/,
`(?<rscsuff>${experimental.ppr ? '(\\.prefetch)?' : ''}\\.rsc)?(?:/)?`
`(?<rscsuff>${isAppPPREnabled ? '(\\.prefetch)?' : ''}\\.rsc)?(?:/)?`
);
let destQueryIndex = rewrite.dest.indexOf('?');
@@ -934,9 +937,6 @@ export async function serverBuild({
const appRouterStreamingActionLambdaGroups: LambdaGroup[] = [];
for (const group of appRouterLambdaGroups) {
if (!group.isPrerenders || group.isExperimentalPPR) {
group.isStreaming = true;
}
group.isAppRouter = true;
// We create a streaming variant of the Prerender lambda group
@@ -951,9 +951,6 @@ export async function serverBuild({
}
for (const group of appRouteHandlersLambdaGroups) {
if (!group.isPrerenders) {
group.isStreaming = true;
}
group.isAppRouter = true;
group.isAppRouteHandler = true;
}
@@ -984,18 +981,24 @@ export async function serverBuild({
apiLambdaGroups: apiLambdaGroups.map(group => ({
pages: group.pages,
isPrerender: group.isPrerenders,
isStreaming: group.isStreaming,
isExperimentalPPR: group.isExperimentalPPR,
pseudoLayerBytes: group.pseudoLayerBytes,
uncompressedLayerBytes: group.pseudoLayerUncompressedBytes,
})),
pageLambdaGroups: pageLambdaGroups.map(group => ({
pages: group.pages,
isPrerender: group.isPrerenders,
isStreaming: group.isStreaming,
isExperimentalPPR: group.isExperimentalPPR,
pseudoLayerBytes: group.pseudoLayerBytes,
uncompressedLayerBytes: group.pseudoLayerUncompressedBytes,
})),
appRouterLambdaGroups: appRouterLambdaGroups.map(group => ({
pages: group.pages,
isPrerender: group.isPrerenders,
isStreaming: group.isStreaming,
isExperimentalPPR: group.isExperimentalPPR,
pseudoLayerBytes: group.pseudoLayerBytes,
uncompressedLayerBytes: group.pseudoLayerUncompressedBytes,
})),
@@ -1003,6 +1006,8 @@ export async function serverBuild({
appRouterStreamingActionLambdaGroups.map(group => ({
pages: group.pages,
isPrerender: group.isPrerenders,
isStreaming: group.isStreaming,
isExperimentalPPR: group.isExperimentalPPR,
pseudoLayerBytes: group.pseudoLayerBytes,
uncompressedLayerBytes: group.pseudoLayerUncompressedBytes,
})),
@@ -1010,6 +1015,8 @@ export async function serverBuild({
group => ({
pages: group.pages,
isPrerender: group.isPrerenders,
isStreaming: group.isStreaming,
isExperimentalPPR: group.isExperimentalPPR,
pseudoLayerBytes: group.pseudoLayerBytes,
uncompressedLayerBytes: group.pseudoLayerUncompressedBytes,
})
@@ -1189,15 +1196,10 @@ export async function serverBuild({
const lambda = await createLambdaFromPseudoLayers(options);
// This is a PPR lambda if it's an App Page with the PPR experimental flag
// enabled.
const isPPR =
experimental.ppr && group.isAppRouter && !group.isAppRouteHandler;
// If PPR is enabled and this is an App Page, create the non-streaming
// lambda for the page for revalidation.
let revalidate: NodejsLambda | undefined;
if (isPPR) {
if (group.isExperimentalPPR) {
if (!options.isStreaming) {
throw new Error("Invariant: PPR lambda isn't streaming");
}
@@ -1214,14 +1216,11 @@ export async function serverBuild({
// This is the name of the page, where the root is `index`.
const pageName = pageFilename.replace(/\.js$/, '');
// This is the name of the page prefixed with a `/`, where the root is
// `/index`.
const pagePath = path.posix.join('/', pageName);
// This is the routable pathname for the page, where the root is `/`.
const pagePathname = pagePath === '/index' ? '/' : pagePath;
const pagePathname = normalizePage(pageName);
let isPrerender = prerenderRoutes.has(pagePathname);
const isRoutePPREnabled = experimentalPPRRoutes.has(pagePathname);
if (!isPrerender && routesManifest?.i18n) {
isPrerender = routesManifest.i18n.locales.some(locale => {
@@ -1239,7 +1238,7 @@ export async function serverBuild({
}
// If this is a PPR page, then we should prefix the output name.
if (isPPR) {
if (isRoutePPREnabled) {
if (!revalidate) {
throw new Error("Invariant: PPR lambda isn't set");
}
@@ -1320,6 +1319,13 @@ export async function serverBuild({
console.timeEnd(lambdaCreationLabel);
}
if (isAppPPREnabled) {
debug(
'experimentalStreamingLambdaPaths',
JSON.stringify(Array.from(experimentalStreamingLambdaPaths))
);
}
const prerenderRoute = onPrerenderRoute({
appDir,
pagesDir,
@@ -1339,6 +1345,7 @@ export async function serverBuild({
hasPages404: routesManifest.pages404,
isCorrectNotFoundRoutes,
isEmptyAllowQueryForPrendered,
isAppPPREnabled,
});
await Promise.all(
@@ -1407,7 +1414,7 @@ export async function serverBuild({
bypassToken: prerenderManifest.bypassToken || '',
isServerMode: true,
dynamicMiddlewareRouteMap: middleware.dynamicRouteMap,
experimentalPPRRoutes,
isAppPPREnabled,
hasActionOutputSupport,
}).then(arr =>
localizeDynamicRoutes(
@@ -1589,7 +1596,7 @@ export async function serverBuild({
if (lambdas[pathname]) {
lambdas[`${pathname}.rsc`] = lambdas[pathname];
if (experimental.ppr) {
if (isAppPPREnabled) {
lambdas[`${pathname}${RSC_PREFETCH_SUFFIX}`] = lambdas[pathname];
}
}
@@ -1597,7 +1604,7 @@ export async function serverBuild({
if (edgeFunctions[pathname]) {
edgeFunctions[`${pathname}.rsc`] = edgeFunctions[pathname];
if (experimental.ppr) {
if (isAppPPREnabled) {
edgeFunctions[`${pathname}${RSC_PREFETCH_SUFFIX}`] =
edgeFunctions[pathname];
}
@@ -1616,7 +1623,7 @@ export async function serverBuild({
'RSC, Next-Router-State-Tree, Next-Router-Prefetch';
const appNotFoundPath = path.posix.join('.', entryDirectory, '_not-found');
if (experimental.ppr && !rscPrefetchHeader) {
if (isAppPPREnabled && !rscPrefetchHeader) {
throw new Error("Invariant: cannot use PPR without 'rsc.prefetchHeader'");
}
@@ -1624,7 +1631,7 @@ export async function serverBuild({
// all the routes that support it (and are listed) have configured lambdas.
// This only applies to routes that do not have fallbacks enabled (these are
// routes that have `dynamicParams = false` defined.
if (experimental.ppr) {
if (isAppPPREnabled) {
for (const { srcRoute, dataRoute, experimentalPPR } of Object.values(
prerenderManifest.staticRoutes
)) {
@@ -1907,7 +1914,7 @@ export async function serverBuild({
...(appDir
? [
...(rscPrefetchHeader && experimental.ppr
...(rscPrefetchHeader && isAppPPREnabled
? [
{
src: `^${path.posix.join('/', entryDirectory, '/')}`,

View File

@@ -192,8 +192,12 @@ function normalizePage(page: string): string {
if (!page.startsWith('/')) {
page = `/${page}`;
}
// remove '/index' from the end
page = page.replace(/\/index$/, '/');
// Replace the `/index` with `/`
if (page === '/index') {
page = '/';
}
return page;
}
@@ -320,8 +324,8 @@ export async function getDynamicRoutes({
bypassToken,
isServerMode,
dynamicMiddlewareRouteMap,
experimentalPPRRoutes,
hasActionOutputSupport,
isAppPPREnabled,
}: {
entryPath: string;
entryDirectory: string;
@@ -333,8 +337,8 @@ export async function getDynamicRoutes({
bypassToken?: string;
isServerMode?: boolean;
dynamicMiddlewareRouteMap?: ReadonlyMap<string, RouteWithSrc>;
experimentalPPRRoutes: ReadonlySet<string>;
hasActionOutputSupport: boolean;
isAppPPREnabled: boolean;
}): Promise<RouteWithSrc[]> {
if (routesManifest) {
switch (routesManifest.version) {
@@ -408,7 +412,7 @@ export async function getDynamicRoutes({
];
}
if (experimentalPPRRoutes.has(page)) {
if (isAppPPREnabled) {
let dest = route.dest?.replace(/($|\?)/, '.prefetch.rsc$1');
if (page === '/' || page === '/index') {
@@ -1504,9 +1508,9 @@ export type LambdaGroup = {
maxDuration?: number;
isAppRouter?: boolean;
isAppRouteHandler?: boolean;
isStreaming?: boolean;
isPrerenders?: boolean;
isExperimentalPPR?: boolean;
readonly isStreaming: boolean;
readonly isPrerenders: boolean;
readonly isExperimentalPPR: boolean;
isActionLambda?: boolean;
isPages?: boolean;
isApiLambda: boolean;
@@ -1561,6 +1565,7 @@ export async function getPageLambdaGroups({
const routeName = normalizePage(page.replace(/\.js$/, ''));
const isPrerenderRoute = prerenderRoutes.has(routeName);
const isExperimentalPPR = experimentalPPRRoutes?.has(routeName) ?? false;
const isStreaming = !isPrerenderRoute || isExperimentalPPR;
let opts: { memory?: number; maxDuration?: number } = {};
@@ -1632,6 +1637,7 @@ export async function getPageLambdaGroups({
...opts,
isPrerenders: isPrerenderRoute,
isExperimentalPPR,
isStreaming,
isApiLambda: !!isApiPage(page),
pseudoLayerBytes: initialPseudoLayer.pseudoLayerBytes,
pseudoLayerUncompressedBytes: initialPseudoLayerUncompressed,
@@ -1948,6 +1954,7 @@ type OnPrerenderRouteArgs = {
routesManifest?: RoutesManifest;
isCorrectNotFoundRoutes?: boolean;
isEmptyAllowQueryForPrendered?: boolean;
isAppPPREnabled: boolean;
};
let prerenderGroup = 1;
@@ -1984,6 +1991,7 @@ export const onPrerenderRoute =
routesManifest,
isCorrectNotFoundRoutes,
isEmptyAllowQueryForPrendered,
isAppPPREnabled,
} = prerenderRouteArgs;
if (isBlocking && isFallback) {
@@ -2219,22 +2227,6 @@ export const onPrerenderRoute =
initialStatus = 404;
}
/**
* If the route key had an `/index` suffix added, we need to note it so we
* can remove it from the output path later accurately.
*/
let addedIndexSuffix = false;
if (isAppPathRoute) {
// for literal index routes we need to append an additional /index
// due to the proxy's normalizing for /index routes
if (routeKey !== '/index' && routeKey.endsWith('/index')) {
routeKey = `${routeKey}/index`;
routeFileNoExt = routeKey;
addedIndexSuffix = true;
}
}
let outputPathPage = path.posix.join(entryDirectory, routeFileNoExt);
if (!isAppPathRoute) {
@@ -2271,7 +2263,7 @@ export const onPrerenderRoute =
let outputPathPrefetchData: null | string = null;
if (prefetchDataRoute) {
if (!experimentalPPR) {
if (!isAppPPREnabled) {
throw new Error(
"Invariant: prefetchDataRoute can't be set without PPR"
);
@@ -2428,7 +2420,7 @@ export const onPrerenderRoute =
// static route first, then try the srcRoute if it doesn't exist. If we
// can't find it at all, this constitutes an error.
experimentalStreamingLambdaPath = experimentalStreamingLambdaPaths.get(
pathnameToOutputName(entryDirectory, routeKey, addedIndexSuffix)
pathnameToOutputName(entryDirectory, routeKey)
);
if (!experimentalStreamingLambdaPath && srcRoute) {
experimentalStreamingLambdaPath =
@@ -2689,19 +2681,10 @@ export function getNextServerPath(nextVersion: string) {
: 'next/dist/next-server/server';
}
function pathnameToOutputName(
entryDirectory: string,
pathname: string,
addedIndexSuffix = false
) {
function pathnameToOutputName(entryDirectory: string, pathname: string) {
if (pathname === '/') {
pathname = '/index';
}
// If the `/index` was added for a route that ended in `/index` we need to
// strip the second one off before joining it with the entryDirectory.
else if (addedIndexSuffix) {
pathname = pathname.replace(/\/index$/, '');
}
return path.posix.join(entryDirectory, pathname);
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,3 @@
export default function Page() {
return <div id="sentinel:static">Static</div>;
}

View File

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

View File

@@ -56,6 +56,11 @@
"status": 200,
"mustContain": "sentinel:dynamic"
},
{
"path": "/static",
"status": 200,
"mustContain": "sentinel:static"
},
{
"path": "/disabled",
"headers": {

View File

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

View File

@@ -1,7 +1,3 @@
export const metadata = {
metadataBase: new URL(process.env.VERCEL_PROJECT_PRODUCTION_URL ?? 'http://localhost:3000'),
};
export default function Root({ children }) {
return (
<html className="this-is-the-document-html">

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -6,7 +6,7 @@
]
},
"overrides": {
"react": "19.0.0-beta-4508873393-20240430",
"react-dom": "19.0.0-beta-4508873393-20240430"
"react": "19.0.0-rc-f994737d14-20240522",
"react-dom": "19.0.0-rc-f994737d14-20240522"
}
}

View File

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

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