Compare commits

..

23 Commits

Author SHA1 Message Date
Vercel Release Bot
fde40e731a Version Packages (#10278)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-07-31 13:31:22 -05:00
Trek Glowacki
f353527421 [cli] Migrate bisect command to new structure (#10276)
Migrating `bisect` to the command structure created in https://github.com/vercel/vercel/pull/10090. Unsure about tests. This is technically a refactor so existing tests should suffice.

Before:
<img width="534" alt="CleanShot 2023-07-31 at 08 14 29@2x" src="https://github.com/vercel/vercel/assets/9736/8ae53672-9b1f-444a-94d3-296ac0fa8d30">

After:
<img width="674" alt="CleanShot 2023-07-31 at 08 15 02@2x" src="https://github.com/vercel/vercel/assets/9736/0ba12f19-fb34-41f3-84fb-0c1498d7a485">
2023-07-31 16:03:13 +00:00
Trek Glowacki
c1cdfb3e75 [cli] Migrate remove command to new structure (#10268)
Migrating `remove` to the command structure created in #10090. Unsure about tests. This is technically a refactor so existing tests should suffice.
2023-07-31 15:42:27 +00:00
Kiko Beats
fc413707d0 fix: move content-type as dependency (#10274)
It's required by `serverless-functions/helpers.js` causing unhandled
error because it's missing.

```
Error: Cannot find module 'content-type'
Require stack:
- /Users/kikobeats/Library/pnpm/global/5/.pnpm/@vercel+node@2.15.6/node_modules/@vercel/node/dist/serverless-functions/helpers.js
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:1077:15)
    at Function.Module._resolveFilename.sharedData.moduleResolveFilenameHook.installedValue [as _resolveFilename] (/Users/kikobeats/Library/pnpm/global/5/.pnpm/@cspotcode+source-map-support@0.8.1/node_modules/@cspotcode/source-map-support/source-map-support.js:811:30)
    at Function.Module._load (node:internal/modules/cjs/loader:922:27)
    at Module.require (node:internal/modules/cjs/loader:1143:19)
    at require (node:internal/modules/cjs/helpers:110:18)
    at Object.<anonymous> (/Users/kikobeats/Library/pnpm/global/5/.pnpm/@vercel+node@2.15.6/node_modules/@vercel/node/dist/serverless-functions/helpers.js:6:24)
    at Module._compile (node:internal/modules/cjs/loader:1256:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1310:10)
    at Object.require.extensions.<computed> [as .js] (/Users/kikobeats/Library/pnpm/global/5/.pnpm/ts-node@10.9.1_@types+node@14.18.33_typescript@4.9.5/node_modules/ts-node/src/index.ts:1608:43)
    at Module.load (node:internal/modules/cjs/loader:1119:32) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    '/Users/kikobeats/Library/pnpm/global/5/.pnpm/@vercel+node@2.15.6/node_modules/@vercel/node/dist/serverless-functions/helpers.js'
  ]
}
```
2023-07-31 16:11:18 +02:00
Vercel Release Bot
e842a8870e Version Packages (#10261)
# Releases
## vercel@31.2.0

### Minor Changes

- Add a "Global Options" section to help output
([#10250](https://github.com/vercel/vercel/pull/10250))

### Patch Changes

- Updated dependencies
\[[`d1b0dbe3a`](d1b0dbe3a7),
[`4a8622a10`](4a8622a10d),
[`6469ef1b8`](6469ef1b8c)]:
    -   @vercel/remix-builder@1.9.0
    -   @vercel/next@3.9.3

## @vercel/remix-builder@1.9.0

### Minor Changes

- Install `@vercel/remix-run-dev` at build-time instead of using symlink
([#9784](https://github.com/vercel/vercel/pull/9784))

### Patch Changes

- Update `@remix-run/dev` fork to v1.19.1
([#10246](https://github.com/vercel/vercel/pull/10246))

## @vercel/next@3.9.3

### Patch Changes

- fix dynamic not found pages
([#10262](https://github.com/vercel/vercel/pull/10262))
2023-07-28 15:40:19 -07:00
Nathan Rajlich
d1b0dbe3a7 [remix] Install @vercel/remix-run-dev at build-time instead of using symlink (#9784)
Instead of including the fork `@remix-run/dev` package as a regular dependency of `@vercel/remix-builder`, install it at build-time by modifying the project's `package.json` file. The reasons for this are:

* Avoids deprecation warnings from a few packages that currently exist on the `@remix-run/dev` package when installing Vercel CLI (those warnings already show up in the build logs anyways, so nothing new there).
* Allows us to install a version as close as possible to the version specified in the user's `package.json` (similar to how we do when auto-injecting the `@vercel/remix` package). This will be especially important once Remix v2 is released, which will have breaking changes compared to v1.

**Note:** `@vercel/remix-run-dev` is still a _dev_ dependency, so that we can use TypeScript types from it, as well as, at runtime, we use the version in the Builder's `package.json` to determine the maximum versions of `@vercel/remix-run-dev` and/or `@vercel/remix` which can safely be installed.

Fixes #10027.
Fixes #10222.
2023-07-28 20:49:32 +00:00
Chris Barber
d614709308 [codeowners] Add @trek to codeowners (#10267)
Adding Trek so he join in on the code review fun!
2023-07-28 13:28:45 -04:00
Trek Glowacki
d5b588bc06 [cli] Add a "Global Options" section to help output (#10250)
Followup PR to #10090. Some of our commands duplicate global options into their `args` structure e.g. 2661f56347/packages/cli/src/commands/logs.ts (L25-L26)

 Others commands omit it entirely.

This updates the `--help` output for commands migrated to our new structure (so far, only `deploy`) will show a "Global Options" section:

```
▲ vercel deploy [project-path] [options]

Deploy your project to Vercel. The `deploy` command is the default command for the Vercel CLI, and can be omitted (`vc deploy my-app` equals `vc my-app`).

Options

  --archive                    Compress the deployment code into a file before uploading it
  -b, --build-env <key=value>  Specify environment variables during build-time (e.g. `-b KEY1=value1 -b KEY2=value2`)
  -e, --env <key=value>        Specify environment variables during run-time (e.g. `-e KEY1=value1 -e KEY2=value2`)
  -f, --force                  Force a new deployment even if nothing has changed
  -m, --meta <key=value>       Specify metadata for the deployment (e.g. `-m KEY1=value1 -m KEY2=value2`)
  --no-wait                    Don't wait for the deployment to finish
  --prebuilt                   Use in combination with `vc build`. Deploy an existing build
  --prod                       Create a production deployment
  -p, --public                 Deployment is public (`/_src`) is exposed)
  --regions                    Set default regions to enable the deployment on
  --with-cache                 Retain build cache when using "--force"
  -y, --yes                    Use default options to skip all prompts

Global Options

  --cwd <DIR>                Sets the current working directory for a single run of a command
  -d, --debug                Debug mode (default off)
  -Q, --global-config <DIR>  Path to the global ${'`.vercel`'} directory
  -h, --help                 Output usage information
  -A, --local-config <FILE>  Path to the local `vercel.json` file
  --no-color                 No color mode (default off)
  -S, --scope                Set a custom scope
  -t, --token <TOKEN>        Login token
  -v, --version              Output the version number
```

As commands are migrated to this new structure, they'll gain this output automatically.
2023-07-27 20:48:07 +00:00
Zack Tanner
4a8622a10d [next] fix dynamic not found pages (#10262)
This updates `getServerlessPages` to consider `/_not-found` pages (which might opt into dynamic rendering)

- Corresponding Next.js changes https://github.com/vercel/next.js/pull/53231
- [slack x-ref](https://vercel.slack.com/archives/C03S8ED1DKM/p1683763412272429)
2023-07-27 16:18:31 +00:00
Vercel Release Bot
6469ef1b8c [remix] Update @remix-run/dev to v1.19.1 (#10246)
This auto-generated PR updates `@remix-run/dev` to version 1.19.1.
2023-07-26 22:22:21 +00:00
Nathan Rajlich
b8d42a521b [examples] Remove "author" field from hydrogen template (#10253) 2023-07-26 14:48:07 -07:00
Vercel Release Bot
b1e8c9cb6e Version Packages (#10260)
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## vercel@31.1.1

### Patch Changes

- Updated dependencies
\[[`7c30b13cc`](7c30b13ccb)]:
    -   @vercel/next@3.9.2

## @vercel/next@3.9.2

### Patch Changes

- Fix pages/404 gsp + i18n case
([#10258](https://github.com/vercel/vercel/pull/10258))

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-07-26 14:50:22 -04:00
JJ Kasper
7c30b13ccb [next] Fix pages/404 gsp + i18n case (#10258)
This ensures we detect the locale prefixed 404 when it uses `getStaticProps` correctly. 

- x-ref: [slack thread](https://vercel.slack.com/archives/C05JTC58AQJ)
- Closes https://github.com/vercel/vercel/pull/10248
2023-07-26 18:41:25 +00:00
Steven
e5e757de34 [tests] fix vary header in next tests (#10249)
Since we run tests against canary, the latest [v13.4.13-canary.0](https://github.com/vercel/next.js/releases/tag/v13.4.13-canary.0) changed the `vary` header in https://github.com/vercel/next.js/pull/52746 so we need to update the tests to match.
2023-07-26 16:52:13 +00:00
Vercel Release Bot
2661f56347 Version Packages (#10227)
# Releases

## vercel@31.1.0

### Minor Changes

- Add 'Environment' column to 'vc list' with new '--environment' filter
and pipe URLs to stdout
([#10239](https://github.com/vercel/vercel/pull/10239))

### Patch Changes

- Update `proxy-agent` to v6.3.0
([#10226](https://github.com/vercel/vercel/pull/10226))

- Use `getNodeBinPaths()` in `vc dev`
([#10225](https://github.com/vercel/vercel/pull/10225))

- Updated dependencies
\[[`b1c14cde0`](b1c14cde03),
[`ce4633fe4`](ce4633fe4d)]:
    -   @vercel/next@3.9.1
    -   @vercel/static-build@1.3.42

## @vercel/frameworks@1.5.0

### Minor Changes

- Add `ignorePackageJsonScript` configuration for Framework command
settings to ignore the `package.json` script.
([#10228](https://github.com/vercel/vercel/pull/10228))

Enable this mode for Storybook's `buildCommand`, since it should not
invoke the "build" script, which is most likely designated for the
frontend app build.

## @vercel/fs-detectors@4.1.1

### Patch Changes

- Updated dependencies
\[[`ce4633fe4`](ce4633fe4d)]:
    -   @vercel/frameworks@1.5.0

## @vercel/next@3.9.1

### Patch Changes

- Fix pages and app router i18n handling
([#10243](https://github.com/vercel/vercel/pull/10243))

## @vercel/static-build@1.3.42

### Patch Changes

- Add `ignorePackageJsonScript` configuration for Framework command
settings to ignore the `package.json` script.
([#10228](https://github.com/vercel/vercel/pull/10228))

Enable this mode for Storybook's `buildCommand`, since it should not
invoke the "build" script, which is most likely designated for the
frontend app build.
2023-07-24 18:02:38 -07:00
JJ Kasper
b1c14cde03 [next] Fix pages and app router i18n handling (#10243)
Ensures app router paths are handled properly when i18n is configured for pages directory. 

x-ref: [slack thread](https://vercel.slack.com/archives/C03KAR5DCKC/p1687565759424049)
x-ref: [slack thread](https://vercel.slack.com/archives/C03KAR5DCKC/p1687565759424049)
x-ref: [slack thread](https://vercel.slack.com/archives/C03KAR5DCKC/p1672781549860349?thread_ts=1671393204.073649&cid=C03KAR5DCKC)

[VCCLI-780](https://linear.app/vercel/issue/VCCLI-780/add-404i18n-invariant-case-in-nextjs-builder)
2023-07-24 23:26:25 +00:00
Chris Barber
8dd6d021df [cli] Add "Environment" column to vc list (#10239)
Also adds a new `--environment=[preview|production]` filter and ability to pipe deployment URLs to `stdout`!

<img width="380" alt="image" src="https://github.com/vercel/vercel/assets/97262/20de0caa-2d63-4112-8213-cc15d23295c7">

```
vc list --environment preview
```

```
vc list --environment production
```

```
vc list --environment preview > preview_deployments.txt
```
2023-07-24 20:02:25 +00:00
Vercel Release Bot
88ec6e69d6 [examples][tests] Upgrade Next.js to version 13.4.12 (#10240)
This auto-generated PR updates 3 packages to Next.js version 13.4.12
2023-07-23 21:51:14 +00:00
Vercel Release Bot
a6f2e7b136 [tests] Upgrade Turbo to version 1.10.9 (#10241)
This auto-generated PR updates Turbo to version 1.10.9
2023-07-23 21:30:01 +00:00
Vercel Release Bot
e906365909 [examples][tests] Upgrade Next.js to version 13.4.11 (#10233)
This auto-generated PR updates 3 packages to Next.js version 13.4.11
2023-07-21 19:01:10 +00:00
Nathan Rajlich
7b01a07394 [cli] Use getNodeBinPaths() in vc dev (#10225)
This allows for the "dev command" of a Project to work better in monorepos, where the dev server might live up the node_modules hierarchy within the repo.
2023-07-19 22:19:43 +00:00
Nathan Rajlich
ce4633fe4d [frameworks][static-build] Add ignorePackageJsonScript configuration for Framework command settings (#10228)
When this property is set to `true`, then the corresponding `package.json` script will not be invoked, allowing for the default setting value will be executed.

This is enabled for Storybook's `buildCommand`, since we do not want the "build" script to be invoked, since that would belong to the frontend application's build instead of Storybook's.
2023-07-19 20:23:51 +00:00
Nathan Rajlich
fdf86fda03 [cli] Update proxy-agent to v6.3.0 (#10226)
This version includes a refactor for proxies specified via PAC files such that it no longer uses the deprecated `vm2` module.

See https://github.com/TooTallNate/proxy-agents/issues/218.
2023-07-18 20:29:37 +00:00
76 changed files with 5590 additions and 3674 deletions

12
.github/CODEOWNERS vendored
View File

@@ -2,11 +2,11 @@
# https://help.github.com/en/articles/about-code-owners
# Restricted Paths
* @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood
/.github/workflows @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @ijjk
/packages/fs-detectors @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @agadzik @chloetedder
/packages/next @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @ijjk
/packages/routing-utils @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @ijjk
* @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/routing-utils @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @trek @ijjk
/packages/edge @vercel/compute
/examples @leerob
/examples/create-react-app @Timer
@@ -14,7 +14,7 @@
/examples/hugo @styfle
/examples/jekyll @styfle
/examples/zola @styfle
/packages/node @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @Kikobeats
/packages/node @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @trek @Kikobeats
# Unrestricted Paths
.changeset/

View File

@@ -44,6 +44,5 @@
"react-use": "^17.4.0",
"title": "^3.4.4",
"typographic-base": "^1.0.4"
},
"author": "nrajlich"
}
}

View File

@@ -9,8 +9,8 @@
"version": "0.1.0",
"dependencies": {
"eslint": "8.45.0",
"eslint-config-next": "13.4.10",
"next": "13.4.10",
"eslint-config-next": "13.4.12",
"next": "13.4.12",
"react": "18.2.0",
"react-dom": "18.2.0"
}
@@ -117,22 +117,22 @@
"integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA=="
},
"node_modules/@next/env": {
"version": "13.4.10",
"resolved": "https://registry.npmjs.org/@next/env/-/env-13.4.10.tgz",
"integrity": "sha512-3G1yD/XKTSLdihyDSa8JEsaWOELY+OWe08o0LUYzfuHp1zHDA8SObQlzKt+v+wrkkPcnPweoLH1ImZeUa0A1NQ=="
"version": "13.4.12",
"resolved": "https://registry.npmjs.org/@next/env/-/env-13.4.12.tgz",
"integrity": "sha512-RmHanbV21saP/6OEPBJ7yJMuys68cIf8OBBWd7+uj40LdpmswVAwe1uzeuFyUsd6SfeITWT3XnQfn6wULeKwDQ=="
},
"node_modules/@next/eslint-plugin-next": {
"version": "13.4.10",
"resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-13.4.10.tgz",
"integrity": "sha512-YJqyq6vk39JQfvaNtN83t/p5Jy45+bazRL+V4QI8FPd3FBqFYMEsULiwRLgSJMgFqkk4t4JbeZurz+gILEAFpA==",
"version": "13.4.12",
"resolved": "https://registry.npmjs.org/@next/eslint-plugin-next/-/eslint-plugin-next-13.4.12.tgz",
"integrity": "sha512-6rhK9CdxEgj/j1qvXIyLTWEaeFv7zOK8yJMulz3Owel0uek0U9MJCGzmKgYxM3aAUBo3gKeywCZKyQnJKto60A==",
"dependencies": {
"glob": "7.1.7"
}
},
"node_modules/@next/swc-darwin-arm64": {
"version": "13.4.10",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.10.tgz",
"integrity": "sha512-4bsdfKmmg7mgFGph0UorD1xWfZ5jZEw4kKRHYEeTK9bT1QnMbPVPlVXQRIiFPrhoDQnZUoa6duuPUJIEGLV1Jg==",
"version": "13.4.12",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.4.12.tgz",
"integrity": "sha512-deUrbCXTMZ6ZhbOoloqecnUeNpUOupi8SE2tx4jPfNS9uyUR9zK4iXBvH65opVcA/9F5I/p8vDXSYbUlbmBjZg==",
"cpu": [
"arm64"
],
@@ -145,9 +145,9 @@
}
},
"node_modules/@next/swc-darwin-x64": {
"version": "13.4.10",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.10.tgz",
"integrity": "sha512-ngXhUBbcZIWZWqNbQSNxQrB9T1V+wgfCzAor2olYuo/YpaL6mUYNUEgeBMhr8qwV0ARSgKaOp35lRvB7EmCRBg==",
"version": "13.4.12",
"resolved": "https://registry.npmjs.org/@next/swc-darwin-x64/-/swc-darwin-x64-13.4.12.tgz",
"integrity": "sha512-WRvH7RxgRHlC1yb5oG0ZLx8F7uci9AivM5/HGGv9ZyG2Als8Ij64GC3d+mQ5sJhWjusyU6T6V1WKTUoTmOB0zQ==",
"cpu": [
"x64"
],
@@ -160,9 +160,9 @@
}
},
"node_modules/@next/swc-linux-arm64-gnu": {
"version": "13.4.10",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.10.tgz",
"integrity": "sha512-SjCZZCOmHD4uyM75MVArSAmF5Y+IJSGroPRj2v9/jnBT36SYFTORN8Ag/lhw81W9EeexKY/CUg2e9mdebZOwsg==",
"version": "13.4.12",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.4.12.tgz",
"integrity": "sha512-YEKracAWuxp54tKiAvvq73PUs9lok57cc8meYRibTWe/VdPB2vLgkTVWFcw31YDuRXdEhdX0fWS6Q+ESBhnEig==",
"cpu": [
"arm64"
],
@@ -175,9 +175,9 @@
}
},
"node_modules/@next/swc-linux-arm64-musl": {
"version": "13.4.10",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.10.tgz",
"integrity": "sha512-F+VlcWijX5qteoYIOxNiBbNE8ruaWuRlcYyIRK10CugqI/BIeCDzEDyrHIHY8AWwbkTwe6GRHabMdE688Rqq4Q==",
"version": "13.4.12",
"resolved": "https://registry.npmjs.org/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.4.12.tgz",
"integrity": "sha512-LhJR7/RAjdHJ2Isl2pgc/JaoxNk0KtBgkVpiDJPVExVWA1c6gzY57+3zWuxuyWzTG+fhLZo2Y80pLXgIJv7g3g==",
"cpu": [
"arm64"
],
@@ -190,9 +190,9 @@
}
},
"node_modules/@next/swc-linux-x64-gnu": {
"version": "13.4.10",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.4.10.tgz",
"integrity": "sha512-WDv1YtAV07nhfy3i1visr5p/tjiH6CeXp4wX78lzP1jI07t4PnHHG1WEDFOduXh3WT4hG6yN82EQBQHDi7hBrQ==",
"version": "13.4.12",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.4.12.tgz",
"integrity": "sha512-1DWLL/B9nBNiQRng+1aqs3OaZcxC16Nf+mOnpcrZZSdyKHek3WQh6j/fkbukObgNGwmCoVevLUa/p3UFTTqgqg==",
"cpu": [
"x64"
],
@@ -205,9 +205,9 @@
}
},
"node_modules/@next/swc-linux-x64-musl": {
"version": "13.4.10",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.4.10.tgz",
"integrity": "sha512-zFkzqc737xr6qoBgDa3AwC7jPQzGLjDlkNmt/ljvQJ/Veri5ECdHjZCUuiTUfVjshNIIpki6FuP0RaQYK9iCRg==",
"version": "13.4.12",
"resolved": "https://registry.npmjs.org/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.4.12.tgz",
"integrity": "sha512-kEAJmgYFhp0VL+eRWmUkVxLVunn7oL9Mdue/FS8yzRBVj7Z0AnIrHpTIeIUl1bbdQq1VaoOztnKicAjfkLTRCQ==",
"cpu": [
"x64"
],
@@ -220,9 +220,9 @@
}
},
"node_modules/@next/swc-win32-arm64-msvc": {
"version": "13.4.10",
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.10.tgz",
"integrity": "sha512-IboRS8IWz5mWfnjAdCekkl8s0B7ijpWeDwK2O8CdgZkoCDY0ZQHBSGiJ2KViAG6+BJVfLvcP+a2fh6cdyBr9QQ==",
"version": "13.4.12",
"resolved": "https://registry.npmjs.org/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.4.12.tgz",
"integrity": "sha512-GMLuL/loR6yIIRTnPRY6UGbLL9MBdw2anxkOnANxvLvsml4F0HNIgvnU3Ej4BjbqMTNjD4hcPFdlEow4XHPdZA==",
"cpu": [
"arm64"
],
@@ -235,9 +235,9 @@
}
},
"node_modules/@next/swc-win32-ia32-msvc": {
"version": "13.4.10",
"resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.10.tgz",
"integrity": "sha512-bSA+4j8jY4EEiwD/M2bol4uVEu1lBlgsGdvM+mmBm/BbqofNBfaZ2qwSbwE2OwbAmzNdVJRFRXQZ0dkjopTRaQ==",
"version": "13.4.12",
"resolved": "https://registry.npmjs.org/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.4.12.tgz",
"integrity": "sha512-PhgNqN2Vnkm7XaMdRmmX0ZSwZXQAtamBVSa9A/V1dfKQCV1rjIZeiy/dbBnVYGdj63ANfsOR/30XpxP71W0eww==",
"cpu": [
"ia32"
],
@@ -250,9 +250,9 @@
}
},
"node_modules/@next/swc-win32-x64-msvc": {
"version": "13.4.10",
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.10.tgz",
"integrity": "sha512-g2+tU63yTWmcVQKDGY0MV1PjjqgZtwM4rB1oVVi/v0brdZAcrcTV+04agKzWtvWroyFz6IqtT0MoZJA7PNyLVw==",
"version": "13.4.12",
"resolved": "https://registry.npmjs.org/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.4.12.tgz",
"integrity": "sha512-Z+56e/Ljt0bUs+T+jPjhFyxYBcdY2RIq9ELFU+qAMQMteHo7ymbV7CKmlcX59RI9C4YzN8PgMgLyAoi916b5HA==",
"cpu": [
"x64"
],
@@ -582,6 +582,25 @@
"get-intrinsic": "^1.1.3"
}
},
"node_modules/arraybuffer.prototype.slice": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.1.tgz",
"integrity": "sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw==",
"dependencies": {
"array-buffer-byte-length": "^1.0.0",
"call-bind": "^1.0.2",
"define-properties": "^1.2.0",
"get-intrinsic": "^1.2.1",
"is-array-buffer": "^3.0.2",
"is-shared-array-buffer": "^1.0.2"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/ast-types-flow": {
"version": "0.0.7",
"resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz",
@@ -704,9 +723,9 @@
}
},
"node_modules/caniuse-lite": {
"version": "1.0.30001515",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001515.tgz",
"integrity": "sha512-eEFDwUOZbE24sb+Ecsx3+OvNETqjWIdabMy52oOkIgcUtAsQifjUG9q4U9dgTHJM2mfk4uEPxc0+xuFdJ629QA==",
"version": "1.0.30001517",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001517.tgz",
"integrity": "sha512-Vdhm5S11DaFVLlyiKu4hiUTkpZu+y1KA/rZZqVQfOD5YdDT/eQKlkt7NaE0WGOFgX32diqt9MiP9CAiFeRklaA==",
"funding": [
{
"type": "opencollective",
@@ -908,11 +927,12 @@
}
},
"node_modules/es-abstract": {
"version": "1.21.3",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.21.3.tgz",
"integrity": "sha512-ZU4miiY1j3sGPFLJ34VJXEqhpmL+HGByCinGHv4HC+Fxl2fI2Z4yR6tl0mORnDr6PA8eihWo4LmSWDbvhALckg==",
"version": "1.22.1",
"resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz",
"integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==",
"dependencies": {
"array-buffer-byte-length": "^1.0.0",
"arraybuffer.prototype.slice": "^1.0.1",
"available-typed-arrays": "^1.0.5",
"call-bind": "^1.0.2",
"es-set-tostringtag": "^2.0.1",
@@ -939,10 +959,13 @@
"object-keys": "^1.1.1",
"object.assign": "^4.1.4",
"regexp.prototype.flags": "^1.5.0",
"safe-array-concat": "^1.0.0",
"safe-regex-test": "^1.0.0",
"string.prototype.trim": "^1.2.7",
"string.prototype.trimend": "^1.0.6",
"string.prototype.trimstart": "^1.0.6",
"typed-array-buffer": "^1.0.0",
"typed-array-byte-length": "^1.0.0",
"typed-array-byte-offset": "^1.0.0",
"typed-array-length": "^1.0.4",
"unbox-primitive": "^1.0.2",
@@ -1057,11 +1080,11 @@
}
},
"node_modules/eslint-config-next": {
"version": "13.4.10",
"resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-13.4.10.tgz",
"integrity": "sha512-+JjcM6lQmFR5Mw0ORm9o1CR29+z/uajgSfYAPEGIBxOhTHBgCMs7ysuwi72o7LkMmA8E3N7/h09pSGZxs0s85g==",
"version": "13.4.12",
"resolved": "https://registry.npmjs.org/eslint-config-next/-/eslint-config-next-13.4.12.tgz",
"integrity": "sha512-ZF0r5vxKaVazyZH/37Au/XItiG7qUOBw+HaH3PeyXltIMwXorsn6bdrl0Nn9N5v5v9spc+6GM2ryjugbjF6X2g==",
"dependencies": {
"@next/eslint-plugin-next": "13.4.10",
"@next/eslint-plugin-next": "13.4.12",
"@rushstack/eslint-patch": "^1.1.3",
"@typescript-eslint/parser": "^5.42.0",
"eslint-import-resolver-node": "^0.3.6",
@@ -1270,9 +1293,9 @@
}
},
"node_modules/eslint-plugin-react": {
"version": "7.32.2",
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.32.2.tgz",
"integrity": "sha512-t2fBMa+XzonrrNkyVirzKlvn5RXzzPwRHtMvLAtVZrt8oxgnTQaYbU6SXTOO1mwQgp1y5+toMSKInnzGr0Knqg==",
"version": "7.33.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.33.0.tgz",
"integrity": "sha512-qewL/8P34WkY8jAqdQxsiL82pDUeT7nhs8IsuXgfgnsEloKCT4miAV9N9kGtx7/KM9NH/NCGUE7Edt9iGxLXFw==",
"dependencies": {
"array-includes": "^3.1.6",
"array.prototype.flatmap": "^1.3.1",
@@ -1287,7 +1310,7 @@
"object.values": "^1.1.6",
"prop-types": "^15.8.1",
"resolve": "^2.0.0-next.4",
"semver": "^6.3.0",
"semver": "^6.3.1",
"string.prototype.matchall": "^4.0.8"
},
"engines": {
@@ -2117,15 +2140,11 @@
}
},
"node_modules/is-typed-array": {
"version": "1.1.10",
"resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.10.tgz",
"integrity": "sha512-PJqgEHiWZvMpaFZ3uTc8kHPM4+4ADTlDniuQL7cU/UDA0Ql7F70yGfHph3cLNe+c9toaigv+DFzTJKhc2CtO6A==",
"version": "1.1.12",
"resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz",
"integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==",
"dependencies": {
"available-typed-arrays": "^1.0.5",
"call-bind": "^1.0.2",
"for-each": "^0.3.3",
"gopd": "^1.0.1",
"has-tostringtag": "^1.0.0"
"which-typed-array": "^1.1.11"
},
"engines": {
"node": ">= 0.4"
@@ -2170,6 +2189,11 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/isarray": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
"integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="
},
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
@@ -2375,11 +2399,11 @@
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="
},
"node_modules/next": {
"version": "13.4.10",
"resolved": "https://registry.npmjs.org/next/-/next-13.4.10.tgz",
"integrity": "sha512-4ep6aKxVTQ7rkUW2fBLhpBr/5oceCuf4KmlUpvG/aXuDTIf9mexNSpabUD6RWPspu6wiJJvozZREhXhueYO36A==",
"version": "13.4.12",
"resolved": "https://registry.npmjs.org/next/-/next-13.4.12.tgz",
"integrity": "sha512-eHfnru9x6NRmTMcjQp6Nz0J4XH9OubmzOa7CkWL+AUrUxpibub3vWwttjduu9No16dug1kq04hiUUpo7J3m3Xw==",
"dependencies": {
"@next/env": "13.4.10",
"@next/env": "13.4.12",
"@swc/helpers": "0.5.1",
"busboy": "1.6.0",
"caniuse-lite": "^1.0.30001406",
@@ -2395,15 +2419,15 @@
"node": ">=16.8.0"
},
"optionalDependencies": {
"@next/swc-darwin-arm64": "13.4.10",
"@next/swc-darwin-x64": "13.4.10",
"@next/swc-linux-arm64-gnu": "13.4.10",
"@next/swc-linux-arm64-musl": "13.4.10",
"@next/swc-linux-x64-gnu": "13.4.10",
"@next/swc-linux-x64-musl": "13.4.10",
"@next/swc-win32-arm64-msvc": "13.4.10",
"@next/swc-win32-ia32-msvc": "13.4.10",
"@next/swc-win32-x64-msvc": "13.4.10"
"@next/swc-darwin-arm64": "13.4.12",
"@next/swc-darwin-x64": "13.4.12",
"@next/swc-linux-arm64-gnu": "13.4.12",
"@next/swc-linux-arm64-musl": "13.4.12",
"@next/swc-linux-x64-gnu": "13.4.12",
"@next/swc-linux-x64-musl": "13.4.12",
"@next/swc-win32-arm64-msvc": "13.4.12",
"@next/swc-win32-ia32-msvc": "13.4.12",
"@next/swc-win32-x64-msvc": "13.4.12"
},
"peerDependencies": {
"@opentelemetry/api": "^1.1.0",
@@ -2984,6 +3008,23 @@
"queue-microtask": "^1.2.2"
}
},
"node_modules/safe-array-concat": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.0.tgz",
"integrity": "sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==",
"dependencies": {
"call-bind": "^1.0.2",
"get-intrinsic": "^1.2.0",
"has-symbols": "^1.0.3",
"isarray": "^2.0.5"
},
"engines": {
"node": ">=0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/safe-regex-test": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz",
@@ -3332,6 +3373,36 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/typed-array-buffer": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz",
"integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==",
"dependencies": {
"call-bind": "^1.0.2",
"get-intrinsic": "^1.2.1",
"is-typed-array": "^1.1.10"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/typed-array-byte-length": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz",
"integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==",
"dependencies": {
"call-bind": "^1.0.2",
"for-each": "^0.3.3",
"has-proto": "^1.0.1",
"is-typed-array": "^1.1.10"
},
"engines": {
"node": ">= 0.4"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/typed-array-byte-offset": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz",
@@ -3448,16 +3519,15 @@
}
},
"node_modules/which-typed-array": {
"version": "1.1.10",
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.10.tgz",
"integrity": "sha512-uxoA5vLUfRPdjCuJ1h5LlYdmTLbYfums398v3WLkM+i/Wltl2/XyZpQWKbN++ck5L64SR/grOHqtXCUKmlZPNA==",
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz",
"integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==",
"dependencies": {
"available-typed-arrays": "^1.0.5",
"call-bind": "^1.0.2",
"for-each": "^0.3.3",
"gopd": "^1.0.1",
"has-tostringtag": "^1.0.0",
"is-typed-array": "^1.1.10"
"has-tostringtag": "^1.0.0"
},
"engines": {
"node": ">= 0.4"

View File

@@ -10,8 +10,8 @@
},
"dependencies": {
"eslint": "8.45.0",
"eslint-config-next": "13.4.10",
"next": "13.4.10",
"eslint-config-next": "13.4.12",
"next": "13.4.12",
"react": "18.2.0",
"react-dom": "18.2.0"
}

View File

@@ -9,6 +9,6 @@
},
"devDependencies": {
"@types/jest": "27.4.1",
"@vercel/frameworks": "1.4.3"
"@vercel/frameworks": "1.5.0"
}
}

View File

@@ -32,7 +32,7 @@
"source-map-support": "0.5.12",
"ts-eager": "2.0.2",
"ts-jest": "29.1.0",
"turbo": "1.10.7",
"turbo": "1.10.9",
"typescript": "4.9.5"
},
"scripts": {

View File

@@ -1,5 +1,52 @@
# vercel
## 31.2.1
### Patch Changes
- Migrate bisect command to new structure ([#10276](https://github.com/vercel/vercel/pull/10276))
- Migrate remove command to new structure ([#10268](https://github.com/vercel/vercel/pull/10268))
- Updated dependencies [[`fc413707d`](https://github.com/vercel/vercel/commit/fc413707d017e234d5013b761d885f65f9b981bc)]:
- @vercel/node@2.15.7
- @vercel/static-build@1.3.43
## 31.2.0
### Minor Changes
- Add a "Global Options" section to help output ([#10250](https://github.com/vercel/vercel/pull/10250))
### Patch Changes
- Updated dependencies [[`d1b0dbe3a`](https://github.com/vercel/vercel/commit/d1b0dbe3a7d8754286aa2b7ba0c8b55d3adafdea), [`4a8622a10`](https://github.com/vercel/vercel/commit/4a8622a10d52260cb629a1c4a6f797ade05ea154), [`6469ef1b8`](https://github.com/vercel/vercel/commit/6469ef1b8ce37e93f50ab4a108aa0953d7631fe8)]:
- @vercel/remix-builder@1.9.0
- @vercel/next@3.9.3
## 31.1.1
### Patch Changes
- Updated dependencies [[`7c30b13cc`](https://github.com/vercel/vercel/commit/7c30b13ccb79bdf0ac240282bba4c084f1d0d122)]:
- @vercel/next@3.9.2
## 31.1.0
### Minor Changes
- Add 'Environment' column to 'vc list' with new '--environment' filter and pipe URLs to stdout ([#10239](https://github.com/vercel/vercel/pull/10239))
### Patch Changes
- Update `proxy-agent` to v6.3.0 ([#10226](https://github.com/vercel/vercel/pull/10226))
- Use `getNodeBinPaths()` in `vc dev` ([#10225](https://github.com/vercel/vercel/pull/10225))
- Updated dependencies [[`b1c14cde0`](https://github.com/vercel/vercel/commit/b1c14cde03f94b2c15ba12c9be9d19c72df2fdbb), [`ce4633fe4`](https://github.com/vercel/vercel/commit/ce4633fe4d00cb5c251cdabbfab08f39ec3f3b5f)]:
- @vercel/next@3.9.1
- @vercel/static-build@1.3.42
## 31.0.4
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "vercel",
"version": "31.0.4",
"version": "31.2.1",
"preferGlobal": true,
"license": "Apache-2.0",
"description": "The command-line interface for Vercel",
@@ -34,13 +34,13 @@
"@vercel/build-utils": "6.8.2",
"@vercel/go": "2.5.1",
"@vercel/hydrogen": "0.0.64",
"@vercel/next": "3.9.0",
"@vercel/node": "2.15.6",
"@vercel/next": "3.9.3",
"@vercel/node": "2.15.7",
"@vercel/python": "3.1.60",
"@vercel/redwood": "1.1.15",
"@vercel/remix-builder": "1.8.18",
"@vercel/remix-builder": "1.9.0",
"@vercel/ruby": "1.3.76",
"@vercel/static-build": "1.3.41"
"@vercel/static-build": "1.3.43"
},
"devDependencies": {
"@alex_neo/jest-expect-message": "1.0.5",
@@ -89,8 +89,8 @@
"@vercel-internals/types": "1.0.5",
"@vercel/client": "12.6.5",
"@vercel/error-utils": "1.0.10",
"@vercel/frameworks": "1.4.3",
"@vercel/fs-detectors": "4.1.0",
"@vercel/frameworks": "1.5.0",
"@vercel/fs-detectors": "4.1.1",
"@vercel/fun": "1.0.4",
"@vercel/ncc": "0.24.0",
"@vercel/routing-utils": "2.2.1",
@@ -149,7 +149,7 @@
"pluralize": "7.0.0",
"promisepipe": "3.0.0",
"proxy": "2.0.0",
"proxy-agent": "6.1.1",
"proxy-agent": "6.3.0",
"psl": "1.1.31",
"qr-image": "3.2.0",
"raw-body": "2.4.1",

View File

@@ -0,0 +1,69 @@
import { Command } from '../help';
import { getPkgName } from '../../util/pkg-name';
export const bisectCommand: Command = {
name: 'bisect',
description: 'Bisect the current project interactively.',
arguments: [],
options: [
{
name: 'bad',
description: 'Known bad URL',
argument: 'URL',
shorthand: 'b',
type: 'string',
deprecated: false,
multi: false,
},
{
name: 'good',
description: 'Known good URL',
argument: 'URL',
shorthand: 'g',
type: 'string',
deprecated: false,
multi: false,
},
{
name: 'open',
description: 'Automatically open each URL in the browser',
argument: 'URL',
shorthand: 'o',
type: 'string',
deprecated: false,
multi: false,
},
{
name: 'path',
description: 'Subpath of the deployment URL to test',
argument: 'URL',
shorthand: 'p',
type: 'string',
deprecated: false,
multi: false,
},
{
name: 'run',
description: 'Test script to run for each deployment',
argument: 'URL',
shorthand: 'r',
type: 'string',
deprecated: false,
multi: false,
},
],
examples: [
{
name: 'Bisect the current project interactively',
value: `${getPkgName()} bisect`,
},
{
name: 'Bisect with a known bad deployment',
value: `${getPkgName()} bisect --bad example-310pce9i0.vercel.app`,
},
{
name: 'Automated bisect with a run script',
value: `${getPkgName()} bisect --run ./test.sh`,
},
],
};

View File

@@ -8,53 +8,19 @@ import { URLSearchParams, parse } from 'url';
import box from '../../util/output/box';
import formatDate from '../../util/format-date';
import link from '../../util/output/link';
import logo from '../../util/output/logo';
import getArgs from '../../util/get-args';
import Client from '../../util/client';
import { getPkgName } from '../../util/pkg-name';
import { Deployment } from '@vercel-internals/types';
import { normalizeURL } from '../../util/bisect/normalize-url';
import getScope from '../../util/get-scope';
import getDeployment from '../../util/get-deployment';
import { help } from '../help';
import { bisectCommand } from './command';
interface Deployments {
deployments: Deployment[];
}
const pkgName = getPkgName();
const help = () => {
console.log(`
${chalk.bold(`${logo} ${pkgName} bisect`)} [options]
${chalk.dim('Options:')}
-h, --help Output usage information
-d, --debug Debug mode [off]
--no-color No color mode [off]
-b, --bad Known bad URL
-g, --good Known good URL
-o, --open Automatically open each URL in the browser
-p, --path Subpath of the deployment URL to test
-r, --run Test script to run for each deployment
${chalk.dim('Examples:')}
${chalk.gray('')} Bisect the current project interactively
${chalk.cyan(`$ ${pkgName} bisect`)}
${chalk.gray('')} Bisect with a known bad deployment
${chalk.cyan(`$ ${pkgName} bisect --bad example-310pce9i0.vercel.app`)}
${chalk.gray('')} Automated bisect with a run script
${chalk.cyan(`$ ${pkgName} bisect --run ./test.sh`)}
`);
};
export default async function main(client: Client): Promise<number> {
export default async function bisect(client: Client): Promise<number> {
const { output } = client;
const scope = await getScope(client);
const { contextName } = scope;
@@ -73,7 +39,7 @@ export default async function main(client: Client): Promise<number> {
});
if (argv['--help']) {
help();
output.print(help(bisectCommand, { columns: client.stderr.columns }));
return 2;
}

View File

@@ -57,12 +57,13 @@ export default async function dev(
let projectSettings: ProjectSettings | undefined;
let envValues: Record<string, string> = {};
let repoRoot: string | undefined;
if (link.status === 'linked') {
const { project, org, repoRoot } = link;
const { project, org } = link;
// If repo linked, update `cwd` to the repo root
if (repoRoot) {
cwd = repoRoot;
if (link.repoRoot) {
repoRoot = cwd = link.repoRoot;
}
client.config.currentTeam = org.type === 'team' ? org.id : undefined;
@@ -82,6 +83,7 @@ export default async function dev(
output,
projectSettings,
envValues,
repoRoot,
});
// listen to SIGTERM for graceful shutdown

View File

@@ -30,6 +30,86 @@ export interface Command {
examples: CommandExample[];
}
const globalCommandOptions: CommandOption[] = [
{
name: 'help',
shorthand: 'h',
type: 'string',
description: 'Output usage information',
deprecated: false,
multi: false,
},
{
name: 'version',
shorthand: 'v',
type: 'string',
description: 'Output the version number',
deprecated: false,
multi: false,
},
{
name: 'cwd',
shorthand: null,
type: 'string',
argument: 'DIR',
description:
'Sets the current working directory for a single run of a command',
deprecated: false,
multi: false,
},
{
name: 'local-config',
shorthand: 'A',
type: 'string',
argument: 'FILE',
description: 'Path to the local `vercel.json` file',
deprecated: false,
multi: false,
},
{
name: 'global-config',
shorthand: 'Q',
type: 'string',
argument: 'DIR',
description: 'Path to the global `.vercel` directory',
deprecated: false,
multi: false,
},
{
name: 'debug',
shorthand: 'd',
type: 'string',
description: 'Debug mode (default off)',
deprecated: false,
multi: false,
},
{
name: 'no-color',
shorthand: null,
type: 'string',
description: 'No color mode (default off)',
deprecated: false,
multi: false,
},
{
name: 'scope',
shorthand: 'S',
type: 'string',
description: 'Set a custom scope',
deprecated: false,
multi: false,
},
{
name: 'token',
shorthand: 't',
type: 'string',
argument: 'TOKEN',
description: 'Login token',
deprecated: false,
multi: false,
},
];
export function calcLineLength(line: string[]) {
return stripAnsi(lineToString(line)).length;
}
@@ -75,27 +155,32 @@ export function buildCommandSynopsisLine(command: Command) {
}
export function buildCommandOptionLines(
command: Command,
options: BuildHelpOutputOptions
commandOptions: CommandOption[],
options: BuildHelpOutputOptions,
sectionTitle: String
) {
// Filter out deprecated and intentionally undocumented options
command.options = command.options.filter(
commandOptions = commandOptions.filter(
option => !option.deprecated && option.description !== undefined
);
if (commandOptions.length === 0) {
return '';
}
// Initialize output array with header and empty line
const outputArray: string[] = [chalk.dim(`Options:`), ''];
const outputArray: string[] = [`${chalk.dim(sectionTitle)}:`, ''];
// Start building option lines
const optionLines: string[][] = [];
// Sort command options alphabetically
command.options.sort((a, b) =>
commandOptions.sort((a, b) =>
a.name < b.name ? -1 : a.name > b.name ? 1 : 0
);
// Keep track of longest "start" of an option line to determine description spacing
let maxLineStartLength = 0;
// Iterate over options and create the "start" of each option (e.g. ` -b, --build-env <key=value>`)
for (const option of command.options) {
for (const option of commandOptions) {
const startLine: string[] = [INDENT];
if (option.shorthand) {
startLine.push(`-${option.shorthand},`);
@@ -135,7 +220,7 @@ export function buildCommandOptionLines(
*/
for (let i = 0; i < optionLines.length; i++) {
const optionLine = optionLines[i];
const option = command.options[i];
const option = commandOptions[i];
// Add only 2 spaces to the longest line, and then make all shorter lines the same length.
optionLine.push(
' '.repeat(2 + (maxLineStartLength - calcLineLength(optionLine)))
@@ -162,8 +247,6 @@ export function buildCommandOptionLines(
for (const line of lines) {
outputArray.push(lineToString(line));
}
// add an empty line in between in each option block for readability (skip the last block)
if (i !== optionLines.length - 1) outputArray.push('');
}
// return the entire list of options as a single string after delete the last '\n' added to the option list
@@ -209,7 +292,9 @@ export function buildHelpOutput(
'',
command.description,
'',
buildCommandOptionLines(command, options),
buildCommandOptionLines(command.options, options, 'Options'),
'',
buildCommandOptionLines(globalCommandOptions, options, 'Global Options'),
'',
buildCommandExampleLines(command),
'',

View File

@@ -44,7 +44,9 @@ const help = () => {
-m, --meta Filter deployments by metadata (e.g.: ${chalk.dim(
'`-m KEY=value`'
)}). Can appear many times.
--prod Filter for production URLs
--environment=${chalk.bold.underline(
'ENVIRONMENT'
)} Filter by environment (production|preview)
-N, --next Show next page of results
${chalk.dim('Examples:')}
@@ -76,11 +78,12 @@ export default async function main(client: Client) {
try {
argv = getArgs(client.argv.slice(2), {
'--environment': String,
'--meta': [String],
'-m': '--meta',
'--next': Number,
'-N': '--next',
'--prod': Boolean,
'--prod': Boolean, // this can be deprecated someday
'--yes': Boolean,
'-y': '--yes',
@@ -113,9 +116,14 @@ export default async function main(client: Client) {
}
const autoConfirm = !!argv['--yes'];
const prod = argv['--prod'] || false;
const meta = parseMeta(argv['--meta']);
const target = argv['--prod']
? 'production'
: typeof argv['--environment'] === 'string'
? argv['--environment'].toLowerCase()
: undefined;
// retrieve `project` and `org` from .vercel
let link = await getLinkedProject(client, cwd);
@@ -219,15 +227,12 @@ export default async function main(client: Client) {
debug('Fetching deployments');
const response = await now.list(
app,
{
version: 6,
meta,
nextTimestamp,
},
prod
);
const response = await now.list(app, {
version: 6,
meta,
nextTimestamp,
target,
});
let {
deployments,
@@ -280,9 +285,11 @@ export default async function main(client: Client) {
}
log(
`${prod ? `Production deployments` : `Deployments`} for ${chalk.bold(
app
)} under ${chalk.bold(contextName)} ${elapsed(Date.now() - start)}`
`${
target === 'production' ? `Production deployments` : `Deployments`
} for ${chalk.bold(app)} under ${chalk.bold(contextName)} ${elapsed(
Date.now() - start
)}`
);
// information to help the user find other deployments or instances
@@ -292,8 +299,9 @@ export default async function main(client: Client) {
print('\n');
const headers = ['Age', 'Deployment', 'Status', 'Duration'];
const headers = ['Age', 'Deployment', 'Status', 'Environment', 'Duration'];
if (showUsername) headers.push('Username');
const urls: string[] = [];
client.output.print(
`${table(
@@ -301,18 +309,17 @@ export default async function main(client: Client) {
headers.map(header => chalk.bold(chalk.cyan(header))),
...deployments
.sort(sortRecent())
.map(dep => [
[
.map(dep => {
urls.push(`https://${dep.url}`);
return [
chalk.gray(ms(Date.now() - dep.createdAt)),
`https://${dep.url}`,
stateString(dep.state || ''),
dep.target === 'production' ? 'Production' : 'Preview',
chalk.gray(getDeploymentDuration(dep)),
showUsername ? chalk.gray(dep.creator?.username) : '',
],
])
// flatten since the previous step returns a nested
// array of the deployment and (optionally) its instances
.flat()
];
})
.filter(app =>
// if an app wasn't supplied to filter by,
// we only want to render one deployment per app
@@ -327,6 +334,11 @@ export default async function main(client: Client) {
).replace(/^/gm, ' ')}\n\n`
);
if (!client.stdout.isTTY) {
client.stdout.write(urls.join('\n'));
client.stdout.write('\n');
}
if (pagination && pagination.count === 20) {
const flags = getCommandFlags(argv, ['_', '--next']);
log(

View File

@@ -35,6 +35,7 @@ const help = () => {
'DIR'
)} Path to the global ${'`.vercel`'} directory
-d, --debug Debug mode [off]
--git-branch Specify the Git branch to pull specific Environment Variables for
--no-color No color mode [off]
--environment [environment] Deployment environment [development]
-y, --yes Skip questions when setting up new project using default scope and settings

View File

@@ -0,0 +1,45 @@
import { Command } from '../help';
import { getPkgName } from '../../util/pkg-name';
export const removeCommand: Command = {
name: 'remove',
description: 'Remove a deployment by name or id.',
arguments: [
{
name: '...deploymentId|deploymentName',
required: true,
},
],
options: [
{
name: 'yes',
shorthand: 'y',
type: 'boolean',
deprecated: false,
description: 'Skip confirmation',
multi: false,
},
{
name: 'safe',
shorthand: 's',
type: 'boolean',
deprecated: false,
description: 'Skip deployments with an active alias',
multi: false,
},
],
examples: [
{
name: 'Remove a deployment identified by `deploymentId`',
value: `${getPkgName()} remove my-app`,
},
{
name: 'Remove all deployments with name `my-app`',
value: `${getPkgName()} remove deploymentId`,
},
{
name: 'Remove two deployments with IDs `eyWt6zuSdeus` and `uWHoA9RQ1d1o`',
value: `${getPkgName()} remove eyWt6zuSdeus uWHoA9RQ1d1o`,
},
],
};

View File

@@ -2,74 +2,31 @@ import chalk from 'chalk';
import ms from 'ms';
import plural from 'pluralize';
import table from 'text-table';
import Now from '../util';
import getAliases from '../util/alias/get-aliases';
import logo from '../util/output/logo';
import elapsed from '../util/output/elapsed';
import { normalizeURL } from '../util/url';
import getScope from '../util/get-scope';
import { isValidName } from '../util/is-valid-name';
import removeProject from '../util/projects/remove-project';
import getProjectByIdOrName from '../util/projects/get-project-by-id-or-name';
import getDeployment from '../util/get-deployment';
import getDeploymentsByProjectId from '../util/deploy/get-deployments-by-project-id';
import { getPkgName, getCommandName } from '../util/pkg-name';
import getArgs from '../util/get-args';
import handleError from '../util/handle-error';
import type Client from '../util/client';
import { Output } from '../util/output';
import Now from '../../util';
import getAliases from '../../util/alias/get-aliases';
import elapsed from '../../util/output/elapsed';
import { normalizeURL } from '../../util/url';
import getScope from '../../util/get-scope';
import { isValidName } from '../../util/is-valid-name';
import removeProject from '../../util/projects/remove-project';
import getProjectByIdOrName from '../../util/projects/get-project-by-id-or-name';
import getDeployment from '../../util/get-deployment';
import getDeploymentsByProjectId from '../../util/deploy/get-deployments-by-project-id';
import { getCommandName } from '../../util/pkg-name';
import getArgs from '../../util/get-args';
import handleError from '../../util/handle-error';
import type Client from '../../util/client';
import { Output } from '../../util/output';
import { Alias, Deployment, Project } from '@vercel-internals/types';
import { NowError } from '../util/now-error';
import { NowError } from '../../util/now-error';
import { help } from '../help';
import { removeCommand } from './command';
type DeploymentWithAliases = Deployment & {
aliases: Alias[];
};
const help = () => {
console.log(`
${chalk.bold(
`${logo} ${getPkgName()} remove`
)} [...deploymentId|deploymentName]
${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]
-t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline(
'TOKEN'
)} Login token
-y, --yes Skip confirmation
-s, --safe Skip deployments with an active alias
-S, --scope Set a custom scope
${chalk.dim('Examples:')}
${chalk.gray('')} Remove a deployment identified by ${chalk.dim(
'`deploymentId`'
)}
${chalk.cyan(`$ ${getPkgName()} rm deploymentId`)}
${chalk.gray('')} Remove all deployments with name ${chalk.dim('`my-app`')}
${chalk.cyan(`$ ${getPkgName()} rm my-app`)}
${chalk.gray('')} Remove two deployments with IDs ${chalk.dim(
'`eyWt6zuSdeus`'
)} and ${chalk.dim('`uWHoA9RQ1d1o`')}
${chalk.cyan(`$ ${getPkgName()} rm eyWt6zuSdeus uWHoA9RQ1d1o`)}
`);
};
export default async function main(client: Client) {
export default async function remove(client: Client) {
let argv;
try {
@@ -98,13 +55,13 @@ export default async function main(client: Client) {
const { success, error, log } = output;
if (argv['--help'] || ids[0] === 'help') {
help();
output.print(help(removeCommand, { columns: client.stderr.columns }));
return 2;
}
if (ids.length < 1) {
error(`${getCommandName('rm')} expects at least one argument`);
help();
output.print(help(removeCommand, { columns: client.stderr.columns }));
return 1;
}

View File

@@ -32,7 +32,7 @@ import {
Builder,
cloneEnv,
Env,
getNodeBinPath,
getNodeBinPaths,
StartDevServerResult,
FileFsRef,
PackageJson,
@@ -124,6 +124,7 @@ function sortBuilders(buildA: Builder, buildB: Builder) {
export default class DevServer {
public cwd: string;
public repoRoot: string;
public output: Output;
public proxy: httpProxy;
public envConfigs: EnvConfigs;
@@ -169,6 +170,7 @@ export default class DevServer {
constructor(cwd: string, options: DevServerOptions) {
this.cwd = cwd;
this.repoRoot = options.repoRoot ?? cwd;
this.output = options.output;
this.envConfigs = { buildEnv: {}, runEnv: {}, allEnv: {} };
this.envValues = options.envValues || {};
@@ -1412,7 +1414,7 @@ export default class DevServer {
files,
entrypoint: middleware.entrypoint,
workPath,
repoRootPath: this.cwd,
repoRootPath: this.repoRoot,
config: middleware.config || {},
meta: {
isDev: true,
@@ -1849,7 +1851,7 @@ export default class DevServer {
entrypoint: match.entrypoint,
workPath,
config: match.config || {},
repoRootPath: this.cwd,
repoRootPath: this.repoRoot,
meta: {
isDev: true,
requestPath,
@@ -2237,7 +2239,8 @@ export default class DevServer {
);
// add the node_modules/.bin directory to the PATH
const nodeBinPath = await getNodeBinPath({ cwd });
const nodeBinPaths = getNodeBinPaths({ base: this.repoRoot, start: cwd });
const nodeBinPath = nodeBinPaths.join(path.delimiter);
env.PATH = `${nodeBinPath}${path.delimiter}${env.PATH}`;
// This is necesary so that the dev command in the Project

View File

@@ -25,6 +25,7 @@ export interface DevServerOptions {
output: Output;
projectSettings?: ProjectSettings;
envValues?: Record<string, string>;
repoRoot?: string;
}
export interface EnvConfigs {

View File

@@ -61,6 +61,7 @@ export interface ListOptions {
version?: number;
meta?: Dictionary<string>;
nextTimestamp?: number;
target?: string;
}
export default class Now extends EventEmitter {
@@ -339,7 +340,7 @@ export default class Now extends EventEmitter {
async list(
app?: string,
{ version = 4, meta = {}, nextTimestamp }: ListOptions = {},
{ version = 4, meta = {}, nextTimestamp, target }: ListOptions = {},
prod?: boolean
) {
const fetchRetry = async (url: string, options: FetchOptions = {}) => {
@@ -405,6 +406,8 @@ export default class Now extends EventEmitter {
}
if (prod) {
query.set('target', 'production');
} else if (target) {
query.set('target', target);
}
const response = await fetchRetry(`/v${version}/now/deployments?${query}`);

View File

@@ -2,8 +2,6 @@
"orgId": ".",
"projectId": ".",
"settings": {
"framework": "storybook",
"buildCommand": "npm run build-storybook",
"outputDirectory": "storybook-static"
"framework": "storybook"
}
}

View File

@@ -5,7 +5,7 @@ exports[`help command help output snapshots column width 40 1`] = `
Deploy your project to Vercel. The \`deploy\` command is the default command for the Vercel CLI, and can be omitted (\`vc deploy my-app\` equals \`vc my-app\`).
Options:
Options:
--archive Compress
the
@@ -15,7 +15,6 @@ Deploy your project to Vercel. The \`deploy\` command is the default command for
before
uploading
it
-b, --build-env <key=value> Specify
environment
variables
@@ -25,7 +24,6 @@ Deploy your project to Vercel. The \`deploy\` command is the default command for
KEY1=value1
-b
KEY2=value2\`)
-e, --env <key=value> Specify
environment
variables
@@ -35,7 +33,6 @@ Deploy your project to Vercel. The \`deploy\` command is the default command for
KEY1=value1
-e
KEY2=value2\`)
-f, --force Force a
new
deployment
@@ -43,7 +40,6 @@ Deploy your project to Vercel. The \`deploy\` command is the default command for
nothing
has
changed
-m, --meta <key=value> Specify
metadata
for the
@@ -52,13 +48,11 @@ Deploy your project to Vercel. The \`deploy\` command is the default command for
KEY1=value1
-m
KEY2=value2\`)
--no-wait Don't
wait for
the
deployment
to finish
--prebuilt Use in
combination
with \`vc
@@ -66,18 +60,15 @@ Deploy your project to Vercel. The \`deploy\` command is the default command for
Deploy an
existing
build
--prod Create a
production
deployment
-p, --public
Deployment
is public
(\`/_src\`)
is
exposed)
--regions Set
default
regions
@@ -85,14 +76,12 @@ Deploy your project to Vercel. The \`deploy\` command is the default command for
the
deployment
on
--with-cache Retain
build
cache
when
using
"--force"
-y, --yes Use
default
options
@@ -100,6 +89,42 @@ Deploy your project to Vercel. The \`deploy\` command is the default command for
all
prompts
Global Options:
--cwd <DIR> Sets the
current
working
directory
for a
single run
of a
command
-d, --debug Debug mode
(default
off)
-Q, --global-config <DIR> Path to the
global
\`.vercel\`
directory
-h, --help Output
usage
information
-A, --local-config <FILE> Path to the
local
\`vercel.json\`
file
--no-color No color
mode
(default
off)
-S, --scope Set a
custom
scope
-t, --token <TOKEN> Login token
-v, --version Output the
version
number
Examples:
- Deploy the current directory
@@ -130,38 +155,40 @@ exports[`help command help output snapshots column width 80 1`] = `
Deploy your project to Vercel. The \`deploy\` command is the default command for the Vercel CLI, and can be omitted (\`vc deploy my-app\` equals \`vc my-app\`).
Options:
Options:
--archive Compress the deployment code into a file before
uploading it
-b, --build-env <key=value> Specify environment variables during build-time
(e.g. \`-b KEY1=value1 -b KEY2=value2\`)
-e, --env <key=value> Specify environment variables during run-time
(e.g. \`-e KEY1=value1 -e KEY2=value2\`)
-f, --force Force a new deployment even if nothing has
changed
-m, --meta <key=value> Specify metadata for the deployment (e.g. \`-m
KEY1=value1 -m KEY2=value2\`)
--no-wait Don't wait for the deployment to finish
--prebuilt Use in combination with \`vc build\`. Deploy an
existing build
--prod Create a production deployment
-p, --public Deployment is public (\`/_src\`) is exposed)
--regions Set default regions to enable the deployment on
--with-cache Retain build cache when using "--force"
-y, --yes Use default options to skip all prompts
Global Options:
--cwd <DIR> Sets the current working directory for a single run
of a command
-d, --debug Debug mode (default off)
-Q, --global-config <DIR> Path to the global \`.vercel\` directory
-h, --help Output usage information
-A, --local-config <FILE> Path to the local \`vercel.json\` file
--no-color No color mode (default off)
-S, --scope Set a custom scope
-t, --token <TOKEN> Login token
-v, --version Output the version number
Examples:
- Deploy the current directory
@@ -192,32 +219,33 @@ exports[`help command help output snapshots column width 120 1`] = `
Deploy your project to Vercel. The \`deploy\` command is the default command for the Vercel CLI, and can be omitted (\`vc deploy my-app\` equals \`vc my-app\`).
Options:
Options:
--archive Compress the deployment code into a file before uploading it
-b, --build-env <key=value> Specify environment variables during build-time (e.g. \`-b KEY1=value1 -b KEY2=value2\`)
-e, --env <key=value> Specify environment variables during run-time (e.g. \`-e KEY1=value1 -e KEY2=value2\`)
-f, --force Force a new deployment even if nothing has changed
-m, --meta <key=value> Specify metadata for the deployment (e.g. \`-m KEY1=value1 -m KEY2=value2\`)
--no-wait Don't wait for the deployment to finish
--prebuilt Use in combination with \`vc build\`. Deploy an existing build
--prod Create a production deployment
-p, --public Deployment is public (\`/_src\`) is exposed)
--regions Set default regions to enable the deployment on
--with-cache Retain build cache when using "--force"
-y, --yes Use default options to skip all prompts
Global Options:
--cwd <DIR> Sets the current working directory for a single run of a command
-d, --debug Debug mode (default off)
-Q, --global-config <DIR> Path to the global \`.vercel\` directory
-h, --help Output usage information
-A, --local-config <FILE> Path to the local \`vercel.json\` file
--no-color No color mode (default off)
-S, --scope Set a custom scope
-t, --token <TOKEN> Login token
-v, --version Output the version number
Examples:
- Deploy the current directory

View File

@@ -58,6 +58,7 @@ describe('list', () => {
'Age',
'Deployment',
'Status',
'Environment',
'Duration',
'Username',
]);
@@ -68,6 +69,7 @@ describe('list', () => {
expect(data).toEqual([
`https://${deployment.url}`,
stateString(deployment.state || ''),
deployment.target === 'production' ? 'Production' : 'Preview',
getDeploymentDuration(deployment),
user.username,
]);
@@ -107,7 +109,13 @@ describe('list', () => {
line = await lines.next();
const header = parseSpacedTableRow(line.value!);
expect(header).toEqual(['Age', 'Deployment', 'Status', 'Duration']);
expect(header).toEqual([
'Age',
'Deployment',
'Status',
'Environment',
'Duration',
]);
line = await lines.next();
const data = parseSpacedTableRow(line.value!);
@@ -116,6 +124,7 @@ describe('list', () => {
expect(data).toEqual([
'https://' + deployment.url,
stateString(deployment.state || ''),
deployment.target === 'production' ? 'Production' : 'Preview',
getDeploymentDuration(deployment),
]);
});
@@ -160,6 +169,7 @@ describe('list', () => {
'Age',
'Deployment',
'Status',
'Environment',
'Duration',
'Username',
]);
@@ -170,8 +180,50 @@ describe('list', () => {
expect(data).toEqual([
`https://${deployment.url}`,
stateString(deployment.state || ''),
deployment.target === 'production' ? 'Production' : 'Preview',
getDeploymentDuration(deployment),
user.username,
]);
});
it('should output deployment URLs to stdout', async () => {
const user = useUser();
useProject({
...defaultProject,
id: 'with-team',
name: 'with-team',
});
const prodDeployment = useDeployment({
creator: user,
createdAt: Date.now() - 1000,
target: 'production',
});
const previewDeployment = useDeployment({
creator: user,
createdAt: Date.now(),
target: undefined,
});
client.stdout.isTTY = false;
client.cwd = fixture('with-team');
// run with all deployments
let prom = list(client);
await expect(client.stdout).toOutput(
`https://${previewDeployment.url}\nhttps://${prodDeployment.url}`
);
await prom;
// run again with preview deployments only
client.setArgv('--environment', 'preview');
prom = list(client);
await expect(client.stdout).toOutput(`https://${previewDeployment.url}`);
await prom;
// run again with production deployments only
client.setArgv('--environment', 'production');
prom = list(client);
await expect(client.stdout).toOutput(`https://${prodDeployment.url}`);
await prom;
});
});

View File

@@ -1,5 +1,13 @@
# @vercel/frameworks
## 1.5.0
### Minor Changes
- Add `ignorePackageJsonScript` configuration for Framework command settings to ignore the `package.json` script. ([#10228](https://github.com/vercel/vercel/pull/10228))
Enable this mode for Storybook's `buildCommand`, since it should not invoke the "build" script, which is most likely designated for the frontend app build.
## 1.4.3
### Patch Changes

View File

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

View File

@@ -1955,6 +1955,7 @@ export const frameworks = [
},
buildCommand: {
value: 'storybook build',
ignorePackageJsonScript: true,
},
devCommand: {
value: `storybook dev -p $PORT`,

View File

@@ -32,11 +32,24 @@ export interface SettingPlaceholder {
export interface SettingValue {
/**
* A predefined setting for the detected framework
* A predefined setting for the detected framework.
* @example "next dev --port $PORT"
*/
value: string | null;
/**
* Placeholder text that may be shown in the UI when
* the user is configuring this setting value.
* @example "`npm run build` or `next build`"
*/
placeholder?: string;
/**
* When set to `true`, then the builder will not
* invoke the equivalent script in `package.json`,
* and instead will invoke the command specified in
* configuration setting directly. When this
* configuration is enabled, `value` must be a string.
*/
ignorePackageJsonScript?: boolean;
}
export type Setting = SettingValue | SettingPlaceholder;

View File

@@ -49,6 +49,22 @@ const SchemaSettings = {
},
},
},
{
type: 'object',
required: ['value', 'ignorePackageJsonScript'],
additionalProperties: false,
properties: {
value: {
type: 'string',
},
placeholder: {
type: 'string',
},
ignorePackageJsonScript: {
type: 'boolean',
},
},
},
{
type: 'object',
required: ['placeholder'],

View File

@@ -1,5 +1,12 @@
# @vercel/fs-detectors
## 4.1.1
### Patch Changes
- Updated dependencies [[`ce4633fe4`](https://github.com/vercel/vercel/commit/ce4633fe4d00cb5c251cdabbfab08f39ec3f3b5f)]:
- @vercel/frameworks@1.5.0
## 4.1.0
### Minor Changes

View File

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

View File

@@ -1,5 +1,12 @@
# @vercel/gatsby-plugin-vercel-builder
## 1.3.15
### Patch Changes
- Updated dependencies [[`fc413707d`](https://github.com/vercel/vercel/commit/fc413707d017e234d5013b761d885f65f9b981bc)]:
- @vercel/node@2.15.7
## 1.3.14
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/gatsby-plugin-vercel-builder",
"version": "1.3.14",
"version": "1.3.15",
"main": "dist/index.js",
"files": [
"dist",
@@ -21,7 +21,7 @@
"dependencies": {
"@sinclair/typebox": "0.25.24",
"@vercel/build-utils": "6.8.2",
"@vercel/node": "2.15.6",
"@vercel/node": "2.15.7",
"@vercel/routing-utils": "2.2.1",
"esbuild": "0.14.47",
"etag": "1.8.1",

View File

@@ -1,5 +1,23 @@
# @vercel/next
## 3.9.3
### Patch Changes
- fix dynamic not found pages ([#10262](https://github.com/vercel/vercel/pull/10262))
## 3.9.2
### Patch Changes
- Fix pages/404 gsp + i18n case ([#10258](https://github.com/vercel/vercel/pull/10258))
## 3.9.1
### Patch Changes
- Fix pages and app router i18n handling ([#10243](https://github.com/vercel/vercel/pull/10243))
## 3.9.0
### Minor Changes

View File

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

View File

@@ -1139,8 +1139,9 @@ export const build: BuildV2 = async ({
const canUsePreviewMode = Object.keys(pages).some(page =>
isApiPage(pages[page].fsPath)
);
staticPages = await filterStaticPages(
await glob('**/*.html', pagesDir),
const originalStaticPages = await glob('**/*.html', pagesDir);
staticPages = filterStaticPages(
originalStaticPages,
dynamicPages,
entryDirectory,
htmlContentType,
@@ -1316,6 +1317,17 @@ export const build: BuildV2 = async ({
);
}
const localePrefixed404 = !!(
routesManifest.i18n &&
originalStaticPages[
path.posix.join(
entryDirectory,
routesManifest.i18n.defaultLocale,
'404.html'
)
]
);
return serverBuild({
config,
functionsConfigManifest,
@@ -1325,6 +1337,7 @@ export const build: BuildV2 = async ({
dynamicPages,
canUsePreviewMode,
staticPages,
localePrefixed404,
lambdaPages: pages,
lambdaAppPaths,
omittedPrerenderRoutes,
@@ -2679,6 +2692,7 @@ async function getServerlessPages(params: {
? Promise.all([
glob('**/page.js', path.join(params.pagesDir, '../app')),
glob('**/route.js', path.join(params.pagesDir, '../app')),
glob('**/_not-found.js', path.join(params.pagesDir, '../app')),
]).then(items => Object.assign(...items))
: Promise.resolve({}),
getMiddlewareManifest(params.entryPath, params.outputDirectory),

View File

@@ -91,6 +91,7 @@ export async function serverBuild({
routesManifest,
staticPages,
lambdaPages,
localePrefixed404,
nextVersion,
lambdaAppPaths,
canUsePreviewMode,
@@ -112,6 +113,7 @@ export async function serverBuild({
baseDir: string;
canUsePreviewMode: boolean;
omittedPrerenderRoutes: Set<string>;
localePrefixed404: boolean;
staticPages: { [key: string]: FileFsRef };
lambdaAppPaths: { [key: string]: FileFsRef };
lambdaPages: { [key: string]: FileFsRef };
@@ -215,12 +217,12 @@ export async function serverBuild({
? path.posix.join(entryDirectory, '_errors/404')
: undefined;
if (!static404Page && i18n) {
static404Page = staticPages[
path.posix.join(entryDirectory, i18n.defaultLocale, '404')
]
? path.posix.join(entryDirectory, i18n.defaultLocale, '404')
: undefined;
if (
!static404Page &&
i18n &&
staticPages[path.posix.join(entryDirectory, i18n.defaultLocale, '404')]
) {
static404Page = path.posix.join(entryDirectory, i18n.defaultLocale, '404');
}
if (!hasStatic500 && i18n) {
@@ -967,6 +969,7 @@ export async function serverBuild({
if (
i18n &&
!isPrerender &&
!group.isAppRouter &&
(!isCorrectLocaleAPIRoutes ||
!(pageNoExt === 'api' || pageNoExt.startsWith('api/')))
) {
@@ -1004,6 +1007,7 @@ export async function serverBuild({
isSharedLambdas: false,
canUsePreviewMode,
static404Page,
localePrefixed404,
hasPages404: routesManifest.pages404,
isCorrectNotFoundRoutes,
isEmptyAllowQueryForPrendered,
@@ -1070,7 +1074,8 @@ export async function serverBuild({
prerenderManifest,
routesManifest,
true,
isCorrectLocaleAPIRoutes
isCorrectLocaleAPIRoutes,
inversedAppPathManifest
)
);

View File

@@ -479,7 +479,8 @@ export function localizeDynamicRoutes(
prerenderManifest: NextPrerenderedRoutes,
routesManifest?: RoutesManifest,
isServerMode?: boolean,
isCorrectLocaleAPIRoutes?: boolean
isCorrectLocaleAPIRoutes?: boolean,
inversedAppPathRoutesManifest?: Record<string, string>
): RouteWithSrc[] {
return dynamicRoutes.map((route: RouteWithSrc) => {
// i18n is already handled for middleware
@@ -498,6 +499,9 @@ export function localizeDynamicRoutes(
const isAutoExport =
staticPages[addLocaleOrDefault(pathname!, routesManifest).substring(1)];
const isAppRoute =
inversedAppPathRoutesManifest?.[pathnameNoPrefix || ''];
const isLocalePrefixed =
isFallback || isBlocking || isAutoExport || isServerMode;
@@ -508,7 +512,11 @@ export function localizeDynamicRoutes(
}${i18n.locales.map(locale => escapeStringRegexp(locale)).join('|')})?`
);
if (isLocalePrefixed && !(isCorrectLocaleAPIRoutes && isApiRoute)) {
if (
isLocalePrefixed &&
!(isCorrectLocaleAPIRoutes && isApiRoute) &&
!isAppRoute
) {
// ensure destination has locale prefix to match prerender output
// path so that the prerender object is used
route.dest = route.dest!.replace(
@@ -1791,6 +1799,7 @@ export const onPrerenderRouteInitial = (
type OnPrerenderRouteArgs = {
appDir: string | null;
pagesDir: string;
localePrefixed404?: boolean;
static404Page?: string;
hasPages404: boolean;
entryDirectory: string;
@@ -1828,6 +1837,7 @@ export const onPrerenderRoute =
appDir,
pagesDir,
static404Page,
localePrefixed404,
entryDirectory,
prerenderManifest,
isSharedLambdas,
@@ -1963,7 +1973,9 @@ export const onPrerenderRoute =
// file.
`${
isOmittedOrNotFound
? addLocaleOrDefault('/404', routesManifest, locale)
? localePrefixed404
? addLocaleOrDefault('/404', routesManifest, locale)
: '/404'
: routeFileNoExt
}.html`
),
@@ -1980,7 +1992,9 @@ export const onPrerenderRoute =
: pagesDir,
`${
isOmittedOrNotFound
? addLocaleOrDefault('/404.html', routesManifest, locale)
? localePrefixed404
? addLocaleOrDefault('/404.html', routesManifest, locale)
: '/404.html'
: isAppPathRoute
? dataRoute
: routeFileNoExt + '.json'

View File

@@ -42,14 +42,14 @@
"status": 200,
"mustContain": "hello from /ssg",
"responseHeaders": {
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
}
},
{
"path": "/hello/world/ssg",
"status": 200,
"responseHeaders": {
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
},
"headers": {
"RSC": "1"
@@ -82,14 +82,14 @@
"status": 200,
"mustContain": "hello from app/dashboard/deployments/[id]/settings",
"responseHeaders": {
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
}
},
{
"path": "/hello/world/dashboard/deployments/123/settings",
"status": 200,
"responseHeaders": {
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
},
"headers": {
"RSC": "1"
@@ -102,14 +102,14 @@
"status": 200,
"mustContain": "catchall",
"responseHeaders": {
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
}
},
{
"path": "/hello/world/dashboard/deployments/catchall/something",
"status": 200,
"responseHeaders": {
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
},
"headers": {
"RSC": "1"
@@ -122,7 +122,7 @@
"status": 200,
"mustContain": "hello from app/dashboard",
"responseHeaders": {
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
}
},
{
@@ -142,7 +142,7 @@
},
"responseHeaders": {
"content-type": "text/x-component",
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
}
},
{

View File

@@ -0,0 +1,10 @@
export default function Layout({ children }) {
return (
<html>
<head>
<title>Hello World</title>
</head>
<body>{children}</body>
</html>
)
}

View File

@@ -0,0 +1,13 @@
import { cookies } from 'next/headers';
export default function Page() {
cookies(); // dynamic
return (
<>
<h1>This Is The Not Found Page</h1>
<div id="timestamp">{Date.now()}</div>
</>
)
}

View File

@@ -0,0 +1,3 @@
export default function Page() {
return <h1>My page TEST</h1>
}

View File

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

View File

@@ -0,0 +1 @@
module.exports = {};

View File

@@ -0,0 +1,11 @@
{
"dependencies": {
"next": "canary",
"react": "experimental",
"react-dom": "experimental"
},
"ignoreNextjsUpdates": true,
"scripts": {
"vercel-build": "next build"
}
}

View File

@@ -0,0 +1,12 @@
{ "probes": [
{
"path": "/",
"status": 200,
"mustContain": "My page"
},
{
"path": "/not-found-page",
"status": 404,
"mustContain": "This Is The Not Found Page"
}
]}

View File

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

View File

@@ -0,0 +1,3 @@
export function GET(req) {
return new Response('hello world')
}

View File

@@ -0,0 +1,16 @@
export default function Page({ params: { slug } }) {
return (
<p>dynamic page {slug}</p>
)
}
export function generateStaticParams() {
return [
{
slug: 'first',
},
{
slug: 'second'
}
]
}

View File

@@ -3,7 +3,7 @@ module.exports = {
appDir: true,
},
i18n: {
locales: ['en'],
locales: ['en', 'fr', 'de'],
defaultLocale: 'en',
},
};

View File

@@ -0,0 +1,5 @@
export default function Page() {
return <>
<p>pages/another.js</p>
</>
}

View File

@@ -0,0 +1,3 @@
export default function handler(req, res) {
res.end('hello world')
}

View File

@@ -0,0 +1,18 @@
export default function Page() {
return <p>dynamic pages page</p>;
}
export function getStaticProps() {
return {
props: {
now: Date.now(),
},
};
}
export function getStaticPaths() {
return {
paths: [{ params: { slug: "first" } }, { params: { slug: "second" } }],
fallback: "blocking",
};
}

View File

@@ -35,6 +35,42 @@
"path": "/en/other",
"status": 200,
"mustContain": "My Other Page"
},
{
"fetchOptions": { "redirect": "manual" },
"path": "/dynamic/first",
"status": 200,
"mustContain": "dynamic page"
},
{
"fetchOptions": { "redirect": "manual" },
"path": "/dynamic/third",
"status": 200,
"mustContain": "dynamic page"
},
{
"fetchOptions": { "redirect": "manual" },
"path": "/another",
"status": 200,
"mustContain": "pages/another"
},
{
"fetchOptions": { "redirect": "manual" },
"path": "/fr/another",
"status": 200,
"mustContain": "pages/another"
},
{
"fetchOptions": { "redirect": "manual" },
"path": "/api/hello",
"status": 200,
"mustContain": "hello world"
},
{
"fetchOptions": { "redirect": "manual" },
"path": "/api/hello-app",
"status": 200,
"mustContain": "hello world"
}
]
}

View File

@@ -22,7 +22,7 @@
"redirect": "manual"
},
"responseHeaders": {
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
},
"headers": {
"RSC": "1"
@@ -46,7 +46,7 @@
"redirect": "manual"
},
"responseHeaders": {
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
},
"headers": {
"RSC": "1"
@@ -70,7 +70,7 @@
"redirect": "manual"
},
"responseHeaders": {
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
},
"headers": {
"RSC": "1"

View File

@@ -11,7 +11,7 @@
"status": 200,
"mustContain": "hello from app/dashboard",
"responseHeaders": {
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
}
},
{
@@ -31,7 +31,7 @@
},
"responseHeaders": {
"content-type": "text/x-component",
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
}
},
{

View File

@@ -23,14 +23,14 @@
"status": 200,
"mustContain": "hello from /ssg",
"responseHeaders": {
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
}
},
{
"path": "/ssg/",
"status": 200,
"responseHeaders": {
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
},
"headers": {
"RSC": "1"
@@ -63,14 +63,14 @@
"status": 200,
"mustContain": "hello from app/dashboard/deployments/[id]/settings",
"responseHeaders": {
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
}
},
{
"path": "/dashboard/deployments/123/settings/",
"status": 200,
"responseHeaders": {
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
},
"headers": {
"RSC": "1"
@@ -83,14 +83,14 @@
"status": 200,
"mustContain": "catchall",
"responseHeaders": {
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
}
},
{
"path": "/dashboard/deployments/catchall/something/",
"status": 200,
"responseHeaders": {
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
},
"headers": {
"RSC": "1"
@@ -103,7 +103,7 @@
"status": 200,
"mustContain": "hello from app/dashboard",
"responseHeaders": {
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
}
},
{
@@ -123,7 +123,7 @@
},
"responseHeaders": {
"content-type": "text/x-component",
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
}
},
{

View File

@@ -42,14 +42,14 @@
"status": 200,
"mustContain": "hello from /ssg",
"responseHeaders": {
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
}
},
{
"path": "/ssg",
"status": 200,
"responseHeaders": {
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
},
"headers": {
"RSC": "1"
@@ -82,14 +82,14 @@
"status": 200,
"mustContain": "hello from app/dashboard/deployments/[id]/settings",
"responseHeaders": {
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
}
},
{
"path": "/dashboard/deployments/123/settings",
"status": 200,
"responseHeaders": {
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
},
"headers": {
"RSC": "1"
@@ -102,14 +102,14 @@
"status": 200,
"mustContain": "catchall",
"responseHeaders": {
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
}
},
{
"path": "/dashboard/deployments/catchall/something",
"status": 200,
"responseHeaders": {
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
},
"headers": {
"RSC": "1"
@@ -122,7 +122,7 @@
"status": 200,
"mustContain": "hello from app/dashboard",
"responseHeaders": {
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
}
},
{
@@ -142,7 +142,7 @@
},
"responseHeaders": {
"content-type": "text/x-component",
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
}
},
{

View File

@@ -0,0 +1,38 @@
import { useRouter } from "next/router"
export default function Page(props) {
const router = useRouter()
return (
<>
<p>/blog/[slug]</p>
<p>{JSON.stringify(router.query)}</p>
<p>{JSON.stringify(props)}</p>
</>
)
}
export function getStaticProps({ params }) {
if (params.slug === 'second') {
return {
notFound: true
}
}
return {
props: {
now: Date.now(),
params
}
}
}
export function getStaticPaths() {
return {
paths: [
{ params: { slug: 'first' } },
{ params: { slug: 'second' } },
],
fallback: 'blocking'
}
}

View File

@@ -11,7 +11,7 @@
"status": 200,
"mustContain": "about",
"responseHeaders": {
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch"
"vary": "RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Url"
}
},
{

View File

@@ -1,5 +1,11 @@
# @vercel/node
## 2.15.7
### Patch Changes
- fix: move content-type as dependency ([#10274](https://github.com/vercel/vercel/pull/10274))
## 2.15.6
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/node",
"version": "2.15.6",
"version": "2.15.7",
"license": "Apache-2.0",
"main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/node-js",
@@ -25,6 +25,7 @@
"@types/node": "14.18.33",
"@types/node-fetch": "2.6.3",
"@vercel/build-utils": "6.8.2",
"content-type": "1.0.4",
"@vercel/error-utils": "1.0.10",
"@vercel/static-config": "2.0.17",
"async-listen": "3.0.0",
@@ -33,6 +34,7 @@
"exit-hook": "2.2.1",
"node-fetch": "2.6.9",
"path-to-regexp": "6.2.1",
"@types/content-type": "1.1.3",
"ts-morph": "12.0.0",
"ts-node": "10.9.1",
"typescript": "4.9.5"
@@ -42,14 +44,12 @@
"@babel/plugin-transform-modules-commonjs": "7.5.0",
"@tootallnate/once": "1.1.2",
"@types/aws-lambda": "8.10.19",
"@types/content-type": "1.1.3",
"@types/cookie": "0.3.3",
"@types/etag": "1.8.0",
"@types/jest": "29.5.0",
"@types/test-listen": "1.1.0",
"@vercel/ncc": "0.24.0",
"@vercel/nft": "0.22.5",
"content-type": "1.0.4",
"cookie": "0.4.0",
"cross-env": "7.0.3",
"etag": "1.8.1",

View File

@@ -1,5 +1,15 @@
# @vercel/remix-builder
## 1.9.0
### Minor Changes
- Install `@vercel/remix-run-dev` at build-time instead of using symlink ([#9784](https://github.com/vercel/vercel/pull/9784))
### Patch Changes
- Update `@remix-run/dev` fork to v1.19.1 ([#10246](https://github.com/vercel/vercel/pull/10246))
## 1.8.18
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/remix-builder",
"version": "1.8.18",
"version": "1.9.0",
"license": "Apache-2.0",
"main": "./dist/index.js",
"homepage": "https://vercel.com/docs",
@@ -20,7 +20,6 @@
"defaults"
],
"dependencies": {
"@remix-run/dev": "npm:@vercel/remix-run-dev@1.18.1",
"@vercel/build-utils": "6.8.2",
"@vercel/nft": "0.22.5",
"@vercel/static-config": "2.0.17",
@@ -29,6 +28,7 @@
"ts-morph": "12.0.0"
},
"devDependencies": {
"@remix-run/dev": "npm:@vercel/remix-run-dev@1.19.1",
"@types/jest": "27.5.1",
"@types/node": "14.18.33",
"@types/semver": "7.3.13"

View File

@@ -1,5 +1,5 @@
import { Project } from 'ts-morph';
import { promises as fs } from 'fs';
import { readFileSync, promises as fs } from 'fs';
import { basename, dirname, extname, join, relative, sep } from 'path';
import {
debug,
@@ -26,7 +26,6 @@ import type {
PackageJson,
BuildResultV2Typical,
} from '@vercel/build-utils';
import type { AppConfig } from '@remix-run/dev/dist/config';
import type { ConfigRoute } from '@remix-run/dev/dist/config/routes';
import type { BaseFunctionConfig } from '@vercel/static-config';
import {
@@ -41,16 +40,22 @@ import {
ResolvedEdgeRouteConfig,
findEntry,
chdirAndReadConfig,
addDependency,
addDependencies,
resolveSemverMinMax,
ensureResolvable,
isESM,
} from './utils';
import semver from 'semver';
const _require: typeof require = eval('require');
interface ServerBundle {
serverBuildPath: string;
routes: string[];
}
const REMIX_RUN_DEV_PATH = dirname(
_require.resolve('@remix-run/dev/package.json')
const remixBuilderPkg = JSON.parse(
readFileSync(join(__dirname, '../package.json'), 'utf8')
);
const remixRunDevForkVersion =
remixBuilderPkg.devDependencies['@remix-run/dev'];
const DEFAULTS_PATH = join(__dirname, '../defaults');
@@ -63,8 +68,17 @@ const nodeServerSrcPromise = fs.readFile(
'utf-8'
);
// This value is the minimum supported version for our fork of Remix
const minimumSupportRemixVersion = '1.10.0';
// Minimum supported version of the `@vercel/remix` package
const VERCEL_REMIX_MIN_VERSION = '1.10.0';
// Minimum supported version of the `@vercel/remix-run-dev` forked compiler
const REMIX_RUN_DEV_MIN_VERSION = '1.15.0';
// Maximum version of `@vercel/remix-run-dev` fork
// (and also `@vercel/remix` since they get published at the same time)
const REMIX_RUN_DEV_MAX_VERSION = remixRunDevForkVersion.slice(
remixRunDevForkVersion.lastIndexOf('@') + 1
);
export const build: BuildV2 = async ({
entrypoint,
@@ -133,18 +147,32 @@ export const build: BuildV2 = async ({
repoRootPath,
'@remix-run/dev'
);
const remixVersion = JSON.parse(
await fs.readFile(join(remixRunDevPath, 'package.json'), 'utf8')
).version;
const remixRunDevPkg = JSON.parse(
readFileSync(join(remixRunDevPath, 'package.json'), 'utf8')
);
const remixVersion = remixRunDevPkg.version;
const remixConfig = await chdirAndReadConfig(
remixRunDevPath,
entrypointFsDirname,
packageJsonPath
);
const { serverEntryPoint, appDirectory } = remixConfig;
const remixRoutes = Object.values(remixConfig.routes);
const depsToAdd: string[] = [];
if (remixRunDevPkg.name !== '@vercel/remix-run-dev') {
const remixDevForkVersion = resolveSemverMinMax(
REMIX_RUN_DEV_MIN_VERSION,
REMIX_RUN_DEV_MAX_VERSION,
remixVersion
);
depsToAdd.push(
`@remix-run/dev@npm:@vercel/remix-run-dev@${remixDevForkVersion}`
);
}
// `app/entry.server.tsx` and `app/entry.client.tsx` are optional in Remix,
// so if either of those files are missing then add our own versions.
const userEntryServerFile = findEntry(appDirectory, 'entry.server');
@@ -155,44 +183,27 @@ export const build: BuildV2 = async ({
);
if (!pkg.dependencies['@vercel/remix']) {
// Dependency version resolution logic
// 1. Users app is on 1.9.0 -> we install the 1.10.0 (minimum) version of our fork (`@vercel/remix`)
// 2. Users app is on 1.11.0 (a version greater than 1.10.0 and less than the latest version of the fork) -> we install the (matching) 1.11.0 version of `@vercel/remix`
// 3. Users app is on something greater than our latest version of the fork -> we install the latest version of our fork
// remixVersion is the version of the `@remix-run/dev` package in the *users' app*
const usersRemixVersion = semver.gt(
remixVersion,
minimumSupportRemixVersion
)
? remixVersion
: minimumSupportRemixVersion;
// Prevent frozen lockfile rejections
const envForAddDep = { ...spawnOpts.env };
delete envForAddDep.CI;
delete envForAddDep.VERCEL;
delete envForAddDep.NOW_BUILDER;
await addDependency(
cliType,
[
`@vercel/remix@${
semver.gt(
usersRemixVersion,
require('@remix-run/dev/package.json').version
)
? 'latest'
: usersRemixVersion
}`,
],
{
...spawnOpts,
env: envForAddDep,
cwd: entrypointFsDirname,
}
// 1. Users app is on 1.9.0 -> we install the 1.10.0 (minimum) version of `@vercel/remix`.
// 2. Users app is on 1.11.0 (a version greater than 1.10.0 and less than the known max
// published version) -> we install the (matching) 1.11.0 version of `@vercel/remix`.
// 3. Users app is on something greater than our latest version of the fork -> we install
// the latest known published version of `@vercel/remix`.
const vercelRemixVersion = resolveSemverMinMax(
VERCEL_REMIX_MIN_VERSION,
REMIX_RUN_DEV_MAX_VERSION,
remixVersion
);
depsToAdd.push(`@vercel/remix@${vercelRemixVersion}`);
}
}
if (depsToAdd.length) {
await addDependencies(cliType, depsToAdd, {
...spawnOpts,
cwd: entrypointFsDirname,
});
}
const userEntryClientFile = findEntry(
remixConfig.appDirectory,
'entry.client'
@@ -210,12 +221,8 @@ export const build: BuildV2 = async ({
? `${remixConfigPath}.original${extname(remixConfigPath)}`
: undefined;
const backupRemixRunDevPath = `${remixRunDevPath}.__vercel_backup`;
await fs.rename(remixRunDevPath, backupRemixRunDevPath);
await fs.symlink(REMIX_RUN_DEV_PATH, remixRunDevPath);
// These get populated inside the try/catch below
let serverBundles: AppConfig['serverBundles'];
let serverBundles: ServerBundle[];
const serverBundlesMap = new Map<string, ConfigRoute[]>();
const resolvedConfigsMap = new Map<ConfigRoute, ResolvedRouteConfig>();
@@ -273,16 +280,9 @@ export const build: BuildV2 = async ({
if (remixConfigPath && renamedRemixConfigPath) {
await fs.rename(remixConfigPath, renamedRemixConfigPath);
// Figure out if the `remix.config` file is using ESM syntax
let isESM = false;
try {
_require(renamedRemixConfigPath);
} catch (err: any) {
isESM = err.code === 'ERR_REQUIRE_ESM';
}
let patchedConfig: string;
if (isESM) {
// Figure out if the `remix.config` file is using ESM syntax
if (isESM(renamedRemixConfigPath)) {
patchedConfig = `import config from './${basename(
renamedRemixConfigPath
)}';
@@ -340,10 +340,6 @@ module.exports = config;`;
if (remixConfigWrapped && remixConfigPath && renamedRemixConfigPath) {
await fs.rename(renamedRemixConfigPath, remixConfigPath);
}
// Remove `@remix-run/dev` symlink
await fs.unlink(remixRunDevPath);
await fs.rename(backupRemixRunDevPath, remixRunDevPath);
}
// This needs to happen before we run NFT to create the Node/Edge functions

View File

@@ -1,6 +1,6 @@
import { glob } from '@vercel/build-utils';
import { dirname, join, relative } from 'path';
import { chdirAndReadConfig } from './utils';
import { _require, chdirAndReadConfig } from './utils';
import type { PrepareCache } from '@vercel/build-utils';
export const prepareCache: PrepareCache = async ({
@@ -12,7 +12,13 @@ export const prepareCache: PrepareCache = async ({
const mountpoint = dirname(entrypoint);
const entrypointFsDirname = join(workPath, mountpoint);
const packageJsonPath = join(entrypointFsDirname, 'package.json');
const remixRunDevPath = dirname(
_require.resolve('@remix-run/dev/package.json', {
paths: [entrypointFsDirname],
})
);
const remixConfig = await chdirAndReadConfig(
remixRunDevPath,
entrypointFsDirname,
packageJsonPath
);

View File

@@ -1,8 +1,8 @@
import semver from 'semver';
import { existsSync, promises as fs } from 'fs';
import { basename, dirname, join, relative, resolve, sep } from 'path';
import { pathToRegexp, Key } from 'path-to-regexp';
import { debug, spawnAsync } from '@vercel/build-utils';
import { readConfig } from '@remix-run/dev/dist/config';
import { walkParentDirs } from '@vercel/build-utils';
import type {
ConfigRoute,
@@ -15,12 +15,15 @@ import type {
SpawnOptionsExtended,
} from '@vercel/build-utils/dist/fs/run-user-scripts';
export const _require: typeof require = eval('require');
export interface ResolvedNodeRouteConfig {
runtime: 'nodejs';
regions?: string[];
maxDuration?: number;
memory?: number;
}
export interface ResolvedEdgeRouteConfig {
runtime: 'edge';
regions?: BaseFunctionConfig['regions'];
@@ -43,8 +46,6 @@ export interface ResolvedRoutePaths {
rePath: string;
}
const _require: typeof require = eval('require');
const SPLAT_PATH = '/:params*';
const entryExts = ['.js', '.jsx', '.ts', '.tsx'];
@@ -212,7 +213,14 @@ export function syncEnv(source: NodeJS.ProcessEnv, dest: NodeJS.ProcessEnv) {
return () => syncEnv(originalDest, dest);
}
export async function chdirAndReadConfig(dir: string, packageJsonPath: string) {
export async function chdirAndReadConfig(
remixRunDevPath: string,
dir: string,
packageJsonPath: string
) {
const { readConfig }: typeof import('@remix-run/dev/dist/config') =
await import(join(remixRunDevPath, 'dist/config.js'));
const originalCwd = process.cwd();
// As of Remix v1.14.0, reading the config may trigger adding
@@ -249,18 +257,22 @@ export async function chdirAndReadConfig(dir: string, packageJsonPath: string) {
return remixConfig;
}
export interface AddDependencyOptions extends SpawnOptionsExtended {
export interface AddDependenciesOptions extends SpawnOptionsExtended {
saveDev?: boolean;
}
/**
* Runs `npm i ${name}` / `pnpm i ${name}` / `yarn add ${name}`.
*/
export function addDependency(
export function addDependencies(
cliType: CliType,
names: string[],
opts: AddDependencyOptions = {}
opts: AddDependenciesOptions = {}
) {
debug('Installing additional dependencies:');
for (const name of names) {
debug(` - ${name}`);
}
const args: string[] = [];
if (cliType === 'npm' || cliType === 'pnpm') {
args.push('install');
@@ -277,6 +289,15 @@ export function addDependency(
return spawnAsync(cliType, args.concat(names), opts);
}
export function resolveSemverMinMax(
min: string,
max: string,
version: string
): string {
const floored = semver.intersects(version, `>= ${min}`) ? version : min;
return semver.intersects(floored, `<= ${max}`) ? floored : max;
}
export async function ensureResolvable(
start: string,
base: string,
@@ -369,3 +390,14 @@ async function ensureSymlink(
await fs.symlink(relativeTarget, symlinkPath);
debug(`Created symlink for "${pkgName}"`);
}
export function isESM(path: string): boolean {
// Figure out if the `remix.config` file is using ESM syntax
let isESM = false;
try {
_require(path);
} catch (err: any) {
isESM = err.code === 'ERR_REQUIRE_ESM';
}
return isESM;
}

View File

@@ -10,14 +10,14 @@
"start": "remix-serve build"
},
"dependencies": {
"@remix-run/node": "^1.7.4",
"@remix-run/react": "^1.7.4",
"@remix-run/serve": "^1.7.4",
"@remix-run/node": "1.15.0",
"@remix-run/react": "1.15.0",
"@remix-run/serve": "1.15.0",
"react": "18.2.0",
"react-dom": "18.2.0"
},
"devDependencies": {
"@remix-run/dev": "^1.7.4",
"@remix-run/dev": "1.15.0",
"@types/react": "^17.0.45",
"@types/react-dom": "^17.0.17",
"typescript": "^4.6.4"

File diff suppressed because it is too large Load Diff

View File

@@ -10,13 +10,13 @@
"start": "remix-serve build"
},
"dependencies": {
"@remix-run/react": "1.5.0",
"@remix-run/serve": "1.5.0",
"@remix-run/react": "1.10.0",
"@remix-run/serve": "1.10.0",
"react": "18.2.0",
"react-dom": "18.2.0"
},
"devDependencies": {
"@remix-run/dev": "1.5.0",
"@remix-run/dev": "1.10.0",
"@types/react": "^17.0.45",
"@types/react-dom": "^17.0.17",
"typescript": "^4.6.4"

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,20 @@
import { resolveSemverMinMax } from '../src/utils';
describe('resolveSemverMinMax()', () => {
it.each([
{ min: '1.0.0', max: '1.15.0', version: '0.9.0', expected: '1.0.0' },
{ min: '1.0.0', max: '1.15.0', version: '1.0.0', expected: '1.0.0' },
{ min: '1.0.0', max: '1.15.0', version: '1.1.0', expected: '1.1.0' },
{ min: '1.0.0', max: '1.15.0', version: '1.10.0', expected: '1.10.0' },
{ min: '1.0.0', max: '1.15.0', version: '1.15.0', expected: '1.15.0' },
{ min: '1.0.0', max: '1.15.0', version: '1.16.0', expected: '1.15.0' },
{ min: '1.0.0', max: '1.15.0', version: '^1.12.0', expected: '^1.12.0' },
{ min: '1.0.0', max: '1.15.0', version: '0.x.x', expected: '1.0.0' },
])(
'Should return "$expected" for version "$version" (min=$min, max=$max)',
({ min, max, version, expected }) => {
const actual = resolveSemverMinMax(min, max, version);
expect(actual).toEqual(expected);
}
);
});

View File

@@ -12,6 +12,7 @@
"noUnusedParameters": true,
"outDir": "./dist",
"types": ["node", "jest"],
"skipLibCheck": true,
"strict": true,
"target": "ES2020",
"sourceMap": true

View File

@@ -1,5 +1,20 @@
# @vercel/static-build
## 1.3.43
### Patch Changes
- Updated dependencies []:
- @vercel/gatsby-plugin-vercel-builder@1.3.15
## 1.3.42
### Patch Changes
- Add `ignorePackageJsonScript` configuration for Framework command settings to ignore the `package.json` script. ([#10228](https://github.com/vercel/vercel/pull/10228))
Enable this mode for Storybook's `buildCommand`, since it should not invoke the "build" script, which is most likely designated for the frontend app build.
## 1.3.41
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/static-build",
"version": "1.3.41",
"version": "1.3.43",
"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.14"
"@vercel/gatsby-plugin-vercel-builder": "1.3.15"
},
"devDependencies": {
"@types/aws-lambda": "8.10.64",
@@ -34,8 +34,8 @@
"@types/semver": "7.3.13",
"@vercel/build-utils": "6.8.2",
"@vercel/error-utils": "1.0.10",
"@vercel/frameworks": "1.4.3",
"@vercel/fs-detectors": "4.1.0",
"@vercel/frameworks": "1.5.0",
"@vercel/fs-detectors": "4.1.1",
"@vercel/ncc": "0.24.0",
"@vercel/routing-utils": "2.2.1",
"@vercel/static-config": "2.0.17",

View File

@@ -137,7 +137,11 @@ function getCommand(
return propValue;
}
if (pkg) {
const ignorePackageJsonScript =
name === 'build' &&
framework?.settings.buildCommand.ignorePackageJsonScript;
if (pkg && !ignorePackageJsonScript) {
const scriptName = getScriptName(pkg, name, config);
if (hasScript(scriptName, pkg)) {

1230
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -11,14 +11,13 @@ module.exports = async ({ github, context }, newVersion) => {
const packagePath = path.join(repoRootPath, 'packages', 'remix');
const oldVersion = JSON.parse(
fs.readFileSync(path.join(packagePath, 'package.json'), 'utf-8')
).dependencies['@remix-run/dev'];
).devDependencies['@remix-run/dev'];
if (newVersion === '') {
newVersion = execSync('npm view @vercel/remix-run-dev dist-tags.latest', {
encoding: 'utf-8',
});
}
newVersion = newVersion.trim();
const branch = `vercel-remix-run-dev-${newVersion.replaceAll('.', '-')}`;
if (oldVersion === newVersion) {
// eslint-disable-next-line no-console
@@ -28,6 +27,7 @@ module.exports = async ({ github, context }, newVersion) => {
return;
}
const branch = `vercel-remix-run-dev-${newVersion.replaceAll('.', '-')}`;
if (
execSync(`git ls-remote --heads origin ${branch}`, { encoding: 'utf-8' })
.toString()
@@ -39,7 +39,7 @@ module.exports = async ({ github, context }, newVersion) => {
}
execSync(
`pnpm install @remix-run/dev@npm:@vercel/remix-run-dev@${newVersion} --save-exact --lockfile-only`,
`pnpm install @remix-run/dev@npm:@vercel/remix-run-dev@${newVersion} --save-exact --save-dev --lockfile-only`,
{ cwd: packagePath }
);