mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-26 19:00:08 +00:00
Compare commits
52 Commits
@vercel/no
...
vercel@28.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fc614a7a92 | ||
|
|
6e4ea0774e | ||
|
|
cfc1c9e818 | ||
|
|
62a872fc0e | ||
|
|
03b5bfbaa2 | ||
|
|
aa305e5c66 | ||
|
|
2309c43fce | ||
|
|
0bbb06daa7 | ||
|
|
61de63d285 | ||
|
|
1ca3704297 | ||
|
|
ae4180b287 | ||
|
|
40081cb319 | ||
|
|
9200be61d2 | ||
|
|
1390f6d2ee | ||
|
|
b78cfc9ba5 | ||
|
|
803a9363f9 | ||
|
|
4a0a3b64a2 | ||
|
|
347c2de3a2 | ||
|
|
a05cc11719 | ||
|
|
55b999ea9b | ||
|
|
8babc3694f | ||
|
|
6dc0321216 | ||
|
|
3df8c05792 | ||
|
|
e0f8bc9820 | ||
|
|
ebd2e1822c | ||
|
|
31bc2581f3 | ||
|
|
96759a9fda | ||
|
|
ad2864bca5 | ||
|
|
40fbc993d7 | ||
|
|
1f30e56a6d | ||
|
|
58d6268899 | ||
|
|
4e6659ace7 | ||
|
|
769234b6a6 | ||
|
|
53cab61e88 | ||
|
|
3a65acfb32 | ||
|
|
48eed7532a | ||
|
|
f09d6fce85 | ||
|
|
cc82c499db | ||
|
|
f0bc207717 | ||
|
|
151c7f99ee | ||
|
|
61c2c494bf | ||
|
|
7f49816129 | ||
|
|
7845bef826 | ||
|
|
7acb2e4b07 | ||
|
|
abea002e93 | ||
|
|
2db9678bd4 | ||
|
|
05f942c53f | ||
|
|
6c5f0b7aa0 | ||
|
|
fea05383b9 | ||
|
|
247f49f765 | ||
|
|
231714c71b | ||
|
|
73d6f0d0fa |
31
.github/workflows/cron-update-gatsby-fixtures.yml
vendored
Normal file
31
.github/workflows/cron-update-gatsby-fixtures.yml
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
name: Cron Update Gatsby Fixtures
|
||||
|
||||
on:
|
||||
# Allow manual runs
|
||||
workflow_dispatch:
|
||||
# Run once a week https://crontab.guru/once-a-week
|
||||
schedule:
|
||||
- cron: '0 0 * * 0'
|
||||
|
||||
jobs:
|
||||
create-pull-request:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
# 0 means fetch all commits so we can commit and push in the script below
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Enable corepack
|
||||
run: corepack enable pnpm
|
||||
- name: Create Pull Request
|
||||
uses: actions/github-script@v6
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.GH_TOKEN_PULL_REQUESTS }}
|
||||
# See https://github.com/actions/github-script#run-a-separate-file-with-an-async-function
|
||||
with:
|
||||
github-token: ${{ secrets.GH_TOKEN_PULL_REQUESTS }}
|
||||
script: |
|
||||
const script = require('./utils/update-gatsby-fixtures.js')
|
||||
await script({ github, context })
|
||||
1
.github/workflows/cron-update-next.yml
vendored
1
.github/workflows/cron-update-next.yml
vendored
@@ -25,6 +25,7 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.GH_TOKEN_PULL_REQUESTS }}
|
||||
# See https://github.com/actions/github-script#run-a-separate-file-with-an-async-function
|
||||
with:
|
||||
github-token: ${{ secrets.GH_TOKEN_PULL_REQUESTS }}
|
||||
script: |
|
||||
const script = require('./utils/update-next.js')
|
||||
await script({ github, context })
|
||||
|
||||
1
.github/workflows/cron-update-turbo.yml
vendored
1
.github/workflows/cron-update-turbo.yml
vendored
@@ -25,6 +25,7 @@ jobs:
|
||||
GITHUB_TOKEN: ${{ secrets.GH_TOKEN_PULL_REQUESTS }}
|
||||
# See https://github.com/actions/github-script#run-a-separate-file-with-an-async-function
|
||||
with:
|
||||
github-token: ${{ secrets.GH_TOKEN_PULL_REQUESTS }}
|
||||
script: |
|
||||
const script = require('./utils/update-turbo.js')
|
||||
await script({ github, context })
|
||||
|
||||
5
.github/workflows/publish.yml
vendored
5
.github/workflows/publish.yml
vendored
@@ -16,6 +16,9 @@ jobs:
|
||||
publish:
|
||||
name: Publish
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
id-token: write
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
@@ -41,6 +44,8 @@ jobs:
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
- name: install npm@9
|
||||
run: npm i -g npm@9
|
||||
- name: install pnpm@7.24.2
|
||||
run: npm i -g pnpm@7.24.2
|
||||
- name: Install
|
||||
|
||||
28
.github/workflows/update-remix-run-dev.yml
vendored
Normal file
28
.github/workflows/update-remix-run-dev.yml
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
name: Update @remix-run/dev
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
new-version:
|
||||
type: string
|
||||
description: "Optional version to update @remix-run/dev to inside of @vercel/remix"
|
||||
|
||||
jobs:
|
||||
update-remix-run-dev:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Setup node
|
||||
uses: actions/setup-node@v3
|
||||
- name: Enable corepack
|
||||
run: corepack enable pnpm
|
||||
- name: Update @remix-run/dev
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
github-token: ${{ secrets.GH_TOKEN_PULL_REQUESTS }}
|
||||
script: |
|
||||
const script = require('./utils/update-remix-run-dev.js')
|
||||
await script({ github, context }, "${{ inputs.new-version }}")
|
||||
1
.npmrc
1
.npmrc
@@ -1,3 +1,4 @@
|
||||
provenance=true
|
||||
save-exact=true
|
||||
hoist-pattern[]=!"**/@types/**"
|
||||
hoist-pattern[]=!"**/typedoc"
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/*": ["./*"]
|
||||
}
|
||||
|
||||
2515
examples/nextjs/package-lock.json
generated
2515
examples/nextjs/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -9,10 +9,9 @@
|
||||
"lint": "next lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@next/font": "13.1.6",
|
||||
"eslint": "8.32.0",
|
||||
"eslint-config-next": "13.1.6",
|
||||
"next": "13.1.6",
|
||||
"eslint": "8.35.0",
|
||||
"eslint-config-next": "13.2.3",
|
||||
"next": "13.2.3",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0"
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import Head from 'next/head'
|
||||
import Image from 'next/image'
|
||||
import { Inter } from '@next/font/google'
|
||||
import { Inter } from 'next/font/google'
|
||||
import styles from '@/styles/Home.module.css'
|
||||
|
||||
const inter = Inter({ subsets: ['latin'] })
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
"source-map-support": "0.5.12",
|
||||
"ts-eager": "2.0.2",
|
||||
"ts-jest": "28.0.5",
|
||||
"turbo": "1.7.4"
|
||||
"turbo": "1.8.2"
|
||||
},
|
||||
"scripts": {
|
||||
"lerna": "lerna",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/build-utils",
|
||||
"version": "6.3.1",
|
||||
"version": "6.3.2",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.js",
|
||||
|
||||
@@ -25,12 +25,16 @@ export async function readConfigFile<T>(
|
||||
|
||||
if (data) {
|
||||
const str = data.toString('utf8');
|
||||
if (name.endsWith('.json')) {
|
||||
return JSON.parse(str) as T;
|
||||
} else if (name.endsWith('.toml')) {
|
||||
return (toml.parse(str) as unknown) as T;
|
||||
} else if (name.endsWith('.yaml') || name.endsWith('.yml')) {
|
||||
return yaml.safeLoad(str, { filename: name }) as T;
|
||||
try {
|
||||
if (name.endsWith('.json')) {
|
||||
return JSON.parse(str) as T;
|
||||
} else if (name.endsWith('.toml')) {
|
||||
return toml.parse(str) as unknown as T;
|
||||
} else if (name.endsWith('.yaml') || name.endsWith('.yml')) {
|
||||
return yaml.safeLoad(str, { filename: name }) as T;
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
console.log(`Error while parsing config file: "${name}"`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
77
packages/build-utils/test/unit.read-config-file.test.ts
vendored
Normal file
77
packages/build-utils/test/unit.read-config-file.test.ts
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
import { join } from 'path';
|
||||
import { writeFile, rm } from 'fs/promises';
|
||||
import { readConfigFile } from '../src';
|
||||
|
||||
describe('Test `readConfigFile()`', () => {
|
||||
let logMessages: string[];
|
||||
const originalConsoleLog = console.log;
|
||||
|
||||
beforeEach(() => {
|
||||
logMessages = [];
|
||||
console.log = m => {
|
||||
logMessages.push(m);
|
||||
};
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
console.log = originalConsoleLog;
|
||||
});
|
||||
|
||||
const doesnotexist = join(__dirname, 'does-not-exist.json');
|
||||
const tsconfig = join(__dirname, '../tsconfig.json');
|
||||
const invalid = join(__dirname, 'invalid.json');
|
||||
|
||||
it('should return null when file does not exist', async () => {
|
||||
expect(await readConfigFile(doesnotexist)).toBeNull();
|
||||
expect(logMessages).toEqual([]);
|
||||
});
|
||||
|
||||
it('should return parsed object when file exists', async () => {
|
||||
expect(await readConfigFile(tsconfig)).toMatchObject({
|
||||
compilerOptions: {
|
||||
strict: true,
|
||||
},
|
||||
});
|
||||
expect(logMessages).toEqual([]);
|
||||
});
|
||||
|
||||
it('should return parsed object when at least one file exists', async () => {
|
||||
const files = [doesnotexist, tsconfig];
|
||||
expect(await readConfigFile(files)).toMatchObject({
|
||||
compilerOptions: {
|
||||
strict: true,
|
||||
},
|
||||
});
|
||||
expect(logMessages).toEqual([]);
|
||||
});
|
||||
|
||||
it('should return null when parse fails', async () => {
|
||||
try {
|
||||
await writeFile(invalid, 'borked');
|
||||
expect(await readConfigFile(invalid)).toBeNull();
|
||||
} finally {
|
||||
await rm(invalid);
|
||||
}
|
||||
expect(logMessages.length).toBe(1);
|
||||
expect(logMessages[0]).toMatch(
|
||||
/^Error while parsing config file.+invalid.json/
|
||||
);
|
||||
});
|
||||
|
||||
it('should return parsed object when at least one file is valid', async () => {
|
||||
try {
|
||||
await writeFile(invalid, 'borked');
|
||||
expect(await readConfigFile([invalid, tsconfig])).toMatchObject({
|
||||
compilerOptions: {
|
||||
strict: true,
|
||||
},
|
||||
});
|
||||
} finally {
|
||||
await rm(invalid);
|
||||
}
|
||||
expect(logMessages.length).toBe(1);
|
||||
expect(logMessages[0]).toMatch(
|
||||
/^Error while parsing config file.+invalid.json/
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vercel",
|
||||
"version": "28.16.5",
|
||||
"version": "28.16.12",
|
||||
"preferGlobal": true,
|
||||
"license": "Apache-2.0",
|
||||
"description": "The command-line interface for Vercel",
|
||||
@@ -41,16 +41,16 @@
|
||||
"node": ">= 14"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/build-utils": "6.3.1",
|
||||
"@vercel/go": "2.3.8",
|
||||
"@vercel/hydrogen": "0.0.54",
|
||||
"@vercel/next": "3.6.0",
|
||||
"@vercel/node": "2.9.7",
|
||||
"@vercel/python": "3.1.50",
|
||||
"@vercel/redwood": "1.1.6",
|
||||
"@vercel/remix": "1.4.0",
|
||||
"@vercel/ruby": "1.3.67",
|
||||
"@vercel/static-build": "1.3.11"
|
||||
"@vercel/build-utils": "6.3.2",
|
||||
"@vercel/go": "2.3.9",
|
||||
"@vercel/hydrogen": "0.0.55",
|
||||
"@vercel/next": "3.6.3",
|
||||
"@vercel/node": "2.9.10",
|
||||
"@vercel/python": "3.1.51",
|
||||
"@vercel/redwood": "1.1.7",
|
||||
"@vercel/remix": "1.5.1",
|
||||
"@vercel/ruby": "1.3.68",
|
||||
"@vercel/static-build": "1.3.14"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@alex_neo/jest-expect-message": "1.0.5",
|
||||
@@ -93,13 +93,13 @@
|
||||
"@types/which": "1.3.2",
|
||||
"@types/write-json-file": "2.2.1",
|
||||
"@types/yauzl-promise": "2.1.0",
|
||||
"@vercel/client": "12.4.1",
|
||||
"@vercel/client": "12.4.2",
|
||||
"@vercel/error-utils": "1.0.8",
|
||||
"@vercel/frameworks": "1.3.1",
|
||||
"@vercel/fs-detectors": "3.8.1",
|
||||
"@vercel/frameworks": "1.3.2",
|
||||
"@vercel/fs-detectors": "3.8.2",
|
||||
"@vercel/fun": "1.0.4",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"@vercel/routing-utils": "2.1.9",
|
||||
"@vercel/routing-utils": "2.1.10",
|
||||
"@zeit/source-map-support": "0.6.2",
|
||||
"ajv": "6.12.2",
|
||||
"alpha-sort": "2.0.1",
|
||||
|
||||
@@ -9,6 +9,7 @@ import { ProjectLinkAndSettings } from '../projects/project-settings';
|
||||
import { Output } from '../output';
|
||||
import title from 'title';
|
||||
import { PartialProjectSettings } from '../input/edit-project-settings';
|
||||
import { debug } from '@vercel/build-utils';
|
||||
|
||||
export async function setMonorepoDefaultSettings(
|
||||
cwd: string,
|
||||
@@ -26,8 +27,8 @@ export async function setMonorepoDefaultSettings(
|
||||
value: string
|
||||
) => {
|
||||
if (projectSettings[command]) {
|
||||
output.warn(
|
||||
`Cannot automatically assign ${command} as it is already set via project settings or configuration overrides.`
|
||||
debug(
|
||||
`Skipping auto-assignment of ${command} as it is already set via project settings or configuration overrides.`
|
||||
);
|
||||
} else {
|
||||
projectSettings[command] = value;
|
||||
|
||||
@@ -6,6 +6,4 @@
|
||||
{{?}}
|
||||
<span class="devinfo-line">ID: <code>{{! it.request_id }}</code>
|
||||
</p>
|
||||
|
||||
<a href="https://vercel.link/404"><div class="note">Click here to learn more about this error.</div></a>
|
||||
</main>
|
||||
|
||||
@@ -247,6 +247,14 @@ async function fetchDistTags(name) {
|
||||
});
|
||||
res.on('end', () => {
|
||||
try {
|
||||
if (res.statusCode && res.statusCode >= 400) {
|
||||
return reject(
|
||||
new Error(
|
||||
`Fetch dist-tags failed ${res.statusCode} ${res.statusMessage}`
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
resolve(JSON.parse(buf));
|
||||
} catch (err) {
|
||||
reject(err);
|
||||
|
||||
@@ -484,6 +484,7 @@ describe('build', () => {
|
||||
{
|
||||
src: '^/.*$',
|
||||
middlewarePath: 'middleware',
|
||||
middlewareRawSrc: [],
|
||||
override: true,
|
||||
continue: true,
|
||||
},
|
||||
@@ -548,6 +549,7 @@ describe('build', () => {
|
||||
{
|
||||
src: '^/.*$',
|
||||
middlewarePath: 'middleware',
|
||||
middlewareRawSrc: [],
|
||||
override: true,
|
||||
continue: true,
|
||||
},
|
||||
@@ -612,6 +614,7 @@ describe('build', () => {
|
||||
{
|
||||
src: '^\\/about(?:\\/((?:[^\\/#\\?]+?)(?:\\/(?:[^\\/#\\?]+?))*))?[\\/#\\?]?$|^\\/dashboard(?:\\/((?:[^\\/#\\?]+?)(?:\\/(?:[^\\/#\\?]+?))*))?[\\/#\\?]?$',
|
||||
middlewarePath: 'middleware',
|
||||
middlewareRawSrc: ['/about/:path*', '/dashboard/:path*'],
|
||||
override: true,
|
||||
continue: true,
|
||||
},
|
||||
|
||||
13
packages/cli/turbo.json
Normal file
13
packages/cli/turbo.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"$schema": "https://turborepo.org/schema.json",
|
||||
"extends": ["//"],
|
||||
"pipeline": {
|
||||
"build": {
|
||||
"outputs": [
|
||||
"dist/**",
|
||||
"src/util/constants.ts",
|
||||
"src/util/dev/templates/*.ts"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/client",
|
||||
"version": "12.4.1",
|
||||
"version": "12.4.2",
|
||||
"main": "dist/index.js",
|
||||
"typings": "dist/index.d.ts",
|
||||
"homepage": "https://vercel.com",
|
||||
@@ -43,8 +43,8 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/build-utils": "6.3.1",
|
||||
"@vercel/routing-utils": "2.1.9",
|
||||
"@vercel/build-utils": "6.3.2",
|
||||
"@vercel/routing-utils": "2.1.10",
|
||||
"@zeit/fetch": "5.2.0",
|
||||
"async-retry": "1.2.3",
|
||||
"async-sema": "3.0.0",
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
- [ExtraResponseInit](interfaces/ExtraResponseInit.md)
|
||||
- [Geo](interfaces/Geo.md)
|
||||
- [ModifiedRequest](interfaces/ModifiedRequest.md)
|
||||
- [RequestContext](interfaces/RequestContext.md)
|
||||
|
||||
### Variables
|
||||
|
||||
|
||||
79
packages/edge/docs/interfaces/RequestContext.md
Normal file
79
packages/edge/docs/interfaces/RequestContext.md
Normal file
@@ -0,0 +1,79 @@
|
||||
# Interface: RequestContext
|
||||
|
||||
An extension to the standard `Request` object that is passed to every Edge Function.
|
||||
|
||||
**`Example`**
|
||||
|
||||
```ts
|
||||
import type { RequestContext } from '@vercel/edge';
|
||||
|
||||
export default async function handler(
|
||||
request: Request,
|
||||
ctx: RequestContext
|
||||
): Promise<Response> {
|
||||
// ctx is the RequestContext
|
||||
}
|
||||
```
|
||||
|
||||
## Table of contents
|
||||
|
||||
### Methods
|
||||
|
||||
- [waitUntil](RequestContext.md#waituntil)
|
||||
|
||||
## Methods
|
||||
|
||||
### waitUntil
|
||||
|
||||
▸ **waitUntil**(`promise`): `void`
|
||||
|
||||
A method that can be used to keep the function running after a response has been sent.
|
||||
This is useful when you have an async task that you want to keep running even after the
|
||||
response has been sent and the request has ended.
|
||||
|
||||
**`Example`**
|
||||
|
||||
<caption>Sending an internal error to an error tracking service</caption>
|
||||
|
||||
```ts
|
||||
import type { RequestContext } from '@vercel/edge';
|
||||
|
||||
export async function handleRequest(
|
||||
request: Request,
|
||||
ctx: RequestContext
|
||||
): Promise<Response> {
|
||||
try {
|
||||
return await myFunctionThatReturnsResponse();
|
||||
} catch (e) {
|
||||
ctx.waitUntil(
|
||||
(async () => {
|
||||
// report this error to your error tracking service
|
||||
await fetch('https://my-error-tracking-service.com', {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({
|
||||
stack: e.stack,
|
||||
message: e.message,
|
||||
name: e.name,
|
||||
url: request.url,
|
||||
}),
|
||||
});
|
||||
})()
|
||||
);
|
||||
return new Response('Internal Server Error', { status: 500 });
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| :-------- | :---------------------------------------------------------------------------------------------------------------- | :-------------------------------------------------------------- |
|
||||
| `promise` | [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise)<`unknown`\> | A promise that will be kept alive until it resolves or rejects. |
|
||||
|
||||
#### Returns
|
||||
|
||||
`void`
|
||||
|
||||
#### Defined in
|
||||
|
||||
[packages/edge/src/request.ts:47](https://github.com/vercel/vercel/blob/main/packages/edge/src/request.ts#L47)
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/edge",
|
||||
"version": "0.2.7",
|
||||
"version": "0.3.1",
|
||||
"license": "MIT",
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/index.mjs",
|
||||
|
||||
@@ -4,5 +4,6 @@ export * from './middleware-helpers';
|
||||
export type { Geo } from './edge-headers';
|
||||
export * from './edge-headers';
|
||||
export * from './response';
|
||||
export type { RequestContext } from './request';
|
||||
|
||||
import './published-types.d.ts';
|
||||
|
||||
52
packages/edge/src/request.ts
Normal file
52
packages/edge/src/request.ts
Normal file
@@ -0,0 +1,52 @@
|
||||
/**
|
||||
* An extension to the standard `Request` object that is passed to every Edge Function.
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* import type { RequestContext } from '@vercel/edge';
|
||||
*
|
||||
* export default async function handler(request: Request, ctx: RequestContext): Promise<Response> {
|
||||
* // ctx is the RequestContext
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export interface RequestContext {
|
||||
/**
|
||||
* A method that can be used to keep the function running after a response has been sent.
|
||||
* This is useful when you have an async task that you want to keep running even after the
|
||||
* response has been sent and the request has ended.
|
||||
*
|
||||
* @example
|
||||
*
|
||||
* <caption>Sending an internal error to an error tracking service</caption>
|
||||
*
|
||||
* ```ts
|
||||
* import type { RequestContext } from '@vercel/edge';
|
||||
*
|
||||
* export async function handleRequest(request: Request, ctx: RequestContext): Promise<Response> {
|
||||
* try {
|
||||
* return await myFunctionThatReturnsResponse();
|
||||
* } catch (e) {
|
||||
* ctx.waitUntil((async () => {
|
||||
* // report this error to your error tracking service
|
||||
* await fetch('https://my-error-tracking-service.com', {
|
||||
* method: 'POST',
|
||||
* body: JSON.stringify({
|
||||
* stack: e.stack,
|
||||
* message: e.message,
|
||||
* name: e.name,
|
||||
* url: request.url,
|
||||
* }),
|
||||
* });
|
||||
* })());
|
||||
* return new Response('Internal Server Error', { status: 500 });
|
||||
* }
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
waitUntil(
|
||||
/**
|
||||
* A promise that will be kept alive until it resolves or rejects.
|
||||
*/ promise: Promise<unknown>
|
||||
): void;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/frameworks",
|
||||
"version": "1.3.1",
|
||||
"version": "1.3.2",
|
||||
"main": "./dist/frameworks.js",
|
||||
"types": "./dist/frameworks.d.ts",
|
||||
"files": [
|
||||
@@ -21,7 +21,7 @@
|
||||
"@types/js-yaml": "3.12.1",
|
||||
"@types/node": "14.18.33",
|
||||
"@types/node-fetch": "2.5.8",
|
||||
"@vercel/routing-utils": "2.1.9",
|
||||
"@vercel/routing-utils": "2.1.10",
|
||||
"ajv": "6.12.2",
|
||||
"typescript": "4.3.4"
|
||||
}
|
||||
|
||||
@@ -202,12 +202,13 @@ export const frameworks = [
|
||||
useRuntime: { src: 'package.json', use: '@vercel/remix' },
|
||||
ignoreRuntimes: ['@vercel/node'],
|
||||
detectors: {
|
||||
every: [
|
||||
// Intentionally does not detect a package name
|
||||
// https://github.com/vercel/vercel/pull/7761
|
||||
some: [
|
||||
{
|
||||
path: 'remix.config.js',
|
||||
},
|
||||
{
|
||||
path: 'remix.config.mjs',
|
||||
},
|
||||
],
|
||||
},
|
||||
settings: {
|
||||
@@ -1698,6 +1699,7 @@ export const frameworks = [
|
||||
description: 'React framework for headless commerce',
|
||||
website: 'https://hydrogen.shopify.dev',
|
||||
useRuntime: { src: 'package.json', use: '@vercel/hydrogen' },
|
||||
envPrefix: 'PUBLIC_',
|
||||
detectors: {
|
||||
some: [
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/fs-detectors",
|
||||
"version": "3.8.1",
|
||||
"version": "3.8.2",
|
||||
"description": "Vercel filesystem detectors",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -20,8 +20,8 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/error-utils": "1.0.8",
|
||||
"@vercel/frameworks": "1.3.1",
|
||||
"@vercel/routing-utils": "2.1.9",
|
||||
"@vercel/frameworks": "1.3.2",
|
||||
"@vercel/routing-utils": "2.1.10",
|
||||
"glob": "8.0.3",
|
||||
"js-yaml": "4.1.0",
|
||||
"json5": "2.2.2",
|
||||
@@ -35,7 +35,7 @@
|
||||
"@types/minimatch": "3.0.5",
|
||||
"@types/node": "14.18.33",
|
||||
"@types/semver": "7.3.10",
|
||||
"@vercel/build-utils": "6.3.1",
|
||||
"@vercel/build-utils": "6.3.2",
|
||||
"typescript": "4.3.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/gatsby-plugin-vercel-analytics",
|
||||
"version": "1.0.7",
|
||||
"version": "1.0.8",
|
||||
"description": "Track Core Web Vitals in Gatsby projects with Vercel Analytics.",
|
||||
"main": "index.js",
|
||||
"files": [
|
||||
|
||||
9
packages/gatsby-plugin-vercel-analytics/turbo.json
Normal file
9
packages/gatsby-plugin-vercel-analytics/turbo.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"$schema": "https://turborepo.org/schema.json",
|
||||
"extends": ["//"],
|
||||
"pipeline": {
|
||||
"build": {
|
||||
"outputs": ["gatsby-browser.js", "web-vitals.js", "index.js"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/gatsby-plugin-vercel-builder",
|
||||
"version": "1.1.8",
|
||||
"version": "1.1.11",
|
||||
"main": "dist/index.js",
|
||||
"files": [
|
||||
"dist",
|
||||
@@ -14,9 +14,9 @@
|
||||
"build:src": "tsc -p tsconfig.src.json"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/build-utils": "6.3.1",
|
||||
"@vercel/node": "2.9.7",
|
||||
"@vercel/routing-utils": "2.1.9",
|
||||
"@vercel/build-utils": "6.3.2",
|
||||
"@vercel/node": "2.9.10",
|
||||
"@vercel/routing-utils": "2.1.10",
|
||||
"ajv": "8.12.0",
|
||||
"esbuild": "0.14.47",
|
||||
"etag": "1.8.1",
|
||||
|
||||
9
packages/gatsby-plugin-vercel-builder/turbo.json
Normal file
9
packages/gatsby-plugin-vercel-builder/turbo.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"$schema": "https://turborepo.org/schema.json",
|
||||
"extends": ["//"],
|
||||
"pipeline": {
|
||||
"build": {
|
||||
"outputs": ["dist/**", "gatsby-node.js"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/go",
|
||||
"version": "2.3.8",
|
||||
"version": "2.3.9",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/go",
|
||||
@@ -36,7 +36,7 @@
|
||||
"@types/node": "14.18.33",
|
||||
"@types/node-fetch": "^2.3.0",
|
||||
"@types/tar": "^4.0.0",
|
||||
"@vercel/build-utils": "6.3.1",
|
||||
"@vercel/build-utils": "6.3.2",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"async-retry": "1.3.1",
|
||||
"execa": "^1.0.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/hydrogen",
|
||||
"version": "0.0.54",
|
||||
"version": "0.0.55",
|
||||
"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.3.1",
|
||||
"@vercel/build-utils": "6.3.2",
|
||||
"@vercel/static-config": "2.0.13",
|
||||
"execa": "3.2.0",
|
||||
"fs-extra": "11.1.0",
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
execCommand,
|
||||
getEnvForPackageManager,
|
||||
getNodeVersion,
|
||||
getPrefixedEnvVars,
|
||||
getSpawnOptions,
|
||||
glob,
|
||||
readConfigFile,
|
||||
@@ -29,6 +30,15 @@ export const build: BuildV2 = async ({
|
||||
|
||||
await download(files, workPath, meta);
|
||||
|
||||
const prefixedEnvs = getPrefixedEnvVars({
|
||||
envPrefix: 'PUBLIC_',
|
||||
envs: process.env,
|
||||
});
|
||||
|
||||
for (const [key, value] of Object.entries(prefixedEnvs)) {
|
||||
process.env[key] = value;
|
||||
}
|
||||
|
||||
const mountpoint = dirname(entrypoint);
|
||||
const entrypointDir = join(workPath, mountpoint);
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/next",
|
||||
"version": "3.6.0",
|
||||
"version": "3.6.3",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/next-js",
|
||||
@@ -45,9 +45,9 @@
|
||||
"@types/semver": "6.0.0",
|
||||
"@types/text-table": "0.2.1",
|
||||
"@types/webpack-sources": "3.2.0",
|
||||
"@vercel/build-utils": "6.3.1",
|
||||
"@vercel/build-utils": "6.3.2",
|
||||
"@vercel/nft": "0.22.5",
|
||||
"@vercel/routing-utils": "2.1.9",
|
||||
"@vercel/routing-utils": "2.1.10",
|
||||
"async-sema": "3.0.1",
|
||||
"buffer-crc32": "0.2.13",
|
||||
"bytes": "3.1.2",
|
||||
|
||||
@@ -150,6 +150,10 @@ export async function serverBuild({
|
||||
nextVersion,
|
||||
EMPTY_ALLOW_QUERY_FOR_PRERENDERED_VERSION
|
||||
);
|
||||
const projectDir = requiredServerFilesManifest.relativeAppDir
|
||||
? path.join(baseDir, requiredServerFilesManifest.relativeAppDir)
|
||||
: requiredServerFilesManifest.appDir || entryPath;
|
||||
|
||||
let appBuildTraces: UnwrapPromise<ReturnType<typeof glob>> = {};
|
||||
let appDir: string | null = null;
|
||||
|
||||
@@ -269,9 +273,10 @@ export async function serverBuild({
|
||||
let initialFileList: string[];
|
||||
let initialFileReasons: NodeFileTraceReasons;
|
||||
let nextServerBuildTrace;
|
||||
let instrumentationHookBuildTrace;
|
||||
|
||||
const nextServerFile = resolveFrom(
|
||||
requiredServerFilesManifest.appDir || entryPath,
|
||||
projectDir,
|
||||
`${getNextServerPath(nextVersion)}/next-server.js`
|
||||
);
|
||||
|
||||
@@ -287,6 +292,22 @@ export async function serverBuild({
|
||||
// if the trace is unavailable we trace inside the runtime
|
||||
}
|
||||
|
||||
try {
|
||||
instrumentationHookBuildTrace = JSON.parse(
|
||||
await fs.readFile(
|
||||
path.join(
|
||||
entryPath,
|
||||
outputDirectory,
|
||||
'server',
|
||||
'instrumentation.js.nft.json'
|
||||
),
|
||||
'utf8'
|
||||
)
|
||||
);
|
||||
} catch (_) {
|
||||
// if the trace is unavailable it means `instrumentation.js` wasn't used
|
||||
}
|
||||
|
||||
if (nextServerBuildTrace) {
|
||||
initialFileList = nextServerBuildTrace.files.map((file: string) => {
|
||||
return path.relative(
|
||||
@@ -321,6 +342,18 @@ export async function serverBuild({
|
||||
initialFileReasons = result.reasons;
|
||||
}
|
||||
|
||||
if (instrumentationHookBuildTrace) {
|
||||
initialFileList = initialFileList.concat(
|
||||
instrumentationHookBuildTrace.files.map((file: string) => {
|
||||
return path.relative(
|
||||
baseDir,
|
||||
path.join(entryPath, outputDirectory, 'server', file)
|
||||
);
|
||||
})
|
||||
);
|
||||
debug('Using instrumentation.js.nft.json trace from build');
|
||||
}
|
||||
|
||||
debug('collecting initial Next.js server files');
|
||||
await Promise.all(
|
||||
initialFileList.map(
|
||||
@@ -437,8 +470,8 @@ export async function serverBuild({
|
||||
file
|
||||
);
|
||||
|
||||
if (requiredServerFilesManifest.appDir) {
|
||||
fsPath = path.join(requiredServerFilesManifest.appDir, file);
|
||||
if (projectDir) {
|
||||
fsPath = path.join(projectDir, file);
|
||||
}
|
||||
|
||||
const relativePath = path.relative(baseDir, fsPath);
|
||||
@@ -516,7 +549,7 @@ export async function serverBuild({
|
||||
`conf: ${JSON.stringify({
|
||||
...requiredServerFilesManifest.config,
|
||||
distDir: path.relative(
|
||||
requiredServerFilesManifest.appDir || entryPath,
|
||||
projectDir,
|
||||
path.join(entryPath, outputDirectory)
|
||||
),
|
||||
compress: false,
|
||||
@@ -543,10 +576,8 @@ export async function serverBuild({
|
||||
}
|
||||
|
||||
const launcherFiles: { [name: string]: FileFsRef | FileBlob } = {
|
||||
[path.join(
|
||||
path.relative(baseDir, requiredServerFilesManifest.appDir || entryPath),
|
||||
'___next_launcher.cjs'
|
||||
)]: new FileBlob({ data: launcher }),
|
||||
[path.join(path.relative(baseDir, projectDir), '___next_launcher.cjs')]:
|
||||
new FileBlob({ data: launcher }),
|
||||
};
|
||||
const pageTraces: {
|
||||
[page: string]: { [key: string]: FileFsRef };
|
||||
@@ -594,7 +625,7 @@ export async function serverBuild({
|
||||
traceResult = await nodeFileTrace(pathsToTrace, {
|
||||
base: baseDir,
|
||||
cache: traceCache,
|
||||
processCwd: requiredServerFilesManifest.appDir || entryPath,
|
||||
processCwd: projectDir,
|
||||
});
|
||||
traceResult.esmFileList.forEach(file => traceResult?.fileList.add(file));
|
||||
parentFilesMap = getFilesMapFromReasons(
|
||||
@@ -703,7 +734,7 @@ export async function serverBuild({
|
||||
const pageExtensions = requiredServerFilesManifest.config?.pageExtensions;
|
||||
|
||||
const pageLambdaGroups = await getPageLambdaGroups({
|
||||
entryPath: requiredServerFilesManifest.appDir || entryPath,
|
||||
entryPath: projectDir,
|
||||
config,
|
||||
pages: nonApiPages,
|
||||
prerenderRoutes,
|
||||
@@ -718,7 +749,7 @@ export async function serverBuild({
|
||||
});
|
||||
|
||||
const streamingPageLambdaGroups = await getPageLambdaGroups({
|
||||
entryPath: requiredServerFilesManifest.appDir || entryPath,
|
||||
entryPath: projectDir,
|
||||
config,
|
||||
pages: streamingPages,
|
||||
prerenderRoutes,
|
||||
@@ -739,7 +770,7 @@ export async function serverBuild({
|
||||
}
|
||||
|
||||
const apiLambdaGroups = await getPageLambdaGroups({
|
||||
entryPath: requiredServerFilesManifest.appDir || entryPath,
|
||||
entryPath: projectDir,
|
||||
config,
|
||||
pages: apiPages,
|
||||
prerenderRoutes,
|
||||
@@ -873,10 +904,7 @@ export async function serverBuild({
|
||||
},
|
||||
layers: [group.pseudoLayer, groupPageFiles],
|
||||
handler: path.join(
|
||||
path.relative(
|
||||
baseDir,
|
||||
requiredServerFilesManifest.appDir || entryPath
|
||||
),
|
||||
path.relative(baseDir, projectDir),
|
||||
'___next_launcher.cjs'
|
||||
),
|
||||
operationType,
|
||||
@@ -1528,7 +1556,7 @@ export async function serverBuild({
|
||||
{
|
||||
src: `^${path.posix.join('/', entryDirectory)}/?(?:${i18n.locales
|
||||
.map(locale => escapeStringRegexp(locale))
|
||||
.join('|')})/(.*)`,
|
||||
.join('|')})/?(.*)`,
|
||||
dest: `${path.posix.join('/', entryDirectory, '/')}$1`,
|
||||
check: true,
|
||||
},
|
||||
|
||||
@@ -811,6 +811,7 @@ export async function createLambdaFromPseudoLayers({
|
||||
|
||||
export type NextRequiredServerFilesManifest = {
|
||||
appDir?: string;
|
||||
relativeAppDir?: string;
|
||||
files: string[];
|
||||
ignore: string[];
|
||||
config: Record<string, any>;
|
||||
@@ -954,6 +955,7 @@ export async function getRequiredServerFilesManifest(
|
||||
ignore: [],
|
||||
config: {},
|
||||
appDir: manifestData.appDir,
|
||||
relativeAppDir: manifestData.relativeAppDir,
|
||||
};
|
||||
|
||||
switch (manifestData.version) {
|
||||
|
||||
1
packages/next/test/fixtures/00-app-dir-i18n/.gitignore
vendored
Normal file
1
packages/next/test/fixtures/00-app-dir-i18n/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.vercel
|
||||
3
packages/next/test/fixtures/00-app-dir-i18n/app/enter/page.js
vendored
Normal file
3
packages/next/test/fixtures/00-app-dir-i18n/app/enter/page.js
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
export default function Page() {
|
||||
return <p>My Enter Page</p>;
|
||||
}
|
||||
10
packages/next/test/fixtures/00-app-dir-i18n/app/layout.js
vendored
Normal file
10
packages/next/test/fixtures/00-app-dir-i18n/app/layout.js
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
export default function Root({ children }) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>My Title</title>
|
||||
</head>
|
||||
<body>{children}</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
3
packages/next/test/fixtures/00-app-dir-i18n/app/other/page.js
vendored
Normal file
3
packages/next/test/fixtures/00-app-dir-i18n/app/other/page.js
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
export default function Page() {
|
||||
return <p>My Other Page</p>;
|
||||
}
|
||||
3
packages/next/test/fixtures/00-app-dir-i18n/app/page.js
vendored
Normal file
3
packages/next/test/fixtures/00-app-dir-i18n/app/page.js
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
export default function Page() {
|
||||
return <p>My Index Page</p>;
|
||||
}
|
||||
12
packages/next/test/fixtures/00-app-dir-i18n/index.test.js
vendored
Normal file
12
packages/next/test/fixtures/00-app-dir-i18n/index.test.js
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
/* eslint-env jest */
|
||||
const path = require('path');
|
||||
const { deployAndTest } = require('../../utils');
|
||||
|
||||
const ctx = {};
|
||||
|
||||
describe(`${__dirname.split(path.sep).pop()}`, () => {
|
||||
it('should deploy and pass probe checks', async () => {
|
||||
const info = await deployAndTest(__dirname);
|
||||
Object.assign(ctx, info);
|
||||
});
|
||||
});
|
||||
9
packages/next/test/fixtures/00-app-dir-i18n/next.config.js
vendored
Normal file
9
packages/next/test/fixtures/00-app-dir-i18n/next.config.js
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
module.exports = {
|
||||
experimental: {
|
||||
appDir: true,
|
||||
},
|
||||
i18n: {
|
||||
locales: ['en'],
|
||||
defaultLocale: 'en',
|
||||
},
|
||||
};
|
||||
13
packages/next/test/fixtures/00-app-dir-i18n/package.json
vendored
Normal file
13
packages/next/test/fixtures/00-app-dir-i18n/package.json
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start"
|
||||
},
|
||||
"dependencies": {
|
||||
"next": "canary",
|
||||
"react": "experimental",
|
||||
"react-dom": "experimental"
|
||||
}
|
||||
}
|
||||
34
packages/next/test/fixtures/00-app-dir-i18n/probes.json
vendored
Normal file
34
packages/next/test/fixtures/00-app-dir-i18n/probes.json
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"probes": [
|
||||
{
|
||||
"fetchOptions": { "redirect": "manual" },
|
||||
"path": "/",
|
||||
"status": 200,
|
||||
"mustContain": "My Index Page"
|
||||
},
|
||||
{
|
||||
"fetchOptions": { "redirect": "manual" },
|
||||
"path": "/en",
|
||||
"status": 200,
|
||||
"mustContain": "My Index Page"
|
||||
},
|
||||
{
|
||||
"fetchOptions": { "redirect": "manual" },
|
||||
"path": "/enter",
|
||||
"status": 200,
|
||||
"mustContain": "My Enter Page"
|
||||
},
|
||||
{
|
||||
"fetchOptions": { "redirect": "manual" },
|
||||
"path": "/other",
|
||||
"status": 200,
|
||||
"mustContain": "My Other Page"
|
||||
},
|
||||
{
|
||||
"fetchOptions": { "redirect": "manual" },
|
||||
"path": "/en/other",
|
||||
"status": 200,
|
||||
"mustContain": "My Other Page"
|
||||
}
|
||||
]
|
||||
}
|
||||
1
packages/next/test/fixtures/00-cached-build/.gitignore
vendored
Normal file
1
packages/next/test/fixtures/00-cached-build/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.vercel
|
||||
7
packages/next/test/fixtures/00-cached-build/apps/web/package.json
vendored
Normal file
7
packages/next/test/fixtures/00-cached-build/apps/web/package.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"name": "web",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "next build && rm -rf .next/cache && node post-build.js"
|
||||
}
|
||||
}
|
||||
3
packages/next/test/fixtures/00-cached-build/apps/web/pages/index.js
vendored
Normal file
3
packages/next/test/fixtures/00-cached-build/apps/web/pages/index.js
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
export default function Page() {
|
||||
return <p>index page</p>;
|
||||
}
|
||||
12
packages/next/test/fixtures/00-cached-build/apps/web/pages/ssg.js
vendored
Normal file
12
packages/next/test/fixtures/00-cached-build/apps/web/pages/ssg.js
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
export default function Page() {
|
||||
return <p>ssg page</p>;
|
||||
}
|
||||
|
||||
export function getStaticProps() {
|
||||
return {
|
||||
props: {
|
||||
now: Date.now(),
|
||||
},
|
||||
revalidate: 3,
|
||||
};
|
||||
}
|
||||
11
packages/next/test/fixtures/00-cached-build/apps/web/pages/ssp.js
vendored
Normal file
11
packages/next/test/fixtures/00-cached-build/apps/web/pages/ssp.js
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
export default function Page() {
|
||||
return <p>ssp page</p>;
|
||||
}
|
||||
|
||||
export function getServerSideProps() {
|
||||
return {
|
||||
props: {
|
||||
now: Date.now(),
|
||||
},
|
||||
};
|
||||
}
|
||||
19
packages/next/test/fixtures/00-cached-build/apps/web/post-build.js
vendored
Normal file
19
packages/next/test/fixtures/00-cached-build/apps/web/post-build.js
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const requiredFilesManifestPath = path.join(
|
||||
__dirname,
|
||||
'.next/required-server-files.json'
|
||||
);
|
||||
|
||||
const requiredFilesManifest = JSON.parse(
|
||||
fs.readFileSync(requiredFilesManifestPath, 'utf8')
|
||||
);
|
||||
|
||||
fs.writeFileSync(
|
||||
requiredFilesManifestPath,
|
||||
JSON.stringify({
|
||||
...requiredFilesManifest,
|
||||
appDir: '/non-existent/apps/web',
|
||||
})
|
||||
);
|
||||
12
packages/next/test/fixtures/00-cached-build/index.test.js
vendored
Normal file
12
packages/next/test/fixtures/00-cached-build/index.test.js
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
/* eslint-env jest */
|
||||
const path = require('path');
|
||||
const { deployAndTest } = require('../../utils');
|
||||
|
||||
const ctx = {};
|
||||
|
||||
describe(`${__dirname.split(path.sep).pop()}`, () => {
|
||||
it('should deploy and pass probe checks', async () => {
|
||||
const info = await deployAndTest(__dirname, { skipForceNew: true });
|
||||
Object.assign(ctx, info);
|
||||
});
|
||||
});
|
||||
15
packages/next/test/fixtures/00-cached-build/package.json
vendored
Normal file
15
packages/next/test/fixtures/00-cached-build/package.json
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"workspaces": [
|
||||
"apps/*"
|
||||
],
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"next": "13.2.2-canary.0",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0",
|
||||
"turbo": "1.8.2"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "turbo build --cache-dir=turbo-cache"
|
||||
}
|
||||
}
|
||||
1
packages/next/test/fixtures/00-cached-build/turbo-cache/3d4a11a80ae91055-meta.json
vendored
Normal file
1
packages/next/test/fixtures/00-cached-build/turbo-cache/3d4a11a80ae91055-meta.json
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{ "hash": "3d4a11a80ae91055", "duration": 5510 }
|
||||
BIN
packages/next/test/fixtures/00-cached-build/turbo-cache/3d4a11a80ae91055.tar.zst
vendored
Normal file
BIN
packages/next/test/fixtures/00-cached-build/turbo-cache/3d4a11a80ae91055.tar.zst
vendored
Normal file
Binary file not shown.
8
packages/next/test/fixtures/00-cached-build/turbo.json
vendored
Normal file
8
packages/next/test/fixtures/00-cached-build/turbo.json
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"pipeline": {
|
||||
"build": {
|
||||
"dependsOn": ["^build"],
|
||||
"outputs": [".next/**"]
|
||||
}
|
||||
}
|
||||
}
|
||||
30
packages/next/test/fixtures/00-cached-build/vercel.json
vendored
Normal file
30
packages/next/test/fixtures/00-cached-build/vercel.json
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
{
|
||||
"builds": [
|
||||
{
|
||||
"src": "package.json",
|
||||
"use": "@vercel/next",
|
||||
"config": {
|
||||
"rootDirectory": "apps/web",
|
||||
"buildCommand": "cd ../../ && yarn build",
|
||||
"installCommand": "yarn"
|
||||
}
|
||||
}
|
||||
],
|
||||
"probes": [
|
||||
{
|
||||
"path": "/",
|
||||
"status": 200,
|
||||
"mustContain": "index page"
|
||||
},
|
||||
{
|
||||
"path": "/ssg",
|
||||
"status": 200,
|
||||
"mustContain": "ssg page"
|
||||
},
|
||||
{
|
||||
"path": "/ssp",
|
||||
"status": 200,
|
||||
"mustContain": "ssp page"
|
||||
}
|
||||
]
|
||||
}
|
||||
227
packages/next/test/fixtures/00-cached-build/yarn.lock
vendored
Normal file
227
packages/next/test/fixtures/00-cached-build/yarn.lock
vendored
Normal file
@@ -0,0 +1,227 @@
|
||||
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
"@next/env@13.2.2-canary.0":
|
||||
version "13.2.2-canary.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/env/-/env-13.2.2-canary.0.tgz#0f843ef602ff25441f17f10d09a93942baa8232b"
|
||||
integrity sha512-EDy4UF4oXGmWgMq9w8P7Wg7JoYbrGY7EVnZcNoyMDU8o9KeiviYjK2IR3yFBulG0/1I2UbVu2wIM1xPYsQIonQ==
|
||||
|
||||
"@next/swc-android-arm-eabi@13.2.2-canary.0":
|
||||
version "13.2.2-canary.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-android-arm-eabi/-/swc-android-arm-eabi-13.2.2-canary.0.tgz#62510cc5b11b677a63363788848efdc8aeda9cf8"
|
||||
integrity sha512-/si1jk3wtrarhdVPQloSubTJjLeuTpgT7V2R2w+acWzvBBsrs2ThhZodLz0fJRKcYKmeDZebhtYGUkxkcm48Tw==
|
||||
|
||||
"@next/swc-android-arm64@13.2.2-canary.0":
|
||||
version "13.2.2-canary.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-android-arm64/-/swc-android-arm64-13.2.2-canary.0.tgz#967fe8a63d59bdd22f57056ef83005242b559c1a"
|
||||
integrity sha512-MKImVjggMFvPJju48fvz/KqjiqXaKoimGz3Vmc3c12WaSIEa5O1sevw0dQKPI6sv+1Mf5MuP7XlLQ9bWJo+72Q==
|
||||
|
||||
"@next/swc-darwin-arm64@13.2.2-canary.0":
|
||||
version "13.2.2-canary.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-darwin-arm64/-/swc-darwin-arm64-13.2.2-canary.0.tgz#1250cf70dc129b765ae11bc596cd4d298a129afe"
|
||||
integrity sha512-Sj+hCut5c6K2lOIJpV9KDsDJNe1dVacAE8WWmvotoeu4ab1W0//axZOxksq0S3240oF9CJ8QPZo+q5lPV6Gn2Q==
|
||||
|
||||
"@next/swc-darwin-x64@13.2.2-canary.0":
|
||||
version "13.2.2-canary.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-darwin-x64/-/swc-darwin-x64-13.2.2-canary.0.tgz#13dde75f037194d46799542111608679c73dc8dc"
|
||||
integrity sha512-/lv1J5ts5UhQ5V2V0PpIkQJw8kJywMgvPegZ/yf0fy9QOOdGCAw1dXtZsKUISrJmuzPcCZo0F56Zjbyb6lCLsw==
|
||||
|
||||
"@next/swc-freebsd-x64@13.2.2-canary.0":
|
||||
version "13.2.2-canary.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-freebsd-x64/-/swc-freebsd-x64-13.2.2-canary.0.tgz#f9709e88c60207fb17244895cfe23a4a2d40b099"
|
||||
integrity sha512-ECQyYOYd1AKu/oTNeI5pWDXebgKTIWXCs84IN9rXsM7f+FOQmVU8V+gK6Oisw3jya68B1vmfMqLDGQClDDIMAg==
|
||||
|
||||
"@next/swc-linux-arm-gnueabihf@13.2.2-canary.0":
|
||||
version "13.2.2-canary.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm-gnueabihf/-/swc-linux-arm-gnueabihf-13.2.2-canary.0.tgz#bdcef78c71820ff64c1225796dc383c8d72fcaed"
|
||||
integrity sha512-/UQf0yoIwJJhgV8dpDmgWq/Q3/IxqFRsUHfBiy2M6kGVYwB9CnsjZzHwUKmg7sASdv+atW+oc4PIXXN6W9CCgg==
|
||||
|
||||
"@next/swc-linux-arm64-gnu@13.2.2-canary.0":
|
||||
version "13.2.2-canary.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-gnu/-/swc-linux-arm64-gnu-13.2.2-canary.0.tgz#e77b30092c22eb0af16a7a6c150d51fa84f0ceb0"
|
||||
integrity sha512-pv0m+4hnKyq0MwEVAvrJScoYme4GKoPieP0Tj32oRK6P1gafFK4uJxF6zMVPlO0D/tGI7EkoHZjv/7sU5pSYSA==
|
||||
|
||||
"@next/swc-linux-arm64-musl@13.2.2-canary.0":
|
||||
version "13.2.2-canary.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-arm64-musl/-/swc-linux-arm64-musl-13.2.2-canary.0.tgz#779514bb2d0e7feced48fac1da0bc344180c8511"
|
||||
integrity sha512-Bpc7nLJoP6dVPG9lOqCGqWkfiMo143YRx7+cvxSl1FVupkGP7Ntldvl3zS/m2CnU/5egQEjC2C5jEgQRY92Zhw==
|
||||
|
||||
"@next/swc-linux-x64-gnu@13.2.2-canary.0":
|
||||
version "13.2.2-canary.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-gnu/-/swc-linux-x64-gnu-13.2.2-canary.0.tgz#d9022f44e0b243d32d39eeac683b1f189ff41487"
|
||||
integrity sha512-2RPr5AxawTUVaQGrkhWWpjVdExPiA8wEJL6E1itI2gNav8LU3FEsIr9juQURv47Xn2KE286fw8214D6+D0RExg==
|
||||
|
||||
"@next/swc-linux-x64-musl@13.2.2-canary.0":
|
||||
version "13.2.2-canary.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-linux-x64-musl/-/swc-linux-x64-musl-13.2.2-canary.0.tgz#8868f650f11594862fa183e0a0dac66d9c72973b"
|
||||
integrity sha512-gKr5tJoJKGSlmDdpmoO1fe6oUeVMz2TluspKPM4ulc0rqyXjrRmQ9pd/oqEoypUKTUkqL49lt4hTL98MkhvXWg==
|
||||
|
||||
"@next/swc-win32-arm64-msvc@13.2.2-canary.0":
|
||||
version "13.2.2-canary.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-arm64-msvc/-/swc-win32-arm64-msvc-13.2.2-canary.0.tgz#29faaa4b760128c648f153964e94a8191bb0b2d7"
|
||||
integrity sha512-0N7+lcV8ycqzgJIye40+Vl0iUk/mu3919T2kfnt20WU7gP+rpRJkPfP44yxBdt7U7XYtnqldM2Ox969y+0qJVw==
|
||||
|
||||
"@next/swc-win32-ia32-msvc@13.2.2-canary.0":
|
||||
version "13.2.2-canary.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-ia32-msvc/-/swc-win32-ia32-msvc-13.2.2-canary.0.tgz#078350e676d1a146442dbc7b1f5c4e03cb1345a5"
|
||||
integrity sha512-vqdsKfJcfvf37P7YcJeIaPP5E7iSR7yTaHwgBpvY6Q0tDRxPv0gr4nRXElBs/V1VcxMaSx9PyyiQkKYB6UzEhg==
|
||||
|
||||
"@next/swc-win32-x64-msvc@13.2.2-canary.0":
|
||||
version "13.2.2-canary.0"
|
||||
resolved "https://registry.yarnpkg.com/@next/swc-win32-x64-msvc/-/swc-win32-x64-msvc-13.2.2-canary.0.tgz#7ca59776b5440e6de3aee341d571a8a4f7cbb40a"
|
||||
integrity sha512-Hf1XQaP/hpi9ddS128u8+npotRzX5EOt9y4nxzHRKn6BmjgAKY7CEBsFQMsjVHWqit2Jt3jXspgaCVIFOCE9Ng==
|
||||
|
||||
"@swc/helpers@0.4.14":
|
||||
version "0.4.14"
|
||||
resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.4.14.tgz#1352ac6d95e3617ccb7c1498ff019654f1e12a74"
|
||||
integrity sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw==
|
||||
dependencies:
|
||||
tslib "^2.4.0"
|
||||
|
||||
caniuse-lite@^1.0.30001406:
|
||||
version "1.0.30001457"
|
||||
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001457.tgz#6af34bb5d720074e2099432aa522c21555a18301"
|
||||
integrity sha512-SDIV6bgE1aVbK6XyxdURbUE89zY7+k1BBBaOwYwkNCglXlel/E7mELiHC64HQ+W0xSKlqWhV9Wh7iHxUjMs4fA==
|
||||
|
||||
client-only@0.0.1:
|
||||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1"
|
||||
integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==
|
||||
|
||||
"js-tokens@^3.0.0 || ^4.0.0":
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
|
||||
integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
|
||||
|
||||
loose-envify@^1.1.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
|
||||
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
|
||||
dependencies:
|
||||
js-tokens "^3.0.0 || ^4.0.0"
|
||||
|
||||
nanoid@^3.3.4:
|
||||
version "3.3.4"
|
||||
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab"
|
||||
integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==
|
||||
|
||||
next@13.2.2-canary.0:
|
||||
version "13.2.2-canary.0"
|
||||
resolved "https://registry.yarnpkg.com/next/-/next-13.2.2-canary.0.tgz#7b8c9e2391d947fb66636fe988af644f2e930db2"
|
||||
integrity sha512-sAzQCPI06df+TY7NI6txOkc7sOC7sErnOGF7vXA28GcQ0r4V09s4GDe8XTlPckxJ7o2Ky4OU1eN4NJ3vnDCcZQ==
|
||||
dependencies:
|
||||
"@next/env" "13.2.2-canary.0"
|
||||
"@swc/helpers" "0.4.14"
|
||||
caniuse-lite "^1.0.30001406"
|
||||
postcss "8.4.14"
|
||||
styled-jsx "5.1.1"
|
||||
optionalDependencies:
|
||||
"@next/swc-android-arm-eabi" "13.2.2-canary.0"
|
||||
"@next/swc-android-arm64" "13.2.2-canary.0"
|
||||
"@next/swc-darwin-arm64" "13.2.2-canary.0"
|
||||
"@next/swc-darwin-x64" "13.2.2-canary.0"
|
||||
"@next/swc-freebsd-x64" "13.2.2-canary.0"
|
||||
"@next/swc-linux-arm-gnueabihf" "13.2.2-canary.0"
|
||||
"@next/swc-linux-arm64-gnu" "13.2.2-canary.0"
|
||||
"@next/swc-linux-arm64-musl" "13.2.2-canary.0"
|
||||
"@next/swc-linux-x64-gnu" "13.2.2-canary.0"
|
||||
"@next/swc-linux-x64-musl" "13.2.2-canary.0"
|
||||
"@next/swc-win32-arm64-msvc" "13.2.2-canary.0"
|
||||
"@next/swc-win32-ia32-msvc" "13.2.2-canary.0"
|
||||
"@next/swc-win32-x64-msvc" "13.2.2-canary.0"
|
||||
|
||||
picocolors@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
|
||||
integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
|
||||
|
||||
postcss@8.4.14:
|
||||
version "8.4.14"
|
||||
resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.14.tgz#ee9274d5622b4858c1007a74d76e42e56fd21caf"
|
||||
integrity sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==
|
||||
dependencies:
|
||||
nanoid "^3.3.4"
|
||||
picocolors "^1.0.0"
|
||||
source-map-js "^1.0.2"
|
||||
|
||||
react-dom@18.2.0:
|
||||
version "18.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d"
|
||||
integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
scheduler "^0.23.0"
|
||||
|
||||
react@18.2.0:
|
||||
version "18.2.0"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5"
|
||||
integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
|
||||
scheduler@^0.23.0:
|
||||
version "0.23.0"
|
||||
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe"
|
||||
integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
|
||||
source-map-js@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
|
||||
integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
|
||||
|
||||
styled-jsx@5.1.1:
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/styled-jsx/-/styled-jsx-5.1.1.tgz#839a1c3aaacc4e735fed0781b8619ea5d0009d1f"
|
||||
integrity sha512-pW7uC1l4mBZ8ugbiZrcIsiIvVx1UmTfw7UkC3Um2tmfUq9Bhk8IiyEIPl6F8agHgjzku6j0xQEZbfA5uSgSaCw==
|
||||
dependencies:
|
||||
client-only "0.0.1"
|
||||
|
||||
tslib@^2.4.0:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf"
|
||||
integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==
|
||||
|
||||
turbo-darwin-64@1.8.2:
|
||||
version "1.8.2"
|
||||
resolved "https://registry.yarnpkg.com/turbo-darwin-64/-/turbo-darwin-64-1.8.2.tgz#14c52e97d128c63fd3c7b2f15963123f02b9aa0e"
|
||||
integrity sha512-j77U0uOeppENexFsIvvzExADSqMBEeCHnm+6LSNQfaajHSrbUVSTsuD6ZMYHamT6bslc+ZZm21jdecWkwZFBbw==
|
||||
|
||||
turbo-darwin-arm64@1.8.2:
|
||||
version "1.8.2"
|
||||
resolved "https://registry.yarnpkg.com/turbo-darwin-arm64/-/turbo-darwin-arm64-1.8.2.tgz#ae5efdb89cbdd667feacd3fe8e9c8110691a4d95"
|
||||
integrity sha512-1NoAvjlwt2wycsAFJouauy9epn9DptSMy6BoGqxJVc4jiibsLepp9qYc4f1/ln0zjd3FR1IvhGOiBfdpqMN7hg==
|
||||
|
||||
turbo-linux-64@1.8.2:
|
||||
version "1.8.2"
|
||||
resolved "https://registry.yarnpkg.com/turbo-linux-64/-/turbo-linux-64-1.8.2.tgz#02442a48104db83c1e53409c85744fdeacbded56"
|
||||
integrity sha512-TcT3CRYnBYA46kLGGbGC2jDyCEAvMgVpUdpIZGTmod48EKpZaEfVgTkpa4GJde8W68yRFogPZjPVL3yJHFpXSA==
|
||||
|
||||
turbo-linux-arm64@1.8.2:
|
||||
version "1.8.2"
|
||||
resolved "https://registry.yarnpkg.com/turbo-linux-arm64/-/turbo-linux-arm64-1.8.2.tgz#890ad0691671cb252e756dcd56295895f61d369a"
|
||||
integrity sha512-Mb9+KBy4YJzPMZ6WGoMzMVZ6EtueCSvOvgmNpVFgkwbtabfBuaBOvN+irtg4RRSWvJQTDTziLABieocEEXZImQ==
|
||||
|
||||
turbo-windows-64@1.8.2:
|
||||
version "1.8.2"
|
||||
resolved "https://registry.yarnpkg.com/turbo-windows-64/-/turbo-windows-64-1.8.2.tgz#a57b902cdccdb69d1efa18772bee9e277e079583"
|
||||
integrity sha512-/+R5ikRrw2w2w38JtNPubGLIQHgUC70m783DI9aPgaM5c8P5D/Y0k6HgjuC/uXgiaz2h3R7p7YWlr+2/E0bqyA==
|
||||
|
||||
turbo-windows-arm64@1.8.2:
|
||||
version "1.8.2"
|
||||
resolved "https://registry.yarnpkg.com/turbo-windows-arm64/-/turbo-windows-arm64-1.8.2.tgz#0f976a2c6b8a46447fc277d5a9f7d8615792bdde"
|
||||
integrity sha512-s07viz5nXSx4kyiksuPM4FGLRkoaGMaw0BpwFjdRQsl1p+WclUN1IPdokVPKOmFpu5pNCVYlG/raP/mXAEzDCg==
|
||||
|
||||
turbo@1.8.2:
|
||||
version "1.8.2"
|
||||
resolved "https://registry.yarnpkg.com/turbo/-/turbo-1.8.2.tgz#869e674a524cde4f449ae4458f4651818e2ffe00"
|
||||
integrity sha512-G/uJx6bZK5RwTWHsRN/MP0MvXFznmCaL3MQXdSf+OG/q0o8GE7+yivyyWEplWI1Asc8AEN909A/wlIkoz2FKTg==
|
||||
optionalDependencies:
|
||||
turbo-darwin-64 "1.8.2"
|
||||
turbo-darwin-arm64 "1.8.2"
|
||||
turbo-linux-64 "1.8.2"
|
||||
turbo-linux-arm64 "1.8.2"
|
||||
turbo-windows-64 "1.8.2"
|
||||
turbo-windows-arm64 "1.8.2"
|
||||
8
packages/next/test/fixtures/36-instrumentation-hook/index.test.js
vendored
Normal file
8
packages/next/test/fixtures/36-instrumentation-hook/index.test.js
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
const path = require('path');
|
||||
const { deployAndTest } = require('../../utils');
|
||||
|
||||
describe(`${__dirname.split(path.sep).pop()}`, () => {
|
||||
it('should deploy and pass probe checks', async () => {
|
||||
await deployAndTest(__dirname);
|
||||
});
|
||||
});
|
||||
3
packages/next/test/fixtures/36-instrumentation-hook/instrumentation.js
vendored
Normal file
3
packages/next/test/fixtures/36-instrumentation-hook/instrumentation.js
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
export function register() {
|
||||
globalThis.isOdd = require('is-odd');
|
||||
}
|
||||
5
packages/next/test/fixtures/36-instrumentation-hook/next.config.js
vendored
Normal file
5
packages/next/test/fixtures/36-instrumentation-hook/next.config.js
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
module.exports = {
|
||||
experimental: {
|
||||
instrumentationHook: true,
|
||||
},
|
||||
};
|
||||
16
packages/next/test/fixtures/36-instrumentation-hook/package.json
vendored
Normal file
16
packages/next/test/fixtures/36-instrumentation-hook/package.json
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"name": "instrumentation-hook",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start"
|
||||
},
|
||||
"dependencies": {
|
||||
"next": "canary",
|
||||
"react": "latest",
|
||||
"react-dom": "latest",
|
||||
"is-odd": "3.0.1"
|
||||
}
|
||||
}
|
||||
5
packages/next/test/fixtures/36-instrumentation-hook/pages/api/hello.js
vendored
Normal file
5
packages/next/test/fixtures/36-instrumentation-hook/pages/api/hello.js
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
export default async (req, res) => {
|
||||
res.status(200).json({
|
||||
payload: `isOdd: ${globalThis.isOdd(3)}`,
|
||||
});
|
||||
};
|
||||
11
packages/next/test/fixtures/36-instrumentation-hook/pages/index.js
vendored
Normal file
11
packages/next/test/fixtures/36-instrumentation-hook/pages/index.js
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
export default function Home(props) {
|
||||
return `isOdd: ${props.isOdd}`;
|
||||
}
|
||||
|
||||
export async function getServerSideProps() {
|
||||
return {
|
||||
props: {
|
||||
isOdd: globalThis.isOdd(2),
|
||||
},
|
||||
};
|
||||
}
|
||||
14
packages/next/test/fixtures/36-instrumentation-hook/probes.json
vendored
Normal file
14
packages/next/test/fixtures/36-instrumentation-hook/probes.json
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"probes": [
|
||||
{
|
||||
"path": "/",
|
||||
"status": 200,
|
||||
"mustContain": "isOdd: false"
|
||||
},
|
||||
{
|
||||
"path": "/api/hello",
|
||||
"status": 200,
|
||||
"mustContain": "isOdd: true"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -26,7 +26,7 @@ if (parseInt(process.versions.node.split('.')[0], 10) >= 16) {
|
||||
}
|
||||
}
|
||||
|
||||
expect(lambdas.size).toBe(1);
|
||||
expect(lambdas.size).toBe(2);
|
||||
expect(buildResult.output['dashboard']).toBeDefined();
|
||||
expect(buildResult.output['dashboard/another']).toBeDefined();
|
||||
expect(buildResult.output['dashboard/changelog']).toBeDefined();
|
||||
|
||||
7
packages/next/test/utils.ts
vendored
7
packages/next/test/utils.ts
vendored
@@ -71,8 +71,11 @@ export const createLoggerServer = async (): Promise<LoggerServer> => {
|
||||
|
||||
process.env.NEXT_TELEMETRY_DISABLED = '1';
|
||||
|
||||
export async function deployAndTest(fixtureDir) {
|
||||
const { deploymentId, deploymentUrl } = await testDeployment(fixtureDir);
|
||||
export async function deployAndTest(fixtureDir, opts) {
|
||||
const { deploymentId, deploymentUrl } = await testDeployment(
|
||||
fixtureDir,
|
||||
opts
|
||||
);
|
||||
|
||||
return {
|
||||
deploymentId,
|
||||
|
||||
@@ -435,7 +435,13 @@ function getStreamResponseCallback({ url, socket, cipher, resolve, reject }) {
|
||||
headers += `x-vercel-status-code: ${response.statusCode || 200}${CRLF}`;
|
||||
for (const [name, value] of getHeadersIterator(response.headers)) {
|
||||
if (!['connection', 'transfer-encoding'].includes(name)) {
|
||||
headers += `x-vercel-header-${name}: ${value}${CRLF}`;
|
||||
if (typeof value === 'string') {
|
||||
headers += `x-vercel-header-${name}: ${value}${CRLF}`;
|
||||
} else {
|
||||
for (const val of value) {
|
||||
headers += `x-vercel-header-${name}: ${val}${CRLF}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/node-bridge",
|
||||
"version": "3.1.11",
|
||||
"version": "3.1.14",
|
||||
"license": "MIT",
|
||||
"main": "./index.js",
|
||||
"repository": {
|
||||
|
||||
9
packages/node-bridge/turbo.json
Normal file
9
packages/node-bridge/turbo.json
Normal file
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"$schema": "https://turborepo.org/schema.json",
|
||||
"extends": ["//"],
|
||||
"pipeline": {
|
||||
"build": {
|
||||
"outputs": ["helpers.js", "source-map-support.js"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/node",
|
||||
"version": "2.9.7",
|
||||
"version": "2.9.10",
|
||||
"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.3.1",
|
||||
"@vercel/node-bridge": "3.1.11",
|
||||
"@vercel/build-utils": "6.3.2",
|
||||
"@vercel/node-bridge": "3.1.14",
|
||||
"@vercel/static-config": "2.0.13",
|
||||
"edge-runtime": "2.0.0",
|
||||
"esbuild": "0.14.47",
|
||||
|
||||
@@ -449,9 +449,19 @@ export const build: BuildV3 = async ({
|
||||
// Middleware is a catch-all for all paths unless a `matcher` property is defined
|
||||
const src = getRegExpFromMatchers(staticConfig?.matcher);
|
||||
|
||||
const middlewareRawSrc: string[] = [];
|
||||
if (staticConfig?.matcher) {
|
||||
if (Array.isArray(staticConfig.matcher)) {
|
||||
middlewareRawSrc.push(...staticConfig.matcher);
|
||||
} else {
|
||||
middlewareRawSrc.push(staticConfig.matcher as string);
|
||||
}
|
||||
}
|
||||
|
||||
routes = [
|
||||
{
|
||||
src,
|
||||
middlewareRawSrc,
|
||||
middlewarePath: outputPath,
|
||||
continue: true,
|
||||
override: true,
|
||||
|
||||
32
packages/node/test/dev.test.ts
vendored
32
packages/node/test/dev.test.ts
vendored
@@ -1,22 +1,29 @@
|
||||
import { forkDevServer, readMessage } from '../src/fork-dev-server';
|
||||
import { resolve } from 'path';
|
||||
import { resolve, extname } from 'path';
|
||||
import fetch from 'node-fetch';
|
||||
|
||||
jest.setTimeout(10 * 1000);
|
||||
|
||||
test('runs a mjs endpoint', async () => {
|
||||
const child = forkDevServer({
|
||||
function testForkDevServer(entrypoint: string) {
|
||||
const ext = extname(entrypoint);
|
||||
const isTypeScript = ext === '.ts';
|
||||
const isEsm = ext === '.mjs';
|
||||
return forkDevServer({
|
||||
maybeTranspile: true,
|
||||
config: {},
|
||||
isEsm: true,
|
||||
isTypeScript: false,
|
||||
isEsm,
|
||||
isTypeScript,
|
||||
meta: {},
|
||||
require_: require,
|
||||
tsConfig: undefined,
|
||||
workPath: resolve(__dirname, './dev-fixtures'),
|
||||
entrypoint: './esm-module.mjs',
|
||||
entrypoint,
|
||||
devServerPath: resolve(__dirname, '../dist/dev-server.js'),
|
||||
});
|
||||
}
|
||||
|
||||
test('runs a mjs endpoint', async () => {
|
||||
const child = testForkDevServer('./esm-module.mjs');
|
||||
|
||||
try {
|
||||
const result = await readMessage(child);
|
||||
@@ -44,18 +51,7 @@ test('runs a mjs endpoint', async () => {
|
||||
});
|
||||
|
||||
test('runs a esm typescript endpoint', async () => {
|
||||
const child = forkDevServer({
|
||||
maybeTranspile: true,
|
||||
config: {},
|
||||
isEsm: true,
|
||||
isTypeScript: true,
|
||||
meta: {},
|
||||
require_: require,
|
||||
tsConfig: undefined,
|
||||
workPath: resolve(__dirname, './dev-fixtures'),
|
||||
entrypoint: './esm-module.ts',
|
||||
devServerPath: resolve(__dirname, '../dist/dev-server.js'),
|
||||
});
|
||||
const child = testForkDevServer('./esm-module.ts');
|
||||
|
||||
try {
|
||||
const result = await readMessage(child);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/python",
|
||||
"version": "3.1.50",
|
||||
"version": "3.1.51",
|
||||
"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.3.1",
|
||||
"@vercel/build-utils": "6.3.2",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"execa": "^1.0.0",
|
||||
"typescript": "4.3.4"
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
{
|
||||
"path": "/cookie_wsgi.py",
|
||||
"responseHeaders": {
|
||||
"set-cookie": ["one=first", "two=second"]
|
||||
"set-cookie": ["one=first; Path=/", "two=second; Path=/"]
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/redwood",
|
||||
"version": "1.1.6",
|
||||
"version": "1.1.7",
|
||||
"main": "./dist/index.js",
|
||||
"license": "MIT",
|
||||
"homepage": "https://vercel.com/docs",
|
||||
@@ -20,14 +20,14 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/nft": "0.22.5",
|
||||
"@vercel/routing-utils": "2.1.9",
|
||||
"@vercel/routing-utils": "2.1.10",
|
||||
"semver": "6.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/aws-lambda": "8.10.19",
|
||||
"@types/node": "14.18.33",
|
||||
"@types/semver": "6.0.0",
|
||||
"@vercel/build-utils": "6.3.1",
|
||||
"@vercel/build-utils": "6.3.2",
|
||||
"execa": "3.2.0",
|
||||
"fs-extra": "11.1.0",
|
||||
"typescript": "4.3.4"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/remix",
|
||||
"version": "1.4.0",
|
||||
"version": "1.5.1",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index.js",
|
||||
"homepage": "https://vercel.com/docs",
|
||||
@@ -18,10 +18,11 @@
|
||||
"files": [
|
||||
"dist",
|
||||
"server-node.mjs",
|
||||
"server-edge.mjs"
|
||||
"server-edge.mjs",
|
||||
"vercel-edge-entrypoint.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@remix-run/dev": "1.12.0",
|
||||
"@remix-run/dev": "npm:@vercel/remix-run-dev@1.13.0-patch.2",
|
||||
"@vercel/nft": "0.22.5",
|
||||
"@vercel/static-config": "2.0.13",
|
||||
"path-to-regexp": "6.2.1",
|
||||
@@ -30,7 +31,7 @@
|
||||
"devDependencies": {
|
||||
"@types/jest": "27.5.1",
|
||||
"@types/node": "14.18.33",
|
||||
"@vercel/build-utils": "6.3.1",
|
||||
"@vercel/build-utils": "6.3.2",
|
||||
"typescript": "4.9.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
import { createRequestHandler } from '@remix-run/server-runtime';
|
||||
import build from './index.js';
|
||||
import build from '@remix-run/dev/server-build';
|
||||
export default createRequestHandler(build);
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
|
||||
installGlobals();
|
||||
|
||||
import build from './index.js';
|
||||
import build from '@remix-run/dev/server-build';
|
||||
|
||||
const handleRequest = createRemixRequestHandler(build, process.env.NODE_ENV);
|
||||
|
||||
@@ -54,11 +54,13 @@ function createRemixRequest(req, res) {
|
||||
}
|
||||
|
||||
async function sendRemixResponse(res, nodeResponse) {
|
||||
res.statusCode = nodeResponse.status;
|
||||
res.statusMessage = nodeResponse.statusText;
|
||||
for (const [name, value] of nodeResponse.headers.entries()) {
|
||||
res.setHeader(name, value);
|
||||
}
|
||||
let multiValueHeaders = nodeResponse.headers.raw();
|
||||
res.writeHead(
|
||||
nodeResponse.status,
|
||||
nodeResponse.statusText,
|
||||
multiValueHeaders
|
||||
);
|
||||
|
||||
if (nodeResponse.body) {
|
||||
await writeReadableStreamToWritable(nodeResponse.body, res);
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
debug,
|
||||
download,
|
||||
execCommand,
|
||||
FileBlob,
|
||||
FileFsRef,
|
||||
getEnvForPackageManager,
|
||||
getNodeVersion,
|
||||
@@ -18,7 +19,7 @@ import {
|
||||
scanParentDirs,
|
||||
walkParentDirs,
|
||||
} from '@vercel/build-utils';
|
||||
import { getConfig, BaseFunctionConfig } from '@vercel/static-config';
|
||||
import { getConfig } from '@vercel/static-config';
|
||||
import { nodeFileTrace } from '@vercel/nft';
|
||||
import { readConfig } from '@remix-run/dev/dist/config';
|
||||
import type {
|
||||
@@ -28,17 +29,36 @@ import type {
|
||||
PackageJson,
|
||||
BuildResultV2Typical,
|
||||
} from '@vercel/build-utils';
|
||||
import type { BaseFunctionConfig } from '@vercel/static-config';
|
||||
import type { RemixConfig } from '@remix-run/dev/dist/config';
|
||||
import type { ConfigRoute } from '@remix-run/dev/dist/config/routes';
|
||||
import {
|
||||
calculateRouteConfigHash,
|
||||
findConfig,
|
||||
getPathFromRoute,
|
||||
getRegExpFromPath,
|
||||
getRouteIterator,
|
||||
getResolvedRouteConfig,
|
||||
isLayoutRoute,
|
||||
ResolvedRouteConfig,
|
||||
ResolvedNodeRouteConfig,
|
||||
ResolvedEdgeRouteConfig,
|
||||
} from './utils';
|
||||
|
||||
const _require: typeof require = eval('require');
|
||||
|
||||
const REMIX_RUN_DEV_PATH = dirname(
|
||||
_require.resolve('@remix-run/dev/package.json')
|
||||
);
|
||||
|
||||
const edgeServerSrcPromise = fs.readFile(
|
||||
join(__dirname, '../server-edge.mjs'),
|
||||
'utf-8'
|
||||
);
|
||||
const nodeServerSrcPromise = fs.readFile(
|
||||
join(__dirname, '../server-node.mjs'),
|
||||
'utf-8'
|
||||
);
|
||||
|
||||
export const build: BuildV2 = async ({
|
||||
entrypoint,
|
||||
files,
|
||||
@@ -91,11 +111,81 @@ export const build: BuildV2 = async ({
|
||||
await runNpmInstall(entrypointFsDirname, [], spawnOpts, meta, nodeVersion);
|
||||
}
|
||||
|
||||
const remixDevPackageJsonPath = _require.resolve(
|
||||
'@remix-run/dev/package.json',
|
||||
{ paths: [entrypointFsDirname] }
|
||||
);
|
||||
const remixVersion = JSON.parse(
|
||||
await fs.readFile(remixDevPackageJsonPath, 'utf8')
|
||||
).version;
|
||||
|
||||
// Make our version of `remix` CLI available to the project's build
|
||||
// command by creating a symlink to the copy in our node modules,
|
||||
// so that `serverBundles` works: https://github.com/remix-run/remix/pull/5479
|
||||
const remixRunDevPath = await ensureResolvable(
|
||||
entrypointFsDirname,
|
||||
repoRootPath,
|
||||
'@remix-run/dev'
|
||||
);
|
||||
const backupRemixRunDevPath = `${remixRunDevPath}.__vercel_backup`;
|
||||
await fs.rename(remixRunDevPath, backupRemixRunDevPath);
|
||||
await fs.symlink(REMIX_RUN_DEV_PATH, remixRunDevPath);
|
||||
|
||||
// Make `remix build` output production mode
|
||||
spawnOpts.env.NODE_ENV = 'production';
|
||||
|
||||
let remixConfig = await readConfig(entrypointFsDirname);
|
||||
const { serverEntryPoint } = remixConfig;
|
||||
const remixConfig = await chdirAndReadConfig(entrypointFsDirname);
|
||||
const remixRoutes = Object.values(remixConfig.routes);
|
||||
|
||||
// Read the `export const config` (if any) for each route
|
||||
const project = new Project();
|
||||
const staticConfigsMap = new Map<ConfigRoute, BaseFunctionConfig | null>();
|
||||
for (const route of remixRoutes) {
|
||||
const routePath = join(remixConfig.appDirectory, route.file);
|
||||
const staticConfig = getConfig(project, routePath);
|
||||
staticConfigsMap.set(route, staticConfig);
|
||||
}
|
||||
|
||||
const resolvedConfigsMap = new Map<ConfigRoute, ResolvedRouteConfig>();
|
||||
for (const route of remixRoutes) {
|
||||
const config = getResolvedRouteConfig(
|
||||
route,
|
||||
remixConfig.routes,
|
||||
staticConfigsMap
|
||||
);
|
||||
resolvedConfigsMap.set(route, config);
|
||||
}
|
||||
|
||||
// Figure out which routes belong to which server bundles
|
||||
// based on having common static config properties
|
||||
const serverBundlesMap = new Map<string, ConfigRoute[]>();
|
||||
for (const route of remixRoutes) {
|
||||
if (isLayoutRoute(route.id, remixRoutes)) continue;
|
||||
|
||||
const config = resolvedConfigsMap.get(route);
|
||||
if (!config) {
|
||||
throw new Error(`Expected resolved config for "${route.id}"`);
|
||||
}
|
||||
const hash = calculateRouteConfigHash(config);
|
||||
|
||||
let routesForHash = serverBundlesMap.get(hash);
|
||||
if (!Array.isArray(routesForHash)) {
|
||||
routesForHash = [];
|
||||
serverBundlesMap.set(hash, routesForHash);
|
||||
}
|
||||
|
||||
routesForHash.push(route);
|
||||
}
|
||||
|
||||
const serverBundles = Array.from(serverBundlesMap.entries()).map(
|
||||
([hash, routes]) => {
|
||||
const runtime = resolvedConfigsMap.get(routes[0])?.runtime ?? 'nodejs';
|
||||
return {
|
||||
serverBuildPath: `build/build-${runtime}-${hash}.js`,
|
||||
routes: routes.map(r => r.id),
|
||||
};
|
||||
}
|
||||
);
|
||||
|
||||
// We need to patch the `remix.config.js` file to force some values necessary
|
||||
// for a build that works on either Node.js or the Edge runtime
|
||||
@@ -122,7 +212,8 @@ export const build: BuildV2 = async ({
|
||||
config.serverBuildTarget = undefined;
|
||||
config.serverModuleFormat = 'cjs';
|
||||
config.serverPlatform = 'node';
|
||||
config.serverBuildPath = 'build/index.js';
|
||||
config.serverBuildPath = undefined;
|
||||
config.serverBundles = ${JSON.stringify(serverBundles)};
|
||||
export default config;`;
|
||||
} else {
|
||||
patchedConfig = `const config = require('./${basename(
|
||||
@@ -131,7 +222,8 @@ export default config;`;
|
||||
config.serverBuildTarget = undefined;
|
||||
config.serverModuleFormat = 'cjs';
|
||||
config.serverPlatform = 'node';
|
||||
config.serverBuildPath = 'build/index.js';
|
||||
config.serverBuildPath = undefined;
|
||||
config.serverBundles = ${JSON.stringify(serverBundles)};
|
||||
module.exports = config;`;
|
||||
}
|
||||
await fs.writeFile(remixConfigPath, patchedConfig);
|
||||
@@ -166,30 +258,15 @@ module.exports = config;`;
|
||||
});
|
||||
}
|
||||
}
|
||||
remixConfig = await readConfig(entrypointFsDirname);
|
||||
} finally {
|
||||
// Clean up our patched `remix.config.js` to be polite
|
||||
if (remixConfigPath && renamedRemixConfigPath) {
|
||||
await fs.rename(renamedRemixConfigPath, remixConfigPath);
|
||||
}
|
||||
}
|
||||
|
||||
const { serverBuildPath } = remixConfig;
|
||||
const remixRoutes = Object.values(remixConfig.routes);
|
||||
|
||||
// Figure out which pages should be edge functions
|
||||
let hasEdgeRoute = false;
|
||||
const staticConfigsMap = new Map<ConfigRoute, BaseFunctionConfig>();
|
||||
const project = new Project();
|
||||
for (const route of remixRoutes) {
|
||||
const routePath = join(remixConfig.appDirectory, route.file);
|
||||
const staticConfig = getConfig(project, routePath);
|
||||
if (staticConfig) {
|
||||
staticConfigsMap.set(route, staticConfig);
|
||||
}
|
||||
if (staticConfig?.runtime && isEdgeRuntime(staticConfig.runtime)) {
|
||||
hasEdgeRoute = true;
|
||||
}
|
||||
// Remove `@remix-run/dev` symlink
|
||||
await fs.unlink(remixRunDevPath);
|
||||
await fs.rename(backupRemixRunDevPath, remixRunDevPath);
|
||||
}
|
||||
|
||||
// This needs to happen before we run NFT to create the Node/Edge functions
|
||||
@@ -202,23 +279,35 @@ module.exports = config;`;
|
||||
ensureResolvable(entrypointFsDirname, repoRootPath, '@remix-run/node'),
|
||||
]);
|
||||
|
||||
const [staticFiles, nodeFunction, edgeFunction] = await Promise.all([
|
||||
const [staticFiles, ...functions] = await Promise.all([
|
||||
glob('**', join(entrypointFsDirname, 'public')),
|
||||
createRenderNodeFunction(
|
||||
entrypointFsDirname,
|
||||
repoRootPath,
|
||||
serverBuildPath,
|
||||
serverEntryPoint,
|
||||
nodeVersion
|
||||
),
|
||||
hasEdgeRoute
|
||||
? createRenderEdgeFunction(
|
||||
...serverBundles.map(bundle => {
|
||||
const firstRoute = remixConfig.routes[bundle.routes[0]];
|
||||
const config = resolvedConfigsMap.get(firstRoute) ?? {
|
||||
runtime: 'nodejs',
|
||||
};
|
||||
|
||||
if (config.runtime === 'edge') {
|
||||
return createRenderEdgeFunction(
|
||||
entrypointFsDirname,
|
||||
repoRootPath,
|
||||
serverBuildPath,
|
||||
serverEntryPoint
|
||||
)
|
||||
: undefined,
|
||||
join(entrypointFsDirname, bundle.serverBuildPath),
|
||||
remixConfig.serverEntryPoint,
|
||||
remixVersion,
|
||||
config
|
||||
);
|
||||
}
|
||||
|
||||
return createRenderNodeFunction(
|
||||
nodeVersion,
|
||||
entrypointFsDirname,
|
||||
repoRootPath,
|
||||
join(entrypointFsDirname, bundle.serverBuildPath),
|
||||
remixConfig.serverEntryPoint,
|
||||
remixVersion,
|
||||
config
|
||||
);
|
||||
}),
|
||||
]);
|
||||
|
||||
const output: BuildResultV2Typical['output'] = staticFiles;
|
||||
@@ -239,27 +328,32 @@ module.exports = config;`;
|
||||
|
||||
const path = getPathFromRoute(route, remixConfig.routes);
|
||||
|
||||
let isEdge = false;
|
||||
for (const currentRoute of getRouteIterator(route, remixConfig.routes)) {
|
||||
const staticConfig = staticConfigsMap.get(currentRoute);
|
||||
if (staticConfig?.runtime) {
|
||||
isEdge = isEdgeRuntime(staticConfig.runtime);
|
||||
break;
|
||||
}
|
||||
// If the route is a pathless layout route (at the root level)
|
||||
// and doesn't have any sub-routes, then a function should not be created.
|
||||
if (!path) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const fn =
|
||||
isEdge && edgeFunction
|
||||
const funcIndex = serverBundles.findIndex(bundle => {
|
||||
return bundle.routes.includes(route.id);
|
||||
});
|
||||
const func = functions[funcIndex];
|
||||
|
||||
if (!func) {
|
||||
throw new Error(`Could not determine server bundle for "${route.id}"`);
|
||||
}
|
||||
|
||||
output[path] =
|
||||
func instanceof EdgeFunction
|
||||
? // `EdgeFunction` currently requires the "name" property to be set.
|
||||
// Ideally this property will be removed, at which point we can
|
||||
// return the same `edgeFunction` instance instead of creating a
|
||||
// new one for each page.
|
||||
new EdgeFunction({
|
||||
...edgeFunction,
|
||||
...func,
|
||||
name: path,
|
||||
})
|
||||
: nodeFunction;
|
||||
output[path] = fn;
|
||||
: func;
|
||||
|
||||
// If this is a dynamic route then add a Vercel route
|
||||
const re = getRegExpFromPath(path);
|
||||
@@ -272,11 +366,20 @@ module.exports = config;`;
|
||||
}
|
||||
|
||||
// Add a 404 path for not found pages to be server-side rendered by Remix.
|
||||
// Use the edge function if one was generated, otherwise use Node.js.
|
||||
// Use an edge function bundle if one was generated, otherwise use Node.js.
|
||||
if (!output['404']) {
|
||||
output['404'] = edgeFunction
|
||||
? new EdgeFunction({ ...edgeFunction, name: '404' })
|
||||
: nodeFunction;
|
||||
const edgeFunctionIndex = Array.from(serverBundlesMap.values()).findIndex(
|
||||
routes => {
|
||||
const runtime = resolvedConfigsMap.get(routes[0])?.runtime;
|
||||
return runtime === 'edge';
|
||||
}
|
||||
);
|
||||
const func =
|
||||
edgeFunctionIndex !== -1 ? functions[edgeFunctionIndex] : functions[0];
|
||||
output['404'] =
|
||||
func instanceof EdgeFunction
|
||||
? new EdgeFunction({ ...func, name: '404' })
|
||||
: func;
|
||||
}
|
||||
routes.push({
|
||||
src: '/(.*)',
|
||||
@@ -292,23 +395,33 @@ function hasScript(scriptName: string, pkg: PackageJson | null) {
|
||||
}
|
||||
|
||||
async function createRenderNodeFunction(
|
||||
nodeVersion: NodeVersion,
|
||||
entrypointDir: string,
|
||||
rootDir: string,
|
||||
serverBuildPath: string,
|
||||
serverEntryPoint: string | undefined,
|
||||
nodeVersion: NodeVersion
|
||||
remixVersion: string,
|
||||
config: ResolvedNodeRouteConfig
|
||||
): Promise<NodejsLambda> {
|
||||
const files: Files = {};
|
||||
|
||||
let handler = relative(rootDir, serverBuildPath);
|
||||
let handlerPath = join(rootDir, handler);
|
||||
if (!serverEntryPoint) {
|
||||
handler = join(dirname(handler), 'server-node.mjs');
|
||||
const baseServerBuildPath = basename(serverBuildPath, '.js');
|
||||
handler = join(dirname(handler), `server-${baseServerBuildPath}.mjs`);
|
||||
handlerPath = join(rootDir, handler);
|
||||
|
||||
// Copy the `server-node.mjs` file into the "build" directory
|
||||
const sourceHandlerPath = join(__dirname, '../server-node.mjs');
|
||||
await fs.copyFile(sourceHandlerPath, handlerPath);
|
||||
const nodeServerSrc = await nodeServerSrcPromise;
|
||||
await writeEntrypointFile(
|
||||
handlerPath,
|
||||
nodeServerSrc.replace(
|
||||
'@remix-run/dev/server-build',
|
||||
`./${baseServerBuildPath}.js`
|
||||
),
|
||||
rootDir
|
||||
);
|
||||
}
|
||||
|
||||
// Trace the handler with `@vercel/nft`
|
||||
@@ -333,6 +446,13 @@ async function createRenderNodeFunction(
|
||||
shouldAddSourcemapSupport: false,
|
||||
operationType: 'SSR',
|
||||
experimentalResponseStreaming: true,
|
||||
regions: config.regions,
|
||||
memory: config.memory,
|
||||
maxDuration: config.maxDuration,
|
||||
framework: {
|
||||
slug: 'remix',
|
||||
version: remixVersion,
|
||||
},
|
||||
});
|
||||
|
||||
return fn;
|
||||
@@ -342,21 +462,33 @@ async function createRenderEdgeFunction(
|
||||
entrypointDir: string,
|
||||
rootDir: string,
|
||||
serverBuildPath: string,
|
||||
serverEntryPoint: string | undefined
|
||||
serverEntryPoint: string | undefined,
|
||||
remixVersion: string,
|
||||
config: ResolvedEdgeRouteConfig
|
||||
): Promise<EdgeFunction> {
|
||||
const files: Files = {};
|
||||
|
||||
let handler = relative(rootDir, serverBuildPath);
|
||||
let handlerPath = join(rootDir, handler);
|
||||
if (!serverEntryPoint) {
|
||||
handler = join(dirname(handler), 'server-edge.mjs');
|
||||
const baseServerBuildPath = basename(serverBuildPath, '.js');
|
||||
handler = join(dirname(handler), `server-${baseServerBuildPath}.mjs`);
|
||||
handlerPath = join(rootDir, handler);
|
||||
|
||||
// Copy the `server-edge.mjs` file into the "build" directory
|
||||
const sourceHandlerPath = join(__dirname, '../server-edge.mjs');
|
||||
await fs.copyFile(sourceHandlerPath, handlerPath);
|
||||
const edgeServerSrc = await edgeServerSrcPromise;
|
||||
await writeEntrypointFile(
|
||||
handlerPath,
|
||||
edgeServerSrc.replace(
|
||||
'@remix-run/dev/server-build',
|
||||
`./${baseServerBuildPath}.js`
|
||||
),
|
||||
rootDir
|
||||
);
|
||||
}
|
||||
|
||||
let remixRunVercelPkgJson: string | undefined;
|
||||
|
||||
// Trace the handler with `@vercel/nft`
|
||||
const trace = await nodeFileTrace([handlerPath], {
|
||||
base: rootDir,
|
||||
@@ -375,6 +507,35 @@ async function createRenderEdgeFunction(
|
||||
if (basename(fsPath) === 'package.json') {
|
||||
// For Edge Functions, patch "main" field to prefer "browser" or "module"
|
||||
const pkgJson = JSON.parse(source.toString());
|
||||
|
||||
// When `@remix-run/vercel` is detected, we need to modify the `package.json`
|
||||
// to include the "browser" field so that the proper Edge entrypoint file
|
||||
// is used. This is a temporary stop gap until this PR is merged:
|
||||
// https://github.com/remix-run/remix/pull/5537
|
||||
if (pkgJson.name === '@remix-run/vercel') {
|
||||
pkgJson.browser = 'dist/edge.js';
|
||||
pkgJson.dependencies['@remix-run/server-runtime'] =
|
||||
pkgJson.dependencies['@remix-run/node'];
|
||||
|
||||
if (!remixRunVercelPkgJson) {
|
||||
remixRunVercelPkgJson = JSON.stringify(pkgJson, null, 2) + '\n';
|
||||
|
||||
// Copy in the edge entrypoint so that NFT can properly resolve it
|
||||
const vercelEdgeEntrypointPath = join(
|
||||
__dirname,
|
||||
'../vercel-edge-entrypoint.js'
|
||||
);
|
||||
const vercelEdgeEntrypointDest = join(
|
||||
dirname(fsPath),
|
||||
'dist/edge.js'
|
||||
);
|
||||
await fs.copyFile(
|
||||
vercelEdgeEntrypointPath,
|
||||
vercelEdgeEntrypointDest
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
for (const prop of ['browser', 'module']) {
|
||||
const val = pkgJson[prop];
|
||||
if (typeof val === 'string') {
|
||||
@@ -395,7 +556,15 @@ async function createRenderEdgeFunction(
|
||||
}
|
||||
|
||||
for (const file of trace.fileList) {
|
||||
files[file] = await FileFsRef.fromFsPath({ fsPath: join(rootDir, file) });
|
||||
if (
|
||||
remixRunVercelPkgJson &&
|
||||
file.endsWith(`@remix-run${sep}vercel${sep}package.json`)
|
||||
) {
|
||||
// Use the modified `@remix-run/vercel` package.json which contains "browser" field
|
||||
files[file] = new FileBlob({ data: remixRunVercelPkgJson });
|
||||
} else {
|
||||
files[file] = await FileFsRef.fromFsPath({ fsPath: join(rootDir, file) });
|
||||
}
|
||||
}
|
||||
|
||||
const fn = new EdgeFunction({
|
||||
@@ -403,18 +572,30 @@ async function createRenderEdgeFunction(
|
||||
deploymentTarget: 'v8-worker',
|
||||
name: 'render',
|
||||
entrypoint: handler,
|
||||
regions: config.regions,
|
||||
framework: {
|
||||
slug: 'remix',
|
||||
version: remixVersion,
|
||||
},
|
||||
});
|
||||
|
||||
return fn;
|
||||
}
|
||||
|
||||
async function ensureResolvable(start: string, base: string, pkgName: string) {
|
||||
async function ensureResolvable(
|
||||
start: string,
|
||||
base: string,
|
||||
pkgName: string
|
||||
): Promise<string> {
|
||||
try {
|
||||
const resolvedPath = _require.resolve(pkgName, { paths: [start] });
|
||||
const resolvedPkgPath = _require.resolve(`${pkgName}/package.json`, {
|
||||
paths: [start],
|
||||
});
|
||||
const resolvedPath = dirname(resolvedPkgPath);
|
||||
if (!relative(base, resolvedPath).startsWith(`..${sep}`)) {
|
||||
// Resolved path is within the root of the project, so all good
|
||||
debug(`"${pkgName}" resolved to '${resolvedPath}'`);
|
||||
return;
|
||||
return resolvedPath;
|
||||
}
|
||||
} catch (err: any) {
|
||||
if (err.code !== 'MODULE_NOT_FOUND') {
|
||||
@@ -437,15 +618,8 @@ async function ensureResolvable(start: string, base: string, pkgName: string) {
|
||||
const match = packages.find(p => p.startsWith(prefix));
|
||||
if (match) {
|
||||
const pkgDir = join(pnpmDir, match, 'node_modules', pkgName);
|
||||
const symlinkPath = join(pnpmDir, '..', pkgName);
|
||||
const symlinkDir = dirname(symlinkPath);
|
||||
const symlinkTarget = relative(symlinkDir, pkgDir);
|
||||
await fs.mkdir(symlinkDir, { recursive: true });
|
||||
await fs.symlink(symlinkTarget, symlinkPath);
|
||||
console.warn(
|
||||
`WARN: Created symlink for "${pkgName}". To silence this warning, add "${pkgName}" to "dependencies" in your \`package.json\` file.`
|
||||
);
|
||||
return;
|
||||
await ensureSymlink(pkgDir, join(pnpmDir, '..'), pkgName);
|
||||
return pkgDir;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -462,15 +636,8 @@ async function ensureResolvable(start: string, base: string, pkgName: string) {
|
||||
const match = packages.find(p => p.startsWith(prefix));
|
||||
if (match) {
|
||||
const pkgDir = join(prefixDir, match, 'node_modules', pkgName);
|
||||
const symlinkPath = join(npmDir, '..', pkgName);
|
||||
const symlinkDir = dirname(symlinkPath);
|
||||
const symlinkTarget = relative(symlinkDir, pkgDir);
|
||||
await fs.mkdir(symlinkDir, { recursive: true });
|
||||
await fs.symlink(symlinkTarget, symlinkPath);
|
||||
console.warn(
|
||||
`WARN: Created symlink for "${pkgName}". To silence this warning, add "${pkgName}" to "dependencies" in your \`package.json\` file.`
|
||||
);
|
||||
return;
|
||||
await ensureSymlink(pkgDir, join(npmDir, '..'), pkgName);
|
||||
return pkgDir;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -479,6 +646,65 @@ async function ensureResolvable(start: string, base: string, pkgName: string) {
|
||||
);
|
||||
}
|
||||
|
||||
function isEdgeRuntime(runtime: string): boolean {
|
||||
return runtime === 'edge' || runtime === 'experimental-edge';
|
||||
async function ensureSymlink(
|
||||
target: string,
|
||||
nodeModulesDir: string,
|
||||
pkgName: string
|
||||
) {
|
||||
const symlinkPath = join(nodeModulesDir, pkgName);
|
||||
const symlinkDir = dirname(symlinkPath);
|
||||
const relativeTarget = relative(symlinkDir, target);
|
||||
|
||||
try {
|
||||
const existingTarget = await fs.readlink(symlinkPath);
|
||||
if (existingTarget === relativeTarget) {
|
||||
// Symlink is already the expected value, so do nothing
|
||||
return;
|
||||
} else {
|
||||
// If a symlink already exists then delete it if the target doesn't match
|
||||
await fs.unlink(symlinkPath);
|
||||
}
|
||||
} catch (err: any) {
|
||||
// Ignore when path does not exist or is not a symlink
|
||||
if (err.code !== 'ENOENT' && err.code !== 'EINVAL') {
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
await fs.symlink(relativeTarget, symlinkPath);
|
||||
console.warn(
|
||||
`WARN: Created symlink for "${pkgName}". To silence this warning, add "${pkgName}" to "dependencies" in your \`package.json\` file.`
|
||||
);
|
||||
}
|
||||
|
||||
async function chdirAndReadConfig(dir: string) {
|
||||
const originalCwd = process.cwd();
|
||||
let remixConfig: RemixConfig;
|
||||
try {
|
||||
process.chdir(dir);
|
||||
remixConfig = await readConfig(dir);
|
||||
} finally {
|
||||
process.chdir(originalCwd);
|
||||
}
|
||||
return remixConfig;
|
||||
}
|
||||
|
||||
async function writeEntrypointFile(
|
||||
path: string,
|
||||
data: string,
|
||||
rootDir: string
|
||||
) {
|
||||
try {
|
||||
await fs.writeFile(path, data);
|
||||
} catch (err: any) {
|
||||
if (err.code === 'ENOENT') {
|
||||
throw new Error(
|
||||
`The "${relative(
|
||||
rootDir,
|
||||
dirname(path)
|
||||
)}" directory does not exist. Please contact support@vercel.com.`
|
||||
);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,22 @@ import type {
|
||||
ConfigRoute,
|
||||
RouteManifest,
|
||||
} from '@remix-run/dev/dist/config/routes';
|
||||
import type { BaseFunctionConfig } from '@vercel/static-config';
|
||||
|
||||
export interface ResolvedNodeRouteConfig {
|
||||
runtime: 'nodejs';
|
||||
regions?: string[];
|
||||
maxDuration?: number;
|
||||
memory?: number;
|
||||
}
|
||||
export interface ResolvedEdgeRouteConfig {
|
||||
runtime: 'edge';
|
||||
regions?: BaseFunctionConfig['regions'];
|
||||
}
|
||||
|
||||
export type ResolvedRouteConfig =
|
||||
| ResolvedNodeRouteConfig
|
||||
| ResolvedEdgeRouteConfig;
|
||||
|
||||
const configExts = ['.js', '.cjs', '.mjs'];
|
||||
|
||||
@@ -18,6 +34,60 @@ export function findConfig(dir: string, basename: string): string | undefined {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function isEdgeRuntime(runtime: string): boolean {
|
||||
return runtime === 'edge' || runtime === 'experimental-edge';
|
||||
}
|
||||
|
||||
export function getResolvedRouteConfig(
|
||||
route: ConfigRoute,
|
||||
routes: RouteManifest,
|
||||
configs: Map<ConfigRoute, BaseFunctionConfig | null>
|
||||
): ResolvedRouteConfig {
|
||||
let runtime: ResolvedRouteConfig['runtime'] | undefined;
|
||||
let regions: ResolvedRouteConfig['regions'];
|
||||
let maxDuration: ResolvedNodeRouteConfig['maxDuration'];
|
||||
let memory: ResolvedNodeRouteConfig['memory'];
|
||||
|
||||
for (const currentRoute of getRouteIterator(route, routes)) {
|
||||
const staticConfig = configs.get(currentRoute);
|
||||
if (staticConfig) {
|
||||
if (typeof runtime === 'undefined' && staticConfig.runtime) {
|
||||
runtime = isEdgeRuntime(staticConfig.runtime) ? 'edge' : 'nodejs';
|
||||
}
|
||||
if (typeof regions === 'undefined') {
|
||||
regions = staticConfig.regions;
|
||||
}
|
||||
if (typeof maxDuration === 'undefined') {
|
||||
maxDuration = staticConfig.maxDuration;
|
||||
}
|
||||
if (typeof memory === 'undefined') {
|
||||
memory = staticConfig.memory;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Array.isArray(regions)) {
|
||||
regions = Array.from(new Set(regions)).sort();
|
||||
}
|
||||
|
||||
if (runtime === 'edge') {
|
||||
return { runtime, regions };
|
||||
}
|
||||
|
||||
if (regions && !Array.isArray(regions)) {
|
||||
throw new Error(
|
||||
`"regions" for route "${route.id}" must be an array of strings`
|
||||
);
|
||||
}
|
||||
|
||||
return { runtime: 'nodejs', regions, maxDuration, memory };
|
||||
}
|
||||
|
||||
export function calculateRouteConfigHash(config: ResolvedRouteConfig): string {
|
||||
const str = JSON.stringify(config);
|
||||
return Buffer.from(str).toString('base64url');
|
||||
}
|
||||
|
||||
export function isLayoutRoute(
|
||||
routeId: string,
|
||||
routes: Pick<ConfigRoute, 'id' | 'parentId'>[]
|
||||
@@ -41,9 +111,15 @@ export function getPathFromRoute(
|
||||
route: ConfigRoute,
|
||||
routes: RouteManifest
|
||||
): string {
|
||||
if (
|
||||
route.id === 'root' ||
|
||||
(route.parentId === 'root' && !route.path && route.index)
|
||||
) {
|
||||
return 'index';
|
||||
}
|
||||
|
||||
const pathParts: string[] = [];
|
||||
for (const currentRoute of getRouteIterator(route, routes)) {
|
||||
if (currentRoute.index) pathParts.push('index');
|
||||
if (currentRoute.path) pathParts.push(currentRoute.path);
|
||||
}
|
||||
const path = pathParts.reverse().join('/');
|
||||
|
||||
20
packages/remix/test/fixtures/01-remix-basics/app/b.server.ts
vendored
Normal file
20
packages/remix/test/fixtures/01-remix-basics/app/b.server.ts
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
// Edge functions can not use child processes, but this is route
|
||||
// uses Node.js. So this is here to verify that bundle splitting
|
||||
// is working correctly (because this route should not exist in
|
||||
// the Edge bundle).
|
||||
import { exec } from 'child_process';
|
||||
|
||||
import { json } from '@remix-run/node';
|
||||
|
||||
export async function loader() {
|
||||
const hi = await new Promise<string>((resolve, reject) => {
|
||||
exec(
|
||||
`echo hi from the B page running in ${process.env.VERCEL_REGION}`,
|
||||
(err, stdout) => {
|
||||
if (err) return reject(err);
|
||||
resolve(stdout);
|
||||
}
|
||||
);
|
||||
});
|
||||
return json({ hi });
|
||||
}
|
||||
4
packages/remix/test/fixtures/01-remix-basics/app/routes/__pathless.tsx
vendored
Normal file
4
packages/remix/test/fixtures/01-remix-basics/app/routes/__pathless.tsx
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
// This is a pathless layout route at the root level,
|
||||
// but there are no child routes, so a function should
|
||||
// not be created for this route.
|
||||
export default () => <div>pathless layout route</div>;
|
||||
@@ -1,7 +1,16 @@
|
||||
import { loader } from '~/b.server';
|
||||
import { useLoaderData } from '@remix-run/react';
|
||||
|
||||
export const config = { regions: ['sfo1'] };
|
||||
|
||||
export { loader };
|
||||
|
||||
export default function B() {
|
||||
const { hi } = useLoaderData<typeof loader>();
|
||||
return (
|
||||
<div style={{ fontFamily: "system-ui, sans-serif", lineHeight: "1.4" }}>
|
||||
<h1>B page</h1>
|
||||
<p>{hi}</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
export const config = {
|
||||
runtime: 'edge'
|
||||
};
|
||||
export const config = { runtime: 'edge' };
|
||||
|
||||
export default function Edge() {
|
||||
return (
|
||||
|
||||
3
packages/remix/test/fixtures/01-remix-basics/app/routes/nested2/__pathless.tsx
vendored
Normal file
3
packages/remix/test/fixtures/01-remix-basics/app/routes/nested2/__pathless.tsx
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
// This is a pathless layout route without any child routes,
|
||||
// but Remix will serve this since its not at the root level.
|
||||
export default () => <div>nested2 pathless layout route</div>;
|
||||
10
packages/remix/test/fixtures/01-remix-basics/app/routes/set-cookie-edge.tsx
vendored
Normal file
10
packages/remix/test/fixtures/01-remix-basics/app/routes/set-cookie-edge.tsx
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
import type { LoaderFunction } from '@remix-run/server-runtime';
|
||||
|
||||
export const config = { runtime: 'edge' };
|
||||
|
||||
export const loader: LoaderFunction = () => {
|
||||
const headers = new Headers();
|
||||
headers.append('Set-Cookie', 'hello=world');
|
||||
headers.append('Set-Cookie', 'foo=bar');
|
||||
return new Response(null, { headers });
|
||||
};
|
||||
8
packages/remix/test/fixtures/01-remix-basics/app/routes/set-cookie-node.tsx
vendored
Normal file
8
packages/remix/test/fixtures/01-remix-basics/app/routes/set-cookie-node.tsx
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
import type { LoaderFunction } from '@remix-run/server-runtime';
|
||||
|
||||
export const loader: LoaderFunction = () => {
|
||||
const headers = new Headers();
|
||||
headers.append('Set-Cookie', 'hello=world');
|
||||
headers.append('Set-Cookie', 'foo=bar');
|
||||
return new Response(null, { headers });
|
||||
};
|
||||
42
packages/remix/test/fixtures/01-remix-basics/probes.json
vendored
Normal file
42
packages/remix/test/fixtures/01-remix-basics/probes.json
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
{
|
||||
"probes": [
|
||||
{ "path": "/", "mustContain": "Welcome to Remix" },
|
||||
{ "path": "/edge", "mustContain": "Welcome to Remix@Edge" },
|
||||
{ "path": "/b", "mustContain": "hi from the B page running in sfo1" },
|
||||
{ "path": "/nested", "mustContain": "Nested index page" },
|
||||
{ "path": "/nested/another", "mustContain": "Nested another page" },
|
||||
{ "path": "/nested/index", "status": 404, "mustContain": "Not Found" },
|
||||
{ "path": "/asdf", "status": 404, "mustContain": "Not Found" },
|
||||
{ "path": "/instanceof", "mustContain": "InstanceOfRequest: true" },
|
||||
{ "path": "/projects/edge", "mustContain": "\"isEdge\":true" },
|
||||
{ "path": "/projects/node", "mustContain": "\"isEdge\":false" },
|
||||
{
|
||||
"path": "/__pathless",
|
||||
"status": 404,
|
||||
"mustContain": "Not Found"
|
||||
},
|
||||
{
|
||||
"path": "/nested2",
|
||||
"mustContain": "nested2 pathless layout route"
|
||||
},
|
||||
{
|
||||
"path": "/nested2/__pathless",
|
||||
"status": 404,
|
||||
"mustContain": "Not Found"
|
||||
},
|
||||
{
|
||||
"path": "/set-cookie-edge",
|
||||
"status": 200,
|
||||
"responseHeaders": {
|
||||
"set-cookie": ["hello=world", "foo=bar"]
|
||||
}
|
||||
},
|
||||
{
|
||||
"path": "/set-cookie-node",
|
||||
"status": 200,
|
||||
"responseHeaders": {
|
||||
"set-cookie": ["hello=world", "foo=bar"]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
{
|
||||
"version": 2,
|
||||
"builds": [
|
||||
{
|
||||
"src": "package.json",
|
||||
"use": "@vercel/remix",
|
||||
"config": {
|
||||
"zeroConfig": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"probes": [
|
||||
{ "path": "/", "mustContain": "Welcome to Remix" },
|
||||
{ "path": "/edge", "mustContain": "Welcome to Remix@Edge" },
|
||||
{ "path": "/b", "mustContain": "B page" },
|
||||
{ "path": "/nested", "mustContain": "Nested index page" },
|
||||
{ "path": "/nested/another", "mustContain": "Nested another page" },
|
||||
{ "path": "/nested/index", "mustContain": "Not Found" },
|
||||
{ "path": "/asdf", "mustContain": "Not Found" },
|
||||
{ "path": "/instanceof", "mustContain": "InstanceOfRequest: true" },
|
||||
{ "path": "/projects/edge", "mustContain": "\"isEdge\":true" },
|
||||
{ "path": "/projects/node", "mustContain": "\"isEdge\":false" }
|
||||
]
|
||||
}
|
||||
9
packages/remix/test/fixtures/02-remix-basics-mjs/app/routes/edge.tsx
vendored
Normal file
9
packages/remix/test/fixtures/02-remix-basics-mjs/app/routes/edge.tsx
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
export const config = { runtime: 'edge' };
|
||||
|
||||
export default function Edge() {
|
||||
return (
|
||||
<div style={{ fontFamily: 'system-ui, sans-serif', lineHeight: '1.4' }}>
|
||||
<h1>Welcome to Remix@Edge</h1>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { json, LoaderFunction } from "@remix-run/node";
|
||||
import { json, LoaderFunction } from "@remix-run/server-runtime";
|
||||
|
||||
export const loader: LoaderFunction = ({ context }) => {
|
||||
return json(context);
|
||||
|
||||
7
packages/remix/test/fixtures/02-remix-basics-mjs/probes.json
vendored
Normal file
7
packages/remix/test/fixtures/02-remix-basics-mjs/probes.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"probes": [
|
||||
{ "path": "/", "mustContain": "Welcome to Remix" },
|
||||
{ "path": "/edge", "mustContain": "Welcome to Remix@Edge" },
|
||||
{ "path": "/load-context", "mustContain": "{\"nodeLoadContext\":true}" }
|
||||
]
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
*/
|
||||
export default {
|
||||
ignoredRouteFiles: ["**/.*"],
|
||||
serverBuildTarget: "vercel",
|
||||
// When running locally in development mode, we use the built-in remix
|
||||
// server. This does not understand the vercel lambda module format,
|
||||
// so we default back to the standard build output.
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"version": 2,
|
||||
"builds": [
|
||||
{
|
||||
"src": "package.json",
|
||||
"use": "@vercel/remix",
|
||||
"config": {
|
||||
"zeroConfig": true
|
||||
}
|
||||
}
|
||||
],
|
||||
"probes": [
|
||||
{ "path": "/", "mustContain": "Welcome to Remix" },
|
||||
{ "path": "/load-context", "mustContain": "{\"nodeLoadContext\":true}" }
|
||||
]
|
||||
}
|
||||
@@ -10,13 +10,13 @@
|
||||
"start": "remix-serve build"
|
||||
},
|
||||
"dependencies": {
|
||||
"@remix-run/react": "^1.7.4",
|
||||
"@remix-run/serve": "^1.7.4",
|
||||
"@remix-run/react": "1.5.0",
|
||||
"@remix-run/serve": "1.5.0",
|
||||
"react": "18.2.0",
|
||||
"react-dom": "18.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@remix-run/dev": "^1.7.4",
|
||||
"@remix-run/dev": "1.5.0",
|
||||
"@types/react": "^17.0.45",
|
||||
"@types/react-dom": "^17.0.17",
|
||||
"typescript": "^4.6.4"
|
||||
|
||||
3281
packages/remix/test/fixtures/03-with-pnpm/pnpm-lock.yaml
generated
vendored
3281
packages/remix/test/fixtures/03-with-pnpm/pnpm-lock.yaml
generated
vendored
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user