Compare commits

...

14 Commits

Author SHA1 Message Date
Vercel Release Bot
82231058da Version Packages (#10400)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-09-08 11:41:32 -05:00
Steven
61227bf7e3 fix .changeset/nice-lies-sip.md (#10474)
I think we need to remove `api` since its private so its not published to npm and therefore isn't versioned.
2023-09-08 02:09:11 +00:00
Zack Tanner
6aa0aa4e65 [next] fix ENOENT on /404.html when fallback: false w/ basePath (#10473)
The following error occurs during build when `basePath` is present in conjunction with `fallback: false` in `getStaticPaths`:

> Error: ENOENT: no such file or directory, open '/vercel/path0/.next/server/pages/404.html'

`localePrefixed404` was incorrectly being set to `false` because it was looking for `/<basePath>/<locale>/404.html` (when it's actually `/<locale>/404.html`)

This meant that inside `onPrerenderRoute`, `htmlFsRef` was pointing to `/404.html` rather than `/en/404.html`.
2023-09-08 00:17:08 +00:00
JJ Kasper
caaba0d685 [next] fix app dir edge functions with basePath (#10465)
x-ref: https://github.com/vercel/vercel/pull/10394
2023-09-07 22:03:12 +00:00
Steven
335fd70a68 [ci] Update codeowners (#10467)
Update codeowners for Next.js
2023-09-07 14:20:20 +00:00
Zack Tanner
c3c54d6e69 [next]: Fix RSC rewrite behavior (#10415)
- Removes some of the hacks from #10388 that were attempting to resolve an issue with RSC prefetches to `pages` routes in favor of adding rsc rewrites for all dynamic paths, and letting it fall through to a 404 if there's no match
- Fixes an issue where RSC requests were matching the wrong path (filesystem rather than RSC variant) introduced in above mentioned change
  - Closes https://github.com/vercel/next.js/issues/54698
2023-09-07 14:03:14 +00:00
Shu Uesugi
43048a0dd8 [CLI] Fix team URL on vercel help switch (#10466)
In `vercel help switch`, it suggests that team URL is of the format `vercel.com/teams/name`, but this will be 404. It should be `vercel.com/name`.
2023-09-07 13:12:54 +00:00
Sean Massa
60c75fd76c [CLI] show instant preview url on vc deploy and vc redeploy (#10458)
Show Instant Preview URLs immediately during `vc deploy`.

This does mean that we'll no longer show the nicer aliased URLs, but that's probably fine.

https://github.com/vercel/vercel/assets/41545/5d6d5695-60c3-49ca-a54d-a16828583070

---

- [Card](https://linear.app/vercel/issue/VCCLI-897/show-instant-preview-url-on-vc-deploy)
2023-09-06 23:46:44 +00:00
Trek Glowacki
bd1319d7a3 [cli] Update secrets.js to more current styles (#10461)
Updates the `secrets` command to be a bit more modern. Initially I was going to covert this to typescript but that change was quite large, so going stepwise for easier review.

1. Moves the command implementation into a directory like other commands
2. Shifts the command data structure into its own file
3. Adds a test.

Other relevant comments inline.
2023-09-06 20:58:57 +00:00
Nathan Rajlich
1138f7e3d1 Use esbuild for non-ncc'd packages (#10430)
The intention is for this to be a drop-in replacement for compiling TypeScript to JavaScript, but using `esbuild` instead of `tsc`. `tsc` is still needed, but only for the cases where we want to generate type definitions.
2023-09-06 19:49:50 +00:00
Ethan Arrowood
bb95cb9225 [cli] migrate teams command (#10434)
Before:
<img width="661" alt="Screenshot 2023-08-31 at 13 59 35" src="https://github.com/vercel/vercel/assets/16144158/7d16367a-662e-4ef1-8561-c197f4badf48">

After:
<img width="1036" alt="Screenshot 2023-08-31 at 14 00 23" src="https://github.com/vercel/vercel/assets/16144158/64431bdb-48ce-4bc1-8ed0-c719bdfbb350">
2023-09-06 16:15:35 +00:00
Trek Glowacki
0048eb999e [cli] N, not n. (#10460)
Followup to https://github.com/vercel/vercel/pull/10432#discussion_r1315482954
2023-09-06 15:42:37 +00:00
Espen Hovlandsdal
1b4de4a986 chore(deps): upgrade semver dependency (#10411)
Addresses ReDoS vulnerability: https://security.snyk.io/vuln/SNYK-JS-SEMVER-3247795
Uses the latest unaffected versions in the respective major versions, to prevent having to deal with any other breaking changes.
2023-09-06 13:37:37 +00:00
JJ Kasper
c9ad4084ee [next] Update page config test (#10456)
Updates failing test in https://github.com/vercel/vercel/actions/runs/6090040294/job/16525842631?pr=10430 per changes in https://github.com/vercel/next.js/pull/54786
2023-09-06 00:46:37 +00:00
115 changed files with 1411 additions and 879 deletions

View File

@@ -1,5 +0,0 @@
---
"@vercel/build-utils": patch
---
add descriptions to NodeVersion properties

View File

@@ -1,2 +0,0 @@
---
---

View File

@@ -1,5 +0,0 @@
---
'vercel': patch
---
Migrates the vc env command to the command data structure for use in the help output.

View File

@@ -1,5 +0,0 @@
---
'vercel': patch
---
Update domains command to new structure

View File

@@ -1,5 +0,0 @@
---
"vercel": patch
---
migrate `rollback` command structure for help output

View File

@@ -1,5 +0,0 @@
---
"vercel": patch
---
migrate `inti` command structure for help output

View File

@@ -1,5 +0,0 @@
---
'vercel': patch
---
Remove mri workaround

View File

@@ -1,5 +0,0 @@
---
"vercel": patch
---
migrate dev command structure for help output

View File

@@ -1,5 +0,0 @@
---
"@vercel/next": patch
---
fix 404 enoent for i18n

View File

@@ -1,5 +0,0 @@
---
'vercel': patch
---
Migrate `vc secrets` to new help command structure

View File

@@ -1,5 +0,0 @@
---
"vercel": patch
---
migrate `promote` command structure for help output

View File

@@ -1,5 +0,0 @@
---
"@vercel/node": patch
---
remove console.log

View File

@@ -1,5 +0,0 @@
---
"examples": patch
---
update examples to use at least node@16

View File

@@ -1,5 +0,0 @@
---
"vercel": patch
---
migrate `git` command structure for help output

View File

@@ -1,5 +0,0 @@
---
'vercel': patch
---
Update project command to new data structure

4
.github/CODEOWNERS vendored
View File

@@ -5,12 +5,12 @@
* @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @trek
/.github/workflows @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @trek @ijjk
/packages/fs-detectors @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @trek @agadzik @chloetedder
/packages/next @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @trek @ijjk
/packages/next @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @trek @ijjk @ztanner
/packages/routing-utils @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @trek @ijjk
/packages/edge @vercel/compute
/examples @leerob
/examples/create-react-app @Timer
/examples/nextjs @timneutkens @ijjk @styfle
/examples/nextjs @timneutkens @ijjk @styfle @ztanner
/examples/hugo @styfle
/examples/jekyll @styfle
/examples/zola @styfle

7
examples/CHANGELOG.md vendored Normal file
View File

@@ -0,0 +1,7 @@
# examples
## null
### Patch Changes
- update examples to use at least node@16 ([#10395](https://github.com/vercel/vercel/pull/10395))

View File

@@ -10,5 +10,6 @@
"devDependencies": {
"@types/jest": "27.4.1",
"@vercel/frameworks": "2.0.1"
}
},
"version": null
}

View File

@@ -8,7 +8,7 @@
"dist"
],
"scripts": {
"build": "tsc",
"build": "node ../../utils/build.mjs",
"test": "jest --reporters=default --reporters=jest-junit --env node --verbose --runInBand --bail",
"test-unit": "pnpm test tests/unit"
},

View File

@@ -1,7 +1,9 @@
{
"extends": "@vercel-internals/tsconfig",
"compilerOptions": {
"outDir": "dist"
"outDir": "dist",
"declaration": true,
"emitDeclarationOnly": true
},
"include": ["src/**/*"]
}

View File

@@ -1,5 +1,12 @@
# @vercel-internals/types
## 1.0.9
### Patch Changes
- Updated dependencies [[`5609a1187`](https://github.com/vercel/vercel/commit/5609a1187be9d6cf8d5f16825690c5ea72f17dc5), [`1b4de4a98`](https://github.com/vercel/vercel/commit/1b4de4a986f7a612aac834ebae3ec7bb9e9b8cf8)]:
- @vercel/build-utils@7.1.1
## 1.0.8
### Patch Changes

View File

@@ -1,7 +1,7 @@
{
"private": true,
"name": "@vercel-internals/types",
"version": "1.0.8",
"version": "1.0.9",
"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": "7.1.0",
"@vercel/build-utils": "7.1.1",
"@vercel/routing-utils": "3.0.0"
},
"devDependencies": {

View File

@@ -16,6 +16,7 @@
"buffer-replace": "1.0.0",
"create-svelte": "2.0.1",
"dot": "1.1.3",
"esbuild": "0.19.2",
"eslint": "8.14.0",
"eslint-config-prettier": "8.5.0",
"eslint-plugin-jest": "26.1.5",

View File

@@ -1,5 +1,13 @@
# @vercel/build-utils
## 7.1.1
### Patch Changes
- add descriptions to NodeVersion properties ([#10403](https://github.com/vercel/vercel/pull/10403))
- Updated semver dependency ([#10411](https://github.com/vercel/vercel/pull/10411))
## 7.1.0
### Minor Changes

View File

@@ -1,30 +0,0 @@
#!/usr/bin/env node
const fs = require('fs-extra');
const execa = require('execa');
const { join } = require('path');
async function main() {
const outDir = join(__dirname, 'dist');
// Start fresh
await fs.remove(outDir);
// Compile TypeScript
await execa('tsc', [], { stdio: 'inherit' });
// Run `ncc`
const mainDir = join(outDir, 'main');
await execa('ncc', ['build', 'src/index.ts', '-o', mainDir], {
stdio: 'inherit',
});
// Move compiled ncc file to out dir
await fs.rename(join(mainDir, 'index.js'), join(outDir, 'index.js'));
// Delete leftover "main" dir
await fs.remove(mainDir);
}
main().catch(err => {
console.error(err);
process.exit(1);
});

View File

@@ -0,0 +1,3 @@
import { tsc, esbuild } from '../../utils/build.mjs';
await Promise.all([tsc(), esbuild().then(() => esbuild({ bundle: true }))]);

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/build-utils",
"version": "7.1.0",
"version": "7.1.1",
"license": "Apache-2.0",
"main": "./dist/index.js",
"types": "./dist/index.d.js",
@@ -11,7 +11,7 @@
"directory": "packages/now-build-utils"
},
"scripts": {
"build": "node build",
"build": "node build.mjs",
"test": "jest --reporters=default --reporters=jest-junit --env node --verbose --runInBand --bail",
"test-unit": "pnpm test test/unit.*test.*",
"test-e2e": "pnpm test test/integration.test.ts"
@@ -49,7 +49,7 @@
"minimatch": "3.1.2",
"multistream": "2.1.1",
"node-fetch": "2.6.7",
"semver": "6.1.1",
"semver": "6.3.1",
"typescript": "4.9.5",
"yazl": "2.5.1"
}

View File

@@ -1,6 +1,7 @@
{
"compilerOptions": {
"declaration": true,
"emitDeclarationOnly": true,
"esModuleInterop": true,
"lib": ["ES2021"],
"module": "commonjs",

View File

@@ -1,5 +1,52 @@
# vercel
## 32.2.0
### Minor Changes
- show instant preview url on deploy ([#10458](https://github.com/vercel/vercel/pull/10458))
### Patch Changes
- N, not n. ([#10460](https://github.com/vercel/vercel/pull/10460))
- Fix team URL on `vercel help switch` ([#10466](https://github.com/vercel/vercel/pull/10466))
- Migrates the vc env command to the command data structure for use in the help output. ([#10429](https://github.com/vercel/vercel/pull/10429))
- Update domains command to new structure ([#10427](https://github.com/vercel/vercel/pull/10427))
- Updated semver dependency ([#10411](https://github.com/vercel/vercel/pull/10411))
- migrate `rollback` command structure for help output ([#10426](https://github.com/vercel/vercel/pull/10426))
- migrate `inti` command structure for help output ([#10428](https://github.com/vercel/vercel/pull/10428))
- Remove mri workaround ([#10452](https://github.com/vercel/vercel/pull/10452))
- migrate dev command structure for help output ([#10433](https://github.com/vercel/vercel/pull/10433))
- Update secrets to more recent structure ([#10461](https://github.com/vercel/vercel/pull/10461))
- Migrate `vc secrets` to new help command structure ([#10435](https://github.com/vercel/vercel/pull/10435))
- migrate `promote` command structure for help output ([#10425](https://github.com/vercel/vercel/pull/10425))
- migrate `git` command structure for help output ([#10431](https://github.com/vercel/vercel/pull/10431))
- Update project command to new data structure ([#10432](https://github.com/vercel/vercel/pull/10432))
- migrate teams command ([#10434](https://github.com/vercel/vercel/pull/10434))
- Updated dependencies [[`5609a1187`](https://github.com/vercel/vercel/commit/5609a1187be9d6cf8d5f16825690c5ea72f17dc5), [`caaba0d68`](https://github.com/vercel/vercel/commit/caaba0d6855eff4350b6a04acc3ea502025bff8f), [`1b4de4a98`](https://github.com/vercel/vercel/commit/1b4de4a986f7a612aac834ebae3ec7bb9e9b8cf8), [`c3c54d6e6`](https://github.com/vercel/vercel/commit/c3c54d6e695ec078777c4b1f4f23acbeee3c3b09), [`6aa0aa4e6`](https://github.com/vercel/vercel/commit/6aa0aa4e65b81903f4fce677a198dcfaebee744b), [`e43191b18`](https://github.com/vercel/vercel/commit/e43191b1866da70a3dab3815a3f2176942240ef3), [`fc1e13c09`](https://github.com/vercel/vercel/commit/fc1e13c09928c654410b373fc1775c2b63c6ef4a)]:
- @vercel/build-utils@7.1.1
- @vercel/next@4.0.2
- @vercel/static-build@2.0.4
- @vercel/redwood@2.0.1
- @vercel/remix-builder@2.0.3
- @vercel/ruby@2.0.1
- @vercel/node@3.0.4
## 32.1.0
### Minor Changes

View File

@@ -1,6 +1,6 @@
{
"name": "vercel",
"version": "32.1.0",
"version": "32.2.0",
"preferGlobal": true,
"license": "Apache-2.0",
"description": "The command-line interface for Vercel",
@@ -31,16 +31,16 @@
"node": ">= 16"
},
"dependencies": {
"@vercel/build-utils": "7.1.0",
"@vercel/build-utils": "7.1.1",
"@vercel/go": "3.0.0",
"@vercel/hydrogen": "1.0.0",
"@vercel/next": "4.0.1",
"@vercel/node": "3.0.3",
"@vercel/next": "4.0.2",
"@vercel/node": "3.0.4",
"@vercel/python": "4.0.0",
"@vercel/redwood": "2.0.0",
"@vercel/remix-builder": "2.0.2",
"@vercel/ruby": "2.0.0",
"@vercel/static-build": "2.0.3"
"@vercel/redwood": "2.0.1",
"@vercel/remix-builder": "2.0.3",
"@vercel/ruby": "2.0.1",
"@vercel/static-build": "2.0.4"
},
"devDependencies": {
"@alex_neo/jest-expect-message": "1.0.5",
@@ -86,11 +86,11 @@
"@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.8",
"@vercel/client": "13.0.1",
"@vercel-internals/types": "1.0.9",
"@vercel/client": "13.0.2",
"@vercel/error-utils": "2.0.1",
"@vercel/frameworks": "2.0.1",
"@vercel/fs-detectors": "5.0.1",
"@vercel/fs-detectors": "5.0.2",
"@vercel/fun": "1.0.4",
"@vercel/ncc": "0.24.0",
"@vercel/routing-utils": "3.0.0",
@@ -156,7 +156,7 @@
"qr-image": "3.2.0",
"raw-body": "2.4.1",
"rimraf": "3.0.2",
"semver": "5.5.0",
"semver": "5.7.2",
"serve-handler": "6.1.1",
"strip-ansi": "6.0.1",
"supports-hyperlinks": "3.0.0",

View File

@@ -48,7 +48,7 @@ export const projectCommand: Command = {
name: 'next',
description: 'Show next page of results',
argument: 'MS',
shorthand: 'n',
shorthand: 'N',
type: 'string',
deprecated: false,
multi: false,

View File

@@ -76,12 +76,23 @@ export default async function redeploy(client: Client): Promise<number> {
});
output.stopSpinner();
const isProdDeployment = deployment.target === 'production';
const previewUrl = `https://${deployment.url}`;
output.print(
`${prependEmoji(
`Inspect: ${chalk.bold(deployment.inspectorUrl)} ${deployStamp()}`,
emoji('inspect')
)}\n`
);
output.print(
prependEmoji(
`${isProdDeployment ? 'Production' : 'Preview'}: ${chalk.bold(
previewUrl
)} ${deployStamp()}`,
emoji('success')
) + `\n`
);
if (!client.stdout.isTTY) {
client.stdout.write(`https://${deployment.url}`);

View File

@@ -0,0 +1,96 @@
import { packageName, getCommandName } from '../../util/pkg-name';
export const secretsCommand = {
name: 'secrets',
description: `NOTE: The ${getCommandName(
'env'
)} command is recommended instead of ${getCommandName('secrets')}`,
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,111 +1,17 @@
import isErrnoException from '@vercel/error-utils';
import chalk from 'chalk';
import table from 'text-table';
import ms from 'ms';
import strlen from '../util/strlen.ts';
import { handleError, error } from '../util/error';
import NowSecrets from '../util/secrets';
import exit from '../util/exit';
import getScope from '../util/get-scope.ts';
import confirm from '../util/input/confirm';
import getCommandFlags from '../util/get-command-flags';
import { packageName, getCommandName } from '../util/pkg-name.ts';
import getArgs from '../util/get-args';
import { help } from './help';
export const secretsCommand = {
name: 'secrets',
description: `NOTE: The ${getCommandName(
'env'
)} command is recommended instead of ${getCommandName('secrets')}`,
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`,
},
],
};
import strlen from '../../util/strlen';
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;
@@ -130,7 +36,7 @@ const main = async client => {
client.output.print(
help(secretsCommand, { columns: client.stderr.columns })
);
await exit(2);
return 2;
}
const {
@@ -142,10 +48,12 @@ const main = async client => {
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;
}
@@ -155,7 +63,7 @@ const main = async client => {
export default async client => {
try {
await main(client);
return await main(client);
} catch (err) {
handleError(err);
process.exit(1);
@@ -218,7 +126,7 @@ async function run({ output, contextName, currentTeam, client }) {
);
if (out) {
console.log(`\n${out}\n`);
client.output.print(`\n${out}\n`);
}
}

View File

@@ -0,0 +1,77 @@
import { Command } from '../help';
import { packageName } from '../../util/pkg-name';
export const teamsCommand: Command = {
name: 'teams',
description: 'Manage teams under your Vercel account',
arguments: [],
subcommands: [
{
name: 'add',
description: 'Create a new team',
arguments: [],
options: [],
examples: [],
},
{
name: 'ls',
description: "Show all teams you're a part of",
arguments: [],
options: [],
examples: [],
},
{
name: 'switch',
description: 'Switch to a different team',
arguments: [
{
name: 'name',
required: false,
},
],
options: [],
examples: [],
},
{
name: 'invite',
description: 'Invite a new member to a team',
arguments: [
{
name: 'emails',
required: true,
},
],
options: [],
examples: [],
},
],
options: [
{
name: 'next',
shorthand: 'N',
type: 'string',
argument: 'MS',
deprecated: false,
multi: false,
description: 'Show next page of results',
},
],
examples: [
{
name: "Switch to a team. If your team's url is 'vercel.com/name', then 'name' is the slug. If the slug is omitted, you can choose interactively.",
value: `${packageName} teams switch <slug>`,
},
{
name: 'Invite new members (interactively)',
value: `${packageName} teams invite`,
},
{
name: 'Invite multiple members simultaneously',
value: `${packageName} teams invite abc@vercel.com xyz@vercel.com`,
},
{
name: 'Paginate results, where `1584722256178` is the time in milliseconds since the UNIX epoch.',
value: `${packageName} teams ls --next 1584722256178`,
},
],
};

View File

@@ -1,63 +1,12 @@
import chalk from 'chalk';
import error from '../../util/output/error';
import list from './list';
import add from './add';
import change from './switch';
import invite from './invite';
import { packageName, logo } from '../../util/pkg-name';
import getArgs from '../../util/get-args';
import Client from '../../util/client';
const help = () => {
console.log(`
${chalk.bold(`${logo} ${packageName} teams`)} [options] <command>
${chalk.dim('Commands:')}
add Create a new team
ls Show all teams you're a part of
switch [name] Switch to a different team
invite [email] Invite a new member to a team
${chalk.dim('Options:')}
-h, --help Output usage information
-A ${chalk.bold.underline('FILE')}, --local-config=${chalk.bold.underline(
'FILE'
)} Path to the local ${'`vercel.json`'} file
-Q ${chalk.bold.underline('DIR')}, --global-config=${chalk.bold.underline(
'DIR'
)} Path to the global ${'`.vercel`'} directory
-d, --debug Debug mode [off]
--no-color No color mode [off]
-N, --next Show next page of results
${chalk.dim('Examples:')}
${chalk.gray('')} Switch to a team
${chalk.cyan(`$ ${packageName} switch <slug>`)}
${chalk.gray(
''
)} If your team's url is 'vercel.com/teams/name', 'name' is the slug
${chalk.gray('')} If the slug is omitted, you can choose interactively
${chalk.yellow(
'NOTE:'
)} When you switch, everything you add, list or remove will be scoped that team!
${chalk.gray('')} Invite new members (interactively)
${chalk.cyan(`$ ${packageName} teams invite`)}
${chalk.gray('')} Paginate results, where ${chalk.dim(
'`1584722256178`'
)} is the time in milliseconds since the UNIX epoch.
${chalk.cyan(`$ ${packageName} teams ls --next 1584722256178`)}
`);
};
import { teamsCommand } from './command';
import { help } from '../help';
export default async (client: Client) => {
let subcommand;
@@ -74,7 +23,7 @@ export default async (client: Client) => {
}
if (argv['--help'] || !subcommand) {
help();
client.output.print(help(teamsCommand, { columns: client.stderr.columns }));
return 2;
}
@@ -107,7 +56,9 @@ export default async (client: Client) => {
);
}
exitCode = 2;
help();
client.output.print(
help(teamsCommand, { columns: client.stderr.columns })
);
}
}
return exitCode;

View File

@@ -1,48 +0,0 @@
import isWildcardAlias from '../alias/is-wildcard-alias';
import { getCertsForCn } from '../certs/get-certs-for-cn';
import Client from '../client';
/**
* Tries to find the "best" alias url.
* @param aliasList
*/
export async function getPreferredPreviewURL(
client: Client,
aliasList: string[]
) {
if (aliasList.length === 0) {
return null;
}
/**
* First checks for non public aliases and non wildcard domains.
*/
const preferredAliases = aliasList.filter(
alias =>
!alias.endsWith('.now.sh') &&
!alias.endsWith('.vercel.app') &&
!isWildcardAlias(alias)
);
for (const alias of preferredAliases) {
const certs = await getCertsForCn(client, alias, { limit: 1 }).catch(() => {
return null;
});
if (certs && certs.length > 0) {
return { previewUrl: `https://${alias}`, isWildcard: false };
}
}
/**
* Fallback to first alias
*/
const [firstAlias] = aliasList;
if (isWildcardAlias(firstAlias)) {
return { previewUrl: firstAlias, isWildcard: true };
}
if (firstAlias.endsWith('.vercel.app') || firstAlias.endsWith('.now.sh')) {
return { previewUrl: `https://${firstAlias}`, isWildcard: false };
}
return { previewUrl: `http://${firstAlias}`, isWildcard: false };
}

View File

@@ -1,20 +1,20 @@
import chalk from 'chalk';
import type Client from '../client';
import type { Deployment } from '@vercel-internals/types';
import { getPreferredPreviewURL } from '../../util/deploy/get-preferred-preview-url';
import { isDeploying } from '../../util/deploy/is-deploying';
import linkStyle from '../output/link';
import { prependEmoji, emoji } from '../../util/emoji';
/**
* Prints (to `client.output`) warnings and errors, if any.
*/
export async function printDeploymentStatus(
client: Client,
{
readyState,
alias: aliasList,
aliasError,
target,
indications,
url: deploymentUrl,
aliasWarning,
}: {
readyState: Deployment['readyState'];
@@ -36,7 +36,6 @@ export async function printDeploymentStatus(
const { output } = client;
indications = indications || [];
const isProdDeployment = target === 'production';
let isStillBuilding = false;
if (noWait) {
@@ -64,30 +63,6 @@ export async function printDeploymentStatus(
aliasError.message ? `: ${aliasError.message}` : ''
}`
);
} else {
// print preview/production url
let previewUrl: string;
// if `noWait` is true, then use the deployment url, not an alias
if (!noWait && Array.isArray(aliasList) && aliasList.length > 0) {
const previewUrlInfo = await getPreferredPreviewURL(client, aliasList);
if (previewUrlInfo) {
previewUrl = previewUrlInfo.previewUrl;
} else {
previewUrl = `https://${deploymentUrl}`;
}
} else {
// fallback to deployment url
previewUrl = `https://${deploymentUrl}`;
}
output.print(
prependEmoji(
`${isProdDeployment ? 'Production' : 'Preview'}: ${chalk.bold(
previewUrl
)} ${deployStamp()}`,
emoji('success')
) + `\n`
);
}
if (aliasWarning?.message) {

View File

@@ -9,7 +9,7 @@ import {
import { Output } from '../output';
import { progress } from '../output/progress';
import Now from '../../util';
import type { Org } from '@vercel-internals/types';
import type { Deployment, Org } from '@vercel-internals/types';
import ua from '../ua';
import { linkFolderToProject } from '../projects/link';
import { prependEmoji, emoji } from '../emoji';
@@ -17,9 +17,13 @@ import type { Agent } from 'http';
function printInspectUrl(
output: Output,
inspectorUrl: string,
inspectorUrl: string | null | undefined,
deployStamp: () => string
) {
if (!inspectorUrl) {
return;
}
output.print(
prependEmoji(
`Inspect: ${chalk.bold(inspectorUrl)} ${deployStamp()}`,
@@ -162,33 +166,47 @@ export default async function processDeployment({
}
if (event.type === 'created') {
const deployment: Deployment = event.payload;
await linkFolderToProject(
client,
cwd,
{
orgId: org.id,
projectId: event.payload.projectId,
projectId: deployment.projectId!,
},
projectName,
org.slug
);
now.url = event.payload.url;
now.url = deployment.url;
output.stopSpinner();
printInspectUrl(output, event.payload.inspectorUrl, deployStamp);
printInspectUrl(output, deployment.inspectorUrl, deployStamp);
const isProdDeployment = requestBody.target === 'production';
const previewUrl = `https://${deployment.url}`;
output.print(
prependEmoji(
`${isProdDeployment ? 'Production' : 'Preview'}: ${chalk.bold(
previewUrl
)} ${deployStamp()}`,
emoji('success')
) + `\n`
);
if (quiet) {
process.stdout.write(`https://${event.payload.url}`);
}
if (noWait) {
return event.payload;
return deployment;
}
output.spinner(
event.payload.readyState === 'QUEUED' ? 'Queued' : 'Building',
deployment.readyState === 'QUEUED' ? 'Queued' : 'Building',
0
);
}
@@ -243,6 +261,7 @@ export default async function processDeployment({
// Handle alias-assigned event
if (event.type === 'alias-assigned') {
output.stopSpinner();
event.payload.indications = indications;
return event.payload;
}

View File

@@ -1,8 +0,0 @@
export default (code?: number) =>
new Promise(() => {
// We give stdout some time to flush out
// because there's a node bug where
// stdout writes are asynchronous
// https://github.com/nodejs/node/issues/6456
setTimeout(() => process.exit(code || 0), 100);
});

View File

@@ -735,6 +735,12 @@ test('deploys with only vercel.json and README.md', async () => {
});
expect(exitCode, formatOutput({ stdout, stderr })).toBe(0);
// assert timing order of showing URLs vs status updates
expect(stderr).toMatch(
/Inspect.*\nPreview.*\nQueued.*\nBuilding.*\nCompleting/
);
const { host } = new URL(stdout);
const res = await fetch(`https://${host}/README.md`);
const text = await res.text();

View File

@@ -0,0 +1,29 @@
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

@@ -0,0 +1,37 @@
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.0.2
### Patch Changes
- Updated dependencies [[`5609a1187`](https://github.com/vercel/vercel/commit/5609a1187be9d6cf8d5f16825690c5ea72f17dc5), [`1b4de4a98`](https://github.com/vercel/vercel/commit/1b4de4a986f7a612aac834ebae3ec7bb9e9b8cf8)]:
- @vercel/build-utils@7.1.1
## 13.0.1
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/client",
"version": "13.0.1",
"version": "13.0.2",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"homepage": "https://vercel.com",
@@ -14,7 +14,7 @@
"directory": "packages/client"
},
"scripts": {
"build": "tsc",
"build": "node ../../utils/build.mjs",
"test-e2e": "pnpm test tests/create-deployment.test.ts tests/create-legacy-deployment.test.ts tests/paths.test.ts",
"test": "jest --reporters=default --reporters=jest-junit --env node --verbose --runInBand --bail",
"test-unit": "pnpm test tests/unit.*test.*"
@@ -36,7 +36,7 @@
"typescript": "4.9.5"
},
"dependencies": {
"@vercel/build-utils": "7.1.0",
"@vercel/build-utils": "7.1.1",
"@vercel/routing-utils": "3.0.0",
"@zeit/fetch": "5.2.0",
"async-retry": "1.2.3",

View File

@@ -1,6 +1,7 @@
{
"compilerOptions": {
"declaration": true,
"emitDeclarationOnly": true,
"esModuleInterop": true,
"lib": ["ES2021"],
"module": "commonjs",

View File

@@ -13,7 +13,7 @@
"directory": "packages/error-utils"
},
"scripts": {
"build": "tsc",
"build": "node ../../utils/build.mjs",
"test": "jest --reporters=default --reporters=jest-junit --coverage --env node --verbose",
"test-unit": "pnpm test"
},

View File

@@ -1,7 +1,7 @@
{
"compilerOptions": {
"declaration": true,
"declarationMap": true,
"emitDeclarationOnly": true,
"esModuleInterop": true,
"lib": ["ES2021"],
"module": "commonjs",

View File

@@ -13,7 +13,7 @@
},
"license": "Apache-2.0",
"scripts": {
"build": "tsc",
"build": "node ../../utils/build.mjs",
"test": "jest --reporters=default --reporters=jest-junit --env node --verbose --runInBand --bail",
"test-unit": "pnpm test"
},

View File

@@ -1,6 +1,7 @@
{
"compilerOptions": {
"declaration": true,
"emitDeclarationOnly": true,
"esModuleInterop": true,
"lib": ["ES2021"],
"module": "commonjs",

View File

@@ -1,5 +1,11 @@
# @vercel/fs-detectors
## 5.0.2
### Patch Changes
- Updated semver dependency ([#10411](https://github.com/vercel/vercel/pull/10411))
## 5.0.1
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/fs-detectors",
"version": "5.0.1",
"version": "5.0.2",
"description": "Vercel filesystem detectors",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
@@ -14,7 +14,7 @@
},
"license": "Apache-2.0",
"scripts": {
"build": "tsc",
"build": "node ../../utils/build.mjs",
"test": "jest --reporters=default --reporters=jest-junit --env node --verbose --runInBand --bail",
"test-unit": "pnpm test test/unit.*test.*",
"test-e2e": "pnpm test test/integration.test.ts"
@@ -27,7 +27,7 @@
"js-yaml": "4.1.0",
"json5": "2.2.2",
"minimatch": "3.1.2",
"semver": "6.1.1"
"semver": "6.3.1"
},
"devDependencies": {
"@types/glob": "7.2.0",
@@ -36,7 +36,7 @@
"@types/minimatch": "3.0.5",
"@types/node": "14.18.33",
"@types/semver": "7.3.10",
"@vercel/build-utils": "7.1.0",
"@vercel/build-utils": "7.1.1",
"jest-junit": "16.0.0",
"typescript": "4.9.5"
}

View File

@@ -1,6 +1,7 @@
{
"compilerOptions": {
"declaration": true,
"emitDeclarationOnly": true,
"esModuleInterop": true,
"lib": ["ES2021"],
"module": "commonjs",

View File

@@ -1,5 +1,13 @@
# @vercel/gatsby-plugin-vercel-builder
## 2.0.4
### Patch Changes
- Updated dependencies [[`5609a1187`](https://github.com/vercel/vercel/commit/5609a1187be9d6cf8d5f16825690c5ea72f17dc5), [`1b4de4a98`](https://github.com/vercel/vercel/commit/1b4de4a986f7a612aac834ebae3ec7bb9e9b8cf8), [`fc1e13c09`](https://github.com/vercel/vercel/commit/fc1e13c09928c654410b373fc1775c2b63c6ef4a)]:
- @vercel/build-utils@7.1.1
- @vercel/node@3.0.4
## 2.0.3
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/gatsby-plugin-vercel-builder",
"version": "2.0.3",
"version": "2.0.4",
"main": "dist/index.js",
"files": [
"dist",
@@ -20,8 +20,8 @@
},
"dependencies": {
"@sinclair/typebox": "0.25.24",
"@vercel/build-utils": "7.1.0",
"@vercel/node": "3.0.3",
"@vercel/build-utils": "7.1.1",
"@vercel/node": "3.0.4",
"@vercel/routing-utils": "3.0.0",
"esbuild": "0.14.47",
"etag": "1.8.1",

View File

@@ -27,7 +27,7 @@
"@types/node-fetch": "^2.3.0",
"@types/tar": "^4.0.0",
"@types/yauzl-promise": "2.1.0",
"@vercel/build-utils": "7.1.0",
"@vercel/build-utils": "7.1.1",
"@vercel/ncc": "0.24.0",
"async-retry": "1.3.1",
"execa": "^1.0.0",

View File

@@ -1,12 +0,0 @@
const execa = require('execa');
const { remove } = require('fs-extra');
async function main() {
await remove('dist');
await execa('tsc', [], { stdio: 'inherit' });
}
main().catch(err => {
console.error(err);
process.exit(1);
});

View File

@@ -10,7 +10,7 @@
"directory": "packages/hydrogen"
},
"scripts": {
"build": "node build.js",
"build": "node ../../utils/build.mjs",
"test-e2e": "pnpm test test/test.js",
"test": "jest --reporters=default --reporters=jest-junit --env node --verbose --bail --runInBand"
},
@@ -21,7 +21,7 @@
"devDependencies": {
"@types/jest": "27.5.1",
"@types/node": "14.18.33",
"@vercel/build-utils": "7.1.0",
"@vercel/build-utils": "7.1.1",
"@vercel/static-config": "3.0.0",
"execa": "3.2.0",
"fs-extra": "11.1.0",

View File

@@ -1,6 +1,7 @@
{
"compilerOptions": {
"declaration": true,
"emitDeclarationOnly": true,
"esModuleInterop": true,
"lib": ["ES2021"],
"module": "commonjs",

View File

@@ -1,5 +1,19 @@
# @vercel/next
## 4.0.2
### Patch Changes
- Fix Next.js with `basePath` + Edge runtime + App Router on a top level `page.jsx` ([#10465](https://github.com/vercel/vercel/pull/10465))
- Updated semver dependency ([#10411](https://github.com/vercel/vercel/pull/10411))
- Fix RSC rewrite behavior ([#10415](https://github.com/vercel/vercel/pull/10415))
- fix ENOENT on /404.html when `fallback: false` w/ `basePath` ([#10473](https://github.com/vercel/vercel/pull/10473))
- fix 404 enoent for i18n ([#10416](https://github.com/vercel/vercel/pull/10416))
## 4.0.1
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/next",
"version": "4.0.1",
"version": "4.0.2",
"license": "Apache-2.0",
"main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/next-js",
@@ -35,7 +35,7 @@
"@types/semver": "6.0.0",
"@types/text-table": "0.2.1",
"@types/webpack-sources": "3.2.0",
"@vercel/build-utils": "7.1.0",
"@vercel/build-utils": "7.1.1",
"@vercel/nft": "0.22.5",
"@vercel/routing-utils": "3.0.0",
"async-sema": "3.0.1",
@@ -54,7 +54,7 @@
"ndjson": "2.0.0",
"pretty-bytes": "5.3.0",
"resolve-from": "5.0.0",
"semver": "6.1.1",
"semver": "6.3.1",
"set-cookie-parser": "2.4.6",
"source-map": "0.7.3",
"test-listen": "1.1.0",

View File

@@ -91,6 +91,7 @@ import {
getOperationType,
isApiPage,
getFunctionsConfigManifest,
normalizeEdgeFunctionPath,
} from './utils';
export const version = 2;
@@ -1320,11 +1321,7 @@ export const build: BuildV2 = async ({
const localePrefixed404 = !!(
routesManifest.i18n &&
originalStaticPages[
path.posix.join(
entryDirectory,
routesManifest.i18n.defaultLocale,
'404.html'
)
path.posix.join('.', routesManifest.i18n.defaultLocale, '404.html')
]
);
@@ -2720,7 +2717,15 @@ async function getServerlessPages(params: {
for (const edgeFunctionFile of Object.keys(
middlewareManifest?.functions ?? {}
)) {
const edgePath = (edgeFunctionFile.slice(1) || 'index') + '.js';
let edgePath =
middlewareManifest?.functions?.[edgeFunctionFile].name ||
edgeFunctionFile;
edgePath = normalizeEdgeFunctionPath(
edgePath,
params.appPathRoutesManifest || {}
);
edgePath = (edgePath || 'index') + '.js';
delete normalizedAppPaths[edgePath];
delete pages[edgePath];
}

View File

@@ -1074,8 +1074,7 @@ export async function serverBuild({
canUsePreviewMode,
prerenderManifest.bypassToken || '',
true,
middleware.dynamicRouteMap,
inversedAppPathManifest
middleware.dynamicRouteMap
).then(arr =>
localizeDynamicRoutes(
arr,
@@ -1090,6 +1089,32 @@ export async function serverBuild({
)
);
const pagesPlaceholderRscEntries: Record<string, FileBlob> = {};
if (appDir) {
// since we attempt to rewrite all paths to an .rsc variant,
// we need to create dummy rsc outputs for all pages entries
// this is so that an RSC request to a `pages` entry will match
// rather than falling back to a catchall `app` entry
// on the nextjs side, invalid RSC response payloads will correctly trigger an mpa navigation
const pagesManifest = path.join(
entryPath,
outputDirectory,
`server/pages-manifest.json`
);
const pagesData = await fs.readJSON(pagesManifest);
const pagesEntries = Object.keys(pagesData);
for (const page of pagesEntries) {
const pathName = page.startsWith('/') ? page.slice(1) : page;
pagesPlaceholderRscEntries[`${pathName}.rsc`] = new FileBlob({
data: '{}',
contentType: 'application/json',
});
}
}
const { staticFiles, publicDirectoryFiles, staticDirectoryFiles } =
await getStaticFiles(entryPath, entryDirectory, outputDirectory);
@@ -1220,10 +1245,9 @@ export async function serverBuild({
if (ogRoute.endsWith('/route')) {
continue;
}
route = path.posix.join(
'./',
entryDirectory,
route === '/' ? '/index' : route
route = normalizeIndexOutput(
path.posix.join('./', entryDirectory, route === '/' ? '/index' : route),
true
);
if (lambdas[route]) {
@@ -1249,6 +1273,7 @@ export async function serverBuild({
...publicDirectoryFiles,
...lambdas,
...appRscPrefetches,
...pagesPlaceholderRscEntries,
// Prerenders may override Lambdas -- this is an intentional behavior.
...prerenders,
...staticPages,
@@ -1632,72 +1657,22 @@ export async function serverBuild({
]
: []),
...(appDir
? [
// check routes that end in `.rsc` to see if a page with the resulting name (sans-.rsc) exists in the filesystem
// if so, we want to match that page instead. (This matters when prefetching a pages route while on an appdir route)
{
src: `^${path.posix.join('/', entryDirectory, '/(.*)\\.rsc$')}`,
dest: path.posix.join('/', entryDirectory, '/$1'),
has: [
{
type: 'header',
key: rscHeader,
},
],
...(rscPrefetchHeader
? {
missing: [
{
type: 'header',
key: rscPrefetchHeader,
},
],
}
: {}),
check: true,
} as Route,
]
: []),
// These need to come before handle: miss or else they are grouped
// with that routing section
...afterFilesRewrites,
...(appDir
? [
// rewrite route back to `.rsc`, but skip checking fs
{
src: `^${path.posix.join(
'/',
entryDirectory,
'/((?!.+\\.rsc).+?)(?:/)?$'
)}`,
has: [
{
type: 'header',
key: rscHeader,
},
],
dest: path.posix.join('/', entryDirectory, '/$1.rsc'),
headers: { vary: rscVaryHeader },
continue: true,
override: true,
},
]
: []),
// make sure 404 page is used when a directory is matched without
// an index page
{ handle: 'resource' },
...fallbackRewrites,
// make sure 404 page is used when a directory is matched without
// an index page
{ src: path.posix.join('/', entryDirectory, '.*'), status: 404 },
{ handle: 'miss' },
// We need to make sure to 404 for /_next after handle: miss since
// handle: miss is called before rewrites and to prevent rewriting /_next
{ handle: 'miss' },
{
src: path.posix.join(
'/',

View File

@@ -305,8 +305,7 @@ export async function getDynamicRoutes(
canUsePreviewMode?: boolean,
bypassToken?: string,
isServerMode?: boolean,
dynamicMiddlewareRouteMap?: Map<string, RouteWithSrc>,
appPathRoutesManifest?: Record<string, string>
dynamicMiddlewareRouteMap?: Map<string, RouteWithSrc>
): Promise<RouteWithSrc[]> {
if (routesManifest) {
switch (routesManifest.version) {
@@ -379,8 +378,6 @@ export async function getDynamicRoutes(
},
];
}
if (appPathRoutesManifest?.[page]) {
routes.push({
...route,
src: route.src.replace(
@@ -389,7 +386,7 @@ export async function getDynamicRoutes(
),
dest: route.dest?.replace(/($|\?)/, '.rsc$1'),
});
}
routes.push(route);
continue;
}
@@ -2347,7 +2344,7 @@ export function normalizeIndexOutput(
outputName: string,
isServerMode: boolean
) {
if (outputName !== '/index' && isServerMode) {
if (outputName !== 'index' && outputName !== '/index' && isServerMode) {
return outputName.replace(/\/index$/, '');
}
return outputName;
@@ -2524,6 +2521,29 @@ function normalizeRegions(regions: Regions): undefined | string | string[] {
return newRegions;
}
export function normalizeEdgeFunctionPath(
shortPath: string,
appPathRoutesManifest: Record<string, string>
) {
if (
shortPath.startsWith('app/') &&
(shortPath.endsWith('/page') ||
shortPath.endsWith('/route') ||
shortPath === 'app/_not-found')
) {
const ogRoute = shortPath.replace(/^app\//, '/');
shortPath = (
appPathRoutesManifest[ogRoute] ||
shortPath.replace(/(^|\/)(page|route)$/, '')
).replace(/^\//, '');
if (!shortPath || shortPath === '/') {
shortPath = 'index';
}
}
return shortPath;
}
export async function getMiddlewareBundle({
entryPath,
outputDirectory,
@@ -2702,27 +2722,19 @@ export async function getMiddlewareBundle({
// app/index/page -> index/index
if (shortPath.startsWith('pages/')) {
shortPath = shortPath.replace(/^pages\//, '');
} else if (
shortPath.startsWith('app/') &&
(shortPath.endsWith('/page') ||
shortPath.endsWith('/route') ||
shortPath === 'app/_not-found')
) {
const ogRoute = shortPath.replace(/^app\//, '/');
shortPath = (
appPathRoutesManifest[ogRoute] ||
shortPath.replace(/(^|\/)(page|route)$/, '')
).replace(/^\//, '');
if (!shortPath || shortPath === '/') {
shortPath = 'index';
}
} else {
shortPath = normalizeEdgeFunctionPath(shortPath, appPathRoutesManifest);
}
if (routesManifest?.basePath) {
shortPath = path.posix
.join(routesManifest.basePath, shortPath)
.replace(/^\//, '');
shortPath = normalizeIndexOutput(
path.posix.join(
'./',
routesManifest?.basePath,
shortPath.replace(/^\//, '')
),
true
);
}
worker.edgeFunction.name = shortPath;

View File

@@ -1,7 +1,10 @@
import Link from 'next/link';
export default function Home() {
return (
<div>
<h1>Home</h1>
<Link href="/en/about">About</Link>
</div>
);
}

View File

@@ -16,7 +16,7 @@
"headers": {
"RSC": "1"
},
"mustContain": "<html"
"bodyMustBe": "{}"
},
{
"path": "/en/foobar",

View File

@@ -2,4 +2,6 @@ export default function handler(req, res) {
return res.json({ hello: 'world' });
}
export const maxDuration = 7;
export const config = {
maxDuration: 7
};

View File

@@ -0,0 +1,16 @@
export default async function DynamicPage({ params }) {
return (
<main>
<h1>Dynamic page</h1>
<p>Param: {params.text}</p>
</main>
);
}
export async function generateStaticParams() {
return [
{
text: 'one',
},
];
}

View File

@@ -0,0 +1,9 @@
export default function Page(props) {
return <div>SSRed Page</div>
}
export async function getServerSideProps() {
return {
props: {},
}
}

View File

@@ -0,0 +1,3 @@
export default function Page() {
return 'Hello World'
}

View File

@@ -47,6 +47,15 @@
"mustContain": ":",
"mustNotContain": "<html"
},
{
"path": "/docs/categories/foo?_rsc=f7pci",
"status": 200,
"headers": {
"RSC": "1",
"Next-Router-Prefetch": "1"
},
"bodyMustBe": "{}"
},
{
"path": "/ssg",
"status": 200,
@@ -235,6 +244,24 @@
},
"mustContain": ":{",
"mustNotContain": "<html"
},
{
"path": "/gsp/one",
"status": 200,
"headers": {
"RSC": "1"
},
"mustContain": ":{",
"mustNotContain": "<html"
},
{
"path": "/gsp/two",
"status": 200,
"headers": {
"RSC": "1"
},
"mustContain": ":{",
"mustNotContain": "<html"
}
]
}

View File

@@ -0,0 +1,8 @@
const path = require('path');
const { deployAndTest } = require('../../utils');
describe(`${__dirname.split(path.sep).pop()}`, () => {
it('should deploy and pass probe checks', async () => {
await deployAndTest(__dirname);
});
});

View File

@@ -0,0 +1,10 @@
module.exports = {
generateBuildId() {
return 'testing-build-id';
},
basePath: '/docs',
i18n: {
locales: ['en', 'fr', 'nl'],
defaultLocale: 'en',
},
};

View File

@@ -0,0 +1,8 @@
{
"dependencies": {
"next": "canary",
"react": "latest",
"react-dom": "latest"
},
"ignoreNextjsUpdates": true
}

View File

@@ -0,0 +1,3 @@
export default function NotFound() {
return 'not found page';
}

View File

@@ -0,0 +1,13 @@
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />;
}
export const getStaticProps = ({ locale }) => ({
props: {
locale
}
});
export default MyApp;

View File

@@ -0,0 +1,11 @@
export default function Another() {
return 'another page';
}
export const getStaticProps = ({ locale }) => ({
props: {
locale,
hello: 'world',
},
revalidate: 1,
});

View File

@@ -0,0 +1,3 @@
export default function handler(req, res) {
res.json({ slug: req.query.slug });
}

View File

@@ -0,0 +1,3 @@
export default function handler(req, res) {
res.json({ rest: req.query.rest.join('/') });
}

View File

@@ -0,0 +1,6 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
export default (req, res) => {
res.statusCode = 200;
res.json({ name: 'John Doe' });
};

View File

@@ -0,0 +1,25 @@
export default function Page() {
return 'Hello World';
}
export const getStaticProps = async ({ locale, params }) => {
const id = params?.['slug'];
if (!id) {
return {
notFound: true,
};
}
return {
props: {
locale,
},
};
};
export const getStaticPaths = async () => {
return {
paths: [{ params: { slug: 'test' } }],
fallback: false,
};
};

View File

@@ -0,0 +1,3 @@
export default function Page() {
return 'hello page';
}

View File

@@ -0,0 +1,11 @@
export default function Home() {
return 'index page';
}
export const getServerSideProps = ({ locale }) => ({
props: {
locale,
hello: 'world',
gsspData: true,
},
});

View File

@@ -0,0 +1,84 @@
{
"probes": [
{
"path": "/docs/non-existent",
"status": 404,
"mustContain": "not found page"
},
{
"path": "/docs/non-existent",
"status": 404,
"mustContain": "lang=\"en\""
},
{
"path": "/docs/fr/non-existent",
"status": 404,
"mustContain": "not found page"
},
{
"path": "/docs/fr/non-existent",
"status": 404,
"mustContain": "lang=\"fr\""
},
{
"path": "/docs",
"status": 200,
"mustContain": "index page"
},
{
"path": "/docs/fr",
"status": 200,
"mustContain": "index page"
},
{
"path": "/docs/another",
"status": 200,
"mustContain": "another page"
},
{
"path": "/docs/fr/another",
"status": 200,
"mustContain": "another page"
},
{
"path": "/docs/fr/another",
"status": 200,
"mustContain": "lang=\"fr\""
},
{
"path": "/docs/hello",
"status": 200,
"mustContain": "hello page"
},
{
"path": "/docs/hello",
"status": 200,
"mustContain": "lang=\"en\""
},
{
"path": "/docs/fr/hello",
"status": 200,
"mustContain": "hello page"
},
{
"path": "/docs/fr/hello",
"status": 200,
"mustContain": "lang=\"fr\""
},
{
"path": "/docs/api/hello",
"status": 200,
"mustContain": "John Doe"
},
{
"path": "/docs/api/blog/first",
"status": 200,
"mustContain": "\"slug\":\"first\""
},
{
"path": "/docs/api/catchall/hello/world",
"status": 200,
"mustContain": "\"rest\":\"hello/world\""
}
]
}

View File

@@ -0,0 +1,7 @@
export const runtime = 'edge';
const Home = () => {
return <div>another</div>;
};
export default Home;

View File

@@ -0,0 +1,7 @@
export const runtime = 'edge';
const Home = () => {
return <div>dynamic</div>;
};
export default Home;

View File

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

View File

@@ -0,0 +1,7 @@
export const runtime = 'edge';
const Home = () => {
return <div>Home</div>;
};
export default Home;

View File

@@ -0,0 +1,7 @@
export const runtime = 'edge';
const Home = () => {
return <div>test</div>;
};
export default Home;

View File

@@ -0,0 +1,7 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
basePath: '/test',
};
module.exports = nextConfig;

View File

@@ -0,0 +1,8 @@
{
"dependencies": {
"next": "canary",
"react": "latest",
"react-dom": "latest"
},
"ignoreNextjsUpdates": true
}

View File

@@ -0,0 +1,4 @@
{
"version": 2,
"builds": [{ "src": "package.json", "use": "@vercel/next" }]
}

View File

@@ -553,3 +553,52 @@ it('Should de-dupe correctly when limit is close (uncompressed)', async () => {
expect(lambdas.size).toBe(2);
expect(lambdas.size).toBeLessThan(totalLambdas);
});
it('should handle edge functions in app with basePath', async () => {
const {
buildResult: { output },
} = await runBuildLambda(path.join(__dirname, 'edge-app-dir-basepath'));
console.error(output);
expect(output['test']).toBeDefined();
expect(output['test']).toBeDefined();
expect(output['test'].type).toBe('EdgeFunction');
expect(output['test'].type).toBe('EdgeFunction');
expect(output['test/another']).toBeDefined();
expect(output['test/another.rsc']).toBeDefined();
expect(output['test/another'].type).toBe('EdgeFunction');
expect(output['test/another.rsc'].type).toBe('EdgeFunction');
expect(output['test/dynamic/[slug]']).toBeDefined();
expect(output['test/dynamic/[slug].rsc']).toBeDefined();
expect(output['test/dynamic/[slug]'].type).toBe('EdgeFunction');
expect(output['test/dynamic/[slug].rsc'].type).toBe('EdgeFunction');
expect(output['test/dynamic/[slug]']).toBeDefined();
expect(output['test/dynamic/[slug].rsc']).toBeDefined();
expect(output['test/dynamic/[slug]'].type).toBe('EdgeFunction');
expect(output['test/dynamic/[slug].rsc'].type).toBe('EdgeFunction');
expect(output['test/test']).toBeDefined();
expect(output['test/test.rsc']).toBeDefined();
expect(output['test/test'].type).toBe('EdgeFunction');
expect(output['test/test.rsc'].type).toBe('EdgeFunction');
expect(output['test/_not-found']).toBeDefined();
expect(output['test/_not-found'].type).toBe('Lambda');
const lambdas = new Set();
const edgeFunctions = new Set();
for (const item of Object.values(output)) {
if (item.type === 'Lambda') {
lambdas.add(item);
} else if (item.type === 'EdgeFunction') {
edgeFunctions.add(item);
}
}
expect(lambdas.size).toBe(1);
expect(edgeFunctions.size).toBe(4);
});

View File

@@ -1,5 +1,14 @@
# @vercel/node
## 3.0.4
### Patch Changes
- remove console.log ([#10417](https://github.com/vercel/vercel/pull/10417))
- Updated dependencies [[`5609a1187`](https://github.com/vercel/vercel/commit/5609a1187be9d6cf8d5f16825690c5ea72f17dc5), [`1b4de4a98`](https://github.com/vercel/vercel/commit/1b4de4a986f7a612aac834ebae3ec7bb9e9b8cf8)]:
- @vercel/build-utils@7.1.1
## 3.0.3
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/node",
"version": "3.0.3",
"version": "3.0.4",
"license": "Apache-2.0",
"main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/node-js",
@@ -23,7 +23,7 @@
"@edge-runtime/primitives": "3.1.0",
"@edge-runtime/vm": "3.1.0",
"@types/node": "14.18.33",
"@vercel/build-utils": "7.1.0",
"@vercel/build-utils": "7.1.1",
"@vercel/error-utils": "2.0.1",
"@vercel/static-config": "3.0.0",
"async-listen": "3.0.0",

View File

@@ -23,7 +23,7 @@
"@types/execa": "^0.9.0",
"@types/jest": "27.4.1",
"@types/node": "14.18.33",
"@vercel/build-utils": "7.1.0",
"@vercel/build-utils": "7.1.1",
"@vercel/ncc": "0.24.0",
"execa": "^1.0.0",
"jest-junit": "16.0.0"

View File

@@ -1,5 +1,11 @@
# @vercel/redwood
## 2.0.1
### Patch Changes
- Updated semver dependency ([#10411](https://github.com/vercel/vercel/pull/10411))
## 2.0.0
### Major Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/redwood",
"version": "2.0.0",
"version": "2.0.1",
"main": "./dist/index.js",
"license": "Apache-2.0",
"homepage": "https://vercel.com/docs",
@@ -21,13 +21,13 @@
"dependencies": {
"@vercel/nft": "0.22.5",
"@vercel/routing-utils": "3.0.0",
"semver": "6.1.1"
"semver": "6.3.1"
},
"devDependencies": {
"@types/aws-lambda": "8.10.19",
"@types/node": "14.18.33",
"@types/semver": "6.0.0",
"@vercel/build-utils": "7.1.0",
"@vercel/build-utils": "7.1.1",
"execa": "3.2.0",
"fs-extra": "11.1.0",
"jest-junit": "16.0.0"

View File

@@ -1,5 +1,14 @@
# @vercel/remix-builder
## 2.0.3
### Patch Changes
- Updated semver dependency ([#10411](https://github.com/vercel/vercel/pull/10411))
- Updated dependencies [[`5609a1187`](https://github.com/vercel/vercel/commit/5609a1187be9d6cf8d5f16825690c5ea72f17dc5), [`1b4de4a98`](https://github.com/vercel/vercel/commit/1b4de4a986f7a612aac834ebae3ec7bb9e9b8cf8)]:
- @vercel/build-utils@7.1.1
## 2.0.2
### Patch Changes

View File

@@ -1,12 +0,0 @@
const execa = require('execa');
const { remove } = require('fs-extra');
async function main() {
await remove('dist');
await execa('tsc', [], { stdio: 'inherit' });
}
main().catch(err => {
console.error(err);
process.exit(1);
});

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