Compare commits

...

15 Commits

Author SHA1 Message Date
Vercel Release Bot
c21d93de44 Version Packages (#10062)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-06-06 16:34:04 -05:00
Kiko Beats
0039c8b5ce [node] Add isomorphic functions (#9947)
This PR allow using Web APIs in Serverless functions

```js
// api/serverless.js
export const GET = () => {
  return new Response(`new Response('👋 Hello from Serverless Web!)`)
}
```

More about that
https://nextjs.org/docs/app/building-your-application/routing/router-handlers

---------

Co-authored-by: Sean Massa <EndangeredMassa@gmail.com>
2023-06-06 23:15:10 +02:00
Vercel Release Bot
49c7178567 [remix] Update @remix-run/dev to v1.17.0 (#10072)
This auto-generated PR updates `@remix-run/dev` to version 1.17.0.
2023-06-06 20:31:48 +00:00
Ethan Arrowood
b038b29614 Add vercel.json setting overrides to storybook example for zero-config experience (#10067)
This PR adds necessary configuration overrides to the storybook example so that it can have a zero-config experience.
2023-06-06 00:52:38 +00:00
Nathan Rajlich
7a249a2284 Enforce a changeset file to be present (#10065)
Based off of these setup instructions:

https://github.com/changesets/changesets/blob/main/docs/automating-changesets.md#blocking

If a commit should really not publish a release, you can run `changeset
--empty`.
2023-06-05 15:44:40 -07:00
Nathan Rajlich
a5e32ec31d [cli] Add client.fetchPaginated() async iterator (#10054)
Adds async iterator helper function for interacting with endpoints that have pagination.

Implemented for use with `vc bisect` (fetching deployments) and `vc link --repo` (fetching projects).
2023-06-05 17:06:57 +00:00
Florentin / 珞辰
bc5afe24c4 [node] add maxDuration config support for vc node deployments (#10028)
This PR enables specifying `maxDuration` in `config` for node vc
deployments.

---------

Co-authored-by: Nathan Rajlich <n@n8.io>
2023-06-05 10:05:53 +02:00
Vercel Release Bot
5070e3bbbd [tests] Upgrade Turbo to version 1.10.1 (#10059)
This auto-generated PR updates Turbo to version 1.10.1
2023-06-05 03:57:56 +00:00
Vercel Release Bot
4ad1cbbd7d Version Packages (#10058)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-06-02 19:29:17 -05:00
Chris Barber
4f4e09477d Attempting to publish build-utils and vercel (#10057) 2023-06-02 19:24:32 -05:00
Chris Barber
cd35071f60 Attempting to publish build-utils and vercel (#10057) 2023-06-02 19:22:22 -05:00
Vercel Release Bot
f373c94508 Version Packages (#10055)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2023-06-02 16:28:57 -05:00
Chris Barber
553c001eb0 [cli] vc build ignore .env* & ignore files for @vercel/static (#10056)
For projects with static files only (e.g. `@vercel/static` builder), do not copy`.env*`, `.vercelignore`, or `.nowignore` into the BOA output dir.
2023-06-02 21:04:03 +00:00
Chris Barber
f6c3a95783 [cli] Ensure .npmrc does not contain use-node-version (#10049)
When a project has a `.npmrc` containing `use-node-version`, package managers (notably `pnpm`) will download the specified Node.js version. This is not the correct way as it can lead to `pnpm` downloading Node.js 18 or newer which depends on a version of GLIBC that is not present in the current AWS image. The proper way is to set the `"engines"` in the `package.json`.

<img width="468" alt="image" src="https://github.com/vercel/vercel/assets/97262/0974cf05-6a11-4d95-88e8-13affc4aad2a">

Discussion: https://github.com/orgs/vercel/discussions/2436
2023-06-02 15:27:28 +00:00
Sean Massa
c0bcef0ca4 Update CODEOWNERS for .changeset/ (#10053) 2023-06-01 12:07:18 -05:00
61 changed files with 654 additions and 191 deletions

4
.github/CODEOWNERS vendored
View File

@@ -1,6 +1,7 @@
# Documentation
# https://help.github.com/en/articles/about-code-owners
# Restricted Paths
* @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood
/.github/workflows @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @ijjk
/packages/fs-detectors @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @agadzik @chloetedder
@@ -14,3 +15,6 @@
/examples/jekyll @styfle
/examples/zola @styfle
/packages/node @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @Kikobeats
# Unrestricted Paths
.changeset/

View File

@@ -19,6 +19,22 @@ concurrency:
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
jobs:
enforce-changeset:
name: Enforce Changeset
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
ref: main
- run: git checkout ${{ github.event.pull_request.head.ref }}
- name: install pnpm@8.3.1
run: npm i -g pnpm@8.3.1
- run: pnpm install
# Enforce a changeset file to be present
- run: pnpm exec changeset status --since=main
test:
name: Lint
timeout-minutes: 10

View File

@@ -0,0 +1,4 @@
{
"framework": "storybook",
"buildCommand": "storybook build"
}

View File

@@ -1,5 +1,12 @@
# @vercel-internals/constants
## 1.0.2
### Patch Changes
- Updated dependencies [[`cd35071f6`](https://github.com/vercel/vercel/commit/cd35071f609d615d47bc04634c123b33768436cb)]:
- @vercel/build-utils@6.7.5
## 1.0.1
### Patch Changes

View File

@@ -1,14 +1,14 @@
{
"private": true,
"name": "@vercel-internals/constants",
"version": "1.0.1",
"version": "1.0.2",
"types": "dist/index.d.ts",
"main": "dist/index.js",
"scripts": {
"build": "tsc -p tsconfig.json"
},
"dependencies": {
"@vercel/build-utils": "6.7.4",
"@vercel/build-utils": "6.7.5",
"@vercel/routing-utils": "2.2.1"
},
"devDependencies": {

View File

@@ -1,5 +1,13 @@
# @vercel-internals/types
## 1.0.2
### Patch Changes
- Updated dependencies [[`cd35071f6`](https://github.com/vercel/vercel/commit/cd35071f609d615d47bc04634c123b33768436cb)]:
- @vercel/build-utils@6.7.5
- @vercel-internals/constants@1.0.2
## 1.0.1
### Patch Changes

View File

@@ -381,9 +381,21 @@ export interface ProjectLink {
}
export interface PaginationOptions {
prev: number;
/**
* Amount of items in the current page.
* @example 20
*/
count: number;
next?: number;
/**
* Timestamp that must be used to request the next page.
* @example 1540095775951
*/
next: number | null;
/**
* Timestamp that must be used to request the previous page.
* @example 1540095775951
*/
prev: number | null;
}
export type ProjectLinkResult =

View File

@@ -1,13 +1,13 @@
{
"private": true,
"name": "@vercel-internals/types",
"version": "1.0.1",
"version": "1.0.2",
"types": "index.d.ts",
"main": "index.d.ts",
"dependencies": {
"@types/node": "14.14.31",
"@vercel-internals/constants": "1.0.1",
"@vercel/build-utils": "6.7.4",
"@vercel-internals/constants": "1.0.2",
"@vercel/build-utils": "6.7.5",
"@vercel/routing-utils": "2.2.1"
},
"devDependencies": {

View File

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

View File

@@ -1,5 +1,11 @@
# @vercel/build-utils
## 6.7.5
### Patch Changes
- Publish missing build-utils ([`cd35071f6`](https://github.com/vercel/vercel/commit/cd35071f609d615d47bc04634c123b33768436cb))
## 6.7.4
### Patch Changes

View File

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

View File

@@ -43,6 +43,7 @@ import { getPlatformEnv } from './get-platform-env';
import { getPrefixedEnvVars } from './get-prefixed-env-vars';
import { cloneEnv } from './clone-env';
import { hardLinkDir } from './hard-link-dir';
import { validateNpmrc } from './validate-npmrc';
export {
FileBlob,
@@ -88,6 +89,7 @@ export {
getIgnoreFilter,
cloneEnv,
hardLinkDir,
validateNpmrc,
};
export { EdgeFunction } from './edge-function';

View File

@@ -0,0 +1,26 @@
import { join } from 'path';
import { readFile } from 'fs/promises';
/**
* Checks if there is a `.npmrc` in the cwd (project root) and makes sure it
* doesn't contain a `use-node-version`. This config setting is not supported
* since it causes the package manager to install the Node.js version which in
* the case of newer Node.js versions is not compatible with AWS due to
* outdated GLIBC binaries.
*
* @see https://pnpm.io/npmrc#use-node-version
*
* @param cwd The current working directory (e.g. project root);
*/
export async function validateNpmrc(cwd: string): Promise<void> {
const npmrc = await readFile(join(cwd, '.npmrc'), 'utf-8').catch(err => {
if (err.code !== 'ENOENT') throw err;
});
const nodeRegExp = /(?<!#.*)use-node-version/;
if (npmrc?.match(nodeRegExp)) {
throw new Error(
'Detected unsupported "use-node-version" in your ".npmrc". Please use "engines" in your "package.json" instead.'
);
}
}

View File

@@ -0,0 +1,2 @@
foo=bar
# use-node-version=16.16.0

View File

@@ -0,0 +1 @@
foo=bar

View File

@@ -0,0 +1,3 @@
foo=bar
# the next line is not supported
use-node-version=16.16.0

View File

@@ -0,0 +1,22 @@
import { join } from 'path';
import { validateNpmrc } from '../src/validate-npmrc';
const fixture = (name: string) => join(__dirname, 'fixtures', '29-npmrc', name);
describe('validateNpmrc', () => {
it('should not error with no use-node-version', async () => {
await expect(validateNpmrc(fixture('good'))).resolves.toBe(undefined);
});
it('should throw when use-node-version is found', async () => {
await expect(
validateNpmrc(fixture('has-use-node-version'))
).rejects.toThrow('Detected unsupported');
});
it('should not error when use-node-version is commented out', async () => {
await expect(
validateNpmrc(fixture('comment-use-node-version'))
).resolves.toBe(undefined);
});
});

View File

@@ -1,5 +1,40 @@
# vercel
## 30.2.0
### Minor Changes
- [node] Add isomorphic functions ([#9947](https://github.com/vercel/vercel/pull/9947))
### Patch Changes
- Add `client.fetchPaginated()` helper function ([#10054](https://github.com/vercel/vercel/pull/10054))
- Updated dependencies [[`bc5afe24c`](https://github.com/vercel/vercel/commit/bc5afe24c4547dbf798b939199e8212c4b34038e), [`49c717856`](https://github.com/vercel/vercel/commit/49c7178567ec5bcebe633b598c8c9c0e1aa40fbb), [`0039c8b5c`](https://github.com/vercel/vercel/commit/0039c8b5cea975316a62c4f6aaca5d66d731cc0d)]:
- @vercel/node@2.15.0
- @vercel/remix-builder@1.8.13
- @vercel/static-build@1.3.35
## 30.1.2
### Patch Changes
- Publish missing build-utils ([`cd35071f6`](https://github.com/vercel/vercel/commit/cd35071f609d615d47bc04634c123b33768436cb))
- Updated dependencies [[`cd35071f6`](https://github.com/vercel/vercel/commit/cd35071f609d615d47bc04634c123b33768436cb)]:
- @vercel/build-utils@6.7.5
- @vercel/node@2.14.5
- @vercel/remix-builder@1.8.12
- @vercel/static-build@1.3.34
## 30.1.1
### Patch Changes
- [cli] vc build ignore '.env\*' & ignore files for '@vercel/static' ([#10056](https://github.com/vercel/vercel/pull/10056))
- [cli] Ensure .npmrc does not contain use-node-version ([#10049](https://github.com/vercel/vercel/pull/10049))
## 30.1.0
### Minor Changes

View File

@@ -1,6 +1,6 @@
{
"name": "vercel",
"version": "30.1.0",
"version": "30.2.0",
"preferGlobal": true,
"license": "Apache-2.0",
"description": "The command-line interface for Vercel",
@@ -32,16 +32,16 @@
"node": ">= 14"
},
"dependencies": {
"@vercel/build-utils": "6.7.4",
"@vercel/build-utils": "6.7.5",
"@vercel/go": "2.5.1",
"@vercel/hydrogen": "0.0.64",
"@vercel/next": "3.8.6",
"@vercel/node": "2.14.4",
"@vercel/node": "2.15.0",
"@vercel/python": "3.1.60",
"@vercel/redwood": "1.1.15",
"@vercel/remix-builder": "1.8.11",
"@vercel/remix-builder": "1.8.13",
"@vercel/ruby": "1.3.76",
"@vercel/static-build": "1.3.33"
"@vercel/static-build": "1.3.35"
},
"devDependencies": {
"@alex_neo/jest-expect-message": "1.0.5",
@@ -85,10 +85,10 @@
"@types/which": "3.0.0",
"@types/write-json-file": "2.2.1",
"@types/yauzl-promise": "2.1.0",
"@vercel-internals/constants": "1.0.1",
"@vercel-internals/constants": "1.0.2",
"@vercel-internals/get-package-json": "1.0.0",
"@vercel-internals/types": "1.0.1",
"@vercel/client": "12.6.1",
"@vercel-internals/types": "1.0.2",
"@vercel/client": "12.6.2",
"@vercel/error-utils": "1.0.10",
"@vercel/frameworks": "1.4.2",
"@vercel/fs-detectors": "3.9.3",

View File

@@ -6,21 +6,19 @@ import chalk, { Chalk } from 'chalk';
import { URLSearchParams, parse } from 'url';
import box from '../../util/output/box';
import sleep from '../../util/sleep';
import formatDate from '../../util/format-date';
import link from '../../util/output/link';
import logo from '../../util/output/logo';
import getArgs from '../../util/get-args';
import Client from '../../util/client';
import { getPkgName } from '../../util/pkg-name';
import { Deployment, PaginationOptions } from '@vercel-internals/types';
import { Deployment } from '@vercel-internals/types';
import { normalizeURL } from '../../util/bisect/normalize-url';
import getScope from '../../util/get-scope';
import getDeployment from '../../util/get-deployment';
interface Deployments {
deployments: Deployment[];
pagination: PaginationOptions;
}
const pkgName = getPkgName();
@@ -206,44 +204,34 @@ export default async function main(client: Client): Promise<number> {
// Fetch all the project's "READY" deployments with the pagination API
let deployments: Deployment[] = [];
let next: number | undefined = badDeployment.createdAt + 1;
do {
const query = new URLSearchParams();
query.set('projectId', projectId);
if (badDeployment.target) {
query.set('target', badDeployment.target);
}
query.set('limit', '100');
query.set('state', 'READY');
if (next) {
query.set('until', String(next));
}
const res = await client.fetch<Deployments>(`/v6/deployments?${query}`, {
const query = new URLSearchParams();
query.set('projectId', projectId);
if (badDeployment.target) {
query.set('target', badDeployment.target);
}
query.set('state', 'READY');
query.set('until', String(badDeployment.createdAt + 1));
for await (const chunk of client.fetchPaginated<Deployments>(
`/v6/deployments?${query}`,
{
accountId: badDeployment.ownerId,
});
next = res.pagination.next;
let newDeployments = res.deployments;
}
)) {
let newDeployments = chunk.deployments;
// If we have the "good" deployment in this chunk, then we're done
for (let i = 0; i < newDeployments.length; i++) {
if (newDeployments[i].url === good) {
// grab all deployments up until the good one
newDeployments = newDeployments.slice(0, i);
next = undefined;
break;
}
}
deployments = deployments.concat(newDeployments);
if (next) {
// Small sleep to avoid rate limiting
await sleep(100);
}
} while (next);
}
if (!deployments.length) {
output.error(

View File

@@ -17,6 +17,7 @@ import {
BuildResultV3,
NowBuildError,
Cron,
validateNpmrc,
} from '@vercel/build-utils';
import {
detectBuilders,
@@ -169,6 +170,13 @@ export default async function main(client: Client): Promise<number> {
const target = argv['--prod'] ? 'production' : 'preview';
const yes = Boolean(argv['--yes']);
try {
await validateNpmrc(cwd);
} catch (err) {
output.prettyError(err);
return 1;
}
// TODO: read project settings from the API, fall back to local `project.json` if that fails
// Read project settings, and pull them from Vercel if necessary

View File

@@ -12,7 +12,10 @@ export const build: BuildV2 = async ({ entrypoint, files, config }) => {
if (
filename.startsWith('.git/') ||
filename === 'vercel.json' ||
filename === 'now.json'
filename === '.vercelignore' ||
filename === 'now.json' ||
filename === '.nowignore' ||
filename.startsWith('.env')
) {
continue;
}

View File

@@ -19,11 +19,13 @@ import type {
Stdio,
ReadableTTY,
WritableTTY,
PaginationOptions,
} from '@vercel-internals/types';
import { sharedPromise } from './promise';
import { APIError } from './errors-ts';
import { normalizeError } from '@vercel/error-utils';
import type { Agent } from 'http';
import sleep from './sleep';
const isSAMLError = (v: any): v is SAMLError => {
return v && v.saml;
@@ -176,6 +178,31 @@ export default class Client extends EventEmitter implements Stdio {
}, opts.retry);
}
async *fetchPaginated<T>(
url: string | URL,
opts?: FetchOptions
): AsyncGenerator<T & { pagination: PaginationOptions }> {
const endpoint =
typeof url === 'string' ? new URL(url, this.apiUrl) : new URL(url.href);
if (!endpoint.searchParams.has('limit')) {
endpoint.searchParams.set('limit', '100');
}
let next: number | null | undefined;
do {
if (next) {
// Small sleep to avoid rate limiting
await sleep(100);
endpoint.searchParams.set('until', String(next));
}
const res = await this.fetch<T & { pagination: PaginationOptions }>(
endpoint.href,
opts
);
yield res;
next = res.pagination?.next;
} while (next);
}
reauthenticate = sharedPromise(async function (
this: Client,
error: SAMLError

View File

@@ -8,10 +8,7 @@ import {
import type { Server } from 'http';
import type Client from '../client';
const toHeaders = buildToHeaders({
// @ts-expect-error - `node-fetch` Headers is missing `getAll()`
Headers,
});
const toHeaders = buildToHeaders({ Headers });
export function createProxy(client: Client): Server {
return createServer(async (req, res) => {

View File

@@ -128,9 +128,30 @@ export async function ensureRepoLink(
output.spinner(
`Fetching Projects for ${link(repoUrl)} under ${chalk.bold(org.slug)}`
);
// TODO: Add pagination to fetch all Projects
const query = new URLSearchParams({ repoUrl, limit: '100' });
const projects: Project[] = await client.fetch(`/v2/projects?${query}`);
let projects: Project[] = [];
const query = new URLSearchParams({ repoUrl });
const projectsIterator = client.fetchPaginated<{
projects: Project[];
}>(`/v9/projects?${query}`);
let printedFound = false;
for await (const chunk of projectsIterator) {
projects = projects.concat(chunk.projects);
if (!printedFound && projects.length > 0) {
output.log(
`${pluralize('Project', chunk.projects.length)} linked to ${link(
repoUrl
)} under ${chalk.bold(org.slug)}:`
);
printedFound = true;
}
for (const project of chunk.projects) {
output.print(` * ${chalk.cyan(`${org.slug}/${project.name}\n`)}`);
}
if (chunk.pagination.next) {
output.spinner(`Found ${chalk.bold(projects.length)} Projects…`, 0);
}
}
if (projects.length === 0) {
output.log(
`No Projects are linked to ${link(repoUrl)} under ${chalk.bold(
@@ -140,24 +161,17 @@ export async function ensureRepoLink(
// TODO: run detection logic to find potential projects.
// then prompt user to select valid projects.
// then create new Projects
} else {
output.log(
`Found ${chalk.bold(projects.length)} ${pluralize(
'Project',
projects.length
)} linked to ${link(repoUrl)} under ${chalk.bold(org.slug)}:`
);
}
for (const project of projects) {
output.print(` * ${chalk.cyan(`${org.slug}/${project.name}\n`)}`);
}
shouldLink =
yes ||
(await confirm(
client,
`Link to ${projects.length === 1 ? 'it' : 'them'}?`,
`Link to ${
projects.length === 1
? 'this Project'
: `these ${chalk.bold(projects.length)} Projects`
}?`,
true
));

View File

@@ -322,14 +322,17 @@ test('[vercel dev] should handle missing handler errors thrown in edge functions
);
validateResponseHeaders(res);
const { stderr } = await dev.kill();
const { stdout } = await dev.kill();
expect(await res.text()).toMatch(
/<strong>500<\/strong>: INTERNAL_SERVER_ERROR/g
);
expect(stderr).toMatch(
/No default export was found. Add a default export to handle requests./g
);
const url = `http://localhost:${port}/api/edge-error-no-handler`;
expect(stdout).toMatchInlineSnapshot(`
"Error from API Route /api/edge-error-no-handler: No default or HTTP-named export was found at ${url}. Add one to handle requests. Learn more: https://vercel.link/creating-edge-middleware
at (api/edge-error-no-handler.js)
"
`);
} finally {
await dev.kill();
}

View File

@@ -0,0 +1,3 @@
foo=bar
# the next line is not supported
use-node-version=16.16.0

View File

@@ -0,0 +1 @@
FOO=bar

View File

@@ -0,0 +1,7 @@
{
"orgId": ".",
"projectId": ".",
"settings": {
"framework": null
}
}

View File

@@ -0,0 +1,5 @@
<html>
<body>
Hello world!
</body>
</html>

View File

@@ -1154,4 +1154,24 @@ describe('build', () => {
delete process.env.STORYBOOK_DISABLE_TELEMETRY;
}
});
it('should error if .npmrc exists containing use-node-version', async () => {
const cwd = fixture('npmrc-use-node-version');
client.cwd = cwd;
client.setArgv('build');
const exitCodePromise = build(client);
await expect(client.stderr).toOutput('Error: Detected unsupported');
await expect(exitCodePromise).resolves.toEqual(1);
});
it('should ignore `.env` for static site', async () => {
const cwd = fixture('static-env');
const output = join(cwd, '.vercel/output');
client.cwd = cwd;
const exitCode = await build(client);
expect(exitCode).toEqual(0);
expect(fs.existsSync(join(output, 'static', 'index.html'))).toBe(true);
expect(fs.existsSync(join(output, 'static', '.env'))).toBe(false);
});
});

