Compare commits

..

96 Commits

Author SHA1 Message Date
Vercel Release Bot
6d312d85b2 Version Packages (#10542)
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@32.3.0

### Minor Changes

- [cli] Support northstar users
([#10535](https://github.com/vercel/vercel/pull/10535))

### Patch Changes

- Internal variants
([#10549](https://github.com/vercel/vercel/pull/10549))

- [speed insights] Prepare for migration to new speed insights package
([#10500](https://github.com/vercel/vercel/pull/10500))

- Updated dependencies
\[[`b0898a665`](b0898a6659),
[`10d4e51ac`](10d4e51ac5),
[`decdf27fb`](decdf27fb5),
[`f5ca497b7`](f5ca497b75),
[`ab329f0fe`](ab329f0fe8),
[`d0d052011`](d0d0520111),
[`9bb3067de`](9bb3067de2)]:
    -   @vercel/static-build@2.0.7
    -   @vercel/node@3.0.6
    -   @vercel/build-utils@7.2.1
    -   @vercel/next@4.0.7
    -   @vercel/python@4.0.2
    -   @vercel/redwood@2.0.3
    -   @vercel/remix-builder@2.0.7
    -   @vercel/go@3.0.2

## @vercel/edge@1.1.0

### Minor Changes

- Add flag to geolocation
([#10443](https://github.com/vercel/vercel/pull/10443))

    Usage

        const { flag } = geolocation(req)

## @vercel/build-utils@7.2.1

### Patch Changes

- Internal variants
([#10549](https://github.com/vercel/vercel/pull/10549))

## @vercel/client@13.0.4

### Patch Changes

- Updated dependencies
\[[`decdf27fb`](decdf27fb5)]:
    -   @vercel/build-utils@7.2.1

## @vercel/gatsby-plugin-vercel-analytics@1.0.11

### Patch Changes

- Remove "babel" compilation
([#10546](https://github.com/vercel/vercel/pull/10546))

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

### Patch Changes

- Use "esbuild" to build package
([#10508](https://github.com/vercel/vercel/pull/10508))

- Updated dependencies
\[[`decdf27fb`](decdf27fb5)]:
    -   @vercel/build-utils@7.2.1

## @vercel/go@3.0.2

### Patch Changes

- Add support for Go v1.21.0
([#10552](https://github.com/vercel/vercel/pull/10552))

## @vercel/next@4.0.7

### Patch Changes

- Internal variants
([#10549](https://github.com/vercel/vercel/pull/10549))

- Update `@vercel/nft` to v0.24.1.
([#10540](https://github.com/vercel/vercel/pull/10540))

- Build package using "esbuild"
([#10482](https://github.com/vercel/vercel/pull/10482))

## @vercel/node@3.0.6

### Patch Changes

- Use "esbuild" to build package
([#10553](https://github.com/vercel/vercel/pull/10553))

- Update `@vercel/nft` to v0.24.1.
([#10540](https://github.com/vercel/vercel/pull/10540))

- Updated dependencies
\[[`decdf27fb`](decdf27fb5)]:
    -   @vercel/build-utils@7.2.1

## @vercel/python@4.0.2

### Patch Changes

- Fix docs URL in error message
([#10544](https://github.com/vercel/vercel/pull/10544))

## @vercel/redwood@2.0.3

### Patch Changes

- Update `@vercel/nft` to v0.24.1.
([#10540](https://github.com/vercel/vercel/pull/10540))

## @vercel/remix-builder@2.0.7

### Patch Changes

- Update `@vercel/nft` to v0.24.1.
([#10540](https://github.com/vercel/vercel/pull/10540))

## @vercel/static-build@2.0.7

### Patch Changes

- Mark `@vercel/static-config` and `ts-morph` as externals
([#10543](https://github.com/vercel/vercel/pull/10543))

- Updated dependencies
\[[`4b376a564`](4b376a564a),
[`b8bc682d3`](b8bc682d3e)]:
    -   @vercel/gatsby-plugin-vercel-builder@2.0.6
    -   @vercel/gatsby-plugin-vercel-analytics@1.0.11

## @vercel-internals/types@1.0.11

### Patch Changes

- Updated dependencies
\[[`decdf27fb`](decdf27fb5)]:
    -   @vercel/build-utils@7.2.1

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-09-21 11:59:12 -06:00
Nathan Rajlich
10d4e51ac5 [node] Use "esbuild" to build package (#10553) 2023-09-20 18:35:57 -03:00
Tobias Lins
57231a0d60 [speed insights] Prepare for migration to new speed insights package (#10500)
During `vc build` do following when `@vercel/speed-insights` package is in dependencies:
- Show a warning when `VERCEL_ANALYTICS_ID` is set in environment variables
- Unset it in process.env to prevent auto-injecting old speed insights in Next.js

Durning `vc env pull` prevent pulling internal environment variables `VERCEL_ANALYTICS_ID`, `VERCEL_SPEED_INSIGHTS_ID` & `VERCEL_WEB_ANALYTICS_ID`. They are never required in the frontend
2023-09-20 21:06:12 +00:00
Vercel Release Bot
e0e9cffc8d [examples][tests] Upgrade Next.js to version 13.5.2 (#10554)
This auto-generated PR updates 4 packages to Next.js version 13.5.2
2023-09-20 20:19:36 +00:00
Nathan Rajlich
d0d0520111 [next] Use "esbuild" to build package (#10482)
### Before

```
$ time pnpm run build

> @vercel/next@4.0.6 build /Users/nrajlich/Code/vercel/vercel/packages/next
> node build.js

ncc: Version 0.24.0
ncc: Compiling file index.js
ncc: Using typescript@4.9.5 (local user-provided)
1506kB  dist/main/index.js
1506kB  [3345ms] - ncc 0.24.0

real    0m5.210s
user    0m9.083s
sys     0m0.506s

$ ls -l dist/
total 1700
-rw-r--r-- 1 nrajlich staff    2176 Sep 20 15:18 ___get-nextjs-edge-function.js
-rw-r--r-- 1 nrajlich staff    3283 Sep 20 15:18 create-serverless-config.js
drwxr-xr-x 6 nrajlich staff     192 Sep 20 15:18 edge-function-source/
-rw-r--r-- 1 nrajlich staff 1542314 Sep 20 15:18 index.js
-rw-r--r-- 1 nrajlich staff     728 Sep 20 15:18 legacy-launcher.js
-rw-r--r-- 1 nrajlich staff    6807 Sep 20 15:18 legacy-versions.js
-rw-r--r-- 1 nrajlich staff   66662 Sep 20 15:18 server-build.js
-rw-r--r-- 1 nrajlich staff    1583 Sep 20 15:18 server-launcher.js
-rw-r--r-- 1 nrajlich staff    5167 Sep 20 15:18 sourcemapped.js
-rw-r--r-- 1 nrajlich staff    1003 Sep 20 15:18 templated-launcher-shared.js
-rw-r--r-- 1 nrajlich staff     799 Sep 20 15:18 templated-launcher.js
-rw-r--r-- 1 nrajlich staff   83876 Sep 20 15:18 utils.js

$ pnpm pack && ls -lh vercel-next-4.0.6.tgz 
-rw-r--r-- 1 nrajlich staff 373K Sep 20 15:19 vercel-next-4.0.6.tgz
```

### After

```
$ time pnpm run build

> @vercel/next@4.0.6 build /Users/nrajlich/Code/vercel/vercel/packages/next
> node build.mjs

real    0m1.144s
user    0m0.550s
sys     0m0.171s

$ ls -l dist/
total 540
-rw-r--r-- 1 nrajlich staff   2176 Sep 20 15:15 ___get-nextjs-edge-function.js
-rw-r--r-- 1 nrajlich staff 528575 Sep 20 15:15 index.js
-rw-r--r-- 1 nrajlich staff   1680 Sep 20 15:15 legacy-launcher.js
-rw-r--r-- 1 nrajlich staff    901 Sep 20 15:15 server-launcher.js
-rw-r--r-- 1 nrajlich staff    532 Sep 20 15:15 templated-launcher-shared.js
-rw-r--r-- 1 nrajlich staff    316 Sep 20 15:15 templated-launcher.js

$ pnpm pack && ls -lh vercel-next-4.0.6.tgz 
-rw-r--r-- 1 nrajlich staff 104K Sep 20 15:15 vercel-next-4.0.6.tgz
```
2023-09-20 20:01:03 +00:00
Ethan Arrowood
9bb3067de2 [go] add support for Go 1.21.0 (#10552)
as titled

updates a test to check for runtime version

---------

Co-authored-by: Nathan Rajlich <n@n8.io>
2023-09-20 12:30:38 -06:00
Andy
decdf27fb5 [cli][next][build-utils] Variants (#10549)
Co-authored-by: Ethan Arrowood <ethan.arrowood@vercel.com>
2023-09-20 19:42:20 +02:00
Nathan Rajlich
4b376a564a [gatsby-plugin-vercel-builder] Use "esbuild" to build package (#10508)
Removes the two-staged `tsc` build into a single `esbuild` bundle. The `ssr-handler.ts` template file is moved to the root of the package and converted to JavaScript.
2023-09-20 13:26:31 +00:00
Shu Uesugi
b7e93524e3 [cli] Support northstar users (#10535)
Supports users who have `version === 'northstar'` and `defaultTeamId`.
2023-09-19 21:45:42 +00:00
Paul Scanlon
62283356b8 feat: add flag to geolocation (#10443)
Co-authored-by: Chris Barber <chris.barber@vercel.com>
2023-09-19 16:25:46 -05:00
Vercel Release Bot
3305f5e832 [examples][tests] Upgrade Next.js to version 13.5.1 (#10545)
This auto-generated PR updates 4 packages to Next.js version 13.5.1
2023-09-19 21:06:40 +00:00
Jiachi Liu
a938706916 update code owners for nextjs example (#10548)
Add @huozhi to nextjs example code owners

---------

Co-authored-by: Steven <steven@ceriously.com>
2023-09-19 17:01:13 -04:00
Nathan Rajlich
b8bc682d3e [gatsby-plugin-vercel-analytics] Remove "babel" compilation (#10546)
The "babel" build for this package essentially does nothing. The output is still using ESM and no transformation is done. Let's just remove the "build" script entirely.
2023-09-19 20:45:26 +00:00
Nathan Rajlich
f5ca497b75 [python] Fix docs URL in error message (#10544) 2023-09-19 18:07:43 +00:00
Nathan Rajlich
b0898a6659 [static-build] Mark @vercel/static-config and ts-morph as externals (#10543)
To be consistent with the other packages that use `@vercel/static-config`/`ts-morph`, move these packages to "dependencies" so that they will be excluded from the bundle, and de-duped at the `node_modules` level when installing CLI.
2023-09-19 17:47:05 +00:00
Chris Barber
ab329f0fe8 [next][node][redwood][remix] Update @vercel/nft (#10540)
Updating `nft` to fix a bug. We're a couple version behind. Here's all cumulative changes:

- 0.24.1
  - resolve cjs deps as cjs instead of esm
- 0.24.0
  - drop node@14 
- 0.23.1
  - use builtinModules from module
- 0.23.0
  - resolve: export resolve() function
- 0.22.6
  - Make caching work correctly in async context
2023-09-19 14:27:54 +00:00
Nathan Rajlich
8b35333446 [examples] Update "remix" template to v2 (#10532) 2023-09-18 16:32:30 -03:00
Vercel Release Bot
a92467719b Version Packages (#10528)
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@32.2.5

### Patch Changes

- Updated dependencies
\[[`849eedf0f`](849eedf0f2),
[`f6f16b034`](f6f16b0347),
[`3035e18fb`](3035e18fb6),
[`cb784aeb9`](cb784aeb9c)]:
    -   @vercel/next@4.0.6
    -   @vercel/remix-builder@2.0.6

## @vercel/next@4.0.6

### Patch Changes

- Fix feature flag detection
([#10531](https://github.com/vercel/vercel/pull/10531))

## @vercel/remix-builder@2.0.6

### Patch Changes

- Fix ESM mode for Edge runtime
([#10530](https://github.com/vercel/vercel/pull/10530))

- Update `@remix-run/dev` fork to v2.0.0
([#10526](https://github.com/vercel/vercel/pull/10526))

- Fixes for Remix v2
([#10525](https://github.com/vercel/vercel/pull/10525))
2023-09-18 15:44:07 -03:00
Nathan Rajlich
f6f16b0347 [remix] Fix ESM mode for Edge runtime, add Remix v2 E2E test (#10530)
Similar to the default import fix from #10525 which was for Node runtime, but this one fixes Edge runtime.

Also adds an E2E test for Remix v2, including both a Node route and Edge route.
2023-09-18 18:26:53 +00:00
Trek Glowacki
92ad73b8f3 Restore datadog checking with logs not exit codes (#10527)
Restores DataDog flakey test detection. Briefly disabled because the old method of using exit codes would bail the entire workflow.

Taking the Turbo team's suggestion of looking at `runData.execution` values to avoid an extra loop. Now with unit tests!
2023-09-18 16:43:16 +00:00
Steven
849eedf0f2 [next] fix feature flag detection (#10531)
For feature flags, we use the string `1` for enabled and the string `0` for disabled.

So we need to check the value of the env var, not the presence of the env var.
2023-09-18 16:17:55 +00:00
Vercel Release Bot
848a62e4a5 [tests] Upgrade Turbo to version 1.10.14 (#10529)
This auto-generated PR updates Turbo to version 1.10.14
2023-09-18 15:31:52 +00:00
Nathan Rajlich
cb784aeb9c [remix] Fixes for Remix v2 (#10525)
The Remix v2 template now uses `"type": "module"` by default, so adjust our bundling logic to account for that possibility.
2023-09-18 14:32:08 +00:00
Vercel Release Bot
3035e18fb6 [remix] Update @remix-run/dev to v2.0.0 (#10526)
This auto-generated PR updates `@remix-run/dev` to version 2.0.0.
2023-09-18 14:05:42 +00:00
Vercel Release Bot
eb40c4c4a0 Version Packages (#10514)
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/fs-detectors@5.1.0

### Minor Changes

- Add support for bun detection in monorepo
([#10511](https://github.com/vercel/vercel/pull/10511))

## vercel@32.2.4

### Patch Changes

- Add support for bun detection in monorepo
([#10511](https://github.com/vercel/vercel/pull/10511))

- Updated dependencies
\[[`1b6f3a0f6`](1b6f3a0f65)]:
    -   @vercel/static-build@2.0.6

## @vercel/static-build@2.0.6

### Patch Changes

- Add support for bun detection in monorepo
([#10511](https://github.com/vercel/vercel/pull/10511))

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-09-15 15:13:54 -04:00
Nathan Rajlich
c90ee12b17 Update bun changeset to bump static-build + CLI (#10516)
Also reverts https://github.com/vercel/vercel/pull/10515 since it didn't
work the way we were hoping.
2023-09-15 16:06:32 -03:00
Nathan Rajlich
78be0200b4 Enable changesets experimental updateInternalDependents: 'always' config (#10515)
From the [sounds of
it](https://github.com/changesets/changesets/blob/main/docs/experimental-options.md#updateinternaldependents-type-out-of-range--always),
setting this config value to "always" will make it so that a patch
release will happen for a package that depends on another package which
is being bumped. This would normally happen anyways, but does not happen
when a dependency is a `devDependency` rather than a `dependency` (which
happens for the Builders and CLI, since those packages get bundled and
thus have their deps listed as devDependencies).
2023-09-15 15:54:47 -03:00
Steven
1b6f3a0f65 [fs-detectors] Add support for bun detection in monorepo (#10511)
E2E test looks like:

```sh
bunx create-turbo@canary
cd my-turborepo
gh repo create
vc link --repo
vc deploy
```
2023-09-15 14:13:26 -04:00
Trek Glowacki
eceb15ace9 Revert skipping datadog reports (#10513)
Revert
[.github/workflows/test.yml](https://github.com/vercel/vercel/pull/10513/files#diff-faff1af3d8ff408964a57b2e475f69a6b7c7b71c9978cccc8f471798caac2c88)
to an earlier version.
2023-09-15 13:49:24 -04:00
Vercel Release Bot
fa3f701e05 Version Packages (#10505)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-09-14 16:06:33 -05:00
Trek Glowacki
9953fc765f Complete the error message (#10509) 2023-09-14 11:39:53 -05:00
Trek Glowacki
29ea1af971 Skip DataDog reporting if Turbo cache indicates the uploaded files would be identical (#10501) 2023-09-14 10:47:20 -05:00
Zack Tanner
083aad448e [next] missed a prerender for experimentalBypassFor (#10504)
Missed this in https://github.com/vercel/vercel/pull/10497
2023-09-14 01:19:13 +00:00
Vercel Release Bot
314a105ba1 Version Packages (#10493)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-09-13 17:15:29 -05:00
Ikko Eltociear Ashimine
1abda9ca87 [cli] Fix typo in corepack.ts (#10499)
Co-authored-by: Sean Massa <EndangeredMassa@gmail.com>
2023-09-13 08:26:51 -05:00
Zack Tanner
7a0fed970c [next] provide experimentalBypassFor to prerender from manifest (#10497) 2023-09-12 17:40:49 -05:00
Jimmy Lai
2f461a8b0b next.js: add option to use bundled runtime (#10485)
This PR adds an environment variable that should allow us to test the bundled version for Next.js on Vercel, see https://github.com/vercel/next.js/pull/52997 for reference.

The changes include:
- a new environment variable `VERCEL_NEXT_BUNDLED_SERVER`
- some logic changes that will put app route handlers into their own lambda groups
- extra logic to require early the rendering runtimes (see PR above for details)
2023-09-12 19:45:23 +00:00
Steven
ec894bdf7f [frameworks] Add bun install placeholder (#10492)
<img width="899" alt="image"
src="https://github.com/vercel/vercel/assets/229881/f37a3cfd-bbb9-4c33-88dc-cd19b9855a47">
2023-09-12 11:29:24 -04:00
Andy
009cea6d30 [examples] Use placeholder for API Key (#10490)
The Ionic example has an actual Google Maps API key by default and we'd
like to not have it displayed, so we'll replace it with a placeholder
instead. Considering it's commented out anyways, this will be a no-op.

---------

Co-authored-by: Steven <steven@ceriously.com>
2023-09-12 11:25:02 -04:00
Nathan Rajlich
1bab21026e [remix] Fix usage with bun install (#10489) 2023-09-12 09:55:16 -05:00
Vercel Release Bot
bcebab7517 Version Packages (#10478)
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @vercel/build-utils@7.2.0

### Minor Changes

- Add new optional prerender field: experimentalStreamingLambdaPath
([#10476](https://github.com/vercel/vercel/pull/10476))

- [build-utils] Add zero config detection for bun package manager
([#10486](https://github.com/vercel/vercel/pull/10486))

### Patch Changes

- add `experimentalBypassFor` field to Prerender
([#10481](https://github.com/vercel/vercel/pull/10481))

## vercel@32.2.1

### Patch Changes

- Update @vercel/fun@1.1.0
([#10477](https://github.com/vercel/vercel/pull/10477))

- [node] upgrade edge-runtime
([#10451](https://github.com/vercel/vercel/pull/10451))

- Updated dependencies
\[[`6784e7751`](6784e77516),
[`a8ad17626`](a8ad176262),
[`0ee089a50`](0ee089a501),
[`f15cba614`](f15cba6148),
[`b265e13d4`](b265e13d40),
[`50e04dd85`](50e04dd858),
[`45b73c7e8`](45b73c7e86),
[`a732d30c8`](a732d30c84),
[`9d64312aa`](9d64312aaa),
[`6baefc825`](6baefc825a),
[`989f0d813`](989f0d8139),
[`d8bc570f6`](d8bc570f60)]:
    -   @vercel/go@3.0.1
    -   @vercel/redwood@2.0.2
    -   @vercel/remix-builder@2.0.4
    -   @vercel/hydrogen@1.0.1
    -   @vercel/static-build@2.0.5
    -   @vercel/build-utils@7.2.0
    -   @vercel/next@4.0.3
    -   @vercel/node@3.0.5
    -   @vercel/python@4.0.1
    -   @vercel/ruby@2.0.2

## @vercel/client@13.0.3

### Patch Changes

- Updated dependencies
\[[`50e04dd85`](50e04dd858),
[`45b73c7e8`](45b73c7e86),
[`d8bc570f6`](d8bc570f60)]:
    -   @vercel/build-utils@7.2.0

## @vercel/edge@1.0.2

### Patch Changes

- [node] upgrade edge-runtime
([#10451](https://github.com/vercel/vercel/pull/10451))

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

### Patch Changes

- Updated dependencies
\[[`50e04dd85`](50e04dd858),
[`45b73c7e8`](45b73c7e86),
[`9d64312aa`](9d64312aaa),
[`d8bc570f6`](d8bc570f60)]:
    -   @vercel/build-utils@7.2.0
    -   @vercel/node@3.0.5

## @vercel/go@3.0.1

### Patch Changes

- Update to esbuild script
([#10468](https://github.com/vercel/vercel/pull/10468))

## @vercel/hydrogen@1.0.1

### Patch Changes

- Use `build-builder.mjs` script to bundle, and remove types and source
maps ([#10480](https://github.com/vercel/vercel/pull/10480))

## @vercel/next@4.0.3

### Patch Changes

- fix content-type for RSC prefetches
([#10487](https://github.com/vercel/vercel/pull/10487))

## @vercel/node@3.0.5

### Patch Changes

- [node] upgrade edge-runtime
([#10451](https://github.com/vercel/vercel/pull/10451))

- Updated dependencies
\[[`50e04dd85`](50e04dd858),
[`45b73c7e8`](45b73c7e86),
[`d8bc570f6`](d8bc570f60)]:
    -   @vercel/build-utils@7.2.0

## @vercel/python@4.0.1

### Patch Changes

- Update to esbuild script
([#10470](https://github.com/vercel/vercel/pull/10470))

## @vercel/redwood@2.0.2

### Patch Changes

- Update to esbuild script
([#10471](https://github.com/vercel/vercel/pull/10471))

## @vercel/remix-builder@2.0.4

### Patch Changes

- Use `build-builder.mjs` script to bundle, and remove types and source
maps ([#10479](https://github.com/vercel/vercel/pull/10479))

## @vercel/ruby@2.0.2

### Patch Changes

- Update to esbuild script
([#10472](https://github.com/vercel/vercel/pull/10472))

## @vercel/static-build@2.0.5

### Patch Changes

- Build package using "esbuild"
([#10462](https://github.com/vercel/vercel/pull/10462))

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

## @vercel-internals/types@1.0.10

### Patch Changes

- Updated dependencies
\[[`50e04dd85`](50e04dd858),
[`45b73c7e8`](45b73c7e86),
[`d8bc570f6`](d8bc570f60)]:
    -   @vercel/build-utils@7.2.0

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-09-11 17:30:02 -04:00
Steven
45b73c7e86 [build-utils] Add zero config detection for bun package manager (#10486)
> [!IMPORTANT]  
> This PR will only support Bun as a package manager at build time. 
> Bun will **not** work at runtime with Serverless Functions or Edge
Functions at this time.

- Depends on https://github.com/vercel/api/pull/21869
- Fixes https://github.com/orgs/vercel/discussions/2021
- Closes https://github.com/vercel/vercel/pull/10244
- Related https://github.com/nodejs/corepack/issues/295
- Docs https://bun.sh/docs/install
2023-09-11 17:26:34 -04:00
Zack Tanner
a732d30c84 [next] fix content-type for RSC prefetches (#10487)
This ensures that the `.prefetch.rsc` requests respond with the correct `content-type` since this is used by Next.js to determine if a request is valid or not (and in the case it's invalid, an mpa navigation will occur)

Fixes: https://github.com/vercel/next.js/issues/54934
2023-09-11 19:04:16 +00:00
Lee Robinson
8504735808 [examples] Update Astro starter (#10397)
Deployed https://astro.vercel.app/image.
2023-09-11 16:29:54 +00:00
Kiko Beats
9d64312aaa [node] upgrade edge-runtime (#10451) 2023-09-10 13:14:43 +00:00
Chris Barber
a8ad176262 [redwood] Use new esbuild script (#10471) 2023-09-09 01:48:54 +00:00
Nathan Rajlich
0ee089a501 [remix] Bundle, remove types and source maps (#10479)
For consistency with other Builders.
2023-09-09 00:35:56 +00:00
Zack Tanner
d8bc570f60 [build-utils] add experimentalBypassFor field to Prerender (#10481)
This adds an experimental flag to `Prerender` outputs as a way to programmatically bypass the cache and hit the lambda directly, using a similar interface to `has`. 

(Note: I copied over `HasField` from `@vercel/router-utils` since it wasn't available for import in `build-utils`, but can add it as a dep if that's preferred)

The specific use-case being targeted here relates to https://github.com/vercel/next.js/pull/51534 -- a Next.js page marked static should still be able to initiate server actions.
2023-09-08 23:33:59 +00:00
Nathan Rajlich
f15cba6148 [hydrogen] Bundle, remove types and source maps (#10480)
Similar to #10479, but for `@vercel/hydrogen`.
2023-09-08 22:55:03 +00:00
Chris Barber
989f0d8139 [ruby] Use new esbuild script (#10472) 2023-09-08 17:27:17 -05:00
Chris Barber
6784e77516 [go] Update to esbuild script (#10468)
Co-authored-by: Nathan Rajlich <n@n8.io>
2023-09-08 17:00:40 -05:00
Chris Barber
6baefc825a [python] Update to esbuild script (#10470)
Co-authored-by: Steven <steven@ceriously.com>
2023-09-08 16:23:23 -05:00
Chris Barber
0a08e4b23e [cli] Update @vercel/fun@1.1.0 (#10477) 2023-09-08 15:39:13 -05:00
Nathan Rajlich
b265e13d40 [static-build] Use esbuild (#10462)
Switch to using esbuild to compile + bundle `@vercel/static-build`.
2023-09-08 19:39:12 +00:00
Nabeel Sulieman
50e04dd858 Add optional experimentalStreamingLambda field for prerender (#10476)
This adds a new `experimentalStreamingLambda` field to Prerender
outputs, allowing references to an optional streaming lambda path.
2023-09-08 11:42:06 -07:00
Vercel Release Bot
82231058da Version Packages (#10400)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-09-08 11:41:32 -05:00
Steven
61227bf7e3 fix .changeset/nice-lies-sip.md (#10474)
I think we need to remove `api` since its private so its not published to npm and therefore isn't versioned.
2023-09-08 02:09:11 +00:00
Zack Tanner
6aa0aa4e65 [next] fix ENOENT on /404.html when fallback: false w/ basePath (#10473)
The following error occurs during build when `basePath` is present in conjunction with `fallback: false` in `getStaticPaths`:

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

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

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

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

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

---

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

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

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

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

Before:
<img width="813" alt="CleanShot 2023-08-31 at 11 40 06@2x" src="https://github.com/vercel/vercel/assets/9736/731626a0-86f0-446d-8f77-436205acac87">
2023-09-05 21:11:03 +00:00
Vercel Release Bot
d7db0c5794 [tests] Upgrade Turbo to version 1.10.13 (#10404)
This auto-generated PR updates Turbo to version 1.10.13
2023-09-05 20:28:17 +00:00
Sean Massa
e90e922ee8 migrate dev command structure for help output (#10433)
Migrates the `vc git` command to the command data structure for use in the help output.

---

<img width="1891" alt="Screenshot 2023-08-31 at 1 35 07 PM" src="https://github.com/vercel/vercel/assets/41545/d3d63faa-9427-49e8-8137-a76d4c208cb3">
2023-09-05 19:51:44 +00:00
Trek Glowacki
adb9ac87ce [cli] Remove mri workaround (#10452)
As of https://github.com/vercel/vercel/pull/10389 the `mri` package is no longer used and this workaround can be removed.
2023-09-05 16:17:18 +00:00
Steven
e43191b186 [next] fix 404 enoent for i18n (#10416)
This PR fixes the following error:

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


https://github.com/vercel/vercel/actions/runs/6030773334/job/16364078054?pr=10415#step:9:1352
2023-09-01 10:39:52 -04:00
Dan Stowell
a962e84409 migrate env to command structure (#10429)
Migrates the `vc env` command to the command data structure for use in the help output.
2023-08-31 23:10:28 +00:00
Trek Glowacki
7593e219fd [cli] Update project command to new structure (#10432)
Before:
<img width="687" alt="CleanShot 2023-08-31 at 13 29 29@2x" src="https://github.com/vercel/vercel/assets/9736/87e0f445-701a-4851-b73f-c787db01abe3">

After:
<img width="868" alt="CleanShot 2023-08-31 at 13 31 50@2x" src="https://github.com/vercel/vercel/assets/9736/b6820654-3254-4a65-820a-30ff7b577a44">
2023-08-31 22:45:44 +00:00
Dan Stowell
ec95066689 migrate vc secrets to help command structure (#10435) 2023-08-31 15:17:51 -07:00
Sean Massa
42a71416b9 migrate init command structure for help output (#10428)
Migrates the `vc init` command to the command data structure for use in the help output.

---

<img width="1891" alt="Screenshot 2023-08-31 at 11 36 37 AM" src="https://github.com/vercel/vercel/assets/41545/1caeb203-470f-49a5-86b2-273b04bc0489">
2023-08-31 21:48:09 +00:00
Sean Massa
80af30ce60 migrate git command structure for help output (#10431) 2023-08-31 16:02:49 -05:00
Sean Massa
74a15b5f32 migrate rollback command structure for help output (#10426)
Migrates the `vc rollback` command to the command data structure for use in the help output.

---

<img width="1891" alt="Screenshot 2023-08-31 at 11 25 49 AM" src="https://github.com/vercel/vercel/assets/41545/a6d802ac-3851-4641-b950-764fc65fa9d2">
2023-08-31 19:09:59 +00:00
Sean Massa
c0416f7e95 migrate promote command structure for help output (#10425)
Migrates the `vc promote` command to the command data structure for use in the help output.

---

<img width="1878" alt="Screenshot 2023-08-31 at 11 04 32 AM" src="https://github.com/vercel/vercel/assets/41545/b79c6aec-af03-4685-8ee4-9c0d89b2f236">
2023-08-31 18:41:55 +00:00
Kiko Beats
fc1e13c099 fix: remove console.log (#10417) 2023-08-31 16:34:27 +02:00
Nathan Rajlich
0e9ec194a3 Keep vercel@canary up to date with vercel@latest (#10410) 2023-08-28 22:50:30 -07:00
Sean Massa
5609a1187b [build-utils] add descriptions to NodeVersion properties (#10403) 2023-08-26 19:49:47 -05:00
Sean Massa
cff72e3129 [examples] fix redwood template and update examples to use at least node@16 (#10395)
The redwood template was broken because it would use node@18, which is not supported for the version of redwood used in the template. This PR updates that version to be node@16, which does work.

While we're at it, I also updated other examples to be at least node@16. I tested deployments of each of these and the all work.
2023-08-25 15:01:55 +00:00
Vercel Release Bot
d3c84e5d2a Version Packages (#10398)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-08-24 16:04:39 -05:00
Andrew Barba
9e3827c785 [build-utils] Support serverless function architecture (#10392)
# Problem

Framework authors often produce build outputs from platforms like Github
Actions or M1 Macs where the arm64 architecture is being used. They then
deploy these outputs to Vercel using `vercel deploy`, bypassing Vercel's
build system. Today they must cross compile to x86_64 in order to deploy
compatible Serverless functions to Vercel.

# Solution

Allow Framework authors to detect the current architecture and specify
either x86_64 or arm64 when deploying a Serverless function to Vercel.

# Related PRs

https://github.com/vercel/api/pull/21559

https://github.com/vercel/proxy/pull/6901

https://github.com/vercel/front/pull/24924
2023-08-24 16:44:30 -04:00
Trek Glowacki
fb6d77afac [cli] Improve error messages for JSON parse issues (#10396) 2023-08-24 15:09:13 -05:00
Vercel Release Bot
cfc1bb180b Version Packages (#10384)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-08-24 13:56:29 -05:00
Trek Glowacki
f06776468f [cli] Remove mri package (#10389)
`vc secrets` appears to be mostly deprecated but this was a fairly straightforward change that lets us drop `mri` today. Tested pretty extensively locally.
2023-08-24 18:05:11 +00:00
Kiko Beats
597a8a8176 upgrade edge-runtime (#10385) 2023-08-24 16:52:49 +02:00
Kiko Beats
3f6d99470d [node] use undici instead of node-fetch (#10387) 2023-08-24 10:06:33 +02:00
JJ Kasper
4422326865 Add handling to leverage RSC prefetch outputs (#10390)
Implements handling for the RSC prefetch outputs when available that
were added in https://github.com/vercel/next.js/pull/54403
2023-08-23 22:26:58 -07:00
Zack Tanner
09446a8fe8 [next] fix RSC matching behavior & 404 status code on fallback: false (#10388)
Fixes two separate issues for the Next builder:

- `pages` routes unexpectedly matching to RSC routes when prefetching from `app`. This update will attempt to match the route with the corresponding `pages` entry rather than falling back to a catch-all RSC
  - Fixes https://github.com/vercel/next.js/issues/53776
- `fallback: false` returning a successful status code when underlying page as a param (e.g. `/blog/[slug]` would 200 but `/blog/non-existent` would 404)
  - [slack x-ref](https://vercel.slack.com/archives/C03S8ED1DKM/p1692817762403579)
2023-08-23 22:30:33 +00:00
Vercel Release Bot
37e93a91a8 [remix] Update @remix-run/dev to v1.19.3 (#10381)
This auto-generated PR updates `@remix-run/dev` to version 1.19.3.
2023-08-22 20:49:48 +00:00
Trek Glowacki
eec6e47232 [cli] Update dns commands to new structure (#10379)
Before:
<img width="795" alt="CleanShot 2023-08-22 at 10 46 34@2x" src="https://github.com/vercel/vercel/assets/9736/456faef8-6335-46ac-89ae-5ce13db4568e">


After:
<img width="815" alt="CleanShot 2023-08-22 at 10 48 04@2x" src="https://github.com/vercel/vercel/assets/9736/e78a9cc5-d9e9-4079-bd4a-81cd68917127">
2023-08-22 20:24:19 +00:00
312 changed files with 10795 additions and 3917 deletions

4
.github/CODEOWNERS vendored
View File

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

View File

@@ -83,7 +83,7 @@ jobs:
env:
FORCE_COLOR: '1'
- name: Test ${{matrix.packageName}}
run: node utils/gen.js && node_modules/.bin/turbo run test --cache-dir=".turbo" --log-order=stream --scope=${{matrix.packageName}} --no-deps -- ${{ join(matrix.testPaths, ' ') }}
run: node utils/gen.js && node_modules/.bin/turbo run test --summarize --cache-dir=".turbo" --log-order=stream --scope=${{matrix.packageName}} --no-deps -- ${{ join(matrix.testPaths, ' ') }}
shell: bash
env:
JEST_JUNIT_OUTPUT_FILE: ${{github.workspace}}/.junit-reports/${{matrix.scriptName}}-${{matrix.packageName}}-${{matrix.chunkNumber}}-${{ matrix.runner }}.xml
@@ -91,13 +91,18 @@ jobs:
VERCEL_TEST_TOKEN: ${{ secrets.VERCEL_TEST_TOKEN }}
VERCEL_TEST_REGISTRATION_URL: ${{ secrets.VERCEL_TEST_REGISTRATION_URL }}
FORCE_COLOR: '1'
- name: 'Determing Turbo HIT or MISS'
id: turbo-summary
shell: bash
run: |
TURBO_MISS_COUNT=`node utils/determine-turbo-hit-or-miss.js`
echo "MISS COUNT: $TURBO_MISS_COUNT"
echo "misses=$TURBO_MISS_COUNT" >> $GITHUB_OUTPUT
- name: fetch ssl certificate after tests (linux, os x)
if: matrix.runner != 'windows-latest'
run: echo | openssl s_client -showcerts -servername 'api.vercel.com' -connect 76.76.21.21:443
- name: 'Upload Test Report to Datadog'
if: always()
if: ${{ steps['turbo-summary'].outputs.misses != '0' }}
run: 'npx @datadog/datadog-ci@2.18.1 junit upload --service vercel-cli .junit-reports'
env:
DATADOG_API_KEY: ${{secrets.DATADOG_API_KEY_CLI}}

7
api/CHANGELOG.md Normal file
View File

@@ -0,0 +1,7 @@
# api
## 0.0.1
### Patch Changes
- fix RSC matching behavior & 404 status code on `fallback: false` ([#10388](https://github.com/vercel/vercel/pull/10388))

View File

@@ -1,7 +1,7 @@
{
"name": "api",
"private": true,
"version": "0.0.0",
"version": "0.0.1",
"description": "API for the vercel/vercel repo",
"main": "index.js",
"scripts": {},

7
examples/CHANGELOG.md vendored Normal file
View File

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

View File

@@ -3,9 +3,10 @@
This directory is a brief example of an [Astro](https://astro.build/) site that can be deployed to Vercel with zero configuration. This demo showcases:
- `/` - A static page (pre-rendered)
- `/ssr` - A page that uses server-side rendering (through Vercel Edge Functions)
- `/ssr-with-swr-caching` - Similar to the previous page, but also caches the response on the Vercel Edge Network using `cache-control` headers
- `/edge.json` - An Astro API Endpoint that returns JSON data using Vercel Edge Functions
- `/ssr` - A page that uses server-side rendering (through [Vercel Edge Functions](https://vercel.com/docs/functions/edge-functions))
- `/ssr-with-swr-caching` - Similar to the previous page, but also caches the response on the [Vercel Edge Network](https://vercel.com/docs/edge-network/overview) using `cache-control` headers
- `/image` - Astro [Asset](https://docs.astro.build/en/guides/assets/) using Vercel [Image Optimization](https://vercel.com/docs/image-optimization)
- `/edge.json` - An Astro API Endpoint that returns JSON data using [Vercel Edge Functions](https://vercel.com/docs/functions/edge-functions)
Learn more about [Astro on Vercel](https://vercel.com/docs/frameworks/astro).

View File

@@ -1,7 +1,17 @@
import { defineConfig } from 'astro/config';
// Use Vercel Edge Functions (Recommended)
import vercel from '@astrojs/vercel/edge';
// Can also use Serverless Functions
// import vercel from '@astrojs/vercel/serverless';
// Or a completely static build
// import vercel from '@astrojs/vercel/static';
export default defineConfig({
output: 'server',
adapter: vercel(),
experimental: {
assets: true
},
adapter: vercel({
imageService: true,
}),
});

View File

@@ -8,8 +8,8 @@
"astro": "astro"
},
"dependencies": {
"@astrojs/vercel": "3.2.2",
"astro": "^2.2.1",
"@astrojs/vercel": "3.8.2",
"astro": "^2.10.14",
"react": "18.2.0",
"web-vitals": "^3.3.1"
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -1,4 +1,4 @@
/// <reference types="astro/client" />
/// <reference types="astro/client-image" />
interface ImportMetaEnv {
readonly PUBLIC_VERCEL_ANALYTICS_ID: string;

View File

@@ -0,0 +1,6 @@
---
import { Image } from 'astro:assets';
import astroLogo from '../assets/logo.png';
---
<Image src={astroLogo} alt="Astro Logo" width={50} quality={75} />

View File

@@ -29,7 +29,7 @@
<!-- Replace the API key with your own, see:
https://developers.google.com/maps/documentation/javascript/get-api-key -->
<!-- <script async="" defer="" src="https://maps.googleapis.com/maps/api/js?key=AIzaSyB8pf6ZdFQj5qw7rc_HSGrhUwQKfIe9ICw"></script> -->
<!-- <script async="" defer="" src="https://maps.googleapis.com/maps/api/js?key=<YOUR_GOOGLE_MAPS_API_KEY>"></script> -->
<noscript>Please enable JavaScript to continue using this application.</noscript>
</body>

View File

@@ -10,6 +10,8 @@ npm run dev
yarn dev
# or
pnpm dev
# or
bun dev
```
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.

File diff suppressed because it is too large Load Diff

View File

@@ -9,17 +9,17 @@
"lint": "next lint"
},
"dependencies": {
"@types/node": "20.5.1",
"@types/react": "18.2.20",
"@types/node": "20.6.3",
"@types/react": "18.2.22",
"@types/react-dom": "18.2.7",
"autoprefixer": "10.4.15",
"eslint": "8.47.0",
"eslint-config-next": "13.4.19",
"next": "13.4.19",
"postcss": "8.4.28",
"eslint": "8.49.0",
"eslint-config-next": "13.5.2",
"next": "13.5.2",
"postcss": "8.4.30",
"react": "18.2.0",
"react-dom": "18.2.0",
"tailwindcss": "3.3.3",
"typescript": "5.1.6"
"typescript": "5.2.2"
}
}

View File

@@ -9,6 +9,7 @@
},
"devDependencies": {
"@types/jest": "27.4.1",
"@vercel/frameworks": "2.0.1"
}
"@vercel/frameworks": "2.0.2"
},
"version": null
}

View File

@@ -30,6 +30,6 @@
"wct-browser-legacy": "^1.0.0"
},
"engines": {
"node": ">=8.0"
"node": ">=16.0"
}
}

View File

@@ -14,7 +14,7 @@
"extends": "@redwoodjs/eslint-config"
},
"engines": {
"node": ">=12",
"node": "16.x",
"yarn": ">=1.15"
}
}

View File

@@ -4,9 +4,4 @@ node_modules
/build
/public/build
.env
.vercel
.output
/api/index.js
/api/index.js.map

View File

@@ -19,7 +19,7 @@ export default function App() {
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<Meta />
<Links />
</head>

View File

@@ -1,10 +1,15 @@
import type { V2_MetaFunction } from "@vercel/remix";
import type { MetaFunction } from "@vercel/remix";
export const meta: V2_MetaFunction = () => [{ title: "New Remix App" }];
export const meta: MetaFunction = () => {
return [
{ title: "New Remix App" },
{ name: "description", content: "Welcome to Remix!" },
];
};
export default function Index() {
return (
<div style={{ fontFamily: "system-ui, sans-serif", lineHeight: "1.4" }}>
<div style={{ fontFamily: "system-ui, sans-serif", lineHeight: "1.8" }}>
<h1>Welcome to Remix</h1>
<ul>
<li>

View File

@@ -1,8 +1,8 @@
import type { V2_MetaFunction } from "@vercel/remix";
import type { MetaFunction } from "@vercel/remix";
export const config = { runtime: "edge" };
export const meta: V2_MetaFunction = () => [{ title: "Remix@Edge | New Remix App" }];
export const meta: MetaFunction = () => [{ title: "Remix@Edge | New Remix App" }];
export default function Edge() {
return (

View File

@@ -1,32 +1,34 @@
{
"name": "my-remix-app",
"private": true,
"sideEffects": false,
"type": "module",
"scripts": {
"build": "remix build",
"dev": "remix dev",
"start": "remix-serve build",
"dev": "remix dev --manual",
"start": "remix-serve ./build/index.js",
"typecheck": "tsc"
},
"dependencies": {
"@remix-run/css-bundle": "^1.18.0",
"@remix-run/node": "^1.18.0",
"@remix-run/react": "^1.18.0",
"@remix-run/serve": "^1.18.0",
"@vercel/analytics": "^0.1.11",
"@vercel/remix": "^1.18.0",
"@remix-run/css-bundle": "^2.0.0",
"@remix-run/node": "^2.0.0",
"@remix-run/react": "^2.0.0",
"@remix-run/serve": "^2.0.0",
"@vercel/analytics": "^1.0.2",
"@vercel/remix": "^2.0.0",
"isbot": "^3.6.8",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@remix-run/dev": "^1.18.0",
"@remix-run/eslint-config": "^1.18.0",
"@types/react": "^18.0.25",
"@types/react-dom": "^18.0.11",
"eslint": "^8.28.0",
"typescript": "^5.1.3"
"@remix-run/dev": "^2.0.0",
"@remix-run/eslint-config": "^2.0.0",
"@types/react": "^18.2.20",
"@types/react-dom": "^18.2.7",
"eslint": "^8.38.0",
"typescript": "^5.1.6"
},
"engines": {
"node": ">=14"
"node": ">=18.0.0"
}
}

View File

@@ -1,17 +1,8 @@
/** @type {import('@remix-run/dev').AppConfig} */
module.exports = {
future: {
v2_dev: true,
v2_errorBoundary: true,
v2_headers: true,
v2_meta: true,
v2_normalizeFormMethod: true,
v2_routeConvention: true,
},
export default {
ignoredRouteFiles: ["**/.*"],
serverModuleFormat: "cjs",
// appDirectory: "app",
// assetsBuildDirectory: "public/build",
// serverBuildPath: "build/index.js",
// publicPath: "/build/",
// serverBuildPath: "build/index.js",
};

View File

@@ -1,13 +1,13 @@
{
"include": ["remix.env.d.ts", "**/*.ts", "**/*.tsx"],
"compilerOptions": {
"lib": ["DOM", "DOM.Iterable", "ES2019"],
"lib": ["DOM", "DOM.Iterable", "ES2022"],
"isolatedModules": true,
"esModuleInterop": true,
"jsx": "react-jsx",
"moduleResolution": "node",
"moduleResolution": "Bundler",
"resolveJsonModule": true,
"target": "ES2019",
"target": "ES2022",
"strict": true,
"allowJs": true,
"forceConsistentCasingInFileNames": true,

View File

@@ -46,6 +46,6 @@
]
},
"engines": {
"node": ">=8.0.0 <17"
"node": "16.x"
}
}

View File

@@ -5,7 +5,7 @@
"build": "vuepress build src"
},
"engines": {
"node": ">=14.0.0 <18.0.0"
"node": ">=16.0.0 <18.0.0"
},
"devDependencies": {
"vuepress": "1.9.7"

View File

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

View File

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

View File

@@ -1,5 +1,33 @@
# @vercel-internals/types
## 1.0.11
### Patch Changes
- Updated dependencies [[`decdf27fb`](https://github.com/vercel/vercel/commit/decdf27fb5ca914fe50a9320c4fd50ef79d2fbb3)]:
- @vercel/build-utils@7.2.1
## 1.0.10
### Patch Changes
- Updated dependencies [[`50e04dd85`](https://github.com/vercel/vercel/commit/50e04dd8584664c842a86c15d92d654f4ea8dcbb), [`45b73c7e8`](https://github.com/vercel/vercel/commit/45b73c7e86458564dc0bab007f6f6365c4c4ab5d), [`d8bc570f6`](https://github.com/vercel/vercel/commit/d8bc570f604950d97156d4f33c8accecf3b3b28f)]:
- @vercel/build-utils@7.2.0
## 1.0.9
### Patch Changes
- Updated dependencies [[`5609a1187`](https://github.com/vercel/vercel/commit/5609a1187be9d6cf8d5f16825690c5ea72f17dc5), [`1b4de4a98`](https://github.com/vercel/vercel/commit/1b4de4a986f7a612aac834ebae3ec7bb9e9b8cf8)]:
- @vercel/build-utils@7.1.1
## 1.0.8
### Patch Changes
- Updated dependencies [[`9e3827c78`](https://github.com/vercel/vercel/commit/9e3827c785e1bc45f2bed421132167381481770f)]:
- @vercel/build-utils@7.1.0
## 1.0.7
### Patch Changes

View File

@@ -65,6 +65,8 @@ export type User = {
billing: Billing;
name?: string;
limited?: boolean;
version?: 'northstar';
defaultTeamId?: string;
};
export interface Team {

View File

@@ -1,7 +1,7 @@
{
"private": true,
"name": "@vercel-internals/types",
"version": "1.0.7",
"version": "1.0.11",
"types": "index.d.ts",
"main": "index.d.ts",
"files": [
@@ -10,7 +10,7 @@
"dependencies": {
"@types/node": "14.14.31",
"@vercel-internals/constants": "1.0.4",
"@vercel/build-utils": "7.0.0",
"@vercel/build-utils": "7.2.1",
"@vercel/routing-utils": "3.0.0"
},
"devDependencies": {

View File

@@ -16,6 +16,7 @@
"buffer-replace": "1.0.0",
"create-svelte": "2.0.1",
"dot": "1.1.3",
"esbuild": "0.19.2",
"eslint": "8.14.0",
"eslint-config-prettier": "8.5.0",
"eslint-plugin-jest": "26.1.5",
@@ -32,7 +33,7 @@
"source-map-support": "0.5.12",
"ts-eager": "2.0.2",
"ts-jest": "29.1.0",
"turbo": "1.10.12",
"turbo": "1.10.14",
"typescript": "4.9.5"
},
"scripts": {
@@ -49,7 +50,7 @@
"prepare": "husky install",
"pack": "cd utils && node -r ts-eager/register ./pack.ts",
"ci:version": "changeset version && pnpm install --no-frozen-lockfile",
"ci:publish": "pnpm publish -r && changeset tag"
"ci:publish": "pnpm publish -r && node utils/update-canary-tags.mjs && changeset tag"
},
"lint-staged": {
"./{*,{api,packages,test,utils}/**/*}.{js,ts}": [

View File

@@ -1,5 +1,37 @@
# @vercel/build-utils
## 7.2.1
### Patch Changes
- Internal variants ([#10549](https://github.com/vercel/vercel/pull/10549))
## 7.2.0
### Minor Changes
- Add new optional prerender field: experimentalStreamingLambdaPath ([#10476](https://github.com/vercel/vercel/pull/10476))
- [build-utils] Add zero config detection for bun package manager ([#10486](https://github.com/vercel/vercel/pull/10486))
### Patch Changes
- add `experimentalBypassFor` field to Prerender ([#10481](https://github.com/vercel/vercel/pull/10481))
## 7.1.1
### Patch Changes
- add descriptions to NodeVersion properties ([#10403](https://github.com/vercel/vercel/pull/10403))
- Updated semver dependency ([#10411](https://github.com/vercel/vercel/pull/10411))
## 7.1.0
### Minor Changes
- Support serverless function architecture ([#10392](https://github.com/vercel/vercel/pull/10392))
## 7.0.0
### Major Changes

View File

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

View File

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

View File

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

View File

@@ -16,7 +16,7 @@ import { cloneEnv } from '../clone-env';
// Only allow one `runNpmInstall()` invocation to run concurrently
const runNpmInstallSema = new Sema(1);
export type CliType = 'yarn' | 'npm' | 'pnpm';
export type CliType = 'yarn' | 'npm' | 'pnpm' | 'bun';
export interface ScanParentDirsResult {
/**
@@ -284,26 +284,34 @@ export async function scanParentDirs(
readPackageJson && pkgJsonPath
? JSON.parse(await fs.readFile(pkgJsonPath, 'utf8'))
: undefined;
const [yarnLockPath, npmLockPath, pnpmLockPath] = await walkParentDirsMulti({
base: '/',
start: destPath,
filenames: ['yarn.lock', 'package-lock.json', 'pnpm-lock.yaml'],
});
const [yarnLockPath, npmLockPath, pnpmLockPath, bunLockPath] =
await walkParentDirsMulti({
base: '/',
start: destPath,
filenames: [
'yarn.lock',
'package-lock.json',
'pnpm-lock.yaml',
'bun.lockb',
],
});
let lockfilePath: string | undefined;
let lockfileVersion: number | undefined;
let cliType: CliType = 'yarn';
const [hasYarnLock, packageLockJson, pnpmLockYaml] = await Promise.all([
Boolean(yarnLockPath),
npmLockPath
? readConfigFile<{ lockfileVersion: number }>(npmLockPath)
: null,
pnpmLockPath
? readConfigFile<{ lockfileVersion: number }>(pnpmLockPath)
: null,
]);
const [hasYarnLock, packageLockJson, pnpmLockYaml, bunLockBin] =
await Promise.all([
Boolean(yarnLockPath),
npmLockPath
? readConfigFile<{ lockfileVersion: number }>(npmLockPath)
: null,
pnpmLockPath
? readConfigFile<{ lockfileVersion: number }>(pnpmLockPath)
: null,
bunLockPath ? fs.readFile(bunLockPath, 'utf8') : null,
]);
// Priority order is Yarn > pnpm > npm
// Priority order is Yarn > pnpm > npm > bun
if (hasYarnLock) {
cliType = 'yarn';
lockfilePath = yarnLockPath;
@@ -315,6 +323,11 @@ export async function scanParentDirs(
cliType = 'npm';
lockfilePath = npmLockPath;
lockfileVersion = packageLockJson.lockfileVersion;
} else if (bunLockBin) {
cliType = 'bun';
lockfilePath = bunLockPath;
// TODO: read "bun-lockfile-format-v0"
lockfileVersion = 0;
}
const packageJsonPath = pkgJsonPath || undefined;
@@ -451,6 +464,10 @@ export async function runNpmInstall(
commandArgs = args
.filter(a => a !== '--prefer-offline')
.concat(['install', '--unsafe-perm']);
} else if (cliType === 'bun') {
// @see options https://bun.sh/docs/cli/install
opts.prettyCommand = 'bun install';
commandArgs = ['install', ...args];
} else {
opts.prettyCommand = 'yarn install';
commandArgs = ['install', ...args];
@@ -505,6 +522,7 @@ export function getEnvForPackageManager({
const npm7 = '/node16/bin-npm7';
const pnpm7 = '/pnpm7/node_modules/.bin';
const pnpm8 = '/pnpm8/node_modules/.bin';
const bun1 = '/bun1';
const corepackEnabled = env.ENABLE_EXPERIMENTAL_COREPACK === '1';
if (cliType === 'npm') {
if (
@@ -516,7 +534,7 @@ export function getEnvForPackageManager({
) {
// Ensure that npm 7 is at the beginning of the `$PATH`
newEnv.PATH = `${npm7}${path.delimiter}${oldPath}`;
console.log('Detected `package-lock.json` generated by npm 7+...');
console.log('Detected `package-lock.json` generated by npm 7+');
}
} else if (cliType === 'pnpm') {
if (
@@ -528,7 +546,7 @@ export function getEnvForPackageManager({
// Ensure that pnpm 7 is at the beginning of the `$PATH`
newEnv.PATH = `${pnpm7}${path.delimiter}${oldPath}`;
console.log(
`Detected \`pnpm-lock.yaml\` version ${lockfileVersion} generated by pnpm 7...`
`Detected \`pnpm-lock.yaml\` version ${lockfileVersion} generated by pnpm 7`
);
} else if (
typeof lockfileVersion === 'number' &&
@@ -539,7 +557,16 @@ export function getEnvForPackageManager({
// Ensure that pnpm 8 is at the beginning of the `$PATH`
newEnv.PATH = `${pnpm8}${path.delimiter}${oldPath}`;
console.log(
`Detected \`pnpm-lock.yaml\` version ${lockfileVersion} generated by pnpm 8...`
`Detected \`pnpm-lock.yaml\` version ${lockfileVersion} generated by pnpm 8`
);
}
} else if (cliType === 'bun') {
if (!oldPath.includes(bun1) && !corepackEnabled) {
// Ensure that Bun 1 is at the beginning of the `$PATH`
newEnv.PATH = `${bun1}${path.delimiter}${oldPath}`;
console.log('Detected `bun.lockb` generated by Bun');
console.warn(
'Warning: Bun is used as a package manager at build time only, not at runtime with Functions'
);
}
} else {
@@ -548,7 +575,6 @@ export function getEnvForPackageManager({
newEnv.YARN_NODE_LINKER = 'node-modules';
}
}
return newEnv;
}
@@ -614,6 +640,8 @@ export async function runPackageJsonScript(
opts.prettyCommand = `npm run ${scriptName}`;
} else if (cliType === 'pnpm') {
opts.prettyCommand = `pnpm run ${scriptName}`;
} else if (cliType === 'bun') {
opts.prettyCommand = `bun run ${scriptName}`;
} else {
opts.prettyCommand = `yarn run ${scriptName}`;
}

View File

@@ -13,9 +13,12 @@ interface Environment {
export type LambdaOptions = LambdaOptionsWithFiles | LambdaOptionsWithZipBuffer;
export type LambdaArchitecture = 'x86_64' | 'arm64';
export interface LambdaOptionsBase {
handler: string;
runtime: string;
architecture?: LambdaArchitecture;
memory?: number;
maxDuration?: number;
environment?: Environment;
@@ -62,6 +65,7 @@ export class Lambda {
files?: Files;
handler: string;
runtime: string;
architecture?: LambdaArchitecture;
memory?: number;
maxDuration?: number;
environment: Environment;
@@ -81,6 +85,7 @@ export class Lambda {
handler,
runtime,
maxDuration,
architecture,
memory,
environment = {},
allowQuery,
@@ -102,6 +107,13 @@ export class Lambda {
assert(typeof runtime === 'string', '"runtime" is not a string');
assert(typeof environment === 'object', '"environment" is not an object');
if (architecture !== undefined) {
assert(
architecture === 'x86_64' || architecture === 'arm64',
'"architecture" must be either "x86_64" or "arm64"'
);
}
if (memory !== undefined) {
assert(typeof memory === 'number', '"memory" is not a number');
}
@@ -159,6 +171,7 @@ export class Lambda {
this.files = 'files' in opts ? opts.files : undefined;
this.handler = handler;
this.runtime = runtime;
this.architecture = architecture;
this.memory = memory;
this.maxDuration = maxDuration;
this.environment = environment;

View File

@@ -1,4 +1,4 @@
import { File } from './types';
import type { File, HasField } from './types';
import { Lambda } from './lambda';
interface PrerenderOptions {
@@ -12,6 +12,8 @@ interface PrerenderOptions {
initialStatus?: number;
passQuery?: boolean;
sourcePath?: string;
experimentalBypassFor?: HasField;
experimentalStreamingLambdaPath?: string;
}
export class Prerender {
@@ -26,6 +28,8 @@ export class Prerender {
public initialStatus?: number;
public passQuery?: boolean;
public sourcePath?: string;
public experimentalBypassFor?: HasField;
public experimentalStreamingLambdaPath?: string;
constructor({
expiration,
@@ -38,6 +42,8 @@ export class Prerender {
initialStatus,
passQuery,
sourcePath,
experimentalBypassFor,
experimentalStreamingLambdaPath,
}: PrerenderOptions) {
this.type = 'Prerender';
this.expiration = expiration;
@@ -86,6 +92,26 @@ export class Prerender {
);
}
if (experimentalBypassFor !== undefined) {
if (
!Array.isArray(experimentalBypassFor) ||
experimentalBypassFor.some(
field =>
typeof field !== 'object' ||
// host doesn't need a key
(field.type !== 'host' && typeof field.key !== 'string') ||
typeof field.type !== 'string' ||
(field.value !== undefined && typeof field.value !== 'string')
)
) {
throw new Error(
'The `experimentalBypassFor` argument for `Prerender` must be Array of objects with fields `type`, `key` and optionally `value`.'
);
}
this.experimentalBypassFor = experimentalBypassFor;
}
if (typeof fallback === 'undefined') {
throw new Error(
'The `fallback` argument for `Prerender` needs to be a `FileBlob`, `FileFsRef`, `FileRef`, or null.'
@@ -130,5 +156,14 @@ export class Prerender {
}
this.allowQuery = allowQuery;
}
if (experimentalStreamingLambdaPath !== undefined) {
if (typeof experimentalStreamingLambdaPath !== 'string') {
throw new Error(
'The `experimentalStreamingLambdaPath` argument for `Prerender` must be a string.'
);
}
this.experimentalStreamingLambdaPath = experimentalStreamingLambdaPath;
}
}
}

View File

@@ -45,6 +45,18 @@ export interface Config {
[key: string]: unknown;
}
export type HasField = Array<
| {
type: 'host';
value: string;
}
| {
type: 'header' | 'cookie' | 'query';
key: string;
value?: string;
}
>;
export interface Meta {
isDev?: boolean;
devCacheDir?: string;
@@ -300,9 +312,13 @@ export interface PackageJson {
}
export interface NodeVersion {
/** major version number: 18 */
major: number;
/** major version range: "18.x" */
range: string;
/** runtime descriptor: "nodejs18.x" */
runtime: string;
/** date beyond which this version is discontinued: 2023-08-17T19:05:45.951Z */
discontinueDate?: Date;
}
@@ -418,6 +434,13 @@ export interface Cron {
schedule: string;
}
// TODO: Proper description once complete
export interface Flag {
key: string;
defaultValue?: unknown;
metadata: Record<string, unknown>;
}
/** The framework which created the function */
export interface FunctionFramework {
slug: string;
@@ -442,6 +465,7 @@ export interface BuildResultV2Typical {
framework?: {
version: string;
};
flags?: Flag[];
}
export type BuildResultV2 = BuildResultV2Typical | BuildResultBuildOutput;

View File

@@ -0,0 +1,2 @@
.vercel
public

View File

@@ -0,0 +1,8 @@
import { mkdir, rm, writeFile } from 'node:fs/promises'
import { say } from 'cowsay'
const text = say({ text: `bun version: ${process.versions.bun}` })
const content = say({ text })
await rm('./public', { recursive: true, force: true })
await mkdir('./public', { recursive: true })
await writeFile('./public/index.txt', content)

Binary file not shown.

View File

@@ -0,0 +1,9 @@
{
"private": true,
"scripts": {
"build": "bun build.js"
},
"dependencies": {
"cowsay": "1.5.0"
}
}

View File

@@ -0,0 +1,8 @@
{
"probes": [
{
"path": "/",
"mustContain": "bun version: 1"
}
]
}

View File

@@ -133,6 +133,22 @@ describe('Test `getEnvForPackageManager()`', () => {
PATH: `/pnpm7/node_modules/.bin${delimiter}foo`,
},
},
{
name: 'should set path if bun v1 is detected',
args: {
cliType: 'bun',
nodeVersion: { major: 18, range: '18.x', runtime: 'nodejs18.x' },
lockfileVersion: 0,
env: {
FOO: 'bar',
PATH: '/usr/local/bin',
},
},
want: {
FOO: 'bar',
PATH: `/bun1${delimiter}/usr/local/bin`,
},
},
{
name: 'should not set pnpm path if corepack is enabled',
args: {

View File

@@ -344,6 +344,70 @@ it('should support initialHeaders and initialStatus correctly', async () => {
});
});
it('should support experimentalBypassFor correctly', async () => {
new Prerender({
expiration: 1,
fallback: null,
group: 1,
bypassToken: 'some-long-bypass-token-to-make-it-work',
experimentalBypassFor: [{ type: 'header', key: 'Next-Action' }],
});
new Prerender({
expiration: 1,
fallback: null,
group: 1,
bypassToken: 'some-long-bypass-token-to-make-it-work',
experimentalBypassFor: [
{ type: 'header', key: 'Next-Action' },
{
type: 'cookie',
key: '__prerender_bypass',
value: 'some-long-bypass-token-to-make-it-work',
},
],
});
new Prerender({
expiration: 1,
fallback: null,
group: 1,
bypassToken: 'some-long-bypass-token-to-make-it-work',
experimentalBypassFor: [{ type: 'query', key: 'bypass', value: '1' }],
});
new Prerender({
expiration: 1,
fallback: null,
group: 1,
bypassToken: 'some-long-bypass-token-to-make-it-work',
experimentalBypassFor: [{ type: 'host', value: 'vercel.com' }],
});
expect(() => {
new Prerender({
expiration: 1,
fallback: null,
group: 1,
bypassToken: 'some-long-bypass-token-to-make-it-work',
// @ts-expect-error: testing invalid args
experimentalBypassFor: 'foo',
});
}).toThrowError(
'The `experimentalBypassFor` argument for `Prerender` must be Array of objects with fields `type`, `key` and optionally `value`.'
);
expect(() => {
new Prerender({
expiration: 1,
fallback: null,
group: 1,
bypassToken: 'some-long-bypass-token-to-make-it-work',
// @ts-expect-error: testing invalid args
experimentalBypassFor: [{ type: 'header', value: { foo: 'bar' } }],
});
}).toThrowError(
'The `experimentalBypassFor` argument for `Prerender` must be Array of objects with fields `type`, `key` and optionally `value`.'
);
});
it('should support passQuery correctly', async () => {
new Prerender({
expiration: 1,
@@ -387,6 +451,42 @@ it('should support passQuery correctly', async () => {
);
});
it('should support experimentalStreamingLambdaPath correctly', async () => {
new Prerender({
expiration: 1,
fallback: null,
group: 1,
bypassToken: 'some-long-bypass-token-to-make-it-work',
experimentalStreamingLambdaPath: undefined,
});
new Prerender({
expiration: 1,
fallback: null,
group: 1,
bypassToken: 'some-long-bypass-token-to-make-it-work',
experimentalStreamingLambdaPath: '/some/path/to/lambda',
});
new Prerender({
expiration: 1,
fallback: null,
group: 1,
bypassToken: 'some-long-bypass-token-to-make-it-work',
});
expect(() => {
new Prerender({
expiration: 1,
fallback: null,
group: 1,
bypassToken: 'some-long-bypass-token-to-make-it-work',
// @ts-expect-error testing invalid field
experimentalStreamingLambdaPath: 1,
});
}).toThrowError(
`The \`experimentalStreamingLambdaPath\` argument for \`Prerender\` must be a string.`
);
});
it('should support require by path for legacy builders', () => {
const index = require('../');
@@ -440,6 +540,15 @@ it(
ms('1m')
);
it('should return cliType bun and correct lock file for bun v1', async () => {
const fixture = path.join(__dirname, 'fixtures', '30-bun-v1');
const result = await scanParentDirs(fixture);
expect(result.cliType).toEqual('bun');
expect(result.lockfileVersion).toEqual(0);
expect(result.lockfilePath).toEqual(path.join(fixture, 'bun.lockb'));
expect(result.packageJsonPath).toEqual(path.join(fixture, 'package.json'));
});
it('should return lockfileVersion 2 with npm7', async () => {
const fixture = path.join(__dirname, 'fixtures', '20-npm-7');
const result = await scanParentDirs(fixture);

View File

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

View File

@@ -1,5 +1,156 @@
# vercel
## 32.3.0
### Minor Changes
- [cli] Support northstar users ([#10535](https://github.com/vercel/vercel/pull/10535))
### Patch Changes
- Internal variants ([#10549](https://github.com/vercel/vercel/pull/10549))
- [speed insights] Prepare for migration to new speed insights package ([#10500](https://github.com/vercel/vercel/pull/10500))
- Updated dependencies [[`b0898a665`](https://github.com/vercel/vercel/commit/b0898a66591d5296dc38ffcf0e8345c9338b72f3), [`10d4e51ac`](https://github.com/vercel/vercel/commit/10d4e51ac57b76f05ddc0bf3adf220e2490244fc), [`decdf27fb`](https://github.com/vercel/vercel/commit/decdf27fb5ca914fe50a9320c4fd50ef79d2fbb3), [`f5ca497b7`](https://github.com/vercel/vercel/commit/f5ca497b7522a2dad637cef238da9716ac133057), [`ab329f0fe`](https://github.com/vercel/vercel/commit/ab329f0fe88e9cb72607d0cba41f5e168d77e077), [`d0d052011`](https://github.com/vercel/vercel/commit/d0d0520111264434d57d5920de0f622f6a2588dc), [`9bb3067de`](https://github.com/vercel/vercel/commit/9bb3067de28be77f3ce268a31a7aa6184836dfb1)]:
- @vercel/static-build@2.0.7
- @vercel/node@3.0.6
- @vercel/build-utils@7.2.1
- @vercel/next@4.0.7
- @vercel/python@4.0.2
- @vercel/redwood@2.0.3
- @vercel/remix-builder@2.0.7
- @vercel/go@3.0.2
## 32.2.5
### Patch Changes
- Updated dependencies [[`849eedf0f`](https://github.com/vercel/vercel/commit/849eedf0f2841211e4175d374f1cf01330bf9611), [`f6f16b034`](https://github.com/vercel/vercel/commit/f6f16b0347bac9f5c33c79ccb1fb9fd9d254cae5), [`3035e18fb`](https://github.com/vercel/vercel/commit/3035e18fb67dfe7031e235a74136a41948f86d5a), [`cb784aeb9`](https://github.com/vercel/vercel/commit/cb784aeb9c9e4eddf1c65b61849a87edb1117af1)]:
- @vercel/next@4.0.6
- @vercel/remix-builder@2.0.6
## 32.2.4
### Patch Changes
- Add support for bun detection in monorepo ([#10511](https://github.com/vercel/vercel/pull/10511))
- Updated dependencies [[`1b6f3a0f6`](https://github.com/vercel/vercel/commit/1b6f3a0f6534f71c7486a4e33ac199f1da330626)]:
- @vercel/static-build@2.0.6
## 32.2.3
### Patch Changes
- Updated dependencies [[`083aad448`](https://github.com/vercel/vercel/commit/083aad448e45edae296da3201eec9f890a01d22d)]:
- @vercel/next@4.0.5
## 32.2.2
### Patch Changes
- Updated dependencies [[`7a0fed970`](https://github.com/vercel/vercel/commit/7a0fed970c39cb8f4df70544ded3284d3538b06a), [`2f461a8b0`](https://github.com/vercel/vercel/commit/2f461a8b0bcbdd05da0516395c2905c2d0242682), [`1bab21026`](https://github.com/vercel/vercel/commit/1bab21026ec0bb8a4a8fbeac3d6e4a197f1030fd)]:
- @vercel/next@4.0.4
- @vercel/remix-builder@2.0.5
## 32.2.1
### Patch Changes
- Update @vercel/fun@1.1.0 ([#10477](https://github.com/vercel/vercel/pull/10477))
- [node] upgrade edge-runtime ([#10451](https://github.com/vercel/vercel/pull/10451))
- Updated dependencies [[`6784e7751`](https://github.com/vercel/vercel/commit/6784e77516ba180a691e3c48323b32bb4506d7b6), [`a8ad17626`](https://github.com/vercel/vercel/commit/a8ad176262ef822860ce338927e6f959961d2d32), [`0ee089a50`](https://github.com/vercel/vercel/commit/0ee089a501ebb78901c4afe1658e794917998f8f), [`f15cba614`](https://github.com/vercel/vercel/commit/f15cba6148a0cdb6975db7724775c35ab7d929b2), [`b265e13d4`](https://github.com/vercel/vercel/commit/b265e13d40d541b77148fa79ac60b4c4dd10974c), [`50e04dd85`](https://github.com/vercel/vercel/commit/50e04dd8584664c842a86c15d92d654f4ea8dcbb), [`45b73c7e8`](https://github.com/vercel/vercel/commit/45b73c7e86458564dc0bab007f6f6365c4c4ab5d), [`a732d30c8`](https://github.com/vercel/vercel/commit/a732d30c8409f96f59ea5406e974a6c4186cc130), [`9d64312aa`](https://github.com/vercel/vercel/commit/9d64312aaaa875a4e193b7602c50e5dc68979aad), [`6baefc825`](https://github.com/vercel/vercel/commit/6baefc825ad7cfc3a5edce31cb4244721452f753), [`989f0d813`](https://github.com/vercel/vercel/commit/989f0d813910d8d67ed355de93018f1dcd91b6ba), [`d8bc570f6`](https://github.com/vercel/vercel/commit/d8bc570f604950d97156d4f33c8accecf3b3b28f)]:
- @vercel/go@3.0.1
- @vercel/redwood@2.0.2
- @vercel/remix-builder@2.0.4
- @vercel/hydrogen@1.0.1
- @vercel/static-build@2.0.5
- @vercel/build-utils@7.2.0
- @vercel/next@4.0.3
- @vercel/node@3.0.5
- @vercel/python@4.0.1
- @vercel/ruby@2.0.2
## 32.2.0
### Minor Changes
- show instant preview url on deploy ([#10458](https://github.com/vercel/vercel/pull/10458))
### Patch Changes
- N, not n. ([#10460](https://github.com/vercel/vercel/pull/10460))
- Fix team URL on `vercel help switch` ([#10466](https://github.com/vercel/vercel/pull/10466))
- Migrates the vc env command to the command data structure for use in the help output. ([#10429](https://github.com/vercel/vercel/pull/10429))
- Update domains command to new structure ([#10427](https://github.com/vercel/vercel/pull/10427))
- Updated semver dependency ([#10411](https://github.com/vercel/vercel/pull/10411))
- migrate `rollback` command structure for help output ([#10426](https://github.com/vercel/vercel/pull/10426))
- migrate `inti` command structure for help output ([#10428](https://github.com/vercel/vercel/pull/10428))
- Remove mri workaround ([#10452](https://github.com/vercel/vercel/pull/10452))
- migrate dev command structure for help output ([#10433](https://github.com/vercel/vercel/pull/10433))
- Update secrets to more recent structure ([#10461](https://github.com/vercel/vercel/pull/10461))
- Migrate `vc secrets` to new help command structure ([#10435](https://github.com/vercel/vercel/pull/10435))
- migrate `promote` command structure for help output ([#10425](https://github.com/vercel/vercel/pull/10425))
- migrate `git` command structure for help output ([#10431](https://github.com/vercel/vercel/pull/10431))
- Update project command to new data structure ([#10432](https://github.com/vercel/vercel/pull/10432))
- migrate teams command ([#10434](https://github.com/vercel/vercel/pull/10434))
- Updated dependencies [[`5609a1187`](https://github.com/vercel/vercel/commit/5609a1187be9d6cf8d5f16825690c5ea72f17dc5), [`caaba0d68`](https://github.com/vercel/vercel/commit/caaba0d6855eff4350b6a04acc3ea502025bff8f), [`1b4de4a98`](https://github.com/vercel/vercel/commit/1b4de4a986f7a612aac834ebae3ec7bb9e9b8cf8), [`c3c54d6e6`](https://github.com/vercel/vercel/commit/c3c54d6e695ec078777c4b1f4f23acbeee3c3b09), [`6aa0aa4e6`](https://github.com/vercel/vercel/commit/6aa0aa4e65b81903f4fce677a198dcfaebee744b), [`e43191b18`](https://github.com/vercel/vercel/commit/e43191b1866da70a3dab3815a3f2176942240ef3), [`fc1e13c09`](https://github.com/vercel/vercel/commit/fc1e13c09928c654410b373fc1775c2b63c6ef4a)]:
- @vercel/build-utils@7.1.1
- @vercel/next@4.0.2
- @vercel/static-build@2.0.4
- @vercel/redwood@2.0.1
- @vercel/remix-builder@2.0.3
- @vercel/ruby@2.0.1
- @vercel/node@3.0.4
## 32.1.0
### Minor Changes
- Improve error messages for JSON parse failures ([#10396](https://github.com/vercel/vercel/pull/10396))
### Patch Changes
- Updated dependencies [[`9e3827c78`](https://github.com/vercel/vercel/commit/9e3827c785e1bc45f2bed421132167381481770f)]:
- @vercel/build-utils@7.1.0
- @vercel/node@3.0.3
- @vercel/remix-builder@2.0.2
- @vercel/static-build@2.0.3
## 32.0.2
### Patch Changes
- Remove use of mri preferring use of arg package ([#10389](https://github.com/vercel/vercel/pull/10389))
- upgrade edge-runtime ([#10385](https://github.com/vercel/vercel/pull/10385))
- Update dns commands to new structure ([#10379](https://github.com/vercel/vercel/pull/10379))
- Updated dependencies [[`09446a8fe`](https://github.com/vercel/vercel/commit/09446a8fe8b8201dbe3ead3ca645ef0aa1833b6b), [`597a8a817`](https://github.com/vercel/vercel/commit/597a8a81764c39e70c65b98e78bf4c3827a779a7), [`442232686`](https://github.com/vercel/vercel/commit/44223268651f1bbd5c6f2b0b315239685dd5716e), [`3f6d99470`](https://github.com/vercel/vercel/commit/3f6d99470db86681e006d66507f32afcea086b41), [`37e93a91a`](https://github.com/vercel/vercel/commit/37e93a91a8659934eac7f5cd441b310511bf5646)]:
- @vercel/next@4.0.1
- @vercel/node@3.0.2
- @vercel/remix-builder@2.0.1
- @vercel/static-build@2.0.2
## 32.0.1
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "vercel",
"version": "32.0.1",
"version": "32.3.0",
"preferGlobal": true,
"license": "Apache-2.0",
"description": "The command-line interface for Vercel",
@@ -31,20 +31,20 @@
"node": ">= 16"
},
"dependencies": {
"@vercel/build-utils": "7.0.0",
"@vercel/go": "3.0.0",
"@vercel/hydrogen": "1.0.0",
"@vercel/next": "4.0.0",
"@vercel/node": "3.0.1",
"@vercel/python": "4.0.0",
"@vercel/redwood": "2.0.0",
"@vercel/remix-builder": "2.0.0",
"@vercel/ruby": "2.0.0",
"@vercel/static-build": "2.0.1"
"@vercel/build-utils": "7.2.1",
"@vercel/go": "3.0.2",
"@vercel/hydrogen": "1.0.1",
"@vercel/next": "4.0.7",
"@vercel/node": "3.0.6",
"@vercel/python": "4.0.2",
"@vercel/redwood": "2.0.3",
"@vercel/remix-builder": "2.0.7",
"@vercel/ruby": "2.0.2",
"@vercel/static-build": "2.0.7"
},
"devDependencies": {
"@alex_neo/jest-expect-message": "1.0.5",
"@edge-runtime/node-utils": "2.1.0",
"@edge-runtime/node-utils": "2.2.1",
"@next/env": "11.1.2",
"@sentry/node": "5.5.0",
"@sindresorhus/slugify": "0.11.0",
@@ -64,10 +64,10 @@
"@types/inquirer": "7.3.1",
"@types/jest": "27.4.1",
"@types/jest-expect-message": "1.0.3",
"@types/json-parse-better-errors": "1.0.0",
"@types/load-json-file": "2.0.7",
"@types/mime-types": "2.1.0",
"@types/minimatch": "3.0.3",
"@types/mri": "1.1.0",
"@types/ms": "0.7.30",
"@types/node": "14.18.33",
"@types/node-fetch": "2.5.10",
@@ -86,12 +86,12 @@
"@types/yauzl-promise": "2.1.0",
"@vercel-internals/constants": "1.0.4",
"@vercel-internals/get-package-json": "1.0.0",
"@vercel-internals/types": "1.0.7",
"@vercel/client": "13.0.0",
"@vercel-internals/types": "1.0.11",
"@vercel/client": "13.0.4",
"@vercel/error-utils": "2.0.1",
"@vercel/frameworks": "2.0.1",
"@vercel/fs-detectors": "5.0.1",
"@vercel/fun": "1.0.4",
"@vercel/frameworks": "2.0.2",
"@vercel/fs-detectors": "5.1.0",
"@vercel/fun": "1.1.0",
"@vercel/ncc": "0.24.0",
"@vercel/routing-utils": "3.0.0",
"@zeit/source-map-support": "0.6.2",
@@ -136,12 +136,12 @@
"jaro-winkler": "0.2.8",
"jest-junit": "16.0.0",
"jest-matcher-utils": "29.3.1",
"json-parse-better-errors": "1.0.2",
"jsonlines": "0.1.1",
"line-async-iterator": "3.0.0",
"load-json-file": "3.0.0",
"mime-types": "2.1.24",
"minimatch": "3.1.2",
"mri": "1.1.5",
"ms": "2.1.2",
"node-fetch": "2.6.7",
"npm-package-arg": "6.1.0",
@@ -156,7 +156,7 @@
"qr-image": "3.2.0",
"raw-body": "2.4.1",
"rimraf": "3.0.2",
"semver": "5.5.0",
"semver": "5.7.2",
"serve-handler": "6.1.1",
"strip-ansi": "6.0.1",
"supports-hyperlinks": "3.0.0",

View File

@@ -27,7 +27,7 @@ export const help = () => `
pull [path] Pull your Project Settings from the cloud
redeploy [url|id] Rebuild and deploy a previous deployment.
rollback [url|id] Quickly revert back to a previous deployment
switch [scope] Switches between teams and your personal account
switch [scope] Switches between different scopes
${chalk.dim('Advanced')}

View File

@@ -21,6 +21,7 @@ import {
NowBuildError,
Cron,
validateNpmrc,
Flag,
} from '@vercel/build-utils';
import {
detectBuilders,
@@ -93,6 +94,7 @@ interface BuildOutputConfig {
version: string;
};
crons?: Cron[];
flags?: Flag[];
}
/**
@@ -426,6 +428,23 @@ async function doBuild(
const ops: Promise<Error | void>[] = [];
const dependencies = [
...Object.keys(pkg?.dependencies ?? {}),
...Object.keys(pkg?.devDependencies ?? {}),
];
const isUsingSpeedInsights = dependencies.some(
d => d === '@vercel/speed-insights'
);
if (isUsingSpeedInsights && process.env.VERCEL_ANALYTICS_ID) {
output.warn(
`The \`VERCEL_ANALYTICS_ID\` environment variable is deprecated and will be removed in a future release. Please remove it from your environment variables`
);
delete process.env.VERCEL_ANALYTICS_ID;
}
// Write the `detectedBuilders` result to output dir
const buildsJsonBuilds = new Map<Builder, SerializedBuilder>(
builds.map(build => {
@@ -627,6 +646,7 @@ async function doBuild(
const mergedWildcard = mergeWildcard(buildResults.values());
const mergedOverrides: Record<string, PathOverride> =
overrides.length > 0 ? Object.assign({}, ...overrides) : undefined;
const mergedFlags = mergeFlags(buildResults.values());
const framework = await getFramework(cwd, buildResults);
@@ -640,6 +660,7 @@ async function doBuild(
overrides: mergedOverrides,
framework,
crons: mergedCrons,
flags: mergedFlags,
};
await fs.writeJSON(join(outputDir, 'config.json'), config, { spaces: 2 });
@@ -774,3 +795,15 @@ function mergeWildcard(
}
return wildcard;
}
function mergeFlags(
buildResults: Iterable<BuildResult | BuildOutputConfig>
): BuildResultV2Typical['flags'] {
return Array.from(buildResults).flatMap(result => {
if ('flags' in result) {
return result.flags ?? [];
}
return [];
});
}

View File

@@ -0,0 +1,34 @@
import { Command } from '../help';
import { packageName } from '../../util/pkg-name';
export const devCommand: Command = {
name: 'dev',
description: `Starts the \`${packageName} dev\` server.`,
arguments: [
{
name: 'dir',
required: false,
},
],
options: [
{
name: 'listen',
description: 'Specify a URI endpoint on which to listen [0.0.0.0:3000]',
argument: 'uri',
shorthand: null,
type: 'string',
deprecated: false,
multi: false,
},
],
examples: [
{
name: `Start the \`${packageName} dev\` server on port 8080`,
value: `${packageName} dev --listen 8080`,
},
{
name: 'Make the `vercel dev` server bind to localhost on port 5000',
value: `${packageName} dev --listen 127.0.0.1:5000 `,
},
],
};

View File

@@ -12,43 +12,16 @@ import highlight from '../../util/output/highlight';
import dev from './dev';
import readConfig from '../../util/config/read-config';
import readJSONFile from '../../util/read-json-file';
import { packageName, getCommandName, logo } from '../../util/pkg-name';
import { packageName, getCommandName } from '../../util/pkg-name';
import { CantParseJSONFile } from '../../util/errors-ts';
import { isErrnoException } from '@vercel/error-utils';
import { help } from '../help';
import { devCommand } from './command';
const COMMAND_CONFIG = {
dev: ['dev'],
};
const help = () => {
console.log(`
${chalk.bold(`${logo} ${packageName} dev`)} [options] <dir>
Starts the \`${packageName} dev\` server.
${chalk.dim('Options:')}
-h, --help Output usage information
-d, --debug Debug mode [off]
--no-color No color mode [off]
-l, --listen [uri] Specify a URI endpoint on which to listen [0.0.0.0:3000]
-t, --token [token] Specify an Authorization Token
-y, --yes Skip questions when setting up new project using default scope and settings
${chalk.dim('Examples:')}
${chalk.gray('')} Start the \`${packageName} dev\` server on port 8080
${chalk.cyan(`$ ${packageName} dev --listen 8080`)}
${chalk.gray(
''
)} Make the \`vercel dev\` server bind to localhost on port 5000
${chalk.cyan(`$ ${packageName} dev --listen 127.0.0.1:5000`)}
`);
};
export default async function main(client: Client) {
if (process.env.__VERCEL_DEV_RUNNING) {
client.output.error(
@@ -100,7 +73,7 @@ export default async function main(client: Client) {
}
if (argv['--help']) {
help();
client.output.print(help(devCommand, { columns: client.stderr.columns }));
return 2;
}
@@ -118,7 +91,7 @@ export default async function main(client: Client) {
const pkg = await readJSONFile<PackageJson>(path.join(dir, 'package.json'));
if (pkg instanceof CantParseJSONFile) {
client.output.error('Could not parse package.json');
client.output.error(pkg.message);
return 1;
}

View File

@@ -0,0 +1,136 @@
import { Command } from '../help';
import { packageName } from '../../util/pkg-name';
export const dnsCommand: Command = {
name: 'dns',
description: 'Interact with DNS entries for a project.',
arguments: [
{
name: 'command',
required: true,
},
],
subcommands: [
{
name: 'import',
description: 'Import a DNS zone file (see below for examples)',
arguments: [
{
name: 'domain',
required: true,
},
{
name: 'zonefile',
required: true,
},
],
options: [],
examples: [],
},
{
name: 'ls',
description: 'List all DNS entries for a domain',
arguments: [
{
name: 'domain',
required: true,
},
],
options: [],
examples: [],
},
{
name: 'add',
description: 'Add a new DNS entry (see below for examples)',
arguments: [
{
name: 'details',
required: true,
},
{
name: 'alias',
required: true,
},
],
options: [],
examples: [],
},
{
name: 'rm',
description: 'Remove a DNS entry using its ID',
arguments: [
{
name: 'id',
required: true,
},
],
options: [],
examples: [],
},
],
options: [
{
name: 'next',
description: 'Show next page of results',
argument: 'MS',
shorthand: 'n',
type: 'string',
deprecated: false,
multi: false,
},
{
name: 'limit',
shorthand: 'n',
description:
'Number of results to return per page (default: 20, max: 100)',
argument: 'NUMBER',
type: 'string',
deprecated: false,
multi: false,
},
],
examples: [
{
name: 'Add an A record for a subdomain',
value: [
`${packageName} dns add <DOMAIN> <SUBDOMAIN> <A | AAAA | ALIAS | CNAME | TXT> <VALUE>`,
`${packageName} dns add zeit.rocks api A 198.51.100.100`,
],
},
{
name: 'Add an MX record (@ as a name refers to the domain)',
value: [
`${packageName} dns add <DOMAIN> '@' MX <RECORD VALUE> <PRIORITY>`,
`${packageName} dns add zeit.rocks '@' MX mail.zeit.rocks 10`,
],
},
{
name: 'Add an SRV record',
value: [
`${packageName} dns add <DOMAIN> <NAME> SRV <PRIORITY> <WEIGHT> <PORT> <TARGET>`,
`${packageName} dns add zeit.rocks '@' SRV 10 0 389 zeit.party`,
],
},
{
name: 'Add a CAA record',
value: [
`${packageName} dns add <DOMAIN> <NAME> CAA '<FLAGS> <TAG> "<VALUE>"'`,
`${packageName} dns add zeit.rocks '@' CAA '0 issue "example.com"'`,
],
},
{
name: 'Import a Zone file',
value: [
`${packageName} dns import <DOMAIN> <FILE>`,
`${packageName} dns import zeit.rocks ./zonefile.txt`,
],
},
{
name: 'Paginate results, where `1584722256178` is the time in milliseconds since the UNIX epoch.',
value: [
`${packageName} dns ls --next 1584722256178`,
`${packageName} dns ls zeit.rocks --next 1584722256178`,
],
},
],
};

View File

@@ -1,96 +1,14 @@
import chalk from 'chalk';
import Client from '../../util/client';
import getArgs from '../../util/get-args';
import getSubcommand from '../../util/get-subcommand';
import handleError from '../../util/handle-error';
import { packageName, logo } from '../../util/pkg-name';
import add from './add';
import importZone from './import';
import ls from './ls';
import rm from './rm';
const help = () => {
console.log(`
${chalk.bold(`${logo} ${packageName} dns`)} [options] <command>
${chalk.dim('Commands:')}
add [details] Add a new DNS entry (see below for examples)
import [domain] [zonefile] Import a DNS zone file (see below for examples)
rm [id] Remove a DNS entry using its ID
ls [domain] List all DNS entries for a domain
${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
-S, --scope Set a custom scope
-N, --next Show next page of results
--limit=${chalk.bold.underline(
'VALUE'
)} Number of results to return per page (default: 20, max: 100)
${chalk.dim('Examples:')}
${chalk.gray('')} Add an A record for a subdomain
${chalk.cyan(
`$ ${packageName} dns add <DOMAIN> <SUBDOMAIN> <A | AAAA | ALIAS | CNAME | TXT> <VALUE>`
)}
${chalk.cyan(`$ ${packageName} dns add zeit.rocks api A 198.51.100.100`)}
${chalk.gray('')} Add an MX record (@ as a name refers to the domain)
${chalk.cyan(
`$ ${packageName} dns add <DOMAIN> '@' MX <RECORD VALUE> <PRIORITY>`
)}
${chalk.cyan(
`$ ${packageName} dns add zeit.rocks '@' MX mail.zeit.rocks 10`
)}
${chalk.gray('')} Add an SRV record
${chalk.cyan(
`$ ${packageName} dns add <DOMAIN> <NAME> SRV <PRIORITY> <WEIGHT> <PORT> <TARGET>`
)}
${chalk.cyan(
`$ ${packageName} dns add zeit.rocks '@' SRV 10 0 389 zeit.party`
)}
${chalk.gray('')} Add a CAA record
${chalk.cyan(
`$ ${packageName} dns add <DOMAIN> <NAME> CAA '<FLAGS> <TAG> "<VALUE>"'`
)}
${chalk.cyan(
`$ ${packageName} dns add zeit.rocks '@' CAA '0 issue "example.com"'`
)}
${chalk.gray('')} Import a Zone file
${chalk.cyan(`$ ${packageName} dns import <DOMAIN> <FILE>`)}
${chalk.cyan(`$ ${packageName} dns import zeit.rocks ./zonefile.txt`)}
${chalk.gray('')} Paginate results, where ${chalk.dim(
'`1584722256178`'
)} is the time in milliseconds since the UNIX epoch.
${chalk.cyan(`$ ${packageName} dns ls --next 1584722256178`)}
${chalk.cyan(`$ ${packageName} dns ls zeit.rocks --next 1584722256178`)}
`);
};
import { dnsCommand } from './command';
import { help } from '../help';
const COMMAND_CONFIG = {
add: ['add'],
@@ -99,7 +17,7 @@ const COMMAND_CONFIG = {
rm: ['rm', 'remove'],
};
export default async function main(client: Client) {
export default async function dns(client: Client) {
let argv;
try {
@@ -114,7 +32,7 @@ export default async function main(client: Client) {
}
if (argv['--help']) {
help();
client.output.print(help(dnsCommand, { columns: client.stderr.columns }));
return 2;
}

View File

@@ -0,0 +1,153 @@
import { Command } from '../help';
import { packageName } from '../../util/pkg-name';
export const domainsCommand: Command = {
name: 'domains',
description: 'Manage domains',
arguments: [
{
name: 'command',
required: true,
},
],
subcommands: [
{
name: 'ls',
description: 'Show all domains in a list',
arguments: [],
options: [],
examples: [],
},
{
name: 'inspect',
description: 'Displays information related to a domain',
arguments: [
{
name: 'name',
required: true,
},
],
options: [],
examples: [],
},
{
name: 'add',
description: 'Add a new domain that you already own',
arguments: [
{
name: 'name',
required: true,
},
{
name: 'project',
required: true,
},
],
options: [],
examples: [],
},
{
name: 'rm',
description: 'Remove a domain',
arguments: [
{
name: 'name',
required: true,
},
],
options: [],
examples: [],
},
{
name: 'buy',
description: "Buy a domain that you don't yet own",
arguments: [
{
name: 'name',
required: true,
},
],
options: [],
examples: [],
},
{
name: 'move',
description: 'Move a domain to another scope',
arguments: [
{
name: 'name',
required: true,
},
{
name: 'destination',
required: true,
},
],
options: [],
examples: [],
},
{
name: 'transfer-in',
description: 'Transfer in a domain to Vercel',
arguments: [
{
name: 'name',
required: true,
},
],
options: [],
examples: [],
},
],
options: [
{
name: 'next',
description: 'Show next page of results',
shorthand: 'N',
type: 'string',
deprecated: false,
multi: false,
},
{
name: 'yes',
description: 'Skip the confirmation prompt when removing a domain',
shorthand: 'y',
type: 'boolean',
deprecated: false,
multi: false,
},
{
name: 'limit',
shorthand: 'n',
description:
'Number of results to return per page (default: 20, max: 100)',
argument: 'NUMBER',
type: 'string',
deprecated: false,
multi: false,
},
{
name: 'force',
shorthand: 'f',
type: 'boolean',
deprecated: false,
description:
'Force a domain on a project and remove it from an existing one',
multi: false,
},
],
examples: [
{
name: 'Add a domain that you already own',
value: [
`${packageName} domains add domain-name.com`,
"Make sure the domain's DNS nameservers are at least 2 of the ones listed on https://vercel.com/edge-network",
`NOTE: Running ${packageName} alias will automatically register your domain if it's configured with these nameservers (no need to 'domains add')`,
],
},
{
name: 'Paginate results, where `1584722256178` is the time in milliseconds since the UNIX epoch',
value: `${packageName} domains ls--next 1584722256178`,
},
],
};

View File

@@ -1,5 +1,3 @@
import chalk from 'chalk';
import Client from '../../util/client';
import getArgs from '../../util/get-args';
import getSubcommand from '../../util/get-subcommand';
@@ -11,69 +9,8 @@ import inspect from './inspect';
import ls from './ls';
import rm from './rm';
import move from './move';
import { packageName, logo } from '../../util/pkg-name';
const help = () => {
console.log(`
${chalk.bold(`${logo} ${packageName} domains`)} [options] <command>
${chalk.dim('Commands:')}
ls Show all domains in a list
inspect [name] Displays information related to a domain
add [name] [project] Add a new domain that you already own
rm [name] Remove a domain
buy [name] Buy a domain that you don't yet own
move [name] [destination] Move a domain to another user or team.
transfer-in [name] Transfer in a domain to Vercel
${chalk.dim('Options:')}
-h, --help Output usage information
-d, --debug Debug mode [off]
--no-color No color mode [off]
-f, --force Force a domain on a project and remove it from an existing one
-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
-t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline(
'TOKEN'
)} Login token
-S, --scope Set a custom scope
-N, --next Show next page of results
--limit=${chalk.bold.underline(
'VALUE'
)} Number of results to return per page (default: 20, max: 100)
-y, --yes Skip the confirmation prompt when removing a domain
${chalk.dim('Examples:')}
${chalk.gray('')} Add a domain that you already own
${chalk.cyan(
`$ ${packageName} domains add ${chalk.underline('domain-name.com')}`
)}
Make sure the domain's DNS nameservers are at least 2 of the
ones listed on ${chalk.underline('https://vercel.com/edge-network')}.
${chalk.yellow('NOTE:')} Running ${chalk.dim(
`${packageName} alias`
)} will automatically register your domain
if it's configured with these nameservers (no need to ${chalk.dim(
'`domain add`'
)}).
${chalk.gray('')} Paginate results, where ${chalk.dim(
'`1584722256178`'
)} is the time in milliseconds since the UNIX epoch.
${chalk.cyan(`$ ${packageName} domains ls --next 1584722256178`)}
`);
};
import { domainsCommand } from './command';
import { help } from '../help';
const COMMAND_CONFIG = {
add: ['add'],
@@ -104,7 +41,9 @@ export default async function main(client: Client) {
}
if (argv['--help']) {
help();
client.output.print(
help(domainsCommand, { columns: client.stderr.columns })
);
return 2;
}

View File

@@ -53,6 +53,12 @@ export default async function move(
const teams = await getTeams(client);
const matchId = await findDestinationMatch(destination, user, teams);
if (matchId && matchId === user.id && user.version === 'northstar') {
output.error(`You may not move your domain to your user account.`);
return 1;
}
if (!matchId && !opts['--yes']) {
output.warn(
`You're not a member of ${param(destination)}. ` +

157
packages/cli/src/commands/env/command.ts vendored Normal file
View File

@@ -0,0 +1,157 @@
import { Command } from '../help';
import { packageName } from '../../util/pkg-name';
import { getEnvTargetPlaceholder } from '../../util/env/env-target';
const targetPlaceholder = getEnvTargetPlaceholder();
export const envCommand: Command = {
name: 'env',
description: 'Interact with environment variables.',
arguments: [
{
name: 'command',
required: false,
},
],
subcommands: [
{
name: 'ls',
description: 'List all variables for the specified Environment',
arguments: [],
options: [],
examples: [],
},
{
name: 'add',
description: 'Add an Environment Variable (see examples below)',
arguments: [
{
name: 'name',
required: true,
},
{
name: 'environment',
required: false,
},
],
options: [],
examples: [],
},
{
name: 'rm',
description: 'Remove an Environment Variable (see examples below)',
arguments: [
{
name: 'name',
required: true,
},
{
name: 'environment',
required: false,
},
],
options: [],
examples: [],
},
{
name: 'pull',
description:
'Pull all Development Environment Variables from the cloud and write to a file [.env.local]',
arguments: [
{
name: 'filename',
required: false,
},
],
options: [],
examples: [],
},
],
options: [
{
name: 'environment',
description:
'Set the Environment (development, preview, production) when pulling Environment Variables',
shorthand: null,
type: 'boolean',
deprecated: false,
multi: false,
},
{
name: 'git-branch',
description:
'Specify the Git branch to pull specific Environment Variables for',
shorthand: null,
type: 'string',
deprecated: false,
multi: false,
},
{
name: 'yes',
description: 'Skip the confirmation prompt when removing an alias',
shorthand: 'y',
type: 'boolean',
deprecated: false,
multi: false,
},
],
examples: [
{
name: 'Pull all Development Environment Variables down from the cloud',
value: [
`${packageName} env pull <file>`,
`${packageName} env pull .env.development.local`,
],
},
{
name: 'Add a new variable to multiple Environments',
value: [
`${packageName} env add <name>`,
`${packageName} env add API_TOKEN`,
],
},
{
name: 'Add a new variable for a specific Environment',
value: [
`${packageName} env add <name> ${targetPlaceholder}`,
`${packageName} env add DB_PASS production`,
],
},
{
name: 'Add a new variable for a specific Environment and Git Branch',
value: [
`${packageName} env add <name> ${targetPlaceholder} <gitbranch>`,
`${packageName} env add DB_PASS preview feat1`,
],
},
{
name: 'Add a new Environment Variable from stdin',
value: [
`cat <file> | ${packageName} env add <name> ${targetPlaceholder}`,
`cat ~/.npmrc | ${packageName} env add NPM_RC preview`,
`${packageName} env add API_URL production < url.txt`,
],
},
{
name: 'Remove a variable from multiple Environments',
value: [
`${packageName} env rm <name>`,
`${packageName} env rm API_TOKEN`,
],
},
{
name: 'Remove a variable from a specific Environment',
value: [
`${packageName} env rm <name> ${targetPlaceholder}`,
`${packageName} env rm NPM_RC preview`,
],
},
{
name: 'Remove a variable from a specific Environment and Git Branch',
value: [
`${packageName} env rm <name> ${targetPlaceholder} <gitbranch>`,
`${packageName} env rm NPM_RC preview feat1`,
],
},
],
};

View File

@@ -8,99 +8,15 @@ import getArgs from '../../util/get-args';
import getInvalidSubcommand from '../../util/get-invalid-subcommand';
import getSubcommand from '../../util/get-subcommand';
import handleError from '../../util/handle-error';
import { getCommandName, packageName, logo } from '../../util/pkg-name';
import { help } from '../help';
import { getCommandName } from '../../util/pkg-name';
import { getLinkedProject } from '../../util/projects/link';
import add from './add';
import ls from './ls';
import pull from './pull';
import rm from './rm';
const help = () => {
const targetPlaceholder = getEnvTargetPlaceholder();
console.log(`
${chalk.bold(`${logo} ${packageName} env`)} [options] <command>
${chalk.dim('Commands:')}
ls [environment] [gitbranch] List all variables for the specified Environment
add [name] [environment] [gitbranch] Add an Environment Variable (see examples below)
rm [name] [environment] [gitbranch] Remove an Environment Variable (see examples below)
pull [filename] Pull all Development Environment Variables from the cloud and write to a file [.env.local]
${chalk.dim('Options:')}
-h, --help Output usage information
--environment Set the Environment (development, preview, production) when pulling Environment Variables
--git-branch Specify the Git branch to pull specific Environment Variables for
-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 the confirmation prompt when overwriting env file on pull or removing an env variable
${chalk.dim('Examples:')}
${chalk.gray(
''
)} Pull all Development Environment Variables down from the cloud
${chalk.cyan(`$ ${packageName} env pull <file>`)}
${chalk.cyan(`$ ${packageName} env pull .env.development.local`)}
${chalk.gray('')} Add a new variable to multiple Environments
${chalk.cyan(`$ ${packageName} env add <name>`)}
${chalk.cyan(`$ ${packageName} env add API_TOKEN`)}
${chalk.gray('')} Add a new variable for a specific Environment
${chalk.cyan(`$ ${packageName} env add <name> ${targetPlaceholder}`)}
${chalk.cyan(`$ ${packageName} env add DB_PASS production`)}
${chalk.gray(
''
)} Add a new variable for a specific Environment and Git Branch
${chalk.cyan(
`$ ${packageName} env add <name> ${targetPlaceholder} <gitbranch>`
)}
${chalk.cyan(`$ ${packageName} env add DB_PASS preview feat1`)}
${chalk.gray('')} Add a new Environment Variable from stdin
${chalk.cyan(
`$ cat <file> | ${packageName} env add <name> ${targetPlaceholder}`
)}
${chalk.cyan(`$ cat ~/.npmrc | ${packageName} env add NPM_RC preview`)}
${chalk.cyan(`$ ${packageName} env add API_URL production < url.txt`)}
${chalk.gray('')} Remove a variable from multiple Environments
${chalk.cyan(`$ ${packageName} env rm <name>`)}
${chalk.cyan(`$ ${packageName} env rm API_TOKEN`)}
${chalk.gray('')} Remove a variable from a specific Environment
${chalk.cyan(`$ ${packageName} env rm <name> ${targetPlaceholder}`)}
${chalk.cyan(`$ ${packageName} env rm NPM_RC preview`)}
${chalk.gray(
''
)} Remove a variable from a specific Environment and Git Branch
${chalk.cyan(
`$ ${packageName} env rm <name> ${targetPlaceholder} <gitbranch>`
)}
${chalk.cyan(`$ ${packageName} env rm NPM_RC preview feat1`)}
`);
};
import { envCommand } from './command';
const COMMAND_CONFIG = {
ls: ['ls', 'list'],
@@ -125,7 +41,7 @@ export default async function main(client: Client) {
}
if (argv['--help']) {
help();
client.output.print(help(envCommand, { columns: client.stderr.columns }));
return 2;
}
@@ -177,7 +93,9 @@ export default async function main(client: Client) {
);
default:
output.error(getInvalidSubcommand(COMMAND_CONFIG));
help();
client.output.print(
help(envCommand, { columns: client.stderr.columns })
);
return 2;
}
}

View File

@@ -24,6 +24,7 @@ import {
} from '../../util/env/diff-env-files';
import { isErrnoException } from '@vercel/error-utils';
import { addToGitIgnore } from '../../util/link/add-to-gitignore';
import JSONparse from 'json-parse-better-errors';
const CONTENTS_PREFIX = '# Created by Vercel CLI\n';
@@ -54,6 +55,12 @@ function tryReadHeadSync(path: string, length: number) {
}
}
const VARIABLES_TO_IGNORE = [
'VERCEL_ANALYTICS_ID',
'VERCEL_SPEED_INSIGHTS_ID',
'VERCEL_WEB_ANALYTICS_ID',
];
export default async function pull(
client: Client,
link: ProjectLinked,
@@ -121,7 +128,7 @@ export default async function pull(
// We need this because double quotes are stripped from the local .env file,
// but `records` is already in the form of a JSON object that doesn't filter
// double quotes.
const newEnv = JSON.parse(JSON.stringify(records).replace(/\\"/g, ''));
const newEnv = JSONparse(JSON.stringify(records).replace(/\\"/g, ''));
deltaString = buildDeltaString(oldEnv, newEnv);
}
}
@@ -130,6 +137,7 @@ export default async function pull(
CONTENTS_PREFIX +
Object.keys(records)
.sort()
.filter(key => !VARIABLES_TO_IGNORE.includes(key))
.map(key => `${key}="${escapeValue(records[key])}"`)
.join('\n') +
'\n';

View File

@@ -0,0 +1,50 @@
import { Command } from '../help';
import { packageName } from '../../util/pkg-name';
export const gitCommand: Command = {
name: 'git',
description: 'Manage your Git provider connections.',
arguments: [
{
name: 'command',
required: true,
},
],
subcommands: [
{
name: 'connect',
description:
'Connect your Vercel Project to your Git repository or provide the remote URL to your Git repository',
arguments: [
{
name: 'git url',
required: false,
},
],
options: [],
examples: [],
},
{
name: 'disconnect',
description: 'Disconnect the Git provider repository from your project',
arguments: [],
options: [],
examples: [],
},
],
options: [],
examples: [
{
name: 'Connect your Vercel Project to your Git repository defined in your local .git config',
value: `${packageName} git connect`,
},
{
name: 'Connect your Vercel Project to a Git repository using the remote URL',
value: `${packageName} git connect https://github.com/user/repo.git`,
},
{
name: 'Disconnect the Git provider repository',
value: `${packageName} git disconnect`,
},
],
};

View File

@@ -1,51 +1,12 @@
import chalk from 'chalk';
import Client from '../../util/client';
import { ensureLink } from '../../util/link/ensure-link';
import getArgs from '../../util/get-args';
import getInvalidSubcommand from '../../util/get-invalid-subcommand';
import handleError from '../../util/handle-error';
import { packageName, logo } from '../../util/pkg-name';
import connect from './connect';
import disconnect from './disconnect';
const help = () => {
console.log(`
${chalk.bold(`${logo} ${packageName} git`)} <command>
${chalk.dim('Commands:')}
connect [url] Connect your Vercel Project to your Git repository or provide the remote URL to your Git repository
disconnect Disconnect the Git provider repository from your project
${chalk.dim('Options:')}
-h, --help Output usage information
-t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline(
'TOKEN'
)} Login token
-y, --yes Skip confirmation when connecting a Git provider
${chalk.dim('Examples:')}
${chalk.gray(
''
)} Connect your Vercel Project to your Git repository defined in your local .git config
${chalk.cyan(`$ ${packageName} git connect`)}
${chalk.gray(
''
)} Connect your Vercel Project to a Git repository using the remote URL
${chalk.cyan(
`$ ${packageName} git connect https://github.com/user/repo.git`
)}
${chalk.gray('')} Disconnect the Git provider repository
${chalk.cyan(`$ ${packageName} git disconnect`)}
`);
};
import { help } from '../help';
import { gitCommand } from './command';
const COMMAND_CONFIG = {
connect: ['connect'],
@@ -71,7 +32,7 @@ export default async function main(client: Client) {
}
if (argv['--help']) {
help();
client.output.print(help(gitCommand, { columns: client.stderr.columns }));
return 2;
}
@@ -96,7 +57,7 @@ export default async function main(client: Client) {
return await disconnect(client, args, project, org);
default:
output.error(getInvalidSubcommand(COMMAND_CONFIG));
help();
client.output.print(help(gitCommand, { columns: client.stderr.columns }));
return 2;
}
}

View File

@@ -12,6 +12,7 @@ export interface CommandOption {
argument?: string;
deprecated: boolean;
description?: string;
/** supports multiple entries */
multi: boolean;
}
export interface CommandArgument {
@@ -322,7 +323,10 @@ export function buildSubcommandLines(
]);
}
const finalColumnWidth = options.columns - maxWidthOfUnwrappedColumns;
// Really long descriptions go RIGHT up to the edge, which looks unpleasant.
const rightMargin = INDENT.repeat(4).length;
const finalColumnWidth =
options.columns - maxWidthOfUnwrappedColumns - rightMargin;
const table = new Table(
Object.assign({}, tableOptions, {

View File

@@ -0,0 +1,47 @@
import { Command } from '../help';
import { packageName } from '../../util/pkg-name';
export const initCommand: Command = {
name: 'init',
description: 'Initialize example Vercel Projects',
arguments: [
{
name: 'example',
required: false,
},
{
name: 'dir',
required: false,
},
],
subcommands: undefined,
options: [
{
name: 'force',
description: 'Overwrite destination directory if exists [off]',
argument: undefined,
shorthand: 'f',
type: 'boolean',
deprecated: false,
multi: false,
},
],
examples: [
{
name: 'Choose from all available examples',
value: `${packageName} init`,
},
{
name: 'Initialize example project into a new directory',
value: `${packageName} init <example>`,
},
{
name: 'Initialize example project into specified directory',
value: `${packageName} <example> <dir>`,
},
{
name: 'Initialize example project without checking',
value: `${packageName} init <example> --force`,
},
],
};

View File

@@ -1,48 +1,16 @@
import chalk from 'chalk';
import getArgs from '../../util/get-args';
import getSubcommand from '../../util/get-subcommand';
import Client from '../../util/client';
import handleError from '../../util/handle-error';
import init from './init';
import { packageName, logo } from '../../util/pkg-name';
import { isError } from '@vercel/error-utils';
import { help } from '../help';
import { initCommand } from './command';
const COMMAND_CONFIG = {
init: ['init'],
};
const help = () => {
console.log(`
${chalk.bold(`${logo} ${packageName} init`)} [example] [dir] [-f | --force]
${chalk.dim('Options:')}
-h, --help Output usage information
-d, --debug Debug mode [off]
--no-color No color mode [off]
-f, --force Overwrite destination directory if exists [off]
${chalk.dim('Examples:')}
${chalk.gray('')} Choose from all available examples
${chalk.cyan(`$ ${packageName} init`)}
${chalk.gray('')} Initialize example project into a new directory
${chalk.cyan(`$ ${packageName} init <example>`)}
${chalk.gray('')} Initialize example project into specified directory
${chalk.cyan(`$ ${packageName} init <example> <dir>`)}
${chalk.gray('')} Initialize example project without checking
${chalk.cyan(`$ ${packageName} init <example> --force`)}
`);
};
export default async function main(client: Client) {
const { output } = client;
let argv;
@@ -60,7 +28,7 @@ export default async function main(client: Client) {
}
if (argv['--help']) {
help();
client.output.print(help(initCommand, { columns: client.stderr.columns }));
return 2;
}

View File

@@ -19,6 +19,7 @@ import Client from '../../util/client';
import { LoginResult } from '../../util/login/types';
import { help } from '../help';
import { loginCommand } from './command';
import { updateCurrentTeamAfterLogin } from '../../util/login/update-current-team-after-login';
export default async function login(client: Client): Promise<number> {
const { output } = client;
@@ -67,20 +68,16 @@ export default async function login(client: Client): Promise<number> {
return result;
}
// If the token was upgraded (not a new login), then don't modify
// the current scope.
if (!client.authConfig.token) {
if (result.teamId) {
// SSO login, so set the current scope to the appropriate Team
client.config.currentTeam = result.teamId;
} else {
delete client.config.currentTeam;
}
}
const isNewLogin = !client.authConfig.token;
// Save the user's authentication token to the configuration file.
client.authConfig.token = result.token;
// If we have a new login, update `currentTeam`
if (isNewLogin) {
await updateCurrentTeamAfterLogin(client, output, result.teamId);
}
writeToAuthConfigFile(client.authConfig);
writeToConfigFile(client.config);

View File

@@ -3,7 +3,7 @@ import { packageName } from '../../util/pkg-name';
export const logoutCommand: Command = {
name: 'logout',
description: 'Logout the current authenticated user or team.',
description: 'Logout the current authenticated user.',
arguments: [],
options: [],
examples: [

View File

@@ -0,0 +1,67 @@
import { Command } from '../help';
import { packageName } from '../../util/pkg-name';
export const projectCommand: Command = {
name: 'project',
description: 'Manage your Vercel Projects.',
arguments: [
{
name: 'command',
required: true,
},
],
subcommands: [
{
name: 'ls',
description: 'Show all projects in the selected scope',
arguments: [],
options: [],
examples: [],
},
{
name: 'add',
description: 'Add a new project',
arguments: [
{
name: 'name',
required: true,
},
],
options: [],
examples: [],
},
{
name: 'rm',
description: 'Remove a project',
arguments: [
{
name: 'name',
required: true,
},
],
options: [],
examples: [],
},
],
options: [
{
name: 'next',
description: 'Show next page of results',
argument: 'MS',
shorthand: 'N',
type: 'string',
deprecated: false,
multi: false,
},
],
examples: [
{
name: 'Add a new project',
value: `${packageName} project add my-project`,
},
{
name: 'Paginate projects, where `1584722256178` is the time in milliseconds since the UNIX epoch',
value: `${packageName} project ls --next 1584722256178`,
},
],
};

View File

@@ -1,46 +1,13 @@
import chalk from 'chalk';
import Client from '../../util/client';
import getArgs from '../../util/get-args';
import getInvalidSubcommand from '../../util/get-invalid-subcommand';
import getScope from '../../util/get-scope';
import handleError from '../../util/handle-error';
import { packageName, logo } from '../../util/pkg-name';
import { help } from '../help';
import add from './add';
import list from './list';
import rm from './rm';
const help = () => {
console.log(`
${chalk.bold(`${logo} ${packageName} project`)} [options] <command>
${chalk.dim('Commands:')}
ls Show all projects in the selected team/user
add [name] Add a new project
rm [name] Remove a project
${chalk.dim('Options:')}
-h, --help Output usage information
-t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline(
'TOKEN'
)} Login token
-S, --scope Set a custom scope
-N, --next Show next page of results
${chalk.dim('Examples:')}
${chalk.gray('')} Add a new project
${chalk.cyan(`$ ${packageName} project add my-project`)}
${chalk.gray('')} Paginate projects, where ${chalk.dim(
'`1584722256178`'
)} is the time in milliseconds since the UNIX epoch.
${chalk.cyan(`$ ${packageName} project ls --next 1584722256178`)}
`);
};
import { projectCommand } from './command';
const COMMAND_CONFIG = {
ls: ['ls', 'list'],
@@ -63,7 +30,9 @@ export default async function main(client: Client) {
}
if (argv['--help']) {
help();
client.output.print(
help(projectCommand, { columns: client.stderr.columns })
);
return 2;
}
@@ -84,7 +53,9 @@ export default async function main(client: Client) {
return await rm(client, args);
default:
output.error(getInvalidSubcommand(COMMAND_CONFIG));
help();
client.output.print(
help(projectCommand, { columns: client.stderr.columns })
);
return 2;
}
}

View File

@@ -0,0 +1,53 @@
import { Command } from '../help';
import { packageName } from '../../util/pkg-name';
export const promoteCommand: Command = {
name: 'promote',
description: 'Promote an existing deployment to current.',
arguments: [
{
name: 'deployment id/url',
required: true,
},
],
subcommands: [
{
name: 'status',
description: 'Show the status of any current pending promotions',
arguments: [
{
name: 'project',
required: false,
},
],
options: [],
examples: [],
},
],
options: [
{
name: 'timeout',
description: 'Time to wait for promotion completion [3m]',
argument: 'timeout',
shorthand: null,
type: 'string',
deprecated: false,
multi: false,
},
],
examples: [
{
name: 'Show the status of any current pending promotions',
value: [
`${packageName} promote`,
`${packageName} promote status`,
`${packageName} promote status <project>`,
`${packageName} promote status --timeout 30s`,
],
},
{
name: 'Promote a deployment using id or url',
value: `${packageName} promote <deployment id/url>`,
},
],
};

View File

@@ -1,53 +1,13 @@
import chalk from 'chalk';
import type Client from '../../util/client';
import getArgs from '../../util/get-args';
import getProjectByCwdOrLink from '../../util/projects/get-project-by-cwd-or-link';
import { packageName, logo } from '../../util/pkg-name';
import handleError from '../../util/handle-error';
import { isErrnoException } from '@vercel/error-utils';
import ms from 'ms';
import requestPromote from './request-promote';
import promoteStatus from './status';
const help = () => {
console.log(`
${chalk.bold(`${logo} ${packageName} promote`)} [deployment id/url]
Promote an existing deployment to current.
${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
--timeout=${chalk.bold.underline(
'TIME'
)} Time to wait for promotion completion [3m]
-y, --yes Skip questions when setting up new project using default scope and settings
${chalk.dim('Examples:')}
${chalk.gray('')} Show the status of any current pending promotions
${chalk.cyan(`$ ${packageName} promote`)}
${chalk.cyan(`$ ${packageName} promote status`)}
${chalk.cyan(`$ ${packageName} promote status <project>`)}
${chalk.cyan(`$ ${packageName} promote status --timeout 30s`)}
${chalk.gray('')} Promote a deployment using id or url
${chalk.cyan(`$ ${packageName} promote <deployment id/url>`)}
`);
};
import { promoteCommand } from './command';
import { help } from '../help';
/**
* `vc promote` command
@@ -68,7 +28,9 @@ export default async (client: Client): Promise<number> => {
}
if (argv['--help'] || argv._[0] === 'help') {
help();
client.output.print(
help(promoteCommand, { columns: client.stderr.columns })
);
return 2;
}

View File

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

View File

@@ -0,0 +1,53 @@
import { Command } from '../help';
import { packageName } from '../../util/pkg-name';
export const rollbackCommand: Command = {
name: 'rollback',
description: 'Quickly revert back to a previous deployment.',
arguments: [
{
name: 'deployment id/url',
required: true,
},
],
subcommands: [
{
name: 'status',
description: 'Show the status of any current pending rollbacks',
arguments: [
{
name: 'project',
required: false,
},
],
options: [],
examples: [],
},
],
options: [
{
name: 'timeout',
description: 'Time to wait for rollback completion [3m]',
argument: 'timeout',
shorthand: null,
type: 'string',
deprecated: false,
multi: false,
},
],
examples: [
{
name: 'Show the status of any current pending rollbacks',
value: [
`${packageName} rollback`,
`${packageName} rollback status`,
`${packageName} rollback status <project>`,
`${packageName} rollback status --timeout 30s`,
],
},
{
name: 'Rollback a deployment using id or url',
value: `${packageName} rollback <deployment id/url>`,
},
],
};

View File

@@ -1,53 +1,13 @@
import chalk from 'chalk';
import type Client from '../../util/client';
import getArgs from '../../util/get-args';
import getProjectByCwdOrLink from '../../util/projects/get-project-by-cwd-or-link';
import { packageName, logo } from '../../util/pkg-name';
import handleError from '../../util/handle-error';
import { isErrnoException } from '@vercel/error-utils';
import ms from 'ms';
import requestRollback from './request-rollback';
import rollbackStatus from './status';
const help = () => {
console.log(`
${chalk.bold(`${logo} ${packageName} rollback`)} [deployment id/url]
Quickly revert back to a previous deployment.
${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
--timeout=${chalk.bold.underline(
'TIME'
)} Time to wait for rollback completion [3m]
-y, --yes Skip questions when setting up new project using default scope and settings
${chalk.dim('Examples:')}
${chalk.gray('')} Show the status of any current pending rollbacks
${chalk.cyan(`$ ${packageName} rollback`)}
${chalk.cyan(`$ ${packageName} rollback status`)}
${chalk.cyan(`$ ${packageName} rollback status <project>`)}
${chalk.cyan(`$ ${packageName} rollback status --timeout 30s`)}
${chalk.gray('')} Rollback a deployment using id or url
${chalk.cyan(`$ ${packageName} rollback <deployment id/url>`)}
`);
};
import { help } from '../help';
import { rollbackCommand } from './command';
/**
* `vc rollback` command
@@ -68,7 +28,9 @@ export default async (client: Client): Promise<number> => {
}
if (argv['--help'] || argv._[0] === 'help') {
help();
client.output.print(
help(rollbackCommand, { columns: client.stderr.columns })
);
return 2;
}

View File

@@ -0,0 +1,96 @@
import { packageName, getCommandName } from '../../util/pkg-name';
export const secretsCommand = {
name: 'secrets',
description: `NOTE: The ${getCommandName(
'env'
)} command is recommended instead of ${getCommandName('secrets')}`,
arguments: [
{
name: 'command',
required: false,
},
],
subcommands: [
{
name: 'ls',
description: 'Show all secrets in a list',
arguments: [],
options: [],
examples: [],
},
{
name: 'add',
description: 'Add a new secret',
arguments: [
{
name: 'name',
required: true,
},
{
name: 'value',
required: true,
},
],
options: [],
examples: [],
},
{
name: 'rename',
description: 'Change the name of a secret',
arguments: [
{
name: 'old-name',
required: true,
},
{
name: 'new-name',
required: true,
},
],
options: [],
examples: [],
},
{
name: 'rm',
description: 'Remove a secret',
arguments: [
{
name: 'name',
required: true,
},
],
options: [],
examples: [],
},
],
options: [
{
name: 'next',
description: 'Show next page of results',
argument: 'MS',
shorthand: 'n',
type: 'string',
deprecated: false,
multi: false,
},
],
examples: [
{
name: 'Add a new secret',
value: `${packageName} secrets add my-secret "my value"
- Once added, a secret's value can't be retrieved in plain text anymore
- If the secret's value is more than one word, wrap it in quotes
- When in doubt, always wrap your value in quotes`,
},
{
name: 'Expose a secret as an environment variable (notice the `@` symbol)',
value: `${packageName} -e MY_SECRET=@my-secret`,
},
{
name: 'Paginate results, where 1584722256178 is the time in milliseconds since the UNIX epoch',
value: `$ ${packageName} secrets ls --next 1584722256178`,
},
],
};

View File

@@ -1,79 +1,17 @@
import isErrnoException from '@vercel/error-utils';
import chalk from 'chalk';
import table from 'text-table';
import mri from 'mri';
import ms from 'ms';
import strlen from '../util/strlen.ts';
import { handleError, error } from '../util/error';
import NowSecrets from '../util/secrets';
import exit from '../util/exit';
import getScope from '../util/get-scope.ts';
import confirm from '../util/input/confirm';
import getCommandFlags from '../util/get-command-flags';
import getPrefixedFlags from '../util/get-prefixed-flags';
import { packageName, getCommandName, logo } from '../util/pkg-name.ts';
const help = () => {
console.log(`
${chalk.yellow(
`${chalk.bold('NOTE:')} The ${getCommandName(
'env'
)} command is recommended instead of ${getCommandName('secrets')}`
)}
${chalk.bold(`${logo} ${packageName} secrets`)} [options] <command>
${chalk.dim('Commands:')}
ls Show all secrets in a list
add [name] [value] Add a new secret
rename [old-name] [new-name] Change the name of a secret
rm [name] Remove a secret
${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]
-t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline(
'TOKEN'
)} Login token
-S, --scope Set a custom scope
-N, --next Show next page of results
${chalk.dim('Examples:')}
${chalk.gray('')} Add a new secret
${chalk.cyan(`$ ${packageName} secrets add my-secret "my value"`)}
${chalk.gray(
''
)} Once added, a secret's value can't be retrieved in plain text anymore
${chalk.gray(
''
)} If the secret's value is more than one word, wrap it in quotes
${chalk.gray('')} When in doubt, always wrap your value in quotes
${chalk.gray(
''
)} Expose a secret as an environment variable (notice the ${chalk.cyan.bold(
'`@`'
)} symbol)
${chalk.cyan(`$ ${packageName} -e MY_SECRET=${chalk.bold('@my-secret')}`)}
${chalk.gray('')} Paginate results, where ${chalk.dim(
'`1584722256178`'
)} is the time in milliseconds since the UNIX epoch
${chalk.cyan(`$ ${packageName} secrets ls --next 1584722256178`)}
`);
};
import strlen from '../../util/strlen';
import { handleError, error } from '../../util/error';
import NowSecrets from '../../util/secrets';
import getScope from '../../util/get-scope';
import confirm from '../../util/input/confirm';
import getCommandFlags from '../../util/get-command-flags';
import { getCommandName } from '../../util/pkg-name';
import getArgs from '../../util/get-args';
import { help } from '../help';
import { secretsCommand } from './command';
// Options
let argv;
@@ -81,14 +19,12 @@ let subcommand;
let nextTimestamp;
const main = async client => {
argv = mri(client.argv.slice(2), {
boolean: ['help', 'debug', 'yes'],
alias: {
help: 'h',
debug: 'd',
yes: 'y',
next: 'N',
},
argv = getArgs(client.argv.slice(2), {
'--yes': Boolean,
'--next': Number,
'--test-warning': Boolean,
'-y': '--yes',
'-N': '--next',
});
argv._ = argv._.slice(1);
@@ -97,8 +33,10 @@ const main = async client => {
nextTimestamp = argv.next;
if (argv.help || !subcommand) {
help();
await exit(2);
client.output.print(
help(secretsCommand, { columns: client.stderr.columns })
);
return 2;
}
const {
@@ -110,9 +48,11 @@ const main = async client => {
try {
({ contextName } = await getScope(client));
} catch (err) {
if (err.code === 'NOT_AUTHORIZED' || err.code === 'TEAM_DELETED') {
output.error(err.message);
return 1;
if (isErrnoException(err)) {
if (err.code === 'NOT_AUTHORIZED' || err.code === 'TEAM_DELETED') {
output.error(err.message);
return 1;
}
}
throw err;
@@ -123,7 +63,7 @@ const main = async client => {
export default async client => {
try {
await main(client);
return await main(client);
} catch (err) {
handleError(err);
process.exit(1);
@@ -134,7 +74,8 @@ async function run({ output, contextName, currentTeam, client }) {
const secrets = new NowSecrets({ client, currentTeam });
const args = argv._.slice(1);
const start = Date.now();
const { 'test-warning': testWarningFlag } = argv;
const { '--test-warning': testWarningFlag } = argv;
const commandName = getCommandName('secret ' + subcommand);
if (subcommand === 'ls' || subcommand === 'list') {
@@ -185,19 +126,12 @@ async function run({ output, contextName, currentTeam, client }) {
);
if (out) {
console.log(`\n${out}\n`);
client.output.print(`\n${out}\n`);
}
}
if (pagination && pagination.count === 20) {
const prefixedArgs = getPrefixedFlags(argv);
const flags = getCommandFlags(prefixedArgs, [
'_',
'--next',
'-N',
'-d',
'-y',
]);
const flags = getCommandFlags(argv, ['_', '--next', '-N', '-d', '-y']);
const nextCmd = `secrets ${subcommand}${flags} --next ${pagination.next}`;
output.log(`To display the next page run ${getCommandName(nextCmd)}`);
}
@@ -225,7 +159,7 @@ async function run({ output, contextName, currentTeam, client }) {
if (theSecret) {
const yes =
argv.yes ||
argv['--yes'] ||
(await readConfirmation(client, output, theSecret, contextName));
if (!yes) {
output.print(`Canceled. Secret not deleted.\n`);
@@ -307,19 +241,7 @@ async function run({ output, contextName, currentTeam, client }) {
return 1;
}
const [name, parsedValue] = args;
const [originalName, originalValue] = client.argv.slice(-2);
let value = parsedValue;
if (
name === originalName &&
typeof parsedValue === 'boolean' &&
parsedValue !== originalValue
) {
// Corner case where `mri` transforms the secret value into a boolean because
// it starts with a `-` so it thinks its a flag, so we use the original value instead.
value = originalValue;
}
const [name, value] = args;
if (typeof value === 'boolean') {
const example = chalk.cyan(
@@ -349,7 +271,7 @@ async function run({ output, contextName, currentTeam, client }) {
console.error(
error('Please specify a valid subcommand: ls | add | rename | rm')
);
help();
client.output.print(help(secretsCommand, { columns: client.stderr.columns }));
return 2;
}

View File

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

View File

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

View File

@@ -2,7 +2,6 @@ import chars from '../../util/output/chars';
import table from '../../util/output/table';
import getUser from '../../util/get-user';
import getTeams from '../../util/teams/get-teams';
import getPrefixedFlags from '../../util/get-prefixed-flags';
import { packageName } from '../../util/pkg-name';
import getCommandFlags from '../../util/get-command-flags';
import cmd from '../../util/output/cmd';
@@ -40,11 +39,12 @@ export default async function list(client: Client): Promise<number> {
apiVersion: 2,
});
let { currentTeam } = config;
const accountIsCurrent = !currentTeam;
output.spinner('Fetching user information');
const user = await getUser(client);
const accountIsCurrent = !currentTeam && user.version !== 'northstar';
if (accountIsCurrent) {
currentTeam = user.id;
}
@@ -56,12 +56,14 @@ export default async function list(client: Client): Promise<number> {
current: id === currentTeam ? chars.tick : '',
}));
teamList.unshift({
id: user.id,
name: user.email,
value: user.username || user.email,
current: accountIsCurrent ? chars.tick : '',
});
if (user.version !== 'northstar') {
teamList.unshift({
id: user.id,
name: user.email,
value: user.username || user.email,
current: accountIsCurrent ? chars.tick : '',
});
}
// Bring the current Team to the beginning of the list
if (!accountIsCurrent) {
@@ -72,19 +74,21 @@ export default async function list(client: Client): Promise<number> {
// Printing
output.stopSpinner();
console.log(); // empty line
client.stdout.write('\n'); // empty line
table(
['', 'id', 'email / name'],
teamList.map(team => [team.current, team.value, team.name]),
[1, 5]
[1, 5],
(str: string) => {
client.stdout.write(str);
}
);
if (pagination?.count === 20) {
const prefixedArgs = getPrefixedFlags(argv);
const flags = getCommandFlags(prefixedArgs, ['_', '--next', '-N', '-d']);
const flags = getCommandFlags(argv, ['_', '--next', '-N', '-d']);
const nextCmd = `${packageName} teams ls${flags} --next ${pagination.next}`;
console.log(); // empty line
client.stdout.write('\n'); // empty line
output.log(`To display the next page run ${cmd(nextCmd)}`);
}

View File

@@ -70,14 +70,21 @@ export default async function main(client: Client, desiredSlug?: string) {
suffix += ` ${emoji('locked')}`;
}
const personalAccountChoice =
user.version === 'northstar'
? []
: [
{ separator: 'Personal Account' },
{
name: `${user.name || user.email} (${user.username})${suffix}`,
value: user.username,
short: user.username,
selected: personalScopeSelected,
},
];
const choices = [
{ separator: 'Personal Account' },
{
name: `${user.name || user.email} (${user.username})${suffix}`,
value: user.username,
short: user.username,
selected: personalScopeSelected,
},
...personalAccountChoice,
{ separator: 'Teams' },
...teamChoices,
];
@@ -97,6 +104,11 @@ export default async function main(client: Client, desiredSlug?: string) {
}
if (desiredSlug === user.username || desiredSlug === user.email) {
if (user.version === 'northstar') {
output.error('You cannot set your Personal Account as the scope.');
return 1;
}
// Switch to user's personal account
if (personalScopeSelected) {
output.log('No changes made');

View File

@@ -56,6 +56,7 @@ import { ProxyAgent } from 'proxy-agent';
import box from './util/output/box';
import { execExtension } from './util/extension/exec';
import { help } from './args';
import { updateCurrentTeamAfterLogin } from './util/login/update-current-team-after-login';
const VERCEL_DIR = getGlobalPathConfig();
const VERCEL_CONFIG_PATH = configFiles.getConfigFilePath();
@@ -337,17 +338,12 @@ const main = async () => {
return result;
}
if (result.teamId) {
// SSO login, so set the current scope to the appropriate Team
client.config.currentTeam = result.teamId;
} else {
delete client.config.currentTeam;
}
// When `result` is a string it's the user's authentication token.
// It needs to be saved to the configuration file.
client.authConfig.token = result.token;
await updateCurrentTeamAfterLogin(client, output, result.teamId);
configFiles.writeToAuthConfigFile(client.authConfig);
configFiles.writeToConfigFile(client.config);
@@ -447,6 +443,11 @@ const main = async () => {
}
if (user.id === scope || user.email === scope || user.username === scope) {
if (user.version === 'northstar') {
output.error('You cannot set your Personal Account as the scope.');
return 1;
}
delete client.config.currentTeam;
} else {
let teams = [];

View File

@@ -20,7 +20,8 @@ export async function initCorepack({
);
if (pkg instanceof CantParseJSONFile) {
console.warn(
'Warning: Could not enable corepack because package.json is invalid JSON'
'Warning: Could not enable corepack because package.json is invalid JSON',
pkg.meta.parseErrorLocation
);
} else if (!pkg?.packageManager) {
console.warn(
@@ -40,7 +41,7 @@ export async function initCorepack({
const pkgManagerName = pkg.packageManager.split('@')[0];
// We must explicitly call `corepack enable npm` since `corepack enable`
// doesn't work with npm. See https://github.com/nodejs/corepack/pull/24
// Also, `corepack enable` is too broad and will change the verison of
// Also, `corepack enable` is too broad and will change the version of
// yarn & pnpm even though those versions are not specified by the user.
// See https://github.com/nodejs/corepack#known-good-releases
// Finally, we use `--install-directory` so we can cache the result to

View File

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

View File

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

View File

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

View File

@@ -20,6 +20,7 @@ import isPortReachable from 'is-port-reachable';
import deepEqual from 'fast-deep-equal';
import npa from 'npm-package-arg';
import type { ChildProcess } from 'child_process';
import JSONparse from 'json-parse-better-errors';
import { getVercelIgnore, fileNameSymbol } from '@vercel/client';
import {
@@ -726,7 +727,7 @@ export default class DevServer {
try {
const raw = await fs.readFile(abs, 'utf8');
const parsed: WithFileNameSymbol<T> = JSON.parse(raw);
const parsed: WithFileNameSymbol<T> = JSONparse(raw);
parsed[fileNameSymbol] = rel;
return parsed;
} catch (err: unknown) {

View File

@@ -59,7 +59,7 @@ export class TeamDeleted extends NowError<'TEAM_DELETED', {}> {
constructor() {
super({
code: 'TEAM_DELETED',
message: `Your team was deleted. You can switch to a different one using ${getCommandName(
message: `Your team was deleted or you were removed from the team. You can switch to a different one using ${getCommandName(
`switch`
)}.`,
meta: {},
@@ -668,13 +668,14 @@ export class CertMissing extends NowError<'ALIAS_IN_USE', { domain: string }> {
export class CantParseJSONFile extends NowError<
'CANT_PARSE_JSON_FILE',
{ file: string }
{ file: string; parseErrorLocation: string }
> {
constructor(file: string) {
constructor(file: string, parseErrorLocation: string) {
const message = `Can't parse json file ${file}: ${parseErrorLocation}`;
super({
code: 'CANT_PARSE_JSON_FILE',
meta: { file },
message: `Can't parse json file`,
meta: { file, parseErrorLocation },
message,
});
}
}

View File

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

View File

@@ -1,26 +0,0 @@
/**
* This function adds a prefix `-` or `--` to the flags
* passed from the command line, because the package `mri`
* used to extract the args removes them for some reason.
*/
export default function getPrefixedFlags(args: { [key in string]: any }) {
const prefixedArgs: {
[key in string]: any;
} = {};
for (const arg in args) {
if (arg === '_') {
prefixedArgs[arg] = args[arg];
} else {
let prefix = '-';
// Full form flags need two dashes, whereas one letter
// flags need only one.
if (arg.length > 1) {
prefix = '--';
}
prefixedArgs[`${prefix}${arg}`] = args[arg];
}
}
return prefixedArgs;
}

View File

@@ -15,9 +15,12 @@ export default async function getScope(
const user = await getUser(client);
let contextName = user.username || user.email;
let team: Team | null = null;
const defaultTeamId =
user.version === 'northstar' ? user.defaultTeamId : undefined;
const currentTeamOrDefaultTeamId = client.config.currentTeam || defaultTeamId;
if (client.config.currentTeam && opts.getTeam !== false) {
team = await getTeamById(client, client.config.currentTeam);
if (currentTeamOrDefaultTeamId && opts.getTeam !== false) {
team = await getTeamById(client, currentTeamOrDefaultTeamId);
if (!team) {
throw new TeamDeleted();

View File

@@ -25,11 +25,18 @@ export default async function selectOrg(
output.stopSpinner();
}
const personalAccountChoice =
user.version === 'northstar'
? []
: [
{
name: user.name || user.username,
value: { type: 'user', id: user.id, slug: user.username },
} as const,
];
const choices: Choice[] = [
{
name: user.name || user.username,
value: { type: 'user', id: user.id, slug: user.username },
},
...personalAccountChoice,
...teams.map<Choice>(team => ({
name: team.name || team.slug,
value: { type: 'team', id: team.id, slug: team.slug },

View File

@@ -0,0 +1,29 @@
import type Client from '../client';
import type { Output } from '../output';
import getUser from '../get-user';
// NOTE: `client.authConfig.token` must be set before calling this
export async function updateCurrentTeamAfterLogin(
client: Client,
output: Output,
ssoTeamId?: string
) {
if (ssoTeamId) {
client.config.currentTeam = ssoTeamId;
} else {
let user = null;
try {
user = await getUser(client);
} catch (err: unknown) {
// Shouldn't happen since we just logged in
output.error('Failed to fetch the logged in user. Please try again.');
return 1;
}
if (user.version === 'northstar' && user.defaultTeamId) {
client.config.currentTeam = user.defaultTeamId;
} else {
delete client.config.currentTeam;
}
}
}

View File

@@ -9,7 +9,8 @@ const printLine = (data: string[], sizes: number[]) =>
export default function table(
fieldNames: string[] = [],
data: string[][] = [],
margins: number[] = []
margins: number[] = [],
print: (str: string) => void
) {
// Compute size of each column
const sizes = data
@@ -26,10 +27,12 @@ export default function table(
.map((size, i) => (i < margins.length && size + margins[i]) || size);
// Print header
console.log(chalk.grey(printLine(fieldNames, sizes)));
print(chalk.grey(printLine(fieldNames, sizes)));
print('\n');
// Print content
for (const row of data) {
console.log(printLine(row, sizes));
print(printLine(row, sizes));
print('\n');
}
}

View File

@@ -1,5 +1,7 @@
import fs from 'fs-extra';
import { CantParseJSONFile } from './errors-ts';
import JSONparse from 'json-parse-better-errors';
import { errorToString } from '@vercel/error-utils';
export default async function readJSONFile<T>(
file: string
@@ -10,10 +12,10 @@ export default async function readJSONFile<T>(
}
try {
const json = JSON.parse(content);
const json = JSONparse(content);
return json;
} catch (error) {
return new CantParseJSONFile(file);
return new CantParseJSONFile(file, errorToString(error));
}
}

View File

@@ -415,6 +415,24 @@ module.exports = async function prepare(session, binaryPath, tmpFixturesDir) {
projectId: 'QmRoBYhejkkmssotLZr8tWgewPdPcjYucYUNERFbhJrRNi',
}),
},
'vc-build-speed-insights': {
'.vercel/project.json': JSON.stringify({
orgId: '.',
projectId: '.',
settings: {
framework: null,
installCommand: 'echo "skipping install"',
},
}),
'package.json': JSON.stringify({
scripts: {
build: 'mkdir -p public && echo hi > public/index.txt',
},
dependencies: {
'@vercel/speed-insights': '0.0.1',
},
}),
},
'vc-build-static-build': {
'.vercel/project.json': JSON.stringify({
orgId: '.',

View File

@@ -16,7 +16,6 @@ import {
import formatOutput from './helpers/format-output';
import type http from 'http';
import type { CLIProcess } from './helpers/types';
import type {} from './helpers/types';
const TEST_TIMEOUT = 3 * 60 * 1000;
jest.setTimeout(TEST_TIMEOUT);
@@ -105,6 +104,8 @@ function mockLoginApi(req: http.IncomingMessage, res: http.ServerResponse) {
query.email === email
) {
res.end(JSON.stringify({ token }));
} else if (method === 'GET' && pathname === '/v2/user') {
res.end(JSON.stringify({ user: { email } }));
} else {
res.statusCode = 405;
res.end(JSON.stringify({ code: 'method_not_allowed' }));
@@ -292,7 +293,7 @@ test('[vc dev] should print help from `vc develop --help`', async () => {
);
expect(exitCode, formatOutput({ stdout, stderr })).toBe(2);
expect(stdout).toMatch(/▲ vercel dev/gm);
expect(stderr).toMatch(/▲ vercel dev/gm);
});
test('default command should deploy directory', async () => {

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