Compare commits

...

55 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
207 changed files with 8093 additions and 2648 deletions

2
.github/CODEOWNERS vendored
View File

@@ -10,7 +10,7 @@
/packages/edge @vercel/compute /packages/edge @vercel/compute
/examples @leerob /examples @leerob
/examples/create-react-app @Timer /examples/create-react-app @Timer
/examples/nextjs @timneutkens @ijjk @styfle @ztanner /examples/nextjs @timneutkens @ijjk @styfle @ztanner @huozhi
/examples/hugo @styfle /examples/hugo @styfle
/examples/jekyll @styfle /examples/jekyll @styfle
/examples/zola @styfle /examples/zola @styfle

View File

@@ -83,7 +83,7 @@ jobs:
env: env:
FORCE_COLOR: '1' FORCE_COLOR: '1'
- name: Test ${{matrix.packageName}} - 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 shell: bash
env: env:
JEST_JUNIT_OUTPUT_FILE: ${{github.workspace}}/.junit-reports/${{matrix.scriptName}}-${{matrix.packageName}}-${{matrix.chunkNumber}}-${{ matrix.runner }}.xml 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_TOKEN: ${{ secrets.VERCEL_TEST_TOKEN }}
VERCEL_TEST_REGISTRATION_URL: ${{ secrets.VERCEL_TEST_REGISTRATION_URL }} VERCEL_TEST_REGISTRATION_URL: ${{ secrets.VERCEL_TEST_REGISTRATION_URL }}
FORCE_COLOR: '1' 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) - name: fetch ssl certificate after tests (linux, os x)
if: matrix.runner != 'windows-latest' if: matrix.runner != 'windows-latest'
run: echo | openssl s_client -showcerts -servername 'api.vercel.com' -connect 76.76.21.21:443 run: echo | openssl s_client -showcerts -servername 'api.vercel.com' -connect 76.76.21.21:443
- name: 'Upload Test Report to Datadog' - 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' run: 'npx @datadog/datadog-ci@2.18.1 junit upload --service vercel-cli .junit-reports'
env: env:
DATADOG_API_KEY: ${{secrets.DATADOG_API_KEY_CLI}} DATADOG_API_KEY: ${{secrets.DATADOG_API_KEY_CLI}}

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: 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) - `/` - A static page (pre-rendered)
- `/ssr` - A page that uses server-side rendering (through 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 using `cache-control` headers - `/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
- `/edge.json` - An Astro API Endpoint that returns JSON data using Vercel Edge Functions - `/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). Learn more about [Astro on Vercel](https://vercel.com/docs/frameworks/astro).

View File

@@ -1,7 +1,17 @@
import { defineConfig } from 'astro/config'; import { defineConfig } from 'astro/config';
// Use Vercel Edge Functions (Recommended)
import vercel from '@astrojs/vercel/edge'; 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({ export default defineConfig({
output: 'server', output: 'server',
adapter: vercel(), experimental: {
assets: true
},
adapter: vercel({
imageService: true,
}),
}); });

View File

@@ -8,8 +8,8 @@
"astro": "astro" "astro": "astro"
}, },
"dependencies": { "dependencies": {
"@astrojs/vercel": "3.2.2", "@astrojs/vercel": "3.8.2",
"astro": "^2.2.1", "astro": "^2.10.14",
"react": "18.2.0", "react": "18.2.0",
"web-vitals": "^3.3.1" "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 { interface ImportMetaEnv {
readonly PUBLIC_VERCEL_ANALYTICS_ID: string; 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: <!-- Replace the API key with your own, see:
https://developers.google.com/maps/documentation/javascript/get-api-key --> 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> <noscript>Please enable JavaScript to continue using this application.</noscript>
</body> </body>

View File

@@ -10,6 +10,8 @@ npm run dev
yarn dev yarn dev
# or # or
pnpm dev pnpm dev
# or
bun dev
``` ```
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. 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" "lint": "next lint"
}, },
"dependencies": { "dependencies": {
"@types/node": "20.5.1", "@types/node": "20.6.3",
"@types/react": "18.2.20", "@types/react": "18.2.22",
"@types/react-dom": "18.2.7", "@types/react-dom": "18.2.7",
"autoprefixer": "10.4.15", "autoprefixer": "10.4.15",
"eslint": "8.47.0", "eslint": "8.49.0",
"eslint-config-next": "13.4.19", "eslint-config-next": "13.5.2",
"next": "13.4.19", "next": "13.5.2",
"postcss": "8.4.28", "postcss": "8.4.30",
"react": "18.2.0", "react": "18.2.0",
"react-dom": "18.2.0", "react-dom": "18.2.0",
"tailwindcss": "3.3.3", "tailwindcss": "3.3.3",
"typescript": "5.1.6" "typescript": "5.2.2"
} }
} }

View File

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

View File

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

View File