View File

@@ -1,5 +1,12 @@
# @vercel/client
## 12.6.2
### Patch Changes
- Updated dependencies [[`cd35071f6`](https://github.com/vercel/vercel/commit/cd35071f609d615d47bc04634c123b33768436cb)]:
- @vercel/build-utils@6.7.5
## 12.6.1
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/client",
"version": "12.6.1",
"version": "12.6.2",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"homepage": "https://vercel.com",
@@ -35,7 +35,7 @@
"typescript": "4.9.5"
},
"dependencies": {
"@vercel/build-utils": "6.7.4",
"@vercel/build-utils": "6.7.5",
"@vercel/routing-utils": "2.2.1",
"@zeit/fetch": "5.2.0",
"async-retry": "1.2.3",

View File

@@ -35,7 +35,7 @@
"@types/minimatch": "3.0.5",
"@types/node": "14.18.33",
"@types/semver": "7.3.10",
"@vercel/build-utils": "6.7.4",
"@vercel/build-utils": "6.7.5",
"typescript": "4.9.5"
}
}

View File

@@ -1,5 +1,20 @@
# @vercel/gatsby-plugin-vercel-builder
## 1.3.8
### Patch Changes
- Updated dependencies [[`bc5afe24c`](https://github.com/vercel/vercel/commit/bc5afe24c4547dbf798b939199e8212c4b34038e), [`0039c8b5c`](https://github.com/vercel/vercel/commit/0039c8b5cea975316a62c4f6aaca5d66d731cc0d)]:
- @vercel/node@2.15.0
## 1.3.7
### Patch Changes
- Updated dependencies [[`cd35071f6`](https://github.com/vercel/vercel/commit/cd35071f609d615d47bc04634c123b33768436cb)]:
- @vercel/build-utils@6.7.5
- @vercel/node@2.14.5
## 1.3.6
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/gatsby-plugin-vercel-builder",
"version": "1.3.6",
"version": "1.3.8",
"main": "dist/index.js",
"files": [
"dist",
@@ -20,8 +20,8 @@
},
"dependencies": {
"@sinclair/typebox": "0.25.24",
"@vercel/build-utils": "6.7.4",
"@vercel/node": "2.14.4",
"@vercel/build-utils": "6.7.5",
"@vercel/node": "2.15.0",
"@vercel/routing-utils": "2.2.1",
"esbuild": "0.14.47",
"etag": "1.8.1",

View File

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

View File

@@ -21,7 +21,7 @@
"devDependencies": {
"@types/jest": "27.5.1",
"@types/node": "14.18.33",
"@vercel/build-utils": "6.7.4",
"@vercel/build-utils": "6.7.5",
"@vercel/static-config": "2.0.17",
"execa": "3.2.0",
"fs-extra": "11.1.0",

View File

@@ -35,7 +35,7 @@
"@types/semver": "6.0.0",
"@types/text-table": "0.2.1",
"@types/webpack-sources": "3.2.0",
"@vercel/build-utils": "6.7.4",
"@vercel/build-utils": "6.7.5",
"@vercel/nft": "0.22.5",
"@vercel/routing-utils": "2.2.1",
"async-sema": "3.0.1",

View File

@@ -1,5 +1,20 @@
# @vercel/node
## 2.15.0
### Minor Changes
- Add maxDuration config support for vc node deployments ([#10028](https://github.com/vercel/vercel/pull/10028))
- [node] Add isomorphic functions ([#9947](https://github.com/vercel/vercel/pull/9947))
## 2.14.5
### Patch Changes
- Updated dependencies [[`cd35071f6`](https://github.com/vercel/vercel/commit/cd35071f609d615d47bc04634c123b33768436cb)]:
- @vercel/build-utils@6.7.5
## 2.14.4
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/node",
"version": "2.14.4",
"version": "2.15.0",
"license": "Apache-2.0",
"main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/node-js",
@@ -19,10 +19,12 @@
"dist"
],
"dependencies": {
"@edge-runtime/node-utils": "2.0.3",
"@edge-runtime/primitives": "2.1.2",
"@edge-runtime/vm": "2.0.0",
"@types/node": "14.18.33",
"@types/node-fetch": "2.6.3",
"@vercel/build-utils": "6.7.4",
"@vercel/build-utils": "6.7.5",
"@vercel/error-utils": "1.0.10",
"@vercel/static-config": "2.0.17",
"async-listen": "3.0.0",

View File

@@ -10,14 +10,14 @@ function getUrl(url, headers) {
return urlObj.toString();
}
async function respond(userEdgeHandler, event, options, dependencies) {
async function respond(handler, event, options, dependencies) {
const { Request, Response } = dependencies;
const { isMiddleware } = options;
event.request.headers.set(
'host',
event.request.headers.get('x-forwarded-host')
);
let response = await userEdgeHandler(
let response = await handler(
new Request(
getUrl(event.request.url, event.request.headers),
event.request
@@ -62,16 +62,34 @@ async function parseRequestEvent(event) {
// This will be invoked by logic using this template
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function registerFetchListener(userEdgeHandler, options, dependencies) {
function registerFetchListener(module, options, dependencies) {
let handler;
addEventListener('fetch', async event => {
try {
const response = await respond(
userEdgeHandler,
event,
options,
dependencies
);
return event.respondWith(response);
if (typeof module.default === 'function') {
handler = module.default;
} else {
if (
['GET', 'HEAD', 'OPTIONS', 'POST', 'PUT', 'DELETE', 'PATCH'].some(
method => typeof module[method] === 'function'
)
) {
const method = event.request.method ?? 'GET';
handler =
typeof module[method] === 'function'
? module[method]
: () => new dependencies.Response(null, { status: 405 });
}
}
if (!handler) {
const url = getUrl(event.request.url, event.request.headers);
throw new Error(
`No default or HTTP-named export was found at ${url}. Add one to handle requests. Learn more: https://vercel.link/creating-edge-middleware`
);
}
const response = await respond(handler, event, options, dependencies);
event.respondWith(response);
} catch (error) {
event.respondWith(toResponseError(error, dependencies.Response));
}

View File

@@ -89,12 +89,7 @@ async function compileUserCode(
// user code
${compiledFile.text};
const userEdgeHandler = module.exports.default;
if (!userEdgeHandler) {
throw new Error(
'No default export was found. Add a default export to handle requests. Learn more: https://vercel.link/creating-edge-middleware'
);
}
const userModule = module.exports;
// request metadata
const isMiddleware = ${isMiddleware};
@@ -104,7 +99,7 @@ async function compileUserCode(
${edgeHandlerTemplate};
const dependencies = { Request, Response };
const options = { isMiddleware, entrypointLabel };
registerFetchListener(userEdgeHandler, options, dependencies);
registerFetchListener(userModule, options, dependencies);
`;
return {

View File

@@ -506,6 +506,7 @@ export const build: BuildV3 = async ({
shouldAddSourcemapSupport,
awsLambdaHandler,
supportsResponseStreaming,
maxDuration: staticConfig?.maxDuration,
});
}

View File

@@ -0,0 +1,76 @@
import type { ServerResponse, IncomingMessage } from 'http';
import type { NodeHandler } from '@edge-runtime/node-utils';
import { buildToNodeHandler } from '@edge-runtime/node-utils';
class FetchEvent {
public request: Request;
public awaiting: Set<Promise<void>>;
public response: Response | null;
constructor(request: Request) {
this.request = request;
this.response = null;
this.awaiting = new Set();
}
respondWith(response: Response) {
this.response = response;
}
waitUntil() {
throw new Error('waitUntil is not implemented yet for Node.js');
}
}
const webHandlerToNodeHandler = buildToNodeHandler(
{
Headers,
ReadableStream,
Request: class extends Request {
constructor(input: RequestInfo | URL, init?: RequestInit | undefined) {
super(input, addDuplexToInit(init));
}
},
Uint8Array: Uint8Array,
FetchEvent: FetchEvent,
},
{ defaultOrigin: 'https://vercel.com' }
);
/**
* When users export at least one HTTP handler, we will generate
* a generic handler routing to the right method. If there is no
* handler function exported returns null.
*/
export function getWebExportsHandler(listener: any, methods: string[]) {
const handlerByMethod: { [key: string]: NodeHandler } = {};
for (const key of methods) {
handlerByMethod[key] =
typeof listener[key] !== 'undefined'
? webHandlerToNodeHandler(listener[key])
: defaultHttpHandler;
}
return (req: IncomingMessage, res: ServerResponse) => {
const method = req.method ?? 'GET';
handlerByMethod[method](req, res);
};
}
/**
* Add `duplex: 'half'` by default to all requests
* https://github.com/vercel/edge-runtime/blob/bf167c418247a79d3941bfce4a5d43c37f512502/packages/primitives/src/primitives/fetch.js#L22-L26
* https://developer.chrome.com/articles/fetch-streaming-requests/#streaming-request-bodies
*/
function addDuplexToInit(init: RequestInit | undefined) {
if (typeof init === 'undefined' || typeof init === 'object') {
return { duplex: 'half', ...init };
}
return init;
}
function defaultHttpHandler(_: IncomingMessage, res: ServerResponse) {
res.statusCode = 405;
res.end();
}

View File

@@ -21,40 +21,63 @@ type ServerlessFunctionSignature = (
res: ServerResponse | VercelResponse
) => void;
async function createServerlessServer(
userCode: ServerlessFunctionSignature,
options: ServerlessServerOptions
) {
const server = createServer(async (req, res) => {
if (options.shouldAddHelpers) await addHelpers(req, res);
return userCode(req, res);
});
const [NODE_MAJOR] = process.versions.node.split('.').map(v => Number(v));
/* https://nextjs.org/docs/app/building-your-application/routing/router-handlers#supported-http-methods */
const HTTP_METHODS = [
'GET',
'HEAD',
'OPTIONS',
'POST',
'PUT',
'DELETE',
'PATCH',
];
async function createServerlessServer(userCode: ServerlessFunctionSignature) {
const server = createServer(userCode);
exitHook(() => server.close());
return { url: await listen(server) };
}
async function compileUserCode(entrypointPath: string) {
async function compileUserCode(
entrypointPath: string,
options: ServerlessServerOptions
) {
const id = isAbsolute(entrypointPath)
? pathToFileURL(entrypointPath).href
: entrypointPath;
let fn = await import(id);
let listener = await import(id);
/**
* In some cases we might have nested default props due to TS => JS
*/
for (let i = 0; i < 5; i++) {
if (fn.default) fn = fn.default;
if (listener.default) listener = listener.default;
}
return fn;
if (HTTP_METHODS.some(method => typeof listener[method] === 'function')) {
if (NODE_MAJOR < 18) {
throw new Error(
'Node.js v18 or above is required to use HTTP method exports in your functions.'
);
}
const { getWebExportsHandler } = await import('./helpers-web.js');
return getWebExportsHandler(listener, HTTP_METHODS);
}
return async (req: IncomingMessage, res: ServerResponse) => {
if (options.shouldAddHelpers) await addHelpers(req, res);
return listener(req, res);
};
}
export async function createServerlessEventHandler(
entrypointPath: string,
options: ServerlessServerOptions
): Promise<(request: IncomingMessage) => Promise<VercelProxyResponse>> {
const userCode = await compileUserCode(entrypointPath);
const server = await createServerlessServer(userCode, options);
const userCode = await compileUserCode(entrypointPath, options);
const server = await createServerlessServer(userCode);
return async function (request: IncomingMessage) {
const url = new URL(request.url ?? '/', server.url);

View File

@@ -59,7 +59,12 @@ export function entrypointToOutputPath(
}
export function logError(error: Error) {
console.error(error.message);
let message = error.message;
if (!message.startsWith('Error:')) {
message = `Error: ${message}`;
}
console.error(message);
if (error.stack) {
// only show the stack trace if debug is enabled
// because it points to internals, not user code

View File

@@ -0,0 +1,10 @@
/* global Response */
const baseUrl = ({ headers }) =>
`${headers.get('x-forwarded-proto')}://${headers.get('x-forwarded-host')}`;
export function GET(request) {
const { searchParams } = new URL(request.url, baseUrl(request));
const name = searchParams.get('name');
return new Response(`Greetings, ${name}`);
}

View File

@@ -4,6 +4,8 @@ import fetch from 'node-fetch';
jest.setTimeout(20 * 1000);
const [NODE_MAJOR] = process.versions.node.split('.').map(v => Number(v));
function testForkDevServer(entrypoint: string) {
const ext = extname(entrypoint);
const isTypeScript = ext === '.ts';
@@ -24,6 +26,41 @@ function testForkDevServer(entrypoint: string) {
});
}
(NODE_MAJOR < 18 ? test.skip : test)(
'runs an serverless function that exports GET',
async () => {
const child = testForkDevServer('./serverless-web.js');
try {
const result = await readMessage(child);
if (result.state !== 'message') {
throw new Error('Exited. error: ' + JSON.stringify(result.value));
}
const { address, port } = result.value;
{
const response = await fetch(
`http://${address}:${port}/api/serverless-web?name=Vercel`
);
expect({
status: response.status,
body: await response.text(),
}).toEqual({ status: 200, body: 'Greetings, Vercel' });
}
{
const response = await fetch(
`http://${address}:${port}/api/serverless-web?name=Vercel`,
{ method: 'HEAD' }
);
expect({ status: response.status }).toEqual({ status: 405 });
}
} finally {
child.kill(9);
}
}
);
test('runs an edge function that uses `WebSocket`', async () => {
const child = testForkDevServer('./edge-websocket.js');
try {
@@ -57,9 +94,8 @@ test('runs an edge function that uses `buffer`', async () => {
throw new Error('Exited. error: ' + JSON.stringify(result.value));
}
const response = await fetch(
`http://localhost:${result.value.port}/api/edge-buffer`
);
const { address, port } = result.value;
const response = await fetch(`http://${address}:${port}/api/edge-buffer`);
expect({
status: response.status,
json: await response.json(),
@@ -84,9 +120,8 @@ test('runs a mjs endpoint', async () => {
throw new Error('Exited. error: ' + JSON.stringify(result.value));
}
const response = await fetch(
`http://localhost:${result.value.port}/api/hello`
);
const { address, port } = result.value;
const response = await fetch(`http://${address}:${port}/api/hello`);
expect({
status: response.status,
headers: Object.fromEntries(response.headers),
@@ -117,9 +152,8 @@ test('runs a esm typescript endpoint', async () => {
throw new Error('Exited. error: ' + JSON.stringify(result.value));
}
const response = await fetch(
`http://localhost:${result.value.port}/api/hello`
);
const { address, port } = result.value;
const response = await fetch(`http://${address}:${port}/api/hello`);
expect({
status: response.status,
headers: Object.fromEntries(response.headers),
@@ -150,9 +184,8 @@ test('allow setting multiple cookies with same name', async () => {
throw new Error(`Exited. error: ${JSON.stringify(result.value)}`);
}
const response = await fetch(
`http://localhost:${result.value.port}/api/hello`
);
const { address, port } = result.value;
const response = await fetch(`http://${address}:${port}/api/hello`);
expect({
status: response.status,
text: await response.text(),

View File

@@ -23,7 +23,7 @@
"@types/execa": "^0.9.0",
"@types/jest": "27.4.1",
"@types/node": "14.18.33",
"@vercel/build-utils": "6.7.4",
"@vercel/build-utils": "6.7.5",
"@vercel/ncc": "0.24.0",
"execa": "^1.0.0"
}

View File

@@ -27,7 +27,7 @@
"@types/aws-lambda": "8.10.19",
"@types/node": "14.18.33",
"@types/semver": "6.0.0",
"@vercel/build-utils": "6.7.4",
"@vercel/build-utils": "6.7.5",
"execa": "3.2.0",
"fs-extra": "11.1.0"
}

View File

@@ -1,5 +1,18 @@
# @vercel/remix-builder
## 1.8.13
### Patch Changes
- Update `@remix-run/dev` fork to v1.17.0 ([#10072](https://github.com/vercel/vercel/pull/10072))
## 1.8.12
### Patch Changes
- Updated dependencies [[`cd35071f6`](https://github.com/vercel/vercel/commit/cd35071f609d615d47bc04634c123b33768436cb)]:
- @vercel/build-utils@6.7.5
## 1.8.11
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/remix-builder",
"version": "1.8.11",
"version": "1.8.13",
"license": "Apache-2.0",
"main": "./dist/index.js",
"homepage": "https://vercel.com/docs",
@@ -20,8 +20,8 @@
"defaults"
],
"dependencies": {
"@remix-run/dev": "npm:@vercel/remix-run-dev@1.16.1",
"@vercel/build-utils": "6.7.4",
"@remix-run/dev": "npm:@vercel/remix-run-dev@1.17.0",
"@vercel/build-utils": "6.7.5",
"@vercel/nft": "0.22.5",
"@vercel/static-config": "2.0.17",
"path-to-regexp": "6.2.1",

View File

@@ -22,7 +22,7 @@
"devDependencies": {
"@types/fs-extra": "8.0.0",
"@types/semver": "6.0.0",
"@vercel/build-utils": "6.7.4",
"@vercel/build-utils": "6.7.5",
"@vercel/ncc": "0.24.0",
"execa": "2.0.4",
"fs-extra": "^7.0.1",

View File

@@ -1,5 +1,19 @@
# @vercel/static-build
## 1.3.35
### Patch Changes
- Updated dependencies []:
- @vercel/gatsby-plugin-vercel-builder@1.3.8
## 1.3.34
### Patch Changes
- Updated dependencies []:
- @vercel/gatsby-plugin-vercel-builder@1.3.7
## 1.3.33
### Patch Changes

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/static-build",
"version": "1.3.33",
"version": "1.3.35",
"license": "Apache-2.0",
"main": "./dist/index",
"homepage": "https://vercel.com/docs/build-step",
@@ -20,7 +20,7 @@
},
"dependencies": {
"@vercel/gatsby-plugin-vercel-analytics": "1.0.10",
"@vercel/gatsby-plugin-vercel-builder": "1.3.6"
"@vercel/gatsby-plugin-vercel-builder": "1.3.8"
},
"devDependencies": {
"@types/aws-lambda": "8.10.64",
@@ -32,7 +32,7 @@
"@types/node-fetch": "2.5.4",
"@types/promise-timeout": "1.3.0",
"@types/semver": "7.3.13",
"@vercel/build-utils": "6.7.4",
"@vercel/build-utils": "6.7.5",
"@vercel/error-utils": "1.0.10",
"@vercel/frameworks": "1.4.2",
"@vercel/fs-detectors": "3.9.3",

View File

@@ -4,6 +4,7 @@ import { readerFromStreamReader } from 'https://deno.land/std@0.107.0/io/streams
export const config = {
runtime: 'deno',
location: 'https://example.com/page',
maxDuration: 60
};
export default async ({ request }: Deno.RequestEvent) => {

View File

@@ -3,6 +3,7 @@ import fs from 'fs';
export const config = {
runtime: 'nodejs',
memory: 1024,
maxDuration: 60,
};
export default function (req, res) {

View File

@@ -9,6 +9,7 @@ describe('getConfig()', () => {
const config = getConfig(project, sourcePath);
expect(config).toMatchInlineSnapshot(`
{
"maxDuration": 60,
"memory": 1024,
"runtime": "nodejs",
}
@@ -27,6 +28,7 @@ describe('getConfig()', () => {
expect(config).toMatchInlineSnapshot(`
{
"location": "https://example.com/page",
"maxDuration": 60,
"runtime": "deno",
}
`);

View File

@@ -56,6 +56,7 @@ describe('getConfig for swc', () => {
const config = getConfig(ast, BaseFunctionConfigSchema);
expect(config).toMatchInlineSnapshot(`
{
"maxDuration": 60,
"memory": 1024,
"runtime": "nodejs",
}
@@ -73,6 +74,7 @@ describe('getConfig for swc', () => {
expect(config).toMatchInlineSnapshot(`
{
"location": "https://example.com/page",
"maxDuration": 60,
"runtime": "deno",
}
`);

122
pnpm-lock.yaml generated
View File

@@ -86,8 +86,8 @@ importers:
specifier: 29.1.0
version: 29.1.0(@babel/core@7.5.0)(jest@29.5.0)(typescript@4.9.5)
turbo:
specifier: 1.9.9
version: 1.9.9
specifier: 1.10.1
version: 1.10.1
typescript:
specifier: 4.9.5
version: 4.9.5
@@ -135,7 +135,7 @@ importers:
internals/constants:
dependencies:
'@vercel/build-utils':
specifier: 6.7.4
specifier: 6.7.5
version: link:../../packages/build-utils
'@vercel/routing-utils':
specifier: 2.2.1
@@ -187,10 +187,10 @@ importers:
specifier: 14.14.31
version: 14.14.31
'@vercel-internals/constants':
specifier: 1.0.1
specifier: 1.0.2
version: link:../constants
'@vercel/build-utils':
specifier: 6.7.4
specifier: 6.7.5
version: link:../../packages/build-utils
'@vercel/routing-utils':
specifier: 2.2.1
@@ -314,7 +314,7 @@ importers:
packages/cli:
dependencies:
'@vercel/build-utils':
specifier: 6.7.4
specifier: 6.7.5
version: link:../build-utils
'@vercel/go':
specifier: 2.5.1
@@ -326,7 +326,7 @@ importers:
specifier: 3.8.6
version: link:../next
'@vercel/node':
specifier: 2.14.4
specifier: 2.15.0
version: link:../node
'@vercel/python':
specifier: 3.1.60
@@ -335,13 +335,13 @@ importers:
specifier: 1.1.15
version: link:../redwood
'@vercel/remix-builder':
specifier: 1.8.11
specifier: 1.8.13
version: link:../remix
'@vercel/ruby':
specifier: 1.3.76
version: link:../ruby
'@vercel/static-build':
specifier: 1.3.33
specifier: 1.3.35
version: link:../static-build
devDependencies:
'@alex_neo/jest-expect-message':
@@ -468,16 +468,16 @@ importers:
specifier: 2.1.0
version: 2.1.0
'@vercel-internals/constants':
specifier: 1.0.1
specifier: 1.0.2
version: link:../../internals/constants
'@vercel-internals/get-package-json':
specifier: 1.0.0
version: link:../../internals/get-package-json
'@vercel-internals/types':
specifier: 1.0.1
specifier: 1.0.2
version: link:../../internals/types
'@vercel/client':
specifier: 12.6.1
specifier: 12.6.2
version: link:../client
'@vercel/error-utils':
specifier: 1.0.10
@@ -735,7 +735,7 @@ importers:
packages/client:
dependencies:
'@vercel/build-utils':
specifier: 6.7.4
specifier: 6.7.5
version: link:../build-utils
'@vercel/routing-utils':
specifier: 2.2.1
@@ -924,7 +924,7 @@ importers:
specifier: 7.3.10
version: 7.3.10
'@vercel/build-utils':
specifier: 6.7.4
specifier: 6.7.5
version: link:../build-utils
typescript:
specifier: 4.9.5
@@ -952,10 +952,10 @@ importers:
specifier: 0.25.24
version: 0.25.24
'@vercel/build-utils':
specifier: 6.7.4
specifier: 6.7.5
version: link:../build-utils
'@vercel/node':
specifier: 2.14.4
specifier: 2.15.0
version: link:../node
'@vercel/routing-utils':
specifier: 2.2.1
@@ -1016,7 +1016,7 @@ importers:
specifier: 2.1.0
version: 2.1.0
'@vercel/build-utils':
specifier: 6.7.4
specifier: 6.7.5
version: link:../build-utils
'@vercel/ncc':
specifier: 0.24.0
@@ -1058,7 +1058,7 @@ importers:
specifier: 14.18.33
version: 14.18.33
'@vercel/build-utils':
specifier: 6.7.4
specifier: 6.7.5
version: link:../build-utils
'@vercel/static-config':
specifier: 2.0.17
@@ -1115,7 +1115,7 @@ importers:
specifier: 3.2.0
version: 3.2.0
'@vercel/build-utils':
specifier: 6.7.4
specifier: 6.7.5
version: link:../build-utils
'@vercel/nft':
specifier: 0.22.5
@@ -1189,6 +1189,12 @@ importers:
packages/node:
dependencies:
'@edge-runtime/node-utils':
specifier: 2.0.3
version: 2.0.3
'@edge-runtime/primitives':
specifier: 2.1.2
version: 2.1.2
'@edge-runtime/vm':
specifier: 2.0.0
version: 2.0.0
@@ -1199,7 +1205,7 @@ importers:
specifier: 2.6.3
version: 2.6.3
'@vercel/build-utils':
specifier: 6.7.4
specifier: 6.7.5
version: link:../build-utils
'@vercel/error-utils':
specifier: 1.0.10
@@ -1308,7 +1314,7 @@ importers:
specifier: 14.18.33
version: 14.18.33
'@vercel/build-utils':
specifier: 6.7.4
specifier: 6.7.5
version: link:../build-utils
'@vercel/ncc':
specifier: 0.24.0
@@ -1339,7 +1345,7 @@ importers:
specifier: 6.0.0
version: 6.0.0
'@vercel/build-utils':
specifier: 6.7.4
specifier: 6.7.5
version: link:../build-utils
execa:
specifier: 3.2.0
@@ -1351,10 +1357,10 @@ importers:
packages/remix:
dependencies:
'@remix-run/dev':
specifier: npm:@vercel/remix-run-dev@1.16.1
version: /@vercel/remix-run-dev@1.16.1(@types/node@14.18.33)
specifier: npm:@vercel/remix-run-dev@1.17.0
version: /@vercel/remix-run-dev@1.17.0(@types/node@14.18.33)
'@vercel/build-utils':
specifier: 6.7.4
specifier: 6.7.5
version: link:../build-utils
'@vercel/nft':
specifier: 0.22.5
@@ -1411,7 +1417,7 @@ importers:
specifier: 6.0.0
version: 6.0.0
'@vercel/build-utils':
specifier: 6.7.4
specifier: 6.7.5
version: link:../build-utils
'@vercel/ncc':
specifier: 0.24.0
@@ -1432,7 +1438,7 @@ importers:
specifier: 1.0.10
version: link:../gatsby-plugin-vercel-analytics
'@vercel/gatsby-plugin-vercel-builder':
specifier: 1.3.6
specifier: 1.3.8
version: link:../gatsby-plugin-vercel-builder
devDependencies:
'@types/aws-lambda':
@@ -1463,7 +1469,7 @@ importers:
specifier: 7.3.13
version: 7.3.13
'@vercel/build-utils':
specifier: 6.7.4
specifier: 6.7.5
version: link:../build-utils
'@vercel/error-utils':
specifier: 1.0.10
@@ -3152,7 +3158,6 @@ packages:
/@edge-runtime/node-utils@2.0.3:
resolution: {integrity: sha512-JUSbi5xu/A8+D2t9B9wfirCI1J8n8q0660FfmqZgA+n3RqxD3y7SnamL1sKRE5/AbHsKs9zcqCbK2YDklbc9Bg==}
engines: {node: '>=14'}
dev: true
/@edge-runtime/primitives@2.0.0:
resolution: {integrity: sha512-AXqUq1zruTJAICrllUvZcgciIcEGHdF6KJ3r6FM0n4k8LpFxZ62tPWVIJ9HKm+xt+ncTBUZxwgUaQ73QMUQEKw==}
@@ -4147,16 +4152,16 @@ packages:
tslib: 2.5.0
dev: true
/@remix-run/router@1.6.2:
resolution: {integrity: sha512-LzqpSrMK/3JBAVBI9u3NWtOhWNw5AMQfrUFYB0+bDHTSw17z++WJLsPsxAuK+oSddsxk4d7F/JcdDPM1M5YAhA==}
/@remix-run/router@1.6.3:
resolution: {integrity: sha512-EXJysQ7J3veRECd0kZFQwYYd5sJMcq2O/m60zu1W2l3oVQ9xtub8jTOtYRE0+M2iomyG/W3Ps7+vp2kna0C27Q==}
engines: {node: '>=14'}
dev: false
/@remix-run/server-runtime@1.16.1:
resolution: {integrity: sha512-HG+f3PGE9kzTTPe5i5Hv7UGrJLmFID1Ae4BMohP5e0xXOxbdlKDPj6NN6yGDgE7OqKFuDVliW2B5LlUdJZgUFw==}
/@remix-run/server-runtime@1.17.0:
resolution: {integrity: sha512-xcUXaOibfIFZlvuyuWouz/t3fYhHCqRoKeGxQFGd1BvQBCmPaiau7B1Ao4aJFKyY7eU/L35KCaGzZBTdIF+d5w==}
engines: {node: '>=14'}
dependencies:
'@remix-run/router': 1.6.2
'@remix-run/router': 1.6.3
'@web3-storage/multipart-parser': 1.0.0
cookie: 0.4.2
set-cookie-parser: 2.5.1
@@ -5956,12 +5961,12 @@ packages:
- encoding
- supports-color
/@vercel/remix-run-dev@1.16.1(@types/node@14.18.33):
resolution: {integrity: sha512-b+gIUNqW9JwPKHSfGs0ylMk9U80dbvEmkjczNmyWvO7r1tz8O9dEmTUmbJ22/aRPPJQ/aEYosqP7UNJtDvieqw==}
/@vercel/remix-run-dev@1.17.0(@types/node@14.18.33):
resolution: {integrity: sha512-S71dx9sxHi/9Ery9za+ryQYNq5rEA/OeWFaKalHsgA7jYhiJC2U2iP9lV4m251oLXp3K6J8gwY0zF1CWmA7ANA==}
engines: {node: '>=14'}
hasBin: true
peerDependencies:
'@remix-run/serve': ^1.16.1
'@remix-run/serve': ^1.17.0
peerDependenciesMeta:
'@remix-run/serve':
optional: true
@@ -5976,7 +5981,7 @@ packages:
'@babel/traverse': 7.21.5
'@babel/types': 7.21.5
'@npmcli/package-json': 2.0.0
'@remix-run/server-runtime': 1.16.1
'@remix-run/server-runtime': 1.17.0
'@vanilla-extract/integration': 6.2.1(@types/node@14.18.33)
arg: 5.0.2
cacache: 15.3.0
@@ -6001,6 +6006,7 @@ packages:
minimatch: 9.0.0
node-fetch: 2.6.9
ora: 5.4.1
picomatch: 2.3.1
postcss: 8.4.21
postcss-discard-duplicates: 5.1.0(postcss@8.4.21)
postcss-load-config: 4.0.1(postcss@8.4.21)
@@ -16247,65 +16253,65 @@ packages:
safe-buffer: 5.2.1
dev: true
/turbo-darwin-64@1.9.9:
resolution: {integrity: sha512-UDGM9E21eCDzF5t1F4rzrjwWutcup33e7ZjNJcW/mJDPorazZzqXGKEPIy9kXwKhamUUXfC7668r6ZuA1WXF2Q==}
/turbo-darwin-64@1.10.1:
resolution: {integrity: sha512-isLLoPuAOMNsYovOq9BhuQOZWQuU13zYsW988KkkaA4OJqOn7qwa9V/KBYCJL8uVQqtG+/Y42J37lO8RJjyXuA==}
cpu: [x64]
os: [darwin]
requiresBuild: true
dev: true
optional: true
/turbo-darwin-arm64@1.9.9:
resolution: {integrity: sha512-VyfkXzTJpYLTAQ9krq2myyEq7RPObilpS04lgJ4OO1piq76RNmSpX9F/t9JCaY9Pj/4TL7i0d8PM7NGhwEA5Ag==}
/turbo-darwin-arm64@1.10.1:
resolution: {integrity: sha512-x1nloPR10fLElNCv17BKr0kCx/O5gse/UXAcVscMZH2tvRUtXrdBmut62uw2YU3J9hli2fszYjUWXkulVpQvFA==}
cpu: [arm64]
os: [darwin]
requiresBuild: true
dev: true
optional: true
/turbo-linux-64@1.9.9:
resolution: {integrity: sha512-Fu1MY29Odg8dHOqXcpIIGC3T63XLOGgnGfbobXMKdrC7JQDvtJv8TUCYciRsyknZYjyyKK1z6zKuYIiDjf3KeQ==}
/turbo-linux-64@1.10.1:
resolution: {integrity: sha512-abV+ODCeOlz0503OZlHhPWdy3VwJZc1jObf1VQj7uQM+JqJ/kXbMyqJIMQVz+m7QJUFdferYPRxGhYT/NbYK7Q==}
cpu: [x64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/turbo-linux-arm64@1.9.9:
resolution: {integrity: sha512-50LI8NafPuJxdnMCBeDdzgyt1cgjQG7FwkyY336v4e95WJPUVjrHdrKH6jYXhOUyrv9+jCJxwX1Yrg02t5yJ1g==}
/turbo-linux-arm64@1.10.1:
resolution: {integrity: sha512-zRC3nZbHQ63tofOmbuySzEn1ROISWTkemYYr1L98rpmT5aVa0kERlGiYcfDwZh3cBso/Ylg/wxexRAaPzcCJYQ==}
cpu: [arm64]
os: [linux]
requiresBuild: true
dev: true
optional: true
/turbo-windows-64@1.9.9:
resolution: {integrity: sha512-9IsTReoLmQl1IRsy3WExe2j2RKWXQyXujfJ4fXF+jp08KxjVF4/tYP2CIRJx/A7UP/7keBta27bZqzAjsmbSTA==}
/turbo-windows-64@1.10.1:
resolution: {integrity: sha512-Irqz8IU+o7Q/5V44qatZBTunk+FQAOII1hZTsEU54ah62f9Y297K6/LSp+yncmVQOZlFVccXb6MDqcETExIQtA==}
cpu: [x64]
os: [win32]
requiresBuild: true
dev: true
optional: true
/turbo-windows-arm64@1.9.9:
resolution: {integrity: sha512-CUu4hpeQo68JjDr0V0ygTQRLbS+/sNfdqEVV+Xz9136vpKn2WMQLAuUBVZV0Sp0S/7i+zGnplskT0fED+W46wQ==}
/turbo-windows-arm64@1.10.1:
resolution: {integrity: sha512-124IT15d2gyjC+NEn11pHOaVFvZDRHpxfF+LDUzV7YxfNIfV0mGkR3R/IyVXtQHOgqOdtQTbC4y411sm31+SEw==}
cpu: [arm64]
os: [win32]
requiresBuild: true
dev: true
optional: true
/turbo@1.9.9:
resolution: {integrity: sha512-+ZS66LOT7ahKHxh6XrIdcmf2Yk9mNpAbPEj4iF2cs0cAeaDU3xLVPZFF0HbSho89Uxwhx7b5HBgPbdcjQTwQkg==}
/turbo@1.10.1:
resolution: {integrity: sha512-wq0YeSv6P/eEDXOL42jkMUr+T4z34dM8mdHu5u6C6OOAq8JuLJ72F/v4EVR1JmY8icyTkFz10ICLV0haUUYhbQ==}
hasBin: true
requiresBuild: true
optionalDependencies:
turbo-darwin-64: 1.9.9
turbo-darwin-arm64: 1.9.9
turbo-linux-64: 1.9.9
turbo-linux-arm64: 1.9.9
turbo-windows-64: 1.9.9
turbo-windows-arm64: 1.9.9
turbo-darwin-64: 1.10.1
turbo-darwin-arm64: 1.10.1
turbo-linux-64: 1.10.1
turbo-linux-arm64: 1.10.1
turbo-windows-64: 1.10.1
turbo-windows-arm64: 1.10.1
dev: true
/tweetnacl@0.14.5: