mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-11 12:57:46 +00:00
Compare commits
40 Commits
@vercel/ru
...
@vercel/py
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e7e0a55b72 | ||
|
|
c2163e3e4f | ||
|
|
873f549637 | ||
|
|
ead1e411ee | ||
|
|
7c1c089a70 | ||
|
|
a7dbd9649b | ||
|
|
2e439045c9 | ||
|
|
520e0d01f4 | ||
|
|
3856623785 | ||
|
|
1c14e945f9 | ||
|
|
32357fc06f | ||
|
|
f7c57dc539 | ||
|
|
34f7c35c13 | ||
|
|
6700630feb | ||
|
|
34cd8b4144 | ||
|
|
ad0ed6d852 | ||
|
|
0bad09b47a | ||
|
|
5120689bf2 | ||
|
|
5a39fd9242 | ||
|
|
352cd00ef0 | ||
|
|
abfe817f86 | ||
|
|
ebb5e2b208 | ||
|
|
e34858d082 | ||
|
|
f03c947f91 | ||
|
|
0d13fe7e34 | ||
|
|
4afec9d373 | ||
|
|
09c85f63d2 | ||
|
|
9963965e9a | ||
|
|
f3ed279007 | ||
|
|
4fe489edad | ||
|
|
e2911aac0b | ||
|
|
f3cbc5d746 | ||
|
|
40df88b483 | ||
|
|
75c4f45b73 | ||
|
|
05a236f944 | ||
|
|
4b7383f521 | ||
|
|
c263c31e48 | ||
|
|
c80530f9b1 | ||
|
|
16fd4396ef | ||
|
|
4e7138f400 |
26
.github/CODEOWNERS
vendored
26
.github/CODEOWNERS
vendored
@@ -1,23 +1,15 @@
|
|||||||
# Documentation
|
# Documentation
|
||||||
# https://help.github.com/en/articles/about-code-owners
|
# https://help.github.com/en/articles/about-code-owners
|
||||||
|
|
||||||
* @TooTallNate @EndangeredMassa @styfle
|
* @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood
|
||||||
/.github/workflows @TooTallNate @EndangeredMassa @styfle @ijjk
|
/.github/workflows @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @ijjk
|
||||||
/packages/frameworks @TooTallNate @EndangeredMassa @styfle @AndyBitz
|
/packages/cli/src/commands/domains @mglagola @anatrajkovska
|
||||||
/packages/cli/src/commands/domains @javivelasco @mglagola @anatrajkovska
|
/packages/cli/src/commands/certs @mglagola @anatrajkovska
|
||||||
/packages/cli/src/commands/certs @javivelasco @mglagola @anatrajkovska
|
/packages/cli/src/commands/env @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood
|
||||||
/packages/cli/src/commands/env @styfle @lucleray
|
/packages/middleware @gdborton @javivelasco @Schniz
|
||||||
/packages/client @TooTallNate @EndangeredMassa @styfle
|
/packages/node-bridge @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @ijjk
|
||||||
/packages/build-utils @TooTallNate @EndangeredMassa @styfle @AndyBitz
|
/packages/next @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @ijjk
|
||||||
/packages/middleware @gdborton @javivelasco
|
/packages/routing-utils @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @ijjk
|
||||||
/packages/node @TooTallNate @EndangeredMassa @styfle
|
|
||||||
/packages/node-bridge @TooTallNate @EndangeredMassa @styfle @ijjk
|
|
||||||
/packages/next @TooTallNate @ijjk
|
|
||||||
/packages/go @TooTallNate @EndangeredMassa @styfle
|
|
||||||
/packages/python @TooTallNate @EndangeredMassa @styfle
|
|
||||||
/packages/ruby @TooTallNate @EndangeredMassa @styfle
|
|
||||||
/packages/static-build @TooTallNate @EndangeredMassa @styfle @AndyBitz
|
|
||||||
/packages/routing-utils @TooTallNate @EndangeredMassa @styfle @ijjk
|
|
||||||
/examples @leerob
|
/examples @leerob
|
||||||
/examples/create-react-app @Timer
|
/examples/create-react-app @Timer
|
||||||
/examples/nextjs @timneutkens @ijjk @styfle
|
/examples/nextjs @timneutkens @ijjk @styfle
|
||||||
|
|||||||
25
.github/workflows/cron-update-next.yml
vendored
Normal file
25
.github/workflows/cron-update-next.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
name: Cron Update Next
|
||||||
|
|
||||||
|
on:
|
||||||
|
# Run every 4 hours https://crontab.guru/every-4-hours
|
||||||
|
schedule:
|
||||||
|
- cron: '0 */4 * * *'
|
||||||
|
|
||||||
|
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: Create Pull Request
|
||||||
|
uses: actions/github-script@v6
|
||||||
|
env:
|
||||||
|
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||||
|
# See https://github.com/actions/github-script#run-a-separate-file-with-an-async-function
|
||||||
|
with:
|
||||||
|
script: |
|
||||||
|
const script = require('./utils/update-next.js')
|
||||||
|
await script({ github, context })
|
||||||
@@ -63,9 +63,6 @@ export async function build(options: BuildOptions) {
|
|||||||
const lambda = createLambda(/* … */);
|
const lambda = createLambda(/* … */);
|
||||||
return {
|
return {
|
||||||
output: lambda,
|
output: lambda,
|
||||||
watch: [
|
|
||||||
// Dependent files to trigger a rebuild in `vercel dev` go here…
|
|
||||||
],
|
|
||||||
routes: [
|
routes: [
|
||||||
// If your Runtime needs to define additional routing, define it here…
|
// If your Runtime needs to define additional routing, define it here…
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ const frameworks = (_frameworks as Framework[])
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (framework.logo) {
|
if (framework.logo) {
|
||||||
framework.logo = `https://res.cloudinary.com/zeit-inc/image/fetch/${framework.logo}`;
|
framework.logo = `https://assets.vercel.com/zeit-inc/image/fetch/${framework.logo}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return framework;
|
return framework;
|
||||||
|
|||||||
9
examples/nextjs/.gitignore
vendored
9
examples/nextjs/.gitignore
vendored
@@ -26,10 +26,11 @@ yarn-error.log*
|
|||||||
.pnpm-debug.log*
|
.pnpm-debug.log*
|
||||||
|
|
||||||
# local env files
|
# local env files
|
||||||
.env.local
|
.env*.local
|
||||||
.env.development.local
|
|
||||||
.env.test.local
|
|
||||||
.env.production.local
|
|
||||||
|
|
||||||
# vercel
|
# vercel
|
||||||
.vercel
|
.vercel
|
||||||
|
|
||||||
|
# typescript
|
||||||
|
*.tsbuildinfo
|
||||||
|
next-env.d.ts
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
/** @type {import('next').NextConfig} */
|
/** @type {import('next').NextConfig} */
|
||||||
const nextConfig = {
|
const nextConfig = {
|
||||||
reactStrictMode: true,
|
reactStrictMode: true,
|
||||||
|
swcMinify: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = nextConfig
|
module.exports = nextConfig
|
||||||
|
|||||||
4882
examples/nextjs/package-lock.json
generated
4882
examples/nextjs/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,4 +1,6 @@
|
|||||||
{
|
{
|
||||||
|
"name": "nextjs",
|
||||||
|
"version": "0.1.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev",
|
"dev": "next dev",
|
||||||
@@ -7,12 +9,12 @@
|
|||||||
"lint": "next lint"
|
"lint": "next lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"next": "12.1.4",
|
"next": "12.2.5",
|
||||||
"react": "18.0.0",
|
"react": "18.2.0",
|
||||||
"react-dom": "18.0.0"
|
"react-dom": "18.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"eslint": "8.12.0",
|
"eslint": "8.22.0",
|
||||||
"eslint-config-next": "12.1.4"
|
"eslint-config-next": "12.2.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -114,3 +114,16 @@
|
|||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
.card,
|
||||||
|
.footer {
|
||||||
|
border-color: #222;
|
||||||
|
}
|
||||||
|
.code {
|
||||||
|
background: #111;
|
||||||
|
}
|
||||||
|
.logo img {
|
||||||
|
filter: invert(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -14,3 +14,13 @@ a {
|
|||||||
* {
|
* {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
html {
|
||||||
|
color-scheme: dark;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
color: white;
|
||||||
|
background: black;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
1703
examples/nextjs/yarn.lock
Normal file
1703
examples/nextjs/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
@@ -8,21 +8,9 @@ Everything you need to build a Svelte project, powered by [`create-svelte`](http
|
|||||||
|
|
||||||
_Live Example: https://sveltekit-template.vercel.app_
|
_Live Example: https://sveltekit-template.vercel.app_
|
||||||
|
|
||||||
## Creating a project
|
|
||||||
|
|
||||||
If you're seeing this, you've probably already done this step. Congrats!
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# create a new project in the current directory
|
|
||||||
npm init svelte
|
|
||||||
|
|
||||||
# create a new project in my-app
|
|
||||||
npm init svelte my-app
|
|
||||||
```
|
|
||||||
|
|
||||||
## Developing
|
## Developing
|
||||||
|
|
||||||
Once you've created a project and installed dependencies with `pnpm install`, start a development server:
|
Once you've installed dependencies with `pnpm install`, start a development server:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
pnpm run dev
|
pnpm run dev
|
||||||
|
|||||||
@@ -10,4 +10,8 @@
|
|||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"strict": true
|
"strict": true
|
||||||
}
|
}
|
||||||
|
// Path aliases are handled by https://kit.svelte.dev/docs/configuration#alias and https://kit.svelte.dev/docs/configuration#files
|
||||||
|
//
|
||||||
|
// If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes
|
||||||
|
// from the referenced tsconfig.json - TypeScript does not merge them in
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,25 +1,25 @@
|
|||||||
{
|
{
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "svelte-kit dev",
|
"dev": "vite dev",
|
||||||
"build": "svelte-kit build",
|
"build": "vite build",
|
||||||
"package": "svelte-kit package",
|
"package": "svelte-kit package",
|
||||||
"preview": "svelte-kit preview",
|
"preview": "vite preview",
|
||||||
"prepare": "svelte-kit sync",
|
|
||||||
"check": "svelte-check --tsconfig ./jsconfig.json",
|
"check": "svelte-check --tsconfig ./jsconfig.json",
|
||||||
"check:watch": "svelte-check --tsconfig ./jsconfig.json --watch",
|
"check:watch": "svelte-check --tsconfig ./jsconfig.json --watch",
|
||||||
"lint": "prettier --check --plugin-search-dir=. .",
|
"lint": "prettier --check .",
|
||||||
"format": "prettier --write --plugin-search-dir=. ."
|
"format": "prettier --write ."
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@sveltejs/adapter-auto": "1.0.0-next.50",
|
"@sveltejs/adapter-auto": "next",
|
||||||
"@sveltejs/kit": "1.0.0-next.347",
|
"@sveltejs/kit": "next",
|
||||||
"@types/cookie": "^0.4.1",
|
"@types/cookie": "^0.5.1",
|
||||||
"prettier": "^2.5.1",
|
"prettier": "^2.6.2",
|
||||||
"prettier-plugin-svelte": "^2.5.0",
|
"prettier-plugin-svelte": "^2.7.0",
|
||||||
"svelte": "^3.46.0",
|
"svelte": "^3.46.0",
|
||||||
"svelte-check": "^2.2.6",
|
"svelte-check": "^2.7.1",
|
||||||
"typescript": "~4.6.2"
|
"typescript": "^4.7.4",
|
||||||
|
"vite": "^3.0.8"
|
||||||
},
|
},
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
1458
examples/sveltekit/pnpm-lock.yaml
generated
Normal file
1458
examples/sveltekit/pnpm-lock.yaml
generated
Normal file
File diff suppressed because it is too large
Load Diff
7
examples/sveltekit/src/app.d.ts
vendored
7
examples/sveltekit/src/app.d.ts
vendored
@@ -1,7 +1,6 @@
|
|||||||
/// <reference types="@sveltejs/kit" />
|
|
||||||
|
|
||||||
// See https://kit.svelte.dev/docs/types#app
|
// See https://kit.svelte.dev/docs/types#app
|
||||||
// for information about these interfaces
|
// for information about these interfaces
|
||||||
|
// and what to do when importing types
|
||||||
declare namespace App {
|
declare namespace App {
|
||||||
interface Locals {
|
interface Locals {
|
||||||
userid: string;
|
userid: string;
|
||||||
@@ -9,7 +8,7 @@ declare namespace App {
|
|||||||
|
|
||||||
// interface Platform {}
|
// interface Platform {}
|
||||||
|
|
||||||
// interface Session {}
|
// interface PrivateEnv {}
|
||||||
|
|
||||||
// interface Stuff {}
|
// interface PublicEnv {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
|
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
<meta name="viewport" content="width=device-width" />
|
||||||
%sveltekit.head%
|
%sveltekit.head%
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -1,107 +1,107 @@
|
|||||||
<script>
|
<script>
|
||||||
import { spring } from 'svelte/motion';
|
import { spring } from 'svelte/motion';
|
||||||
|
|
||||||
let count = 0;
|
let count = 0;
|
||||||
|
|
||||||
const displayed_count = spring();
|
const displayed_count = spring();
|
||||||
$: displayed_count.set(count);
|
$: displayed_count.set(count);
|
||||||
$: offset = modulo($displayed_count, 1);
|
$: offset = modulo($displayed_count, 1);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {number} n
|
* @param {number} n
|
||||||
* @param {number} m
|
* @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;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="counter">
|
<div class="counter">
|
||||||
<button on:click={() => (count -= 1)} aria-label="Decrease the counter by one">
|
<button on:click={() => (count -= 1)} aria-label="Decrease the counter by one">
|
||||||
<svg aria-hidden="true" viewBox="0 0 1 1">
|
<svg aria-hidden="true" viewBox="0 0 1 1">
|
||||||
<path d="M0,0.5 L1,0.5" />
|
<path d="M0,0.5 L1,0.5" />
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div class="counter-viewport">
|
<div class="counter-viewport">
|
||||||
<div class="counter-digits" style="transform: translate(0, {100 * offset}%)">
|
<div class="counter-digits" style="transform: translate(0, {100 * offset}%)">
|
||||||
<strong class="hidden" aria-hidden="true">{Math.floor($displayed_count + 1)}</strong>
|
<strong class="hidden" aria-hidden="true">{Math.floor($displayed_count + 1)}</strong>
|
||||||
<strong>{Math.floor($displayed_count)}</strong>
|
<strong>{Math.floor($displayed_count)}</strong>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button on:click={() => (count += 1)} aria-label="Increase the counter by one">
|
<button on:click={() => (count += 1)} aria-label="Increase the counter by one">
|
||||||
<svg aria-hidden="true" viewBox="0 0 1 1">
|
<svg aria-hidden="true" viewBox="0 0 1 1">
|
||||||
<path d="M0,0.5 L1,0.5 M0.5,0 L0.5,1" />
|
<path d="M0,0.5 L1,0.5 M0.5,0 L0.5,1" />
|
||||||
</svg>
|
</svg>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.counter {
|
.counter {
|
||||||
display: flex;
|
display: flex;
|
||||||
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
||||||
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
|
||||||
margin: 1rem 0;
|
margin: 1rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.counter button {
|
.counter button {
|
||||||
width: 2em;
|
width: 2em;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
border: 0;
|
border: 0;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
touch-action: manipulation;
|
touch-action: manipulation;
|
||||||
color: var(--text-color);
|
color: var(--text-color);
|
||||||
font-size: 2rem;
|
font-size: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.counter button:hover {
|
.counter button:hover {
|
||||||
background-color: var(--secondary-color);
|
background-color: var(--secondary-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
width: 25%;
|
width: 25%;
|
||||||
height: 25%;
|
height: 25%;
|
||||||
}
|
}
|
||||||
|
|
||||||
path {
|
path {
|
||||||
vector-effect: non-scaling-stroke;
|
vector-effect: non-scaling-stroke;
|
||||||
stroke-width: 2px;
|
stroke-width: 2px;
|
||||||
stroke: var(--text-color);
|
stroke: var(--text-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.counter-viewport {
|
.counter-viewport {
|
||||||
width: 8em;
|
width: 8em;
|
||||||
height: 4em;
|
height: 4em;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.counter-viewport strong {
|
.counter-viewport strong {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
display: flex;
|
display: flex;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
color: var(--accent-color);
|
color: var(--accent-color);
|
||||||
font-size: 4rem;
|
font-size: 4rem;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.counter-digits {
|
.counter-digits {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hidden {
|
.hidden {
|
||||||
top: -100%;
|
top: -100%;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -31,11 +31,11 @@ import { invalidate } from '$app/navigation';
|
|||||||
export function enhance(form, { pending, error, result } = {}) {
|
export function enhance(form, { pending, error, result } = {}) {
|
||||||
let current_token;
|
let current_token;
|
||||||
|
|
||||||
/** @param {SubmitEvent} e */
|
/** @param {SubmitEvent} event */
|
||||||
async function handle_submit(e) {
|
async function handle_submit(event) {
|
||||||
const token = (current_token = {});
|
const token = (current_token = {});
|
||||||
|
|
||||||
e.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
const data = new FormData(form);
|
const data = new FormData(form);
|
||||||
|
|
||||||
@@ -63,11 +63,11 @@ export function enhance(form, { pending, error, result } = {}) {
|
|||||||
} else {
|
} else {
|
||||||
console.error(await response.text());
|
console.error(await response.text());
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (err) {
|
||||||
if (error && e instanceof Error) {
|
if (error && err instanceof Error) {
|
||||||
error({ data, form, error: e, response: null });
|
error({ data, form, error: err, response: null });
|
||||||
} else {
|
} else {
|
||||||
throw e;
|
throw err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,124 +1,124 @@
|
|||||||
<script>
|
<script>
|
||||||
import { page } from '$app/stores';
|
import { page } from '$app/stores';
|
||||||
import logo from './svelte-logo.svg';
|
import logo from './svelte-logo.svg';
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<header>
|
<header>
|
||||||
<div class="corner">
|
<div class="corner">
|
||||||
<a href="https://kit.svelte.dev">
|
<a href="https://kit.svelte.dev">
|
||||||
<img src={logo} alt="SvelteKit" />
|
<img src={logo} alt="SvelteKit" />
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<nav>
|
<nav>
|
||||||
<svg viewBox="0 0 2 3" aria-hidden="true">
|
<svg viewBox="0 0 2 3" aria-hidden="true">
|
||||||
<path d="M0,0 L1,2 C1.5,3 1.5,3 2,3 L2,0 Z" />
|
<path d="M0,0 L1,2 C1.5,3 1.5,3 2,3 L2,0 Z" />
|
||||||
</svg>
|
</svg>
|
||||||
<ul>
|
<ul>
|
||||||
<li class:active={$page.url.pathname === '/'}><a sveltekit:prefetch href="/">Home</a></li>
|
<li class:active={$page.url.pathname === '/'}><a sveltekit:prefetch href="/">Home</a></li>
|
||||||
<li class:active={$page.url.pathname === '/about'}>
|
<li class:active={$page.url.pathname === '/about'}>
|
||||||
<a sveltekit:prefetch href="/about">About</a>
|
<a sveltekit:prefetch href="/about">About</a>
|
||||||
</li>
|
</li>
|
||||||
<li class:active={$page.url.pathname === '/todos'}>
|
<li class:active={$page.url.pathname === '/todos'}>
|
||||||
<a sveltekit:prefetch href="/todos">Todos</a>
|
<a sveltekit:prefetch href="/todos">Todos</a>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<svg viewBox="0 0 2 3" aria-hidden="true">
|
<svg viewBox="0 0 2 3" aria-hidden="true">
|
||||||
<path d="M0,0 L0,3 C0.5,3 0.5,3 1,2 L2,0 Z" />
|
<path d="M0,0 L0,3 C0.5,3 0.5,3 1,2 L2,0 Z" />
|
||||||
</svg>
|
</svg>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<div class="corner">
|
<div class="corner">
|
||||||
<!-- TODO put something else here? github link? -->
|
<!-- TODO put something else here? github link? -->
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
header {
|
header {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
.corner {
|
.corner {
|
||||||
width: 3em;
|
width: 3em;
|
||||||
height: 3em;
|
height: 3em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.corner a {
|
.corner a {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.corner img {
|
.corner img {
|
||||||
width: 2em;
|
width: 2em;
|
||||||
height: 2em;
|
height: 2em;
|
||||||
object-fit: contain;
|
object-fit: contain;
|
||||||
}
|
}
|
||||||
|
|
||||||
nav {
|
nav {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
--background: rgba(255, 255, 255, 0.7);
|
--background: rgba(255, 255, 255, 0.7);
|
||||||
}
|
}
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
width: 2em;
|
width: 2em;
|
||||||
height: 3em;
|
height: 3em;
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
path {
|
path {
|
||||||
fill: var(--background);
|
fill: var(--background);
|
||||||
}
|
}
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
position: relative;
|
position: relative;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
height: 3em;
|
height: 3em;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
background: var(--background);
|
background: var(--background);
|
||||||
background-size: contain;
|
background-size: contain;
|
||||||
}
|
}
|
||||||
|
|
||||||
li {
|
li {
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
li.active::before {
|
li.active::before {
|
||||||
--size: 6px;
|
--size: 6px;
|
||||||
content: '';
|
content: '';
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: calc(50% - var(--size));
|
left: calc(50% - var(--size));
|
||||||
border: var(--size) solid transparent;
|
border: var(--size) solid transparent;
|
||||||
border-top: var(--size) solid var(--accent-color);
|
border-top: var(--size) solid var(--accent-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
nav a {
|
nav a {
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0 1em;
|
padding: 0 1em;
|
||||||
color: var(--heading-color);
|
color: var(--heading-color);
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
font-size: 0.8rem;
|
font-size: 0.8rem;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
letter-spacing: 0.1em;
|
letter-spacing: 0.1em;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
transition: color 0.2s linear;
|
transition: color 0.2s linear;
|
||||||
}
|
}
|
||||||
|
|
||||||
a:hover {
|
a:hover {
|
||||||
color: var(--accent-color);
|
color: var(--accent-color);
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
58
examples/sveltekit/src/routes/+layout.svelte
Normal file
58
examples/sveltekit/src/routes/+layout.svelte
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
<script>
|
||||||
|
import Header from '$lib/header/Header.svelte';
|
||||||
|
import { webVitals } from '$lib/vitals';
|
||||||
|
import { browser } from '$app/env';
|
||||||
|
import { page } from '$app/stores';
|
||||||
|
import '../app.css';
|
||||||
|
|
||||||
|
let analyticsId = import.meta.env.VERCEL_ANALYTICS_ID;
|
||||||
|
|
||||||
|
$: if (browser && analyticsId) {
|
||||||
|
webVitals({
|
||||||
|
path: $page.url.pathname,
|
||||||
|
params: $page.params,
|
||||||
|
analyticsId
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<Header />
|
||||||
|
|
||||||
|
<main>
|
||||||
|
<slot />
|
||||||
|
</main>
|
||||||
|
|
||||||
|
<footer>
|
||||||
|
<p>visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to learn SvelteKit</p>
|
||||||
|
</footer>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
main {
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 1rem;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 1024px;
|
||||||
|
margin: 0 auto;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
padding: 40px;
|
||||||
|
}
|
||||||
|
|
||||||
|
footer a {
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 480px) {
|
||||||
|
footer {
|
||||||
|
padding: 40px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
1
examples/sveltekit/src/routes/+page.js
Normal file
1
examples/sveltekit/src/routes/+page.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
export const prerender = true;
|
||||||
57
examples/sveltekit/src/routes/+page.svelte
Normal file
57
examples/sveltekit/src/routes/+page.svelte
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
<script>
|
||||||
|
import Counter from '$lib/Counter.svelte';
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<title>Home</title>
|
||||||
|
<meta name="description" content="Svelte demo app" />
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h1>
|
||||||
|
<span class="welcome">
|
||||||
|
<picture>
|
||||||
|
<source srcset="svelte-welcome.webp" type="image/webp" />
|
||||||
|
<img src="svelte-welcome.png" alt="Welcome" />
|
||||||
|
</picture>
|
||||||
|
</span>
|
||||||
|
|
||||||
|
to your new<br />SvelteKit app
|
||||||
|
</h1>
|
||||||
|
|
||||||
|
<h2>
|
||||||
|
try editing <strong>src/routes/index.svelte</strong>
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<Counter />
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
section {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.welcome {
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
height: 0;
|
||||||
|
padding: 0 0 calc(100% * 495 / 2048) 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.welcome img {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
top: 0;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
<script>
|
|
||||||
import Header from '$lib/header/Header.svelte';
|
|
||||||
import { webVitals } from '$lib/vitals';
|
|
||||||
import { browser } from '$app/env';
|
|
||||||
import { page } from '$app/stores';
|
|
||||||
import '../app.css';
|
|
||||||
|
|
||||||
let analyticsId = import.meta.env.VERCEL_ANALYTICS_ID;
|
|
||||||
|
|
||||||
$: if (browser && analyticsId) {
|
|
||||||
webVitals({
|
|
||||||
path: $page.url.pathname,
|
|
||||||
params: $page.params,
|
|
||||||
analyticsId
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<Header />
|
|
||||||
|
|
||||||
<main>
|
|
||||||
<slot />
|
|
||||||
</main>
|
|
||||||
|
|
||||||
<footer>
|
|
||||||
<p>visit <a href="https://kit.svelte.dev">kit.svelte.dev</a> to learn SvelteKit</p>
|
|
||||||
</footer>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
main {
|
|
||||||
flex: 1;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
padding: 1rem;
|
|
||||||
width: 100%;
|
|
||||||
max-width: 1024px;
|
|
||||||
margin: 0 auto;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
footer {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
padding: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
footer a {
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 480px) {
|
|
||||||
footer {
|
|
||||||
padding: 40px 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
<script context="module">
|
|
||||||
import { browser, dev } from '$app/env';
|
|
||||||
|
|
||||||
// we don't need any JS on this page, though we'll load
|
|
||||||
// it in dev so that we get hot module replacement...
|
|
||||||
export const hydrate = dev;
|
|
||||||
|
|
||||||
// ...but if the client-side router is already loaded
|
|
||||||
// (i.e. we came here from elsewhere in the app), use it
|
|
||||||
export const router = browser;
|
|
||||||
|
|
||||||
// since there's no dynamic data here, we can prerender
|
|
||||||
// it so that it gets served as a static asset in prod
|
|
||||||
export const prerender = true;
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<svelte:head>
|
|
||||||
<title>About</title>
|
|
||||||
<meta name="description" content="About this app" />
|
|
||||||
</svelte:head>
|
|
||||||
|
|
||||||
<div class="content">
|
|
||||||
<h1>About this app</h1>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
This is a <a href="https://kit.svelte.dev">SvelteKit</a> app. You can make your own by typing the
|
|
||||||
following into your command line and following the prompts:
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<pre>npm init svelte</pre>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The page you're looking at is purely static HTML, with no client-side interactivity needed.
|
|
||||||
Because of that, we don't need to load any JavaScript. Try viewing the page's source, or opening
|
|
||||||
the devtools network panel and reloading.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p>
|
|
||||||
The <a href="/todos">TODOs</a> page illustrates SvelteKit's data loading and form handling. Try using
|
|
||||||
it with JavaScript disabled!
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.content {
|
|
||||||
width: 100%;
|
|
||||||
max-width: var(--column-width);
|
|
||||||
margin: var(--column-margin-top) auto 0 auto;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
13
examples/sveltekit/src/routes/about/+page.js
Normal file
13
examples/sveltekit/src/routes/about/+page.js
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { browser, dev } from '$app/env';
|
||||||
|
|
||||||
|
// we don't need any JS on this page, though we'll load
|
||||||
|
// it in dev so that we get hot module replacement...
|
||||||
|
export const hydrate = dev;
|
||||||
|
|
||||||
|
// ...but if the client-side router is already loaded
|
||||||
|
// (i.e. we came here from elsewhere in the app), use it
|
||||||
|
export const router = browser;
|
||||||
|
|
||||||
|
// since there's no dynamic data here, we can prerender
|
||||||
|
// it so that it gets served as a static asset in prod
|
||||||
|
export const prerender = true;
|
||||||
34
examples/sveltekit/src/routes/about/+page.svelte
Normal file
34
examples/sveltekit/src/routes/about/+page.svelte
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
<svelte:head>
|
||||||
|
<title>About</title>
|
||||||
|
<meta name="description" content="About this app" />
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
|
<div class="content">
|
||||||
|
<h1>About this app</h1>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
This is a <a href="https://kit.svelte.dev">SvelteKit</a> app. You can make your own by typing the
|
||||||
|
following into your command line and following the prompts:
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre>npm create svelte@latest</pre>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The page you're looking at is purely static HTML, with no client-side interactivity needed.
|
||||||
|
Because of that, we don't need to load any JavaScript. Try viewing the page's source, or opening
|
||||||
|
the devtools network panel and reloading.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p>
|
||||||
|
The <a href="/todos">TODOs</a> page illustrates SvelteKit's data loading and form handling. Try using
|
||||||
|
it with JavaScript disabled!
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.content {
|
||||||
|
width: 100%;
|
||||||
|
max-width: var(--column-width);
|
||||||
|
margin: var(--column-margin-top) auto 0 auto;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
<script context="module">
|
|
||||||
export const prerender = true;
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import Counter from '$lib/Counter.svelte';
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<svelte:head>
|
|
||||||
<title>Home</title>
|
|
||||||
<meta name="description" content="Svelte demo app" />
|
|
||||||
</svelte:head>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<h1>
|
|
||||||
<div class="welcome">
|
|
||||||
<picture>
|
|
||||||
<source srcset="svelte-welcome.webp" type="image/webp" />
|
|
||||||
<img src="svelte-welcome.png" alt="Welcome" />
|
|
||||||
</picture>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
to your new<br />SvelteKit app
|
|
||||||
</h1>
|
|
||||||
|
|
||||||
<h2>
|
|
||||||
try editing <strong>src/routes/index.svelte</strong>
|
|
||||||
</h2>
|
|
||||||
|
|
||||||
<Counter />
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
section {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.welcome {
|
|
||||||
position: relative;
|
|
||||||
width: 100%;
|
|
||||||
height: 0;
|
|
||||||
padding: 0 0 calc(100% * 495 / 2048) 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.welcome img {
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
top: 0;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
62
examples/sveltekit/src/routes/todos/+page.server.js
Normal file
62
examples/sveltekit/src/routes/todos/+page.server.js
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
import { error } from '@sveltejs/kit';
|
||||||
|
import { api } from './api';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {{
|
||||||
|
* uid: string;
|
||||||
|
* created_at: Date;
|
||||||
|
* text: string;
|
||||||
|
* done: boolean;
|
||||||
|
* pending_delete: boolean;
|
||||||
|
* }} Todo
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @type {import('./$types').PageServerLoad} */
|
||||||
|
export const load = async ({ locals }) => {
|
||||||
|
// locals.userid comes from src/hooks.js
|
||||||
|
const response = await api('GET', `todos/${locals.userid}`);
|
||||||
|
|
||||||
|
if (response.status === 404) {
|
||||||
|
// user hasn't created a todo list.
|
||||||
|
// start with an empty array
|
||||||
|
return {
|
||||||
|
/** @type {Todo[]} */
|
||||||
|
todos: []
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.status === 200) {
|
||||||
|
return {
|
||||||
|
/** @type {Todo[]} */
|
||||||
|
todos: await response.json()
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
throw error(response.status);
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @type {import('./$types').Action} */
|
||||||
|
export const POST = async ({ request, locals }) => {
|
||||||
|
const form = await request.formData();
|
||||||
|
|
||||||
|
await api('POST', `todos/${locals.userid}`, {
|
||||||
|
text: form.get('text')
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @type {import('./$types').Action} */
|
||||||
|
export const PATCH = async ({ request, locals }) => {
|
||||||
|
const form = await request.formData();
|
||||||
|
|
||||||
|
await api('PATCH', `todos/${locals.userid}/${form.get('uid')}`, {
|
||||||
|
text: form.has('text') ? form.get('text') : undefined,
|
||||||
|
done: form.has('done') ? !!form.get('done') : undefined
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/** @type {import('./$types').Action} */
|
||||||
|
export const DELETE = async ({ request, locals }) => {
|
||||||
|
const form = await request.formData();
|
||||||
|
|
||||||
|
await api('DELETE', `todos/${locals.userid}/${form.get('uid')}`);
|
||||||
|
};
|
||||||
180
examples/sveltekit/src/routes/todos/+page.svelte
Normal file
180
examples/sveltekit/src/routes/todos/+page.svelte
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
<script>
|
||||||
|
import { enhance } from '$lib/form';
|
||||||
|
import { scale } from 'svelte/transition';
|
||||||
|
import { flip } from 'svelte/animate';
|
||||||
|
|
||||||
|
/** @type {import('./$types').PageData} */
|
||||||
|
export let data;
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<svelte:head>
|
||||||
|
<title>Todos</title>
|
||||||
|
<meta name="description" content="A todo list app" />
|
||||||
|
</svelte:head>
|
||||||
|
|
||||||
|
<div class="todos">
|
||||||
|
<h1>Todos</h1>
|
||||||
|
|
||||||
|
<form
|
||||||
|
class="new"
|
||||||
|
action="/todos"
|
||||||
|
method="post"
|
||||||
|
use:enhance={{
|
||||||
|
result: async ({ form }) => {
|
||||||
|
form.reset();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<input name="text" aria-label="Add todo" placeholder="+ tap to add a todo" />
|
||||||
|
</form>
|
||||||
|
|
||||||
|
{#each data.todos as todo (todo.uid)}
|
||||||
|
<div
|
||||||
|
class="todo"
|
||||||
|
class:done={todo.done}
|
||||||
|
transition:scale|local={{ start: 0.7 }}
|
||||||
|
animate:flip={{ duration: 200 }}
|
||||||
|
>
|
||||||
|
<form
|
||||||
|
action="/todos?_method=PATCH"
|
||||||
|
method="post"
|
||||||
|
use:enhance={{
|
||||||
|
pending: ({ data }) => {
|
||||||
|
todo.done = !!data.get('done');
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<input type="hidden" name="uid" value={todo.uid} />
|
||||||
|
<input type="hidden" name="done" value={todo.done ? '' : 'true'} />
|
||||||
|
<button class="toggle" aria-label="Mark todo as {todo.done ? 'not done' : 'done'}" />
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<form class="text" action="/todos?_method=PATCH" method="post" use:enhance>
|
||||||
|
<input type="hidden" name="uid" value={todo.uid} />
|
||||||
|
<input aria-label="Edit todo" type="text" name="text" value={todo.text} />
|
||||||
|
<button class="save" aria-label="Save todo" />
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<form
|
||||||
|
action="/todos?_method=DELETE"
|
||||||
|
method="post"
|
||||||
|
use:enhance={{
|
||||||
|
pending: () => (todo.pending_delete = true)
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<input type="hidden" name="uid" value={todo.uid} />
|
||||||
|
<button class="delete" aria-label="Delete todo" disabled={todo.pending_delete} />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.todos {
|
||||||
|
width: 100%;
|
||||||
|
max-width: var(--column-width);
|
||||||
|
margin: var(--column-margin-top) auto 0 auto;
|
||||||
|
line-height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.new {
|
||||||
|
margin: 0 0 0.5rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
border: 1px solid transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
input:focus-visible {
|
||||||
|
box-shadow: inset 1px 1px 6px rgba(0, 0, 0, 0.1);
|
||||||
|
border: 1px solid #ff3e00 !important;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.new input {
|
||||||
|
font-size: 28px;
|
||||||
|
width: 100%;
|
||||||
|
padding: 0.5em 1em 0.3em 1em;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background: rgba(255, 255, 255, 0.05);
|
||||||
|
border-radius: 8px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.todo {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 2rem 1fr 2rem;
|
||||||
|
grid-gap: 0.5rem;
|
||||||
|
align-items: center;
|
||||||
|
margin: 0 0 0.5rem 0;
|
||||||
|
padding: 0.5rem;
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 8px;
|
||||||
|
filter: drop-shadow(2px 4px 6px rgba(0, 0, 0, 0.1));
|
||||||
|
transform: translate(-1px, -1px);
|
||||||
|
transition: filter 0.2s, transform 0.2s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.done {
|
||||||
|
transform: none;
|
||||||
|
opacity: 0.4;
|
||||||
|
filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.1));
|
||||||
|
}
|
||||||
|
|
||||||
|
form.text {
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.todo input {
|
||||||
|
flex: 1;
|
||||||
|
padding: 0.5em 2em 0.5em 0.8em;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.todo button {
|
||||||
|
width: 2em;
|
||||||
|
height: 2em;
|
||||||
|
border: none;
|
||||||
|
background-color: transparent;
|
||||||
|
background-position: 50% 50%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.toggle {
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.2);
|
||||||
|
border-radius: 50%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
background-size: 1em auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.done .toggle {
|
||||||
|
background-image: url("data:image/svg+xml,%3Csvg width='22' height='16' viewBox='0 0 22 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20.5 1.5L7.4375 14.5L1.5 8.5909' stroke='%23676778' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete {
|
||||||
|
background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M4.5 5V22H19.5V5H4.5Z' fill='%23676778' stroke='%23676778' stroke-width='1.5' stroke-linejoin='round'/%3E%3Cpath d='M10 10V16.5' stroke='white' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M14 10V16.5' stroke='white' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M2 5H22' stroke='%23676778' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M8 5L9.6445 2H14.3885L16 5H8Z' fill='%23676778' stroke='%23676778' stroke-width='1.5' stroke-linejoin='round'/%3E%3C/svg%3E%0A");
|
||||||
|
opacity: 0.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.delete:hover,
|
||||||
|
.delete:focus {
|
||||||
|
transition: opacity 0.2s;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.save {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
opacity: 0;
|
||||||
|
background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20.5 2H3.5C2.67158 2 2 2.67157 2 3.5V20.5C2 21.3284 2.67158 22 3.5 22H20.5C21.3284 22 22 21.3284 22 20.5V3.5C22 2.67157 21.3284 2 20.5 2Z' fill='%23676778' stroke='%23676778' stroke-width='1.5' stroke-linejoin='round'/%3E%3Cpath d='M17 2V11H7.5V2H17Z' fill='white' stroke='white' stroke-width='1.5' stroke-linejoin='round'/%3E%3Cpath d='M13.5 5.5V7.5' stroke='%23676778' stroke-width='1.5' stroke-linecap='round'/%3E%3Cpath d='M5.99844 2H18.4992' stroke='%23676778' stroke-width='1.5' stroke-linecap='round'/%3E%3C/svg%3E%0A");
|
||||||
|
}
|
||||||
|
|
||||||
|
.todo input:focus + .save,
|
||||||
|
.save:focus {
|
||||||
|
transition: opacity 0.2s;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,9 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
This module is used by the /todos endpoint to
|
This module is used by the /todos endpoint to
|
||||||
make calls to api.svelte.dev, which stores todos
|
make calls to api.svelte.dev, which stores todos
|
||||||
for each user. The leading underscore indicates that this is
|
for each user.
|
||||||
a private module, _not_ an endpoint — visiting /todos/_api
|
|
||||||
will net you a 404 response.
|
|
||||||
|
|
||||||
(The data on the todo app will expire periodically; no
|
(The data on the todo app will expire periodically; no
|
||||||
guarantees are made. Don't use it to organise your life.)
|
guarantees are made. Don't use it to organise your life.)
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
import { api } from './_api';
|
|
||||||
|
|
||||||
/** @type {import('./__types').RequestHandler} */
|
|
||||||
export const get = async ({ locals }) => {
|
|
||||||
// locals.userid comes from src/hooks.js
|
|
||||||
const response = await api('get', `todos/${locals.userid}`);
|
|
||||||
|
|
||||||
if (response.status === 404) {
|
|
||||||
// user hasn't created a todo list.
|
|
||||||
// start with an empty array
|
|
||||||
return {
|
|
||||||
body: {
|
|
||||||
todos: []
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
if (response.status === 200) {
|
|
||||||
return {
|
|
||||||
body: {
|
|
||||||
todos: await response.json()
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
status: response.status
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/** @type {import('./index').RequestHandler} */
|
|
||||||
export const post = async ({ request, locals }) => {
|
|
||||||
const form = await request.formData();
|
|
||||||
|
|
||||||
await api('post', `todos/${locals.userid}`, {
|
|
||||||
text: form.get('text')
|
|
||||||
});
|
|
||||||
|
|
||||||
return {};
|
|
||||||
};
|
|
||||||
|
|
||||||
// If the user has JavaScript disabled, the URL will change to
|
|
||||||
// include the method override unless we redirect back to /todos
|
|
||||||
const redirect = {
|
|
||||||
status: 303,
|
|
||||||
headers: {
|
|
||||||
location: '/todos'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/** @type {import('./index').RequestHandler} */
|
|
||||||
export const patch = async ({ request, locals }) => {
|
|
||||||
const form = await request.formData();
|
|
||||||
|
|
||||||
await api('patch', `todos/${locals.userid}/${form.get('uid')}`, {
|
|
||||||
text: form.has('text') ? form.get('text') : undefined,
|
|
||||||
done: form.has('done') ? !!form.get('done') : undefined
|
|
||||||
});
|
|
||||||
|
|
||||||
return redirect;
|
|
||||||
};
|
|
||||||
|
|
||||||
/** @type {import('./index').RequestHandler} */
|
|
||||||
export const del = async ({ request, locals }) => {
|
|
||||||
const form = await request.formData();
|
|
||||||
|
|
||||||
await api('delete', `todos/${locals.userid}/${form.get('uid')}`);
|
|
||||||
|
|
||||||
return redirect;
|
|
||||||
};
|
|
||||||
@@ -1,190 +0,0 @@
|
|||||||
<script>
|
|
||||||
import { enhance } from '$lib/form';
|
|
||||||
import { scale } from 'svelte/transition';
|
|
||||||
import { flip } from 'svelte/animate';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @typedef {{
|
|
||||||
* uid: string;
|
|
||||||
* created_at: Date;
|
|
||||||
* text: string;
|
|
||||||
* done: boolean;
|
|
||||||
* pending_delete: boolean;
|
|
||||||
* }} Todo
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** @type {Todo[]} */
|
|
||||||
export let todos;
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<svelte:head>
|
|
||||||
<title>Todos</title>
|
|
||||||
<meta name="description" content="A todo list app" />
|
|
||||||
</svelte:head>
|
|
||||||
|
|
||||||
<div class="todos">
|
|
||||||
<h1>Todos</h1>
|
|
||||||
|
|
||||||
<form
|
|
||||||
class="new"
|
|
||||||
action="/todos"
|
|
||||||
method="post"
|
|
||||||
use:enhance={{
|
|
||||||
result: async ({ form }) => {
|
|
||||||
form.reset();
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<input name="text" aria-label="Add todo" placeholder="+ tap to add a todo" />
|
|
||||||
</form>
|
|
||||||
|
|
||||||
{#each todos as todo (todo.uid)}
|
|
||||||
<div
|
|
||||||
class="todo"
|
|
||||||
class:done={todo.done}
|
|
||||||
transition:scale|local={{ start: 0.7 }}
|
|
||||||
animate:flip={{ duration: 200 }}
|
|
||||||
>
|
|
||||||
<form
|
|
||||||
action="/todos?_method=PATCH"
|
|
||||||
method="post"
|
|
||||||
use:enhance={{
|
|
||||||
pending: ({ data }) => {
|
|
||||||
todo.done = !!data.get('done');
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<input type="hidden" name="uid" value={todo.uid} />
|
|
||||||
<input type="hidden" name="done" value={todo.done ? '' : 'true'} />
|
|
||||||
<button class="toggle" aria-label="Mark todo as {todo.done ? 'not done' : 'done'}" />
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<form class="text" action="/todos?_method=PATCH" method="post" use:enhance>
|
|
||||||
<input type="hidden" name="uid" value={todo.uid} />
|
|
||||||
<input aria-label="Edit todo" type="text" name="text" value={todo.text} />
|
|
||||||
<button class="save" aria-label="Save todo" />
|
|
||||||
</form>
|
|
||||||
|
|
||||||
<form
|
|
||||||
action="/todos?_method=DELETE"
|
|
||||||
method="post"
|
|
||||||
use:enhance={{
|
|
||||||
pending: () => (todo.pending_delete = true)
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<input type="hidden" name="uid" value={todo.uid} />
|
|
||||||
<button class="delete" aria-label="Delete todo" disabled={todo.pending_delete} />
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.todos {
|
|
||||||
width: 100%;
|
|
||||||
max-width: var(--column-width);
|
|
||||||
margin: var(--column-margin-top) auto 0 auto;
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.new {
|
|
||||||
margin: 0 0 0.5rem 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
input {
|
|
||||||
border: 1px solid transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
input:focus-visible {
|
|
||||||
box-shadow: inset 1px 1px 6px rgba(0, 0, 0, 0.1);
|
|
||||||
border: 1px solid #ff3e00 !important;
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.new input {
|
|
||||||
font-size: 28px;
|
|
||||||
width: 100%;
|
|
||||||
padding: 0.5em 1em 0.3em 1em;
|
|
||||||
box-sizing: border-box;
|
|
||||||
background: rgba(255, 255, 255, 0.05);
|
|
||||||
border-radius: 8px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.todo {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 2rem 1fr 2rem;
|
|
||||||
grid-gap: 0.5rem;
|
|
||||||
align-items: center;
|
|
||||||
margin: 0 0 0.5rem 0;
|
|
||||||
padding: 0.5rem;
|
|
||||||
background-color: white;
|
|
||||||
border-radius: 8px;
|
|
||||||
filter: drop-shadow(2px 4px 6px rgba(0, 0, 0, 0.1));
|
|
||||||
transform: translate(-1px, -1px);
|
|
||||||
transition: filter 0.2s, transform 0.2s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.done {
|
|
||||||
transform: none;
|
|
||||||
opacity: 0.4;
|
|
||||||
filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.1));
|
|
||||||
}
|
|
||||||
|
|
||||||
form.text {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
flex: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.todo input {
|
|
||||||
flex: 1;
|
|
||||||
padding: 0.5em 2em 0.5em 0.8em;
|
|
||||||
border-radius: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.todo button {
|
|
||||||
width: 2em;
|
|
||||||
height: 2em;
|
|
||||||
border: none;
|
|
||||||
background-color: transparent;
|
|
||||||
background-position: 50% 50%;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
}
|
|
||||||
|
|
||||||
button.toggle {
|
|
||||||
border: 1px solid rgba(0, 0, 0, 0.2);
|
|
||||||
border-radius: 50%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
background-size: 1em auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.done .toggle {
|
|
||||||
background-image: url("data:image/svg+xml,%3Csvg width='22' height='16' viewBox='0 0 22 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20.5 1.5L7.4375 14.5L1.5 8.5909' stroke='%23676778' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
|
|
||||||
}
|
|
||||||
|
|
||||||
.delete {
|
|
||||||
background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M4.5 5V22H19.5V5H4.5Z' fill='%23676778' stroke='%23676778' stroke-width='1.5' stroke-linejoin='round'/%3E%3Cpath d='M10 10V16.5' stroke='white' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M14 10V16.5' stroke='white' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M2 5H22' stroke='%23676778' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3Cpath d='M8 5L9.6445 2H14.3885L16 5H8Z' fill='%23676778' stroke='%23676778' stroke-width='1.5' stroke-linejoin='round'/%3E%3C/svg%3E%0A");
|
|
||||||
opacity: 0.2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.delete:hover,
|
|
||||||
.delete:focus {
|
|
||||||
transition: opacity 0.2s;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.save {
|
|
||||||
position: absolute;
|
|
||||||
right: 0;
|
|
||||||
opacity: 0;
|
|
||||||
background-image: url("data:image/svg+xml,%3Csvg width='24' height='24' viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M20.5 2H3.5C2.67158 2 2 2.67157 2 3.5V20.5C2 21.3284 2.67158 22 3.5 22H20.5C21.3284 22 22 21.3284 22 20.5V3.5C22 2.67157 21.3284 2 20.5 2Z' fill='%23676778' stroke='%23676778' stroke-width='1.5' stroke-linejoin='round'/%3E%3Cpath d='M17 2V11H7.5V2H17Z' fill='white' stroke='white' stroke-width='1.5' stroke-linejoin='round'/%3E%3Cpath d='M13.5 5.5V7.5' stroke='%23676778' stroke-width='1.5' stroke-linecap='round'/%3E%3Cpath d='M5.99844 2H18.4992' stroke='%23676778' stroke-width='1.5' stroke-linecap='round'/%3E%3C/svg%3E%0A");
|
|
||||||
}
|
|
||||||
|
|
||||||
.todo input:focus + .save,
|
|
||||||
.save:focus {
|
|
||||||
transition: opacity 0.2s;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -8,11 +8,6 @@ const config = {
|
|||||||
// Override http methods in the Todo forms
|
// Override http methods in the Todo forms
|
||||||
methodOverride: {
|
methodOverride: {
|
||||||
allowed: ['PATCH', 'DELETE']
|
allowed: ['PATCH', 'DELETE']
|
||||||
},
|
|
||||||
vite: {
|
|
||||||
define: {
|
|
||||||
'import.meta.env.VERCEL_ANALYTICS_ID': JSON.stringify(process.env.VERCEL_ANALYTICS_ID)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
11
examples/sveltekit/vite.config.js
Normal file
11
examples/sveltekit/vite.config.js
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
import { sveltekit } from '@sveltejs/kit/vite';
|
||||||
|
|
||||||
|
/** @type {import('vite').UserConfig} */
|
||||||
|
const config = {
|
||||||
|
plugins: [sveltekit()],
|
||||||
|
define: {
|
||||||
|
'import.meta.env.VERCEL_ANALYTICS_ID': JSON.stringify(process.env.VERCEL_ANALYTICS_ID)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export default config;
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -99,6 +99,7 @@
|
|||||||
"selector": "MemberExpression > Identifier[name='substr']"
|
"selector": "MemberExpression > Identifier[name='substr']"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"no-dupe-keys": 2,
|
||||||
"require-atomic-updates": 0,
|
"require-atomic-updates": 0,
|
||||||
"@typescript-eslint/ban-ts-comment": 0,
|
"@typescript-eslint/ban-ts-comment": 0,
|
||||||
"@typescript-eslint/camelcase": 0,
|
"@typescript-eslint/camelcase": 0,
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vercel/build-utils",
|
"name": "@vercel/build-utils",
|
||||||
"version": "5.3.1",
|
"version": "5.4.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"types": "./dist/index.d.js",
|
"types": "./dist/index.d.js",
|
||||||
|
|||||||
@@ -3,5 +3,7 @@ import { getPlatformEnv } from './get-platform-env';
|
|||||||
export default function debug(message: string, ...additional: any[]) {
|
export default function debug(message: string, ...additional: any[]) {
|
||||||
if (getPlatformEnv('BUILDER_DEBUG')) {
|
if (getPlatformEnv('BUILDER_DEBUG')) {
|
||||||
console.log(message, ...additional);
|
console.log(message, ...additional);
|
||||||
|
} else if (process.env.VERCEL_DEBUG_PREFIX) {
|
||||||
|
console.log(`${process.env.VERCEL_DEBUG_PREFIX}${message}`, ...additional);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -335,7 +335,6 @@ export interface ProjectSettings {
|
|||||||
directoryListing?: boolean;
|
directoryListing?: boolean;
|
||||||
gitForkProtection?: boolean;
|
gitForkProtection?: boolean;
|
||||||
commandForIgnoringBuildStep?: string | null;
|
commandForIgnoringBuildStep?: string | null;
|
||||||
skipGitConnectDuringLink?: boolean;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface BuilderV2 {
|
export interface BuilderV2 {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "vercel",
|
"name": "vercel",
|
||||||
"version": "28.0.1",
|
"version": "28.2.0",
|
||||||
"preferGlobal": true,
|
"preferGlobal": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"description": "The command-line interface for Vercel",
|
"description": "The command-line interface for Vercel",
|
||||||
@@ -41,16 +41,16 @@
|
|||||||
"node": ">= 14"
|
"node": ">= 14"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vercel/build-utils": "5.3.1",
|
"@vercel/build-utils": "5.4.0",
|
||||||
"@vercel/go": "2.1.1",
|
"@vercel/go": "2.2.3",
|
||||||
"@vercel/hydrogen": "0.0.14",
|
"@vercel/hydrogen": "0.0.16",
|
||||||
"@vercel/next": "3.1.18",
|
"@vercel/next": "3.1.22",
|
||||||
"@vercel/node": "2.5.8",
|
"@vercel/node": "2.5.11",
|
||||||
"@vercel/python": "3.1.9",
|
"@vercel/python": "3.1.12",
|
||||||
"@vercel/redwood": "1.0.18",
|
"@vercel/redwood": "1.0.20",
|
||||||
"@vercel/remix": "1.0.19",
|
"@vercel/remix": "1.0.21",
|
||||||
"@vercel/ruby": "1.3.26",
|
"@vercel/ruby": "1.3.29",
|
||||||
"@vercel/static-build": "1.0.18",
|
"@vercel/static-build": "1.0.20",
|
||||||
"update-notifier": "5.1.0"
|
"update-notifier": "5.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -96,7 +96,7 @@
|
|||||||
"@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": "12.2.0",
|
"@vercel/client": "12.2.2",
|
||||||
"@vercel/frameworks": "1.1.3",
|
"@vercel/frameworks": "1.1.3",
|
||||||
"@vercel/fs-detectors": "2.0.5",
|
"@vercel/fs-detectors": "2.0.5",
|
||||||
"@vercel/fun": "1.0.4",
|
"@vercel/fun": "1.0.4",
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ export default async function rm(
|
|||||||
|
|
||||||
const removeStamp = stamp();
|
const removeStamp = stamp();
|
||||||
if (!opts['--yes'] && !(await confirmAliasRemove(client, alias))) {
|
if (!opts['--yes'] && !(await confirmAliasRemove(client, alias))) {
|
||||||
output.log('Aborted');
|
output.log('Canceled');
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -220,7 +220,7 @@ function handleSetupDomainError<T>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (error instanceof ERRORS.UserAborted) {
|
if (error instanceof ERRORS.UserAborted) {
|
||||||
output.error(`User aborted`);
|
output.error(`User canceled.`);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -116,8 +116,6 @@ export default async function main(client: Client): Promise<number> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const badDeploymentPromise = getDeployment(client, bad).catch(err => err);
|
|
||||||
|
|
||||||
good = normalizeURL(good);
|
good = normalizeURL(good);
|
||||||
parsed = parse(good);
|
parsed = parse(good);
|
||||||
if (!parsed.hostname) {
|
if (!parsed.hostname) {
|
||||||
@@ -138,8 +136,6 @@ export default async function main(client: Client): Promise<number> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const goodDeploymentPromise = getDeployment(client, good).catch(err => err);
|
|
||||||
|
|
||||||
if (!subpath) {
|
if (!subpath) {
|
||||||
subpath = await prompt(
|
subpath = await prompt(
|
||||||
client,
|
client,
|
||||||
@@ -148,10 +144,9 @@ export default async function main(client: Client): Promise<number> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
output.spinner('Retrieving deployments…');
|
output.spinner('Retrieving deployments…');
|
||||||
const [badDeployment, goodDeployment] = await Promise.all([
|
|
||||||
badDeploymentPromise,
|
// `getDeployment` cannot be parallelized because it might prompt for login
|
||||||
goodDeploymentPromise,
|
const badDeployment = await getDeployment(client, bad).catch(err => err);
|
||||||
]);
|
|
||||||
|
|
||||||
if (badDeployment) {
|
if (badDeployment) {
|
||||||
if (badDeployment instanceof Error) {
|
if (badDeployment instanceof Error) {
|
||||||
@@ -165,7 +160,8 @@ export default async function main(client: Client): Promise<number> {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { projectId } = badDeployment;
|
// `getDeployment` cannot be parallelized because it might prompt for login
|
||||||
|
const goodDeployment = await getDeployment(client, good).catch(err => err);
|
||||||
|
|
||||||
if (goodDeployment) {
|
if (goodDeployment) {
|
||||||
if (goodDeployment instanceof Error) {
|
if (goodDeployment instanceof Error) {
|
||||||
@@ -181,6 +177,8 @@ export default async function main(client: Client): Promise<number> {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { projectId } = badDeployment;
|
||||||
|
|
||||||
if (projectId !== goodDeployment.projectId) {
|
if (projectId !== goodDeployment.projectId) {
|
||||||
output.error(`Good and Bad deployments must be from the same Project`);
|
output.error(`Good and Bad deployments must be from the same Project`);
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import cliPkg from '../util/pkg';
|
|||||||
import readJSONFile from '../util/read-json-file';
|
import readJSONFile from '../util/read-json-file';
|
||||||
import { CantParseJSONFile } from '../util/errors-ts';
|
import { CantParseJSONFile } from '../util/errors-ts';
|
||||||
import {
|
import {
|
||||||
|
pickOverrides,
|
||||||
ProjectLinkAndSettings,
|
ProjectLinkAndSettings,
|
||||||
readProjectSettings,
|
readProjectSettings,
|
||||||
} from '../util/projects/project-settings';
|
} from '../util/projects/project-settings';
|
||||||
@@ -171,7 +172,7 @@ export default async function main(client: Client): Promise<number> {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (!confirmed) {
|
if (!confirmed) {
|
||||||
client.output.print(`Aborted. No Project Settings retrieved.\n`);
|
client.output.print(`Canceled. No Project Settings retrieved.\n`);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
const { argv: originalArgv } = client;
|
const { argv: originalArgv } = client;
|
||||||
@@ -278,6 +279,11 @@ async function doBuild(
|
|||||||
if (pkg instanceof CantParseJSONFile) throw pkg;
|
if (pkg instanceof CantParseJSONFile) throw pkg;
|
||||||
if (vercelConfig instanceof CantParseJSONFile) throw vercelConfig;
|
if (vercelConfig instanceof CantParseJSONFile) throw vercelConfig;
|
||||||
|
|
||||||
|
const projectSettings = {
|
||||||
|
...project.settings,
|
||||||
|
...pickOverrides(vercelConfig || {}),
|
||||||
|
};
|
||||||
|
|
||||||
// Get a list of source files
|
// Get a list of source files
|
||||||
const files = (await getFiles(workPath, client)).map(f =>
|
const files = (await getFiles(workPath, client)).map(f =>
|
||||||
normalizePath(relative(workPath, f))
|
normalizePath(relative(workPath, f))
|
||||||
@@ -313,7 +319,7 @@ async function doBuild(
|
|||||||
// Detect the Vercel Builders that will need to be invoked
|
// Detect the Vercel Builders that will need to be invoked
|
||||||
const detectedBuilders = await detectBuilders(files, pkg, {
|
const detectedBuilders = await detectBuilders(files, pkg, {
|
||||||
...vercelConfig,
|
...vercelConfig,
|
||||||
projectSettings: project.settings,
|
projectSettings,
|
||||||
ignoreBuildScript: true,
|
ignoreBuildScript: true,
|
||||||
featHandleMiss: true,
|
featHandleMiss: true,
|
||||||
});
|
});
|
||||||
@@ -425,14 +431,14 @@ async function doBuild(
|
|||||||
|
|
||||||
const buildConfig: Config = isZeroConfig
|
const buildConfig: Config = isZeroConfig
|
||||||
? {
|
? {
|
||||||
outputDirectory: project.settings.outputDirectory ?? undefined,
|
outputDirectory: projectSettings.outputDirectory ?? undefined,
|
||||||
...build.config,
|
...build.config,
|
||||||
projectSettings: project.settings,
|
projectSettings,
|
||||||
installCommand: project.settings.installCommand ?? undefined,
|
installCommand: projectSettings.installCommand ?? undefined,
|
||||||
devCommand: project.settings.devCommand ?? undefined,
|
devCommand: projectSettings.devCommand ?? undefined,
|
||||||
buildCommand: project.settings.buildCommand ?? undefined,
|
buildCommand: projectSettings.buildCommand ?? undefined,
|
||||||
framework: project.settings.framework,
|
framework: projectSettings.framework,
|
||||||
nodeVersion: project.settings.nodeVersion,
|
nodeVersion: projectSettings.nodeVersion,
|
||||||
}
|
}
|
||||||
: build.config || {};
|
: build.config || {};
|
||||||
const buildOptions: BuildOptions = {
|
const buildOptions: BuildOptions = {
|
||||||
|
|||||||
@@ -47,9 +47,7 @@ import {
|
|||||||
import { SchemaValidationFailed } from '../../util/errors';
|
import { SchemaValidationFailed } from '../../util/errors';
|
||||||
import purchaseDomainIfAvailable from '../../util/domains/purchase-domain-if-available';
|
import purchaseDomainIfAvailable from '../../util/domains/purchase-domain-if-available';
|
||||||
import confirm from '../../util/input/confirm';
|
import confirm from '../../util/input/confirm';
|
||||||
import editProjectSettings, {
|
import editProjectSettings from '../../util/input/edit-project-settings';
|
||||||
PartialProjectSettings,
|
|
||||||
} from '../../util/input/edit-project-settings';
|
|
||||||
import {
|
import {
|
||||||
getLinkedProject,
|
getLinkedProject,
|
||||||
linkFolderToProject,
|
linkFolderToProject,
|
||||||
@@ -73,6 +71,7 @@ import { createGitMeta } from '../../util/create-git-meta';
|
|||||||
import { isValidArchive } from '../../util/deploy/validate-archive-format';
|
import { isValidArchive } from '../../util/deploy/validate-archive-format';
|
||||||
import { parseEnv } from '../../util/parse-env';
|
import { parseEnv } from '../../util/parse-env';
|
||||||
import { errorToString, isErrnoException, isError } from '../../util/is-error';
|
import { errorToString, isErrnoException, isError } from '../../util/is-error';
|
||||||
|
import { pickOverrides } from '../../util/projects/project-settings';
|
||||||
|
|
||||||
export default async (client: Client): Promise<number> => {
|
export default async (client: Client): Promise<number> => {
|
||||||
const { output } = client;
|
const { output } = client;
|
||||||
@@ -296,7 +295,7 @@ export default async (client: Client): Promise<number> => {
|
|||||||
));
|
));
|
||||||
|
|
||||||
if (!shouldStartSetup) {
|
if (!shouldStartSetup) {
|
||||||
output.print(`Aborted. Project not set up.\n`);
|
output.print(`Canceled. Project not set up.\n`);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -509,14 +508,7 @@ export default async (client: Client): Promise<number> => {
|
|||||||
let deployStamp = stamp();
|
let deployStamp = stamp();
|
||||||
let deployment = null;
|
let deployment = null;
|
||||||
|
|
||||||
const localConfigurationOverrides: PartialProjectSettings = {
|
const localConfigurationOverrides = pickOverrides(localConfig);
|
||||||
buildCommand: localConfig?.buildCommand,
|
|
||||||
devCommand: localConfig?.devCommand,
|
|
||||||
framework: localConfig?.framework,
|
|
||||||
commandForIgnoringBuildStep: localConfig?.ignoreCommand,
|
|
||||||
installCommand: localConfig?.installCommand,
|
|
||||||
outputDirectory: localConfig?.outputDirectory,
|
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const createArgs: any = {
|
const createArgs: any = {
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ import parseListen from '../../util/dev/parse-listen';
|
|||||||
import { ProjectEnvVariable } from '../../types';
|
import { ProjectEnvVariable } from '../../types';
|
||||||
import Client from '../../util/client';
|
import Client from '../../util/client';
|
||||||
import { getLinkedProject } from '../../util/projects/link';
|
import { getLinkedProject } from '../../util/projects/link';
|
||||||
import { getFrameworks } from '../../util/get-frameworks';
|
|
||||||
import { ProjectSettings } from '../../types';
|
import { ProjectSettings } from '../../types';
|
||||||
import getDecryptedEnvRecords from '../../util/get-decrypted-env-records';
|
import getDecryptedEnvRecords from '../../util/get-decrypted-env-records';
|
||||||
import setupAndLink from '../../util/link/setup-and-link';
|
import setupAndLink from '../../util/link/setup-and-link';
|
||||||
@@ -31,10 +30,7 @@ export default async function dev(
|
|||||||
const listen = parseListen(opts['--listen'] || '3000');
|
const listen = parseListen(opts['--listen'] || '3000');
|
||||||
|
|
||||||
// retrieve dev command
|
// retrieve dev command
|
||||||
let [link, frameworks] = await Promise.all([
|
let link = await getLinkedProject(client, cwd);
|
||||||
getLinkedProject(client, cwd),
|
|
||||||
getFrameworks(client),
|
|
||||||
]);
|
|
||||||
|
|
||||||
if (link.status === 'not_linked' && !process.env.__VERCEL_SKIP_DEV_CMD) {
|
if (link.status === 'not_linked' && !process.env.__VERCEL_SKIP_DEV_CMD) {
|
||||||
link = await setupAndLink(client, cwd, {
|
link = await setupAndLink(client, cwd, {
|
||||||
@@ -60,7 +56,6 @@ export default async function dev(
|
|||||||
return link.exitCode;
|
return link.exitCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
let devCommand: string | undefined;
|
|
||||||
let projectSettings: ProjectSettings | undefined;
|
let projectSettings: ProjectSettings | undefined;
|
||||||
let projectEnvs: ProjectEnvVariable[] = [];
|
let projectEnvs: ProjectEnvVariable[] = [];
|
||||||
let systemEnvValues: string[] = [];
|
let systemEnvValues: string[] = [];
|
||||||
@@ -70,19 +65,6 @@ export default async function dev(
|
|||||||
|
|
||||||
projectSettings = project;
|
projectSettings = project;
|
||||||
|
|
||||||
if (project.devCommand) {
|
|
||||||
devCommand = project.devCommand;
|
|
||||||
} else if (project.framework) {
|
|
||||||
const framework = frameworks.find(f => f.slug === project.framework);
|
|
||||||
|
|
||||||
if (framework) {
|
|
||||||
const defaults = framework.settings.devCommand.value;
|
|
||||||
if (defaults) {
|
|
||||||
devCommand = defaults;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (project.rootDirectory) {
|
if (project.rootDirectory) {
|
||||||
cwd = join(cwd, project.rootDirectory);
|
cwd = join(cwd, project.rootDirectory);
|
||||||
}
|
}
|
||||||
@@ -95,16 +77,17 @@ export default async function dev(
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is just for tests - can be removed once project settings
|
const devServer = new DevServer(cwd, {
|
||||||
// are respected locally in `.vercel/project.json`
|
output,
|
||||||
if (process.env.VERCEL_DEV_COMMAND) {
|
projectSettings,
|
||||||
devCommand = process.env.VERCEL_DEV_COMMAND;
|
projectEnvs,
|
||||||
}
|
systemEnvValues,
|
||||||
|
});
|
||||||
|
|
||||||
// If there is no Development Command, we must delete the
|
// If there is no Development Command, we must delete the
|
||||||
// v3 Build Output because it will incorrectly be detected by
|
// v3 Build Output because it will incorrectly be detected by
|
||||||
// @vercel/static-build in BuildOutputV3.getBuildOutputDirectory()
|
// @vercel/static-build in BuildOutputV3.getBuildOutputDirectory()
|
||||||
if (!devCommand) {
|
if (!devServer.devCommand) {
|
||||||
const outputDir = join(cwd, OUTPUT_DIR);
|
const outputDir = join(cwd, OUTPUT_DIR);
|
||||||
if (await fs.pathExists(outputDir)) {
|
if (await fs.pathExists(outputDir)) {
|
||||||
output.log(`Removing ${OUTPUT_DIR}`);
|
output.log(`Removing ${OUTPUT_DIR}`);
|
||||||
@@ -112,13 +95,5 @@ export default async function dev(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const devServer = new DevServer(cwd, {
|
|
||||||
output,
|
|
||||||
devCommand,
|
|
||||||
projectSettings,
|
|
||||||
projectEnvs,
|
|
||||||
systemEnvValues,
|
|
||||||
});
|
|
||||||
|
|
||||||
await devServer.start(...listen);
|
await devServer.start(...listen);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ export default async function add(
|
|||||||
const { domain, data: argData } = parsedParams;
|
const { domain, data: argData } = parsedParams;
|
||||||
const data = await getDNSData(client, argData);
|
const data = await getDNSData(client, argData);
|
||||||
if (!data) {
|
if (!data) {
|
||||||
output.log(`Aborted`);
|
output.log(`Canceled`);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ export default async function rm(
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!yes) {
|
if (!yes) {
|
||||||
output.error(`User aborted.`);
|
output.error(`User canceled.`);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ export default async function move(
|
|||||||
client
|
client
|
||||||
))
|
))
|
||||||
) {
|
) {
|
||||||
output.log('Aborted');
|
output.log('Canceled');
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -87,7 +87,7 @@ export default async function move(
|
|||||||
client
|
client
|
||||||
))
|
))
|
||||||
) {
|
) {
|
||||||
output.log('Aborted');
|
output.log('Canceled');
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ export default async function rm(
|
|||||||
client
|
client
|
||||||
))
|
))
|
||||||
) {
|
) {
|
||||||
output.log('Aborted');
|
output.log('Canceled');
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,7 +224,7 @@ async function removeDomain(
|
|||||||
!skipConfirmation &&
|
!skipConfirmation &&
|
||||||
!(await promptBool(`Remove conflicts associated with domain?`, client))
|
!(await promptBool(`Remove conflicts associated with domain?`, client))
|
||||||
) {
|
) {
|
||||||
output.log('Aborted');
|
output.log('Canceled');
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
2
packages/cli/src/commands/env/pull.ts
vendored
2
packages/cli/src/commands/env/pull.ts
vendored
@@ -84,7 +84,7 @@ export default async function pull(
|
|||||||
false
|
false
|
||||||
))
|
))
|
||||||
) {
|
) {
|
||||||
output.log('Aborted');
|
output.log('Canceled');
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
2
packages/cli/src/commands/env/rm.ts
vendored
2
packages/cli/src/commands/env/rm.ts
vendored
@@ -111,7 +111,7 @@ export default async function rm(
|
|||||||
false
|
false
|
||||||
))
|
))
|
||||||
) {
|
) {
|
||||||
output.log('Aborted');
|
output.log('Canceled');
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ export default async function connect(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (remoteUrl === '') {
|
if (remoteUrl === '') {
|
||||||
output.log('Aborted.');
|
output.log('Canceled');
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -317,7 +317,7 @@ async function promptConnectArg({
|
|||||||
false
|
false
|
||||||
);
|
);
|
||||||
if (!shouldConnect) {
|
if (!shouldConnect) {
|
||||||
client.output.log('Aborted. Repo not connected.');
|
client.output.log('Canceled. Repo not connected.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return shouldConnect;
|
return shouldConnect;
|
||||||
@@ -404,7 +404,7 @@ async function confirmRepoConnect(
|
|||||||
true
|
true
|
||||||
);
|
);
|
||||||
if (!shouldReplaceProject) {
|
if (!shouldReplaceProject) {
|
||||||
client.output.log('Aborted. Repo not connected.');
|
client.output.log('Canceled. Repo not connected.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return shouldReplaceProject;
|
return shouldReplaceProject;
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ export default async function disconnect(
|
|||||||
await disconnectGitProvider(client, org, project.id);
|
await disconnectGitProvider(client, org, project.id);
|
||||||
output.log(`Disconnected ${chalk.cyan(`${linkOrg}/${repo}`)}.`);
|
output.log(`Disconnected ${chalk.cyan(`${linkOrg}/${repo}`)}.`);
|
||||||
} else {
|
} else {
|
||||||
output.log('Aborted.');
|
output.log('Canceled');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
output.error(
|
output.error(
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ const help = () => {
|
|||||||
-t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline(
|
-t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline(
|
||||||
'TOKEN'
|
'TOKEN'
|
||||||
)} Login token
|
)} Login token
|
||||||
-y, --yes Skip questions when setting up new project using default scope and settings
|
-y, --yes Skip confirmation when connecting a Git provider
|
||||||
|
|
||||||
${chalk.dim('Examples:')}
|
${chalk.dim('Examples:')}
|
||||||
|
|
||||||
@@ -35,7 +35,9 @@ const help = () => {
|
|||||||
|
|
||||||
${chalk.cyan(`$ ${getPkgName()} git connect`)}
|
${chalk.cyan(`$ ${getPkgName()} git connect`)}
|
||||||
|
|
||||||
${chalk.gray('–')} Connect your Vercel Project to a Git repository using the remote URL
|
${chalk.gray(
|
||||||
|
'–'
|
||||||
|
)} Connect your Vercel Project to a Git repository using the remote URL
|
||||||
|
|
||||||
${chalk.cyan(
|
${chalk.cyan(
|
||||||
`$ ${getPkgName()} git connect https://github.com/user/repo.git`
|
`$ ${getPkgName()} git connect https://github.com/user/repo.git`
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ export default async function init(
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!chosen) {
|
if (!chosen) {
|
||||||
output.log('Aborted');
|
output.log('Canceled');
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -293,9 +293,7 @@ export default async function main(client: Client) {
|
|||||||
|
|
||||||
// information to help the user find other deployments or instances
|
// information to help the user find other deployments or instances
|
||||||
log(
|
log(
|
||||||
`To list more deployments for a project, run ${getCommandName(
|
`To list deployments for a project, run ${getCommandName('ls [project]')}.`
|
||||||
'ls [project]'
|
|
||||||
)}.`
|
|
||||||
);
|
);
|
||||||
|
|
||||||
print('\n');
|
print('\n');
|
||||||
@@ -338,7 +336,7 @@ export default async function main(client: Client) {
|
|||||||
if (pagination && pagination.count === 20) {
|
if (pagination && pagination.count === 20) {
|
||||||
const flags = getCommandFlags(argv, ['_', '--next']);
|
const flags = getCommandFlags(argv, ['_', '--next']);
|
||||||
log(
|
log(
|
||||||
`To display the next page run ${getCommandName(
|
`To display the next page, run ${getCommandName(
|
||||||
`ls${app ? ' ' + app : ''}${flags} --next ${pagination.next}`
|
`ls${app ? ' ' + app : ''}${flags} --next ${pagination.next}`
|
||||||
)}`
|
)}`
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -226,7 +226,7 @@ export default async function main(client: Client) {
|
|||||||
).toLowerCase();
|
).toLowerCase();
|
||||||
|
|
||||||
if (confirmation !== 'y' && confirmation !== 'yes') {
|
if (confirmation !== 'y' && confirmation !== 'yes') {
|
||||||
output.log('Aborted');
|
output.log('Canceled');
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -229,7 +229,7 @@ async function run({ output, contextName, currentTeam, client }) {
|
|||||||
argv.yes ||
|
argv.yes ||
|
||||||
(await readConfirmation(client, output, theSecret, contextName));
|
(await readConfirmation(client, output, theSecret, contextName));
|
||||||
if (!yes) {
|
if (!yes) {
|
||||||
output.print(`Aborted. Secret not deleted.\n`);
|
output.print(`Canceled. Secret not deleted.\n`);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ export default async function add(client: Client): Promise<number> {
|
|||||||
});
|
});
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
if (isError(err) && err.message === 'USER_ABORT') {
|
if (isError(err) && err.message === 'USER_ABORT') {
|
||||||
output.log('Aborted');
|
output.log('Canceled');
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import {
|
|||||||
Lambda,
|
Lambda,
|
||||||
FileBlob,
|
FileBlob,
|
||||||
FileFsRef,
|
FileFsRef,
|
||||||
|
normalizePath,
|
||||||
} from '@vercel/build-utils';
|
} from '@vercel/build-utils';
|
||||||
import { isOfficialRuntime } from '@vercel/fs-detectors';
|
import { isOfficialRuntime } from '@vercel/fs-detectors';
|
||||||
import plural from 'pluralize';
|
import plural from 'pluralize';
|
||||||
@@ -269,7 +270,9 @@ export async function executeBuild(
|
|||||||
const { cleanUrls } = vercelConfig;
|
const { cleanUrls } = vercelConfig;
|
||||||
|
|
||||||
// Mimic fmeta-util and perform file renaming
|
// Mimic fmeta-util and perform file renaming
|
||||||
Object.entries(output).forEach(([path, value]) => {
|
for (const [originalPath, value] of Object.entries(output)) {
|
||||||
|
let path = normalizePath(originalPath);
|
||||||
|
|
||||||
if (cleanUrls && path.endsWith('.html')) {
|
if (cleanUrls && path.endsWith('.html')) {
|
||||||
path = path.slice(0, -5);
|
path = path.slice(0, -5);
|
||||||
|
|
||||||
@@ -284,7 +287,7 @@ export async function executeBuild(
|
|||||||
}
|
}
|
||||||
|
|
||||||
output[path] = value;
|
output[path] = value;
|
||||||
});
|
}
|
||||||
|
|
||||||
// Convert the JSON-ified output map back into their corresponding `File`
|
// Convert the JSON-ified output map back into their corresponding `File`
|
||||||
// subclass type instances.
|
// subclass type instances.
|
||||||
|
|||||||
@@ -101,6 +101,7 @@ import {
|
|||||||
isError,
|
isError,
|
||||||
isSpawnError,
|
isSpawnError,
|
||||||
} from '../is-error';
|
} from '../is-error';
|
||||||
|
import { pickOverrides } from '../projects/project-settings';
|
||||||
|
|
||||||
const frontendRuntimeSet = new Set(
|
const frontendRuntimeSet = new Set(
|
||||||
frameworkList.map(f => f.useRuntime?.use || '@vercel/static-build')
|
frameworkList.map(f => f.useRuntime?.use || '@vercel/static-build')
|
||||||
@@ -136,6 +137,7 @@ export default class DevServer {
|
|||||||
public address: string;
|
public address: string;
|
||||||
public devCacheDir: string;
|
public devCacheDir: string;
|
||||||
|
|
||||||
|
private currentDevCommand?: string;
|
||||||
private caseSensitive: boolean;
|
private caseSensitive: boolean;
|
||||||
private apiDir: string | null;
|
private apiDir: string | null;
|
||||||
private apiExtensions: Set<string>;
|
private apiExtensions: Set<string>;
|
||||||
@@ -149,10 +151,10 @@ export default class DevServer {
|
|||||||
private watchAggregationTimeout: number;
|
private watchAggregationTimeout: number;
|
||||||
private filter: (path: string) => boolean;
|
private filter: (path: string) => boolean;
|
||||||
private podId: string;
|
private podId: string;
|
||||||
private devCommand?: string;
|
|
||||||
private devProcess?: ChildProcess;
|
private devProcess?: ChildProcess;
|
||||||
private devProcessPort?: number;
|
private devProcessPort?: number;
|
||||||
private devServerPids: Set<number>;
|
private devServerPids: Set<number>;
|
||||||
|
private originalProjectSettings?: ProjectSettings;
|
||||||
private projectSettings?: ProjectSettings;
|
private projectSettings?: ProjectSettings;
|
||||||
|
|
||||||
private vercelConfigWarning: boolean;
|
private vercelConfigWarning: boolean;
|
||||||
@@ -173,7 +175,7 @@ export default class DevServer {
|
|||||||
this.projectEnvs = options.projectEnvs || [];
|
this.projectEnvs = options.projectEnvs || [];
|
||||||
this.files = {};
|
this.files = {};
|
||||||
this.address = '';
|
this.address = '';
|
||||||
this.devCommand = options.devCommand;
|
this.originalProjectSettings = options.projectSettings;
|
||||||
this.projectSettings = options.projectSettings;
|
this.projectSettings = options.projectSettings;
|
||||||
this.caseSensitive = false;
|
this.caseSensitive = false;
|
||||||
this.apiDir = null;
|
this.apiDir = null;
|
||||||
@@ -549,6 +551,23 @@ export default class DevServer {
|
|||||||
return this.getVercelConfigPromise;
|
return this.getVercelConfigPromise;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get devCommand() {
|
||||||
|
if (this.projectSettings?.devCommand) {
|
||||||
|
return this.projectSettings.devCommand;
|
||||||
|
} else if (this.projectSettings?.framework) {
|
||||||
|
const frameworkSlug = this.projectSettings.framework;
|
||||||
|
const framework = frameworkList.find(f => f.slug === frameworkSlug);
|
||||||
|
|
||||||
|
if (framework) {
|
||||||
|
const defaults = framework.settings.devCommand.value;
|
||||||
|
if (defaults) {
|
||||||
|
return defaults;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
async _getVercelConfig(): Promise<VercelConfig> {
|
async _getVercelConfig(): Promise<VercelConfig> {
|
||||||
const configPath = getVercelConfigPath(this.cwd);
|
const configPath = getVercelConfigPath(this.cwd);
|
||||||
|
|
||||||
@@ -563,6 +582,12 @@ export default class DevServer {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
await this.validateVercelConfig(vercelConfig);
|
await this.validateVercelConfig(vercelConfig);
|
||||||
|
|
||||||
|
this.projectSettings = {
|
||||||
|
...this.originalProjectSettings,
|
||||||
|
...pickOverrides(vercelConfig),
|
||||||
|
};
|
||||||
|
|
||||||
const { error: routeError, routes: maybeRoutes } =
|
const { error: routeError, routes: maybeRoutes } =
|
||||||
getTransformedRoutes(vercelConfig);
|
getTransformedRoutes(vercelConfig);
|
||||||
if (routeError) {
|
if (routeError) {
|
||||||
@@ -703,6 +728,11 @@ export default class DevServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.envConfigs = { buildEnv, runEnv, allEnv };
|
this.envConfigs = { buildEnv, runEnv, allEnv };
|
||||||
|
|
||||||
|
// If the `devCommand` was modified via project settings
|
||||||
|
// overrides then the dev process needs to be restarted
|
||||||
|
await this.runDevCommand();
|
||||||
|
|
||||||
return vercelConfig;
|
return vercelConfig;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1856,7 +1886,9 @@ export default class DevServer {
|
|||||||
devCacheDir,
|
devCacheDir,
|
||||||
env: {
|
env: {
|
||||||
...envConfigs.runEnv,
|
...envConfigs.runEnv,
|
||||||
VERCEL_BUILDER_DEBUG: this.output.debugEnabled ? '1' : undefined,
|
VERCEL_DEBUG_PREFIX: this.output.debugEnabled
|
||||||
|
? '[builder]'
|
||||||
|
: undefined,
|
||||||
},
|
},
|
||||||
buildEnv: { ...envConfigs.buildEnv },
|
buildEnv: { ...envConfigs.buildEnv },
|
||||||
},
|
},
|
||||||
@@ -2203,10 +2235,21 @@ export default class DevServer {
|
|||||||
async runDevCommand() {
|
async runDevCommand() {
|
||||||
const { devCommand, cwd } = this;
|
const { devCommand, cwd } = this;
|
||||||
|
|
||||||
|
if (devCommand === this.currentDevCommand) {
|
||||||
|
// `devCommand` has not changed, so don't restart frontend dev process
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.currentDevCommand = devCommand;
|
||||||
|
|
||||||
if (!devCommand) {
|
if (!devCommand) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.devProcess) {
|
||||||
|
await treeKill(this.devProcess.pid);
|
||||||
|
}
|
||||||
|
|
||||||
this.output.log(
|
this.output.log(
|
||||||
`Running Dev Command ${chalk.cyan.bold(`“${devCommand}”`)}`
|
`Running Dev Command ${chalk.cyan.bold(`“${devCommand}”`)}`
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ export { VercelConfig };
|
|||||||
|
|
||||||
export interface DevServerOptions {
|
export interface DevServerOptions {
|
||||||
output: Output;
|
output: Output;
|
||||||
devCommand?: string;
|
|
||||||
projectSettings?: ProjectSettings;
|
projectSettings?: ProjectSettings;
|
||||||
systemEnvValues?: string[];
|
systemEnvValues?: string[];
|
||||||
projectEnvs?: ProjectEnvVariable[];
|
projectEnvs?: ProjectEnvVariable[];
|
||||||
|
|||||||
@@ -426,7 +426,7 @@ export class UserAborted extends NowError<'USER_ABORTED', {}> {
|
|||||||
super({
|
super({
|
||||||
code: 'USER_ABORTED',
|
code: 'USER_ABORTED',
|
||||||
meta: {},
|
meta: {},
|
||||||
message: `The user aborted the operation.`,
|
message: `The user canceled the operation.`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,9 +58,9 @@ export async function connectGitProvider(
|
|||||||
(err.action === 'Install GitHub App' || err.code === 'repo_not_found')
|
(err.action === 'Install GitHub App' || err.code === 'repo_not_found')
|
||||||
) {
|
) {
|
||||||
client.output.error(
|
client.output.error(
|
||||||
`Failed to link ${chalk.cyan(
|
`Failed to connect ${chalk.cyan(
|
||||||
repo
|
repo
|
||||||
)}. Make sure there aren't any typos and that you have access to the repository if it's private.`
|
)} to project. Make sure there aren't any typos and that you have access to the repository if it's private.`
|
||||||
);
|
);
|
||||||
} else if (apiError && err.action === 'Add a Login Connection') {
|
} else if (apiError && err.action === 'Add a Login Connection') {
|
||||||
client.output.error(
|
client.output.error(
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ export default function handleError(error: unknown, { debug = false } = {}) {
|
|||||||
} else if (status === 500) {
|
} else if (status === 500) {
|
||||||
console.error(errorOutput('Unexpected server error. Please retry.'));
|
console.error(errorOutput('Unexpected server error. Please retry.'));
|
||||||
} else if (code === 'USER_ABORT') {
|
} else if (code === 'USER_ABORT') {
|
||||||
info('Aborted');
|
info('Canceled');
|
||||||
} else {
|
} else {
|
||||||
console.error(
|
console.error(
|
||||||
errorOutput(`Unexpected error. Please try again later. (${message})`)
|
errorOutput(`Unexpected error. Please try again later. (${message})`)
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ interface ListOptions {
|
|||||||
choices: ListChoice[];
|
choices: ListChoice[];
|
||||||
pageSize?: number;
|
pageSize?: number;
|
||||||
separator?: boolean;
|
separator?: boolean;
|
||||||
abort?: 'start' | 'end';
|
cancel?: 'start' | 'end';
|
||||||
eraseFinalAnswer?: boolean;
|
eraseFinalAnswer?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@ export default async function list(
|
|||||||
],
|
],
|
||||||
pageSize = 15, // Show 15 lines without scrolling (~4 credit cards)
|
pageSize = 15, // Show 15 lines without scrolling (~4 credit cards)
|
||||||
separator = false, // Puts a blank separator between each choice
|
separator = false, // Puts a blank separator between each choice
|
||||||
abort = 'end', // Whether the `abort` option will be at the `start` or the `end`,
|
cancel = 'end', // Whether the `cancel` option will be at the `start` or the `end`,
|
||||||
eraseFinalAnswer = false, // If true, the line with the final answer that inquirer prints will be erased before returning
|
eraseFinalAnswer = false, // If true, the line with the final answer that inquirer prints will be erased before returning
|
||||||
}: ListOptions
|
}: ListOptions
|
||||||
): Promise<string> {
|
): Promise<string> {
|
||||||
@@ -97,17 +97,17 @@ export default async function list(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const abortSeparator = new inquirer.Separator('─'.repeat(biggestLength));
|
const cancelSeparator = new inquirer.Separator('─'.repeat(biggestLength));
|
||||||
const _abort = {
|
const _cancel = {
|
||||||
name: 'Abort',
|
name: 'Cancel',
|
||||||
value: '',
|
value: '',
|
||||||
short: '',
|
short: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
if (abort === 'start') {
|
if (cancel === 'start') {
|
||||||
choices.unshift(_abort, abortSeparator);
|
choices.unshift(_cancel, cancelSeparator);
|
||||||
} else {
|
} else {
|
||||||
choices.push(abortSeparator, _abort);
|
choices.push(cancelSeparator, _cancel);
|
||||||
}
|
}
|
||||||
|
|
||||||
const answer = await client.prompt({
|
const answer = await client.prompt({
|
||||||
|
|||||||
@@ -1,107 +0,0 @@
|
|||||||
import { Dictionary } from '@vercel/client';
|
|
||||||
import { parseRepoUrl } from '../git/connect-git-provider';
|
|
||||||
import Client from '../client';
|
|
||||||
import { Org, Project, ProjectSettings } from '../../types';
|
|
||||||
import { handleOptions } from './handle-options';
|
|
||||||
import {
|
|
||||||
promptGitConnectMultipleUrls,
|
|
||||||
promptGitConnectSingleUrl,
|
|
||||||
} from './git-connect-prompts';
|
|
||||||
|
|
||||||
function getProjectSettings(project: Project): ProjectSettings {
|
|
||||||
return {
|
|
||||||
createdAt: project.createdAt,
|
|
||||||
framework: project.framework,
|
|
||||||
devCommand: project.devCommand,
|
|
||||||
installCommand: project.installCommand,
|
|
||||||
buildCommand: project.buildCommand,
|
|
||||||
outputDirectory: project.outputDirectory,
|
|
||||||
rootDirectory: project.rootDirectory,
|
|
||||||
directoryListing: project.directoryListing,
|
|
||||||
nodeVersion: project.nodeVersion,
|
|
||||||
skipGitConnectDuringLink: project.skipGitConnectDuringLink,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function addGitConnection(
|
|
||||||
client: Client,
|
|
||||||
org: Org,
|
|
||||||
project: Project,
|
|
||||||
remoteUrls: Dictionary<string>,
|
|
||||||
settings?: ProjectSettings
|
|
||||||
): Promise<number | void> {
|
|
||||||
if (!settings) {
|
|
||||||
settings = getProjectSettings(project);
|
|
||||||
}
|
|
||||||
if (Object.keys(remoteUrls).length === 1) {
|
|
||||||
return addSingleGitRemote(
|
|
||||||
client,
|
|
||||||
org,
|
|
||||||
project,
|
|
||||||
remoteUrls,
|
|
||||||
settings || project
|
|
||||||
);
|
|
||||||
} else if (Object.keys(remoteUrls).length > 1 && !project.link) {
|
|
||||||
return addMultipleGitRemotes(
|
|
||||||
client,
|
|
||||||
org,
|
|
||||||
project,
|
|
||||||
remoteUrls,
|
|
||||||
settings || project
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function addSingleGitRemote(
|
|
||||||
client: Client,
|
|
||||||
org: Org,
|
|
||||||
project: Project,
|
|
||||||
remoteUrls: Dictionary<string>,
|
|
||||||
settings: ProjectSettings
|
|
||||||
) {
|
|
||||||
const [remoteName, remoteUrl] = Object.entries(remoteUrls)[0];
|
|
||||||
const repoInfo = parseRepoUrl(remoteUrl);
|
|
||||||
if (!repoInfo) {
|
|
||||||
client.output.debug(`Could not parse repo url ${repoInfo}.`);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
const { org: parsedOrg, repo, provider } = repoInfo;
|
|
||||||
const alreadyLinked =
|
|
||||||
project.link &&
|
|
||||||
project.link.org === parsedOrg &&
|
|
||||||
project.link.repo === repo &&
|
|
||||||
project.link.type === provider;
|
|
||||||
if (alreadyLinked) {
|
|
||||||
client.output.debug('Project already linked. Skipping...');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const replace =
|
|
||||||
project.link &&
|
|
||||||
(project.link.org !== parsedOrg ||
|
|
||||||
project.link.repo !== repo ||
|
|
||||||
project.link.type !== provider);
|
|
||||||
const shouldConnect = await promptGitConnectSingleUrl(
|
|
||||||
client,
|
|
||||||
project,
|
|
||||||
remoteName,
|
|
||||||
remoteUrl,
|
|
||||||
replace
|
|
||||||
);
|
|
||||||
return handleOptions(shouldConnect, client, org, project, settings, repoInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function addMultipleGitRemotes(
|
|
||||||
client: Client,
|
|
||||||
org: Org,
|
|
||||||
project: Project,
|
|
||||||
remoteUrls: Dictionary<string>,
|
|
||||||
settings: ProjectSettings
|
|
||||||
) {
|
|
||||||
client.output.log('Found multiple Git remote URLs in Git config.');
|
|
||||||
const remoteUrlOrOptions = await promptGitConnectMultipleUrls(
|
|
||||||
client,
|
|
||||||
remoteUrls
|
|
||||||
);
|
|
||||||
return handleOptions(remoteUrlOrOptions, client, org, project, settings);
|
|
||||||
}
|
|
||||||
@@ -1,86 +0,0 @@
|
|||||||
import { Dictionary } from '@vercel/client';
|
|
||||||
import chalk from 'chalk';
|
|
||||||
import { Project } from '../../types';
|
|
||||||
import Client from '../client';
|
|
||||||
import { formatProvider } from '../git/connect-git-provider';
|
|
||||||
import list from '../input/list';
|
|
||||||
export async function promptGitConnectSingleUrl(
|
|
||||||
client: Client,
|
|
||||||
project: Project,
|
|
||||||
remoteName: string,
|
|
||||||
remoteUrl: string,
|
|
||||||
hasDiffConnectedProvider = false
|
|
||||||
) {
|
|
||||||
const { output } = client;
|
|
||||||
if (hasDiffConnectedProvider) {
|
|
||||||
const currentRepoPath = `${project.link!.org}/${project.link!.repo}`;
|
|
||||||
const currentProvider = project.link!.type;
|
|
||||||
output.print('\n');
|
|
||||||
output.log(
|
|
||||||
`Found Git remote URL ${chalk.cyan(
|
|
||||||
remoteUrl
|
|
||||||
)}, which is different from the connected ${formatProvider(
|
|
||||||
currentProvider
|
|
||||||
)} repository ${chalk.cyan(currentRepoPath)}.`
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
output.print('\n');
|
|
||||||
output.log(
|
|
||||||
`Found local Git remote "${remoteName}": ${chalk.cyan(remoteUrl)}`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return await list(client, {
|
|
||||||
message: hasDiffConnectedProvider
|
|
||||||
? 'Do you want to replace it?'
|
|
||||||
: `Do you want to connect "${remoteName}" to your Vercel project?`,
|
|
||||||
choices: [
|
|
||||||
{
|
|
||||||
name: 'Yes',
|
|
||||||
value: 'yes',
|
|
||||||
short: 'yes',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'No',
|
|
||||||
value: 'no',
|
|
||||||
short: 'no',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Do not ask again for this project',
|
|
||||||
value: 'opt-out',
|
|
||||||
short: 'no (opt out)',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function promptGitConnectMultipleUrls(
|
|
||||||
client: Client,
|
|
||||||
remoteUrls: Dictionary<string>
|
|
||||||
) {
|
|
||||||
const staticOptions = [
|
|
||||||
{
|
|
||||||
name: 'No',
|
|
||||||
value: 'no',
|
|
||||||
short: 'no',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Do not ask again for this project',
|
|
||||||
value: 'opt-out',
|
|
||||||
short: 'no (opt out)',
|
|
||||||
},
|
|
||||||
];
|
|
||||||
let choices = [];
|
|
||||||
for (const url of Object.values(remoteUrls)) {
|
|
||||||
choices.push({
|
|
||||||
name: url,
|
|
||||||
value: url,
|
|
||||||
short: url,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
choices = choices.concat(staticOptions);
|
|
||||||
|
|
||||||
return await list(client, {
|
|
||||||
message: 'Do you want to connect a Git repository to your Vercel project?',
|
|
||||||
choices,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -1,98 +0,0 @@
|
|||||||
import chalk from 'chalk';
|
|
||||||
import { Org, Project, ProjectSettings } from '../../types';
|
|
||||||
import Client from '../client';
|
|
||||||
import {
|
|
||||||
connectGitProvider,
|
|
||||||
disconnectGitProvider,
|
|
||||||
formatProvider,
|
|
||||||
RepoInfo,
|
|
||||||
parseRepoUrl,
|
|
||||||
} from '../git/connect-git-provider';
|
|
||||||
import { Output } from '../output';
|
|
||||||
import { getCommandName } from '../pkg-name';
|
|
||||||
import updateProject from '../projects/update-project';
|
|
||||||
|
|
||||||
export async function handleOptions(
|
|
||||||
option: string,
|
|
||||||
client: Client,
|
|
||||||
org: Org,
|
|
||||||
project: Project,
|
|
||||||
settings: ProjectSettings,
|
|
||||||
repoInfo?: RepoInfo
|
|
||||||
) {
|
|
||||||
const { output } = client;
|
|
||||||
if (option === 'no') {
|
|
||||||
skip(output);
|
|
||||||
return;
|
|
||||||
} else if (option === 'opt-out') {
|
|
||||||
optOut(client, project, settings);
|
|
||||||
return;
|
|
||||||
} else if (option !== '') {
|
|
||||||
// Option is "yes" or a URL
|
|
||||||
|
|
||||||
// Ensure parsed url exists
|
|
||||||
if (!repoInfo) {
|
|
||||||
const _repoInfo = parseRepoUrl(option);
|
|
||||||
if (!_repoInfo) {
|
|
||||||
output.debug(`Could not parse repo url ${option}.`);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
repoInfo = _repoInfo;
|
|
||||||
}
|
|
||||||
return connect(client, org, project, repoInfo);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function optOut(
|
|
||||||
client: Client,
|
|
||||||
project: Project,
|
|
||||||
settings: ProjectSettings
|
|
||||||
) {
|
|
||||||
settings.skipGitConnectDuringLink = true;
|
|
||||||
await updateProject(client, project.name, settings);
|
|
||||||
client.output
|
|
||||||
.log(`Opted out. You can re-enable this prompt by visiting the Settings > Git page on the
|
|
||||||
dashboard for this Project.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
function skip(output: Output) {
|
|
||||||
output.log('Skipping...');
|
|
||||||
output.log(
|
|
||||||
`You can connect a Git repository in the future by running ${getCommandName(
|
|
||||||
'git connect'
|
|
||||||
)}.`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function connect(
|
|
||||||
client: Client,
|
|
||||||
org: Org,
|
|
||||||
project: Project,
|
|
||||||
repoInfo: RepoInfo
|
|
||||||
): Promise<number | void> {
|
|
||||||
const { output } = client;
|
|
||||||
const { provider, org: parsedOrg, repo } = repoInfo;
|
|
||||||
const repoPath = `${parsedOrg}/${repo}`;
|
|
||||||
|
|
||||||
output.log('Connecting...');
|
|
||||||
|
|
||||||
if (project.link) {
|
|
||||||
await disconnectGitProvider(client, org, project.id);
|
|
||||||
}
|
|
||||||
const connect = await connectGitProvider(
|
|
||||||
client,
|
|
||||||
org,
|
|
||||||
project.id,
|
|
||||||
provider,
|
|
||||||
repoPath
|
|
||||||
);
|
|
||||||
if (connect !== 1) {
|
|
||||||
output.log(
|
|
||||||
`Connected ${formatProvider(provider)} repository ${chalk.cyan(
|
|
||||||
repoPath
|
|
||||||
)}!`
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
return connect;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -28,8 +28,6 @@ import { EmojiLabel } from '../emoji';
|
|||||||
import createDeploy from '../deploy/create-deploy';
|
import createDeploy from '../deploy/create-deploy';
|
||||||
import Now, { CreateOptions } from '../index';
|
import Now, { CreateOptions } from '../index';
|
||||||
import { isAPIError } from '../errors-ts';
|
import { isAPIError } from '../errors-ts';
|
||||||
import { getRemoteUrls } from '../create-git-meta';
|
|
||||||
import { addGitConnection } from './add-git-connection';
|
|
||||||
|
|
||||||
export interface SetupAndLinkOptions {
|
export interface SetupAndLinkOptions {
|
||||||
forceDelete?: boolean;
|
forceDelete?: boolean;
|
||||||
@@ -89,7 +87,7 @@ export default async function setupAndLink(
|
|||||||
));
|
));
|
||||||
|
|
||||||
if (!shouldStartSetup) {
|
if (!shouldStartSetup) {
|
||||||
output.print(`Aborted. Project not set up.\n`);
|
output.print(`Canceled. Project not set up.\n`);
|
||||||
return { status: 'not_linked', org: null, project: null };
|
return { status: 'not_linked', org: null, project: null };
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -130,19 +128,6 @@ export default async function setupAndLink(
|
|||||||
} else {
|
} else {
|
||||||
const project = projectOrNewProjectName;
|
const project = projectOrNewProjectName;
|
||||||
|
|
||||||
const remoteUrls = await getRemoteUrls(join(path, '.git/config'), output);
|
|
||||||
if (remoteUrls && !project.skipGitConnectDuringLink) {
|
|
||||||
const connectGit = await addGitConnection(
|
|
||||||
client,
|
|
||||||
org,
|
|
||||||
project,
|
|
||||||
remoteUrls
|
|
||||||
);
|
|
||||||
if (typeof connectGit === 'number') {
|
|
||||||
return { status: 'error', exitCode: connectGit };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await linkFolderToProject(
|
await linkFolderToProject(
|
||||||
output,
|
output,
|
||||||
path,
|
path,
|
||||||
@@ -257,20 +242,6 @@ export default async function setupAndLink(
|
|||||||
|
|
||||||
const project = await createProject(client, newProjectName);
|
const project = await createProject(client, newProjectName);
|
||||||
|
|
||||||
const remoteUrls = await getRemoteUrls(join(path, '.git/config'), output);
|
|
||||||
if (remoteUrls) {
|
|
||||||
const connectGit = await addGitConnection(
|
|
||||||
client,
|
|
||||||
org,
|
|
||||||
project,
|
|
||||||
remoteUrls,
|
|
||||||
settings
|
|
||||||
);
|
|
||||||
if (typeof connectGit === 'number') {
|
|
||||||
return { status: 'error', exitCode: connectGit };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
await updateProject(client, project.id, settings);
|
await updateProject(client, project.id, settings);
|
||||||
Object.assign(project, settings);
|
Object.assign(project, settings);
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ import { outputJSON } from 'fs-extra';
|
|||||||
import { Org, Project, ProjectLink } from '../../types';
|
import { Org, Project, ProjectLink } from '../../types';
|
||||||
import { getLinkFromDir, VERCEL_DIR, VERCEL_DIR_PROJECT } from './link';
|
import { getLinkFromDir, VERCEL_DIR, VERCEL_DIR_PROJECT } from './link';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
import { VercelConfig } from '@vercel/client';
|
||||||
|
import { PartialProjectSettings } from '../input/edit-project-settings';
|
||||||
|
|
||||||
export type ProjectLinkAndSettings = ProjectLink & {
|
export type ProjectLinkAndSettings = ProjectLink & {
|
||||||
settings: {
|
settings: {
|
||||||
@@ -51,3 +53,26 @@ export async function writeProjectSettings(
|
|||||||
export async function readProjectSettings(cwd: string) {
|
export async function readProjectSettings(cwd: string) {
|
||||||
return await getLinkFromDir<ProjectLinkAndSettings>(cwd);
|
return await getLinkFromDir<ProjectLinkAndSettings>(cwd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function pickOverrides(
|
||||||
|
vercelConfig: VercelConfig
|
||||||
|
): PartialProjectSettings {
|
||||||
|
const overrides: PartialProjectSettings = {};
|
||||||
|
for (const prop of [
|
||||||
|
'buildCommand',
|
||||||
|
'devCommand',
|
||||||
|
'framework',
|
||||||
|
'ignoreCommand',
|
||||||
|
'installCommand',
|
||||||
|
'outputDirectory',
|
||||||
|
] as const) {
|
||||||
|
if (typeof vercelConfig[prop] !== 'undefined') {
|
||||||
|
if (prop === 'ignoreCommand') {
|
||||||
|
overrides.commandForIgnoringBuildStep = vercelConfig[prop];
|
||||||
|
} else {
|
||||||
|
overrides[prop] = vercelConfig[prop];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return overrides;
|
||||||
|
}
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ export default async function validatePaths(
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (!shouldDeployHomeDirectory) {
|
if (!shouldDeployHomeDirectory) {
|
||||||
output.print(`Aborted\n`);
|
output.print(`Canceled\n`);
|
||||||
return { valid: false, exitCode: 0 };
|
return { valid: false, exitCode: 0 };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"devCommand": "next dev --port $PORT"
|
||||||
|
}
|
||||||
@@ -5,5 +5,6 @@
|
|||||||
"src": "/test",
|
"src": "/test",
|
||||||
"dest": "/?route-param=b"
|
"dest": "/?route-param=b"
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"devCommand": "next dev --port $PORT"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import mod from '../increment.wasm?module';
|
||||||
|
|
||||||
|
export const config = { runtime: 'experimental-edge' };
|
||||||
|
|
||||||
|
const init$ = WebAssembly.instantiate(mod);
|
||||||
|
|
||||||
|
/** @param {Request} req */
|
||||||
|
export default async req => {
|
||||||
|
const givenNumber = Number(new URL(req.url).searchParams.get('number') || 0);
|
||||||
|
const { exports } = await init$;
|
||||||
|
const added = exports.add_one(givenNumber);
|
||||||
|
return new Response(`${givenNumber} + 1 = ${added}`);
|
||||||
|
};
|
||||||
BIN
packages/cli/test/dev/fixtures/edge-function/increment.wasm
Executable file
BIN
packages/cli/test/dev/fixtures/edge-function/increment.wasm
Executable file
Binary file not shown.
@@ -0,0 +1 @@
|
|||||||
|
This is the original
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
This is the overridden!
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"build": "not used - required for zero-config"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"serve": "14.0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
{"devCommand":"serve -p $PORT original"}
|
||||||
@@ -0,0 +1,588 @@
|
|||||||
|
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
||||||
|
# yarn lockfile v1
|
||||||
|
|
||||||
|
|
||||||
|
"@zeit/schemas@2.21.0":
|
||||||
|
version "2.21.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@zeit/schemas/-/schemas-2.21.0.tgz#cd242c6551ffb51830049d68d9743ab65b45b820"
|
||||||
|
integrity sha512-/J4WBTpWtQ4itN1rb3ao8LfClmVcmz2pO6oYb7Qd4h7VSqUhIbJIvrykz9Ew1WMg6eFWsKdsMHc5uPbFxqlCpg==
|
||||||
|
|
||||||
|
accepts@~1.3.5:
|
||||||
|
version "1.3.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e"
|
||||||
|
integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==
|
||||||
|
dependencies:
|
||||||
|
mime-types "~2.1.34"
|
||||||
|
negotiator "0.6.3"
|
||||||
|
|
||||||
|
ajv@8.11.0:
|
||||||
|
version "8.11.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f"
|
||||||
|
integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==
|
||||||
|
dependencies:
|
||||||
|
fast-deep-equal "^3.1.1"
|
||||||
|
json-schema-traverse "^1.0.0"
|
||||||
|
require-from-string "^2.0.2"
|
||||||
|
uri-js "^4.2.2"
|
||||||
|
|
||||||
|
ansi-align@^3.0.1:
|
||||||
|
version "3.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59"
|
||||||
|
integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==
|
||||||
|
dependencies:
|
||||||
|
string-width "^4.1.0"
|
||||||
|
|
||||||
|
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-regex@^6.0.1:
|
||||||
|
version "6.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a"
|
||||||
|
integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==
|
||||||
|
|
||||||
|
ansi-styles@^4.1.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"
|
||||||
|
|
||||||
|
ansi-styles@^6.1.0:
|
||||||
|
version "6.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.1.0.tgz#87313c102b8118abd57371afab34618bf7350ed3"
|
||||||
|
integrity sha512-VbqNsoz55SYGczauuup0MFUyXNQviSpFTj1RQtFzmQLk18qbVSpTFFGMT293rmDaQuKCT6InmbuEyUne4mTuxQ==
|
||||||
|
|
||||||
|
arch@^2.2.0:
|
||||||
|
version "2.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11"
|
||||||
|
integrity sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ==
|
||||||
|
|
||||||
|
arg@5.0.2:
|
||||||
|
version "5.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c"
|
||||||
|
integrity sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==
|
||||||
|
|
||||||
|
balanced-match@^1.0.0:
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
|
||||||
|
integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==
|
||||||
|
|
||||||
|
boxen@7.0.0:
|
||||||
|
version "7.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/boxen/-/boxen-7.0.0.tgz#9e5f8c26e716793fc96edcf7cf754cdf5e3fbf32"
|
||||||
|
integrity sha512-j//dBVuyacJbvW+tvZ9HuH03fZ46QcaKvvhZickZqtB271DxJ7SNRSNxrV/dZX0085m7hISRZWbzWlJvx/rHSg==
|
||||||
|
dependencies:
|
||||||
|
ansi-align "^3.0.1"
|
||||||
|
camelcase "^7.0.0"
|
||||||
|
chalk "^5.0.1"
|
||||||
|
cli-boxes "^3.0.0"
|
||||||
|
string-width "^5.1.2"
|
||||||
|
type-fest "^2.13.0"
|
||||||
|
widest-line "^4.0.1"
|
||||||
|
wrap-ansi "^8.0.1"
|
||||||
|
|
||||||
|
brace-expansion@^1.1.7:
|
||||||
|
version "1.1.11"
|
||||||
|
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd"
|
||||||
|
integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
|
||||||
|
dependencies:
|
||||||
|
balanced-match "^1.0.0"
|
||||||
|
concat-map "0.0.1"
|
||||||
|
|
||||||
|
bytes@3.0.0:
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
|
||||||
|
integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw==
|
||||||
|
|
||||||
|
camelcase@^7.0.0:
|
||||||
|
version "7.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-7.0.0.tgz#fd112621b212126741f998d614cbc2a8623fd174"
|
||||||
|
integrity sha512-JToIvOmz6nhGsUhAYScbo2d6Py5wojjNfoxoc2mEVLUdJ70gJK2gnd+ABY1Tc3sVMyK7QDPtN0T/XdlCQWITyQ==
|
||||||
|
|
||||||
|
chalk-template@0.4.0:
|
||||||
|
version "0.4.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/chalk-template/-/chalk-template-0.4.0.tgz#692c034d0ed62436b9062c1707fadcd0f753204b"
|
||||||
|
integrity sha512-/ghrgmhfY8RaSdeo43hNXxpoHAtxdbskUHjPpfqUWGttFgycUhYPGx3YZBCnUCvOa7Doivn1IZec3DEGFoMgLg==
|
||||||
|
dependencies:
|
||||||
|
chalk "^4.1.2"
|
||||||
|
|
||||||
|
chalk@5.0.1, chalk@^5.0.1:
|
||||||
|
version "5.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/chalk/-/chalk-5.0.1.tgz#ca57d71e82bb534a296df63bbacc4a1c22b2a4b6"
|
||||||
|
integrity sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==
|
||||||
|
|
||||||
|
chalk@^4.1.2:
|
||||||
|
version "4.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
|
||||||
|
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
|
||||||
|
dependencies:
|
||||||
|
ansi-styles "^4.1.0"
|
||||||
|
supports-color "^7.1.0"
|
||||||
|
|
||||||
|
cli-boxes@^3.0.0:
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-3.0.0.tgz#71a10c716feeba005e4504f36329ef0b17cf3145"
|
||||||
|
integrity sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==
|
||||||
|
|
||||||
|
clipboardy@3.0.0:
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/clipboardy/-/clipboardy-3.0.0.tgz#f3876247404d334c9ed01b6f269c11d09a5e3092"
|
||||||
|
integrity sha512-Su+uU5sr1jkUy1sGRpLKjKrvEOVXgSgiSInwa/qeID6aJ07yh+5NWc3h2QfjHjBnfX4LhtFcuAWKUsJ3r+fjbg==
|
||||||
|
dependencies:
|
||||||
|
arch "^2.2.0"
|
||||||
|
execa "^5.1.1"
|
||||||
|
is-wsl "^2.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==
|
||||||
|
|
||||||
|
compressible@~2.0.16:
|
||||||
|
version "2.0.18"
|
||||||
|
resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba"
|
||||||
|
integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==
|
||||||
|
dependencies:
|
||||||
|
mime-db ">= 1.43.0 < 2"
|
||||||
|
|
||||||
|
compression@1.7.4:
|
||||||
|
version "1.7.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f"
|
||||||
|
integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==
|
||||||
|
dependencies:
|
||||||
|
accepts "~1.3.5"
|
||||||
|
bytes "3.0.0"
|
||||||
|
compressible "~2.0.16"
|
||||||
|
debug "2.6.9"
|
||||||
|
on-headers "~1.0.2"
|
||||||
|
safe-buffer "5.1.2"
|
||||||
|
vary "~1.1.2"
|
||||||
|
|
||||||
|
concat-map@0.0.1:
|
||||||
|
version "0.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
|
||||||
|
integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==
|
||||||
|
|
||||||
|
content-disposition@0.5.2:
|
||||||
|
version "0.5.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4"
|
||||||
|
integrity sha512-kRGRZw3bLlFISDBgwTSA1TMBFN6J6GWDeubmDE3AF+3+yXL8hTWv8r5rkLbqYXY4RjPk/EzHnClI3zQf1cFmHA==
|
||||||
|
|
||||||
|
cross-spawn@^7.0.3:
|
||||||
|
version "7.0.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
|
||||||
|
integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==
|
||||||
|
dependencies:
|
||||||
|
path-key "^3.1.0"
|
||||||
|
shebang-command "^2.0.0"
|
||||||
|
which "^2.0.1"
|
||||||
|
|
||||||
|
debug@2.6.9:
|
||||||
|
version "2.6.9"
|
||||||
|
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
|
||||||
|
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
|
||||||
|
dependencies:
|
||||||
|
ms "2.0.0"
|
||||||
|
|
||||||
|
deep-extend@^0.6.0:
|
||||||
|
version "0.6.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
|
||||||
|
integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==
|
||||||
|
|
||||||
|
eastasianwidth@^0.2.0:
|
||||||
|
version "0.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb"
|
||||||
|
integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==
|
||||||
|
|
||||||
|
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==
|
||||||
|
|
||||||
|
emoji-regex@^9.2.2:
|
||||||
|
version "9.2.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72"
|
||||||
|
integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==
|
||||||
|
|
||||||
|
execa@^5.1.1:
|
||||||
|
version "5.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd"
|
||||||
|
integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==
|
||||||
|
dependencies:
|
||||||
|
cross-spawn "^7.0.3"
|
||||||
|
get-stream "^6.0.0"
|
||||||
|
human-signals "^2.1.0"
|
||||||
|
is-stream "^2.0.0"
|
||||||
|
merge-stream "^2.0.0"
|
||||||
|
npm-run-path "^4.0.1"
|
||||||
|
onetime "^5.1.2"
|
||||||
|
signal-exit "^3.0.3"
|
||||||
|
strip-final-newline "^2.0.0"
|
||||||
|
|
||||||
|
fast-deep-equal@^3.1.1:
|
||||||
|
version "3.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
|
||||||
|
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
|
||||||
|
|
||||||
|
fast-url-parser@1.1.3:
|
||||||
|
version "1.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/fast-url-parser/-/fast-url-parser-1.1.3.tgz#f4af3ea9f34d8a271cf58ad2b3759f431f0b318d"
|
||||||
|
integrity sha512-5jOCVXADYNuRkKFzNJ0dCCewsZiYo0dz8QNYljkOpFC6r2U4OBmKtvm/Tsuh4w1YYdDqDb31a8TVhBJ2OJKdqQ==
|
||||||
|
dependencies:
|
||||||
|
punycode "^1.3.2"
|
||||||
|
|
||||||
|
get-stream@^6.0.0:
|
||||||
|
version "6.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7"
|
||||||
|
integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==
|
||||||
|
|
||||||
|
has-flag@^4.0.0:
|
||||||
|
version "4.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
|
||||||
|
integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
|
||||||
|
|
||||||
|
human-signals@^2.1.0:
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0"
|
||||||
|
integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==
|
||||||
|
|
||||||
|
ini@~1.3.0:
|
||||||
|
version "1.3.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c"
|
||||||
|
integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==
|
||||||
|
|
||||||
|
is-docker@^2.0.0:
|
||||||
|
version "2.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa"
|
||||||
|
integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==
|
||||||
|
|
||||||
|
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==
|
||||||
|
|
||||||
|
is-port-reachable@4.0.0:
|
||||||
|
version "4.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-port-reachable/-/is-port-reachable-4.0.0.tgz#dac044091ef15319c8ab2f34604d8794181f8c2d"
|
||||||
|
integrity sha512-9UoipoxYmSk6Xy7QFgRv2HDyaysmgSG75TFQs6S+3pDM7ZhKTF/bskZV+0UlABHzKjNVhPjYCLfeZUEg1wXxig==
|
||||||
|
|
||||||
|
is-stream@^2.0.0:
|
||||||
|
version "2.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077"
|
||||||
|
integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==
|
||||||
|
|
||||||
|
is-wsl@^2.2.0:
|
||||||
|
version "2.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271"
|
||||||
|
integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==
|
||||||
|
dependencies:
|
||||||
|
is-docker "^2.0.0"
|
||||||
|
|
||||||
|
isexe@^2.0.0:
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
|
||||||
|
integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==
|
||||||
|
|
||||||
|
json-schema-traverse@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2"
|
||||||
|
integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==
|
||||||
|
|
||||||
|
merge-stream@^2.0.0:
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60"
|
||||||
|
integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==
|
||||||
|
|
||||||
|
mime-db@1.52.0, "mime-db@>= 1.43.0 < 2":
|
||||||
|
version "1.52.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70"
|
||||||
|
integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==
|
||||||
|
|
||||||
|
mime-db@~1.33.0:
|
||||||
|
version "1.33.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db"
|
||||||
|
integrity sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==
|
||||||
|
|
||||||
|
mime-types@2.1.18:
|
||||||
|
version "2.1.18"
|
||||||
|
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8"
|
||||||
|
integrity sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==
|
||||||
|
dependencies:
|
||||||
|
mime-db "~1.33.0"
|
||||||
|
|
||||||
|
mime-types@~2.1.34:
|
||||||
|
version "2.1.35"
|
||||||
|
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a"
|
||||||
|
integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==
|
||||||
|
dependencies:
|
||||||
|
mime-db "1.52.0"
|
||||||
|
|
||||||
|
mimic-fn@^2.1.0:
|
||||||
|
version "2.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
|
||||||
|
integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
|
||||||
|
|
||||||
|
minimatch@3.0.4:
|
||||||
|
version "3.0.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
|
||||||
|
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
|
||||||
|
dependencies:
|
||||||
|
brace-expansion "^1.1.7"
|
||||||
|
|
||||||
|
minimist@^1.2.0:
|
||||||
|
version "1.2.6"
|
||||||
|
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44"
|
||||||
|
integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==
|
||||||
|
|
||||||
|
ms@2.0.0:
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
|
||||||
|
integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==
|
||||||
|
|
||||||
|
negotiator@0.6.3:
|
||||||
|
version "0.6.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd"
|
||||||
|
integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==
|
||||||
|
|
||||||
|
npm-run-path@^4.0.1:
|
||||||
|
version "4.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea"
|
||||||
|
integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==
|
||||||
|
dependencies:
|
||||||
|
path-key "^3.0.0"
|
||||||
|
|
||||||
|
on-headers@~1.0.2:
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f"
|
||||||
|
integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==
|
||||||
|
|
||||||
|
onetime@^5.1.2:
|
||||||
|
version "5.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e"
|
||||||
|
integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==
|
||||||
|
dependencies:
|
||||||
|
mimic-fn "^2.1.0"
|
||||||
|
|
||||||
|
path-is-inside@1.0.2:
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53"
|
||||||
|
integrity sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w==
|
||||||
|
|
||||||
|
path-key@^3.0.0, path-key@^3.1.0:
|
||||||
|
version "3.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375"
|
||||||
|
integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==
|
||||||
|
|
||||||
|
path-to-regexp@2.2.1:
|
||||||
|
version "2.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-2.2.1.tgz#90b617025a16381a879bc82a38d4e8bdeb2bcf45"
|
||||||
|
integrity sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==
|
||||||
|
|
||||||
|
punycode@^1.3.2:
|
||||||
|
version "1.4.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
|
||||||
|
integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==
|
||||||
|
|
||||||
|
punycode@^2.1.0:
|
||||||
|
version "2.1.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec"
|
||||||
|
integrity sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==
|
||||||
|
|
||||||
|
range-parser@1.2.0:
|
||||||
|
version "1.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e"
|
||||||
|
integrity sha512-kA5WQoNVo4t9lNx2kQNFCxKeBl5IbbSNBl1M/tLkw9WCn+hxNBAW5Qh8gdhs63CJnhjJ2zQWFoqPJP2sK1AV5A==
|
||||||
|
|
||||||
|
rc@^1.0.1, rc@^1.1.6:
|
||||||
|
version "1.2.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
|
||||||
|
integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==
|
||||||
|
dependencies:
|
||||||
|
deep-extend "^0.6.0"
|
||||||
|
ini "~1.3.0"
|
||||||
|
minimist "^1.2.0"
|
||||||
|
strip-json-comments "~2.0.1"
|
||||||
|
|
||||||
|
registry-auth-token@3.3.2:
|
||||||
|
version "3.3.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/registry-auth-token/-/registry-auth-token-3.3.2.tgz#851fd49038eecb586911115af845260eec983f20"
|
||||||
|
integrity sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==
|
||||||
|
dependencies:
|
||||||
|
rc "^1.1.6"
|
||||||
|
safe-buffer "^5.0.1"
|
||||||
|
|
||||||
|
registry-url@3.1.0:
|
||||||
|
version "3.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/registry-url/-/registry-url-3.1.0.tgz#3d4ef870f73dde1d77f0cf9a381432444e174942"
|
||||||
|
integrity sha512-ZbgR5aZEdf4UKZVBPYIgaglBmSF2Hi94s2PcIHhRGFjKYu+chjJdYfHn4rt3hB6eCKLJ8giVIIfgMa1ehDfZKA==
|
||||||
|
dependencies:
|
||||||
|
rc "^1.0.1"
|
||||||
|
|
||||||
|
require-from-string@^2.0.2:
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909"
|
||||||
|
integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==
|
||||||
|
|
||||||
|
safe-buffer@5.1.2:
|
||||||
|
version "5.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
|
||||||
|
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
|
||||||
|
|
||||||
|
safe-buffer@^5.0.1:
|
||||||
|
version "5.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
|
||||||
|
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
|
||||||
|
|
||||||
|
serve-handler@6.1.3:
|
||||||
|
version "6.1.3"
|
||||||
|
resolved "https://registry.yarnpkg.com/serve-handler/-/serve-handler-6.1.3.tgz#1bf8c5ae138712af55c758477533b9117f6435e8"
|
||||||
|
integrity sha512-FosMqFBNrLyeiIDvP1zgO6YoTzFYHxLDEIavhlmQ+knB2Z7l1t+kGLHkZIDN7UVWqQAmKI3D20A6F6jo3nDd4w==
|
||||||
|
dependencies:
|
||||||
|
bytes "3.0.0"
|
||||||
|
content-disposition "0.5.2"
|
||||||
|
fast-url-parser "1.1.3"
|
||||||
|
mime-types "2.1.18"
|
||||||
|
minimatch "3.0.4"
|
||||||
|
path-is-inside "1.0.2"
|
||||||
|
path-to-regexp "2.2.1"
|
||||||
|
range-parser "1.2.0"
|
||||||
|
|
||||||
|
serve@14.0.1:
|
||||||
|
version "14.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/serve/-/serve-14.0.1.tgz#5b6ffc17e18e1a8e963cc392958d7df13e1ef9fd"
|
||||||
|
integrity sha512-tNGwxl27FwA8TbmMQqN0jTaSx8/trL532qZsJHX1VdiEIjjtMJHCs7AFS6OvtC7cTHOvmjXqt5yczejU6CV2Xg==
|
||||||
|
dependencies:
|
||||||
|
"@zeit/schemas" "2.21.0"
|
||||||
|
ajv "8.11.0"
|
||||||
|
arg "5.0.2"
|
||||||
|
boxen "7.0.0"
|
||||||
|
chalk "5.0.1"
|
||||||
|
chalk-template "0.4.0"
|
||||||
|
clipboardy "3.0.0"
|
||||||
|
compression "1.7.4"
|
||||||
|
is-port-reachable "4.0.0"
|
||||||
|
serve-handler "6.1.3"
|
||||||
|
update-check "1.5.4"
|
||||||
|
|
||||||
|
shebang-command@^2.0.0:
|
||||||
|
version "2.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea"
|
||||||
|
integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==
|
||||||
|
dependencies:
|
||||||
|
shebang-regex "^3.0.0"
|
||||||
|
|
||||||
|
shebang-regex@^3.0.0:
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
|
||||||
|
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
|
||||||
|
|
||||||
|
signal-exit@^3.0.3:
|
||||||
|
version "3.0.7"
|
||||||
|
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9"
|
||||||
|
integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==
|
||||||
|
|
||||||
|
string-width@^4.1.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@^5.0.1, string-width@^5.1.2:
|
||||||
|
version "5.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794"
|
||||||
|
integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==
|
||||||
|
dependencies:
|
||||||
|
eastasianwidth "^0.2.0"
|
||||||
|
emoji-regex "^9.2.2"
|
||||||
|
strip-ansi "^7.0.1"
|
||||||
|
|
||||||
|
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-ansi@^7.0.1:
|
||||||
|
version "7.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.0.1.tgz#61740a08ce36b61e50e65653f07060d000975fb2"
|
||||||
|
integrity sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==
|
||||||
|
dependencies:
|
||||||
|
ansi-regex "^6.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==
|
||||||
|
|
||||||
|
strip-json-comments@~2.0.1:
|
||||||
|
version "2.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a"
|
||||||
|
integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==
|
||||||
|
|
||||||
|
supports-color@^7.1.0:
|
||||||
|
version "7.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
|
||||||
|
integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
|
||||||
|
dependencies:
|
||||||
|
has-flag "^4.0.0"
|
||||||
|
|
||||||
|
type-fest@^2.13.0:
|
||||||
|
version "2.19.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b"
|
||||||
|
integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==
|
||||||
|
|
||||||
|
update-check@1.5.4:
|
||||||
|
version "1.5.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/update-check/-/update-check-1.5.4.tgz#5b508e259558f1ad7dbc8b4b0457d4c9d28c8743"
|
||||||
|
integrity sha512-5YHsflzHP4t1G+8WGPlvKbJEbAJGCgw+Em+dGR1KmBUbr1J36SJBqlHLjR7oob7sco5hWHGQVcr9B2poIVDDTQ==
|
||||||
|
dependencies:
|
||||||
|
registry-auth-token "3.3.2"
|
||||||
|
registry-url "3.1.0"
|
||||||
|
|
||||||
|
uri-js@^4.2.2:
|
||||||
|
version "4.4.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e"
|
||||||
|
integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==
|
||||||
|
dependencies:
|
||||||
|
punycode "^2.1.0"
|
||||||
|
|
||||||
|
vary@~1.1.2:
|
||||||
|
version "1.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc"
|
||||||
|
integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==
|
||||||
|
|
||||||
|
which@^2.0.1:
|
||||||
|
version "2.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1"
|
||||||
|
integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==
|
||||||
|
dependencies:
|
||||||
|
isexe "^2.0.0"
|
||||||
|
|
||||||
|
widest-line@^4.0.1:
|
||||||
|
version "4.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-4.0.1.tgz#a0fc673aaba1ea6f0a0d35b3c2795c9a9cc2ebf2"
|
||||||
|
integrity sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==
|
||||||
|
dependencies:
|
||||||
|
string-width "^5.0.1"
|
||||||
|
|
||||||
|
wrap-ansi@^8.0.1:
|
||||||
|
version "8.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.0.1.tgz#2101e861777fec527d0ea90c57c6b03aac56a5b3"
|
||||||
|
integrity sha512-QFF+ufAqhoYHvoHdajT/Po7KoXVBPXS2bgjIam5isfWJPfIOnQZ50JtUiVvCv/sjgacf3yRrt2ZKUZ/V4itN4g==
|
||||||
|
dependencies:
|
||||||
|
ansi-styles "^6.1.0"
|
||||||
|
string-width "^5.0.1"
|
||||||
|
strip-ansi "^7.0.1"
|
||||||
@@ -53,6 +53,33 @@ test('[vercel dev] should support edge functions', async () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('[vercel dev] edge functions support WebAssembly files', async () => {
|
||||||
|
const dir = fixture('edge-function');
|
||||||
|
const { dev, port, readyResolver } = await testFixture(dir, {
|
||||||
|
env: {
|
||||||
|
ENV_VAR_IN_EDGE: '1',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
await readyResolver;
|
||||||
|
|
||||||
|
for (const { number, result } of [
|
||||||
|
{ number: 1, result: 2 },
|
||||||
|
{ number: 2, result: 3 },
|
||||||
|
{ number: 12, result: 13 },
|
||||||
|
]) {
|
||||||
|
let res = await fetch(
|
||||||
|
`http://localhost:${port}/api/webassembly?number=${number}`
|
||||||
|
);
|
||||||
|
validateResponseHeaders(res);
|
||||||
|
await expect(res.text()).resolves.toEqual(`${number} + 1 = ${result}`);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
await dev.kill('SIGTERM');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
test(
|
test(
|
||||||
'[vercel dev] edge functions respond properly the same as production',
|
'[vercel dev] edge functions respond properly the same as production',
|
||||||
testFixtureStdio('edge-function', async (testPath: any) => {
|
testFixtureStdio('edge-function', async (testPath: any) => {
|
||||||
@@ -422,11 +449,7 @@ test('[vercel dev] should maintain query when proxy passing', async () => {
|
|||||||
|
|
||||||
test('[vercel dev] should maintain query when dev server defines routes', async () => {
|
test('[vercel dev] should maintain query when dev server defines routes', async () => {
|
||||||
const dir = fixture('dev-server-query');
|
const dir = fixture('dev-server-query');
|
||||||
const { dev, port, readyResolver } = await testFixture(dir, {
|
const { dev, port, readyResolver } = await testFixture(dir);
|
||||||
env: {
|
|
||||||
VERCEL_DEV_COMMAND: 'next dev --port $PORT',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await readyResolver;
|
await readyResolver;
|
||||||
@@ -489,11 +512,7 @@ test('[vercel dev] should send `etag` header for static files', async () => {
|
|||||||
|
|
||||||
test('[vercel dev] should frontend dev server and routes', async () => {
|
test('[vercel dev] should frontend dev server and routes', async () => {
|
||||||
const dir = fixture('dev-server-and-routes');
|
const dir = fixture('dev-server-and-routes');
|
||||||
const { dev, port, readyResolver } = await testFixture(dir, {
|
const { dev, port, readyResolver } = await testFixture(dir);
|
||||||
env: {
|
|
||||||
VERCEL_DEV_COMMAND: 'next dev --port $PORT',
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await readyResolver;
|
await readyResolver;
|
||||||
|
|||||||
@@ -539,3 +539,40 @@ test(
|
|||||||
);
|
);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'[vercel dev] restarts dev process when `devCommand` setting is modified',
|
||||||
|
testFixtureStdio(
|
||||||
|
'project-settings-override',
|
||||||
|
async (_testPath: any, port: any) => {
|
||||||
|
const directory = fixture('project-settings-override');
|
||||||
|
const vercelJsonPath = join(directory, 'vercel.json');
|
||||||
|
const originalVercelJson = await fs.readJSON(vercelJsonPath);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const originalResponse = await fetch(
|
||||||
|
`http://localhost:${port}/index.txt`
|
||||||
|
);
|
||||||
|
validateResponseHeaders(originalResponse);
|
||||||
|
const body = await originalResponse.text();
|
||||||
|
expect(body.trim()).toEqual('This is the original');
|
||||||
|
expect(originalResponse.status).toBe(200);
|
||||||
|
|
||||||
|
await fs.writeJSON(vercelJsonPath, {
|
||||||
|
devCommand: 'serve -p $PORT overridden',
|
||||||
|
});
|
||||||
|
|
||||||
|
const overriddenResponse = await fetch(
|
||||||
|
`http://localhost:${port}/index.txt`
|
||||||
|
);
|
||||||
|
validateResponseHeaders(overriddenResponse);
|
||||||
|
const body2 = await overriddenResponse.text();
|
||||||
|
expect(body2.trim()).toEqual('This is the overridden!');
|
||||||
|
expect(overriddenResponse.status).toBe(200);
|
||||||
|
} finally {
|
||||||
|
await fs.writeJSON(vercelJsonPath, originalVercelJson);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ skipDeploy: true }
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|||||||
1
packages/cli/test/fixtures/unit/commands/build/project-settings-override/.gitignore
vendored
Normal file
1
packages/cli/test/fixtures/unit/commands/build/project-settings-override/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
output
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"orgId": ".",
|
||||||
|
"projectId": ".",
|
||||||
|
"settings": {
|
||||||
|
"buildCommand": "mkdir -p output && echo 2 > output/index.txt",
|
||||||
|
"outputDirectory": "output",
|
||||||
|
"framework": null
|
||||||
|
}
|
||||||
|
}
|
||||||
5
packages/cli/test/fixtures/unit/commands/build/project-settings-override/package.json
vendored
Normal file
5
packages/cli/test/fixtures/unit/commands/build/project-settings-override/package.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"scripts": {
|
||||||
|
"build": "mkdir -p output && echo 1 > output/index.txt"
|
||||||
|
}
|
||||||
|
}
|
||||||
3
packages/cli/test/fixtures/unit/commands/build/project-settings-override/vercel.json
vendored
Normal file
3
packages/cli/test/fixtures/unit/commands/build/project-settings-override/vercel.json
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"buildCommand": "mkdir -p output && echo 3 > output/index.txt"
|
||||||
|
}
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
!.vercel
|
|
||||||
.vercel
|
|
||||||
16
packages/cli/test/fixtures/unit/link-connect-git/multiple-remotes/git/config
generated
vendored
16
packages/cli/test/fixtures/unit/link-connect-git/multiple-remotes/git/config
generated
vendored
@@ -1,16 +0,0 @@
|
|||||||
[core]
|
|
||||||
repositoryformatversion = 0
|
|
||||||
filemode = true
|
|
||||||
bare = false
|
|
||||||
logallrefupdates = true
|
|
||||||
ignorecase = true
|
|
||||||
precomposeunicode = true
|
|
||||||
[remote "origin"]
|
|
||||||
url = https://github.com/user/repo.git
|
|
||||||
fetch = +refs/heads/*:refs/remotes/origin/*
|
|
||||||
[remote "secondary"]
|
|
||||||
url = https://github.com/user2/repo2.git
|
|
||||||
fetch = +refs/heads/*:refs/remotes/secondary/*
|
|
||||||
[remote "gitlab"]
|
|
||||||
url = https://gitlab.com/user/repo.git
|
|
||||||
fetch = +refs/heads/*:refs/remotes/gitlab/*
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
!.vercel
|
|
||||||
.vercel
|
|
||||||
13
packages/cli/test/fixtures/unit/link-connect-git/single-remote-existing-link/git/config
generated
vendored
13
packages/cli/test/fixtures/unit/link-connect-git/single-remote-existing-link/git/config
generated
vendored
@@ -1,13 +0,0 @@
|
|||||||
[core]
|
|
||||||
repositoryformatversion = 0
|
|
||||||
filemode = true
|
|
||||||
bare = false
|
|
||||||
logallrefupdates = true
|
|
||||||
ignorecase = true
|
|
||||||
precomposeunicode = true
|
|
||||||
[remote "origin"]
|
|
||||||
url = https://github.com/user2/repo2.git
|
|
||||||
fetch = +refs/heads/*:refs/remotes/origin/*
|
|
||||||
[branch "master"]
|
|
||||||
remote = origin
|
|
||||||
merge = refs/heads/master
|
|
||||||
@@ -1,2 +0,0 @@
|
|||||||
!.vercel
|
|
||||||
.vercel
|
|
||||||
13
packages/cli/test/fixtures/unit/link-connect-git/single-remote/git/config
generated
vendored
13
packages/cli/test/fixtures/unit/link-connect-git/single-remote/git/config
generated
vendored
@@ -1,13 +0,0 @@
|
|||||||
[core]
|
|
||||||
repositoryformatversion = 0
|
|
||||||
filemode = true
|
|
||||||
bare = false
|
|
||||||
logallrefupdates = true
|
|
||||||
ignorecase = true
|
|
||||||
precomposeunicode = true
|
|
||||||
[remote "origin"]
|
|
||||||
url = https://github.com/user/repo.git
|
|
||||||
fetch = +refs/heads/*:refs/remotes/origin/*
|
|
||||||
[branch "master"]
|
|
||||||
remote = origin
|
|
||||||
merge = refs/heads/master
|
|
||||||
@@ -76,25 +76,6 @@ module.exports = async function prepare(session, binaryPath, tmpFixturesDir) {
|
|||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
'build-env-debug': {
|
|
||||||
'now.json': JSON.stringify({
|
|
||||||
builds: [{ src: 'index.js', use: '@vercel/node' }],
|
|
||||||
}),
|
|
||||||
'package.json': JSON.stringify({
|
|
||||||
scripts: {
|
|
||||||
'now-build': 'node now-build.js',
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
'now-build.js': `
|
|
||||||
const fs = require('fs');
|
|
||||||
fs.writeFileSync(
|
|
||||||
'index.js',
|
|
||||||
fs.readFileSync('index.js', 'utf8')
|
|
||||||
.replace('BUILD_ENV_DEBUG', process.env.NOW_BUILDER_DEBUG ? 'on' : 'off'),
|
|
||||||
);
|
|
||||||
`,
|
|
||||||
'index.js': `module.exports = (req, res) => { res.status(200).send('BUILD_ENV_DEBUG'); }`,
|
|
||||||
},
|
|
||||||
'now-revert-alias-1': {
|
'now-revert-alias-1': {
|
||||||
'index.json': JSON.stringify({ name: 'now-revert-alias-1' }),
|
'index.json': JSON.stringify({ name: 'now-revert-alias-1' }),
|
||||||
'now.json': getRevertAliasConfigFile(),
|
'now.json': getRevertAliasConfigFile(),
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export function readOutputStream(
|
|||||||
let lines = 0;
|
let lines = 0;
|
||||||
const timeout = setTimeout(() => {
|
const timeout = setTimeout(() => {
|
||||||
reject(
|
reject(
|
||||||
new Error(`Was waiting for ${length} lines, but only received ${chunks.length}`)
|
new Error(`Was waiting for ${length} lines, but only received ${lines}`)
|
||||||
);
|
);
|
||||||
}, 3000);
|
}, 3000);
|
||||||
|
|
||||||
|
|||||||
41
packages/cli/test/integration.js
vendored
41
packages/cli/test/integration.js
vendored
@@ -1862,7 +1862,7 @@ test('ensure we render a prompt when deploying home directory', async t => {
|
|||||||
'You are deploying your home directory. Do you want to continue? [y/N]'
|
'You are deploying your home directory. Do you want to continue? [y/N]'
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
t.true(stderr.includes('Aborted'));
|
t.true(stderr.includes('Canceled'));
|
||||||
});
|
});
|
||||||
|
|
||||||
test('ensure the `scope` property works with email', async t => {
|
test('ensure the `scope` property works with email', async t => {
|
||||||
@@ -2170,45 +2170,6 @@ test('use build-env', async t => {
|
|||||||
t.is(content.trim(), 'bar');
|
t.is(content.trim(), 'bar');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('use `--debug` CLI flag', async t => {
|
|
||||||
const directory = fixture('build-env-debug');
|
|
||||||
|
|
||||||
const { stderr, stdout, exitCode } = await execa(
|
|
||||||
binaryPath,
|
|
||||||
[
|
|
||||||
directory,
|
|
||||||
'--public',
|
|
||||||
'--name',
|
|
||||||
session,
|
|
||||||
'--debug',
|
|
||||||
...defaultArgs,
|
|
||||||
'--yes',
|
|
||||||
],
|
|
||||||
{
|
|
||||||
reject: false,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
console.log(stderr);
|
|
||||||
console.log(stdout);
|
|
||||||
console.log(exitCode);
|
|
||||||
|
|
||||||
// Ensure the exit code is right
|
|
||||||
t.is(exitCode, 0, `Received:\n"${stderr}"\n"${stdout}"`);
|
|
||||||
|
|
||||||
// Test if the output is really a URL
|
|
||||||
const deploymentUrl = pickUrl(stdout);
|
|
||||||
const { href, host } = new URL(deploymentUrl);
|
|
||||||
t.is(host.split('-')[0], session);
|
|
||||||
|
|
||||||
await waitForDeployment(href);
|
|
||||||
|
|
||||||
// get the content
|
|
||||||
const response = await fetch(href);
|
|
||||||
const content = await response.text();
|
|
||||||
t.is(content.trim(), 'off');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('try to deploy non-existing path', async t => {
|
test('try to deploy non-existing path', async t => {
|
||||||
const goal = `Error! The specified file or directory "${session}" does not exist.`;
|
const goal = `Error! The specified file or directory "${session}" does not exist.`;
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ export function useDeployment({
|
|||||||
const deployment: Deployment = {
|
const deployment: Deployment = {
|
||||||
id,
|
id,
|
||||||
url: url.hostname,
|
url: url.hostname,
|
||||||
inspectorUrl: `https://vercel.com/team/project/${id.replace('dpl_', '')}`,
|
|
||||||
name,
|
name,
|
||||||
meta: {},
|
meta: {},
|
||||||
regions: [],
|
regions: [],
|
||||||
|
|||||||
@@ -894,6 +894,27 @@ describe('build', () => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should apply project settings overrides from "vercel.json"', async () => {
|
||||||
|
const cwd = fixture('project-settings-override');
|
||||||
|
const output = join(cwd, '.vercel/output');
|
||||||
|
try {
|
||||||
|
process.chdir(cwd);
|
||||||
|
const exitCode = await build(client);
|
||||||
|
expect(exitCode).toEqual(0);
|
||||||
|
|
||||||
|
// The `buildCommand` override in "vercel.json" outputs "3" to the
|
||||||
|
// index.txt file, so verify that that was produced in the build output
|
||||||
|
const contents = await fs.readFile(
|
||||||
|
join(output, 'static/index.txt'),
|
||||||
|
'utf8'
|
||||||
|
);
|
||||||
|
expect(contents.trim()).toEqual('3');
|
||||||
|
} finally {
|
||||||
|
process.chdir(originalCwd);
|
||||||
|
delete process.env.__VERCEL_BUILD_RUNNING;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
describe('should find packages with different main/module/browser keys', function () {
|
describe('should find packages with different main/module/browser keys', function () {
|
||||||
let output: string;
|
let output: string;
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user