@@ -19,7 +19,7 @@ export default function App() {
<html lang="en"> <html lang="en">
<head> <head>
<meta charSet="utf-8" /> <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 /> <Meta />
<Links /> <Links />
</head> </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() { export default function Index() {
return ( 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> <h1>Welcome to Remix</h1>
<ul> <ul>
<li> <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 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() { export default function Edge() {
return ( return (

View File

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

View File

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

View File

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

View File

@@ -1,5 +1,19 @@
# @vercel-internals/types # @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 ## 1.0.9
### Patch Changes ### Patch Changes

View File

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

View File

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

View File

@@ -33,7 +33,7 @@
"source-map-support": "0.5.12", "source-map-support": "0.5.12",
"ts-eager": "2.0.2", "ts-eager": "2.0.2",
"ts-jest": "29.1.0", "ts-jest": "29.1.0",
"turbo": "1.10.13", "turbo": "1.10.14",
"typescript": "4.9.5" "typescript": "4.9.5"
}, },
"scripts": { "scripts": {

View File

@@ -1,5 +1,23 @@
# @vercel/build-utils # @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 ## 7.1.1
### Patch Changes ### Patch Changes

View File

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

View File

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

View File

@@ -1,4 +1,4 @@
import { File } from './types'; import type { File, HasField } from './types';
import { Lambda } from './lambda'; import { Lambda } from './lambda';
interface PrerenderOptions { interface PrerenderOptions {
@@ -12,6 +12,8 @@ interface PrerenderOptions {
initialStatus?: number; initialStatus?: number;
passQuery?: boolean; passQuery?: boolean;
sourcePath?: string; sourcePath?: string;
experimentalBypassFor?: HasField;
experimentalStreamingLambdaPath?: string;
} }
export class Prerender { export class Prerender {
@@ -26,6 +28,8 @@ export class Prerender {
public initialStatus?: number; public initialStatus?: number;
public passQuery?: boolean; public passQuery?: boolean;
public sourcePath?: string; public sourcePath?: string;
public experimentalBypassFor?: HasField;
public experimentalStreamingLambdaPath?: string;
constructor({ constructor({
expiration, expiration,
@@ -38,6 +42,8 @@ export class Prerender {
initialStatus, initialStatus,
passQuery, passQuery,
sourcePath, sourcePath,
experimentalBypassFor,
experimentalStreamingLambdaPath,
}: PrerenderOptions) { }: PrerenderOptions) {
this.type = 'Prerender'; this.type = 'Prerender';
this.expiration = expiration; 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') { if (typeof fallback === 'undefined') {
throw new Error( throw new Error(
'The `fallback` argument for `Prerender` needs to be a `FileBlob`, `FileFsRef`, `FileRef`, or null.' 'The `fallback` argument for `Prerender` needs to be a `FileBlob`, `FileFsRef`, `FileRef`, or null.'
@@ -130,5 +156,14 @@ export class Prerender {
} }
this.allowQuery = allowQuery; 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; [key: string]: unknown;
} }
export type HasField = Array<
| {
type: 'host';
value: string;
}
| {
type: 'header' | 'cookie' | 'query';
key: string;
value?: string;
}
>;
export interface Meta { export interface Meta {
isDev?: boolean; isDev?: boolean;
devCacheDir?: string; devCacheDir?: string;
@@ -422,6 +434,13 @@ export interface Cron {
schedule: string; schedule: string;
} }
// TODO: Proper description once complete
export interface Flag {
key: string;
defaultValue?: unknown;
metadata: Record<string, unknown>;
}
/** The framework which created the function */ /** The framework which created the function */
export interface FunctionFramework { export interface FunctionFramework {
slug: string; slug: string;
@@ -446,6 +465,7 @@ export interface BuildResultV2Typical {
framework?: { framework?: {
version: string; version: string;
}; };
flags?: Flag[];
} }
export type BuildResultV2 = BuildResultV2Typical | BuildResultBuildOutput; 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`, 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', name: 'should not set pnpm path if corepack is enabled',
args: { 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 () => { it('should support passQuery correctly', async () => {
new Prerender({ new Prerender({
expiration: 1, 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', () => { it('should support require by path for legacy builders', () => {
const index = require('../'); const index = require('../');
@@ -440,6 +540,15 @@ it(
ms('1m') 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 () => { it('should return lockfileVersion 2 with npm7', async () => {
const fixture = path.join(__dirname, 'fixtures', '20-npm-7'); const fixture = path.join(__dirname, 'fixtures', '20-npm-7');
const result = await scanParentDirs(fixture); const result = await scanParentDirs(fixture);

View File

@@ -1,5 +1,79 @@
# vercel # 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 ## 32.2.0
### Minor Changes ### Minor Changes

View File

@@ -1,6 +1,6 @@
{ {
"name": "vercel", "name": "vercel",
"version": "32.2.0", "version": "32.3.0",
"preferGlobal": true, "preferGlobal": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"description": "The command-line interface for Vercel", "description": "The command-line interface for Vercel",
@@ -31,20 +31,20 @@
"node": ">= 16" "node": ">= 16"
}, },
"dependencies": { "dependencies": {
"@vercel/build-utils": "7.1.1", "@vercel/build-utils": "7.2.1",
"@vercel/go": "3.0.0", "@vercel/go": "3.0.2",
"@vercel/hydrogen": "1.0.0", "@vercel/hydrogen": "1.0.1",
"@vercel/next": "4.0.2", "@vercel/next": "4.0.7",
"@vercel/node": "3.0.4", "@vercel/node": "3.0.6",
"@vercel/python": "4.0.0", "@vercel/python": "4.0.2",
"@vercel/redwood": "2.0.1", "@vercel/redwood": "2.0.3",
"@vercel/remix-builder": "2.0.3", "@vercel/remix-builder": "2.0.7",
"@vercel/ruby": "2.0.1", "@vercel/ruby": "2.0.2",
"@vercel/static-build": "2.0.4" "@vercel/static-build": "2.0.7"
}, },
"devDependencies": { "devDependencies": {
"@alex_neo/jest-expect-message": "1.0.5", "@alex_neo/jest-expect-message": "1.0.5",
"@edge-runtime/node-utils": "2.2.0", "@edge-runtime/node-utils": "2.2.1",
"@next/env": "11.1.2", "@next/env": "11.1.2",
"@sentry/node": "5.5.0", "@sentry/node": "5.5.0",
"@sindresorhus/slugify": "0.11.0", "@sindresorhus/slugify": "0.11.0",
@@ -86,12 +86,12 @@
"@types/yauzl-promise": "2.1.0", "@types/yauzl-promise": "2.1.0",
"@vercel-internals/constants": "1.0.4", "@vercel-internals/constants": "1.0.4",
"@vercel-internals/get-package-json": "1.0.0", "@vercel-internals/get-package-json": "1.0.0",
"@vercel-internals/types": "1.0.9", "@vercel-internals/types": "1.0.11",
"@vercel/client": "13.0.2", "@vercel/client": "13.0.4",
"@vercel/error-utils": "2.0.1", "@vercel/error-utils": "2.0.1",
"@vercel/frameworks": "2.0.1", "@vercel/frameworks": "2.0.2",
"@vercel/fs-detectors": "5.0.2", "@vercel/fs-detectors": "5.1.0",
"@vercel/fun": "1.0.4", "@vercel/fun": "1.1.0",
"@vercel/ncc": "0.24.0", "@vercel/ncc": "0.24.0",
"@vercel/routing-utils": "3.0.0", "@vercel/routing-utils": "3.0.0",
"@zeit/source-map-support": "0.6.2", "@zeit/source-map-support": "0.6.2",

View File

@@ -27,7 +27,7 @@ export const help = () => `
pull [path] Pull your Project Settings from the cloud pull [path] Pull your Project Settings from the cloud
redeploy [url|id] Rebuild and deploy a previous deployment. redeploy [url|id] Rebuild and deploy a previous deployment.
rollback [url|id] Quickly revert back to 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')} ${chalk.dim('Advanced')}

View File

@@ -21,6 +21,7 @@ import {
NowBuildError, NowBuildError,
Cron, Cron,
validateNpmrc, validateNpmrc,
Flag,
} from '@vercel/build-utils'; } from '@vercel/build-utils';
import { import {
detectBuilders, detectBuilders,
@@ -93,6 +94,7 @@ interface BuildOutputConfig {
version: string; version: string;
}; };
crons?: Cron[]; crons?: Cron[];
flags?: Flag[];
} }
/** /**
@@ -426,6 +428,23 @@ async function doBuild(
const ops: Promise<Error | void>[] = []; 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 // Write the `detectedBuilders` result to output dir
const buildsJsonBuilds = new Map<Builder, SerializedBuilder>( const buildsJsonBuilds = new Map<Builder, SerializedBuilder>(
builds.map(build => { builds.map(build => {
@@ -627,6 +646,7 @@ async function doBuild(
const mergedWildcard = mergeWildcard(buildResults.values()); const mergedWildcard = mergeWildcard(buildResults.values());
const mergedOverrides: Record<string, PathOverride> = const mergedOverrides: Record<string, PathOverride> =
overrides.length > 0 ? Object.assign({}, ...overrides) : undefined; overrides.length > 0 ? Object.assign({}, ...overrides) : undefined;
const mergedFlags = mergeFlags(buildResults.values());
const framework = await getFramework(cwd, buildResults); const framework = await getFramework(cwd, buildResults);
@@ -640,6 +660,7 @@ async function doBuild(
overrides: mergedOverrides, overrides: mergedOverrides,
framework, framework,
crons: mergedCrons, crons: mergedCrons,
flags: mergedFlags,
}; };
await fs.writeJSON(join(outputDir, 'config.json'), config, { spaces: 2 }); await fs.writeJSON(join(outputDir, 'config.json'), config, { spaces: 2 });
@@ -774,3 +795,15 @@ function mergeWildcard(
} }
return wildcard; 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

@@ -72,7 +72,7 @@ export const domainsCommand: Command = {
}, },
{ {
name: 'move', name: 'move',
description: 'Move a domain to another user or team', description: 'Move a domain to another scope',
arguments: [ arguments: [
{ {
name: 'name', name: 'name',

View File

@@ -53,6 +53,12 @@ export default async function move(
const teams = await getTeams(client); const teams = await getTeams(client);
const matchId = await findDestinationMatch(destination, user, teams); 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']) { if (!matchId && !opts['--yes']) {
output.warn( output.warn(
`You're not a member of ${param(destination)}. ` + `You're not a member of ${param(destination)}. ` +

View File

@@ -55,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( export default async function pull(
client: Client, client: Client,
link: ProjectLinked, link: ProjectLinked,
@@ -131,6 +137,7 @@ export default async function pull(
CONTENTS_PREFIX + CONTENTS_PREFIX +
Object.keys(records) Object.keys(records)
.sort() .sort()
.filter(key => !VARIABLES_TO_IGNORE.includes(key))
.map(key => `${key}="${escapeValue(records[key])}"`) .map(key => `${key}="${escapeValue(records[key])}"`)
.join('\n') + .join('\n') +
'\n'; '\n';

View File

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

View File

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

View File

@@ -13,7 +13,7 @@ export const projectCommand: Command = {
subcommands: [ subcommands: [
{ {
name: 'ls', name: 'ls',
description: 'Show all projects in the selected team/user', description: 'Show all projects in the selected scope',
arguments: [], arguments: [],
options: [], options: [],
examples: [], examples: [],

View File

@@ -39,11 +39,12 @@ export default async function list(client: Client): Promise<number> {
apiVersion: 2, apiVersion: 2,
}); });
let { currentTeam } = config; let { currentTeam } = config;
const accountIsCurrent = !currentTeam;
output.spinner('Fetching user information'); output.spinner('Fetching user information');
const user = await getUser(client); const user = await getUser(client);
const accountIsCurrent = !currentTeam && user.version !== 'northstar';
if (accountIsCurrent) { if (accountIsCurrent) {
currentTeam = user.id; currentTeam = user.id;
} }
@@ -55,12 +56,14 @@ export default async function list(client: Client): Promise<number> {
current: id === currentTeam ? chars.tick : '', current: id === currentTeam ? chars.tick : '',
})); }));
teamList.unshift({ if (user.version !== 'northstar') {
id: user.id, teamList.unshift({
name: user.email, id: user.id,
value: user.username || user.email, name: user.email,
current: accountIsCurrent ? chars.tick : '', value: user.username || user.email,
}); current: accountIsCurrent ? chars.tick : '',
});
}
// Bring the current Team to the beginning of the list // Bring the current Team to the beginning of the list
if (!accountIsCurrent) { if (!accountIsCurrent) {
@@ -71,18 +74,21 @@ export default async function list(client: Client): Promise<number> {
// Printing // Printing
output.stopSpinner(); output.stopSpinner();
console.log(); // empty line client.stdout.write('\n'); // empty line
table( table(
['', 'id', 'email / name'], ['', 'id', 'email / name'],
teamList.map(team => [team.current, team.value, team.name]), teamList.map(team => [team.current, team.value, team.name]),
[1, 5] [1, 5],
(str: string) => {
client.stdout.write(str);
}
); );
if (pagination?.count === 20) { if (pagination?.count === 20) {
const flags = getCommandFlags(argv, ['_', '--next', '-N', '-d']); const flags = getCommandFlags(argv, ['_', '--next', '-N', '-d']);
const nextCmd = `${packageName} teams ls${flags} --next ${pagination.next}`; 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)}`); 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')}`; 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 = [ const choices = [
{ separator: 'Personal Account' }, ...personalAccountChoice,
{
name: `${user.name || user.email} (${user.username})${suffix}`,
value: user.username,
short: user.username,
selected: personalScopeSelected,
},
{ separator: 'Teams' }, { separator: 'Teams' },
...teamChoices, ...teamChoices,
]; ];
@@ -97,6 +104,11 @@ export default async function main(client: Client, desiredSlug?: string) {
} }
if (desiredSlug === user.username || desiredSlug === user.email) { 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 // Switch to user's personal account
if (personalScopeSelected) { if (personalScopeSelected) {
output.log('No changes made'); output.log('No changes made');

View File

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

View File

@@ -41,7 +41,7 @@ export async function initCorepack({
const pkgManagerName = pkg.packageManager.split('@')[0]; const pkgManagerName = pkg.packageManager.split('@')[0];
// We must explicitly call `corepack enable npm` since `corepack enable` // We must explicitly call `corepack enable npm` since `corepack enable`
// doesn't work with npm. See https://github.com/nodejs/corepack/pull/24 // 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. // yarn & pnpm even though those versions are not specified by the user.
// See https://github.com/nodejs/corepack#known-good-releases // See https://github.com/nodejs/corepack#known-good-releases
// Finally, we use `--install-directory` so we can cache the result to // Finally, we use `--install-directory` so we can cache the result to

View File

@@ -59,7 +59,7 @@ export class TeamDeleted extends NowError<'TEAM_DELETED', {}> {
constructor() { constructor() {
super({ super({
code: 'TEAM_DELETED', 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` `switch`
)}.`, )}.`,
meta: {}, meta: {},

View File

@@ -15,9 +15,12 @@ export default async function getScope(
const user = await getUser(client); const user = await getUser(client);
let contextName = user.username || user.email; let contextName = user.username || user.email;
let team: Team | null = null; 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) { if (currentTeamOrDefaultTeamId && opts.getTeam !== false) {
team = await getTeamById(client, client.config.currentTeam); team = await getTeamById(client, currentTeamOrDefaultTeamId);
if (!team) { if (!team) {
throw new TeamDeleted(); throw new TeamDeleted();

View File

@@ -25,11 +25,18 @@ export default async function selectOrg(
output.stopSpinner(); 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[] = [ const choices: Choice[] = [
{ ...personalAccountChoice,
name: user.name || user.username,
value: { type: 'user', id: user.id, slug: user.username },
},
...teams.map<Choice>(team => ({ ...teams.map<Choice>(team => ({
name: team.name || team.slug, name: team.name || team.slug,
value: { type: 'team', id: team.id, slug: 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( export default function table(
fieldNames: string[] = [], fieldNames: string[] = [],
data: string[][] = [], data: string[][] = [],
margins: number[] = [] margins: number[] = [],
print: (str: string) => void
) { ) {
// Compute size of each column // Compute size of each column
const sizes = data const sizes = data
@@ -26,10 +27,12 @@ export default function table(
.map((size, i) => (i < margins.length && size + margins[i]) || size); .map((size, i) => (i < margins.length && size + margins[i]) || size);
// Print header // Print header
console.log(chalk.grey(printLine(fieldNames, sizes))); print(chalk.grey(printLine(fieldNames, sizes)));
print('\n');
// Print content // Print content
for (const row of data) { for (const row of data) {
console.log(printLine(row, sizes)); print(printLine(row, sizes));
print('\n');
} }
} }

View File

@@ -415,6 +415,24 @@ module.exports = async function prepare(session, binaryPath, tmpFixturesDir) {
projectId: 'QmRoBYhejkkmssotLZr8tWgewPdPcjYucYUNERFbhJrRNi', 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': { 'vc-build-static-build': {
'.vercel/project.json': JSON.stringify({ '.vercel/project.json': JSON.stringify({
orgId: '.', orgId: '.',

View File

@@ -16,7 +16,6 @@ import {
import formatOutput from './helpers/format-output'; import formatOutput from './helpers/format-output';
import type http from 'http'; import type http from 'http';
import type { CLIProcess } from './helpers/types'; import type { CLIProcess } from './helpers/types';
import type {} from './helpers/types';
const TEST_TIMEOUT = 3 * 60 * 1000; const TEST_TIMEOUT = 3 * 60 * 1000;
jest.setTimeout(TEST_TIMEOUT); jest.setTimeout(TEST_TIMEOUT);
@@ -105,6 +104,8 @@ function mockLoginApi(req: http.IncomingMessage, res: http.ServerResponse) {
query.email === email query.email === email
) { ) {
res.end(JSON.stringify({ token })); res.end(JSON.stringify({ token }));
} else if (method === 'GET' && pathname === '/v2/user') {
res.end(JSON.stringify({ user: { email } }));
} else { } else {
res.statusCode = 405; res.statusCode = 405;
res.end(JSON.stringify({ code: 'method_not_allowed' })); res.end(JSON.stringify({ code: 'method_not_allowed' }));

View File

@@ -79,6 +79,8 @@ function mockLoginApi(req: http.IncomingMessage, res: http.ServerResponse) {
query.email === email query.email === email
) { ) {
res.end(JSON.stringify({ token })); res.end(JSON.stringify({ token }));
} else if (method === 'GET' && pathname === '/v2/user') {
res.end(JSON.stringify({ user: { email } }));
} else { } else {
res.statusCode = 405; res.statusCode = 405;
res.end(JSON.stringify({ code: 'method_not_allowed' })); res.end(JSON.stringify({ code: 'method_not_allowed' }));
@@ -1152,6 +1154,22 @@ test('[vc build] should build project with `@vercel/static-build`', async () =>
expect(builds.builds[0].use).toBe('@vercel/static-build'); expect(builds.builds[0].use).toBe('@vercel/static-build');
}); });
test('[vc build] should build project with `@vercel/speed-insights`', async () => {
try {
process.env.VERCEL_ANALYTICS_ID = '123';
const directory = await setupE2EFixture('vc-build-speed-insights');
const output = await execCli(binaryPath, ['build'], { cwd: directory });
expect(output.exitCode, formatOutput(output)).toBe(0);
expect(output.stderr).toContain('Build Completed in .vercel/output');
expect(output.stderr).toContain(
'The `VERCEL_ANALYTICS_ID` environment variable is deprecated and will be removed in a future release. Please remove it from your environment variables'
);
} finally {
delete process.env.VERCEL_ANALYTICS_ID;
}
});
test('[vc build] should not include .vercel when distDir is "."', async () => { test('[vc build] should not include .vercel when distDir is "."', async () => {
const directory = await setupE2EFixture('static-build-dist-dir'); const directory = await setupE2EFixture('static-build-dist-dir');
const output = await execCli(binaryPath, ['build'], { cwd: directory }); const output = await execCli(binaryPath, ['build'], { cwd: directory });

View File

@@ -89,6 +89,8 @@ function mockLoginApi(req: http.IncomingMessage, res: http.ServerResponse) {
query.email === email query.email === email
) { ) {
res.end(JSON.stringify({ token })); res.end(JSON.stringify({ token }));
} else if (method === 'GET' && pathname === '/v2/user') {
res.end(JSON.stringify({ user: { email } }));
} else { } else {
res.statusCode = 405; res.statusCode = 405;
res.end(JSON.stringify({ code: 'method_not_allowed' })); res.end(JSON.stringify({ code: 'method_not_allowed' }));

View File

@@ -40,3 +40,15 @@ export function useDomains() {
}); });
}); });
} }
export function useDomain(postfix: string) {
client.scenario.get(
`/v4/domains/${encodeURIComponent(`example-${postfix}.com`)}`,
(req, res) => {
const domain = createDomain(postfix);
res.json({
domain,
});
}
);
}

View File

@@ -7,10 +7,12 @@ export function useTeams(
failMissingToken?: boolean; failMissingToken?: boolean;
failInvalidToken?: boolean; failInvalidToken?: boolean;
failNoAccess?: boolean; failNoAccess?: boolean;
apiVersion?: number;
} = { } = {
failMissingToken: false, failMissingToken: false,
failInvalidToken: false, failInvalidToken: false,
failNoAccess: false, failNoAccess: false,
apiVersion: 1,
} }
) { ) {
const id = teamId || chance().guid(); const id = teamId || chance().guid();
@@ -59,11 +61,11 @@ export function useTeams(
}); });
} }
client.scenario.get('/v1/teams', (_req, res) => { client.scenario.get(`/v${options.apiVersion}/teams`, (_req, res) => {
res.json({ res.json({
teams, teams,
}); });
}); });
return teams; return options.apiVersion === 2 ? { teams } : teams;
} }

View File

@@ -1,12 +1,14 @@
import chance from 'chance'; import chance from 'chance';
import { client } from './client'; import { client } from './client';
import type { User } from '@vercel-internals/types';
export function useUser() { export function useUser(additionalAttrs: Partial<User> = {}) {
const user = { const user = {
id: chance().guid(), id: chance().guid(),
email: chance().email(), email: chance().email(),
name: chance().name(), name: chance().name(),
username: chance().first().toLowerCase(), username: chance().first().toLowerCase(),
...additionalAttrs,
}; };
client.scenario.get('/v2/user', (_req, res) => { client.scenario.get('/v2/user', (_req, res) => {
res.json({ res.json({

173
packages/cli/test/northstar.test.ts vendored Normal file
View File

@@ -0,0 +1,173 @@
import type http from 'http';
import fs from 'fs-extra';
import path from 'path';
import { parse as parseUrl } from 'url';
import { execCli } from './helpers/exec';
import waitForPrompt from './helpers/wait-for-prompt';
import getGlobalDir from './helpers/get-global-dir';
import { listTmpDirs } from './helpers/get-tmp-dir';
import formatOutput from './helpers/format-output';
import { User } from '@vercel-internals/types';
const binaryPath = path.resolve(__dirname, `../scripts/start.js`);
function getGlobalConfigPath() {
return path.join(getGlobalDir(), 'config.json');
}
function getConfigAuthPath() {
return path.join(getGlobalDir(), 'auth.json');
}
beforeEach(async () => {
try {
await fs.remove(getGlobalConfigPath());
await fs.remove(getConfigAuthPath());
} catch (err) {
process.exit(1);
}
});
afterEach(() => {
if (localApiServer) {
localApiServer.close();
}
const allTmpDirs = listTmpDirs();
for (const tmpDir of allTmpDirs) {
tmpDir.removeCallback();
}
});
function mockApi(user: Partial<User>) {
return function (req: http.IncomingMessage, res: http.ServerResponse) {
const { url = '/', method } = req;
let { pathname = '/', query = {} } = parseUrl(url, true);
const securityCode = 'Bears Beets Battlestar Galactica';
res.setHeader('content-type', 'application/json');
if (
method === 'POST' &&
pathname === '/registration' &&
query.mode === 'login'
) {
res.end(JSON.stringify({ token: 'test', securityCode }));
} else if (
method === 'GET' &&
pathname === '/registration/verify' &&
query.email === user.email
) {
res.end(JSON.stringify({ token: 'test' }));
} else if (method === 'GET' && pathname === '/v2/user') {
res.end(JSON.stringify({ user }));
} else {
res.statusCode = 405;
res.end(JSON.stringify({ code: 'method_not_allowed' }));
}
};
}
let localApiServer: any;
function setupLocalApiServer(user: Partial<User>) {
return new Promise<string>(resolve => {
localApiServer = require('http')
.createServer(mockApi(user))
.listen(0, () => {
const { port } = localApiServer.address();
const loginApiUrl = `http://localhost:${port}`;
resolve(loginApiUrl);
});
});
}
async function loginSteps(
vercel: ReturnType<typeof execCli>,
user: Partial<User>
) {
await waitForPrompt(vercel, 'Continue with Email');
vercel.stdin?.write('\x1B[B'); // Down arrow
vercel.stdin?.write('\x1B[B'); // Down arrow
vercel.stdin?.write('\x1B[B'); // Down arrow
vercel.stdin?.write('\r'); // Return key
await waitForPrompt(vercel, 'Enter your email address');
vercel.stdin?.write(user.email);
vercel.stdin?.write('\r');
await waitForPrompt(
vercel,
`Email authentication complete for ${user.email}`
);
return vercel;
}
describe('CLI initialization', () => {
describe('login required before running a command', () => {
describe('non-northstar', () => {
const user = {
id: 'test-id',
username: 'test-username',
email: 'test@example.com',
};
it('should not set currentTeam to defaultTeamId', async () => {
const loginApiUrl = await setupLocalApiServer(user);
const vercel = execCli(
binaryPath,
['domains', 'invalidSubCommand', '--api', loginApiUrl],
{ env: { FORCE_TTY: '1' } }
);
const steps = loginSteps(vercel, user);
await waitForPrompt(vercel, 'Please specify a valid subcommand');
const output = await steps;
expect(output.exitCode, formatOutput(output)).toBe(2);
const config = await fs.readJSON(getGlobalConfigPath());
expect(config.currentTeam).toBeUndefined();
});
});
describe('northstar', () => {
const user = {
id: 'test-id',
username: 'test-username',
email: 'test@example.com',
version: 'northstar',
defaultTeamId: 'test-default-team-id',
};
it('should set currentTeam to defaultTeamId', async () => {
const loginApiUrl = await setupLocalApiServer(user);
const vercel = execCli(
binaryPath,
['domains', 'invalidSubCommand', '--api', loginApiUrl],
{ env: { FORCE_TTY: '1' } }
);
const steps = loginSteps(vercel, user);
await waitForPrompt(vercel, 'Please specify a valid subcommand');
const output = await steps;
expect(output.exitCode, formatOutput(output)).toBe(2);
const config = await fs.readJSON(getGlobalConfigPath());
expect(config.currentTeam).toEqual(user.defaultTeamId);
});
it('should not allow setting user as scope', async () => {
const loginApiUrl = await setupLocalApiServer(user);
const vercel = execCli(
binaryPath,
[
'domains',
'invalidSubCommand',
'--api',
loginApiUrl,
'--scope',
user.username,
],
{ env: { FORCE_TTY: '1' } }
);
const steps = loginSteps(vercel, user);
await waitForPrompt(
vercel,
'You cannot set your Personal Account as the scope.'
);
const output = await steps;
expect(output.exitCode, formatOutput(output)).toBe(1);
});
});
});
});

View File

@@ -1,7 +1,8 @@
import { client } from '../../mocks/client'; import { client } from '../../mocks/client';
import domains from '../../../src/commands/domains'; import domains from '../../../src/commands/domains';
import { useUser } from '../../mocks/user'; import { useUser } from '../../mocks/user';
import { useDomains } from '../../mocks/domains'; import { useTeams } from '../../mocks/team';
import { useDomain, useDomains } from '../../mocks/domains';
describe('domains', () => { describe('domains', () => {
it('should list up to 20 domains by default', async () => { it('should list up to 20 domains by default', async () => {
@@ -21,4 +22,19 @@ describe('domains', () => {
await expect(client.stderr).toOutput('example-1.com'); await expect(client.stderr).toOutput('example-1.com');
await expect(exitCodePromise).resolves.toEqual(0); await expect(exitCodePromise).resolves.toEqual(0);
}); });
describe('northstar', () => {
it('should prevent moving a domain to a user account', async () => {
const { username } = useUser({ version: 'northstar' });
useTeams();
useDomain('northstar');
client.setArgv('domains', 'move', 'example-northstar.com', username);
const exitCodePromise = domains(client);
await expect(client.stderr).toOutput(
`Fetching domain example-northstar.com under ${username}
Error: You may not move your domain to your user account.`
);
await expect(exitCodePromise).resolves.toEqual(1);
});
});
}); });

View File

@@ -426,5 +426,46 @@ describe('env', () => {
); );
expect(gitignoreAfter).toBe(gitignoreBefore); expect(gitignoreAfter).toBe(gitignoreBefore);
}); });
it('should not pull VERCEL_ANALYTICS_ID', async () => {
useUser();
useTeams('team_dummy');
useProject(
{
...defaultProject,
id: 'vercel-env-pull',
name: 'vercel-env-pull',
analytics: {
id: 'VC-ANALYTICS-ID',
enabledAt: Date.now(),
},
},
[
{
type: 'encrypted',
id: '781dt89g8r2h789g',
key: 'VERCEL_ANALYTICS_ID',
value: 'VC-ANALYTICS-ID',
target: ['development'],
configurationId: null,
updatedAt: 1557241361455,
createdAt: 1557241361455,
},
]
);
const cwd = setupUnitFixture('vercel-env-pull');
client.cwd = cwd;
client.setArgv('env', 'pull', '--yes');
const exitCodePromise = env(client);
await expect(client.stderr).toOutput(
'Downloading `development` Environment Variables for Project '
);
await expect(client.stderr).toOutput('Created .env.local file');
await expect(exitCodePromise).resolves.toEqual(0);
const rawDevEnv = await fs.readFile(path.join(cwd, '.env.local'));
expect(rawDevEnv.toString().includes('VERCEL_ANALYTICS_ID')).toBeFalsy();
});
}); });
}); });

View File

@@ -13,8 +13,8 @@ import { setupTmpDir } from '../../helpers/setup-unit-fixture';
describe('link', () => { describe('link', () => {
it('should prompt for link', async () => { it('should prompt for link', async () => {
const cwd = setupTmpDir();
const user = useUser(); const user = useUser();
const cwd = setupTmpDir();
useTeams('team_dummy'); useTeams('team_dummy');
const { project } = useProject({ const { project } = useProject({
...defaultProject, ...defaultProject,

View File

@@ -25,6 +25,22 @@ describe('login', () => {
await expect(exitCodePromise).resolves.toEqual(0); await expect(exitCodePromise).resolves.toEqual(0);
}); });
describe('northstar', () => {
it('should set currentTeam to defaultTeamId', async () => {
const user = useUser({
version: 'northstar',
defaultTeamId: 'northstar-defaultTeamId',
});
client.authConfig.token = undefined;
client.setArgv('login', user.email);
const exitCodePromise = login(client);
await expect(exitCodePromise).resolves.toEqual(0);
await expect(client.config.currentTeam).toEqual(
'northstar-defaultTeamId'
);
});
});
describe('interactive', () => { describe('interactive', () => {
it('should allow login via email', async () => { it('should allow login via email', async () => {
const user = useUser(); const user = useUser();

View File

@@ -0,0 +1,81 @@
import { client } from '../../mocks/client';
import teamsSwitch from '../../../src/commands/teams/switch';
import { useUser } from '../../mocks/user';
import { useTeams } from '../../mocks/team';
describe('switch', () => {
describe('non-northstar', () => {
it('should let you switch to team and back', async () => {
const user = useUser();
const team = useTeams()[0];
// ? Switch to:
// ── Personal Account ──────────────
// ● Name (username) (current)
// ── Teams ─────────────────────────
// ○ Team (slug)
// ──────────────────────────────────
// ○ Cancel
let exitCodePromise = teamsSwitch(client);
await expect(client.stderr).toOutput('Switch to:');
client.stdin.write('\x1B[B'); // Down arrow
client.stdin.write('\r'); // Return key
await expect(exitCodePromise).resolves.toEqual(0);
await expect(client.stderr).toOutput(
`Success! The team ${team.name} (${team.slug}) is now active!`
);
// ? Switch to:
// ── Personal Account ──────────────
// ○ Name (username)
// ── Teams ─────────────────────────
// ● Team (slug) (current)
// ──────────────────────────────────
// ○ Cancel
exitCodePromise = teamsSwitch(client);
await expect(client.stderr).toOutput('Switch to:');
client.stdin.write('\x1B[A'); // Up arrow
client.stdin.write('\r'); // Return key
await expect(exitCodePromise).resolves.toEqual(0);
await expect(client.stderr).toOutput(
`Your account (${user.username}) is now active!`
);
});
});
describe('northstar', () => {
it('should not let you switch to personal account', async () => {
const user = useUser({
version: 'northstar',
});
const team = useTeams()[0];
client.config.currentTeam = team.id;
// ? Switch to:
// ── Teams ─────────────────────────
// ● Team (slug) (current)
// ──────────────────────────────────
// ○ Cancel
const exitCodePromise = teamsSwitch(client);
// Test that personal account is not displayed in scope switcher
await expect(client.stderr).not.toOutput(user.username);
client.stdin.write('\r'); // Return key
await expect(exitCodePromise).resolves.toEqual(0);
await expect(client.stderr).toOutput('No changes made');
});
it('should not let you switch to personal account if desiredSlug is set as personal account', async () => {
const user = useUser({
version: 'northstar',
});
useTeams();
const exitCodePromise = teamsSwitch(client, user.username);
// Personal account should be hidden
await expect(client.stderr).toOutput(
'You cannot set your Personal Account as the scope.'
);
await expect(exitCodePromise).resolves.toEqual(1);
});
});
});

View File

@@ -0,0 +1,30 @@
import { client } from '../../mocks/client';
import teamsList from '../../../src/commands/teams/list';
import { useUser } from '../../mocks/user';
import { useTeams } from '../../mocks/team';
describe('teams', () => {
describe('ls', () => {
describe('non-northstar', () => {
it('should display your personal account', async () => {
const user = useUser();
useTeams(undefined, { apiVersion: 2 });
const exitCodePromise = teamsList(client);
await expect(client.stdout).toOutput(user.username);
await expect(exitCodePromise).resolves.toEqual(0);
});
});
describe('northstar', () => {
it('should not display your personal account', async () => {
const user = useUser({
version: 'northstar',
});
useTeams(undefined, { apiVersion: 2 });
const exitCodePromise = teamsList(client);
await expect(client.stdout).not.toOutput(user.username);
await expect(exitCodePromise).resolves.toEqual(0);
});
});
});
});

View File

@@ -0,0 +1,68 @@
import { client } from '../../mocks/client';
import { useUser } from '../../mocks/user';
import { useTeams } from '../../mocks/team';
import getScope from '../../../src/util/get-scope';
describe('getScope', () => {
let mockTeam: ReturnType<typeof useTeams>[0];
let mockUser: ReturnType<typeof useUser>;
beforeEach(() => {
mockTeam = useTeams()[0];
});
describe('non-northstar', () => {
beforeEach(() => {
mockUser = useUser();
});
it('should return user if team is unspecified', async () => {
const { contextName, team, user } = await getScope(client);
await expect(user.id).toEqual(mockUser.id);
await expect(team).toBeNull();
await expect(contextName).toEqual(mockUser.username);
});
it('should return team if team is specified', async () => {
client.config.currentTeam = mockTeam.id;
const { contextName, team, user } = await getScope(client);
await expect(user.id).toEqual(mockUser.id);
await expect(team?.id).toEqual(mockTeam.id);
await expect(contextName).toEqual(mockTeam.slug);
});
it('should not return team if team is specified but getTeam is false', async () => {
client.config.currentTeam = mockTeam.id;
const { contextName, team, user } = await getScope(client, {
getTeam: false,
});
await expect(user.id).toEqual(mockUser.id);
await expect(team).toBeNull();
await expect(contextName).toEqual(mockUser.username);
});
});
describe('northstar', () => {
beforeEach(() => {
mockUser = useUser({
version: 'northstar',
defaultTeamId: mockTeam.id,
});
});
it('should return default team', async () => {
const { contextName, team, user } = await getScope(client);
await expect(user.id).toEqual(mockUser.id);
await expect(team?.id).toEqual(mockTeam.id);
await expect(contextName).toEqual(mockTeam.slug);
});
it('should not return default team if getTeam is false', async () => {
const { contextName, team, user } = await getScope(client, {
getTeam: false,
});
await expect(user.id).toEqual(mockUser.id);
await expect(team).toBeNull();
await expect(contextName).toEqual(mockUser.username);
});
});
});

View File

@@ -0,0 +1,40 @@
import { client } from '../../../mocks/client';
import selectOrg from '../../../../src/util/input/select-org';
import { useTeams } from '../../../mocks/team';
import { useUser } from '../../../mocks/user';
describe('selectOrg', () => {
describe('non-northstar', () => {
it('should allow selecting user', async () => {
const user = useUser();
useTeams();
const selectOrgPromise = selectOrg(client, 'Select the scope');
await expect(client.stderr).toOutput(user.name);
client.stdin.write('\r'); // Return key
await expect(selectOrgPromise).resolves.toHaveProperty('id', user.id);
});
it('should allow selecting team', async () => {
useUser();
const team = useTeams()[0];
const selectOrgPromise = selectOrg(client, 'Select the scope');
await expect(client.stderr).toOutput('Select the scope');
client.stdin.write('\x1B[B'); // Down arrow
client.stdin.write('\r'); // Return key
await expect(selectOrgPromise).resolves.toHaveProperty('id', team.id);
});
});
describe('northstar', () => {
it('should not allow selecting user', async () => {
const user = useUser({
version: 'northstar',
});
const team = useTeams()[0];
const selectOrgPromise = selectOrg(client, 'Select the scope');
await expect(client.stderr).not.toOutput(user.name);
client.stdin.write('\r'); // Return key
await expect(selectOrgPromise).resolves.toHaveProperty('id', team.id);
});
});
});

View File

@@ -0,0 +1,33 @@
import { client } from '../../../mocks/client';
import { useUser } from '../../../mocks/user';
import { updateCurrentTeamAfterLogin } from '../../../../src/util/login/update-current-team-after-login';
describe('updateCurrentTeamAfterLogin', () => {
describe('SSO Login', () => {
it('should set currentTeam to SSO team ID', async () => {
useUser();
await updateCurrentTeamAfterLogin(client, client.output, 'ssoTeamId');
await expect(client.config.currentTeam).toEqual('ssoTeamId');
});
});
describe('northstar', () => {
it('should set currentTeam to defaultTeamId', async () => {
useUser({
version: 'northstar',
defaultTeamId: 'defaultTeamId',
});
await updateCurrentTeamAfterLogin(client, client.output);
await expect(client.config.currentTeam).toEqual('defaultTeamId');
});
});
describe('non-northstar', () => {
it('should reset currentTeam', async () => {
client.config.currentTeam = 'previousTeamId';
useUser();
await updateCurrentTeamAfterLogin(client, client.output);
await expect(client.config.currentTeam).toBeUndefined();
});
});
});

View File

@@ -1,5 +1,19 @@
# @vercel/client # @vercel/client
## 13.0.4
### Patch Changes
- Updated dependencies [[`decdf27fb`](https://github.com/vercel/vercel/commit/decdf27fb5ca914fe50a9320c4fd50ef79d2fbb3)]:
- @vercel/build-utils@7.2.1
## 13.0.3
### 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
## 13.0.2 ## 13.0.2
### Patch Changes ### Patch Changes

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/client", "name": "@vercel/client",
"version": "13.0.2", "version": "13.0.4",
"main": "dist/index.js", "main": "dist/index.js",
"typings": "dist/index.d.ts", "typings": "dist/index.d.ts",
"homepage": "https://vercel.com", "homepage": "https://vercel.com",
@@ -36,7 +36,7 @@
"typescript": "4.9.5" "typescript": "4.9.5"
}, },
"dependencies": { "dependencies": {
"@vercel/build-utils": "7.1.1", "@vercel/build-utils": "7.2.1",
"@vercel/routing-utils": "3.0.0", "@vercel/routing-utils": "3.0.0",
"@zeit/fetch": "5.2.0", "@zeit/fetch": "5.2.0",
"async-retry": "1.2.3", "async-retry": "1.2.3",

View File

@@ -1,5 +1,23 @@
# @vercel/edge # @vercel/edge
## 1.1.0
### Minor Changes
- Add flag to geolocation ([#10443](https://github.com/vercel/vercel/pull/10443))
Usage
```
const { flag } = geolocation(req)
```
## 1.0.2
### Patch Changes
- [node] upgrade edge-runtime ([#10451](https://github.com/vercel/vercel/pull/10451))
## 1.0.1 ## 1.0.1
### Patch Changes ### Patch Changes

View File

@@ -13,6 +13,7 @@
- [CITY_HEADER_NAME](README.md#city_header_name) - [CITY_HEADER_NAME](README.md#city_header_name)
- [COUNTRY_HEADER_NAME](README.md#country_header_name) - [COUNTRY_HEADER_NAME](README.md#country_header_name)
- [EMOJI_FLAG_UNICODE_STARTING_POSITION](README.md#emoji_flag_unicode_starting_position)
- [IP_HEADER_NAME](README.md#ip_header_name) - [IP_HEADER_NAME](README.md#ip_header_name)
- [LATITUDE_HEADER_NAME](README.md#latitude_header_name) - [LATITUDE_HEADER_NAME](README.md#latitude_header_name)
- [LONGITUDE_HEADER_NAME](README.md#longitude_header_name) - [LONGITUDE_HEADER_NAME](README.md#longitude_header_name)
@@ -53,6 +54,18 @@ Country of the original client IP as calculated by Vercel Proxy.
--- ---
### EMOJI_FLAG_UNICODE_STARTING_POSITION
`Const` **EMOJI_FLAG_UNICODE_STARTING_POSITION**: `127397`
Unicode characters for emoji flags start at this number, and run up to 127469.
#### Defined in
[packages/edge/src/edge-headers.ts:34](https://github.com/vercel/vercel/blob/main/packages/edge/src/edge-headers.ts#L34)
---
### IP_HEADER_NAME ### IP_HEADER_NAME
`Const` **IP_HEADER_NAME**: `"x-real-ip"` `Const` **IP_HEADER_NAME**: `"x-real-ip"`
@@ -141,7 +154,7 @@ Returns the location information for the incoming request.
#### Defined in #### Defined in
[packages/edge/src/edge-headers.ts:106](https://github.com/vercel/vercel/blob/main/packages/edge/src/edge-headers.ts#L106) [packages/edge/src/edge-headers.ts:128](https://github.com/vercel/vercel/blob/main/packages/edge/src/edge-headers.ts#L128)
--- ---
@@ -167,7 +180,7 @@ Returns the IP address of the request from the headers.
#### Defined in #### Defined in
[packages/edge/src/edge-headers.ts:77](https://github.com/vercel/vercel/blob/main/packages/edge/src/edge-headers.ts#L77) [packages/edge/src/edge-headers.ts:99](https://github.com/vercel/vercel/blob/main/packages/edge/src/edge-headers.ts#L99)
--- ---

View File

@@ -9,6 +9,7 @@ The location information of a given request.
- [city](Geo.md#city) - [city](Geo.md#city)
- [country](Geo.md#country) - [country](Geo.md#country)
- [countryRegion](Geo.md#countryregion) - [countryRegion](Geo.md#countryregion)
- [flag](Geo.md#flag)
- [latitude](Geo.md#latitude) - [latitude](Geo.md#latitude)
- [longitude](Geo.md#longitude) - [longitude](Geo.md#longitude)
- [region](Geo.md#region) - [region](Geo.md#region)
@@ -23,7 +24,7 @@ The city that the request originated from.
#### Defined in #### Defined in
[packages/edge/src/edge-headers.ts:47](https://github.com/vercel/vercel/blob/main/packages/edge/src/edge-headers.ts#L47) [packages/edge/src/edge-headers.ts:50](https://github.com/vercel/vercel/blob/main/packages/edge/src/edge-headers.ts#L50)
--- ---
@@ -35,7 +36,7 @@ The country that the request originated from.
#### Defined in #### Defined in
[packages/edge/src/edge-headers.ts:50](https://github.com/vercel/vercel/blob/main/packages/edge/src/edge-headers.ts#L50) [packages/edge/src/edge-headers.ts:53](https://github.com/vercel/vercel/blob/main/packages/edge/src/edge-headers.ts#L53)
--- ---
@@ -48,7 +49,19 @@ See [docs](https://vercel.com/docs/concepts/edge-network/headers#x-vercel-ip-cou
#### Defined in #### Defined in
[packages/edge/src/edge-headers.ts:58](https://github.com/vercel/vercel/blob/main/packages/edge/src/edge-headers.ts#L58) [packages/edge/src/edge-headers.ts:64](https://github.com/vercel/vercel/blob/main/packages/edge/src/edge-headers.ts#L64)
---
### flag
`Optional` **flag**: `string`
The flag emoji for the country the request originated from.
#### Defined in
[packages/edge/src/edge-headers.ts:56](https://github.com/vercel/vercel/blob/main/packages/edge/src/edge-headers.ts#L56)
--- ---
@@ -60,7 +73,7 @@ The latitude of the client.
#### Defined in #### Defined in
[packages/edge/src/edge-headers.ts:61](https://github.com/vercel/vercel/blob/main/packages/edge/src/edge-headers.ts#L61) [packages/edge/src/edge-headers.ts:67](https://github.com/vercel/vercel/blob/main/packages/edge/src/edge-headers.ts#L67)
--- ---
@@ -72,7 +85,7 @@ The longitude of the client.
#### Defined in #### Defined in
[packages/edge/src/edge-headers.ts:64](https://github.com/vercel/vercel/blob/main/packages/edge/src/edge-headers.ts#L64) [packages/edge/src/edge-headers.ts:70](https://github.com/vercel/vercel/blob/main/packages/edge/src/edge-headers.ts#L70)
--- ---
@@ -84,4 +97,4 @@ The [Vercel Edge Network region](https://vercel.com/docs/concepts/edge-network/r
#### Defined in #### Defined in
[packages/edge/src/edge-headers.ts:53](https://github.com/vercel/vercel/blob/main/packages/edge/src/edge-headers.ts#L53) [packages/edge/src/edge-headers.ts:59](https://github.com/vercel/vercel/blob/main/packages/edge/src/edge-headers.ts#L59)

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/edge", "name": "@vercel/edge",
"version": "1.0.1", "version": "1.1.0",
"license": "Apache-2.0", "license": "Apache-2.0",
"main": "dist/index.js", "main": "dist/index.js",
"module": "dist/index.mjs", "module": "dist/index.mjs",
@@ -21,7 +21,7 @@
"build:docs": "typedoc && node scripts/fix-links.js && prettier --write docs/**/*.md docs/*.md" "build:docs": "typedoc && node scripts/fix-links.js && prettier --write docs/**/*.md docs/*.md"
}, },
"devDependencies": { "devDependencies": {
"@edge-runtime/jest-environment": "2.3.0", "@edge-runtime/jest-environment": "2.3.1",
"@types/jest": "27.4.1", "@types/jest": "27.4.1",
"jest-junit": "16.0.0", "jest-junit": "16.0.0",
"ts-node": "8.9.1", "ts-node": "8.9.1",

View File

@@ -28,7 +28,10 @@ export const REGION_HEADER_NAME = 'x-vercel-ip-country-region';
* The request ID for each request generated by Vercel Proxy. * The request ID for each request generated by Vercel Proxy.
*/ */
export const REQUEST_ID_HEADER_NAME = 'x-vercel-id'; export const REQUEST_ID_HEADER_NAME = 'x-vercel-id';
/**
* Unicode characters for emoji flags start at this number, and run up to 127469.
*/
export const EMOJI_FLAG_UNICODE_STARTING_POSITION = 127397;
/** /**
* We define a new type so this function can be reused with * We define a new type so this function can be reused with
* the global `Request`, `node-fetch` and other types. * the global `Request`, `node-fetch` and other types.
@@ -49,6 +52,9 @@ export interface Geo {
/** The country that the request originated from. */ /** The country that the request originated from. */
country?: string; country?: string;
/** The flag emoji for the country the request originated from. */
flag?: string;
/** The [Vercel Edge Network region](https://vercel.com/docs/concepts/edge-network/regions) that received the request. */ /** The [Vercel Edge Network region](https://vercel.com/docs/concepts/edge-network/regions) that received the request. */
region?: string; region?: string;
@@ -68,6 +74,22 @@ function getHeader(request: Request, key: string): string | undefined {
return request.headers.get(key) ?? undefined; return request.headers.get(key) ?? undefined;
} }
/**
* Converts the 2 digit countryCode into a flag emoji by adding the current character value to the emoji flag unicode starting position. See [Country Code to Flag Emoji](https://dev.to/jorik/country-code-to-flag-emoji-a21) by Jorik Tangelder.
*
* @param countryCode The country code returned by: `getHeader(request, COUNTRY_HEADER_NAME)`.
* @returns A flag emoji or undefined.
*/
function getFlag(countryCode: string | undefined): string | undefined {
const regex = new RegExp('^[A-Z]{2}$').test(countryCode!);
if (!countryCode || !regex) return undefined;
return String.fromCodePoint(
...countryCode
.split('')
.map(char => EMOJI_FLAG_UNICODE_STARTING_POSITION + char.charCodeAt(0))
);
}
/** /**
* Returns the IP address of the request from the headers. * Returns the IP address of the request from the headers.
* *
@@ -107,6 +129,7 @@ export function geolocation(request: Request): Geo {
return { return {
city: getHeader(request, CITY_HEADER_NAME), city: getHeader(request, CITY_HEADER_NAME),
country: getHeader(request, COUNTRY_HEADER_NAME), country: getHeader(request, COUNTRY_HEADER_NAME),
flag: getFlag(getHeader(request, COUNTRY_HEADER_NAME)),
countryRegion: getHeader(request, REGION_HEADER_NAME), countryRegion: getHeader(request, REGION_HEADER_NAME),
region: getRegionFromRequestId(getHeader(request, REQUEST_ID_HEADER_NAME)), region: getRegionFromRequestId(getHeader(request, REQUEST_ID_HEADER_NAME)),
latitude: getHeader(request, LATITUDE_HEADER_NAME), latitude: getHeader(request, LATITUDE_HEADER_NAME),

View File

@@ -29,6 +29,7 @@ describe('`geolocation`', () => {
const req = new Request('https://example.vercel.sh'); const req = new Request('https://example.vercel.sh');
expect(geolocation(req)).toEqual({ expect(geolocation(req)).toEqual({
city: undefined, city: undefined,
flag: undefined,
country: undefined, country: undefined,
countryRegion: undefined, countryRegion: undefined,
latitude: undefined, latitude: undefined,
@@ -41,7 +42,7 @@ describe('`geolocation`', () => {
const req = new Request('https://example.vercel.sh', { const req = new Request('https://example.vercel.sh', {
headers: { headers: {
[CITY_HEADER_NAME]: 'Tel Aviv', [CITY_HEADER_NAME]: 'Tel Aviv',
[COUNTRY_HEADER_NAME]: 'Israel', [COUNTRY_HEADER_NAME]: 'IL',
[LATITUDE_HEADER_NAME]: '32.109333', [LATITUDE_HEADER_NAME]: '32.109333',
[LONGITUDE_HEADER_NAME]: '34.855499', [LONGITUDE_HEADER_NAME]: '34.855499',
[REGION_HEADER_NAME]: 'TA', // https://en.wikipedia.org/wiki/ISO_3166-2:IL [REGION_HEADER_NAME]: 'TA', // https://en.wikipedia.org/wiki/ISO_3166-2:IL
@@ -50,7 +51,8 @@ describe('`geolocation`', () => {
}); });
expect(geolocation(req)).toEqual<Geo>({ expect(geolocation(req)).toEqual<Geo>({
city: 'Tel Aviv', city: 'Tel Aviv',
country: 'Israel', flag: '🇮🇱',
country: 'IL',
latitude: '32.109333', latitude: '32.109333',
longitude: '34.855499', longitude: '34.855499',
region: 'fra1', region: 'fra1',
@@ -62,7 +64,7 @@ describe('`geolocation`', () => {
const req = new Request('https://example.vercel.sh', { const req = new Request('https://example.vercel.sh', {
headers: { headers: {
[CITY_HEADER_NAME]: 'Tokyo', [CITY_HEADER_NAME]: 'Tokyo',
[COUNTRY_HEADER_NAME]: 'Japan', [COUNTRY_HEADER_NAME]: 'JP',
[LATITUDE_HEADER_NAME]: '37.1233', [LATITUDE_HEADER_NAME]: '37.1233',
[LONGITUDE_HEADER_NAME]: '30.733399', [LONGITUDE_HEADER_NAME]: '30.733399',
[REGION_HEADER_NAME]: '13', [REGION_HEADER_NAME]: '13',
@@ -71,7 +73,8 @@ describe('`geolocation`', () => {
}); });
expect(geolocation(req)).toEqual<Geo>({ expect(geolocation(req)).toEqual<Geo>({
city: 'Tokyo', city: 'Tokyo',
country: 'Japan', flag: '🇯🇵',
country: 'JP',
latitude: '37.1233', latitude: '37.1233',
longitude: '30.733399', longitude: '30.733399',
region: 'hnd1', region: 'hnd1',
@@ -83,7 +86,7 @@ describe('`geolocation`', () => {
const req = new Request('https://example.vercel.sh', { const req = new Request('https://example.vercel.sh', {
headers: { headers: {
[CITY_HEADER_NAME]: 'Tokyo', [CITY_HEADER_NAME]: 'Tokyo',
[COUNTRY_HEADER_NAME]: 'Japan', [COUNTRY_HEADER_NAME]: 'JP',
[LATITUDE_HEADER_NAME]: '37.1233', [LATITUDE_HEADER_NAME]: '37.1233',
[LONGITUDE_HEADER_NAME]: '30.733399', [LONGITUDE_HEADER_NAME]: '30.733399',
[REGION_HEADER_NAME]: '13', [REGION_HEADER_NAME]: '13',
@@ -91,7 +94,29 @@ describe('`geolocation`', () => {
}); });
expect(geolocation(req)).toEqual<Geo>({ expect(geolocation(req)).toEqual<Geo>({
city: 'Tokyo', city: 'Tokyo',
country: 'Japan', flag: '🇯🇵',
country: 'JP',
latitude: '37.1233',
longitude: '30.733399',
region: 'dev1',
countryRegion: '13',
});
});
test('returns undefined if countryCode is invalid', () => {
const req = new Request('https://example.vercel.sh', {
headers: {
[CITY_HEADER_NAME]: 'Tokyo',
[COUNTRY_HEADER_NAME]: 'AAA',
[LATITUDE_HEADER_NAME]: '37.1233',
[LONGITUDE_HEADER_NAME]: '30.733399',
[REGION_HEADER_NAME]: '13',
},
});
expect(geolocation(req)).toEqual<Geo>({
city: 'Tokyo',
flag: undefined,
country: 'AAA',
latitude: '37.1233', latitude: '37.1233',
longitude: '30.733399', longitude: '30.733399',
region: 'dev1', region: 'dev1',

View File

@@ -1,5 +1,11 @@
# @vercel/frameworks # @vercel/frameworks
## 2.0.2
### Patch Changes
- Add `bun install` placeholder ([#10492](https://github.com/vercel/vercel/pull/10492))
## 2.0.1 ## 2.0.1
### Patch Changes ### Patch Changes

View File

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

View File

@@ -42,7 +42,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
placeholder: '`npm run build` or `blitz build`', placeholder: '`npm run build` or `blitz build`',
@@ -82,7 +83,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
placeholder: '`npm run build` or `next build`', placeholder: '`npm run build` or `next build`',
@@ -125,7 +127,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
placeholder: '`npm run build` or `gatsby build`', placeholder: '`npm run build` or `gatsby build`',
@@ -214,7 +217,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
value: 'remix build', value: 'remix build',
@@ -252,7 +256,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install` or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
value: 'astro build', value: 'astro build',
@@ -299,7 +304,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
placeholder: '`npm run build` or `hexo generate`', placeholder: '`npm run build` or `hexo generate`',
@@ -334,7 +340,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
placeholder: '`npm run build` or `npx @11ty/eleventy`', placeholder: '`npm run build` or `npx @11ty/eleventy`',
@@ -371,7 +378,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
placeholder: '`npm run build` or `docusaurus build`', placeholder: '`npm run build` or `docusaurus build`',
@@ -457,7 +465,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
placeholder: '`npm run build` or `docusaurus-build`', placeholder: '`npm run build` or `docusaurus-build`',
@@ -508,7 +517,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
placeholder: '`npm run build` or `preact build`', placeholder: '`npm run build` or `preact build`',
@@ -555,7 +565,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
placeholder: '`npm run build` or `solid-start build`', placeholder: '`npm run build` or `solid-start build`',
@@ -591,7 +602,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
placeholder: '`npm run build` or `dojo build`', placeholder: '`npm run build` or `dojo build`',
@@ -651,7 +663,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
placeholder: '`npm run build` or `ember build`', placeholder: '`npm run build` or `ember build`',
@@ -696,7 +709,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
placeholder: '`npm run build` or `vue-cli-service build`', placeholder: '`npm run build` or `vue-cli-service build`',
@@ -749,7 +763,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
placeholder: '`npm run build` or `ng build && scully`', placeholder: '`npm run build` or `ng build && scully`',
@@ -784,7 +799,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
placeholder: '`npm run build` or `ng build`', placeholder: '`npm run build` or `ng build`',
@@ -827,7 +843,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
placeholder: '`npm run build` or `ng build`', placeholder: '`npm run build` or `ng build`',
@@ -885,7 +902,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
placeholder: '`npm run build` or `polymer build`', placeholder: '`npm run build` or `polymer build`',
@@ -944,7 +962,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
placeholder: '`npm run build` or `rollup -c`', placeholder: '`npm run build` or `rollup -c`',
@@ -994,7 +1013,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
placeholder: '`npm run build` or `svelte-kit build`', placeholder: '`npm run build` or `svelte-kit build`',
@@ -1032,7 +1052,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
placeholder: 'vite build', placeholder: 'vite build',
@@ -1066,7 +1087,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
placeholder: '`npm run build` or `react-scripts build`', placeholder: '`npm run build` or `react-scripts build`',
@@ -1129,7 +1151,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
placeholder: '`npm run build` or `react-scripts build`', placeholder: '`npm run build` or `react-scripts build`',
@@ -1188,7 +1211,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
placeholder: '`npm run build` or `gridsome build`', placeholder: '`npm run build` or `gridsome build`',
@@ -1223,7 +1247,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
placeholder: '`npm run build` or `umi build`', placeholder: '`npm run build` or `umi build`',
@@ -1267,7 +1292,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
placeholder: '`npm run build` or `sapper export`', placeholder: '`npm run build` or `sapper export`',
@@ -1302,7 +1328,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
placeholder: '`npm run build` or `saber build`', placeholder: '`npm run build` or `saber build`',
@@ -1351,7 +1378,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
placeholder: '`npm run build` or `stencil build`', placeholder: '`npm run build` or `stencil build`',
@@ -1420,7 +1448,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
placeholder: '`npm run build` or `nuxt generate`', placeholder: '`npm run build` or `nuxt generate`',
@@ -1476,7 +1505,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
value: 'yarn rw deploy vercel', value: 'yarn rw deploy vercel',
@@ -1606,7 +1636,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
placeholder: '`npm run build` or `brunch build --production`', placeholder: '`npm run build` or `brunch build --production`',
@@ -1717,7 +1748,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
value: 'shopify hydrogen build', value: 'shopify hydrogen build',
@@ -1753,7 +1785,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
placeholder: '`npm run build` or `vite build`', placeholder: '`npm run build` or `vite build`',
@@ -1787,7 +1820,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
placeholder: '`npm run build` or `vitepress build docs`', placeholder: '`npm run build` or `vitepress build docs`',
@@ -1819,7 +1853,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
placeholder: '`npm run build` or `vuepress build src`', placeholder: '`npm run build` or `vuepress build src`',
@@ -1852,7 +1887,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
placeholder: '`npm run build` or `parcel build`', placeholder: '`npm run build` or `parcel build`',
@@ -1909,7 +1945,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
placeholder: '`npm run build` or `sanity build`', placeholder: '`npm run build` or `sanity build`',
@@ -1953,7 +1990,8 @@ export const frameworks = [
}, },
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
value: 'storybook build', value: 'storybook build',
@@ -1975,7 +2013,8 @@ export const frameworks = [
description: 'No framework or an unoptimized framework.', description: 'No framework or an unoptimized framework.',
settings: { settings: {
installCommand: { installCommand: {
placeholder: '`yarn install`, `pnpm install`, or `npm install`', placeholder:
'`yarn install`, `pnpm install`, `npm install`, or `bun install`',
}, },
buildCommand: { buildCommand: {
placeholder: '`npm run vercel-build` or `npm run build`', placeholder: '`npm run vercel-build` or `npm run build`',

View File

@@ -1,5 +1,18 @@
# @vercel/fs-detectors # @vercel/fs-detectors
## 5.1.0
### Minor Changes
- Add support for bun detection in monorepo ([#10511](https://github.com/vercel/vercel/pull/10511))
## 5.0.3
### Patch Changes
- Updated dependencies [[`ec894bdf7`](https://github.com/vercel/vercel/commit/ec894bdf7f167debded37183f11360756f577f14)]:
- @vercel/frameworks@2.0.2
## 5.0.2 ## 5.0.2
### Patch Changes ### Patch Changes

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/fs-detectors", "name": "@vercel/fs-detectors",
"version": "5.0.2", "version": "5.1.0",
"description": "Vercel filesystem detectors", "description": "Vercel filesystem detectors",
"main": "./dist/index.js", "main": "./dist/index.js",
"types": "./dist/index.d.ts", "types": "./dist/index.d.ts",
@@ -21,7 +21,7 @@
}, },
"dependencies": { "dependencies": {
"@vercel/error-utils": "2.0.1", "@vercel/error-utils": "2.0.1",
"@vercel/frameworks": "2.0.1", "@vercel/frameworks": "2.0.2",
"@vercel/routing-utils": "3.0.0", "@vercel/routing-utils": "3.0.0",
"glob": "8.0.3", "glob": "8.0.3",
"js-yaml": "4.1.0", "js-yaml": "4.1.0",
@@ -36,7 +36,7 @@
"@types/minimatch": "3.0.5", "@types/minimatch": "3.0.5",
"@types/node": "14.18.33", "@types/node": "14.18.33",
"@types/semver": "7.3.10", "@types/semver": "7.3.10",
"@vercel/build-utils": "7.1.1", "@vercel/build-utils": "7.2.1",
"jest-junit": "16.0.0", "jest-junit": "16.0.0",
"typescript": "4.9.5" "typescript": "4.9.5"
} }

View File

@@ -37,6 +37,24 @@ export const packageManagers: Array<
], ],
}, },
}, },
{
name: 'bun',
slug: 'bun',
logo: '',
darkModeLogo: '',
detectors: {
some: [
{
path: 'bun.lockb',
},
{
path: 'package.json',
// Depends on https://github.com/nodejs/corepack/pull/307
matchContent: '"packageManager":\\s*"bun@.*"',
},
],
},
},
{ {
name: 'yarn', name: 'yarn',
slug: 'yarn', slug: 'yarn',

View File

@@ -0,0 +1 @@
{}

View File

@@ -0,0 +1,3 @@
{
"packageManager": "bun@1.0.1"
}

View File

@@ -14,6 +14,8 @@ describe('package-managers', () => {
['54-yarn-with-corepack', 'yarn'], ['54-yarn-with-corepack', 'yarn'],
['55-pnpm-with-lockfile', 'pnpm'], ['55-pnpm-with-lockfile', 'pnpm'],
['56-pnpm-with-corepack', 'pnpm'], ['56-pnpm-with-corepack', 'pnpm'],
['57-bun-with-lockfile', 'bun'],
['58-bun-with-corepack', 'bun'],
])('with detectFramework', (fixturePath, frameworkSlug) => { ])('with detectFramework', (fixturePath, frameworkSlug) => {
const testName = `should detect package manager '${frameworkSlug}' for ${fixturePath}`; const testName = `should detect package manager '${frameworkSlug}' for ${fixturePath}`;

View File

@@ -1,4 +1,2 @@
node_modules node_modules
.DS_Store .DS_Store
gatsby-browser.js
web-vitals.js

View File

@@ -0,0 +1,7 @@
# @vercel/gatsby-plugin-vercel-analytics
## 1.0.11
### Patch Changes
- Remove "babel" compilation ([#10546](https://github.com/vercel/vercel/pull/10546))

View File

@@ -1,17 +1,13 @@
{ {
"name": "@vercel/gatsby-plugin-vercel-analytics", "name": "@vercel/gatsby-plugin-vercel-analytics",
"version": "1.0.10", "version": "1.0.11",
"description": "Track Core Web Vitals in Gatsby projects with Vercel Speed Insights.", "description": "Track Core Web Vitals in Gatsby projects with Vercel Speed Insights.",
"main": "index.js", "main": "index.js",
"files": [ "files": [
"gatsby-browser.js", "gatsby-browser.js",
"web-vitals.js" "web-vitals.js"
], ],
"scripts": {
"build": "babel src --out-dir ."
},
"dependencies": { "dependencies": {
"@babel/runtime": "7.12.1",
"web-vitals": "0.2.4" "web-vitals": "0.2.4"
}, },
"repository": { "repository": {
@@ -33,8 +29,6 @@
], ],
"license": "Apache-2.0", "license": "Apache-2.0",
"devDependencies": { "devDependencies": {
"@babel/cli": "7.20.7",
"@babel/core": "7.5.0",
"jest-junit": "16.0.0" "jest-junit": "16.0.0"
} }
} }

View File

@@ -1,4 +1 @@
gatsby-node.*
!gatsby-node.ts
dist dist

View File

@@ -1,5 +1,22 @@
# @vercel/gatsby-plugin-vercel-builder # @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`](https://github.com/vercel/vercel/commit/decdf27fb5ca914fe50a9320c4fd50ef79d2fbb3)]:
- @vercel/build-utils@7.2.1
## 2.0.5
### Patch Changes
- Updated dependencies [[`50e04dd85`](https://github.com/vercel/vercel/commit/50e04dd8584664c842a86c15d92d654f4ea8dcbb), [`45b73c7e8`](https://github.com/vercel/vercel/commit/45b73c7e86458564dc0bab007f6f6365c4c4ab5d), [`9d64312aa`](https://github.com/vercel/vercel/commit/9d64312aaaa875a4e193b7602c50e5dc68979aad), [`d8bc570f6`](https://github.com/vercel/vercel/commit/d8bc570f604950d97156d4f33c8accecf3b3b28f)]:
- @vercel/build-utils@7.2.0
- @vercel/node@3.0.5
## 2.0.4 ## 2.0.4
### Patch Changes ### Patch Changes

View File

@@ -0,0 +1,8 @@
const { generateVercelBuildOutputAPI3Output } = require('./dist/index.js');
exports.onPostBuild = async ({ store }) => {
await generateVercelBuildOutputAPI3Output({
// validated by `pluginOptionSchema`
gatsbyStoreState: store.getState(),
});
};

View File

@@ -1,9 +0,0 @@
// this gets built separately, so import from "dist" instead of "src"
import { generateVercelBuildOutputAPI3Output } from './dist';
export const onPostBuild = async ({ store }: { store: any }) => {
await generateVercelBuildOutputAPI3Output({
// validated by `pluginOptionSchema`
gatsbyStoreState: store.getState(),
});
};

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