mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-12 12:57:47 +00:00
Compare commits
13 Commits
@vercel/py
...
@vercel/no
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
54514a44af | ||
|
|
0db8fadf74 | ||
|
|
6f01e5ab75 | ||
|
|
78d45f9e7e | ||
|
|
22e1a6a9ce | ||
|
|
8391734b5e | ||
|
|
6a7fa1526c | ||
|
|
64b15d2409 | ||
|
|
40f73e7978 | ||
|
|
4c9ca27195 | ||
|
|
a847ef43fd | ||
|
|
3b466232a9 | ||
|
|
efdeea9db2 |
1
.github/workflows/publish.yml
vendored
1
.github/workflows/publish.yml
vendored
@@ -61,6 +61,7 @@ jobs:
|
||||
if: ${{ steps.check-release.outputs.IS_RELEASE == 'true' }}
|
||||
run: pnpm publish-from-github
|
||||
env:
|
||||
NPM_CONFIG_PROVENANCE: 'true'
|
||||
NPM_TOKEN: ${{ secrets.NPM_TOKEN_ELEVATED }}
|
||||
GA_TRACKING_ID: ${{ secrets.GA_TRACKING_ID }}
|
||||
SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
import { RemixServer } from "@remix-run/react";
|
||||
import { handleRequest } from "@vercel/remix";
|
||||
import type { EntryContext } from "@vercel/remix";
|
||||
|
||||
export default function (
|
||||
request: Request,
|
||||
responseStatusCode: number,
|
||||
responseHeaders: Headers,
|
||||
remixContext: EntryContext
|
||||
) {
|
||||
const remixServer = <RemixServer context={remixContext} url={request.url} />;
|
||||
return handleRequest(
|
||||
request,
|
||||
responseStatusCode,
|
||||
responseHeaders,
|
||||
remixServer
|
||||
);
|
||||
}
|
||||
@@ -6,6 +6,7 @@
|
||||
"dev": "remix dev"
|
||||
},
|
||||
"dependencies": {
|
||||
"@remix-run/node": "^1.14.3",
|
||||
"@remix-run/react": "^1.14.3",
|
||||
"@remix-run/serve": "^1.14.3",
|
||||
"@vercel/analytics": "^0.1.11",
|
||||
|
||||
2
examples/remix/pnpm-lock.yaml
generated
2
examples/remix/pnpm-lock.yaml
generated
@@ -6,6 +6,7 @@ importers:
|
||||
specifiers:
|
||||
'@remix-run/dev': ^1.14.3
|
||||
'@remix-run/eslint-config': ^1.14.3
|
||||
'@remix-run/node': ^1.14.3
|
||||
'@remix-run/react': ^1.14.3
|
||||
'@remix-run/serve': ^1.14.3
|
||||
'@types/react': ^18.0.25
|
||||
@@ -17,6 +18,7 @@ importers:
|
||||
react-dom: ^18.2.0
|
||||
typescript: ^4.9.3
|
||||
dependencies:
|
||||
'@remix-run/node': 1.14.3
|
||||
'@remix-run/react': 1.14.3_biqbaboplfbrettd7655fr4n2y
|
||||
'@remix-run/serve': 1.14.3
|
||||
'@vercel/analytics': 0.1.11_react@18.2.0
|
||||
|
||||
12
package.json
12
package.json
@@ -32,7 +32,7 @@
|
||||
"source-map-support": "0.5.12",
|
||||
"ts-eager": "2.0.2",
|
||||
"ts-jest": "28.0.5",
|
||||
"turbo": "1.8.3"
|
||||
"turbo": "1.8.5"
|
||||
},
|
||||
"scripts": {
|
||||
"lerna": "lerna",
|
||||
@@ -42,14 +42,14 @@
|
||||
"publish-canary": "git checkout main && git pull && lerna version prerelease --preid canary --message \"Publish Canary\" --exact",
|
||||
"publish-from-github": "./utils/publish.sh",
|
||||
"changelog": "node utils/changelog.js",
|
||||
"build": "node utils/gen.js && turbo run build",
|
||||
"build": "node utils/gen.js && turbo --no-update-notifier run build",
|
||||
"vercel-build": "pnpm build && pnpm run pack && cd api && node -r ts-eager/register ./_lib/script/build.ts",
|
||||
"pre-commit": "lint-staged",
|
||||
"test": "jest --rootDir=\"test\" --testPathPattern=\"\\.test.js\"",
|
||||
"test-unit": "pnpm test && node utils/gen.js && turbo run test-unit",
|
||||
"test-cli": "node utils/gen.js && turbo run test-cli",
|
||||
"test-e2e": "node utils/gen.js && turbo run test-e2e",
|
||||
"test-dev": "node utils/gen.js && turbo run test-dev",
|
||||
"test-unit": "pnpm test && node utils/gen.js && turbo --no-update-notifier run test-unit",
|
||||
"test-cli": "node utils/gen.js && turbo --no-update-notifier run test-cli",
|
||||
"test-e2e": "node utils/gen.js && turbo --no-update-notifier run test-e2e",
|
||||
"test-dev": "node utils/gen.js && turbo --no-update-notifier run test-dev",
|
||||
"lint": "eslint . --cache --ext .ts,.js",
|
||||
"prettier-check": "prettier --check .",
|
||||
"prepare": "husky install",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/build-utils",
|
||||
"version": "6.5.0",
|
||||
"version": "6.6.0",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.js",
|
||||
|
||||
@@ -487,6 +487,7 @@ export function getEnvForPackageManager({
|
||||
const oldPath = env.PATH + '';
|
||||
const npm7 = '/node16/bin-npm7';
|
||||
const pnpm7 = '/pnpm7/node_modules/.bin';
|
||||
const pnpm8 = '/pnpm8/node_modules/.bin';
|
||||
const corepackEnabled = env.ENABLE_EXPERIMENTAL_COREPACK === '1';
|
||||
if (cliType === 'npm') {
|
||||
if (
|
||||
@@ -509,7 +510,20 @@ export function getEnvForPackageManager({
|
||||
) {
|
||||
// Ensure that pnpm 7 is at the beginning of the `$PATH`
|
||||
newEnv.PATH = `${pnpm7}${path.delimiter}${oldPath}`;
|
||||
console.log('Detected `pnpm-lock.yaml` generated by pnpm 7...');
|
||||
console.log(
|
||||
`Detected \`pnpm-lock.yaml\` version ${lockfileVersion} generated by pnpm 7...`
|
||||
);
|
||||
} else if (
|
||||
typeof lockfileVersion === 'number' &&
|
||||
lockfileVersion >= 6 &&
|
||||
!oldPath.includes(pnpm8) &&
|
||||
!corepackEnabled
|
||||
) {
|
||||
// Ensure that pnpm 8 is at the beginning of the `$PATH`
|
||||
newEnv.PATH = `${pnpm8}${path.delimiter}${oldPath}`;
|
||||
console.log(
|
||||
`Detected \`pnpm-lock.yaml\` version ${lockfileVersion} generated by pnpm 8...`
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// Yarn v2 PnP mode may be activated, so force "node-modules" linker style
|
||||
|
||||
@@ -14,10 +14,11 @@ export function getPrefixedEnvVars({
|
||||
envs: Envs;
|
||||
}): Envs {
|
||||
const vercelSystemEnvPrefix = 'VERCEL_';
|
||||
const allowed = ['VERCEL_URL', 'VERCEL_ENV', 'VERCEL_REGION'];
|
||||
const newEnvs: Envs = {};
|
||||
if (envPrefix && envs.VERCEL_URL) {
|
||||
Object.keys(envs)
|
||||
.filter(key => key.startsWith(vercelSystemEnvPrefix))
|
||||
.filter(key => allowed.includes(key) || key.startsWith('VERCEL_GIT_'))
|
||||
.forEach(key => {
|
||||
const newKey = `${envPrefix}${key}`;
|
||||
if (!(newKey in envs)) {
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
"probes": [
|
||||
{
|
||||
"path": "/",
|
||||
"mustContain": "pnpm version: 6",
|
||||
"logMustContain": "pnpm run build"
|
||||
"mustContain": "pnpm version: 7"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
9
packages/build-utils/test/fixtures/27-pnpm-v7/package.json
vendored
Normal file
9
packages/build-utils/test/fixtures/27-pnpm-v7/package.json
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "mkdir -p public && (printf \"pnpm version: \" && pnpm -v) > public/index.txt"
|
||||
},
|
||||
"dependencies": {
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
}
|
||||
21
packages/build-utils/test/fixtures/27-pnpm-v7/pnpm-lock.yaml
generated
vendored
Normal file
21
packages/build-utils/test/fixtures/27-pnpm-v7/pnpm-lock.yaml
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
lockfileVersion: 5.4
|
||||
|
||||
importers:
|
||||
|
||||
.:
|
||||
specifiers:
|
||||
once: ^1.4.0
|
||||
dependencies:
|
||||
once: 1.4.0
|
||||
|
||||
packages:
|
||||
|
||||
/once/1.4.0:
|
||||
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
|
||||
dependencies:
|
||||
wrappy: 1.0.2
|
||||
dev: false
|
||||
|
||||
/wrappy/1.0.2:
|
||||
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
||||
dev: false
|
||||
1
packages/build-utils/test/fixtures/27-pnpm-v7/pnpm-workspace.yaml
vendored
Normal file
1
packages/build-utils/test/fixtures/27-pnpm-v7/pnpm-workspace.yaml
vendored
Normal file
@@ -0,0 +1 @@
|
||||
# Empty so this is treated as its own pnpm workspace
|
||||
8
packages/build-utils/test/fixtures/27-pnpm-v7/probes.json
vendored
Normal file
8
packages/build-utils/test/fixtures/27-pnpm-v7/probes.json
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"probes": [
|
||||
{
|
||||
"path": "/",
|
||||
"mustContain": "pnpm version: 7"
|
||||
}
|
||||
]
|
||||
}
|
||||
9
packages/build-utils/test/fixtures/28-pnpm-v8/package.json
vendored
Normal file
9
packages/build-utils/test/fixtures/28-pnpm-v8/package.json
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "mkdir -p public && (printf \"pnpm version: \" && pnpm -v) > public/index.txt"
|
||||
},
|
||||
"dependencies": {
|
||||
"once": "^1.4.0"
|
||||
}
|
||||
}
|
||||
21
packages/build-utils/test/fixtures/28-pnpm-v8/pnpm-lock.yaml
generated
vendored
Normal file
21
packages/build-utils/test/fixtures/28-pnpm-v8/pnpm-lock.yaml
generated
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
lockfileVersion: '6.0'
|
||||
|
||||
importers:
|
||||
|
||||
.:
|
||||
dependencies:
|
||||
once:
|
||||
specifier: ^1.4.0
|
||||
version: 1.4.0
|
||||
|
||||
packages:
|
||||
|
||||
/once@1.4.0:
|
||||
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
|
||||
dependencies:
|
||||
wrappy: 1.0.2
|
||||
dev: false
|
||||
|
||||
/wrappy@1.0.2:
|
||||
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
||||
dev: false
|
||||
1
packages/build-utils/test/fixtures/28-pnpm-v8/pnpm-workspace.yaml
vendored
Normal file
1
packages/build-utils/test/fixtures/28-pnpm-v8/pnpm-workspace.yaml
vendored
Normal file
@@ -0,0 +1 @@
|
||||
# Empty so this is treated as its own pnpm workspace
|
||||
8
packages/build-utils/test/fixtures/28-pnpm-v8/probes.json
vendored
Normal file
8
packages/build-utils/test/fixtures/28-pnpm-v8/probes.json
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"probes": [
|
||||
{
|
||||
"path": "/",
|
||||
"mustContain": "pnpm version: 8"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -14,6 +14,7 @@ describe('Test `getPrefixedEnvVars()`', () => {
|
||||
VERCEL: '1',
|
||||
VERCEL_URL: 'example.vercel.sh',
|
||||
USER_ENV_VAR_NOT_VERCEL: 'example.com',
|
||||
VERCEL_ARTIFACTS_TOKEN: 'abc123',
|
||||
FOO: 'bar',
|
||||
},
|
||||
},
|
||||
@@ -28,6 +29,7 @@ describe('Test `getPrefixedEnvVars()`', () => {
|
||||
envPrefix: 'GATSBY_',
|
||||
envs: {
|
||||
USER_ENV_VAR_NOT_VERCEL: 'example.com',
|
||||
VERCEL_ARTIFACTS_TOKEN: 'abc123',
|
||||
FOO: 'bar',
|
||||
VERCEL_URL: 'example.vercel.sh',
|
||||
VERCEL_ENV: 'production',
|
||||
@@ -51,6 +53,7 @@ describe('Test `getPrefixedEnvVars()`', () => {
|
||||
USER_ENV_VAR_NOT_VERCEL: 'example.com',
|
||||
FOO: 'bar',
|
||||
BLARG_VERCEL_THING: 'fake',
|
||||
VERCEL_ARTIFACTS_TOKEN: 'abc123',
|
||||
},
|
||||
},
|
||||
want: {},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vercel",
|
||||
"version": "28.18.0",
|
||||
"version": "28.18.2",
|
||||
"preferGlobal": true,
|
||||
"license": "Apache-2.0",
|
||||
"description": "The command-line interface for Vercel",
|
||||
@@ -32,16 +32,16 @@
|
||||
"node": ">= 14"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/build-utils": "6.5.0",
|
||||
"@vercel/go": "2.4.1",
|
||||
"@vercel/hydrogen": "0.0.59",
|
||||
"@vercel/next": "3.7.0",
|
||||
"@vercel/node": "2.9.14",
|
||||
"@vercel/python": "3.1.55",
|
||||
"@vercel/redwood": "1.1.11",
|
||||
"@vercel/remix-builder": "1.8.0",
|
||||
"@vercel/ruby": "1.3.72",
|
||||
"@vercel/static-build": "1.3.18"
|
||||
"@vercel/build-utils": "6.6.0",
|
||||
"@vercel/go": "2.4.2",
|
||||
"@vercel/hydrogen": "0.0.60",
|
||||
"@vercel/next": "3.7.2",
|
||||
"@vercel/node": "2.10.1",
|
||||
"@vercel/python": "3.1.56",
|
||||
"@vercel/redwood": "1.1.12",
|
||||
"@vercel/remix-builder": "1.8.2",
|
||||
"@vercel/ruby": "1.3.73",
|
||||
"@vercel/static-build": "1.3.20"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@alex_neo/jest-expect-message": "1.0.5",
|
||||
@@ -85,10 +85,10 @@
|
||||
"@types/write-json-file": "2.2.1",
|
||||
"@types/yauzl-promise": "2.1.0",
|
||||
"@vercel-internals/types": "*",
|
||||
"@vercel/client": "12.4.6",
|
||||
"@vercel/client": "12.4.7",
|
||||
"@vercel/error-utils": "1.0.8",
|
||||
"@vercel/frameworks": "1.3.3",
|
||||
"@vercel/fs-detectors": "3.8.6",
|
||||
"@vercel/fs-detectors": "3.8.7",
|
||||
"@vercel/fun": "1.0.4",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"@vercel/routing-utils": "2.1.11",
|
||||
|
||||
@@ -157,6 +157,7 @@ export default async function main(client: Client): Promise<number> {
|
||||
'--output': String,
|
||||
'--prod': Boolean,
|
||||
'--yes': Boolean,
|
||||
'-y': '--yes',
|
||||
});
|
||||
|
||||
if (argv['--help']) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/client",
|
||||
"version": "12.4.6",
|
||||
"version": "12.4.7",
|
||||
"main": "dist/index.js",
|
||||
"typings": "dist/index.d.ts",
|
||||
"homepage": "https://vercel.com",
|
||||
@@ -43,7 +43,7 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/build-utils": "6.5.0",
|
||||
"@vercel/build-utils": "6.6.0",
|
||||
"@vercel/routing-utils": "2.1.11",
|
||||
"@zeit/fetch": "5.2.0",
|
||||
"async-retry": "1.2.3",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/fs-detectors",
|
||||
"version": "3.8.6",
|
||||
"version": "3.8.7",
|
||||
"description": "Vercel filesystem detectors",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -35,7 +35,7 @@
|
||||
"@types/minimatch": "3.0.5",
|
||||
"@types/node": "14.18.33",
|
||||
"@types/semver": "7.3.10",
|
||||
"@vercel/build-utils": "6.5.0",
|
||||
"@vercel/build-utils": "6.6.0",
|
||||
"typescript": "4.3.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/gatsby-plugin-vercel-builder",
|
||||
"version": "1.2.3",
|
||||
"version": "1.2.5",
|
||||
"main": "dist/index.js",
|
||||
"files": [
|
||||
"dist",
|
||||
@@ -15,8 +15,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@sinclair/typebox": "0.25.24",
|
||||
"@vercel/build-utils": "6.5.0",
|
||||
"@vercel/node": "2.9.14",
|
||||
"@vercel/build-utils": "6.6.0",
|
||||
"@vercel/node": "2.10.1",
|
||||
"@vercel/routing-utils": "2.1.11",
|
||||
"esbuild": "0.14.47",
|
||||
"etag": "1.8.1",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/go",
|
||||
"version": "2.4.1",
|
||||
"version": "2.4.2",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/go",
|
||||
@@ -37,7 +37,7 @@
|
||||
"@types/node-fetch": "^2.3.0",
|
||||
"@types/tar": "^4.0.0",
|
||||
"@types/yauzl-promise": "2.1.0",
|
||||
"@vercel/build-utils": "6.5.0",
|
||||
"@vercel/build-utils": "6.6.0",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"async-retry": "1.3.1",
|
||||
"execa": "^1.0.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/hydrogen",
|
||||
"version": "0.0.59",
|
||||
"version": "0.0.60",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index.js",
|
||||
"homepage": "https://vercel.com/docs",
|
||||
@@ -21,7 +21,7 @@
|
||||
"devDependencies": {
|
||||
"@types/jest": "27.5.1",
|
||||
"@types/node": "14.18.33",
|
||||
"@vercel/build-utils": "6.5.0",
|
||||
"@vercel/build-utils": "6.6.0",
|
||||
"@vercel/static-config": "2.0.14",
|
||||
"execa": "3.2.0",
|
||||
"fs-extra": "11.1.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/next",
|
||||
"version": "3.7.0",
|
||||
"version": "3.7.2",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/next-js",
|
||||
@@ -45,7 +45,7 @@
|
||||
"@types/semver": "6.0.0",
|
||||
"@types/text-table": "0.2.1",
|
||||
"@types/webpack-sources": "3.2.0",
|
||||
"@vercel/build-utils": "6.5.0",
|
||||
"@vercel/build-utils": "6.6.0",
|
||||
"@vercel/nft": "0.22.5",
|
||||
"@vercel/routing-utils": "2.1.11",
|
||||
"async-sema": "3.0.1",
|
||||
|
||||
@@ -410,7 +410,6 @@ export const build: BuildV2 = async ({
|
||||
|
||||
const env: typeof process.env = { ...spawnOpts.env };
|
||||
env.NEXT_EDGE_RUNTIME_PROVIDER = 'vercel';
|
||||
env.NEXT_PUBLIC_EDGE_RUNTIME_PROVIDER = env.NEXT_EDGE_RUNTIME_PROVIDER;
|
||||
|
||||
if (target) {
|
||||
// Since version v10.0.8-canary.15 of Next.js the NEXT_PRIVATE_TARGET env
|
||||
@@ -418,13 +417,11 @@ export const build: BuildV2 = async ({
|
||||
// this helps us catch cases where we can't locate the next.config.js
|
||||
// correctly
|
||||
env.NEXT_PRIVATE_TARGET = target;
|
||||
env.NEXT_PUBLIC_TARGET = target;
|
||||
}
|
||||
// Only NEXT_PUBLIC_ is considered for turbo/nx cache keys
|
||||
// and caches may not have the correct trace root so we
|
||||
// need to ensure this included in the cache key
|
||||
env.NEXT_PRIVATE_OUTPUT_TRACE_ROOT = baseDir;
|
||||
env.NEXT_PUBLIC_OUTPUT_TRACE_ROOT = baseDir;
|
||||
|
||||
if (isServerMode) {
|
||||
// when testing with jest NODE_ENV will be set to test so ensure
|
||||
|
||||
@@ -39,19 +39,20 @@ function normalizeProxyEvent(event) {
|
||||
responseCallbackCipherKey,
|
||||
responseCallbackStream,
|
||||
responseCallbackUrl,
|
||||
features,
|
||||
} = payload;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string | Buffer} b
|
||||
* @param {string | Buffer} body
|
||||
* @returns Buffer
|
||||
*/
|
||||
const normalizeBody = b => {
|
||||
if (b) {
|
||||
if (typeof b === 'string' && encoding === 'base64') {
|
||||
bodyBuffer = Buffer.from(b, encoding);
|
||||
const normalizeBody = body => {
|
||||
if (body) {
|
||||
if (typeof body === 'string' && encoding === 'base64') {
|
||||
bodyBuffer = Buffer.from(body, encoding);
|
||||
} else if (encoding === undefined) {
|
||||
bodyBuffer = Buffer.from(b);
|
||||
bodyBuffer = Buffer.from(body);
|
||||
} else {
|
||||
throw new Error(`Unsupported encoding: ${encoding}`);
|
||||
}
|
||||
@@ -62,8 +63,9 @@ function normalizeProxyEvent(event) {
|
||||
};
|
||||
|
||||
if (payloads) {
|
||||
for (const p of payloads) {
|
||||
p.body = normalizeBody(payload.body);
|
||||
for (const targetPayload of payloads) {
|
||||
targetPayload.features = features;
|
||||
targetPayload.body = normalizeBody(payload.body);
|
||||
}
|
||||
}
|
||||
bodyBuffer = normalizeBody(body);
|
||||
@@ -75,6 +77,7 @@ function normalizeProxyEvent(event) {
|
||||
headers,
|
||||
body: bodyBuffer,
|
||||
payloads,
|
||||
features,
|
||||
responseCallbackCipher,
|
||||
responseCallbackCipherIV,
|
||||
responseCallbackCipherKey,
|
||||
@@ -84,50 +87,12 @@ function normalizeProxyEvent(event) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('aws-lambda').APIGatewayProxyEvent} event
|
||||
*/
|
||||
function normalizeAPIGatewayProxyEvent(event) {
|
||||
let bodyBuffer;
|
||||
const { httpMethod: method, path, headers, body } = event;
|
||||
|
||||
if (body) {
|
||||
if (event.isBase64Encoded) {
|
||||
bodyBuffer = Buffer.from(body, 'base64');
|
||||
} else {
|
||||
bodyBuffer = Buffer.from(body);
|
||||
}
|
||||
} else {
|
||||
bodyBuffer = Buffer.alloc(0);
|
||||
}
|
||||
|
||||
return {
|
||||
body: bodyBuffer,
|
||||
headers,
|
||||
isApiGateway: true,
|
||||
method,
|
||||
path,
|
||||
responseCallbackCipher: undefined,
|
||||
responseCallbackCipherIV: undefined,
|
||||
responseCallbackCipherKey: undefined,
|
||||
responseCallbackStream: undefined,
|
||||
responseCallbackUrl: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('./types').VercelProxyEvent | import('aws-lambda').APIGatewayProxyEvent} event
|
||||
* @return {import('./types').VercelProxyRequest}
|
||||
* @param {import('./types').VercelProxyEvent } event
|
||||
* @return {import('./types').VercelProxyRequest }
|
||||
*/
|
||||
function normalizeEvent(event) {
|
||||
if ('Action' in event) {
|
||||
if (event.Action === 'Invoke') {
|
||||
return normalizeProxyEvent(event);
|
||||
} else {
|
||||
if (event.Action === 'Invoke') return normalizeProxyEvent(event);
|
||||
throw new Error(`Unexpected event.Action: ${event.Action}`);
|
||||
}
|
||||
} else {
|
||||
return normalizeAPIGatewayProxyEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
class Bridge {
|
||||
@@ -207,7 +172,7 @@ class Bridge {
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {import('./types').VercelProxyEvent | import('aws-lambda').APIGatewayProxyEvent} event
|
||||
* @param {import('./types').VercelProxyEvent} event
|
||||
* @param {import('aws-lambda').Context} context
|
||||
* @return {Promise<import('./types').VercelProxyResponse>}
|
||||
*/
|
||||
|
||||
@@ -153,17 +153,17 @@ function getAwsLauncher({ entrypointPath, awsLambdaHandler = '' }) {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {import('aws-lambda').APIGatewayProxyEvent} e
|
||||
* @param {import('aws-lambda').APIGatewayProxyEvent} event
|
||||
* @param {import('aws-lambda').Context} context
|
||||
* @param {() => void} callback
|
||||
*/
|
||||
function internal(e, context, callback) {
|
||||
function internal(event, context, callback) {
|
||||
const {
|
||||
path,
|
||||
method: httpMethod,
|
||||
body,
|
||||
headers,
|
||||
} = JSON.parse(e.body || '{}');
|
||||
} = JSON.parse(event.body || '{}');
|
||||
const { query } = parse(path, true);
|
||||
/**
|
||||
* @type {{[key: string]: string}}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/node-bridge",
|
||||
"version": "3.1.14",
|
||||
"version": "4.0.0",
|
||||
"license": "MIT",
|
||||
"main": "./index.js",
|
||||
"repository": {
|
||||
|
||||
48
packages/node-bridge/test/bridge.test.js
vendored
48
packages/node-bridge/test/bridge.test.js
vendored
@@ -19,39 +19,6 @@ test('port binding', async () => {
|
||||
server.close();
|
||||
});
|
||||
|
||||
test('`APIGatewayProxyEvent` normalizing', async () => {
|
||||
const server = new Server((req, res) =>
|
||||
res.end(
|
||||
JSON.stringify({
|
||||
method: req.method,
|
||||
path: req.url,
|
||||
headers: req.headers,
|
||||
})
|
||||
)
|
||||
);
|
||||
const bridge = new Bridge(server);
|
||||
bridge.listen();
|
||||
const context = {};
|
||||
const result = await bridge.launcher(
|
||||
{
|
||||
httpMethod: 'GET',
|
||||
headers: { foo: 'bar' },
|
||||
path: '/apigateway',
|
||||
body: null,
|
||||
},
|
||||
context
|
||||
);
|
||||
assert.strictEqual(result.encoding, 'base64');
|
||||
assert.strictEqual(result.statusCode, 200);
|
||||
const body = JSON.parse(Buffer.from(result.body, 'base64').toString());
|
||||
assert.strictEqual(body.method, 'GET');
|
||||
assert.strictEqual(body.path, '/apigateway');
|
||||
assert.strictEqual(body.headers.foo, 'bar');
|
||||
assert.strictEqual(context.callbackWaitsForEmptyEventLoop, false);
|
||||
|
||||
server.close();
|
||||
});
|
||||
|
||||
test('`NowProxyEvent` normalizing', async () => {
|
||||
const server = new Server((req, res) =>
|
||||
res.end(
|
||||
@@ -62,8 +29,19 @@ test('`NowProxyEvent` normalizing', async () => {
|
||||
})
|
||||
)
|
||||
);
|
||||
const bridge = new Bridge(server);
|
||||
|
||||
let features;
|
||||
|
||||
class CustomBridge extends Bridge {
|
||||
handleEvent(normalizedEvent) {
|
||||
features = normalizedEvent.features;
|
||||
return super.handleEvent(normalizedEvent);
|
||||
}
|
||||
}
|
||||
|
||||
const bridge = new CustomBridge(server);
|
||||
bridge.listen();
|
||||
|
||||
const context = { callbackWaitsForEmptyEventLoop: true };
|
||||
const result = await bridge.launcher(
|
||||
{
|
||||
@@ -71,12 +49,14 @@ test('`NowProxyEvent` normalizing', async () => {
|
||||
body: JSON.stringify({
|
||||
method: 'POST',
|
||||
headers: { foo: 'baz' },
|
||||
features: { enabled: true },
|
||||
path: '/nowproxy',
|
||||
body: 'body=1',
|
||||
}),
|
||||
},
|
||||
context
|
||||
);
|
||||
assert.deepStrictEqual(features, { enabled: true });
|
||||
assert.strictEqual(result.encoding, 'base64');
|
||||
assert.strictEqual(result.statusCode, 200);
|
||||
const body = JSON.parse(Buffer.from(result.body, 'base64').toString());
|
||||
|
||||
@@ -19,6 +19,7 @@ export interface VercelProxyRequest {
|
||||
body: Buffer;
|
||||
encoding?: string;
|
||||
payloads?: Array<VercelProxyRequest>;
|
||||
features?: Record<string, boolean>;
|
||||
responseCallbackCipher?: CipherCCMTypes;
|
||||
responseCallbackCipherIV?: string;
|
||||
responseCallbackCipherKey?: string;
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/node",
|
||||
"version": "2.9.14",
|
||||
"version": "2.10.1",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/node-js",
|
||||
@@ -31,8 +31,8 @@
|
||||
"dependencies": {
|
||||
"@edge-runtime/vm": "2.0.0",
|
||||
"@types/node": "14.18.33",
|
||||
"@vercel/build-utils": "6.5.0",
|
||||
"@vercel/node-bridge": "3.1.14",
|
||||
"@vercel/build-utils": "6.6.0",
|
||||
"@vercel/node-bridge": "4.0.0",
|
||||
"@vercel/static-config": "2.0.14",
|
||||
"edge-runtime": "2.0.0",
|
||||
"esbuild": "0.14.47",
|
||||
|
||||
@@ -93,7 +93,7 @@ async function main() {
|
||||
handleEvent = await createEventHandler(entrypoint!, config, {
|
||||
shouldAddHelpers,
|
||||
});
|
||||
} catch (error) {
|
||||
} catch (error: any) {
|
||||
logError(error);
|
||||
handlerEventError = error;
|
||||
}
|
||||
@@ -132,7 +132,7 @@ export async function onDevRequest(
|
||||
}
|
||||
}
|
||||
res.end(Buffer.from(result.body, result.encoding));
|
||||
} catch (error) {
|
||||
} catch (error: any) {
|
||||
res.statusCode = 500;
|
||||
res.end(error.stack);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,10 @@ import fetch from 'node-fetch';
|
||||
import { createEdgeWasmPlugin, WasmAssets } from './edge-wasm-plugin';
|
||||
import { entrypointToOutputPath, logError } from '../utils';
|
||||
import { readFileSync } from 'fs';
|
||||
import {
|
||||
createNodeCompatPlugin,
|
||||
NodeCompatBindings,
|
||||
} from './edge-node-compat-plugin';
|
||||
|
||||
const NODE_VERSION_MAJOR = process.version.match(/^v(\d+)\.\d+/)?.[1];
|
||||
const NODE_VERSION_IDENTIFIER = `node${NODE_VERSION_MAJOR}`;
|
||||
@@ -37,8 +41,17 @@ async function compileUserCode(
|
||||
entrypointFullPath: string,
|
||||
entrypointRelativePath: string,
|
||||
isMiddleware: boolean
|
||||
): Promise<undefined | { userCode: string; wasmAssets: WasmAssets }> {
|
||||
): Promise<
|
||||
| undefined
|
||||
| {
|
||||
userCode: string;
|
||||
wasmAssets: WasmAssets;
|
||||
nodeCompatBindings: NodeCompatBindings;
|
||||
}
|
||||
> {
|
||||
const { wasmAssets, plugin: edgeWasmPlugin } = createEdgeWasmPlugin();
|
||||
const nodeCompatPlugin = createNodeCompatPlugin();
|
||||
|
||||
try {
|
||||
const result = await esbuild.build({
|
||||
// bundling behavior: use globals (like "browser") instead
|
||||
@@ -50,7 +63,7 @@ async function compileUserCode(
|
||||
sourcemap: 'inline',
|
||||
legalComments: 'none',
|
||||
bundle: true,
|
||||
plugins: [edgeWasmPlugin],
|
||||
plugins: [edgeWasmPlugin, nodeCompatPlugin.plugin],
|
||||
entryPoints: [entrypointFullPath],
|
||||
write: false, // operate in memory
|
||||
format: 'cjs',
|
||||
@@ -93,7 +106,11 @@ async function compileUserCode(
|
||||
registerFetchListener(userEdgeHandler, options, dependencies);
|
||||
`;
|
||||
|
||||
return { userCode, wasmAssets };
|
||||
return {
|
||||
userCode,
|
||||
wasmAssets,
|
||||
nodeCompatBindings: nodeCompatPlugin.bindings,
|
||||
};
|
||||
} catch (error) {
|
||||
// We can't easily show a meaningful stack trace from ncc -> edge-runtime.
|
||||
// So, stick with just the message for now.
|
||||
@@ -106,6 +123,7 @@ async function compileUserCode(
|
||||
async function createEdgeRuntime(params?: {
|
||||
userCode: string;
|
||||
wasmAssets: WasmAssets;
|
||||
nodeCompatBindings: NodeCompatBindings;
|
||||
}) {
|
||||
try {
|
||||
if (!params) {
|
||||
@@ -113,6 +131,8 @@ async function createEdgeRuntime(params?: {
|
||||
}
|
||||
|
||||
const wasmBindings = await params.wasmAssets.getContext();
|
||||
const nodeCompatBindings = params.nodeCompatBindings.getContext();
|
||||
|
||||
const edgeRuntime = new EdgeRuntime({
|
||||
initialCode: params.userCode,
|
||||
extend: (context: EdgeContext) => {
|
||||
@@ -127,6 +147,9 @@ async function createEdgeRuntime(params?: {
|
||||
env: process.env,
|
||||
},
|
||||
|
||||
// These are the global bindings for Node.js compatibility
|
||||
...nodeCompatBindings,
|
||||
|
||||
// These are the global bindings for WebAssembly module
|
||||
...wasmBindings,
|
||||
});
|
||||
|
||||
162
packages/node/src/edge-functions/edge-node-compat-plugin.ts
Normal file
162
packages/node/src/edge-functions/edge-node-compat-plugin.ts
Normal file
@@ -0,0 +1,162 @@
|
||||
import BufferImplementation from 'buffer';
|
||||
import EventsImplementation from 'events';
|
||||
import AsyncHooksImplementation from 'async_hooks';
|
||||
import AssertImplementation from 'assert';
|
||||
import UtilImplementation from 'util';
|
||||
import type { Plugin } from 'esbuild';
|
||||
|
||||
const SUPPORTED_NODE_MODULES = [
|
||||
'buffer',
|
||||
'events',
|
||||
'assert',
|
||||
'util',
|
||||
'async_hooks',
|
||||
] as const;
|
||||
|
||||
const getSupportedNodeModuleRegex = () =>
|
||||
new RegExp(`^(?:node:)?(?:${SUPPORTED_NODE_MODULES.join('|')})$`);
|
||||
|
||||
function pick<T, K extends keyof T>(obj: T, keys: K[]): Pick<T, K> {
|
||||
const res: Partial<Pick<T, K>> = {};
|
||||
for (const key of keys) {
|
||||
res[key] = obj[key];
|
||||
}
|
||||
return res as Pick<T, K>;
|
||||
}
|
||||
|
||||
const NativeModuleMap = () => {
|
||||
const mods: Record<typeof SUPPORTED_NODE_MODULES[number], unknown> = {
|
||||
buffer: pick(BufferImplementation, [
|
||||
'constants',
|
||||
'kMaxLength',
|
||||
'kStringMaxLength',
|
||||
'Buffer',
|
||||
'SlowBuffer',
|
||||
]),
|
||||
events: pick(EventsImplementation, [
|
||||
'EventEmitter',
|
||||
'captureRejectionSymbol',
|
||||
'defaultMaxListeners',
|
||||
'errorMonitor',
|
||||
'listenerCount',
|
||||
'on',
|
||||
'once',
|
||||
]),
|
||||
async_hooks: pick(AsyncHooksImplementation, [
|
||||
'AsyncLocalStorage',
|
||||
'AsyncResource',
|
||||
]),
|
||||
assert: pick(AssertImplementation, [
|
||||
'AssertionError',
|
||||
'deepEqual',
|
||||
'deepStrictEqual',
|
||||
'doesNotMatch',
|
||||
'doesNotReject',
|
||||
'doesNotThrow',
|
||||
'equal',
|
||||
'fail',
|
||||
'ifError',
|
||||
'match',
|
||||
'notDeepEqual',
|
||||
'notDeepStrictEqual',
|
||||
'notEqual',
|
||||
'notStrictEqual',
|
||||
'ok',
|
||||
'rejects',
|
||||
'strict',
|
||||
'strictEqual',
|
||||
'throws',
|
||||
]),
|
||||
util: pick(UtilImplementation, [
|
||||
'_extend' as any,
|
||||
'callbackify',
|
||||
'format',
|
||||
'inherits',
|
||||
'promisify',
|
||||
'types',
|
||||
]),
|
||||
};
|
||||
return new Map(Object.entries(mods));
|
||||
};
|
||||
|
||||
const NODE_COMPAT_NAMESPACE = 'vercel-node-compat';
|
||||
|
||||
export class NodeCompatBindings {
|
||||
private bindings = new Map<
|
||||
string,
|
||||
{
|
||||
name: string;
|
||||
modulePath: string;
|
||||
value: unknown;
|
||||
}
|
||||
>();
|
||||
|
||||
use(modulePath: `node:${string}`) {
|
||||
const stripped = modulePath.replace(/^node:/, '');
|
||||
const name = `__vc_node_${stripped}__`;
|
||||
if (!this.bindings.has(modulePath)) {
|
||||
const value = NativeModuleMap().get(stripped);
|
||||
if (value === undefined) {
|
||||
throw new Error(`Could not find module ${modulePath}`);
|
||||
}
|
||||
this.bindings.set(modulePath, {
|
||||
modulePath: modulePath,
|
||||
name,
|
||||
value,
|
||||
});
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
getContext(): Record<string, unknown> {
|
||||
const context: Record<string, unknown> = {};
|
||||
for (const binding of this.bindings.values()) {
|
||||
context[binding.name] = binding.value;
|
||||
}
|
||||
return context;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to enable Node.js compatibility by detecting namespaced `node:`
|
||||
* imports and producing metadata to bind global variables for each.
|
||||
* It requires from the consumer to add the imports.
|
||||
*/
|
||||
export function createNodeCompatPlugin() {
|
||||
const bindings = new NodeCompatBindings();
|
||||
const plugin: Plugin = {
|
||||
name: 'vc-node-compat',
|
||||
setup(b) {
|
||||
b.onResolve({ filter: getSupportedNodeModuleRegex() }, async args => {
|
||||
const importee = args.path.replace('node:', '');
|
||||
if (!SUPPORTED_NODE_MODULES.includes(importee as any)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return {
|
||||
namespace: NODE_COMPAT_NAMESPACE,
|
||||
path: args.path,
|
||||
};
|
||||
});
|
||||
|
||||
b.onLoad(
|
||||
{ filter: /.+/, namespace: NODE_COMPAT_NAMESPACE },
|
||||
async args => {
|
||||
const fullName = args.path.startsWith('node:')
|
||||
? (args.path as `node:${string}`)
|
||||
: (`node:${args.path}` as const);
|
||||
const globalName = bindings.use(fullName);
|
||||
|
||||
return {
|
||||
contents: `module.exports = ${globalName};`,
|
||||
loader: 'js',
|
||||
};
|
||||
}
|
||||
);
|
||||
},
|
||||
};
|
||||
return {
|
||||
plugin,
|
||||
bindings,
|
||||
};
|
||||
}
|
||||
16
packages/node/test/dev-fixtures/edge-buffer.js
Normal file
16
packages/node/test/dev-fixtures/edge-buffer.js
Normal file
@@ -0,0 +1,16 @@
|
||||
/* global Response */
|
||||
|
||||
import B from 'node:buffer';
|
||||
import { Buffer } from 'buffer';
|
||||
|
||||
export const config = { runtime: 'edge' };
|
||||
|
||||
export default async () => {
|
||||
const encoded = Buffer.from('Hello, world!').toString('base64');
|
||||
return new Response(
|
||||
JSON.stringify({
|
||||
encoded,
|
||||
'Buffer === B.Buffer': Buffer === B.Buffer,
|
||||
})
|
||||
);
|
||||
};
|
||||
27
packages/node/test/dev.test.ts
vendored
27
packages/node/test/dev.test.ts
vendored
@@ -22,6 +22,33 @@ function testForkDevServer(entrypoint: string) {
|
||||
});
|
||||
}
|
||||
|
||||
test('runs an edge function that uses `buffer`', async () => {
|
||||
const child = testForkDevServer('./edge-buffer.js');
|
||||
|
||||
try {
|
||||
const result = await readMessage(child);
|
||||
if (result.state !== 'message') {
|
||||
throw new Error('Exited. error: ' + JSON.stringify(result.value));
|
||||
}
|
||||
|
||||
const response = await fetch(
|
||||
`http://localhost:${result.value.port}/api/edge-buffer`
|
||||
);
|
||||
expect({
|
||||
status: response.status,
|
||||
json: await response.json(),
|
||||
}).toEqual({
|
||||
status: 200,
|
||||
json: {
|
||||
encoded: Buffer.from('Hello, world!').toString('base64'),
|
||||
'Buffer === B.Buffer': true,
|
||||
},
|
||||
});
|
||||
} finally {
|
||||
child.kill(9);
|
||||
}
|
||||
});
|
||||
|
||||
test('runs a mjs endpoint', async () => {
|
||||
const child = testForkDevServer('./esm-module.mjs');
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/python",
|
||||
"version": "3.1.55",
|
||||
"version": "3.1.56",
|
||||
"main": "./dist/index.js",
|
||||
"license": "MIT",
|
||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/python",
|
||||
@@ -23,7 +23,7 @@
|
||||
"@types/execa": "^0.9.0",
|
||||
"@types/jest": "27.4.1",
|
||||
"@types/node": "14.18.33",
|
||||
"@vercel/build-utils": "6.5.0",
|
||||
"@vercel/build-utils": "6.6.0",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"execa": "^1.0.0",
|
||||
"typescript": "4.3.4"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/redwood",
|
||||
"version": "1.1.11",
|
||||
"version": "1.1.12",
|
||||
"main": "./dist/index.js",
|
||||
"license": "MIT",
|
||||
"homepage": "https://vercel.com/docs",
|
||||
@@ -27,7 +27,7 @@
|
||||
"@types/aws-lambda": "8.10.19",
|
||||
"@types/node": "14.18.33",
|
||||
"@types/semver": "6.0.0",
|
||||
"@vercel/build-utils": "6.5.0",
|
||||
"@vercel/build-utils": "6.6.0",
|
||||
"execa": "3.2.0",
|
||||
"fs-extra": "11.1.0",
|
||||
"typescript": "4.3.4"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/remix-builder",
|
||||
"version": "1.8.0",
|
||||
"version": "1.8.2",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index.js",
|
||||
"homepage": "https://vercel.com/docs",
|
||||
@@ -21,7 +21,7 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"@remix-run/dev": "npm:@vercel/remix-run-dev@1.14.2",
|
||||
"@vercel/build-utils": "6.5.0",
|
||||
"@vercel/build-utils": "6.6.0",
|
||||
"@vercel/nft": "0.22.5",
|
||||
"@vercel/static-config": "2.0.14",
|
||||
"path-to-regexp": "6.2.1",
|
||||
|
||||
@@ -42,7 +42,7 @@ export interface ResolvedRoutePaths {
|
||||
rePath: string;
|
||||
}
|
||||
|
||||
const SPLAT_PATH = '/:params+';
|
||||
const SPLAT_PATH = '/:params*';
|
||||
|
||||
const entryExts = ['.js', '.jsx', '.ts', '.tsx'];
|
||||
|
||||
|
||||
3
packages/remix/test/fixtures/03-with-pnpm/app/routes/sub/$.tsx
vendored
Normal file
3
packages/remix/test/fixtures/03-with-pnpm/app/routes/sub/$.tsx
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
export const config = { runtime: 'edge' };
|
||||
|
||||
export default function () { return <div>Sub catch-all</div> }
|
||||
@@ -12,6 +12,10 @@
|
||||
{ "path": "/nested", "mustContain": "Nested index page" },
|
||||
{ "path": "/nested/another", "mustContain": "Nested another page" },
|
||||
{ "path": "/nested/index", "mustContain": "<div>nested/index</div>" },
|
||||
{ "path": "/asdf", "mustContain": "<div>asdf</div>" }
|
||||
{ "path": "/asdf", "mustContain": "<div>asdf</div>" },
|
||||
{ "path": "/foo/bar", "mustContain": "<div>foo/bar</div>" },
|
||||
{ "path": "/sub", "mustContain": "<div>Sub catch-all</div>" },
|
||||
{ "path": "/sub/", "mustContain": "<div>Sub catch-all</div>" },
|
||||
{ "path": "/sub/another", "mustContain": "<div>Sub catch-all</div>" }
|
||||
]
|
||||
}
|
||||
|
||||
@@ -144,14 +144,14 @@ describe('getPathFromRoute()', () => {
|
||||
},
|
||||
{
|
||||
id: 'routes/projects/$',
|
||||
expected: { path: 'projects/*', rePath: '/projects/:params+' },
|
||||
expected: { path: 'projects/*', rePath: '/projects/:params*' },
|
||||
},
|
||||
{
|
||||
id: 'routes/$foo.$bar.$baz',
|
||||
expected: { path: ':foo/:bar/:baz', rePath: '/:foo/:bar/:baz' },
|
||||
},
|
||||
{ id: 'routes/node', expected: { path: 'node', rePath: '/node' } },
|
||||
{ id: 'routes/$', expected: { path: '*', rePath: '/:params+' } },
|
||||
{ id: 'routes/$', expected: { path: '*', rePath: '/:params*' } },
|
||||
{
|
||||
id: 'routes/($lang)/index',
|
||||
expected: { path: '(:lang)', rePath: '/:lang?' },
|
||||
|
||||
@@ -13,11 +13,11 @@ describe('getRegExpFromPath()', () => {
|
||||
|
||||
describe.each([
|
||||
{
|
||||
path: '/:params+',
|
||||
path: '/:params*',
|
||||
urls: [
|
||||
{
|
||||
url: '/',
|
||||
expected: false,
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
url: '/foo',
|
||||
@@ -38,7 +38,7 @@ describe('getRegExpFromPath()', () => {
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/projects/:params+',
|
||||
path: '/projects/:params*',
|
||||
urls: [
|
||||
{
|
||||
url: '/',
|
||||
@@ -48,12 +48,20 @@ describe('getRegExpFromPath()', () => {
|
||||
url: '/foo',
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
url: '/projects',
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
url: '/projects/',
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
url: '/projects/foo',
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
url: '/projects/another',
|
||||
url: '/projects/foo/another',
|
||||
expected: true,
|
||||
},
|
||||
],
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@vercel/ruby",
|
||||
"author": "Nathan Cahill <nathan@nathancahill.com>",
|
||||
"version": "1.3.72",
|
||||
"version": "1.3.73",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/ruby",
|
||||
@@ -22,7 +22,7 @@
|
||||
"devDependencies": {
|
||||
"@types/fs-extra": "8.0.0",
|
||||
"@types/semver": "6.0.0",
|
||||
"@vercel/build-utils": "6.5.0",
|
||||
"@vercel/build-utils": "6.6.0",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"execa": "2.0.4",
|
||||
"fs-extra": "^7.0.1",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/static-build",
|
||||
"version": "1.3.18",
|
||||
"version": "1.3.20",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://vercel.com/docs/build-step",
|
||||
@@ -30,7 +30,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/gatsby-plugin-vercel-analytics": "1.0.8",
|
||||
"@vercel/gatsby-plugin-vercel-builder": "1.2.3"
|
||||
"@vercel/gatsby-plugin-vercel-builder": "1.2.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/aws-lambda": "8.10.64",
|
||||
@@ -42,9 +42,9 @@
|
||||
"@types/node-fetch": "2.5.4",
|
||||
"@types/promise-timeout": "1.3.0",
|
||||
"@types/semver": "7.3.13",
|
||||
"@vercel/build-utils": "6.5.0",
|
||||
"@vercel/build-utils": "6.6.0",
|
||||
"@vercel/frameworks": "1.3.3",
|
||||
"@vercel/fs-detectors": "3.8.6",
|
||||
"@vercel/fs-detectors": "3.8.7",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"@vercel/routing-utils": "2.1.11",
|
||||
"@vercel/static-config": "2.0.14",
|
||||
|
||||
308
pnpm-lock.yaml
generated
308
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user