mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-12 12:57:47 +00:00
Compare commits
21 Commits
@vercel/py
...
@vercel/py
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ad436313e1 | ||
|
|
c414288b2f | ||
|
|
b07ff7431f | ||
|
|
79fde4475c | ||
|
|
855197c699 | ||
|
|
fbd9080859 | ||
|
|
b5c5b7b82c | ||
|
|
0a072ee850 | ||
|
|
0b56caba45 | ||
|
|
ab3db60824 | ||
|
|
f2f2ff2c67 | ||
|
|
ba7dafff71 | ||
|
|
987fb4d4f7 | ||
|
|
be74f79fa0 | ||
|
|
86886e6b60 | ||
|
|
e8a9000137 | ||
|
|
75ea68d445 | ||
|
|
a5a990995c | ||
|
|
cd7dcc6731 | ||
|
|
c4bd462b85 | ||
|
|
5fc266bd8a |
8
.github/CONTRIBUTING.md
vendored
8
.github/CONTRIBUTING.md
vendored
@@ -23,7 +23,7 @@ Make sure all the tests pass before making changes.
|
|||||||
|
|
||||||
## Verifying your change
|
## Verifying your change
|
||||||
|
|
||||||
Once you are done with your changes (we even suggest doing it along the way), make sure all the test still pass by running:
|
Once you are done with your changes (we even suggest doing it along the way), make sure all the tests still pass by running:
|
||||||
|
|
||||||
```
|
```
|
||||||
yarn test-unit
|
yarn test-unit
|
||||||
@@ -64,7 +64,7 @@ Integration tests create deployments to your Vercel account using the `test` pro
|
|||||||
x-now-trace=iad1]
|
x-now-trace=iad1]
|
||||||
```
|
```
|
||||||
|
|
||||||
In such cases you can visit the URL of the failed deployment and append `/_logs` so see the build error. In the case above, that would be https://test-8ashcdlew.vercel.app/_logs
|
In such cases, you can visit the URL of the failed deployment and append `/_logs` to see the build error. In the case above, that would be https://test-8ashcdlew.vercel.app/_logs
|
||||||
|
|
||||||
The logs of this deployment will contain the actual error which may help you to understand what went wrong.
|
The logs of this deployment will contain the actual error which may help you to understand what went wrong.
|
||||||
|
|
||||||
@@ -82,11 +82,11 @@ nodeFileTrace(['path/to/entrypoint.js'], {
|
|||||||
.then(e => console.error(e));
|
.then(e => console.error(e));
|
||||||
```
|
```
|
||||||
|
|
||||||
When you run this script, you'll see all imported files. If anything file is missing, the bug is in [@vercel/nft](https://github.com/vercel/nft) and not the Builder.
|
When you run this script, you'll see all the imported files. If anything file is missing, the bug is in [@vercel/nft](https://github.com/vercel/nft) and not the Builder.
|
||||||
|
|
||||||
## Deploy a Builder with existing project
|
## Deploy a Builder with existing project
|
||||||
|
|
||||||
Sometimes you want to test changes to a Builder against an existing project, maybe with `vercel dev` or an actual deployment. You can avoid publishing every Builder change to npm by uploading the Builder as a tarball.
|
Sometimes you want to test changes to a Builder against an existing project, maybe with `vercel dev` or actual deployment. You can avoid publishing every Builder change to npm by uploading the Builder as a tarball.
|
||||||
|
|
||||||
1. Change directory to the desired Builder `cd ./packages/node`
|
1. Change directory to the desired Builder `cd ./packages/node`
|
||||||
2. Run `yarn build` to compile typescript and other build steps
|
2. Run `yarn build` to compile typescript and other build steps
|
||||||
|
|||||||
12
.github/workflows/test-integration-cli.yml
vendored
12
.github/workflows/test-integration-cli.yml
vendored
@@ -16,13 +16,15 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest]
|
os: [ubuntu-latest]
|
||||||
node: [12]
|
node: [14]
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
env:
|
|
||||||
TURBO_REMOTE_ONLY: true
|
|
||||||
TURBO_TEAM: vercel
|
|
||||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
|
||||||
steps:
|
steps:
|
||||||
|
- name: Conditionally set remote env
|
||||||
|
if: github.event.pull_request.head.repo.full_name == github.repository
|
||||||
|
run: |
|
||||||
|
echo "TURBO_REMOTE_ONLY=true" >> $GITHUB_ENV
|
||||||
|
echo "TURBO_TEAM=vercel" >> $GITHUB_ENV
|
||||||
|
echo "TURBO_TOKEN=${{ secrets.TURBO_TOKEN }}" >> $GITHUB_ENV
|
||||||
- uses: actions/setup-go@v2
|
- uses: actions/setup-go@v2
|
||||||
with:
|
with:
|
||||||
go-version: '1.13.15'
|
go-version: '1.13.15'
|
||||||
|
|||||||
10
.github/workflows/test-unit.yml
vendored
10
.github/workflows/test-unit.yml
vendored
@@ -18,11 +18,13 @@ jobs:
|
|||||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
node: [14]
|
node: [14]
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
env:
|
|
||||||
TURBO_REMOTE_ONLY: true
|
|
||||||
TURBO_TEAM: vercel
|
|
||||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
|
||||||
steps:
|
steps:
|
||||||
|
- name: Conditionally set remote env
|
||||||
|
if: github.event.pull_request.head.repo.full_name == github.repository
|
||||||
|
run: |
|
||||||
|
echo "TURBO_REMOTE_ONLY=true" >> $GITHUB_ENV
|
||||||
|
echo "TURBO_TEAM=vercel" >> $GITHUB_ENV
|
||||||
|
echo "TURBO_TOKEN=${{ secrets.TURBO_TOKEN }}" >> $GITHUB_ENV
|
||||||
- uses: actions/setup-go@v2
|
- uses: actions/setup-go@v2
|
||||||
with:
|
with:
|
||||||
go-version: '1.13.15'
|
go-version: '1.13.15'
|
||||||
|
|||||||
10
.github/workflows/test.yml
vendored
10
.github/workflows/test.yml
vendored
@@ -38,10 +38,6 @@ jobs:
|
|||||||
runs-on: ${{ matrix.runner }}
|
runs-on: ${{ matrix.runner }}
|
||||||
name: ${{matrix.scriptName}} (${{matrix.packageName}}, ${{matrix.chunkNumber}}, ${{ matrix.runner }})
|
name: ${{matrix.scriptName}} (${{matrix.packageName}}, ${{matrix.chunkNumber}}, ${{ matrix.runner }})
|
||||||
if: ${{ needs.setup.outputs['tests'] != '[]' }}
|
if: ${{ needs.setup.outputs['tests'] != '[]' }}
|
||||||
env:
|
|
||||||
TURBO_REMOTE_ONLY: true
|
|
||||||
TURBO_TEAM: vercel
|
|
||||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
|
||||||
needs:
|
needs:
|
||||||
- setup
|
- setup
|
||||||
strategy:
|
strategy:
|
||||||
@@ -49,6 +45,12 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
include: ${{ fromJson(needs.setup.outputs['tests']) }}
|
include: ${{ fromJson(needs.setup.outputs['tests']) }}
|
||||||
steps:
|
steps:
|
||||||
|
- name: Conditionally set remote env
|
||||||
|
if: github.event.pull_request.head.repo.full_name == github.repository
|
||||||
|
run: |
|
||||||
|
echo "TURBO_REMOTE_ONLY=true" >> $GITHUB_ENV
|
||||||
|
echo "TURBO_TEAM=vercel" >> $GITHUB_ENV
|
||||||
|
echo "TURBO_TOKEN=${{ secrets.TURBO_TOKEN }}" >> $GITHUB_ENV
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
with:
|
with:
|
||||||
fetch-depth: 2
|
fetch-depth: 2
|
||||||
|
|||||||
1
examples/sveltekit/.gitignore
vendored
1
examples/sveltekit/.gitignore
vendored
@@ -7,3 +7,4 @@ node_modules
|
|||||||
.env.*
|
.env.*
|
||||||
!.env.example
|
!.env.example
|
||||||
.vercel
|
.vercel
|
||||||
|
.output
|
||||||
|
|||||||
13
examples/sveltekit/.prettierignore
Normal file
13
examples/sveltekit/.prettierignore
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
.DS_Store
|
||||||
|
node_modules
|
||||||
|
/build
|
||||||
|
/.svelte-kit
|
||||||
|
/package
|
||||||
|
.env
|
||||||
|
.env.*
|
||||||
|
!.env.example
|
||||||
|
|
||||||
|
# Ignore files for PNPM, NPM and YARN
|
||||||
|
pnpm-lock.yaml
|
||||||
|
package-lock.json
|
||||||
|
yarn.lock
|
||||||
6
examples/sveltekit/.prettierrc
Normal file
6
examples/sveltekit/.prettierrc
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"useTabs": false,
|
||||||
|
"singleQuote": true,
|
||||||
|
"trailingComma": "none",
|
||||||
|
"printWidth": 100
|
||||||
|
}
|
||||||
@@ -14,31 +14,29 @@ If you're seeing this, you've probably already done this step. Congrats!
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# create a new project in the current directory
|
# create a new project in the current directory
|
||||||
npm init svelte@next
|
npm init svelte
|
||||||
|
|
||||||
# create a new project in my-app
|
# create a new project in my-app
|
||||||
npm init svelte@next my-app
|
npm init svelte my-app
|
||||||
```
|
```
|
||||||
|
|
||||||
> Note: the `@next` is temporary
|
|
||||||
|
|
||||||
## Developing
|
## Developing
|
||||||
|
|
||||||
Once you've created a project and installed dependencies with `npm install` (or `pnpm install` or `yarn`), start a development server:
|
Once you've created a project and installed dependencies with `pnpm install`, start a development server:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run dev
|
pnpm run dev
|
||||||
|
|
||||||
# or start the server and open the app in a new browser tab
|
# or start the server and open the app in a new browser tab
|
||||||
npm run dev -- --open
|
pnpm run dev -- --open
|
||||||
```
|
```
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
This uses the adapter-auto for SvelteKit, which detects Vercel and runs adapter-vercel on your behalf.
|
To create a production version of your app:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npm run build
|
pnpm run build
|
||||||
```
|
```
|
||||||
|
|
||||||
> You can preview the built app with `npm run preview`, regardless of whether you installed an adapter. This should _not_ be used to serve your app in production.
|
You can preview the production build with `npm run preview`.
|
||||||
|
|||||||
@@ -1,10 +1,13 @@
|
|||||||
{
|
{
|
||||||
|
"extends": "./.svelte-kit/tsconfig.json",
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"baseUrl": ".",
|
"allowJs": true,
|
||||||
"paths": {
|
"checkJs": true,
|
||||||
"$lib": ["src/lib"],
|
"esModuleInterop": true,
|
||||||
"$lib/*": ["src/lib/*"]
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
"strict": true
|
||||||
}
|
}
|
||||||
},
|
|
||||||
"include": ["src/**/*.d.ts", "src/**/*.js", "src/**/*.svelte"]
|
|
||||||
}
|
}
|
||||||
|
|||||||
1267
examples/sveltekit/package-lock.json
generated
1267
examples/sveltekit/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,22 +1,29 @@
|
|||||||
{
|
{
|
||||||
"private": true,
|
"private": true,
|
||||||
"name": "sveltekit",
|
|
||||||
"version": "0.0.1",
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "svelte-kit dev",
|
"dev": "svelte-kit dev",
|
||||||
"build": "svelte-kit build",
|
"build": "svelte-kit build",
|
||||||
"package": "svelte-kit package",
|
"package": "svelte-kit package",
|
||||||
"preview": "svelte-kit preview"
|
"preview": "svelte-kit preview",
|
||||||
|
"prepare": "svelte-kit sync",
|
||||||
|
"check": "svelte-check --tsconfig ./jsconfig.json",
|
||||||
|
"check:watch": "svelte-check --tsconfig ./jsconfig.json --watch",
|
||||||
|
"lint": "prettier --check --plugin-search-dir=. .",
|
||||||
|
"format": "prettier --write --plugin-search-dir=. ."
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@sveltejs/adapter-auto": "next",
|
"@sveltejs/adapter-auto": "next",
|
||||||
"@sveltejs/kit": "next",
|
"@sveltejs/kit": "next",
|
||||||
"svelte": "^3.46.0"
|
"@types/cookie": "^0.4.1",
|
||||||
|
"prettier": "^2.5.1",
|
||||||
|
"prettier-plugin-svelte": "^2.5.0",
|
||||||
|
"svelte": "^3.46.0",
|
||||||
|
"svelte-check": "^2.2.6",
|
||||||
|
"typescript": "~4.6.2"
|
||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@fontsource/fira-mono": "^4.5.0",
|
"@fontsource/fira-mono": "^4.5.0",
|
||||||
"@lukeed/uuid": "^2.0.0",
|
|
||||||
"cookie": "^0.4.1"
|
"cookie": "^0.4.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
1633
examples/sveltekit/pnpm-lock.yaml
generated
Normal file
1633
examples/sveltekit/pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
15
examples/sveltekit/src/app.d.ts
vendored
Normal file
15
examples/sveltekit/src/app.d.ts
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
/// <reference types="@sveltejs/kit" />
|
||||||
|
|
||||||
|
// See https://kit.svelte.dev/docs/types#app
|
||||||
|
// for information about these interfaces
|
||||||
|
declare namespace App {
|
||||||
|
interface Locals {
|
||||||
|
userid: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
// interface Platform {}
|
||||||
|
|
||||||
|
// interface Session {}
|
||||||
|
|
||||||
|
// interface Stuff {}
|
||||||
|
}
|
||||||
@@ -2,12 +2,11 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="description" content="Svelte demo app" />
|
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
|
||||||
<link rel="icon" href="%svelte.assets%/favicon.png" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||||
%svelte.head%
|
%sveltekit.head%
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div>%svelte.body%</div>
|
<div>%sveltekit.body%</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
import cookie from 'cookie';
|
import * as cookie from 'cookie';
|
||||||
import { v4 as uuid } from '@lukeed/uuid';
|
|
||||||
|
|
||||||
|
/** @type {import('@sveltejs/kit').Handle} */
|
||||||
export const handle = async ({ event, resolve }) => {
|
export const handle = async ({ event, resolve }) => {
|
||||||
const cookies = cookie.parse(event.request.headers.get('cookie') || '');
|
const cookies = cookie.parse(event.request.headers.get('cookie') || '');
|
||||||
event.locals.userid = cookies.userid || uuid();
|
event.locals.userid = cookies['userid'] || crypto.randomUUID();
|
||||||
|
|
||||||
const response = await resolve(event);
|
const response = await resolve(event);
|
||||||
|
|
||||||
if (!cookies.userid) {
|
if (!cookies['userid']) {
|
||||||
// if this is the first time the user has visited this app,
|
// if this is the first time the user has visited this app,
|
||||||
// set a cookie so that we recognise them when they return
|
// set a cookie so that we recognise them when they return
|
||||||
response.headers.set(
|
response.headers.set(
|
||||||
|
|||||||
@@ -7,6 +7,10 @@
|
|||||||
$: displayed_count.set(count);
|
$: displayed_count.set(count);
|
||||||
$: offset = modulo($displayed_count, 1);
|
$: offset = modulo($displayed_count, 1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} n
|
||||||
|
* @param {number} m
|
||||||
|
*/
|
||||||
function modulo(n, m) {
|
function modulo(n, m) {
|
||||||
// handle negative numbers
|
// handle negative numbers
|
||||||
return ((n % m) + m) % m;
|
return ((n % m) + m) % m;
|
||||||
@@ -50,6 +54,7 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
border: 0;
|
border: 0;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
|
touch-action: manipulation;
|
||||||
color: var(--text-color);
|
color: var(--text-color);
|
||||||
font-size: 2rem;
|
font-size: 2rem;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,9 +2,36 @@ import { invalidate } from '$app/navigation';
|
|||||||
|
|
||||||
// this action (https://svelte.dev/tutorial/actions) allows us to
|
// this action (https://svelte.dev/tutorial/actions) allows us to
|
||||||
// progressively enhance a <form> that already works without JS
|
// progressively enhance a <form> that already works without JS
|
||||||
|
/**
|
||||||
|
* @param {HTMLFormElement} form
|
||||||
|
* @param {{
|
||||||
|
* pending?: ({ data, form }: { data: FormData; form: HTMLFormElement }) => void;
|
||||||
|
* error?: ({
|
||||||
|
* data,
|
||||||
|
* form,
|
||||||
|
* response,
|
||||||
|
* error
|
||||||
|
* }: {
|
||||||
|
* data: FormData;
|
||||||
|
* form: HTMLFormElement;
|
||||||
|
* response: Response | null;
|
||||||
|
* error: Error | null;
|
||||||
|
* }) => void;
|
||||||
|
* result?: ({
|
||||||
|
* data,
|
||||||
|
* form,
|
||||||
|
* response
|
||||||
|
* }: {
|
||||||
|
* data: FormData;
|
||||||
|
* response: Response;
|
||||||
|
* form: HTMLFormElement;
|
||||||
|
* }) => void;
|
||||||
|
* }} [opts]
|
||||||
|
*/
|
||||||
export function enhance(form, { pending, error, result } = {}) {
|
export function enhance(form, { pending, error, result } = {}) {
|
||||||
let current_token;
|
let current_token;
|
||||||
|
|
||||||
|
/** @param {SubmitEvent} e */
|
||||||
async function handle_submit(e) {
|
async function handle_submit(e) {
|
||||||
const token = (current_token = {});
|
const token = (current_token = {});
|
||||||
|
|
||||||
@@ -37,7 +64,7 @@ export function enhance(form, { pending, error, result } = {}) {
|
|||||||
console.error(await response.text());
|
console.error(await response.text());
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (error) {
|
if (error && e instanceof Error) {
|
||||||
error({ data, form, error: e, response: null });
|
error({ data, form, error: e, response: null });
|
||||||
} else {
|
} else {
|
||||||
throw e;
|
throw e;
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
<title>About</title>
|
<title>About</title>
|
||||||
|
<meta name="description" content="About this app" />
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
@@ -26,8 +27,7 @@
|
|||||||
following into your command line and following the prompts:
|
following into your command line and following the prompts:
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<!-- TODO lose the @next! -->
|
<pre>npm init svelte</pre>
|
||||||
<pre>npm init svelte@next</pre>
|
|
||||||
|
|
||||||
<p>
|
<p>
|
||||||
The page you're looking at is purely static HTML, with no client-side interactivity needed.
|
The page you're looking at is purely static HTML, with no client-side interactivity needed.
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
<title>Home</title>
|
<title>Home</title>
|
||||||
|
<meta name="description" content="Svelte demo app" />
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
|
|||||||
@@ -11,6 +11,11 @@
|
|||||||
|
|
||||||
const base = 'https://api.svelte.dev';
|
const base = 'https://api.svelte.dev';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} method
|
||||||
|
* @param {string} resource
|
||||||
|
* @param {Record<string, unknown>} [data]
|
||||||
|
*/
|
||||||
export function api(method, resource, data) {
|
export function api(method, resource, data) {
|
||||||
return fetch(`${base}/${resource}`, {
|
return fetch(`${base}/${resource}`, {
|
||||||
method,
|
method,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { api } from './_api';
|
import { api } from './_api';
|
||||||
|
|
||||||
|
/** @type {import('./__types').RequestHandler} */
|
||||||
export const get = async ({ locals }) => {
|
export const get = async ({ locals }) => {
|
||||||
// locals.userid comes from src/hooks.js
|
// locals.userid comes from src/hooks.js
|
||||||
const response = await api('get', `todos/${locals.userid}`);
|
const response = await api('get', `todos/${locals.userid}`);
|
||||||
@@ -27,6 +28,7 @@ export const get = async ({ locals }) => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** @type {import('./index').RequestHandler} */
|
||||||
export const post = async ({ request, locals }) => {
|
export const post = async ({ request, locals }) => {
|
||||||
const form = await request.formData();
|
const form = await request.formData();
|
||||||
|
|
||||||
@@ -46,6 +48,7 @@ const redirect = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** @type {import('./index').RequestHandler} */
|
||||||
export const patch = async ({ request, locals }) => {
|
export const patch = async ({ request, locals }) => {
|
||||||
const form = await request.formData();
|
const form = await request.formData();
|
||||||
|
|
||||||
@@ -57,6 +60,7 @@ export const patch = async ({ request, locals }) => {
|
|||||||
return redirect;
|
return redirect;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** @type {import('./index').RequestHandler} */
|
||||||
export const del = async ({ request, locals }) => {
|
export const del = async ({ request, locals }) => {
|
||||||
const form = await request.formData();
|
const form = await request.formData();
|
||||||
|
|
||||||
|
|||||||
@@ -3,11 +3,23 @@
|
|||||||
import { scale } from 'svelte/transition';
|
import { scale } from 'svelte/transition';
|
||||||
import { flip } from 'svelte/animate';
|
import { flip } from 'svelte/animate';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {{
|
||||||
|
* uid: string;
|
||||||
|
* created_at: Date;
|
||||||
|
* text: string;
|
||||||
|
* done: boolean;
|
||||||
|
* pending_delete: boolean;
|
||||||
|
* }} Todo
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @type {Todo[]} */
|
||||||
export let todos;
|
export let todos;
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
<title>Todos</title>
|
<title>Todos</title>
|
||||||
|
<meta name="description" content="A todo list app" />
|
||||||
</svelte:head>
|
</svelte:head>
|
||||||
|
|
||||||
<div class="todos">
|
<div class="todos">
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
"prettier": "2.6.2",
|
"prettier": "2.6.2",
|
||||||
"ts-eager": "2.0.2",
|
"ts-eager": "2.0.2",
|
||||||
"ts-jest": "28.0.0-next.1",
|
"ts-jest": "28.0.0-next.1",
|
||||||
"turbo": "1.2.9"
|
"turbo": "1.2.14"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"lerna": "lerna",
|
"lerna": "lerna",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vercel/build-utils",
|
"name": "@vercel/build-utils",
|
||||||
"version": "3.1.1-canary.1",
|
"version": "3.1.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"types": "./dist/index.d.js",
|
"types": "./dist/index.d.js",
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
"@types/node-fetch": "^2.1.6",
|
"@types/node-fetch": "^2.1.6",
|
||||||
"@types/semver": "6.0.0",
|
"@types/semver": "6.0.0",
|
||||||
"@types/yazl": "2.4.2",
|
"@types/yazl": "2.4.2",
|
||||||
"@vercel/frameworks": "0.9.2-canary.0",
|
"@vercel/frameworks": "1.0.0",
|
||||||
"@vercel/ncc": "0.24.0",
|
"@vercel/ncc": "0.24.0",
|
||||||
"aggregate-error": "3.0.1",
|
"aggregate-error": "3.0.1",
|
||||||
"async-retry": "1.2.3",
|
"async-retry": "1.2.3",
|
||||||
|
|||||||
@@ -205,7 +205,9 @@ export function getSpawnOptions(
|
|||||||
|
|
||||||
if (!meta.isDev) {
|
if (!meta.isDev) {
|
||||||
// Ensure that the selected Node version is at the beginning of the `$PATH`
|
// Ensure that the selected Node version is at the beginning of the `$PATH`
|
||||||
opts.env.PATH = `/node${nodeVersion.major}/bin:${opts.env.PATH}`;
|
opts.env.PATH = `/node${nodeVersion.major}/bin${path.delimiter}${
|
||||||
|
opts.env.PATH || process.env.PATH
|
||||||
|
}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return opts;
|
return opts;
|
||||||
@@ -433,13 +435,13 @@ export function getEnvForPackageManager({
|
|||||||
(nodeVersion?.major || 0) < 16
|
(nodeVersion?.major || 0) < 16
|
||||||
) {
|
) {
|
||||||
// Ensure that npm 7 is at the beginning of the `$PATH`
|
// Ensure that npm 7 is at the beginning of the `$PATH`
|
||||||
newEnv.PATH = `/node16/bin-npm7:${env.PATH}`;
|
newEnv.PATH = `/node16/bin-npm7${path.delimiter}${env.PATH}`;
|
||||||
console.log('Detected `package-lock.json` generated by npm 7...');
|
console.log('Detected `package-lock.json` generated by npm 7...');
|
||||||
}
|
}
|
||||||
} else if (cliType === 'pnpm') {
|
} else if (cliType === 'pnpm') {
|
||||||
if (typeof lockfileVersion === 'number' && lockfileVersion === 5.4) {
|
if (typeof lockfileVersion === 'number' && lockfileVersion === 5.4) {
|
||||||
// Ensure that pnpm 7 is at the beginning of the `$PATH`
|
// Ensure that pnpm 7 is at the beginning of the `$PATH`
|
||||||
newEnv.PATH = `/pnpm7/node_modules/.bin:${env.PATH}`;
|
newEnv.PATH = `/pnpm7/node_modules/.bin${path.delimiter}${env.PATH}`;
|
||||||
console.log('Detected `pnpm-lock.yaml` generated by pnpm 7...');
|
console.log('Detected `pnpm-lock.yaml` generated by pnpm 7...');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -117,4 +117,5 @@ export const isStaticRuntime = (name?: string): boolean => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export { workspaceManagers } from './workspaces/workspace-managers';
|
export { workspaceManagers } from './workspaces/workspace-managers';
|
||||||
|
export { getWorkspaces } from './workspaces/get-workspaces';
|
||||||
export { monorepoManagers } from './monorepos/monorepo-managers';
|
export { monorepoManagers } from './monorepos/monorepo-managers';
|
||||||
|
|||||||
59
packages/build-utils/src/workspaces/get-workspaces.ts
Normal file
59
packages/build-utils/src/workspaces/get-workspaces.ts
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
import path from 'path';
|
||||||
|
import { DetectorFilesystem } from '../detectors/filesystem';
|
||||||
|
import { workspaceManagers } from './workspace-managers';
|
||||||
|
import { detectFramework as detectWorkspaceManagers } from '../detect-framework';
|
||||||
|
|
||||||
|
const MAX_DEPTH_TRAVERSE = 3;
|
||||||
|
const posixPath = path.posix;
|
||||||
|
|
||||||
|
export interface GetWorkspaceOptions {
|
||||||
|
fs: DetectorFilesystem;
|
||||||
|
depth?: number;
|
||||||
|
cwd?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type WorkspaceType = 'yarn' | 'pnpm' | 'npm';
|
||||||
|
|
||||||
|
export type Workspace = {
|
||||||
|
type: WorkspaceType;
|
||||||
|
rootPath: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export async function getWorkspaces({
|
||||||
|
fs,
|
||||||
|
depth = MAX_DEPTH_TRAVERSE,
|
||||||
|
cwd = '/',
|
||||||
|
}: GetWorkspaceOptions): Promise<Workspace[]> {
|
||||||
|
if (depth === 0) return [];
|
||||||
|
|
||||||
|
const workspaceType = await detectWorkspaceManagers({
|
||||||
|
fs,
|
||||||
|
frameworkList: workspaceManagers,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (workspaceType === null) {
|
||||||
|
const directoryContents = await fs.readdir('./');
|
||||||
|
const childDirectories = directoryContents.filter(
|
||||||
|
stat => stat.type === 'dir'
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
await Promise.all(
|
||||||
|
childDirectories.map(childDirectory =>
|
||||||
|
getWorkspaces({
|
||||||
|
fs: fs.chdir(childDirectory.path),
|
||||||
|
depth: depth - 1,
|
||||||
|
cwd: posixPath.join(cwd, childDirectory.path),
|
||||||
|
})
|
||||||
|
)
|
||||||
|
)
|
||||||
|
).flat();
|
||||||
|
}
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
type: workspaceType as WorkspaceType,
|
||||||
|
rootPath: cwd,
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
@@ -17,5 +17,13 @@ checkPkgOrThrow('exeggcute');
|
|||||||
|
|
||||||
// This is to satisfy `@vercel/static-build` which needs a `dist` directory.
|
// This is to satisfy `@vercel/static-build` which needs a `dist` directory.
|
||||||
const { exec } = require('exeggcute');
|
const { exec } = require('exeggcute');
|
||||||
exec('mkdir dist', __dirname);
|
exec('mkdir dist', __dirname)
|
||||||
exec('echo "node-env:RANDOMNESS_PLACEHOLDER" > dist/index.html', __dirname);
|
.then(() => {
|
||||||
|
exec(
|
||||||
|
'echo "node-env:RANDOMNESS_PLACEHOLDER" > dist/index.html',
|
||||||
|
__dirname
|
||||||
|
).then(() => {
|
||||||
|
console.log('Success');
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(console.error);
|
||||||
|
|||||||
@@ -6,5 +6,10 @@ const b = require('./b');
|
|||||||
a();
|
a();
|
||||||
b();
|
b();
|
||||||
|
|
||||||
exec('mkdir public', __dirname);
|
exec('mkdir public', __dirname)
|
||||||
exec('echo "Hello, World!" > public/index.html', __dirname);
|
.then(() => {
|
||||||
|
exec('echo "Hello, World!" > public/index.html', __dirname).then(() => {
|
||||||
|
console.log('Success');
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(console.error);
|
||||||
|
|||||||
5
packages/build-utils/test/fixtures/29-nested-workspaces/backend/c/package.json
vendored
Normal file
5
packages/build-utils/test/fixtures/29-nested-workspaces/backend/c/package.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"name": "c",
|
||||||
|
"license": "MIT",
|
||||||
|
"version": "0.1.0"
|
||||||
|
}
|
||||||
8
packages/build-utils/test/fixtures/29-nested-workspaces/backend/d/package.json
vendored
Normal file
8
packages/build-utils/test/fixtures/29-nested-workspaces/backend/d/package.json
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"name": "d",
|
||||||
|
"license": "MIT",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"devDependencies": {
|
||||||
|
"once": "1.4.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
6
packages/build-utils/test/fixtures/29-nested-workspaces/backend/package.json
vendored
Normal file
6
packages/build-utils/test/fixtures/29-nested-workspaces/backend/package.json
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"private": true,
|
||||||
|
"name": "29-nested-workspaces-backend",
|
||||||
|
"license": "MIT",
|
||||||
|
"version": "1.0.0"
|
||||||
|
}
|
||||||
27
packages/build-utils/test/fixtures/29-nested-workspaces/backend/pnpm-lock.yaml
generated
vendored
Normal file
27
packages/build-utils/test/fixtures/29-nested-workspaces/backend/pnpm-lock.yaml
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
lockfileVersion: 5.3
|
||||||
|
|
||||||
|
importers:
|
||||||
|
|
||||||
|
.:
|
||||||
|
specifiers: {}
|
||||||
|
|
||||||
|
c:
|
||||||
|
specifiers: {}
|
||||||
|
|
||||||
|
d:
|
||||||
|
specifiers:
|
||||||
|
once: 1.4.0
|
||||||
|
devDependencies:
|
||||||
|
once: 1.4.0
|
||||||
|
|
||||||
|
packages:
|
||||||
|
|
||||||
|
/once/1.4.0:
|
||||||
|
resolution: {integrity: sha1-WDsap3WWHUsROsF9nFC6753Xa9E=}
|
||||||
|
dependencies:
|
||||||
|
wrappy: 1.0.2
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/wrappy/1.0.2:
|
||||||
|
resolution: {integrity: sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=}
|
||||||
|
dev: true
|
||||||
3
packages/build-utils/test/fixtures/29-nested-workspaces/backend/pnpm-workspace.yaml
vendored
Normal file
3
packages/build-utils/test/fixtures/29-nested-workspaces/backend/pnpm-workspace.yaml
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
packages:
|
||||||
|
- 'c'
|
||||||
|
- 'd'
|
||||||
0
packages/build-utils/test/fixtures/29-nested-workspaces/frontend/ignored/.gitkeep
vendored
Normal file
0
packages/build-utils/test/fixtures/29-nested-workspaces/frontend/ignored/.gitkeep
vendored
Normal file
9
packages/build-utils/test/fixtures/29-nested-workspaces/frontend/package.json
vendored
Normal file
9
packages/build-utils/test/fixtures/29-nested-workspaces/frontend/package.json
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"name": "29-nested-workspaces-frontend",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"private": true,
|
||||||
|
"workspaces": [
|
||||||
|
"a",
|
||||||
|
"b"
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"name": "c",
|
||||||
|
"license": "MIT",
|
||||||
|
"version": "0.1.0"
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"name": "d",
|
||||||
|
"license": "MIT",
|
||||||
|
"version": "0.1.0",
|
||||||
|
"devDependencies": {
|
||||||
|
"once": "1.4.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
6
packages/build-utils/test/fixtures/30-double-nested-workspaces/packages/backend/package.json
vendored
Normal file
6
packages/build-utils/test/fixtures/30-double-nested-workspaces/packages/backend/package.json
vendored
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"private": true,
|
||||||
|
"name": "30-double-nested-workspaces-packages-backend",
|
||||||
|
"license": "MIT",
|
||||||
|
"version": "1.0.0"
|
||||||
|
}
|
||||||
27
packages/build-utils/test/fixtures/30-double-nested-workspaces/packages/backend/pnpm-lock.yaml
generated
vendored
Normal file
27
packages/build-utils/test/fixtures/30-double-nested-workspaces/packages/backend/pnpm-lock.yaml
generated
vendored
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
lockfileVersion: 5.3
|
||||||
|
|
||||||
|
importers:
|
||||||
|
|
||||||
|
.:
|
||||||
|
specifiers: {}
|
||||||
|
|
||||||
|
c:
|
||||||
|
specifiers: {}
|
||||||
|
|
||||||
|
d:
|
||||||
|
specifiers:
|
||||||
|
once: 1.4.0
|
||||||
|
devDependencies:
|
||||||
|
once: 1.4.0
|
||||||
|
|
||||||
|
packages:
|
||||||
|
|
||||||
|
/once/1.4.0:
|
||||||
|
resolution: {integrity: sha1-WDsap3WWHUsROsF9nFC6753Xa9E=}
|
||||||
|
dependencies:
|
||||||
|
wrappy: 1.0.2
|
||||||
|
dev: true
|
||||||
|
|
||||||
|
/wrappy/1.0.2:
|
||||||
|
resolution: {integrity: sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=}
|
||||||
|
dev: true
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
packages:
|
||||||
|
- 'c'
|
||||||
|
- 'd'
|
||||||
15
packages/build-utils/test/fixtures/30-double-nested-workspaces/packages/frontend/a/package.json
vendored
Normal file
15
packages/build-utils/test/fixtures/30-double-nested-workspaces/packages/frontend/a/package.json
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "a",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "^4.3.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
15
packages/build-utils/test/fixtures/30-double-nested-workspaces/packages/frontend/b/package.json
vendored
Normal file
15
packages/build-utils/test/fixtures/30-double-nested-workspaces/packages/frontend/b/package.json
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "b",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"cowsay": "^1.5.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"name": "30-double-nested-workspaces-packages-frontend",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"private": true,
|
||||||
|
"workspaces": [
|
||||||
|
"a",
|
||||||
|
"b"
|
||||||
|
]
|
||||||
|
}
|
||||||
232
packages/build-utils/test/fixtures/30-double-nested-workspaces/packages/frontend/yarn.lock
vendored
Normal file
232
packages/build-utils/test/fixtures/30-double-nested-workspaces/packages/frontend/yarn.lock
vendored
Normal file
@@ -0,0 +1,232 @@
|
|||||||
|
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||||
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
|
ansi-regex@^3.0.0:
|
||||||
|
version "3.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1"
|
||||||
|
integrity sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==
|
||||||
|
|
||||||
|
ansi-regex@^5.0.1:
|
||||||
|
version "5.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
|
||||||
|
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
|
||||||
|
|
||||||
|
ansi-styles@^4.0.0:
|
||||||
|
version "4.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
|
||||||
|
integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
|
||||||
|
dependencies:
|
||||||
|
color-convert "^2.0.1"
|
||||||
|
|
||||||
|
camelcase@^5.0.0:
|
||||||
|
version "5.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
|
||||||
|
integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
|
||||||
|
|
||||||
|
cliui@^6.0.0:
|
||||||
|
version "6.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1"
|
||||||
|
integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==
|
||||||
|
dependencies:
|
||||||
|
string-width "^4.2.0"
|
||||||
|
strip-ansi "^6.0.0"
|
||||||
|
wrap-ansi "^6.2.0"
|
||||||
|
|
||||||
|
color-convert@^2.0.1:
|
||||||
|
version "2.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
|
||||||
|
integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
|
||||||
|
dependencies:
|
||||||
|
color-name "~1.1.4"
|
||||||
|
|
||||||
|
color-name@~1.1.4:
|
||||||
|
version "1.1.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
||||||
|
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||||
|
|
||||||
|
cowsay@^1.5.0:
|
||||||
|
version "1.5.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/cowsay/-/cowsay-1.5.0.tgz#4a2a453b8b59383c7d7a50e44d765c5de0bf615f"
|
||||||
|
integrity sha512-8Ipzr54Z8zROr/62C8f0PdhQcDusS05gKTS87xxdji8VbWefWly0k8BwGK7+VqamOrkv3eGsCkPtvlHzrhWsCA==
|
||||||
|
dependencies:
|
||||||
|
get-stdin "8.0.0"
|
||||||
|
string-width "~2.1.1"
|
||||||
|
strip-final-newline "2.0.0"
|
||||||
|
yargs "15.4.1"
|
||||||
|
|
||||||
|
debug@^4.3.2:
|
||||||
|
version "4.3.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
|
||||||
|
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
|
||||||
|
dependencies:
|
||||||
|
ms "2.1.2"
|
||||||
|
|
||||||
|
decamelize@^1.2.0:
|
||||||
|
version "1.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
|
||||||
|
integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=
|
||||||
|
|
||||||
|
emoji-regex@^8.0.0:
|
||||||
|
version "8.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
|
||||||
|
integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
|
||||||
|
|
||||||
|
find-up@^4.1.0:
|
||||||
|
version "4.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19"
|
||||||
|
integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==
|
||||||
|
dependencies:
|
||||||
|
locate-path "^5.0.0"
|
||||||
|
path-exists "^4.0.0"
|
||||||
|
|
||||||
|
get-caller-file@^2.0.1:
|
||||||
|
version "2.0.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
|
||||||
|
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
|
||||||
|
|
||||||
|
get-stdin@8.0.0:
|
||||||
|
version "8.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-8.0.0.tgz#cbad6a73feb75f6eeb22ba9e01f89aa28aa97a53"
|
||||||
|
integrity sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==
|
||||||
|
|
||||||
|
is-fullwidth-code-point@^2.0.0:
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
|
||||||
|
integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=
|
||||||
|
|
||||||
|
is-fullwidth-code-point@^3.0.0:
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
|
||||||
|
integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
|
||||||
|
|
||||||
|
locate-path@^5.0.0:
|
||||||
|
version "5.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0"
|
||||||
|
integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==
|
||||||
|
dependencies:
|
||||||
|
p-locate "^4.1.0"
|
||||||
|
|
||||||
|
ms@2.1.2:
|
||||||
|
version "2.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
||||||
|
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
||||||
|
|
||||||
|
p-limit@^2.2.0:
|
||||||
|
version "2.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1"
|
||||||
|
integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==
|
||||||
|
dependencies:
|
||||||
|
p-try "^2.0.0"
|
||||||
|
|
||||||
|
p-locate@^4.1.0:
|
||||||
|
version "4.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07"
|
||||||
|
integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==
|
||||||
|
dependencies:
|
||||||
|
p-limit "^2.2.0"
|
||||||
|
|
||||||
|
p-try@^2.0.0:
|
||||||
|
version "2.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
|
||||||
|
integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
|
||||||
|
|
||||||
|
path-exists@^4.0.0:
|
||||||
|
version "4.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
|
||||||
|
integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
|
||||||
|
|
||||||
|
require-directory@^2.1.1:
|
||||||
|
version "2.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
|
||||||
|
integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
|
||||||
|
|
||||||
|
require-main-filename@^2.0.0:
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b"
|
||||||
|
integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==
|
||||||
|
|
||||||
|
set-blocking@^2.0.0:
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
|
||||||
|
integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
|
||||||
|
|
||||||
|
string-width@^4.1.0, string-width@^4.2.0:
|
||||||
|
version "4.2.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||||
|
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||||
|
dependencies:
|
||||||
|
emoji-regex "^8.0.0"
|
||||||
|
is-fullwidth-code-point "^3.0.0"
|
||||||
|
strip-ansi "^6.0.1"
|
||||||
|
|
||||||
|
string-width@~2.1.1:
|
||||||
|
version "2.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e"
|
||||||
|
integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==
|
||||||
|
dependencies:
|
||||||
|
is-fullwidth-code-point "^2.0.0"
|
||||||
|
strip-ansi "^4.0.0"
|
||||||
|
|
||||||
|
strip-ansi@^4.0.0:
|
||||||
|
version "4.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f"
|
||||||
|
integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8=
|
||||||
|
dependencies:
|
||||||
|
ansi-regex "^3.0.0"
|
||||||
|
|
||||||
|
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||||
|
version "6.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||||
|
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||||
|
dependencies:
|
||||||
|
ansi-regex "^5.0.1"
|
||||||
|
|
||||||
|
strip-final-newline@2.0.0:
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad"
|
||||||
|
integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==
|
||||||
|
|
||||||
|
which-module@^2.0.0:
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
|
||||||
|
integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=
|
||||||
|
|
||||||
|
wrap-ansi@^6.2.0:
|
||||||
|
version "6.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53"
|
||||||
|
integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==
|
||||||
|
dependencies:
|
||||||
|
ansi-styles "^4.0.0"
|
||||||
|
string-width "^4.1.0"
|
||||||
|
strip-ansi "^6.0.0"
|
||||||
|
|
||||||
|
y18n@^4.0.0:
|
||||||
|
version "4.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf"
|
||||||
|
integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==
|
||||||
|
|
||||||
|
yargs-parser@^18.1.2:
|
||||||
|
version "18.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0"
|
||||||
|
integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==
|
||||||
|
dependencies:
|
||||||
|
camelcase "^5.0.0"
|
||||||
|
decamelize "^1.2.0"
|
||||||
|
|
||||||
|
yargs@15.4.1:
|
||||||
|
version "15.4.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8"
|
||||||
|
integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==
|
||||||
|
dependencies:
|
||||||
|
cliui "^6.0.0"
|
||||||
|
decamelize "^1.2.0"
|
||||||
|
find-up "^4.1.0"
|
||||||
|
get-caller-file "^2.0.1"
|
||||||
|
require-directory "^2.1.1"
|
||||||
|
require-main-filename "^2.0.0"
|
||||||
|
set-blocking "^2.0.0"
|
||||||
|
string-width "^4.2.0"
|
||||||
|
which-module "^2.0.0"
|
||||||
|
y18n "^4.0.0"
|
||||||
|
yargs-parser "^18.1.2"
|
||||||
15
packages/build-utils/test/fixtures/31-turborepo-in-package-json/a/package.json
vendored
Normal file
15
packages/build-utils/test/fixtures/31-turborepo-in-package-json/a/package.json
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "a",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"debug": "^4.3.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
15
packages/build-utils/test/fixtures/31-turborepo-in-package-json/b/package.json
vendored
Normal file
15
packages/build-utils/test/fixtures/31-turborepo-in-package-json/b/package.json
vendored
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
{
|
||||||
|
"name": "b",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "",
|
||||||
|
"main": "index.js",
|
||||||
|
"scripts": {
|
||||||
|
"test": "echo \"Error: no test specified\" && exit 1"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "",
|
||||||
|
"license": "ISC",
|
||||||
|
"dependencies": {
|
||||||
|
"cowsay": "^1.5.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
232
packages/build-utils/test/fixtures/31-turborepo-in-package-json/yarn.lock
vendored
Normal file
232
packages/build-utils/test/fixtures/31-turborepo-in-package-json/yarn.lock
vendored
Normal file
@@ -0,0 +1,232 @@
|
|||||||
|
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||||
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
|
ansi-regex@^3.0.0:
|
||||||
|
version "3.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.1.tgz#123d6479e92ad45ad897d4054e3c7ca7db4944e1"
|
||||||
|
integrity sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==
|
||||||
|
|
||||||
|
ansi-regex@^5.0.1:
|
||||||
|
version "5.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
|
||||||
|
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
|
||||||
|
|
||||||
|
ansi-styles@^4.0.0:
|
||||||
|
version "4.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
|
||||||
|
integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
|
||||||
|
dependencies:
|
||||||
|
color-convert "^2.0.1"
|
||||||
|
|
||||||
|
camelcase@^5.0.0:
|
||||||
|
version "5.3.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320"
|
||||||
|
integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==
|
||||||
|
|
||||||
|
cliui@^6.0.0:
|
||||||
|
version "6.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1"
|
||||||
|
integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==
|
||||||
|
dependencies:
|
||||||
|
string-width "^4.2.0"
|
||||||
|
strip-ansi "^6.0.0"
|
||||||
|
wrap-ansi "^6.2.0"
|
||||||
|
|
||||||
|
color-convert@^2.0.1:
|
||||||
|
version "2.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
|
||||||
|
integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
|
||||||
|
dependencies:
|
||||||
|
color-name "~1.1.4"
|
||||||
|
|
||||||
|
color-name@~1.1.4:
|
||||||
|
version "1.1.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
|
||||||
|
integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
|
||||||
|
|
||||||
|
cowsay@^1.5.0:
|
||||||
|
version "1.5.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/cowsay/-/cowsay-1.5.0.tgz#4a2a453b8b59383c7d7a50e44d765c5de0bf615f"
|
||||||
|
integrity sha512-8Ipzr54Z8zROr/62C8f0PdhQcDusS05gKTS87xxdji8VbWefWly0k8BwGK7+VqamOrkv3eGsCkPtvlHzrhWsCA==
|
||||||
|
dependencies:
|
||||||
|
get-stdin "8.0.0"
|
||||||
|
string-width "~2.1.1"
|
||||||
|
strip-final-newline "2.0.0"
|
||||||
|
yargs "15.4.1"
|
||||||
|
|
||||||
|
debug@^4.3.2:
|
||||||
|
version "4.3.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
|
||||||
|
integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
|
||||||
|
dependencies:
|
||||||
|
ms "2.1.2"
|
||||||
|
|
||||||
|
decamelize@^1.2.0:
|
||||||
|
version "1.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290"
|
||||||
|
integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=
|
||||||
|
|
||||||
|
emoji-regex@^8.0.0:
|
||||||
|
version "8.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37"
|
||||||
|
integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==
|
||||||
|
|
||||||
|
find-up@^4.1.0:
|
||||||
|
version "4.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19"
|
||||||
|
integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==
|
||||||
|
dependencies:
|
||||||
|
locate-path "^5.0.0"
|
||||||
|
path-exists "^4.0.0"
|
||||||
|
|
||||||
|
get-caller-file@^2.0.1:
|
||||||
|
version "2.0.5"
|
||||||
|
resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e"
|
||||||
|
integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==
|
||||||
|
|
||||||
|
get-stdin@8.0.0:
|
||||||
|
version "8.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-8.0.0.tgz#cbad6a73feb75f6eeb22ba9e01f89aa28aa97a53"
|
||||||
|
integrity sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==
|
||||||
|
|
||||||
|
is-fullwidth-code-point@^2.0.0:
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f"
|
||||||
|
integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=
|
||||||
|
|
||||||
|
is-fullwidth-code-point@^3.0.0:
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d"
|
||||||
|
integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==
|
||||||
|
|
||||||
|
locate-path@^5.0.0:
|
||||||
|
version "5.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0"
|
||||||
|
integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==
|
||||||
|
dependencies:
|
||||||
|
p-locate "^4.1.0"
|
||||||
|
|
||||||
|
ms@2.1.2:
|
||||||
|
version "2.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
|
||||||
|
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
|
||||||
|
|
||||||
|
p-limit@^2.2.0:
|
||||||
|
version "2.3.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1"
|
||||||
|
integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==
|
||||||
|
dependencies:
|
||||||
|
p-try "^2.0.0"
|
||||||
|
|
||||||
|
p-locate@^4.1.0:
|
||||||
|
version "4.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07"
|
||||||
|
integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==
|
||||||
|
dependencies:
|
||||||
|
p-limit "^2.2.0"
|
||||||
|
|
||||||
|
p-try@^2.0.0:
|
||||||
|
version "2.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
|
||||||
|
integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
|
||||||
|
|
||||||
|
path-exists@^4.0.0:
|
||||||
|
version "4.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3"
|
||||||
|
integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==
|
||||||
|
|
||||||
|
require-directory@^2.1.1:
|
||||||
|
version "2.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42"
|
||||||
|
integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
|
||||||
|
|
||||||
|
require-main-filename@^2.0.0:
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b"
|
||||||
|
integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==
|
||||||
|
|
||||||
|
set-blocking@^2.0.0:
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7"
|
||||||
|
integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
|
||||||
|
|
||||||
|
string-width@^4.1.0, string-width@^4.2.0:
|
||||||
|
version "4.2.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
|
||||||
|
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
|
||||||
|
dependencies:
|
||||||
|
emoji-regex "^8.0.0"
|
||||||
|
is-fullwidth-code-point "^3.0.0"
|
||||||
|
strip-ansi "^6.0.1"
|
||||||
|
|
||||||
|
string-width@~2.1.1:
|
||||||
|
version "2.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e"
|
||||||
|
integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==
|
||||||
|
dependencies:
|
||||||
|
is-fullwidth-code-point "^2.0.0"
|
||||||
|
strip-ansi "^4.0.0"
|
||||||
|
|
||||||
|
strip-ansi@^4.0.0:
|
||||||
|
version "4.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f"
|
||||||
|
integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8=
|
||||||
|
dependencies:
|
||||||
|
ansi-regex "^3.0.0"
|
||||||
|
|
||||||
|
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
|
||||||
|
version "6.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
|
||||||
|
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
|
||||||
|
dependencies:
|
||||||
|
ansi-regex "^5.0.1"
|
||||||
|
|
||||||
|
strip-final-newline@2.0.0:
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad"
|
||||||
|
integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==
|
||||||
|
|
||||||
|
which-module@^2.0.0:
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a"
|
||||||
|
integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=
|
||||||
|
|
||||||
|
wrap-ansi@^6.2.0:
|
||||||
|
version "6.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53"
|
||||||
|
integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==
|
||||||
|
dependencies:
|
||||||
|
ansi-styles "^4.0.0"
|
||||||
|
string-width "^4.1.0"
|
||||||
|
strip-ansi "^6.0.0"
|
||||||
|
|
||||||
|
y18n@^4.0.0:
|
||||||
|
version "4.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf"
|
||||||
|
integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==
|
||||||
|
|
||||||
|
yargs-parser@^18.1.2:
|
||||||
|
version "18.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0"
|
||||||
|
integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==
|
||||||
|
dependencies:
|
||||||
|
camelcase "^5.0.0"
|
||||||
|
decamelize "^1.2.0"
|
||||||
|
|
||||||
|
yargs@15.4.1:
|
||||||
|
version "15.4.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8"
|
||||||
|
integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==
|
||||||
|
dependencies:
|
||||||
|
cliui "^6.0.0"
|
||||||
|
decamelize "^1.2.0"
|
||||||
|
find-up "^4.1.0"
|
||||||
|
get-caller-file "^2.0.1"
|
||||||
|
require-directory "^2.1.1"
|
||||||
|
require-main-filename "^2.0.0"
|
||||||
|
set-blocking "^2.0.0"
|
||||||
|
string-width "^4.2.0"
|
||||||
|
which-module "^2.0.0"
|
||||||
|
y18n "^4.0.0"
|
||||||
|
yargs-parser "^18.1.2"
|
||||||
@@ -34,7 +34,9 @@ const skipFixtures: string[] = [
|
|||||||
'23-pnpm-workspaces',
|
'23-pnpm-workspaces',
|
||||||
'27-yarn-workspaces',
|
'27-yarn-workspaces',
|
||||||
'28-turborepo-with-yarn-workspaces',
|
'28-turborepo-with-yarn-workspaces',
|
||||||
'29-turborepo-in-package-json',
|
'29-nested-workspaces',
|
||||||
|
'30-double-nested-workspaces',
|
||||||
|
'31-turborepo-in-package-json',
|
||||||
];
|
];
|
||||||
|
|
||||||
// eslint-disable-next-line no-restricted-syntax
|
// eslint-disable-next-line no-restricted-syntax
|
||||||
|
|||||||
@@ -5,10 +5,10 @@ import { FixtureFilesystem } from './utils/fixture-filesystem';
|
|||||||
|
|
||||||
describe('monorepo-managers', () => {
|
describe('monorepo-managers', () => {
|
||||||
describe.each([
|
describe.each([
|
||||||
['turbo', '28-turborepo-with-yarn-workspaces'],
|
['28-turborepo-with-yarn-workspaces', 'turbo'],
|
||||||
['turbo', '29-turborepo-in-package-json'],
|
['31-turborepo-in-package-json', 'turbo'],
|
||||||
[null, '22-pnpm'],
|
['22-pnpm', null],
|
||||||
])('with detectFramework', (frameworkSlug, fixturePath) => {
|
])('with detectFramework', (fixturePath, frameworkSlug) => {
|
||||||
const testName = frameworkSlug
|
const testName = frameworkSlug
|
||||||
? `should detect a ${frameworkSlug} workspace for ${fixturePath}`
|
? `should detect a ${frameworkSlug} workspace for ${fixturePath}`
|
||||||
: `should not detect a monorepo manager for ${fixturePath}`;
|
: `should not detect a monorepo manager for ${fixturePath}`;
|
||||||
|
|||||||
@@ -5,13 +5,13 @@ import { FixtureFilesystem } from './utils/fixture-filesystem';
|
|||||||
|
|
||||||
describe('workspace-managers', () => {
|
describe('workspace-managers', () => {
|
||||||
describe.each([
|
describe.each([
|
||||||
['npm', '21-npm-workspaces'],
|
['21-npm-workspaces', 'npm'],
|
||||||
['pnpm', '23-pnpm-workspaces'],
|
['23-pnpm-workspaces', 'pnpm'],
|
||||||
['yarn', '27-yarn-workspaces'],
|
['27-yarn-workspaces', 'yarn'],
|
||||||
['yarn', '25-multiple-lock-files-yarn'],
|
['25-multiple-lock-files-yarn', 'yarn'],
|
||||||
['pnpm', '26-multiple-lock-files-pnpm'],
|
['26-multiple-lock-files-pnpm', 'pnpm'],
|
||||||
[null, '22-pnpm'],
|
['22-pnpm', null],
|
||||||
])('with detectFramework', (frameworkSlug, fixturePath) => {
|
])('with detectFramework', (fixturePath, frameworkSlug) => {
|
||||||
const testName = frameworkSlug
|
const testName = frameworkSlug
|
||||||
? `should detect a ${frameworkSlug} workspace for ${fixturePath}`
|
? `should detect a ${frameworkSlug} workspace for ${fixturePath}`
|
||||||
: `should not detect framework for ${fixturePath}`;
|
: `should not detect framework for ${fixturePath}`;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import assert from 'assert';
|
import assert from 'assert';
|
||||||
|
import { delimiter } from 'path';
|
||||||
import { getEnvForPackageManager } from '../src';
|
import { getEnvForPackageManager } from '../src';
|
||||||
|
|
||||||
describe('Test `getEnvForPackageManager()`', () => {
|
describe('Test `getEnvForPackageManager()`', () => {
|
||||||
@@ -34,7 +35,7 @@ describe('Test `getEnvForPackageManager()`', () => {
|
|||||||
},
|
},
|
||||||
want: {
|
want: {
|
||||||
FOO: 'bar',
|
FOO: 'bar',
|
||||||
PATH: `/node16/bin-npm7:foo`,
|
PATH: `/node16/bin-npm7${delimiter}foo`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -97,7 +98,7 @@ describe('Test `getEnvForPackageManager()`', () => {
|
|||||||
},
|
},
|
||||||
want: {
|
want: {
|
||||||
FOO: 'bar',
|
FOO: 'bar',
|
||||||
PATH: '/pnpm7/node_modules/.bin:foo',
|
PATH: `/pnpm7/node_modules/.bin${delimiter}foo`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
43
packages/build-utils/test/unit.get-workspaces.test.ts
vendored
Normal file
43
packages/build-utils/test/unit.get-workspaces.test.ts
vendored
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
import path from 'path';
|
||||||
|
import { getWorkspaces, Workspace } from '../src/workspaces/get-workspaces';
|
||||||
|
import { FixtureFilesystem } from './utils/fixture-filesystem';
|
||||||
|
|
||||||
|
describe.each<[string, Workspace[]]>([
|
||||||
|
['21-npm-workspaces', [{ type: 'npm', rootPath: '/' }]],
|
||||||
|
['23-pnpm-workspaces', [{ type: 'pnpm', rootPath: '/' }]],
|
||||||
|
['27-yarn-workspaces', [{ type: 'yarn', rootPath: '/' }]],
|
||||||
|
['25-multiple-lock-files-yarn', [{ type: 'yarn', rootPath: '/' }]],
|
||||||
|
['26-multiple-lock-files-pnpm', [{ type: 'pnpm', rootPath: '/' }]],
|
||||||
|
[
|
||||||
|
'29-nested-workspaces',
|
||||||
|
[
|
||||||
|
{ type: 'pnpm', rootPath: '/backend' },
|
||||||
|
{ type: 'yarn', rootPath: '/frontend' },
|
||||||
|
],
|
||||||
|
],
|
||||||
|
[
|
||||||
|
'30-double-nested-workspaces',
|
||||||
|
[
|
||||||
|
{ type: 'pnpm', rootPath: '/packages/backend' },
|
||||||
|
{ type: 'yarn', rootPath: '/packages/frontend' },
|
||||||
|
],
|
||||||
|
],
|
||||||
|
['22-pnpm', []],
|
||||||
|
])('`getWorkspaces()`', (fixturePath, workspaces) => {
|
||||||
|
const expectedImplementations = workspaces.map(({ type }) => type);
|
||||||
|
const testName =
|
||||||
|
workspaces.length > 0
|
||||||
|
? `should detect ${expectedImplementations.join()} workspace${
|
||||||
|
expectedImplementations.length > 1 ? 's' : ''
|
||||||
|
} for ${fixturePath}`
|
||||||
|
: `should not detect any workspace for ${fixturePath}`;
|
||||||
|
|
||||||
|
it(testName, async () => {
|
||||||
|
const fixture = path.join(__dirname, 'fixtures', fixturePath);
|
||||||
|
const fs = new FixtureFilesystem(fixture);
|
||||||
|
|
||||||
|
const actualWorkspaces = await getWorkspaces({ fs });
|
||||||
|
|
||||||
|
expect(actualWorkspaces).toEqual(expect.arrayContaining(workspaces));
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "vercel",
|
"name": "vercel",
|
||||||
"version": "24.2.5-canary.1",
|
"version": "24.2.5",
|
||||||
"preferGlobal": true,
|
"preferGlobal": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"description": "The command-line interface for Vercel",
|
"description": "The command-line interface for Vercel",
|
||||||
@@ -43,15 +43,15 @@
|
|||||||
"node": ">= 12"
|
"node": ">= 12"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vercel/build-utils": "3.1.1-canary.1",
|
"@vercel/build-utils": "3.1.1",
|
||||||
"@vercel/go": "1.4.4-canary.1",
|
"@vercel/go": "1.4.4",
|
||||||
"@vercel/next": "2.8.67-canary.1",
|
"@vercel/next": "2.9.0",
|
||||||
"@vercel/node": "1.15.4-canary.1",
|
"@vercel/node": "1.15.4",
|
||||||
"@vercel/python": "2.3.4-canary.1",
|
"@vercel/python": "2.3.4",
|
||||||
"@vercel/redwood": "0.8.4-canary.1",
|
"@vercel/redwood": "0.8.4",
|
||||||
"@vercel/remix": "0.0.2-canary.1",
|
"@vercel/remix": "0.0.2",
|
||||||
"@vercel/ruby": "1.3.7-canary.1",
|
"@vercel/ruby": "1.3.7",
|
||||||
"@vercel/static-build": "0.25.3-canary.1",
|
"@vercel/static-build": "0.26.0",
|
||||||
"update-notifier": "4.1.0"
|
"update-notifier": "4.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -95,8 +95,8 @@
|
|||||||
"@types/which": "1.3.2",
|
"@types/which": "1.3.2",
|
||||||
"@types/write-json-file": "2.2.1",
|
"@types/write-json-file": "2.2.1",
|
||||||
"@types/yauzl-promise": "2.1.0",
|
"@types/yauzl-promise": "2.1.0",
|
||||||
"@vercel/client": "11.0.4-canary.1",
|
"@vercel/client": "11.0.4",
|
||||||
"@vercel/frameworks": "0.9.2-canary.0",
|
"@vercel/frameworks": "1.0.0",
|
||||||
"@vercel/ncc": "0.24.0",
|
"@vercel/ncc": "0.24.0",
|
||||||
"@zeit/fun": "0.11.2",
|
"@zeit/fun": "0.11.2",
|
||||||
"@zeit/source-map-support": "0.6.2",
|
"@zeit/source-map-support": "0.6.2",
|
||||||
|
|||||||
@@ -98,6 +98,12 @@ export default async function dev(
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// This is just for tests - can be removed once project settings
|
||||||
|
// are respected locally in `.vercel/project.json`
|
||||||
|
if (process.env.VERCEL_DEV_COMMAND) {
|
||||||
|
devCommand = process.env.VERCEL_DEV_COMMAND;
|
||||||
|
}
|
||||||
|
|
||||||
const devServer = new DevServer(cwd, {
|
const devServer = new DevServer(cwd, {
|
||||||
output,
|
output,
|
||||||
devCommand,
|
devCommand,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import npa from 'npm-package-arg';
|
import npa from 'npm-package-arg';
|
||||||
import { satisfies } from 'semver';
|
import { satisfies } from 'semver';
|
||||||
import { dirname, join } from 'path';
|
import { dirname, join } from 'path';
|
||||||
import { outputJSON, readJSON } from 'fs-extra';
|
import { mkdirp, outputJSON, readJSON, symlink } from 'fs-extra';
|
||||||
import {
|
import {
|
||||||
BuilderV2,
|
BuilderV2,
|
||||||
BuilderV3,
|
BuilderV3,
|
||||||
@@ -203,6 +203,11 @@ async function installBuilders(
|
|||||||
cwd: buildersDir,
|
cwd: buildersDir,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Symlink `@now/build-utils` -> `@vercel/build-utils` to support legacy Builders
|
||||||
|
const nowScopePath = join(buildersDir, 'node_modules/@now');
|
||||||
|
await mkdirp(nowScopePath);
|
||||||
|
await symlink('../@vercel/build-utils', join(nowScopePath, 'build-utils'));
|
||||||
|
|
||||||
// Cross-reference any builderSpecs from the saved `package.json` file,
|
// Cross-reference any builderSpecs from the saved `package.json` file,
|
||||||
// in case they were installed from a URL
|
// in case they were installed from a URL
|
||||||
const buildersPkg = await readJSONFile<PackageJson>(buildersPkgPath);
|
const buildersPkg = await readJSONFile<PackageJson>(buildersPkgPath);
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
export default () => <div>hello, this is the frontend</div>;
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": 2,
|
"version": 2,
|
||||||
"name": "now-dev-headers",
|
|
||||||
"builds": [
|
"builds": [
|
||||||
{ "src": "index.js", "use": "@vercel/node" },
|
{ "src": "index.js", "use": "@vercel/node" },
|
||||||
{ "src": "foo.txt", "use": "@vercel/static" }
|
{ "src": "foo.txt", "use": "@vercel/static" }
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": 2,
|
"version": 2,
|
||||||
"name": "now-dev-query-test",
|
|
||||||
"builds": [{ "src": "index.js", "use": "@vercel/node" }],
|
"builds": [{ "src": "index.js", "use": "@vercel/node" }],
|
||||||
"routes": [
|
"routes": [
|
||||||
{
|
{
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "now-dev-static-build-routing",
|
"name": "vc-dev-static-build-routing",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"now-dev": "serve -l $PORT src",
|
"now-dev": "serve -l $PORT src",
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
import os from 'os';
|
import os from 'os';
|
||||||
|
import url from 'url';
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
import listen from 'async-listen';
|
||||||
|
import { createServer } from 'http';
|
||||||
|
|
||||||
const {
|
const {
|
||||||
exec,
|
exec,
|
||||||
@@ -8,8 +11,374 @@ const {
|
|||||||
fixture,
|
fixture,
|
||||||
testFixture,
|
testFixture,
|
||||||
testFixtureStdio,
|
testFixtureStdio,
|
||||||
|
validateResponseHeaders,
|
||||||
} = require('./utils.js');
|
} = require('./utils.js');
|
||||||
|
|
||||||
|
test('[vercel dev] should support request body', async () => {
|
||||||
|
const dir = fixture('node-request-body');
|
||||||
|
const { dev, port, readyResolver } = await testFixture(dir);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await readyResolver;
|
||||||
|
|
||||||
|
const body = { hello: 'world' };
|
||||||
|
|
||||||
|
// Test that `req.body` works in dev
|
||||||
|
let res = await fetch(`http://localhost:${port}/api/req-body`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'content-type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
});
|
||||||
|
validateResponseHeaders(res);
|
||||||
|
expect(await res.json()).toMatchObject(body);
|
||||||
|
|
||||||
|
// Test that `req` "data" events work in dev
|
||||||
|
res = await fetch(`http://localhost:${port}/api/data-events`, {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'content-type': 'application/json',
|
||||||
|
},
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
});
|
||||||
|
} finally {
|
||||||
|
dev.kill('SIGTERM');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[vercel dev] should maintain query when invoking serverless function', async () => {
|
||||||
|
const dir = fixture('node-query-invoke');
|
||||||
|
const { dev, port, readyResolver } = await testFixture(dir);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await readyResolver;
|
||||||
|
|
||||||
|
const res = await fetch(`http://localhost:${port}/something?url-param=a`);
|
||||||
|
validateResponseHeaders(res);
|
||||||
|
|
||||||
|
const text = await res.text();
|
||||||
|
const parsed = url.parse(text, true);
|
||||||
|
expect(parsed.pathname).toEqual('/something');
|
||||||
|
expect(parsed.query['url-param']).toEqual('a');
|
||||||
|
expect(parsed.query['route-param']).toEqual('b');
|
||||||
|
} finally {
|
||||||
|
dev.kill('SIGTERM');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[vercel dev] should maintain query when proxy passing', async () => {
|
||||||
|
const dir = fixture('query-proxy');
|
||||||
|
const { dev, port, readyResolver } = await testFixture(dir);
|
||||||
|
const dest = createServer((req, res) => {
|
||||||
|
res.end(req.url);
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
await Promise.all([readyResolver, listen(dest, 0)]);
|
||||||
|
|
||||||
|
const destAddr = dest.address();
|
||||||
|
if (!destAddr || typeof destAddr === 'string') {
|
||||||
|
throw new Error('Unexpected HTTP address');
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await fetch(
|
||||||
|
`http://localhost:${port}/${destAddr.port}?url-param=a`
|
||||||
|
);
|
||||||
|
validateResponseHeaders(res);
|
||||||
|
|
||||||
|
const text = await res.text();
|
||||||
|
const parsed = url.parse(text, true);
|
||||||
|
expect(parsed.pathname).toEqual('/something');
|
||||||
|
expect(parsed.query['url-param']).toEqual('a');
|
||||||
|
expect(parsed.query['route-param']).toEqual('b');
|
||||||
|
} finally {
|
||||||
|
dest.close();
|
||||||
|
dev.kill('SIGTERM');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[vercel dev] should maintain query when dev server defines routes', async () => {
|
||||||
|
const dir = fixture('dev-server-query');
|
||||||
|
const { dev, port, readyResolver } = await testFixture(dir, {
|
||||||
|
env: {
|
||||||
|
VERCEL_DEV_COMMAND: 'next dev --port $PORT',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
await readyResolver;
|
||||||
|
|
||||||
|
const res = await fetch(`http://localhost:${port}/test?url-param=a`);
|
||||||
|
validateResponseHeaders(res);
|
||||||
|
|
||||||
|
const text = await res.text();
|
||||||
|
|
||||||
|
// Hacky way of getting the page payload from the response
|
||||||
|
// HTML since we don't have a HTML parser handy.
|
||||||
|
const json = text
|
||||||
|
.match(/<pre>(.*)<\/pre>/)![1]
|
||||||
|
.replace('</pre>', '')
|
||||||
|
.replace('<!-- -->', '')
|
||||||
|
.replace(/&/g, '&')
|
||||||
|
.replace(/"/g, '"');
|
||||||
|
const parsed = JSON.parse(json);
|
||||||
|
const query = url.parse(parsed.url, true).query;
|
||||||
|
|
||||||
|
expect(query['url-param']).toEqual('a');
|
||||||
|
expect(query['route-param']).toEqual('b');
|
||||||
|
} finally {
|
||||||
|
dev.kill('SIGTERM');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[vercel dev] should allow `cache-control` to be overwritten', async () => {
|
||||||
|
const dir = fixture('headers');
|
||||||
|
const { dev, port, readyResolver } = await testFixture(dir);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await readyResolver;
|
||||||
|
|
||||||
|
const res = await fetch(
|
||||||
|
`http://localhost:${port}/?name=cache-control&value=immutable`
|
||||||
|
);
|
||||||
|
expect(res.headers.get('cache-control')).toEqual('immutable');
|
||||||
|
} finally {
|
||||||
|
dev.kill('SIGTERM');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[vercel dev] should send `etag` header for static files', async () => {
|
||||||
|
const dir = fixture('headers');
|
||||||
|
const { dev, port, readyResolver } = await testFixture(dir);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await readyResolver;
|
||||||
|
|
||||||
|
const res = await fetch(`http://localhost:${port}/foo.txt`);
|
||||||
|
const expected = 'd263af8ab880c0b97eb6c5c125b5d44f9e5addd9';
|
||||||
|
expect(res.headers.get('etag')).toEqual(`"${expected}"`);
|
||||||
|
const body = await res.text();
|
||||||
|
expect(body.trim()).toEqual('hi');
|
||||||
|
} finally {
|
||||||
|
dev.kill('SIGTERM');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[vercel dev] should frontend dev server and routes', async () => {
|
||||||
|
const dir = fixture('dev-server-and-routes');
|
||||||
|
const { dev, port, readyResolver } = await testFixture(dir, {
|
||||||
|
env: {
|
||||||
|
VERCEL_DEV_COMMAND: 'next dev --port $PORT',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
await readyResolver;
|
||||||
|
|
||||||
|
let podId: string;
|
||||||
|
|
||||||
|
let res = await fetch(`http://localhost:${port}/`);
|
||||||
|
validateResponseHeaders(res);
|
||||||
|
podId = res.headers.get('x-vercel-id')!.match(/:(\w+)-/)![1];
|
||||||
|
let body = await res.text();
|
||||||
|
expect(body.includes('hello, this is the frontend')).toBeTruthy();
|
||||||
|
|
||||||
|
res = await fetch(`http://localhost:${port}/api/users`);
|
||||||
|
validateResponseHeaders(res, podId);
|
||||||
|
body = await res.text();
|
||||||
|
expect(body).toEqual('users');
|
||||||
|
|
||||||
|
res = await fetch(`http://localhost:${port}/api/users/1`);
|
||||||
|
validateResponseHeaders(res, podId);
|
||||||
|
body = await res.text();
|
||||||
|
expect(body).toEqual('users/1');
|
||||||
|
|
||||||
|
res = await fetch(`http://localhost:${port}/api/welcome`);
|
||||||
|
validateResponseHeaders(res, podId);
|
||||||
|
body = await res.text();
|
||||||
|
expect(body).toEqual('hello and welcome');
|
||||||
|
} finally {
|
||||||
|
dev.kill('SIGTERM');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[vercel dev] should support `@vercel/static` routing', async () => {
|
||||||
|
const dir = fixture('static-routes');
|
||||||
|
const { dev, port, readyResolver } = await testFixture(dir);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await readyResolver;
|
||||||
|
|
||||||
|
const res = await fetch(`http://localhost:${port}/`);
|
||||||
|
expect(res.status).toEqual(200);
|
||||||
|
const body = await res.text();
|
||||||
|
expect(body.trim()).toEqual('<body>Hello!</body>');
|
||||||
|
} finally {
|
||||||
|
dev.kill('SIGTERM');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[vercel dev] should support `@vercel/static-build` routing', async () => {
|
||||||
|
const dir = fixture('static-build-routing');
|
||||||
|
const { dev, port, readyResolver } = await testFixture(dir);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await readyResolver;
|
||||||
|
|
||||||
|
const res = await fetch(`http://localhost:${port}/api/date`);
|
||||||
|
expect(res.status).toEqual(200);
|
||||||
|
const body = await res.text();
|
||||||
|
expect(body.startsWith('The current date:')).toBeTruthy();
|
||||||
|
} finally {
|
||||||
|
dev.kill('SIGTERM');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[vercel dev] should support directory listing', async () => {
|
||||||
|
const dir = fixture('directory-listing');
|
||||||
|
const { dev, port, readyResolver } = await testFixture(dir);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await readyResolver;
|
||||||
|
|
||||||
|
// Get directory listing
|
||||||
|
let res = await fetch(`http://localhost:${port}/`);
|
||||||
|
let body = await res.text();
|
||||||
|
expect(res.status).toEqual(200);
|
||||||
|
expect(body.includes('Index of')).toBeTruthy();
|
||||||
|
|
||||||
|
// Get a file
|
||||||
|
res = await fetch(`http://localhost:${port}/file.txt`);
|
||||||
|
body = await res.text();
|
||||||
|
expect(res.status).toEqual(200);
|
||||||
|
expect(body.trim()).toEqual('Hello from file!');
|
||||||
|
|
||||||
|
// Invoke a lambda
|
||||||
|
res = await fetch(`http://localhost:${port}/lambda.js`);
|
||||||
|
body = await res.text();
|
||||||
|
expect(res.status).toEqual(200);
|
||||||
|
expect(body).toEqual('Hello from Lambda!');
|
||||||
|
|
||||||
|
// Trigger a 404
|
||||||
|
res = await fetch(`http://localhost:${port}/does-not-exist`);
|
||||||
|
expect(res.status).toEqual(404);
|
||||||
|
} finally {
|
||||||
|
dev.kill('SIGTERM');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[vercel dev] should respond with 404 listing with Accept header support', async () => {
|
||||||
|
const dir = fixture('directory-listing');
|
||||||
|
const { dev, port, readyResolver } = await testFixture(dir);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await readyResolver;
|
||||||
|
|
||||||
|
// HTML response
|
||||||
|
let res = await fetch(`http://localhost:${port}/does-not-exist`, {
|
||||||
|
headers: {
|
||||||
|
Accept: 'text/html',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(res.status).toEqual(404);
|
||||||
|
expect(res.headers.get('content-type')).toEqual('text/html; charset=utf-8');
|
||||||
|
let body = await res.text();
|
||||||
|
expect(body.startsWith('<!DOCTYPE html>')).toBeTruthy();
|
||||||
|
|
||||||
|
// JSON response
|
||||||
|
res = await fetch(`http://localhost:${port}/does-not-exist`, {
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/json',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
expect(res.status).toEqual(404);
|
||||||
|
expect(res.headers.get('content-type')).toEqual('application/json');
|
||||||
|
body = await res.text();
|
||||||
|
expect(body).toEqual(
|
||||||
|
'{"error":{"code":404,"message":"The page could not be found."}}\n'
|
||||||
|
);
|
||||||
|
|
||||||
|
// Plain text response
|
||||||
|
res = await fetch(`http://localhost:${port}/does-not-exist`);
|
||||||
|
expect(res.status).toEqual(404);
|
||||||
|
body = await res.text();
|
||||||
|
expect(res.headers.get('content-type')).toEqual(
|
||||||
|
'text/plain; charset=utf-8'
|
||||||
|
);
|
||||||
|
expect(body).toEqual('The page could not be found.\n\nNOT_FOUND\n');
|
||||||
|
} finally {
|
||||||
|
dev.kill('SIGTERM');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[vercel dev] should support `public` directory with zero config', async () => {
|
||||||
|
const dir = fixture('api-with-public');
|
||||||
|
const { dev, port, readyResolver } = await testFixture(dir);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await readyResolver;
|
||||||
|
|
||||||
|
let res = await fetch(`http://localhost:${port}/api/user`);
|
||||||
|
let body = await res.text();
|
||||||
|
expect(body).toEqual('hello:user');
|
||||||
|
|
||||||
|
res = await fetch(`http://localhost:${port}/`);
|
||||||
|
body = await res.text();
|
||||||
|
expect(body.startsWith('<h1>hello world</h1>')).toBeTruthy();
|
||||||
|
} finally {
|
||||||
|
dev.kill('SIGTERM');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[vercel dev] should support static files with zero config', async () => {
|
||||||
|
const dir = fixture('api-with-static');
|
||||||
|
const { dev, port, readyResolver } = await testFixture(dir);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await readyResolver;
|
||||||
|
|
||||||
|
let res = await fetch(`http://localhost:${port}/api/user`);
|
||||||
|
let body = await res.text();
|
||||||
|
expect(body).toEqual('bye:user');
|
||||||
|
|
||||||
|
res = await fetch(`http://localhost:${port}/`);
|
||||||
|
body = await res.text();
|
||||||
|
expect(body.startsWith('<h1>goodbye world</h1>')).toBeTruthy();
|
||||||
|
} finally {
|
||||||
|
dev.kill('SIGTERM');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[vercel dev] should support custom 404 routes', async () => {
|
||||||
|
const dir = fixture('custom-404');
|
||||||
|
const { dev, port, readyResolver } = await testFixture(dir);
|
||||||
|
|
||||||
|
try {
|
||||||
|
await readyResolver;
|
||||||
|
|
||||||
|
// Test custom 404 with static dest
|
||||||
|
let res = await fetch(`http://localhost:${port}/error.html`);
|
||||||
|
expect(res.status).toEqual(404);
|
||||||
|
let body = await res.text();
|
||||||
|
expect(body.trim()).toEqual('<div>Custom 404 page</div>');
|
||||||
|
|
||||||
|
// Test custom 404 with lambda dest
|
||||||
|
res = await fetch(`http://localhost:${port}/error.js`);
|
||||||
|
expect(res.status).toEqual(404);
|
||||||
|
body = await res.text();
|
||||||
|
expect(body).toEqual('Custom 404 Lambda\n');
|
||||||
|
|
||||||
|
// Test regular 404 still works
|
||||||
|
res = await fetch(`http://localhost:${port}/does-not-exist`);
|
||||||
|
expect(res.status).toEqual(404);
|
||||||
|
body = await res.text();
|
||||||
|
expect(body).toEqual('The page could not be found.\n\nNOT_FOUND\n');
|
||||||
|
} finally {
|
||||||
|
dev.kill('SIGTERM');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
test('[vercel dev] prints `npm install` errors', async () => {
|
test('[vercel dev] prints `npm install` errors', async () => {
|
||||||
const dir = fixture('runtime-not-installed');
|
const dir = fixture('runtime-not-installed');
|
||||||
const result = await exec(dir);
|
const result = await exec(dir);
|
||||||
|
|||||||
@@ -96,10 +96,16 @@ function shouldSkip(name, versions) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function validateResponseHeaders(res) {
|
function validateResponseHeaders(res, podId) {
|
||||||
if (res.status < 500) {
|
if (res.status < 500) {
|
||||||
|
expect(res.headers.get('server')).toEqual('Vercel');
|
||||||
|
expect(res.headers.get('cache-control').length > 0).toBeTruthy();
|
||||||
expect(res.headers.get('x-vercel-id')).toBeTruthy();
|
expect(res.headers.get('x-vercel-id')).toBeTruthy();
|
||||||
expect(res.headers.get('cache-control').length > 0).toBeTruthy;
|
if (podId) {
|
||||||
|
expect(
|
||||||
|
res.headers.get('x-vercel-id').includes(`::${podId}-`)
|
||||||
|
).toBeTruthy();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
export default () => <div>hello, this is the frontend</div>
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user