Compare commits

..

11 Commits

Author SHA1 Message Date
Nathan Rajlich
d1d3e9384d Publish Stable
- vercel@29.2.0
 - @vercel/client@12.5.0
 - @vercel/frameworks@1.4.2
 - @vercel/fs-detectors@3.9.2
 - @vercel/gatsby-plugin-vercel-builder@1.3.3
 - @vercel/node@2.14.2
 - @vercel/static-build@1.3.30
2023-05-10 10:39:11 -07:00
Nathan Rajlich
8428632eb1 [cli] Add support for Vercel CLI Extensions (#9800)
# Vercel CLI Extensions

Adds a new mechanism to add additional sub-commands to Vercel CLI, inspired by how Git handles sub-commands:

* Extensions are standalone executables that Vercel CLI will spawn as a child process.
* The name of the executable must begin with `vercel-`. For example, to add a sub-command called `vercel example`, there should exist an executable called `vercel-example`.
* The executable can either be a npm package with a `"bin"` entry installed into the local project's workspace, or be globally available in the `$PATH`.
* Extensions can access the [Vercel REST API](https://vercel.com/docs/rest-api), pre-authenticated, by utilizing the `VERCEL_API` env var. Vercel CLI spawns a local HTTP server that adds the `Authorization` header and then proxies to the Vercel REST API.

## Environment Variables

A few environment variables which provide features and context to the extension:

| Name      | Description |
| ----------- | ----------- |
| `VERCEL_API`      | HTTP URL to access the pre-authenticated Vercel API.       |
| `VERCEL_TEAM_ID`  | Provided when the currently selected scope is a Team. |
| `VERCEL_DEBUG` | Provided when the `--debug` flag is used. The command _may_ output additional debug logging. |
| `VERCEL_HELP` | Provided when the `--help` flag is used. The command _should_ print the help output and then end with exit code **2**. |

## Example

```bash
#!/usr/bin/env bash
set -euo pipefail

echo Hi, from a Vercel CLI Extension!
user="$(curl -s "$VERCEL_API/v2/user" | jq -r .user.username)"
echo "Logged in as: $user"
```

Usage:

```
$ vc example
Vercel CLI 28.18.5
Hi, from a Vercel CLI Extension!
Logged in as: tootallnate
```
2023-05-10 16:36:58 +00:00
Chris Barber
fa443035f6 [tests] Add test for set-cookie with multiple cookies (#9916)
This adds the missing test for https://github.com/vercel/vercel/pull/9899.
2023-05-06 10:18:52 +00:00
Sean Massa
de2c7e1633 [cli] rename global options in help output (#9917)
Make the distinction between global and deploy options more clear.

The dim note about how to get `deploy`-specific help:

<img width="670" alt="Screenshot 2023-05-05 at 3 55 49 PM" src="https://user-images.githubusercontent.com/41545/236568356-10b9ce4f-2865-4267-a3eb-3488df88a133.png">
2023-05-05 22:00:27 +00:00
Sean Massa
75d2435138 [cli] refactor help output around default and deploy commands (#9912)
When getting help output for the default command `vc --help`, you get a list of commands. When you specify the `deploy` command with `vc deploy --help`, you get the same list of commands.

This PR makes a distinction between an explicit `deploy` command and a default one for the purposes of help output.

Should show CLI help:

- `vc -h`
- `vc --help`
- `vc help`

Should show `deploy` command help:

- `vc deploy -h`
- `vc deploy --help`
- `vc help deploy`
2023-05-05 18:54:50 +00:00
Vercel Release Bot
5328bb69e2 [examples] Upgrade Next.js to version 13.4.1 (#9911)
This auto-generated PR updates Next.js to version 13.4.1
2023-05-05 16:25:11 +00:00
Kiko Beats
e3fe368baa [cli][node] upgrade async-listen to 3.0.0 (#9907)
The `async-listen@3.0.0` is ESM ready and always returns a `URL`
instance; That helps us to unify code.
2023-05-05 16:09:10 +02:00
Nathan Rajlich
99832587c5 [cli] Add support for HTTPS_PROXY env var (#9880)
By leveraging the [`proxy-agent`](https://www.npmjs.com/package/proxy-agent) npm module, enable CLI to support making HTTP requests over a proxy, by leveraging the `HTTPS_PROXY` or `ALL_PROXY` env var (same convention as `curl` uses).

Finally closes this ancient issue: https://github.com/vercel/vercel/issues/255
2023-05-05 00:52:18 +00:00
Vercel Release Bot
47d0d4f84a [examples] Upgrade Next.js to version 13.4.0 (#9902)
This auto-generated PR updates Next.js to version 13.4.0
2023-05-04 20:25:08 +00:00
Sean Massa
aba54ee6cf [frameworks] validate getOutputDirName and other missing values on framework entries (#9900)
Covers the validation whole in Framework entries over function properties and other missing holes.
2023-05-03 23:36:26 +00:00
Chris Barber
cd7d3ef1c5 [node] Explicitly set 'set-cookie' header (#9899)
When looping over the response headers returned by `node-fetch`, it will join `set-cookie` header value into a single string. The whatwg calls for a `headers.getSetCookie()` function to handle the `set-cookie` special case, but `node-fetch@2.x` doesn't support it.

As a workaround, we need to grab the raw `set-cookie` header value.
2023-05-03 22:12:45 +00:00
52 changed files with 1788 additions and 857 deletions

View File

@@ -14,11 +14,7 @@ pnpm dev
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
[API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`.
The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages.
You can start editing the page by modifying `app/page.js`. The page auto-updates as you edit the file.
This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.

View File

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 25 KiB

View File

@@ -0,0 +1,17 @@
import './globals.css'
import { Inter } from 'next/font/google'
const inter = Inter({ subsets: ['latin'] })
export const metadata = {
title: 'Create Next App',
description: 'Generated by create next app',
}
export default function RootLayout({ children }) {
return (
<html lang="en">
<body className={inter.className}>{children}</body>
</html>
)
}

View File

@@ -0,0 +1,95 @@
import Image from 'next/image'
import styles from './page.module.css'
export default function Home() {
return (
<main className={styles.main}>
<div className={styles.description}>
<p>
Get started by editing&nbsp;
<code className={styles.code}>app/page.js</code>
</p>
<div>
<a
href="https://vercel.com?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
By{' '}
<Image
src="/vercel.svg"
alt="Vercel Logo"
className={styles.vercelLogo}
width={100}
height={24}
priority
/>
</a>
</div>
</div>
<div className={styles.center}>
<Image
className={styles.logo}
src="/next.svg"
alt="Next.js Logo"
width={180}
height={37}
priority
/>
</div>
<div className={styles.grid}>
<a
href="https://beta.nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
className={styles.card}
target="_blank"
rel="noopener noreferrer"
>
<h2>
Docs <span>-&gt;</span>
</h2>
<p>Find in-depth information about Next.js features and API.</p>
</a>
<a
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
className={styles.card}
target="_blank"
rel="noopener noreferrer"
>
<h2>
Learn <span>-&gt;</span>
</h2>
<p>Learn about Next.js in an interactive course with&nbsp;quizzes!</p>
</a>
<a
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
className={styles.card}
target="_blank"
rel="noopener noreferrer"
>
<h2>
Templates <span>-&gt;</span>
</h2>
<p>Explore the Next.js 13 playground.</p>
</a>
<a
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
className={styles.card}
target="_blank"
rel="noopener noreferrer"
>
<h2>
Deploy <span>-&gt;</span>
</h2>
<p>
Instantly deploy your Next.js site to a shareable URL with Vercel.
</p>
</a>
</div>
</main>
)
}

View File

@@ -1,6 +1,4 @@
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
}
const nextConfig = {}
module.exports = nextConfig

View File

@@ -9,8 +9,8 @@
"version": "0.1.0",
"dependencies": {
"eslint": "8.39.0",
"eslint-config-next": "13.3.4",
"next": "13.3.4",
"eslint-config-next": "13.4.1",
"next": "13.4.1",
"react": "18.2.0",
"react-dom": "18.2.0"
}
@@ -109,22 +109,22 @@
"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA=="
},
"node_modules/@next/env": {
"version": "13.3.4",
"resolved": "https://registry.npmjs.org/@next/env/-/env-13.3.4.tgz",
"integrity": "sha512-oTK/wRV2qga86m/4VdrR1+/56UA6U1Qv3sIgowB+bZjahniZLEG5BmmQjfoGv7ZuLXBZ8Eec6hkL9BqJcrEL2g=="
"version": "13.4.1",
"resolved": "https://registry.npmjs.org/@next/env/-/env-13.4.1.tgz",
"integrity": "sha512-eD6WCBMFjLFooLM19SIhSkWBHtaFrZFfg2Cxnyl3vS3DAdFRfnx5TY2RxlkuKXdIRCC0ySbtK9JXXt8qLCqzZg=="
},
"node_modules/@next/eslint-plugin-next": {
"version": "13.3.4",
"resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-13.3.4.tgz",
"integrity": "sha512-mvS+HafOPy31oJbAi920WJXMdjbyb4v5FAMr9PeGZfRIdEcsLkA3mU/ZvmwzovJgP3nAWw2e2yM8iIFW8VpvIA==",
"version": "13.4.1",
"resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-13.4.1.tgz",
"integrity": "sha512-tVPS/2FKlA3ANCRCYZVT5jdbUKasBU8LG6bYqcNhyORDFTlDYa4cAWQJjZ7msIgLwMQIbL8CAsxrOL8maa/4Lg==",
"dependencies": {
"glob": "7.1.7"
}
},
"node_modules/@next/swc-darwin-arm64": {
"version": "13.3.4",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.3.4.tgz",
"integrity": "sha512-vux7RWfzxy1lD21CMwZsy9Ej+0+LZdIIj1gEhVmzOQqQZ5N56h8JamrjIVCfDL+Lpj8KwOmFZbPHE8qaYnL2pg==",
"version": "13.4.1",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.1.tgz",
"integrity": "sha512-eF8ARHtYfnoYtDa6xFHriUKA/Mfj/cCbmKb3NofeKhMccs65G6/loZ15a6wYCCx4rPAd6x4t1WmVYtri7EdeBg==",
"cpu": [
"arm64"
],
@@ -137,9 +137,9 @@
}
},
"node_modules/@next/swc-darwin-x64": {
"version": "13.3.4",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.3.4.tgz",
"integrity": "sha512-1tb+6JT98+t7UIhVQpKL7zegKnCs9RKU6cKNyj+DYKuC/NVl49/JaIlmwCwK8Ibl+RXxJrK7uSXSIO71feXsgw==",
"version": "13.4.1",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.1.tgz",
"integrity": "sha512-7cmDgF9tGWTgn5Gw+vP17miJbH4wcraMHDCOHTYWkO/VeKT73dUWG23TNRLfgtCNSPgH4V5B4uLHoZTanx9bAw==",
"cpu": [
"x64"
],
@@ -152,9 +152,9 @@
}
},
"node_modules/@next/swc-linux-arm64-gnu": {
"version": "13.3.4",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.3.4.tgz",
"integrity": "sha512-UqcKkYTKslf5YAJNtZ5XV1D5MQJIkVtDHL8OehDZERHzqOe7jvy41HFto33IDPPU8gJiP5eJb3V9U26uifqHjw==",
"version": "13.4.1",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.1.tgz",
"integrity": "sha512-qwJqmCri2ie8aTtE5gjTSr8S6O8B67KCYgVZhv9gKH44yvc/zXbAY8u23QGULsYOyh1islWE5sWfQNLOj9iryg==",
"cpu": [
"arm64"
],
@@ -167,9 +167,9 @@
}
},
"node_modules/@next/swc-linux-arm64-musl": {
"version": "13.3.4",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.3.4.tgz",
"integrity": "sha512-HE/FmE8VvstAfehyo/XsrhGgz97cEr7uf9IfkgJ/unqSXE0CDshDn/4as6rRid74eDR8/exi7c2tdo49Tuqxrw==",
"version": "13.4.1",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.1.tgz",
"integrity": "sha512-qcC54tWNGDv/VVIFkazxhqH1Bnagjfs4enzELVRlUOoJPD2BGJTPI7z08pQPbbgxLtRiu8gl2mXvpB8WlOkMeA==",
"cpu": [
"arm64"
],
@@ -182,9 +182,9 @@
}
},
"node_modules/@next/swc-linux-x64-gnu": {
"version": "13.3.4",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.3.4.tgz",
"integrity": "sha512-xU+ugaupGA4SL5aK1ZYEqVHrW3TPOhxVcpaJLfpANm2443J4GfxCmOacu9XcSgy5c51Mq7C9uZ1LODKHfZosRQ==",
"version": "13.4.1",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.4.1.tgz",
"integrity": "sha512-9TeWFlpLsBosZ+tsm/rWBaMwt5It9tPH8m3nawZqFUUrZyGRfGcI67js774vtx0k3rL9qbyY6+3pw9BCVpaYUA==",
"cpu": [
"x64"
],
@@ -197,9 +197,9 @@
}
},
"node_modules/@next/swc-linux-x64-musl": {
"version": "13.3.4",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.3.4.tgz",
"integrity": "sha512-cZvmf5KcYeTfIK6bCypfmxGUjme53Ep7hx94JJtGrYgCA1VwEuYdh+KouubJaQCH3aqnNE7+zGnVEupEKfoaaA==",
"version": "13.4.1",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.4.1.tgz",
"integrity": "sha512-sNDGaWmSqTS4QRUzw61wl4mVPeSqNIr1OOjLlQTRuyInxMxtqImRqdvzDvFTlDfdeUMU/DZhWGYoHrXLlZXe6A==",
"cpu": [
"x64"
],
@@ -212,9 +212,9 @@
}
},
"node_modules/@next/swc-win32-arm64-msvc": {
"version": "13.3.4",
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.3.4.tgz",
"integrity": "sha512-7dL+CAUAjmgnVbjXPIpdj7/AQKFqEUL3bKtaOIE1JzJ5UMHHAXCPwzQtibrsvQpf9MwcAmiv8aburD3xH1xf8w==",
"version": "13.4.1",
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.1.tgz",
"integrity": "sha512-+CXZC7u1iXdLRudecoUYbhbsXpglYv8KFYsFxKBPn7kg+bk7eJo738wAA4jXIl8grTF2mPdmO93JOQym+BlYGA==",
"cpu": [
"arm64"
],
@@ -227,9 +227,9 @@
}
},
"node_modules/@next/swc-win32-ia32-msvc": {
"version": "13.3.4",
"resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.3.4.tgz",
"integrity": "sha512-qplTyzEl1vPkS+/DRK3pKSL0HeXrPHkYsV7U6gboHYpfqoHY+bcLUj3gwVUa9PEHRIoq4vXvPzx/WtzE6q52ng==",
"version": "13.4.1",
"resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.1.tgz",
"integrity": "sha512-vIoXVVc7UYO68VwVMDKwJC2+HqAZQtCYiVlApyKEeIPIQpz2gpufzGxk1z3/gwrJt/kJ5CDZjlhYDCzd3hdz+g==",
"cpu": [
"ia32"
],
@@ -242,9 +242,9 @@
}
},
"node_modules/@next/swc-win32-x64-msvc": {
"version": "13.3.4",
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.3.4.tgz",
"integrity": "sha512-usdvZT7JHrTuXC+4OKN5mCzUkviFkCyJJTkEz8jhBpucg+T7s83e7owm3oNFzmj5iKfvxU2St6VkcnSgpFvEYA==",
"version": "13.4.1",
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.1.tgz",
"integrity": "sha512-n8V5ImLQZibKTu10UUdI3nIeTLkliEXe628qxqW9v8My3BAH2a7H0SaCqkV2OgqFnn8sG1wxKYw9/SNJ632kSA==",
"cpu": [
"x64"
],
@@ -289,16 +289,16 @@
}
},
"node_modules/@pkgr/utils": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.3.1.tgz",
"integrity": "sha512-wfzX8kc1PMyUILA+1Z/EqoE4UCXGy0iRGMhPwdfae1+f0OXlLqCk+By+aMzgJBzR9AzS4CDizioG6Ss1gvAFJw==",
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.0.tgz",
"integrity": "sha512-2OCURAmRtdlL8iUDTypMrrxfwe8frXTeXaxGsVOaYtc/wrUyk8Z/0OBetM7cdlsy7ZFWlMX72VogKeh+A4Xcjw==",
"dependencies": {
"cross-spawn": "^7.0.3",
"fast-glob": "^3.2.12",
"is-glob": "^4.0.3",
"open": "^8.4.0",
"open": "^9.1.0",
"picocolors": "^1.0.0",
"tiny-glob": "^0.2.9",
"tslib": "^2.4.0"
"tslib": "^2.5.0"
},
"engines": {
"node": "^12.20.0 || ^14.18.0 || >=16.0.0"
@@ -326,13 +326,13 @@
"integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ=="
},
"node_modules/@typescript-eslint/parser": {
"version": "5.59.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.1.tgz",
"integrity": "sha512-nzjFAN8WEu6yPRDizIFyzAfgK7nybPodMNFGNH0M9tei2gYnYszRDqVA0xlnRjkl7Hkx2vYrEdb6fP2a21cG1g==",
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.59.2.tgz",
"integrity": "sha512-uq0sKyw6ao1iFOZZGk9F8Nro/8+gfB5ezl1cA06SrqbgJAt0SRoFhb9pXaHvkrxUpZaoLxt8KlovHNk8Gp6/HQ==",
"dependencies": {
"@typescript-eslint/scope-manager": "5.59.1",
"@typescript-eslint/types": "5.59.1",
"@typescript-eslint/typescript-estree": "5.59.1",
"@typescript-eslint/scope-manager": "5.59.2",
"@typescript-eslint/types": "5.59.2",
"@typescript-eslint/typescript-estree": "5.59.2",
"debug": "^4.3.4"
},
"engines": {
@@ -352,12 +352,12 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
"version": "5.59.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.1.tgz",
"integrity": "sha512-mau0waO5frJctPuAzcxiNWqJR5Z8V0190FTSqRw1Q4Euop6+zTwHAf8YIXNwDOT29tyUDrQ65jSg9aTU/H0omA==",
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.59.2.tgz",
"integrity": "sha512-dB1v7ROySwQWKqQ8rEWcdbTsFjh2G0vn8KUyvTXdPoyzSL6lLGkiXEV5CvpJsEe9xIdKV+8Zqb7wif2issoOFA==",
"dependencies": {
"@typescript-eslint/types": "5.59.1",
"@typescript-eslint/visitor-keys": "5.59.1"
"@typescript-eslint/types": "5.59.2",
"@typescript-eslint/visitor-keys": "5.59.2"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -368,9 +368,9 @@
}
},
"node_modules/@typescript-eslint/types": {
"version": "5.59.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.1.tgz",
"integrity": "sha512-dg0ICB+RZwHlysIy/Dh1SP+gnXNzwd/KS0JprD3Lmgmdq+dJAJnUPe1gNG34p0U19HvRlGX733d/KqscrGC1Pg==",
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.59.2.tgz",
"integrity": "sha512-LbJ/HqoVs2XTGq5shkiKaNTuVv5tTejdHgfdjqRUGdYhjW1crm/M7og2jhVskMt8/4wS3T1+PfFvL1K3wqYj4w==",
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
},
@@ -380,12 +380,12 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
"version": "5.59.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.1.tgz",
"integrity": "sha512-lYLBBOCsFltFy7XVqzX0Ju+Lh3WPIAWxYpmH/Q7ZoqzbscLiCW00LeYCdsUnnfnj29/s1WovXKh2gwCoinHNGA==",
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.59.2.tgz",
"integrity": "sha512-+j4SmbwVmZsQ9jEyBMgpuBD0rKwi9RxRpjX71Brr73RsYnEr3Lt5QZ624Bxphp8HUkSKfqGnPJp1kA5nl0Sh7Q==",
"dependencies": {
"@typescript-eslint/types": "5.59.1",
"@typescript-eslint/visitor-keys": "5.59.1",
"@typescript-eslint/types": "5.59.2",
"@typescript-eslint/visitor-keys": "5.59.2",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@@ -406,11 +406,11 @@
}
},
"node_modules/@typescript-eslint/visitor-keys": {
"version": "5.59.1",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.1.tgz",
"integrity": "sha512-6waEYwBTCWryx0VJmP7JaM4FpipLsFl9CvYf2foAE8Qh/Y0s+bxWysciwOs0LTBED4JCaNxTZ5rGadB14M6dwA==",
"version": "5.59.2",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.59.2.tgz",
"integrity": "sha512-EEpsO8m3RASrKAHI9jpavNv9NlEUebV4qmF1OWxSTtKSFBpC1NCmWazDQHFivRf0O1DV11BA645yrLEVQ0/Lig==",
"dependencies": {
"@typescript-eslint/types": "5.59.1",
"@typescript-eslint/types": "5.59.2",
"eslint-visitor-keys": "^3.3.0"
},
"engines": {
@@ -611,6 +611,25 @@
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
},
"node_modules/big-integer": {
"version": "1.6.51",
"resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.51.tgz",
"integrity": "sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg==",
"engines": {
"node": ">=0.6"
}
},
"node_modules/bplist-parser": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/bplist-parser/-/bplist-parser-0.2.0.tgz",
"integrity": "sha512-z0M+byMThzQmD9NILRniCUXYsYpjwnlO8N5uCFaCqIOpqRsJCrQL9NK3JsD67CN5a08nF5oIL2bD6loTdHOuKw==",
"dependencies": {
"big-integer": "^1.6.44"
},
"engines": {
"node": ">= 5.10.0"
}
},
"node_modules/brace-expansion": {
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
@@ -631,6 +650,20 @@
"node": ">=8"
}
},
"node_modules/bundle-name": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz",
"integrity": "sha512-PKA4BeSvBpQKQ8iPOGCSiell+N8P+Tf1DlwqmYhpe2gAhKPHn8EYOxVT+ShuGmhg8lN8XiSlS80yiExKXrURlw==",
"dependencies": {
"run-applescript": "^5.0.0"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/busboy": {
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz",
@@ -663,9 +696,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001481",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001481.tgz",
"integrity": "sha512-KCqHwRnaa1InZBtqXzP98LPg0ajCVujMKjqKDhZEthIpAsJl/YEIa3YvXjGXPVqzZVguccuu7ga9KOE1J9rKPQ==",
"version": "1.0.30001482",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001482.tgz",
"integrity": "sha512-F1ZInsg53cegyjroxLNW9DmrEQ1SuGRTO1QlpA0o2/6OpQ0gFeDRoq1yFmnr8Sakn9qwwt9DmbxHB6w167OSuQ==",
"funding": [
{
"type": "opencollective",
@@ -789,12 +822,47 @@
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
"integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="
},
"node_modules/define-lazy-prop": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
"integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==",
"node_modules/default-browser": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/default-browser/-/default-browser-4.0.0.tgz",
"integrity": "sha512-wX5pXO1+BrhMkSbROFsyxUm0i/cJEScyNhA4PPxc41ICuv05ZZB/MX28s8aZx6xjmatvebIapF6hLEKEcpneUA==",
"dependencies": {
"bundle-name": "^3.0.0",
"default-browser-id": "^3.0.0",
"execa": "^7.1.1",
"titleize": "^3.0.0"
},
"engines": {
"node": ">=8"
"node": ">=14.16"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/default-browser-id": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-3.0.0.tgz",
"integrity": "sha512-OZ1y3y0SqSICtE8DE4S8YOE9UZOJ8wO16fKWVP5J1Qz42kV9jcnMVFrEE/noXb/ss3Q4pZIH79kxofzyNNtUNA==",
"dependencies": {
"bplist-parser": "^0.2.0",
"untildify": "^4.0.0"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/define-lazy-prop": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz",
"integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/define-properties": {
@@ -1022,11 +1090,11 @@
}
},
"node_modules/eslint-config-next": {
"version": "13.3.4",
"resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-13.3.4.tgz",
"integrity": "sha512-TknEcP+EdTqLvJ2zMY1KnWqcx8ZHl1C2Tjjbq3qmtWcHRU5oxe1PAsz3vrKG3NOzonSaPcB2SpCSfYqcgj6nfA==",
"version": "13.4.1",
"resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-13.4.1.tgz",
"integrity": "sha512-ajuxjCkW1hvirr0EQZb3/B/bFH52Z7CT89uCtTcICFL9l30i5c8hN4p0LXvTjdOXNPV5fEDcxBgGHgXdzTj1/A==",
"dependencies": {
"@next/eslint-plugin-next": "13.3.4",
"@next/eslint-plugin-next": "13.4.1",
"@rushstack/eslint-patch": "^1.1.3",
"@typescript-eslint/parser": "^5.42.0",
"eslint-import-resolver-node": "^0.3.6",
@@ -1388,6 +1456,28 @@
"node": ">=0.10.0"
}
},
"node_modules/execa": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/execa/-/execa-7.1.1.tgz",
"integrity": "sha512-wH0eMf/UXckdUYnO21+HDztteVv05rq2GXksxT4fCGeHkBhw1DROXh40wcjMcRqDOWE7iPJ4n3M7e2+YFP+76Q==",
"dependencies": {
"cross-spawn": "^7.0.3",
"get-stream": "^6.0.1",
"human-signals": "^4.3.0",
"is-stream": "^3.0.0",
"merge-stream": "^2.0.0",
"npm-run-path": "^5.1.0",
"onetime": "^6.0.0",
"signal-exit": "^3.0.7",
"strip-final-newline": "^3.0.0"
},
"engines": {
"node": "^14.18.0 || ^16.14.0 || >=18.0.0"
},
"funding": {
"url": "https://github.com/sindresorhus/execa?sponsor=1"
}
},
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
@@ -1547,6 +1637,17 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/get-stream": {
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
"integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/get-symbol-description": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz",
@@ -1628,11 +1729,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/globalyzer": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/globalyzer/-/globalyzer-0.1.0.tgz",
"integrity": "sha512-40oNTM9UfG6aBmuKxk/giHn5nQ8RVz/SS4Ir6zgzOv9/qC3kKZ9v4etGTcJbEl/NyVQH7FGU7d+X1egr57Md2Q=="
},
"node_modules/globby": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
@@ -1652,11 +1748,6 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/globrex": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/globrex/-/globrex-0.1.2.tgz",
"integrity": "sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg=="
},
"node_modules/gopd": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
@@ -1752,6 +1843,14 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/human-signals": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-4.3.1.tgz",
"integrity": "sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==",
"engines": {
"node": ">=14.18.0"
}
},
"node_modules/ignore": {
"version": "5.2.4",
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
@@ -1901,14 +2000,14 @@
}
},
"node_modules/is-docker": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
"integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz",
"integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==",
"bin": {
"is-docker": "cli.js"
},
"engines": {
"node": ">=8"
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
@@ -1933,6 +2032,23 @@
"node": ">=0.10.0"
}
},
"node_modules/is-inside-container": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz",
"integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==",
"dependencies": {
"is-docker": "^3.0.0"
},
"bin": {
"is-inside-container": "cli.js"
},
"engines": {
"node": ">=14.16"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/is-map": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/is-map/-/is-map-2.0.2.tgz",
@@ -2016,6 +2132,17 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/is-stream": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz",
"integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==",
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/is-string": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz",
@@ -2104,6 +2231,20 @@
"node": ">=8"
}
},
"node_modules/is-wsl/node_modules/is-docker": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz",
"integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==",
"bin": {
"is-docker": "cli.js"
},
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/isarray": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
@@ -2238,6 +2379,11 @@
"node": ">=10"
}
},
"node_modules/merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="
},
"node_modules/merge2": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
@@ -2258,6 +2404,17 @@
"node": ">=8.6"
}
},
"node_modules/mimic-fn": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz",
"integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/minimatch": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
@@ -2305,16 +2462,17 @@
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="
},
"node_modules/next": {
"version": "13.3.4",
"resolved": "https://registry.npmjs.org/next/-/next-13.3.4.tgz",
"integrity": "sha512-sod7HeokBSvH5QV0KB+pXeLfcXUlLrGnVUXxHpmhilQ+nQYT3Im2O8DswD5e4uqbR8Pvdu9pcWgb1CbXZQZlmQ==",
"version": "13.4.1",
"resolved": "https://registry.npmjs.org/next/-/next-13.4.1.tgz",
"integrity": "sha512-JBw2kAIyhKDpjhEWvNVoFeIzNp9xNxg8wrthDOtMctfn3EpqGCmW0FSviNyGgOSOSn6zDaX48pmvbdf6X2W9xA==",
"dependencies": {
"@next/env": "13.3.4",
"@next/env": "13.4.1",
"@swc/helpers": "0.5.1",
"busboy": "1.6.0",
"caniuse-lite": "^1.0.30001406",
"postcss": "8.4.14",
"styled-jsx": "5.1.1"
"styled-jsx": "5.1.1",
"zod": "3.21.4"
},
"bin": {
"next": "dist/bin/next"
@@ -2323,15 +2481,15 @@
"node": ">=16.8.0"
},
"optionalDependencies": {
"@next/swc-darwin-arm64": "13.3.4",
"@next/swc-darwin-x64": "13.3.4",
"@next/swc-linux-arm64-gnu": "13.3.4",
"@next/swc-linux-arm64-musl": "13.3.4",
"@next/swc-linux-x64-gnu": "13.3.4",
"@next/swc-linux-x64-musl": "13.3.4",
"@next/swc-win32-arm64-msvc": "13.3.4",
"@next/swc-win32-ia32-msvc": "13.3.4",
"@next/swc-win32-x64-msvc": "13.3.4"
"@next/swc-darwin-arm64": "13.4.1",
"@next/swc-darwin-x64": "13.4.1",
"@next/swc-linux-arm64-gnu": "13.4.1",
"@next/swc-linux-arm64-musl": "13.4.1",
"@next/swc-linux-x64-gnu": "13.4.1",
"@next/swc-linux-x64-musl": "13.4.1",
"@next/swc-win32-arm64-msvc": "13.4.1",
"@next/swc-win32-ia32-msvc": "13.4.1",
"@next/swc-win32-x64-msvc": "13.4.1"
},
"peerDependencies": {
"@opentelemetry/api": "^1.1.0",
@@ -2356,6 +2514,31 @@
}
}
},
"node_modules/npm-run-path": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.1.0.tgz",
"integrity": "sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==",
"dependencies": {
"path-key": "^4.0.0"
},
"engines": {
"node": "^12.20.0 || ^14.13.1 || >=16.0.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/npm-run-path/node_modules/path-key": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
"integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
@@ -2477,14 +2660,12 @@
"wrappy": "1"
}
},
"node_modules/open": {
"version": "8.4.2",
"resolved": "https://registry.npmjs.org/open/-/open-8.4.2.tgz",
"integrity": "sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==",
"node_modules/onetime": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz",
"integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==",
"dependencies": {
"define-lazy-prop": "^2.0.0",
"is-docker": "^2.1.1",
"is-wsl": "^2.2.0"
"mimic-fn": "^4.0.0"
},
"engines": {
"node": ">=12"
@@ -2493,6 +2674,23 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/open": {
"version": "9.1.0",
"resolved": "https://registry.npmjs.org/open/-/open-9.1.0.tgz",
"integrity": "sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==",
"dependencies": {
"default-browser": "^4.0.0",
"define-lazy-prop": "^3.0.0",
"is-inside-container": "^1.0.0",
"is-wsl": "^2.2.0"
},
"engines": {
"node": ">=14.16"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/optionator": {
"version": "0.9.1",
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz",
@@ -2765,6 +2963,102 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/run-applescript": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-5.0.0.tgz",
"integrity": "sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==",
"dependencies": {
"execa": "^5.0.0"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/run-applescript/node_modules/execa": {
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
"integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
"dependencies": {
"cross-spawn": "^7.0.3",
"get-stream": "^6.0.0",
"human-signals": "^2.1.0",
"is-stream": "^2.0.0",
"merge-stream": "^2.0.0",
"npm-run-path": "^4.0.1",
"onetime": "^5.1.2",
"signal-exit": "^3.0.3",
"strip-final-newline": "^2.0.0"
},
"engines": {
"node": ">=10"
},
"funding": {
"url": "https://github.com/sindresorhus/execa?sponsor=1"
}
},
"node_modules/run-applescript/node_modules/human-signals": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
"integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
"engines": {
"node": ">=10.17.0"
}
},
"node_modules/run-applescript/node_modules/is-stream": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
"engines": {
"node": ">=8"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/run-applescript/node_modules/mimic-fn": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
"engines": {
"node": ">=6"
}
},
"node_modules/run-applescript/node_modules/npm-run-path": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
"integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
"dependencies": {
"path-key": "^3.0.0"
},
"engines": {
"node": ">=8"
}
},
"node_modules/run-applescript/node_modules/onetime": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
"dependencies": {
"mimic-fn": "^2.1.0"
},
"engines": {
"node": ">=6"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/run-applescript/node_modules/strip-final-newline": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
"integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
"engines": {
"node": ">=6"
}
},
"node_modules/run-parallel": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
@@ -2854,6 +3148,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/signal-exit": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
},
"node_modules/slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
@@ -2968,6 +3267,17 @@
"node": ">=4"
}
},
"node_modules/strip-final-newline": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz",
"integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/strip-json-comments": {
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
@@ -3051,13 +3361,15 @@
"resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw=="
},
"node_modules/tiny-glob": {
"version": "0.2.9",
"resolved": "https://registry.npmjs.org/tiny-glob/-/tiny-glob-0.2.9.tgz",
"integrity": "sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==",
"dependencies": {
"globalyzer": "0.1.0",
"globrex": "^0.1.2"
"node_modules/titleize": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/titleize/-/titleize-3.0.0.tgz",
"integrity": "sha512-KxVu8EYHDPBdUYdKZdKtU2aj2XfEx9AfjXxE/Aj0vT06w2icA09Vus1rh6eSu1y01akYg6BjIK/hxyLJINoMLQ==",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/to-regex-range": {
@@ -3168,6 +3480,14 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/untildify": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/untildify/-/untildify-4.0.0.tgz",
"integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==",
"engines": {
"node": ">=8"
}
},
"node_modules/uri-js": {
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
@@ -3266,6 +3586,14 @@
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/zod": {
"version": "3.21.4",
"resolved": "https://registry.npmjs.org/zod/-/zod-3.21.4.tgz",
"integrity": "sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==",
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
}
}
}

View File

@@ -10,8 +10,8 @@
},
"dependencies": {
"eslint": "8.39.0",
"eslint-config-next": "13.3.4",
"next": "13.3.4",
"eslint-config-next": "13.4.1",
"next": "13.4.1",
"react": "18.2.0",
"react-dom": "18.2.0"
}

View File

@@ -1,5 +0,0 @@
import '@/styles/globals.css'
export default function App({ Component, pageProps }) {
return <Component {...pageProps} />
}

View File

@@ -1,13 +0,0 @@
import { Html, Head, Main, NextScript } from 'next/document'
export default function Document() {
return (
<Html lang="en">
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}

View File

@@ -1,5 +0,0 @@
// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
export default function handler(req, res) {
res.status(200).json({ name: 'John Doe' })
}

View File

@@ -1,114 +0,0 @@
import Head from 'next/head'
import Image from 'next/image'
import { Inter } from 'next/font/google'
import styles from '@/styles/Home.module.css'
const inter = Inter({ subsets: ['latin'] })
export default function Home() {
return (
<>
<Head>
<title>Create Next App</title>
<meta name="description" content="Generated by create next app" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="/favicon.ico" />
</Head>
<main className={`${styles.main} ${inter.className}`}>
<div className={styles.description}>
<p>
Get started by editing&nbsp;
<code className={styles.code}>pages/index.js</code>
</p>
<div>
<a
href="https://vercel.com?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
By{' '}
<Image
src="/vercel.svg"
alt="Vercel Logo"
className={styles.vercelLogo}
width={100}
height={24}
priority
/>
</a>
</div>
</div>
<div className={styles.center}>
<Image
className={styles.logo}
src="/next.svg"
alt="Next.js Logo"
width={180}
height={37}
priority
/>
</div>
<div className={styles.grid}>
<a
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
className={styles.card}
target="_blank"
rel="noopener noreferrer"
>
<h2>
Docs <span>-&gt;</span>
</h2>
<p>
Find in-depth information about Next.js features and&nbsp;API.
</p>
</a>
<a
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
className={styles.card}
target="_blank"
rel="noopener noreferrer"
>
<h2>
Learn <span>-&gt;</span>
</h2>
<p>
Learn about Next.js in an interactive course with&nbsp;quizzes!
</p>
</a>
<a
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
className={styles.card}
target="_blank"
rel="noopener noreferrer"
>
<h2>
Templates <span>-&gt;</span>
</h2>
<p>
Discover and deploy boilerplate example Next.js&nbsp;projects.
</p>
</a>
<a
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=default-template&utm_campaign=create-next-app"
className={styles.card}
target="_blank"
rel="noopener noreferrer"
>
<h2>
Deploy <span>-&gt;</span>
</h2>
<p>
Instantly deploy your Next.js site to a shareable URL
with&nbsp;Vercel.
</p>
</a>
</div>
</main>
</>
)
}

View File

@@ -1,6 +1,6 @@
{
"name": "vercel",
"version": "29.1.1",
"version": "29.2.0",
"preferGlobal": true,
"license": "Apache-2.0",
"description": "The command-line interface for Vercel",
@@ -36,15 +36,16 @@
"@vercel/go": "2.5.1",
"@vercel/hydrogen": "0.0.64",
"@vercel/next": "3.8.2",
"@vercel/node": "2.14.1",
"@vercel/node": "2.14.2",
"@vercel/python": "3.1.60",
"@vercel/redwood": "1.1.15",
"@vercel/remix-builder": "1.8.7",
"@vercel/ruby": "1.3.76",
"@vercel/static-build": "1.3.29"
"@vercel/static-build": "1.3.30"
},
"devDependencies": {
"@alex_neo/jest-expect-message": "1.0.5",
"@edge-runtime/node-utils": "2.0.3",
"@next/env": "11.1.2",
"@sentry/node": "5.5.0",
"@sindresorhus/slugify": "0.11.0",
@@ -81,16 +82,16 @@
"@types/title": "3.4.1",
"@types/universal-analytics": "0.4.2",
"@types/update-notifier": "5.1.0",
"@types/which": "1.3.2",
"@types/which": "3.0.0",
"@types/write-json-file": "2.2.1",
"@types/yauzl-promise": "2.1.0",
"@vercel-internals/constants": "*",
"@vercel-internals/get-package-json": "*",
"@vercel-internals/types": "*",
"@vercel/client": "12.4.12",
"@vercel/client": "12.5.0",
"@vercel/error-utils": "1.0.10",
"@vercel/frameworks": "1.4.1",
"@vercel/fs-detectors": "3.9.1",
"@vercel/frameworks": "1.4.2",
"@vercel/fs-detectors": "3.9.2",
"@vercel/fun": "1.0.4",
"@vercel/ncc": "0.24.0",
"@vercel/routing-utils": "2.2.1",
@@ -100,7 +101,7 @@
"ansi-escapes": "4.3.2",
"ansi-regex": "5.0.1",
"arg": "5.0.0",
"async-listen": "1.2.0",
"async-listen": "3.0.0",
"async-retry": "1.1.3",
"async-sema": "2.1.4",
"bytes": "3.0.0",
@@ -147,6 +148,8 @@
"pcre-to-regexp": "1.0.0",
"pluralize": "7.0.0",
"promisepipe": "3.0.0",
"proxy": "2.0.0",
"proxy-agent": "6.1.1",
"psl": "1.1.31",
"qr-image": "3.2.0",
"raw-body": "2.4.1",
@@ -165,6 +168,7 @@
"ts-node": "10.9.1",
"universal-analytics": "0.4.20",
"utility-types": "2.1.0",
"which": "3.0.0",
"write-json-file": "2.2.0",
"xdg-app-paths": "5.1.0",
"yauzl-promise": "2.1.3"

82
packages/cli/src/args.ts Normal file
View File

@@ -0,0 +1,82 @@
import chalk from 'chalk';
import logo from './util/output/logo';
import { getPkgName } from './util/pkg-name';
export const help = () => `
${chalk.bold(`${logo} ${getPkgName()}`)} [options] <command | path>
${chalk.dim('For deploy command help, run `vercel deploy --help`')}
${chalk.dim('Commands:')}
${chalk.dim('Basic')}
deploy [path] Performs a deployment ${chalk.bold(
'(default)'
)}
dev Start a local development server
env Manages the Environment Variables for your current Project
git Manage Git provider repository for your current Project
help [cmd] Displays complete help for [cmd]
init [example] Initialize an example project
inspect [id] Displays information related to a deployment
link [path] Link local directory to a Vercel Project
ls | list [app] Lists deployments
login [email] Logs into your account or creates a new one
logout Logs out of your account
pull [path] Pull your Project Settings from the cloud
rollback [url|id] Quickly revert back to a previous deployment [beta]
switch [scope] Switches between teams and your personal account
${chalk.dim('Advanced')}
alias [cmd] Manages your domain aliases
bisect Use binary search to find the deployment that introduced a bug
certs [cmd] Manages your SSL certificates
dns [name] Manages your DNS records
domains [name] Manages your domain names
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
${chalk.dim('Global Options:')}
-h, --help Output usage information
-v, --version Output the version number
--cwd Current working directory
-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]
-S, --scope Set a custom scope
-t ${chalk.underline('TOKEN')}, --token=${chalk.underline(
'TOKEN'
)} Login token
${chalk.dim('Examples:')}
${chalk.gray('')} Deploy the current directory
${chalk.cyan(`$ ${getPkgName()}`)}
${chalk.gray('')} Deploy a custom path
${chalk.cyan(`$ ${getPkgName()} /usr/src/project`)}
${chalk.gray('')} Deploy with Environment Variables
${chalk.cyan(`$ ${getPkgName()} -e NODE_ENV=production`)}
${chalk.gray('')} Show the usage information for the sub command ${chalk.dim(
'`list`'
)}
${chalk.cyan(`$ ${getPkgName()} help list`)}
`;

View File

@@ -2,80 +2,27 @@ import chalk from 'chalk';
import logo from '../../util/output/logo';
import { getPkgName } from '../../util/pkg-name';
export const help = () => `
${chalk.bold(`${logo} ${getPkgName()}`)} [options] <command | path>
export const help = () => {
return `
${chalk.bold(`${logo} ${getPkgName()} [deploy]`)} [path-to-project] [options]
${chalk.dim('Commands:')}
${chalk.dim('Basic')}
deploy [path] Performs a deployment ${chalk.bold(
'(default)'
)}
dev Start a local development server
env Manages the Environment Variables for your current Project
git Manage Git provider repository for your current Project
help [cmd] Displays complete help for [cmd]
init [example] Initialize an example project
inspect [id] Displays information related to a deployment
link [path] Link local directory to a Vercel Project
ls | list [app] Lists deployments
login [email] Logs into your account or creates a new one
logout Logs out of your account
pull [path] Pull your Project Settings from the cloud
rollback [url|id] Quickly revert back to a previous deployment [beta]
switch [scope] Switches between teams and your personal account
${chalk.dim('Advanced')}
alias [cmd] Manages your domain aliases
bisect Use binary search to find the deployment that introduced a bug
certs [cmd] Manages your SSL certificates
dns [name] Manages your DNS records
domains [name] Manages your domain names
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
${chalk.dim('Options:')}
-h, --help Output usage information
-v, --version Output the version number
--cwd Current working directory
-V, --platform-version Set the platform version to deploy to
-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]
-f, --force Force a new deployment even if nothing has changed
--with-cache Retain build cache when using "--force"
-t ${chalk.underline('TOKEN')}, --token=${chalk.underline(
'TOKEN'
)} Login token
-p, --public Deployment is public (${chalk.dim(
'`/_src`'
)} is exposed)
-e, --env Include an env var during run time (e.g.: ${chalk.dim(
'`-e KEY=value`'
)}). Can appear many times.
-b, --build-env Similar to ${chalk.dim(
'`--env`'
)} but for build time only.
-m, --meta Add metadata for the deployment (e.g.: ${chalk.dim(
'`-m KEY=value`'
)}). Can appear many times.
--no-wait Don't wait for the deployment to finish
-S, --scope Set a custom scope
--regions Set default regions to enable the deployment on
--prod Create a production deployment
-y, --yes Skip questions when setting up new project using default scope and settings
--prod Create a production deployment
-p, --public Deployment is public (${chalk.dim(
'`/_src`'
)} is exposed)
-e, --env Include an env var during run time (e.g.: ${chalk.dim(
'`-e KEY=value`'
)}). Can appear many times.
-b, --build-env Similar to ${chalk.dim(
'`--env`'
)} but for build time only.
-m, --meta Add metadata for the deployment (e.g.: ${chalk.dim(
'`-m KEY=value`'
)}). Can appear many times.
--no-wait Don't wait for the deployment to finish
-f, --force Force a new deployment even if nothing has changed
--with-cache Retain build cache when using "--force"
--regions Set default regions to enable the deployment on
${chalk.dim('Examples:')}
@@ -89,14 +36,15 @@ export const help = () => `
${chalk.gray('')} Deploy with Environment Variables
${chalk.cyan(
`$ ${getPkgName()} -e NODE_ENV=production -e SECRET=@mysql-secret`
)}
${chalk.cyan(`$ ${getPkgName()} -e NODE_ENV=production`)}
${chalk.gray('')} Show the usage information for the sub command ${chalk.dim(
'`list`'
)}
${chalk.gray('')} Deploy with prebuilt outputs
${chalk.cyan(`$ ${getPkgName()} help list`)}
${chalk.cyan(`$ ${getPkgName()} build`)}
${chalk.cyan(`$ ${getPkgName()} deploy --prebuilt`)}
${chalk.gray('')} Write Deployment URL to a file
${chalk.cyan(`$ ${getPkgName()} > deployment-url.txt`)}
`;
};

View File

@@ -52,7 +52,7 @@ export default async function main(client: Client) {
try {
argv = getArgs(client.argv.slice(2), {
'--force': Boolean,
'-f': Boolean,
'-f': '--force',
});
args = getSubcommand(argv._.slice(1), COMMAND_CONFIG).args;
} catch (err) {

View File

@@ -35,7 +35,7 @@ export default async function init(
) {
const { output } = client;
const [name, dir] = args;
const force = opts['-f'] || opts['--force'];
const force = opts['--force'];
const examples = await fetchExampleList(client);

View File

@@ -52,7 +52,10 @@ import { getCommandName, getTitleName } from './util/pkg-name';
import doLoginPrompt from './util/login/prompt';
import type { AuthConfig, GlobalConfig } from '@vercel-internals/types';
import { VercelConfig } from '@vercel/client';
import { ProxyAgent } from 'proxy-agent';
import box from './util/output/box';
import { execExtension } from './util/extension/exec';
import { help } from './args';
const VERCEL_DIR = getGlobalPathConfig();
const VERCEL_CONFIG_PATH = configFiles.getConfigFilePath();
@@ -141,18 +144,19 @@ const main = async () => {
return 1;
}
const cwd = argv['--cwd'];
let cwd = argv['--cwd'];
if (cwd) {
process.chdir(cwd);
}
cwd = process.cwd();
// The second argument to the command can be:
//
// * a path to deploy (as in: `vercel path/`)
// * a subcommand (as in: `vercel ls`)
const targetOrSubcommand = argv._[2];
const subSubCommand = argv._[3];
// Currently no beta commands - add here as needed
const betaCommands: string[] = ['rollback'];
if (betaCommands.includes(targetOrSubcommand)) {
console.log(
@@ -172,6 +176,14 @@ const main = async () => {
return 0;
}
// Handle bare `-h` directly
const bareHelpOption = !targetOrSubcommand && argv['--help'];
const bareHelpSubcommand = targetOrSubcommand === 'help' && !subSubCommand;
if (bareHelpOption || bareHelpSubcommand) {
output.print(help());
return 2;
}
// Ensure that the Vercel global configuration directory exists
try {
await mkdirp(VERCEL_DIR);
@@ -251,6 +263,7 @@ const main = async () => {
// Shared API `Client` instance for all sub-commands to utilize
client = new Client({
agent: new ProxyAgent({ keepAlive: true }),
apiUrl,
stdin: process.stdin,
stdout: process.stdout,
@@ -263,11 +276,13 @@ const main = async () => {
argv: process.argv,
});
let subcommand;
// Gets populated to the subcommand name when a built-in is
// provided, otherwise it remains undefined for an extension
let subcommand: string | undefined = undefined;
// Check if we are deploying something
if (targetOrSubcommand) {
const targetPath = join(process.cwd(), targetOrSubcommand);
const targetPath = join(cwd, targetOrSubcommand);
const targetPathExists = existsSync(targetPath);
const subcommandExists =
GLOBAL_COMMANDS.has(targetOrSubcommand) ||
@@ -289,8 +304,7 @@ const main = async () => {
debug(`user supplied known subcommand: "${targetOrSubcommand}"`);
subcommand = targetOrSubcommand;
} else {
debug('user supplied a possible target for deployment');
subcommand = 'deploy';
debug('user supplied a possible target for deployment or an extension');
}
} else {
debug('user supplied no target, defaulting to deploy');
@@ -298,7 +312,7 @@ const main = async () => {
}
if (subcommand === 'help') {
subcommand = argv._[3] || 'deploy';
subcommand = subSubCommand || 'deploy';
client.argv.push('-h');
}
@@ -310,6 +324,7 @@ const main = async () => {
!client.argv.includes('-h') &&
!client.argv.includes('--help') &&
!argv['--token'] &&
subcommand &&
!subcommandsWithoutToken.includes(subcommand)
) {
if (isTTY) {
@@ -401,7 +416,8 @@ const main = async () => {
);
}
const targetCommand = commands.get(subcommand);
let targetCommand =
typeof subcommand === 'string' ? commands.get(subcommand) : undefined;
const scope = argv['--scope'] || argv['--team'] || localConfig?.scope;
if (
@@ -409,7 +425,7 @@ const main = async () => {
targetCommand !== 'login' &&
targetCommand !== 'dev' &&
targetCommand !== 'build' &&
!(targetCommand === 'teams' && argv._[3] !== 'invite')
!(targetCommand === 'teams' && subSubCommand !== 'invite')
) {
let user = null;
@@ -472,96 +488,123 @@ const main = async () => {
try {
const start = Date.now();
let func: any;
switch (targetCommand) {
case 'alias':
func = require('./commands/alias').default;
break;
case 'bisect':
func = require('./commands/bisect').default;
break;
case 'build':
func = require('./commands/build').default;
break;
case 'certs':
func = require('./commands/certs').default;
break;
case 'deploy':
func = require('./commands/deploy').default;
break;
case 'dev':
func = require('./commands/dev').default;
break;
case 'dns':
func = require('./commands/dns').default;
break;
case 'domains':
func = require('./commands/domains').default;
break;
case 'env':
func = require('./commands/env').default;
break;
case 'git':
func = require('./commands/git').default;
break;
case 'init':
func = require('./commands/init').default;
break;
case 'inspect':
func = require('./commands/inspect').default;
break;
case 'link':
func = require('./commands/link').default;
break;
case 'list':
func = require('./commands/list').default;
break;
case 'logs':
func = require('./commands/logs').default;
break;
case 'login':
func = require('./commands/login').default;
break;
case 'logout':
func = require('./commands/logout').default;
break;
case 'project':
func = require('./commands/project').default;
break;
case 'pull':
func = require('./commands/pull').default;
break;
case 'remove':
func = require('./commands/remove').default;
break;
case 'rollback':
func = require('./commands/rollback').default;
break;
case 'secrets':
func = require('./commands/secrets').default;
break;
case 'teams':
func = require('./commands/teams').default;
break;
case 'whoami':
func = require('./commands/whoami').default;
break;
default:
func = null;
break;
if (!targetCommand) {
// Set this for the metrics to record it at the end
targetCommand = argv._[2];
// Try to execute as an extension
try {
exitCode = await execExtension(
client,
targetCommand,
argv._.slice(3),
cwd
);
} catch (err: unknown) {
if (isErrnoException(err) && err.code === 'ENOENT') {
// Fall back to `vc deploy <dir>`
targetCommand = subcommand = 'deploy';
} else {
throw err;
}
}
}
if (!func || !targetCommand) {
const sub = param(subcommand);
output.error(`The ${sub} subcommand does not exist`);
return 1;
}
// Not using an `else` here because if the CLI extension
// was not found then we have to fall back to `vc deploy`
if (subcommand) {
let func: any;
switch (targetCommand) {
case 'alias':
func = require('./commands/alias').default;
break;
case 'bisect':
func = require('./commands/bisect').default;
break;
case 'build':
func = require('./commands/build').default;
break;
case 'certs':
func = require('./commands/certs').default;
break;
case 'deploy':
func = require('./commands/deploy').default;
break;
case 'dev':
func = require('./commands/dev').default;
break;
case 'dns':
func = require('./commands/dns').default;
break;
case 'domains':
func = require('./commands/domains').default;
break;
case 'env':
func = require('./commands/env').default;
break;
case 'git':
func = require('./commands/git').default;
break;
case 'init':
func = require('./commands/init').default;
break;
case 'inspect':
func = require('./commands/inspect').default;
break;
case 'link':
func = require('./commands/link').default;
break;
case 'list':
func = require('./commands/list').default;
break;
case 'logs':
func = require('./commands/logs').default;
break;
case 'login':
func = require('./commands/login').default;
break;
case 'logout':
func = require('./commands/logout').default;
break;
case 'project':
func = require('./commands/project').default;
break;
case 'pull':
func = require('./commands/pull').default;
break;
case 'remove':
func = require('./commands/remove').default;
break;
case 'rollback':
func = require('./commands/rollback').default;
break;
case 'secrets':
func = require('./commands/secrets').default;
break;
case 'teams':
func = require('./commands/teams').default;
break;
case 'whoami':
func = require('./commands/whoami').default;
break;
default:
func = null;
break;
}
if (func.default) {
func = func.default;
}
if (!func || !targetCommand) {
const sub = param(subcommand);
output.error(`The ${sub} subcommand does not exist`);
return 1;
}
exitCode = await func(client);
if (func.default) {
func = func.default;
}
exitCode = await func(client);
}
const end = Date.now() - start;
if (shouldCollectMetrics) {

View File

@@ -2,9 +2,6 @@ const ARG_COMMON = {
'--help': Boolean,
'-h': '--help',
'--platform-version': Number,
'-V': '--platform-version',
'--debug': Boolean,
'-d': '--debug',
@@ -28,6 +25,10 @@ const ARG_COMMON = {
'--api': String,
'--cwd': String,
// Deprecated
'--platform-version': Number,
'-V': '--platform-version',
};
export default () => ARG_COMMON;

View File

@@ -23,6 +23,7 @@ import type {
import { sharedPromise } from './promise';
import { APIError } from './errors-ts';
import { normalizeError } from '@vercel/error-utils';
import type { Agent } from 'http';
const isSAMLError = (v: any): v is SAMLError => {
return v && v.saml;
@@ -44,6 +45,7 @@ export interface ClientOptions extends Stdio {
config: GlobalConfig;
localConfig?: VercelConfig;
localConfigPath?: string;
agent?: Agent;
}
export const isJSONObject = (v: any): v is JSONObject => {
@@ -59,13 +61,15 @@ export default class Client extends EventEmitter implements Stdio {
stderr: WritableTTY;
output: Output;
config: GlobalConfig;
agent?: Agent;
localConfig?: VercelConfig;
localConfigPath?: string;
prompt!: inquirer.PromptModule;
private requestIdCounter: number;
requestIdCounter: number;
constructor(opts: ClientOptions) {
super();
this.agent = opts.agent;
this.argv = opts.argv;
this.apiUrl = opts.apiUrl;
this.authConfig = opts.authConfig;
@@ -126,10 +130,10 @@ export default class Client extends EventEmitter implements Stdio {
} else {
return `#${requestId}${opts.method || 'GET'} ${url.href}`;
}
}, fetch(url, { ...opts, headers, body }));
}, fetch(url, { agent: this.agent, ...opts, headers, body }));
}
fetch(url: string, opts: { json: false }): Promise<Response>;
fetch(url: string, opts: FetchOptions & { json: false }): Promise<Response>;
fetch<T>(url: string, opts?: FetchOptions): Promise<T>;
fetch(url: string, opts: FetchOptions = {}) {
return this.retry(async bail => {

View File

@@ -13,6 +13,7 @@ import type { Org } from '@vercel-internals/types';
import ua from '../ua';
import { linkFolderToProject } from '../projects/link';
import { prependEmoji, emoji } from '../emoji';
import type { Agent } from 'http';
function printInspectUrl(
output: Output,
@@ -35,6 +36,7 @@ export default async function processDeployment({
archive,
skipAutoDetectionConfirmation,
noWait,
agent,
...args
}: {
now: Now;
@@ -55,6 +57,7 @@ export default async function processDeployment({
cwd?: string;
rootDirectory?: string | null;
noWait?: boolean;
agent?: Agent;
}) {
let {
now,
@@ -91,6 +94,7 @@ export default async function processDeployment({
rootDirectory,
skipAutoDetectionConfirmation,
archive,
agent,
};
const deployingSpinnerVal = isSettingUpProject

View File

@@ -5,7 +5,7 @@ import chalk from 'chalk';
import fetch from 'node-fetch';
import plural from 'pluralize';
import rawBody from 'raw-body';
import listen from 'async-listen';
import { listen } from 'async-listen';
import minimatch from 'minimatch';
import httpProxy from 'http-proxy';
import { randomBytes } from 'crypto';
@@ -860,7 +860,7 @@ export default class DevServer {
let address: string | null = null;
while (typeof address !== 'string') {
try {
address = await listen(this.server, ...listenSpec);
address = (await listen(this.server, ...listenSpec)).toString();
} catch (err: unknown) {
if (isErrnoException(err)) {
this.output.debug(`Got listen error: ${err.code}`);

View File

@@ -0,0 +1,90 @@
import which from 'which';
import execa from 'execa';
import { dirname } from 'path';
import { listen } from 'async-listen';
import { scanParentDirs, walkParentDirs } from '@vercel/build-utils';
import { createProxy } from './proxy';
import type Client from '../client';
/**
* Attempts to execute a Vercel CLI Extension.
*
* If the extension was found and executed, then the
* exit code is returned.
*
* If the program could not be found, then an `ENOENT`
* error is thrown.
*/
export async function execExtension(
client: Client,
name: string,
args: string[],
cwd: string
): Promise<number> {
const { debug } = client.output;
const extensionCommand = `vercel-${name}`;
const { packageJsonPath, lockfilePath } = await scanParentDirs(cwd);
const baseFile = lockfilePath || packageJsonPath;
let extensionPath: string | null = null;
if (baseFile) {
// Scan `node_modules/.bin` works for npm / pnpm / yarn v1
// TOOD: add support for Yarn PnP
extensionPath = await walkParentDirs({
base: dirname(baseFile),
start: cwd,
filename: `node_modules/.bin/${extensionCommand}`,
});
}
if (!extensionPath) {
// Attempt global `$PATH` lookup
extensionPath = which.sync(extensionCommand, { nothrow: true });
}
if (!extensionPath) {
debug(`failed to find extension command with name "${extensionCommand}"`);
throw new ENOENT(extensionCommand);
}
debug(`invoking extension: ${extensionPath}`);
const proxy = createProxy(client);
proxy.once('close', () => {
debug(`extension proxy server shut down`);
});
const proxyUrl = await listen(proxy, { port: 0, host: '127.0.0.1' });
const VERCEL_API = proxyUrl.href.replace(/\/$/, '');
debug(`extension proxy server listening at ${VERCEL_API}`);
const result = await execa(extensionPath, args, {
cwd,
reject: false,
stdio: 'inherit',
env: {
...process.env,
VERCEL_API,
// TODO:
// VERCEL_SCOPE
// VERCEL_DEBUG
// VERCEL_HELP
},
});
proxy.close();
if (result instanceof Error) {
debug(`error running extension: ${result.message}`);
}
return result.exitCode;
}
class ENOENT extends Error {
code = 'ENOENT';
constructor(command: string) {
super(`Command "${command}" not found`);
}
}

View File

@@ -0,0 +1,44 @@
import { createServer } from 'http';
import { Headers } from 'node-fetch';
import {
toOutgoingHeaders,
mergeIntoServerResponse,
buildToHeaders,
} from '@edge-runtime/node-utils';
import type { Server } from 'http';
import type Client from '../client';
const toHeaders = buildToHeaders({
// @ts-expect-error - `node-fetch` Headers is missing `getAll()`
Headers,
});
export function createProxy(client: Client): Server {
return createServer(async (req, res) => {
try {
// Proxy to the upstream Vercel REST API
const headers = toHeaders(req.headers);
headers.delete('host');
const fetchRes = await client.fetch(req.url || '/', {
headers,
method: req.method,
body: req.method === 'GET' || req.method === 'HEAD' ? undefined : req,
useCurrentTeam: false,
json: false,
});
res.statusCode = fetchRes.status;
mergeIntoServerResponse(
// @ts-expect-error - `node-fetch` Headers is missing `getAll()`
toOutgoingHeaders(fetchRes.headers),
res
);
fetchRes.body.pipe(res);
} catch (err: unknown) {
client.output.prettyError(err);
if (!res.headersSent) {
res.statusCode = 500;
res.end('Unexpected error during API call');
}
}
});
}

View File

@@ -161,6 +161,7 @@ export default class Now extends EventEmitter {
const deployment = await processDeployment({
now: this,
output: this._output,
agent: this._client.agent,
paths,
requestBody,
uploadStamp,
@@ -294,7 +295,7 @@ export default class Now extends EventEmitter {
if (
error.errorCode === 'BUILD_FAILED' ||
error.errorCode === 'UNEXPECTED_ERROR' ||
error.errorCode.includes('BUILD_UTILS_SPAWN_')
error.errorCode?.includes('BUILD_UTILS_SPAWN_')
) {
return new BuildError({
message: error.errorMessage,

View File

@@ -1,7 +1,7 @@
import http from 'http';
import open from 'open';
import { URL } from 'url';
import listen from 'async-listen';
import { listen } from 'async-listen';
import isDocker from 'is-docker';
import Client from '../client';
import prompt, { readInput } from './prompt';
@@ -64,8 +64,7 @@ async function getVerificationTokenInBand(
) {
const { output } = client;
const server = http.createServer();
const address = await listen(server, 0, '127.0.0.1');
const { port } = new URL(address);
const { port } = await listen(server, 0, '127.0.0.1');
url.searchParams.set('next', `http://localhost:${port}`);
output.log(`Please visit the following URL in your web browser:`);

View File

@@ -2,7 +2,7 @@ import os from 'os';
import url from 'url';
import fs from 'fs-extra';
import { join } from 'path';
import listen from 'async-listen';
import { listen } from 'async-listen';
import stripAnsi from 'strip-ansi';
import { createServer } from 'http';

View File

@@ -0,0 +1,16 @@
#!/usr/bin/env node
const { get } = require('http');
const { VERCEL_API } = process.env;
console.log('Hello from a CLI extension!');
console.log(`VERCEL_API: ${VERCEL_API}`);
get(`${VERCEL_API}/v2/user`, async (res) => {
let body = '';
res.setEncoding('utf8');
for await (const chunk of res) {
body += chunk;
}
const data = JSON.parse(body);
console.log(`Username: ${data.user.username}`);
});

View File

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

View File

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

View File

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

View File

@@ -5,6 +5,7 @@ import { URL, parse as parseUrl } from 'url';
import semVer from 'semver';
import { Readable } from 'stream';
import { homedir } from 'os';
import { runNpmInstall } from '@vercel/build-utils';
import { execCli } from './helpers/exec';
import fetch, { RequestInit, RequestInfo } from 'node-fetch';
import retry from 'async-retry';
@@ -1420,6 +1421,19 @@ test('use build-env', async () => {
expect(content.trim()).toBe('bar');
});
test('should invoke CLI extension', async () => {
const fixture = path.join(__dirname, 'fixtures/e2e/cli-extension');
// Ensure the `.bin` is populated in the fixture
await runNpmInstall(fixture);
const output = await execCli(binaryPath, ['mywhoami'], { cwd: fixture });
const formatted = formatOutput(output);
expect(output.stdout, formatted).toContain('Hello from a CLI extension!');
expect(output.stdout, formatted).toContain('VERCEL_API: http://127.0.0.1:');
expect(output.stdout, formatted).toContain(`Username: ${contextName}`);
});
// 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

@@ -5,7 +5,7 @@ import chalk from 'chalk';
import { PassThrough } from 'stream';
import { createServer, Server } from 'http';
import express, { Express, Router } from 'express';
import listen from 'async-listen';
import { listen } from 'async-listen';
import Client from '../../src/util/client';
import { Output } from '../../src/util/output';
@@ -101,6 +101,9 @@ export class MockClient extends Client {
this.localConfig = {};
this.scenario = Router();
this.agent?.destroy();
this.agent = undefined;
}
async startMockServer() {

View File

@@ -0,0 +1,35 @@
import { listen } from 'async-listen';
import { createProxy } from 'proxy';
import { ProxyAgent } from 'proxy-agent';
import { client } from '../../mocks/client';
describe('Client', () => {
describe('fetch()', () => {
beforeEach(() => {
delete process.env.HTTPS_PROXY;
});
it('should respect the `HTTPS_PROXY` env var', async () => {
let connectCount = 0;
const proxy = createProxy();
const proxyUrl = await listen(proxy);
proxy.on('connect', () => {
connectCount++;
});
try {
process.env.HTTPS_PROXY = proxyUrl.href;
client.agent = new ProxyAgent({ keepAlive: true });
expect(connectCount).toEqual(0);
const res = await client.fetch('https://example.com/', { json: false });
expect(connectCount).toEqual(1);
expect(res.status).toEqual(200);
} finally {
client.agent?.destroy();
proxy.close();
}
});
});
});

View File

@@ -1,5 +1,5 @@
import fetch from 'node-fetch';
import listen from 'async-listen';
import { listen } from 'async-listen';
import { createServer, IncomingMessage, Server, ServerResponse } from 'http';
import type { JSONValue } from '@vercel-internals/types';
import {
@@ -22,7 +22,7 @@ describe('responseError()', () => {
beforeAll(async () => {
server = createServer((req, res) => handler(req, res));
url = await listen(server);
url = (await listen(server)).toString();
});
afterAll(() => {

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/client",
"version": "12.4.12",
"version": "12.5.0",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"homepage": "https://vercel.com",

View File

@@ -56,7 +56,7 @@ export async function* checkDeploymentStatus(
teamId ? `?teamId=${teamId}` : ''
}`,
token,
{ apiUrl, userAgent }
{ apiUrl, userAgent, agent: clientOptions.agent }
);
const deploymentUpdate = await deploymentData.json();

View File

@@ -46,6 +46,7 @@ async function* postDeployment(
}),
apiUrl: clientOptions.apiUrl,
userAgent: clientOptions.userAgent,
agent: clientOptions.agent,
}
);

View File

@@ -1,3 +1,4 @@
import type { Agent } from 'http';
import type {
Builder,
BuilderFunctions,
@@ -31,6 +32,7 @@ export interface VercelClientOptions {
isDirectory?: boolean;
skipAutoDetectionConfirmation?: boolean;
archive?: ArchiveFormat;
agent?: Agent;
}
/** @deprecated Use VercelClientOptions instead. */

View File

@@ -79,7 +79,7 @@ export async function* upload(
debug('Building an upload list...');
const semaphore = new Sema(50, { capacity: 50 });
const agent = apiUrl?.startsWith('https://')
const defaultAgent = apiUrl?.startsWith('https://')
? new https.Agent({ keepAlive: true })
: new http.Agent({ keepAlive: true });
@@ -132,7 +132,7 @@ export async function* upload(
API_FILES,
token,
{
agent,
agent: clientOptions.agent || defaultAgent,
method: 'POST',
headers: {
'Content-Type': 'application/octet-stream',

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/frameworks",
"version": "1.4.1",
"version": "1.4.2",
"main": "./dist/frameworks.js",
"types": "./dist/frameworks.d.ts",
"files": [

View File

@@ -62,16 +62,40 @@ const SchemaSettings = {
],
};
const RouteSchema = {
type: 'array',
items: {
properties: {
src: { type: 'string' },
dest: { type: 'string' },
status: { type: 'number' },
handle: { type: 'string' },
headers: { type: 'object' },
continue: { type: 'boolean' },
},
},
};
const Schema = {
type: 'array',
items: {
type: 'object',
required: ['name', 'slug', 'logo', 'description', 'settings'],
additionalProperties: false,
required: [
'name',
'slug',
'logo',
'description',
'settings',
'getOutputDirName',
],
properties: {
name: { type: 'string' },
slug: { type: ['string', 'null'] },
sort: { type: 'number' },
logo: { type: 'string' },
darkModeLogo: { type: 'string' },
screenshot: { type: 'string' },
demo: { type: 'string' },
tagline: { type: 'string' },
website: { type: 'string' },
@@ -116,6 +140,26 @@ const Schema = {
outputDirectory: SchemaSettings,
},
},
getOutputDirName: {
isFunction: true,
},
defaultRoutes: {
oneOf: [{ isFunction: true }, RouteSchema],
},
defaulHeaders: {
type: 'array',
items: {
properties: {
source: { type: 'string' },
regex: { type: 'string' },
headers: { type: 'object' },
continue: { type: 'boolean' },
},
},
},
disableRootMiddleware: {
type: 'boolean',
},
recommendedIntegrations: {
type: 'array',
items: {
@@ -167,7 +211,8 @@ describe('frameworks', () => {
});
it('ensure schema', async () => {
const ajv = new Ajv();
const ajv = getValidator();
const result = ajv.validate(Schema, frameworkList);
if (ajv.errors) {
@@ -246,3 +291,16 @@ describe('frameworks', () => {
);
});
});
function getValidator() {
const ajv = new Ajv();
ajv.addKeyword('isFunction', {
compile: shouldMatch => data => {
const matches = typeof data === 'function';
return (shouldMatch && matches) || (!shouldMatch && !matches);
},
});
return ajv;
}

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/fs-detectors",
"version": "3.9.1",
"version": "3.9.2",
"description": "Vercel filesystem detectors",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
@@ -20,7 +20,7 @@
},
"dependencies": {
"@vercel/error-utils": "1.0.10",
"@vercel/frameworks": "1.4.1",
"@vercel/frameworks": "1.4.2",
"@vercel/routing-utils": "2.2.1",
"glob": "8.0.3",
"js-yaml": "4.1.0",

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/gatsby-plugin-vercel-builder",
"version": "1.3.2",
"version": "1.3.3",
"main": "dist/index.js",
"files": [
"dist",
@@ -16,7 +16,7 @@
"dependencies": {
"@sinclair/typebox": "0.25.24",
"@vercel/build-utils": "6.7.2",
"@vercel/node": "2.14.1",
"@vercel/node": "2.14.2",
"@vercel/routing-utils": "2.2.1",
"esbuild": "0.14.47",
"etag": "1.8.1",

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/node",
"version": "2.14.1",
"version": "2.14.2",
"license": "Apache-2.0",
"main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/node-js",
@@ -25,7 +25,7 @@
"@vercel/build-utils": "6.7.2",
"@vercel/error-utils": "1.0.8",
"@vercel/static-config": "2.0.17",
"async-listen": "1.2.0",
"async-listen": "3.0.0",
"edge-runtime": "2.1.4",
"esbuild": "0.14.47",
"exit-hook": "2.2.1",

View File

@@ -15,9 +15,7 @@ import { createServerlessEventHandler } from './serverless-functions/serverless-
import { isEdgeRuntime, logError, validateConfiguredRuntime } from './utils.js';
import { getConfig } from '@vercel/static-config';
import { Project } from 'ts-morph';
import asyncListen from 'async-listen';
const { default: listen } = asyncListen;
import { listen } from 'async-listen';
const parseConfig = (entryPointPath: string) =>
getConfig(new Project(), entryPointPath);
@@ -105,9 +103,12 @@ async function onDevRequest(
try {
const { headers, body, status } = await handleEvent(req);
res.statusCode = status;
for (const [key, value] of headers as unknown as Headers) {
// node-fetch does not support headers.getSetCookie(), so we need to
// manually set the raw value which can be an array of strings
if (value !== undefined) {
res.setHeader(key, value);
res.setHeader(key, key === 'set-cookie' ? headers.raw()[key] : value);
}
}

View File

@@ -4,15 +4,13 @@ import { serializeBody } from '../utils.js';
import { streamToBuffer } from '@vercel/build-utils';
import exitHook from 'exit-hook';
import fetch from 'node-fetch';
import asyncListen from 'async-listen';
import { listen } from 'async-listen';
import { isAbsolute } from 'path';
import { pathToFileURL } from 'url';
import type { ServerResponse, IncomingMessage } from 'http';
import type { VercelProxyResponse } from '../types.js';
import type { VercelRequest, VercelResponse } from './helpers.js';
const { default: listen } = asyncListen;
type ServerlessServerOptions = {
shouldAddHelpers: boolean;
mode: 'streaming' | 'buffer';

View File

@@ -0,0 +1,6 @@
import type { VercelRequest, VercelResponse } from '../..';
export default (_req: VercelRequest, res: VercelResponse) => {
res.setHeader('Set-Cookie', ['a=x', 'b=y', 'c=z']);
res.send('Hello, world!').end();
};

View File

@@ -135,3 +135,34 @@ test('runs a esm typescript endpoint', async () => {
child.kill(9);
}
});
test('allow setting multiple cookies with same name', async () => {
if (process.platform === 'win32') {
console.log('Skipping test on Windows');
return;
}
const child = testForkDevServer('./multiple-cookies.ts');
try {
const result = await readMessage(child);
if (result.state !== 'message') {
throw new Error(`Exited. error: ${JSON.stringify(result.value)}`);
}
const response = await fetch(
`http://localhost:${result.value.port}/api/hello`
);
expect({
status: response.status,
text: await response.text(),
}).toEqual({
status: 200,
text: 'Hello, world!',
});
expect(response.headers.raw()['set-cookie']).toEqual(['a=x', 'b=y', 'c=z']);
} finally {
child.kill(9);
}
});

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/static-build",
"version": "1.3.29",
"version": "1.3.30",
"license": "Apache-2.0",
"main": "./dist/index",
"homepage": "https://vercel.com/docs/build-step",
@@ -20,7 +20,7 @@
},
"dependencies": {
"@vercel/gatsby-plugin-vercel-analytics": "1.0.10",
"@vercel/gatsby-plugin-vercel-builder": "1.3.2"
"@vercel/gatsby-plugin-vercel-builder": "1.3.3"
},
"devDependencies": {
"@types/aws-lambda": "8.10.64",
@@ -34,8 +34,8 @@
"@types/semver": "7.3.13",
"@vercel/build-utils": "6.7.2",
"@vercel/error-utils": "1.0.10",
"@vercel/frameworks": "1.4.1",
"@vercel/fs-detectors": "3.9.1",
"@vercel/frameworks": "1.4.2",
"@vercel/fs-detectors": "3.9.2",
"@vercel/ncc": "0.24.0",
"@vercel/routing-utils": "2.2.1",
"@vercel/static-config": "2.0.17",

945
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff