mirror of
https://github.com/LukeHagar/vercel.git
synced 2026-01-01 04:09:15 +00:00
Compare commits
32 Commits
vercel@28.
...
@vercel/fr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9308a0fda5 | ||
|
|
c2f8a5990a | ||
|
|
fc2f0b919b | ||
|
|
a606ab8678 | ||
|
|
13062cd47d | ||
|
|
bb9faaed99 | ||
|
|
881e43a0e2 | ||
|
|
578a7742fe | ||
|
|
2d84a64430 | ||
|
|
200ac99647 | ||
|
|
1d3f2b5a62 | ||
|
|
8f49969585 | ||
|
|
cfbfaa7cd0 | ||
|
|
25747a7621 | ||
|
|
8d635beed7 | ||
|
|
6225f050fa | ||
|
|
30a899bab1 | ||
|
|
a010d8fe8a | ||
|
|
a9ff23fe22 | ||
|
|
b60d3f657a | ||
|
|
e7947a1b33 | ||
|
|
95a4dcfb33 | ||
|
|
124b747b0e | ||
|
|
a735527d8f | ||
|
|
d628880942 | ||
|
|
084125d90f | ||
|
|
2b483b0fd0 | ||
|
|
fdcd86d37c | ||
|
|
f5280cb375 | ||
|
|
26773daf05 | ||
|
|
8087b7804e | ||
|
|
c8690190f6 |
5
.github/workflows/cron-update-next.yml
vendored
5
.github/workflows/cron-update-next.yml
vendored
@@ -1,6 +1,8 @@
|
||||
name: Cron Update Next
|
||||
|
||||
on:
|
||||
# Allow manual runs
|
||||
workflow_dispatch:
|
||||
# Run every 4 hours https://crontab.guru/every-4-hours
|
||||
schedule:
|
||||
- cron: '0 */4 * * *'
|
||||
@@ -14,10 +16,13 @@ jobs:
|
||||
# 0 means fetch all commits so we can commit and push in the script below
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Enable corepack
|
||||
run: corepack enable pnpm
|
||||
- name: Create Pull Request
|
||||
uses: actions/github-script@v6
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.GH_TOKEN_PULL_REQUESTS }}
|
||||
# See https://github.com/actions/github-script#run-a-separate-file-with-an-async-function
|
||||
with:
|
||||
script: |
|
||||
|
||||
7
.github/workflows/cron-update-turbo.yml
vendored
7
.github/workflows/cron-update-turbo.yml
vendored
@@ -1,6 +1,8 @@
|
||||
name: Cron Update Turbo
|
||||
|
||||
on:
|
||||
# Allow manual runs
|
||||
workflow_dispatch:
|
||||
# Run every week https://crontab.guru/every-week
|
||||
schedule:
|
||||
- cron: '0 0 * * 0'
|
||||
@@ -14,12 +16,13 @@ jobs:
|
||||
# 0 means fetch all commits so we can commit and push in the script below
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: install pnpm@7.26.0
|
||||
run: npm i -g pnpm@7.26.0
|
||||
- name: Enable corepack
|
||||
run: corepack enable pnpm
|
||||
- name: Create Pull Request
|
||||
uses: actions/github-script@v6
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.GH_TOKEN_PULL_REQUESTS }}
|
||||
# See https://github.com/actions/github-script#run-a-separate-file-with-an-async-function
|
||||
with:
|
||||
script: |
|
||||
|
||||
2
.github/workflows/publish.yml
vendored
2
.github/workflows/publish.yml
vendored
@@ -40,7 +40,7 @@ jobs:
|
||||
if: ${{ steps.check-release.outputs.IS_RELEASE == 'true' }}
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 14
|
||||
node-version: 16
|
||||
- name: install pnpm@7.24.2
|
||||
run: npm i -g pnpm@7.24.2
|
||||
- name: Install
|
||||
|
||||
4
.github/workflows/test-integration-cli.yml
vendored
4
.github/workflows/test-integration-cli.yml
vendored
@@ -25,7 +25,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
node: [14]
|
||||
node: [16]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
@@ -41,7 +41,7 @@ jobs:
|
||||
run: npm i -g pnpm@7.24.2
|
||||
- run: pnpm install
|
||||
- run: pnpm run build
|
||||
- run: pnpm test-integration-cli
|
||||
- run: pnpm test-cli
|
||||
env:
|
||||
VERCEL_TEST_TOKEN: ${{ secrets.VERCEL_TEST_TOKEN }}
|
||||
VERCEL_TEST_REGISTRATION_URL: ${{ secrets.VERCEL_TEST_REGISTRATION_URL }}
|
||||
|
||||
2
.github/workflows/test-unit.yml
vendored
2
.github/workflows/test-unit.yml
vendored
@@ -25,7 +25,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||
node: [14]
|
||||
node: [16]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/setup-go@v3
|
||||
|
||||
2
.github/workflows/test.yml
vendored
2
.github/workflows/test.yml
vendored
@@ -9,7 +9,7 @@ on:
|
||||
pull_request:
|
||||
|
||||
env:
|
||||
NODE_VERSION: '14'
|
||||
NODE_VERSION: '16'
|
||||
TURBO_REMOTE_ONLY: 'true'
|
||||
TURBO_TEAM: 'vercel'
|
||||
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
||||
|
||||
@@ -11,4 +11,4 @@ Remove the `functions` config from your `now.json` or `vercel.json` to take adva
|
||||
|
||||
### Useful Links
|
||||
|
||||
- [Functions Config Documentation](https://vercel.com/docs/configuration?query=functions#project/functions)
|
||||
- [Functions Config Documentation](https://vercel.com/docs/concepts/projects/project-configuration#functions)
|
||||
|
||||
@@ -11,6 +11,6 @@ Migrate from using legacy `routes` to the new `rewrites`, `redirects`, and `head
|
||||
|
||||
### Useful Links
|
||||
|
||||
- [Rewrites Documentation](https://vercel.com/docs/configuration?query=rewrites#project/rewrites)
|
||||
- [Redirects Documentation](https://vercel.com/docs/configuration?query=rewrites#project/redirects)
|
||||
- [Headers Documentation](https://vercel.com/docs/configuration?query=rewrites#project/headers)
|
||||
- [Rewrites Documentation](https://vercel.com/docs/concepts/projects/project-configuration#rewrites)
|
||||
- [Redirects Documentation](https://vercel.com/docs/concepts/projects/project-configuration#redirects)
|
||||
- [Headers Documentation](https://vercel.com/docs/concepts/projects/project-configuration#headers)
|
||||
|
||||
@@ -2,15 +2,15 @@
|
||||
|
||||
#### Why This Error Occurred
|
||||
|
||||
This could be caused by a misconfigured "Build Command" or "Output Directory" for your Next.js project.
|
||||
This error is often caused by a misconfigured "Build Command" or "Output Directory" for your Next.js project.
|
||||
|
||||
#### Possible Ways to Fix It
|
||||
|
||||
In the Vercel dashboard, open your "Project Settings" and draw attention to "Build & Development Settings":
|
||||
|
||||
1. Ensure that the "Build Command" setting is not changed, or that it calls `next build`. If this command is not changed but you are seeing this error, double check that your `build` script in `package.json` calls `next build`.
|
||||
2. Ensure that the "Output Directory" setting is not changed. This value almost never needs to be configured, and is only necessary if you override `distDir` in `next.config.js`.
|
||||
3. For `next export` users: **do not override the "Output Directory"**. Next.js automatically detects what folder you outputted `next export` to.
|
||||
1. Ensure that the "Build Command" setting is not overridden, or that it calls `next build`. If this command is not overridden but you are seeing this error, double check that your `build` script in `package.json` calls `next build`. If `buildCommand` exists in `vercel.json`, make sure it calls `next build`.
|
||||
2. Ensure that the "Output Directory" setting is not overridden. This value almost never needs to be configured, and is only necessary if you override `distDir` in `next.config.js`. If `outputDirectory` exists in `vercel.json`, remove that property.
|
||||
3. For `next export` users: **do not override the "Output Directory"**, even if you customized the `next export` output directory. It will automatically detects the correct output.
|
||||
|
||||
In rare scenarios, this error message can also be caused by a Next.js build failure (if your "Build Command" accidentally returns an exit code that is not 0).
|
||||
Double check for any error messages above the Routes Manifest error, which may provide additional details.
|
||||
|
||||
5
examples/__tests__/integration/angular.test.ts
Normal file
5
examples/__tests__/integration/angular.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/astro.test.ts
Normal file
5
examples/__tests__/integration/astro.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/blitzjs.test.ts
Normal file
5
examples/__tests__/integration/blitzjs.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/brunch.test.ts
Normal file
5
examples/__tests__/integration/brunch.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/create-react-app.test.ts
Normal file
5
examples/__tests__/integration/create-react-app.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/docusaurus-2.test.ts
Normal file
5
examples/__tests__/integration/docusaurus-2.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/docusaurus.test.ts
Normal file
5
examples/__tests__/integration/docusaurus.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/dojo.test.ts
Normal file
5
examples/__tests__/integration/dojo.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/eleventy.test.ts
Normal file
5
examples/__tests__/integration/eleventy.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/ember.test.ts
Normal file
5
examples/__tests__/integration/ember.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/gatsby.test.ts
Normal file
5
examples/__tests__/integration/gatsby.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/gridsome.test.ts
Normal file
5
examples/__tests__/integration/gridsome.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/hexo.test.ts
Normal file
5
examples/__tests__/integration/hexo.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/hugo.test.ts
Normal file
5
examples/__tests__/integration/hugo.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/hydrogen.test.ts
Normal file
5
examples/__tests__/integration/hydrogen.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/ionic-angular.test.ts
Normal file
5
examples/__tests__/integration/ionic-angular.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/ionic-react.test.ts
Normal file
5
examples/__tests__/integration/ionic-react.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/jekyll.test.ts
Normal file
5
examples/__tests__/integration/jekyll.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/middleman.test.ts
Normal file
5
examples/__tests__/integration/middleman.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/nextjs.test.ts
Normal file
5
examples/__tests__/integration/nextjs.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/node_modules.test.ts
Normal file
5
examples/__tests__/integration/node_modules.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/nuxtjs.test.ts
Normal file
5
examples/__tests__/integration/nuxtjs.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/parcel.test.ts
Normal file
5
examples/__tests__/integration/parcel.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/polymer.test.ts
Normal file
5
examples/__tests__/integration/polymer.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/preact.test.ts
Normal file
5
examples/__tests__/integration/preact.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/redwoodjs.test.ts
Normal file
5
examples/__tests__/integration/redwoodjs.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/remix.test.ts
Normal file
5
examples/__tests__/integration/remix.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/saber.test.ts
Normal file
5
examples/__tests__/integration/saber.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/sanity.test.ts
Normal file
5
examples/__tests__/integration/sanity.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/sapper.test.ts
Normal file
5
examples/__tests__/integration/sapper.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/scully.test.ts
Normal file
5
examples/__tests__/integration/scully.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/solidstart.test.ts
Normal file
5
examples/__tests__/integration/solidstart.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/stencil.test.ts
Normal file
5
examples/__tests__/integration/stencil.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/svelte.test.ts
Normal file
5
examples/__tests__/integration/svelte.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/sveltekit-1.test.ts
Normal file
5
examples/__tests__/integration/sveltekit-1.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/sveltekit.test.ts
Normal file
5
examples/__tests__/integration/sveltekit.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/umijs.test.ts
Normal file
5
examples/__tests__/integration/umijs.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/vite.test.ts
Normal file
5
examples/__tests__/integration/vite.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/vitepress.test.ts
Normal file
5
examples/__tests__/integration/vitepress.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/vue.test.ts
Normal file
5
examples/__tests__/integration/vue.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/vuepress.test.ts
Normal file
5
examples/__tests__/integration/vuepress.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
5
examples/__tests__/integration/zola.test.ts
Normal file
5
examples/__tests__/integration/zola.test.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { deployExample } from '../test-utils';
|
||||
it('should deploy', async () => {
|
||||
await deployExample(__filename);
|
||||
});
|
||||
|
||||
27
examples/__tests__/test-utils.ts
Normal file
27
examples/__tests__/test-utils.ts
Normal file
@@ -0,0 +1,27 @@
|
||||
import { basename, join } from 'path';
|
||||
import { lstatSync, readdirSync } from 'fs';
|
||||
|
||||
export async function deployExample(filename: string) {
|
||||
const { testDeployment } = require('../../test/lib/deployment/test-deployment.js');
|
||||
const example = basename(filename).replace(/\.test\.ts$/, '');
|
||||
await testDeployment(join(filename, '..', '..', '..', example));
|
||||
}
|
||||
|
||||
export function getExamples() {
|
||||
const dirname = join(__dirname, '..');
|
||||
const examples = readdirSync(dirname)
|
||||
.map(example =>
|
||||
({
|
||||
exampleName: example,
|
||||
examplePath: join(dirname, example),
|
||||
testPath: join(dirname, '__tests__', 'integration', `${example}.test.ts`),
|
||||
})
|
||||
)
|
||||
.filter(o =>
|
||||
!o.exampleName.startsWith('.') &&
|
||||
!o.exampleName.startsWith('_') &&
|
||||
o.exampleName !== 'node_modules' &&
|
||||
lstatSync(o.examplePath).isDirectory()
|
||||
);
|
||||
return examples;
|
||||
}
|
||||
8
examples/__tests__/unit/index.test.ts
Normal file
8
examples/__tests__/unit/index.test.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
import { existsSync } from 'fs';
|
||||
import { getExamples } from '../test-utils';
|
||||
|
||||
describe('should have test for each example', () => {
|
||||
it.each(getExamples())('should exist $exampleName', async ({testPath}) => {
|
||||
expect(existsSync(testPath)).toBeTruthy();
|
||||
});
|
||||
});
|
||||
@@ -8,6 +8,9 @@
|
||||
"lint": "eslint --ignore-path .gitignore --ext .js,.ts,.tsx .",
|
||||
"test": "echo \"No tests yet\""
|
||||
},
|
||||
"engines": {
|
||||
"node": "16.x"
|
||||
},
|
||||
"browserslist": [
|
||||
"defaults"
|
||||
],
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
"test:functional": "dojo build --mode functional && dojo test --functional --config local",
|
||||
"test:all": "dojo build --mode unit && dojo build --mode functional && dojo test --all --config local"
|
||||
},
|
||||
"engines": {
|
||||
"node": "16.x"
|
||||
},
|
||||
"dependencies": {
|
||||
"@dojo/framework": "^6.0.0",
|
||||
"@dojo/themes": "^6.0.0",
|
||||
|
||||
@@ -18,6 +18,9 @@
|
||||
"url": "https://github.com/ionic-team/ionic-conference-app.git"
|
||||
},
|
||||
"private": true,
|
||||
"engines": {
|
||||
"node": "16.x"
|
||||
},
|
||||
"dependencies": {
|
||||
"@angular/common": "^8.2.14",
|
||||
"@angular/core": "^8.2.14",
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
"name": "ionic-react",
|
||||
"version": "0.0.1",
|
||||
"private": true,
|
||||
"engines": {
|
||||
"node": "16.x"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ionic/react": "^4.11.0",
|
||||
"@ionic/react-router": "^4.11.0",
|
||||
|
||||
7
examples/jest.config.js
vendored
Normal file
7
examples/jest.config.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
/** @type {import('@ts-jest/dist/types').InitialOptionsTsJest} */
|
||||
module.exports = {
|
||||
preset: 'ts-jest',
|
||||
testEnvironment: 'node',
|
||||
testMatch: ['<rootDir>/__tests__/**/*.test.ts'],
|
||||
testTimeout: 5 * 60 * 1000,
|
||||
};
|
||||
14
examples/package.json
vendored
Normal file
14
examples/package.json
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "examples",
|
||||
"description": "Each subdirectory is an example boilerplate for a framework. This package.json only exists for testing purposes.",
|
||||
"scripts": {
|
||||
"test-unit": "pnpm test __tests__/unit/",
|
||||
"test-e2e": "pnpm test __tests__/integration/",
|
||||
"test": "jest --env node --verbose --runInBand --bail"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "27.4.1",
|
||||
"@vercel/frameworks": "1.3.0"
|
||||
}
|
||||
}
|
||||
@@ -7,6 +7,9 @@
|
||||
"lint": "eslint src",
|
||||
"test": "jest"
|
||||
},
|
||||
"engines": {
|
||||
"node": "16.x"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": "preact",
|
||||
"ignorePatterns": [
|
||||
@@ -35,4 +38,4 @@
|
||||
"<rootDir>/tests/__mocks__/setupTests.js"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
"dev": "saber",
|
||||
"build": "saber build"
|
||||
},
|
||||
"engines": {
|
||||
"node": "16.x"
|
||||
},
|
||||
"devDependencies": {
|
||||
"saber": "latest",
|
||||
"saber-theme-minima": "latest",
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
{
|
||||
"name": "TODO",
|
||||
"description": "TODO",
|
||||
"version": "0.0.1",
|
||||
"name": "sapper",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"start": "sapper dev",
|
||||
"dev": "sapper dev --port $PORT",
|
||||
@@ -10,6 +9,9 @@
|
||||
"cy:open": "cypress open",
|
||||
"test": "run-p --race dev cy:run"
|
||||
},
|
||||
"engines": {
|
||||
"node": "16.x"
|
||||
},
|
||||
"dependencies": {
|
||||
"compression": "^1.7.1",
|
||||
"polka": "next",
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
"scully": "scully"
|
||||
},
|
||||
"private": true,
|
||||
"engines": {
|
||||
"node": "16.x"
|
||||
},
|
||||
"dependencies": {
|
||||
"@angular/animations": "~9.0.0-rc.7",
|
||||
"@angular/common": "~9.0.0-rc.7",
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
"format": "prettier --write ."
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sveltejs/adapter-auto": "next",
|
||||
"@sveltejs/kit": "1.0.0-next.589",
|
||||
"@sveltejs/adapter-auto": "1.0.0-next.65",
|
||||
"@sveltejs/kit": "1.0.0-next.428",
|
||||
"@types/cookie": "^0.5.1",
|
||||
"prettier": "^2.6.2",
|
||||
"prettier-plugin-svelte": "^2.7.0",
|
||||
|
||||
63
examples/sveltekit/pnpm-lock.yaml
generated
63
examples/sveltekit/pnpm-lock.yaml
generated
@@ -2,8 +2,8 @@ lockfileVersion: 5.4
|
||||
|
||||
specifiers:
|
||||
'@fontsource/fira-mono': ^4.5.0
|
||||
'@sveltejs/adapter-auto': next
|
||||
'@sveltejs/kit': next
|
||||
'@sveltejs/adapter-auto': 1.0.0-next.65
|
||||
'@sveltejs/kit': 1.0.0-next.428
|
||||
'@types/cookie': ^0.5.1
|
||||
cookie: ^0.4.1
|
||||
prettier: ^2.6.2
|
||||
@@ -32,8 +32,8 @@ devDependencies:
|
||||
|
||||
packages:
|
||||
|
||||
/@cloudflare/workers-types/3.14.1:
|
||||
resolution: {integrity: sha512-B1/plF62pt+H2IJHvApK8fdOJAVsvojvacuac8x8s+JIyqbropMyqNqHTKLm3YD8ZFLGwYeFTudU+PQ7vGvBdA==}
|
||||
/@cloudflare/workers-types/3.19.0:
|
||||
resolution: {integrity: sha512-0FRcsz7Ea3jT+gc5gKPIYciykm1bbAaTpygdzpCwGt0RL+V83zWnYN30NWDW4rIHj/FHtz+MIuBKS61C8l7AzQ==}
|
||||
dev: true
|
||||
|
||||
/@esbuild/linux-loong64/0.14.54:
|
||||
@@ -69,19 +69,19 @@ packages:
|
||||
'@jridgewell/sourcemap-codec': 1.4.14
|
||||
dev: true
|
||||
|
||||
/@mapbox/node-pre-gyp/1.0.9:
|
||||
resolution: {integrity: sha512-aDF3S3rK9Q2gey/WAttUlISduDItz5BU3306M9Eyv6/oS40aMprnopshtlKTykxRNIBEZuRMaZAnbrQ4QtKGyw==}
|
||||
/@mapbox/node-pre-gyp/1.0.10:
|
||||
resolution: {integrity: sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA==}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
detect-libc: 2.0.1
|
||||
https-proxy-agent: 5.0.1
|
||||
make-dir: 3.1.0
|
||||
node-fetch: 2.6.7
|
||||
node-fetch: 2.6.9
|
||||
nopt: 5.0.0
|
||||
npmlog: 5.0.1
|
||||
rimraf: 3.0.2
|
||||
semver: 7.3.7
|
||||
tar: 6.1.11
|
||||
semver: 7.3.8
|
||||
tar: 6.1.13
|
||||
transitivePeerDependencies:
|
||||
- encoding
|
||||
- supports-color
|
||||
@@ -134,7 +134,7 @@ packages:
|
||||
/@sveltejs/adapter-cloudflare/1.0.0-next.31:
|
||||
resolution: {integrity: sha512-HhEFZP72GJ8AZGgFECKIiayDcLaAWi65pI0AnBfiNhCifYSlH/mPNWNVD4AWRDnXnH6XU+FLwhGDnIDwytTyYg==}
|
||||
dependencies:
|
||||
'@cloudflare/workers-types': 3.14.1
|
||||
'@cloudflare/workers-types': 3.19.0
|
||||
esbuild: 0.14.54
|
||||
worktop: 0.8.0-next.14
|
||||
dev: true
|
||||
@@ -231,15 +231,15 @@ packages:
|
||||
resolution: {integrity: sha512-hFCAETfI5cG8l5iAiLhMC2bReC5K7SIybzrxGorv+eGspIbIFsVw7Vg85GovXm/LxA08pIDrAlrhR6GN36XB/Q==}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
'@mapbox/node-pre-gyp': 1.0.9
|
||||
acorn: 8.8.0
|
||||
'@mapbox/node-pre-gyp': 1.0.10
|
||||
acorn: 8.8.2
|
||||
async-sema: 3.1.1
|
||||
bindings: 1.5.0
|
||||
estree-walker: 2.0.2
|
||||
glob: 7.2.3
|
||||
graceful-fs: 4.2.10
|
||||
micromatch: 4.0.5
|
||||
node-gyp-build: 4.5.0
|
||||
node-gyp-build: 4.6.0
|
||||
resolve-from: 5.0.0
|
||||
rollup-pluginutils: 2.8.2
|
||||
transitivePeerDependencies:
|
||||
@@ -251,8 +251,8 @@ packages:
|
||||
resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==}
|
||||
dev: true
|
||||
|
||||
/acorn/8.8.0:
|
||||
resolution: {integrity: sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==}
|
||||
/acorn/8.8.2:
|
||||
resolution: {integrity: sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
hasBin: true
|
||||
dev: true
|
||||
@@ -688,7 +688,7 @@ packages:
|
||||
resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==}
|
||||
engines: {node: '>= 8'}
|
||||
dependencies:
|
||||
minipass: 3.3.4
|
||||
minipass: 3.3.6
|
||||
dev: true
|
||||
|
||||
/fs.realpath/1.0.0:
|
||||
@@ -893,18 +893,23 @@ packages:
|
||||
resolution: {integrity: sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==}
|
||||
dev: true
|
||||
|
||||
/minipass/3.3.4:
|
||||
resolution: {integrity: sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==}
|
||||
/minipass/3.3.6:
|
||||
resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==}
|
||||
engines: {node: '>=8'}
|
||||
dependencies:
|
||||
yallist: 4.0.0
|
||||
dev: true
|
||||
|
||||
/minipass/4.0.3:
|
||||
resolution: {integrity: sha512-OW2r4sQ0sI+z5ckEt5c1Tri4xTgZwYDxpE54eqWlQloQRoWtXjqt9udJ5Z4dSv7wK+nfFI7FRXyCpBSft+gpFw==}
|
||||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/minizlib/2.1.2:
|
||||
resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==}
|
||||
engines: {node: '>= 8'}
|
||||
dependencies:
|
||||
minipass: 3.3.4
|
||||
minipass: 3.3.6
|
||||
yallist: 4.0.0
|
||||
dev: true
|
||||
|
||||
@@ -946,8 +951,8 @@ packages:
|
||||
engines: {node: '>=10.5.0'}
|
||||
dev: true
|
||||
|
||||
/node-fetch/2.6.7:
|
||||
resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==}
|
||||
/node-fetch/2.6.9:
|
||||
resolution: {integrity: sha512-DJm/CJkZkRjKKj4Zi4BsKVZh3ValV5IR5s7LVZnW+6YMh0W1BfNA8XSs6DLMGYlId5F3KnA70uu2qepcR08Qqg==}
|
||||
engines: {node: 4.x || >=6.0.0}
|
||||
peerDependencies:
|
||||
encoding: ^0.1.0
|
||||
@@ -967,8 +972,8 @@ packages:
|
||||
formdata-polyfill: 4.0.10
|
||||
dev: true
|
||||
|
||||
/node-gyp-build/4.5.0:
|
||||
resolution: {integrity: sha512-2iGbaQBV+ITgCz76ZEjmhUKAKVf7xfY1sRl4UiKQspfZMH2h06SyhNsnSVy50cwkFQDGLyif6m/6uFXHkOZ6rg==}
|
||||
/node-gyp-build/4.6.0:
|
||||
resolution: {integrity: sha512-NTZVKn9IylLwUzaKjkas1e4u2DLNcV4rdYagA4PWdPwW87Bi7z+BznyKSRwS/761tV/lzCGXplWsiaMjLqP2zQ==}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
@@ -1163,8 +1168,8 @@ packages:
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/semver/7.3.7:
|
||||
resolution: {integrity: sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==}
|
||||
/semver/7.3.8:
|
||||
resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==}
|
||||
engines: {node: '>=10'}
|
||||
hasBin: true
|
||||
dependencies:
|
||||
@@ -1338,13 +1343,13 @@ packages:
|
||||
engines: {node: '>= 8'}
|
||||
dev: true
|
||||
|
||||
/tar/6.1.11:
|
||||
resolution: {integrity: sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==}
|
||||
engines: {node: '>= 10'}
|
||||
/tar/6.1.13:
|
||||
resolution: {integrity: sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==}
|
||||
engines: {node: '>=10'}
|
||||
dependencies:
|
||||
chownr: 2.0.0
|
||||
fs-minipass: 2.1.0
|
||||
minipass: 3.3.4
|
||||
minipass: 4.0.3
|
||||
minizlib: 2.1.2
|
||||
mkdirp: 1.0.4
|
||||
yallist: 4.0.0
|
||||
|
||||
7
examples/tsconfig.json
vendored
Normal file
7
examples/tsconfig.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"esModuleInterop": true,
|
||||
"target": "esnext",
|
||||
"module": "commonjs"
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,9 @@
|
||||
"build": "vue-cli-service build",
|
||||
"lint": "vue-cli-service lint"
|
||||
},
|
||||
"engines": {
|
||||
"node": "16.x"
|
||||
},
|
||||
"dependencies": {
|
||||
"core-js": "^3.6.5",
|
||||
"vue": "^3.0.0"
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
"source-map-support": "0.5.12",
|
||||
"ts-eager": "2.0.2",
|
||||
"ts-jest": "28.0.5",
|
||||
"turbo": "1.7.0"
|
||||
"turbo": "1.7.4"
|
||||
},
|
||||
"scripts": {
|
||||
"lerna": "lerna",
|
||||
@@ -47,9 +47,9 @@
|
||||
"pre-commit": "lint-staged",
|
||||
"test": "jest --rootDir=\"test\" --testPathPattern=\"\\.test.js\"",
|
||||
"test-unit": "pnpm test && node utils/gen.js && turbo run test-unit",
|
||||
"test-integration-cli": "node utils/gen.js && turbo run test-integration-cli",
|
||||
"test-integration-once": "node utils/gen.js && turbo run test-integration-once",
|
||||
"test-integration-dev": "node utils/gen.js && turbo run test-integration-dev",
|
||||
"test-cli": "node utils/gen.js && turbo run test-cli",
|
||||
"test-e2e": "node utils/gen.js && turbo run test-e2e",
|
||||
"test-dev": "node utils/gen.js && turbo run test-dev",
|
||||
"lint": "eslint . --cache --ext .ts,.js",
|
||||
"prepare": "husky install",
|
||||
"pack": "cd utils && node -r ts-eager/register ./pack.ts"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/build-utils",
|
||||
"version": "6.2.1",
|
||||
"version": "6.2.4",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.js",
|
||||
@@ -14,7 +14,7 @@
|
||||
"build": "node build",
|
||||
"test": "jest --env node --verbose --runInBand --bail",
|
||||
"test-unit": "pnpm test test/unit.*test.*",
|
||||
"test-integration-once": "pnpm test test/integration.test.ts"
|
||||
"test-e2e": "pnpm test test/integration.test.ts"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iarna/toml": "2.2.3",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Cron, Files } from './types';
|
||||
import type { Cron, Files, FunctionFramework } from './types';
|
||||
|
||||
/**
|
||||
* An Edge Functions output
|
||||
@@ -44,6 +44,9 @@ export class EdgeFunction {
|
||||
/** Cronjob definition for the edge function */
|
||||
cron?: Cron;
|
||||
|
||||
/** The framework */
|
||||
framework?: FunctionFramework;
|
||||
|
||||
constructor(params: Omit<EdgeFunction, 'type'>) {
|
||||
this.type = 'EdgeFunction';
|
||||
this.name = params.name;
|
||||
@@ -54,5 +57,6 @@ export class EdgeFunction {
|
||||
this.assets = params.assets;
|
||||
this.regions = params.regions;
|
||||
this.cron = params.cron;
|
||||
this.framework = params.framework;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,7 +44,8 @@ export function getPrettyError(obj: {
|
||||
message?: string;
|
||||
params: any;
|
||||
}): NowBuildError {
|
||||
const docsUrl = 'https://vercel.com/docs/configuration';
|
||||
const docsUrl =
|
||||
'https://vercel.com/docs/concepts/projects/project-configuration';
|
||||
try {
|
||||
const { dataPath, params, message: ajvMessage } = obj;
|
||||
const prop = getTopLevelPropertyName(dataPath);
|
||||
@@ -63,7 +64,7 @@ export function getPrettyError(obj: {
|
||||
return new NowBuildError({
|
||||
code: 'INVALID_VERCEL_CONFIG',
|
||||
message: message,
|
||||
link: prop ? `${docsUrl}#project/${prop.toLowerCase()}` : docsUrl,
|
||||
link: prop ? `${docsUrl}#${prop.toLowerCase()}` : docsUrl,
|
||||
action: 'View Documentation',
|
||||
});
|
||||
} catch (e) {
|
||||
|
||||
@@ -2,7 +2,7 @@ import path from 'path';
|
||||
import assert from 'assert';
|
||||
import vanillaGlob_ from 'glob';
|
||||
import { promisify } from 'util';
|
||||
import { lstat, Stats } from 'fs-extra';
|
||||
import { lstat, readlink, Stats } from 'fs-extra';
|
||||
import { normalizePath } from './normalize-path';
|
||||
import FileFsRef from '../file-fs-ref';
|
||||
|
||||
@@ -45,16 +45,33 @@ export default async function glob(
|
||||
const dirsWithEntries = new Set<string>();
|
||||
|
||||
for (const relativePath of files) {
|
||||
const fsPath = normalizePath(path.join(options.cwd, relativePath));
|
||||
const absPath = path.join(options.cwd, relativePath);
|
||||
const fsPath = normalizePath(absPath);
|
||||
|
||||
let stat = statCache[fsPath];
|
||||
assert(
|
||||
stat,
|
||||
`statCache does not contain value for ${relativePath} (resolved to ${fsPath})`
|
||||
);
|
||||
|
||||
const isSymlink = symlinks[fsPath];
|
||||
|
||||
// When `follow` mode is enabled, ensure that the entry is not a symlink
|
||||
// that points to outside of `cwd`
|
||||
if (
|
||||
options.follow &&
|
||||
(isSymlink || (await lstat(fsPath)).isSymbolicLink())
|
||||
) {
|
||||
const target = await readlink(absPath);
|
||||
const absTarget = path.resolve(path.dirname(absPath), target);
|
||||
if (path.relative(options.cwd, absTarget).startsWith(`..${path.sep}`)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (isSymlink || stat.isFile() || stat.isDirectory()) {
|
||||
if (isSymlink) {
|
||||
stat = await lstat(fsPath);
|
||||
stat = await lstat(absPath);
|
||||
}
|
||||
|
||||
// Some bookkeeping to track which directories already have entries within
|
||||
|
||||
@@ -5,7 +5,7 @@ import minimatch from 'minimatch';
|
||||
import { readlink } from 'fs-extra';
|
||||
import { isSymbolicLink, isDirectory } from './fs/download';
|
||||
import streamToBuffer from './fs/stream-to-buffer';
|
||||
import type { Files, Config, Cron } from './types';
|
||||
import type { Files, Config, Cron, FunctionFramework } from './types';
|
||||
|
||||
interface Environment {
|
||||
[key: string]: string;
|
||||
@@ -26,6 +26,7 @@ export interface LambdaOptionsBase {
|
||||
experimentalResponseStreaming?: boolean;
|
||||
operationType?: string;
|
||||
cron?: Cron;
|
||||
framework?: FunctionFramework;
|
||||
}
|
||||
|
||||
export interface LambdaOptionsWithFiles extends LambdaOptionsBase {
|
||||
@@ -71,6 +72,7 @@ export class Lambda {
|
||||
supportsMultiPayloads?: boolean;
|
||||
supportsWrapper?: boolean;
|
||||
experimentalResponseStreaming?: boolean;
|
||||
framework?: FunctionFramework;
|
||||
|
||||
constructor(opts: LambdaOptions) {
|
||||
const {
|
||||
@@ -86,6 +88,7 @@ export class Lambda {
|
||||
supportsWrapper,
|
||||
experimentalResponseStreaming,
|
||||
operationType,
|
||||
framework,
|
||||
} = opts;
|
||||
if ('files' in opts) {
|
||||
assert(typeof opts.files === 'object', '"files" must be an object');
|
||||
@@ -139,6 +142,20 @@ export class Lambda {
|
||||
assert(typeof cron === 'string', '"cron" is not a string');
|
||||
}
|
||||
|
||||
if (framework !== undefined) {
|
||||
assert(typeof framework === 'object', '"framework" is not an object');
|
||||
assert(
|
||||
typeof framework.slug === 'string',
|
||||
'"framework.slug" is not a string'
|
||||
);
|
||||
if (framework.version !== undefined) {
|
||||
assert(
|
||||
typeof framework.version === 'string',
|
||||
'"framework.version" is not a string'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
this.type = 'Lambda';
|
||||
this.operationType = operationType;
|
||||
this.files = 'files' in opts ? opts.files : undefined;
|
||||
@@ -154,6 +171,7 @@ export class Lambda {
|
||||
this.supportsMultiPayloads = supportsMultiPayloads;
|
||||
this.supportsWrapper = supportsWrapper;
|
||||
this.experimentalResponseStreaming = experimentalResponseStreaming;
|
||||
this.framework = framework;
|
||||
}
|
||||
|
||||
async createZip(): Promise<Buffer> {
|
||||
|
||||
@@ -13,10 +13,8 @@ export const functionsSchema = {
|
||||
maxLength: 256,
|
||||
},
|
||||
memory: {
|
||||
// Number between 128 and 3008 in steps of 64
|
||||
enum: Object.keys(Array.from({ length: 50 }))
|
||||
.slice(2, 48)
|
||||
.map(x => Number(x) * 64),
|
||||
minimum: 128,
|
||||
maximum: 3008,
|
||||
},
|
||||
maxDuration: {
|
||||
type: 'number',
|
||||
|
||||
@@ -412,6 +412,11 @@ export interface BuildResultBuildOutput {
|
||||
}
|
||||
|
||||
export type Cron = string;
|
||||
/** The framework which created the function */
|
||||
export interface FunctionFramework {
|
||||
slug: string;
|
||||
version?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* When a Builder implements `version: 2`, the `build()` function is expected
|
||||
|
||||
41
packages/build-utils/test/unit.glob.test.ts
vendored
41
packages/build-utils/test/unit.glob.test.ts
vendored
@@ -1,7 +1,7 @@
|
||||
import fs from 'fs-extra';
|
||||
import { join } from 'path';
|
||||
import { tmpdir } from 'os';
|
||||
import { glob, isDirectory } from '../src';
|
||||
import { glob, isDirectory, isSymbolicLink } from '../src';
|
||||
|
||||
describe('glob()', () => {
|
||||
it('should not return entries for empty directories by default', async () => {
|
||||
@@ -62,4 +62,43 @@ describe('glob()', () => {
|
||||
await fs.remove(dir);
|
||||
}
|
||||
});
|
||||
|
||||
it('should allow for following symlinks', async () => {
|
||||
const rootDir = await fs.mkdtemp(join(tmpdir(), 'build-utils-test'));
|
||||
const dir = await fs.mkdtemp(join(rootDir, 'build-utils-test'));
|
||||
try {
|
||||
await Promise.all([
|
||||
fs.writeFile(join(rootDir, 'root.txt'), 'file outside of "dir"'),
|
||||
fs.writeFile(join(dir, 'root.txt'), 'file at the root'),
|
||||
fs.mkdirp(join(dir, 'empty-dir')),
|
||||
fs
|
||||
.mkdirp(join(dir, 'dir-with-file'))
|
||||
.then(() =>
|
||||
fs.writeFile(join(dir, 'dir-with-file/data.json'), '{"a":"b"}')
|
||||
),
|
||||
fs.mkdirp(join(dir, 'another/subdir')),
|
||||
fs.symlink('root.txt', join(dir, 'root-link')),
|
||||
fs.symlink(join(dir, 'root.txt'), join(dir, 'abs-root-link')),
|
||||
fs.symlink('dir-with-file', join(dir, 'dir-link')),
|
||||
fs.symlink('empty-dir', join(dir, 'empty-dir-link')),
|
||||
fs.symlink('../root.txt', join(dir, 'outside-cwd-link')),
|
||||
fs.symlink(join(dir, '../root.txt'), join(dir, 'abs-outside-cwd-link')),
|
||||
]);
|
||||
const files = await glob('**', { cwd: dir, follow: true });
|
||||
const fileNames = Object.keys(files).sort();
|
||||
expect(fileNames).toHaveLength(5);
|
||||
expect(fileNames).toEqual([
|
||||
'abs-root-link',
|
||||
'dir-link/data.json',
|
||||
'dir-with-file/data.json',
|
||||
'root-link',
|
||||
'root.txt',
|
||||
]);
|
||||
for (const file of Object.values(files)) {
|
||||
expect(isSymbolicLink(file.mode)).toEqual(false);
|
||||
}
|
||||
} finally {
|
||||
await fs.remove(dir);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
4
packages/build-utils/test/unit.test.ts
vendored
4
packages/build-utils/test/unit.test.ts
vendored
@@ -502,6 +502,10 @@ it('should retry npm install when peer deps invalid and npm@8 on node@16', async
|
||||
console.log(`Skipping test on node@${nodeMajor}`);
|
||||
return;
|
||||
}
|
||||
if (process.platform === 'win32') {
|
||||
console.log('Skipping test on windows');
|
||||
return;
|
||||
}
|
||||
const fixture = path.join(__dirname, 'fixtures', '15-npm-8-legacy-peer-deps');
|
||||
const nodeVersion = { major: nodeMajor } as any;
|
||||
await runNpmInstall(fixture, [], {}, {}, nodeVersion);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vercel",
|
||||
"version": "28.15.3",
|
||||
"version": "28.15.6",
|
||||
"preferGlobal": true,
|
||||
"license": "Apache-2.0",
|
||||
"description": "The command-line interface for Vercel",
|
||||
@@ -14,8 +14,8 @@
|
||||
"preinstall": "node ./scripts/preinstall.js",
|
||||
"test": "jest --env node --verbose --bail",
|
||||
"test-unit": "pnpm test test/unit/",
|
||||
"test-integration-cli": "rimraf test/fixtures/integration && ava test/integration.js --serial --fail-fast --verbose",
|
||||
"test-integration-dev": "pnpm test test/dev/",
|
||||
"test-cli": "rimraf test/fixtures/integration && ava test/integration.js --serial --fail-fast --verbose",
|
||||
"test-dev": "pnpm test test/dev/",
|
||||
"coverage": "codecov",
|
||||
"build": "ts-node ./scripts/build.ts",
|
||||
"dev": "ts-node ./src/index.ts"
|
||||
@@ -41,16 +41,16 @@
|
||||
"node": ">= 14"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/build-utils": "6.2.1",
|
||||
"@vercel/go": "2.3.3",
|
||||
"@vercel/hydrogen": "0.0.49",
|
||||
"@vercel/next": "3.4.2",
|
||||
"@vercel/node": "2.9.2",
|
||||
"@vercel/python": "3.1.45",
|
||||
"@vercel/redwood": "1.1.1",
|
||||
"@vercel/remix": "1.2.12",
|
||||
"@vercel/ruby": "1.3.61",
|
||||
"@vercel/static-build": "1.3.5"
|
||||
"@vercel/build-utils": "6.2.4",
|
||||
"@vercel/go": "2.3.6",
|
||||
"@vercel/hydrogen": "0.0.52",
|
||||
"@vercel/next": "3.4.5",
|
||||
"@vercel/node": "2.9.5",
|
||||
"@vercel/python": "3.1.48",
|
||||
"@vercel/redwood": "1.1.4",
|
||||
"@vercel/remix": "1.3.1",
|
||||
"@vercel/ruby": "1.3.64",
|
||||
"@vercel/static-build": "1.3.8"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@alex_neo/jest-expect-message": "1.0.5",
|
||||
@@ -93,13 +93,13 @@
|
||||
"@types/which": "1.3.2",
|
||||
"@types/write-json-file": "2.2.1",
|
||||
"@types/yauzl-promise": "2.1.0",
|
||||
"@vercel/client": "12.3.7",
|
||||
"@vercel/client": "12.3.10",
|
||||
"@vercel/error-utils": "1.0.8",
|
||||
"@vercel/frameworks": "1.3.0",
|
||||
"@vercel/fs-detectors": "3.7.10",
|
||||
"@vercel/frameworks": "1.3.1",
|
||||
"@vercel/fs-detectors": "3.7.13",
|
||||
"@vercel/fun": "1.0.4",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"@vercel/routing-utils": "2.1.8",
|
||||
"@vercel/routing-utils": "2.1.9",
|
||||
"@zeit/source-map-support": "0.6.2",
|
||||
"ajv": "6.12.2",
|
||||
"alpha-sort": "2.0.1",
|
||||
@@ -110,7 +110,6 @@
|
||||
"async-retry": "1.1.3",
|
||||
"async-sema": "2.1.4",
|
||||
"ava": "2.2.0",
|
||||
"boxen": "4.2.0",
|
||||
"bytes": "3.0.0",
|
||||
"chalk": "4.1.0",
|
||||
"chance": "1.1.7",
|
||||
@@ -128,6 +127,7 @@
|
||||
"execa": "3.2.0",
|
||||
"express": "4.17.1",
|
||||
"fast-deep-equal": "3.1.3",
|
||||
"find-up": "4.1.0",
|
||||
"fs-extra": "10.0.0",
|
||||
"get-port": "5.1.1",
|
||||
"git-last-commit": "1.0.1",
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import open from 'open';
|
||||
import boxen from 'boxen';
|
||||
import execa from 'execa';
|
||||
import plural from 'pluralize';
|
||||
import { resolve } from 'path';
|
||||
import chalk, { Chalk } from 'chalk';
|
||||
import { URLSearchParams, parse } from 'url';
|
||||
|
||||
import box from '../../util/output/box';
|
||||
import sleep from '../../util/sleep';
|
||||
import formatDate from '../../util/format-date';
|
||||
import link from '../../util/output/link';
|
||||
@@ -363,7 +363,7 @@ export default async function main(client: Client): Promise<number> {
|
||||
|
||||
result.push(`${chalk.bold('Inspect:')} ${link(lastBad.inspectorUrl)}`);
|
||||
|
||||
output.print(boxen(result.join('\n'), { padding: 1 }));
|
||||
output.print(box(result.join('\n')));
|
||||
output.print('\n');
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -701,7 +701,7 @@ function expandBuild(files: string[], build: Builder): Builder[] {
|
||||
throw new NowBuildError({
|
||||
code: `invalid_build_specification`,
|
||||
message: 'Field `use` is missing in build specification',
|
||||
link: 'https://vercel.com/docs/configuration#project/builds',
|
||||
link: 'https://vercel.com/docs/concepts/projects/project-configuration#builds',
|
||||
action: 'View Documentation',
|
||||
});
|
||||
}
|
||||
@@ -711,7 +711,7 @@ function expandBuild(files: string[], build: Builder): Builder[] {
|
||||
throw new NowBuildError({
|
||||
code: `invalid_build_specification`,
|
||||
message: 'A build `src` path resolves to an empty string',
|
||||
link: 'https://vercel.com/docs/configuration#project/builds',
|
||||
link: 'https://vercel.com/docs/concepts/projects/project-configuration#builds',
|
||||
action: 'View Documentation',
|
||||
});
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ import { getCommandName, getTitleName } from './util/pkg-name';
|
||||
import doLoginPrompt from './util/login/prompt';
|
||||
import { AuthConfig, GlobalConfig } from './types';
|
||||
import { VercelConfig } from '@vercel/client';
|
||||
import box from './util/output/box';
|
||||
|
||||
const isCanary = pkg.version.includes('canary');
|
||||
|
||||
@@ -73,11 +74,12 @@ Sentry.init({
|
||||
});
|
||||
|
||||
let client: Client;
|
||||
let output: Output;
|
||||
let { isTTY } = process.stdout;
|
||||
let debug: (s: string) => void = () => {};
|
||||
let apiUrl = 'https://api.vercel.com';
|
||||
|
||||
const main = async () => {
|
||||
let { isTTY } = process.stdout;
|
||||
if (process.env.FORCE_TTY === '1') {
|
||||
isTTY = true;
|
||||
process.stdout.isTTY = true;
|
||||
@@ -105,7 +107,7 @@ const main = async () => {
|
||||
const isDebugging = argv['--debug'];
|
||||
const isNoColor = argv['--no-color'];
|
||||
|
||||
const output = new Output(process.stderr, {
|
||||
output = new Output(process.stderr, {
|
||||
debug: isDebugging,
|
||||
noColor: isNoColor,
|
||||
});
|
||||
@@ -146,29 +148,6 @@ const main = async () => {
|
||||
process.chdir(cwd);
|
||||
}
|
||||
|
||||
// Print update information, if available
|
||||
if (isTTY && !process.env.NO_UPDATE_NOTIFIER) {
|
||||
// Check if an update is available. If so, `latest` will contain a string
|
||||
// of the latest version, otherwise `undefined`.
|
||||
const latest = getLatestVersion({
|
||||
distTag: isCanary ? 'canary' : 'latest',
|
||||
output,
|
||||
pkg,
|
||||
});
|
||||
if (latest) {
|
||||
output.log(
|
||||
`${chalk.black.bgCyan('UPDATE AVAILABLE')} ` +
|
||||
`Run ${cmd(
|
||||
await getUpdateCommand()
|
||||
)} to install ${getTitleName()} CLI ${latest}`
|
||||
);
|
||||
|
||||
output.log(
|
||||
`Changelog: https://github.com/vercel/vercel/releases/tag/vercel@${latest}\n`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// The second argument to the command can be:
|
||||
//
|
||||
// * a path to deploy (as in: `vercel path/`)
|
||||
@@ -716,7 +695,39 @@ process.on('unhandledRejection', handleRejection);
|
||||
process.on('uncaughtException', handleUnexpected);
|
||||
|
||||
main()
|
||||
.then(exitCode => {
|
||||
.then(async exitCode => {
|
||||
// Print update information, if available
|
||||
if (isTTY && !process.env.NO_UPDATE_NOTIFIER) {
|
||||
// Check if an update is available. If so, `latest` will contain a string
|
||||
// of the latest version, otherwise `undefined`.
|
||||
const latest = getLatestVersion({
|
||||
distTag: isCanary ? 'canary' : 'latest',
|
||||
output,
|
||||
pkg,
|
||||
});
|
||||
if (latest) {
|
||||
const changelog = 'https://github.com/vercel/vercel/releases';
|
||||
const errorMsg =
|
||||
exitCode && exitCode !== 2
|
||||
? chalk.magenta(
|
||||
`\n\nThe latest update ${chalk.italic(
|
||||
'may'
|
||||
)} fix any errors that occurred.`
|
||||
)
|
||||
: '';
|
||||
output.print(
|
||||
box(
|
||||
`Update available! ${chalk.gray(`v${pkg.version}`)} ≫ ${chalk.green(
|
||||
`v${latest}`
|
||||
)}
|
||||
Changelog: ${output.link(changelog, changelog, { fallback: false })}
|
||||
Run ${chalk.cyan(cmd(await getUpdateCommand()))} to update.${errorMsg}`
|
||||
)
|
||||
);
|
||||
output.print('\n\n');
|
||||
}
|
||||
}
|
||||
|
||||
process.exitCode = exitCode;
|
||||
})
|
||||
.catch(handleUnexpected);
|
||||
|
||||
@@ -2307,7 +2307,10 @@ function proxyPass(
|
||||
res,
|
||||
{ target: dest, ignorePath },
|
||||
(error: NodeJS.ErrnoException) => {
|
||||
devServer.output.error(
|
||||
// only debug output this error because it's always something generic like
|
||||
// "Error: socket hang up"
|
||||
// and the original error should have already been logged
|
||||
devServer.output.debug(
|
||||
`Failed to complete request to ${req.url}: ${error}`
|
||||
);
|
||||
if (!res.headersSent) {
|
||||
|
||||
@@ -116,45 +116,10 @@ process.once('message', async msg => {
|
||||
output.debug(`Initializing lock file with pid ${process.pid}`);
|
||||
await writeFile(lockFile, String(process.pid), 'utf-8');
|
||||
|
||||
// fetch the latest version from npm
|
||||
const agent = new https.Agent({
|
||||
keepAlive: true,
|
||||
maxSockets: 15, // See: `npm config get maxsockets`
|
||||
});
|
||||
const headers = {
|
||||
accept:
|
||||
'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*',
|
||||
};
|
||||
const url = `https://registry.npmjs.org/-/package/${name}/dist-tags`;
|
||||
output.debug(`Fetching ${url}`);
|
||||
|
||||
const tags = await new Promise((resolve, reject) => {
|
||||
const req = https.get(
|
||||
url,
|
||||
{
|
||||
agent,
|
||||
headers,
|
||||
},
|
||||
res => {
|
||||
let buf = '';
|
||||
res.on('data', chunk => {
|
||||
buf += chunk;
|
||||
});
|
||||
res.on('end', () => {
|
||||
try {
|
||||
resolve(JSON.parse(buf));
|
||||
} catch (err) {
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
req.on('error', reject);
|
||||
req.end();
|
||||
});
|
||||
|
||||
const tags = await fetchDistTags(name);
|
||||
const version = tags[distTag];
|
||||
const expireAt = Date.now() + updateCheckInterval;
|
||||
const notifyAt = await getNotifyAt(cacheFile, version);
|
||||
|
||||
if (version) {
|
||||
output.debug(`Found dist tag "${distTag}" with version "${version}"`);
|
||||
@@ -167,8 +132,8 @@ process.once('message', async msg => {
|
||||
await writeFile(
|
||||
cacheFile,
|
||||
JSON.stringify({
|
||||
expireAt: Date.now() + updateCheckInterval,
|
||||
notified: false,
|
||||
expireAt,
|
||||
notifyAt,
|
||||
version,
|
||||
})
|
||||
);
|
||||
@@ -223,3 +188,74 @@ async function isRunning(lockFile) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to load and return the previous `notifyAt` value.
|
||||
*
|
||||
* If the latest version is newer than the previous latest version, then
|
||||
* return `undefined` to invalidate `notifyAt` which forces the notification
|
||||
* to be displayed, otherwise keep the existing `notifyAt`.
|
||||
*
|
||||
* @param {string} cacheFile The path to the cache file
|
||||
* @param {string} version The latest version
|
||||
* @returns {number | undefined} The previous notifyAt
|
||||
*/
|
||||
async function getNotifyAt(cacheFile, version) {
|
||||
try {
|
||||
const old = JSON.parse(await readFile(cacheFile, 'utf-8'));
|
||||
if (old?.version && old.version === version) {
|
||||
return old.notifyAt;
|
||||
}
|
||||
} catch (err) {
|
||||
// cache does not exist or malformed
|
||||
if (err.code !== 'ENOENT') {
|
||||
output.debug(`Error reading latest package cache file: ${err}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches the dist tags from npm for a given package.
|
||||
*
|
||||
* @param {string} name The package name
|
||||
* @returns A map of dist tags to versions
|
||||
*/
|
||||
async function fetchDistTags(name) {
|
||||
// fetch the latest version from npm
|
||||
const agent = new https.Agent({
|
||||
keepAlive: true,
|
||||
maxSockets: 15, // See: `npm config get maxsockets`
|
||||
});
|
||||
const headers = {
|
||||
accept:
|
||||
'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*',
|
||||
};
|
||||
const url = `https://registry.npmjs.org/-/package/${name}/dist-tags`;
|
||||
output.debug(`Fetching ${url}`);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const req = https.get(
|
||||
url,
|
||||
{
|
||||
agent,
|
||||
headers,
|
||||
},
|
||||
res => {
|
||||
let buf = '';
|
||||
res.on('data', chunk => {
|
||||
buf += chunk;
|
||||
});
|
||||
res.on('end', () => {
|
||||
try {
|
||||
resolve(JSON.parse(buf));
|
||||
} catch (err) {
|
||||
reject(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
req.on('error', reject);
|
||||
req.end();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -9,22 +9,23 @@ import { spawn } from 'child_process';
|
||||
interface GetLatestVersionOptions {
|
||||
cacheDir?: string;
|
||||
distTag?: string;
|
||||
notifyInterval?: number;
|
||||
output?: Output;
|
||||
pkg: PackageJson;
|
||||
updateCheckInterval?: number;
|
||||
}
|
||||
|
||||
interface PackageInfoCache {
|
||||
version: string;
|
||||
expireAt: number;
|
||||
notified: boolean;
|
||||
notifyAt: number;
|
||||
version: string;
|
||||
}
|
||||
|
||||
interface GetLatestWorkerPayload {
|
||||
cacheFile?: string;
|
||||
distTag?: string;
|
||||
updateCheckInterval?: number;
|
||||
name?: string;
|
||||
updateCheckInterval?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -38,9 +39,10 @@ interface GetLatestWorkerPayload {
|
||||
export default function getLatestVersion({
|
||||
cacheDir = XDGAppPaths('com.vercel.cli').cache(),
|
||||
distTag = 'latest',
|
||||
notifyInterval = 1000 * 60 * 60 * 24 * 3, // 3 days
|
||||
output,
|
||||
pkg,
|
||||
updateCheckInterval = 1000 * 60 * 60 * 24 * 7, // 1 week
|
||||
updateCheckInterval = 1000 * 60 * 60 * 24, // 1 day
|
||||
}: GetLatestVersionOptions): string | undefined {
|
||||
if (
|
||||
!pkg ||
|
||||
@@ -67,27 +69,31 @@ export default function getLatestVersion({
|
||||
}
|
||||
}
|
||||
|
||||
if (!cache || cache.expireAt < Date.now()) {
|
||||
if (!cache || !cache.expireAt || cache.expireAt < Date.now()) {
|
||||
spawnWorker(
|
||||
{
|
||||
cacheFile,
|
||||
distTag,
|
||||
updateCheckInterval,
|
||||
name: pkg.name,
|
||||
updateCheckInterval,
|
||||
},
|
||||
output
|
||||
);
|
||||
}
|
||||
|
||||
if (
|
||||
cache &&
|
||||
!cache.notified &&
|
||||
pkg.version &&
|
||||
semver.lt(pkg.version, cache.version)
|
||||
) {
|
||||
cache.notified = true;
|
||||
outputJSONSync(cacheFile, cache);
|
||||
return cache.version;
|
||||
if (cache) {
|
||||
const shouldNotify = !cache.notifyAt || cache.notifyAt < Date.now();
|
||||
|
||||
let updateAvailable = false;
|
||||
if (cache.version && pkg.version) {
|
||||
updateAvailable = semver.lt(pkg.version, cache.version);
|
||||
}
|
||||
|
||||
if (shouldNotify && updateAvailable) {
|
||||
cache.notifyAt = Date.now() + notifyInterval;
|
||||
outputJSONSync(cacheFile, cache);
|
||||
return cache.version;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
112
packages/cli/src/util/output/box.ts
Normal file
112
packages/cli/src/util/output/box.ts
Normal file
@@ -0,0 +1,112 @@
|
||||
import chalk from 'chalk';
|
||||
import stripAnsi from 'strip-ansi';
|
||||
|
||||
const border = ['─', '╭', '╮', '│', '│', '╰', '╯'];
|
||||
const nothing = ['─', '', '', '', '', '', ''];
|
||||
|
||||
export type BoxOptions = {
|
||||
borderColor?:
|
||||
| 'black'
|
||||
| 'red'
|
||||
| 'green'
|
||||
| 'yellow'
|
||||
| 'blue'
|
||||
| 'magenta'
|
||||
| 'cyan'
|
||||
| 'white';
|
||||
padding?: number;
|
||||
textAlignment?: 'left' | 'center' | 'right';
|
||||
terminalColumns?: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* Renders text centered inside a yellow box. If terminal is too narrow to fit
|
||||
* the text without wrapping, the box will only consist of a top and bottom
|
||||
* horizontal rule with the text left justified.
|
||||
*
|
||||
* @param message The multiline message to display
|
||||
* @param options Various formatting options
|
||||
* @returns The rendered string
|
||||
*
|
||||
* @example Simple box
|
||||
*
|
||||
* # Usage
|
||||
* ```
|
||||
* console.log(box('Hello world!\nThe quick brown fox jumps over the lazy dog'));
|
||||
* ```
|
||||
*
|
||||
* # Result
|
||||
* ```
|
||||
* ╭─────────────────────────────────────────────────╮
|
||||
* │ │
|
||||
* │ Hello world! │
|
||||
* │ The quick brown fox jumps over the lazy dog │
|
||||
* │ │
|
||||
* ╰─────────────────────────────────────────────────╯
|
||||
* ```
|
||||
*/
|
||||
export default function box(
|
||||
message: string,
|
||||
{
|
||||
borderColor,
|
||||
padding = 1,
|
||||
textAlignment = 'center',
|
||||
terminalColumns: cols = process.stdout.columns ||
|
||||
(process.env.COLUMNS && parseInt(process.env.COLUMNS, 10)) ||
|
||||
80,
|
||||
}: BoxOptions = {}
|
||||
): string {
|
||||
const lines: [string, number][] = message
|
||||
.split(/\r?\n/)
|
||||
.map(line => [line, stripAnsi(line).length]);
|
||||
const maxLine = lines.reduce((p, [, len]) => Math.max(p, len), 0);
|
||||
const borderColorFn = (borderColor && chalk[borderColor]) || chalk.yellow;
|
||||
const clampedSidePadding = Math.max(1, padding * 3);
|
||||
const narrowMode = maxLine + 2 + clampedSidePadding * 2 > cols;
|
||||
const sidePadding = narrowMode ? 0 : clampedSidePadding;
|
||||
const innerWidth = Math.min(maxLine + sidePadding * 2, cols);
|
||||
const [hr, topLeft, topRight, left, right, bottomLeft, bottomRight] =
|
||||
narrowMode ? nothing : border;
|
||||
const spacerRow = narrowMode
|
||||
? '\n'.repeat(padding)
|
||||
: `${borderColorFn(`${left}${' '.repeat(innerWidth)}${right}`)}\n`.repeat(
|
||||
padding
|
||||
);
|
||||
|
||||
const renderLine = ([line, len]: [string, number]) => {
|
||||
let leftPadding = 0;
|
||||
let rightPadding = 0;
|
||||
|
||||
if (!narrowMode) {
|
||||
leftPadding = sidePadding;
|
||||
rightPadding = sidePadding;
|
||||
|
||||
if (textAlignment === 'center') {
|
||||
leftPadding += Math.floor((maxLine - len) / 2);
|
||||
rightPadding += maxLine - len - leftPadding + sidePadding;
|
||||
} else if (textAlignment === 'right') {
|
||||
leftPadding += maxLine - len;
|
||||
} else if (textAlignment === 'left') {
|
||||
rightPadding += maxLine - len;
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
borderColorFn(left) +
|
||||
' '.repeat(leftPadding) +
|
||||
line +
|
||||
' '.repeat(rightPadding) +
|
||||
borderColorFn(right)
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
borderColorFn(`${topLeft}${hr.repeat(innerWidth)}${topRight}`) +
|
||||
'\n' +
|
||||
spacerRow +
|
||||
lines.map(renderLine).join('\n') +
|
||||
'\n' +
|
||||
spacerRow +
|
||||
borderColorFn(`${bottomLeft}${hr.repeat(innerWidth)}${bottomRight}`)
|
||||
);
|
||||
}
|
||||
@@ -1,73 +0,0 @@
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Runtime data
|
||||
pids
|
||||
*.pid
|
||||
*.seed
|
||||
*.pid.lock
|
||||
|
||||
# Directory for instrumented libs generated by jscoverage/JSCover
|
||||
lib-cov
|
||||
|
||||
# Coverage directory used by tools like istanbul
|
||||
coverage
|
||||
|
||||
# nyc test coverage
|
||||
.nyc_output
|
||||
|
||||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
||||
# Bower dependency directory (https://bower.io/)
|
||||
bower_components
|
||||
|
||||
# node-waf configuration
|
||||
.lock-wscript
|
||||
|
||||
# Compiled binary addons (http://nodejs.org/api/addons.html)
|
||||
build/Release
|
||||
|
||||
# Dependency directories
|
||||
node_modules/
|
||||
jspm_packages/
|
||||
|
||||
# Typescript v1 declaration files
|
||||
typings/
|
||||
|
||||
# Optional npm cache directory
|
||||
.npm
|
||||
|
||||
# Optional eslint cache
|
||||
.eslintcache
|
||||
|
||||
# Optional REPL history
|
||||
.node_repl_history
|
||||
|
||||
# Output of 'npm pack'
|
||||
*.tgz
|
||||
|
||||
# dotenv environment variables file
|
||||
.env
|
||||
.env.build
|
||||
|
||||
# gatsby files
|
||||
.cache/
|
||||
public
|
||||
|
||||
# Mac files
|
||||
.DS_Store
|
||||
|
||||
# Yarn
|
||||
yarn-error.log
|
||||
.pnp/
|
||||
.pnp.js
|
||||
# Yarn Integrity file
|
||||
.yarn-integrity
|
||||
|
||||
.now
|
||||
.vercel
|
||||
@@ -1,7 +0,0 @@
|
||||
/**
|
||||
* Implement Gatsby's Browser APIs in this file.
|
||||
*
|
||||
* See: https://www.gatsbyjs.org/docs/browser-apis/
|
||||
*/
|
||||
|
||||
// You can delete this file if you're not using it
|
||||
@@ -1,16 +0,0 @@
|
||||
module.exports = {
|
||||
siteMetadata: {
|
||||
title: 'Gatsby Default Starter',
|
||||
},
|
||||
plugins: [
|
||||
{
|
||||
resolve: `gatsby-plugin-manifest`,
|
||||
options: {
|
||||
name: `05-gatsby`,
|
||||
short_name: `starter`,
|
||||
start_url: `/`,
|
||||
icon: 'src/images/gatsby-icon.png',
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -1,7 +0,0 @@
|
||||
/**
|
||||
* Implement Gatsby's Node APIs in this file.
|
||||
*
|
||||
* See: https://www.gatsbyjs.org/docs/node-apis/
|
||||
*/
|
||||
|
||||
// You can delete this file if you're not using it
|
||||
@@ -1,7 +0,0 @@
|
||||
/**
|
||||
* Implement Gatsby's SSR (Server Side Rendering) APIs in this file.
|
||||
*
|
||||
* See: https://www.gatsbyjs.org/docs/ssr-apis/
|
||||
*/
|
||||
|
||||
// You can delete this file if you're not using it
|
||||
@@ -1,16 +0,0 @@
|
||||
{
|
||||
"private": true,
|
||||
"name": "gatsby",
|
||||
"version": "1.0.0",
|
||||
"dependencies": {
|
||||
"gatsby": "^2.18.14",
|
||||
"gatsby-image": "^2.0.15",
|
||||
"gatsby-plugin-manifest": "^2.0.5",
|
||||
"react": "^16.5.1",
|
||||
"react-dom": "^16.5.1"
|
||||
},
|
||||
"scripts": {
|
||||
"dev": "gatsby develop",
|
||||
"build": "gatsby build"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 21 KiB |
@@ -1,11 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
function Custom404() {
|
||||
return (
|
||||
<main>
|
||||
<h1>Custom Gatsby 404</h1>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
export default Custom404;
|
||||
@@ -1,12 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
function Index() {
|
||||
return (
|
||||
<main>
|
||||
<h1>Gatsby Default Starter</h1>
|
||||
<p>Hello World</p>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
export default Index;
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,12 +0,0 @@
|
||||
*.log
|
||||
.cache
|
||||
.DS_Store
|
||||
src/.temp
|
||||
node_modules
|
||||
dist
|
||||
.env
|
||||
.env.*
|
||||
!yarn.lock
|
||||
|
||||
.now
|
||||
.vercel
|
||||
@@ -1,2 +0,0 @@
|
||||
README.md
|
||||
yarn.lock
|
||||
@@ -1,19 +0,0 @@
|
||||
# Gridsome Example
|
||||
|
||||
This directory is a brief example of a [Gridsome](https://gridsome.org/) app that can be deployed to Vercel with zero configuration.
|
||||
|
||||
## How we created this example
|
||||
|
||||
To get started with Gridsome on Vercel, you can use the [Gridsome CLI](https://gridsome.org/docs/gridsome-cli/) to initialize the project:
|
||||
|
||||
```shell
|
||||
$ gridsome create my-website
|
||||
```
|
||||
|
||||
## Deploying this Example
|
||||
|
||||
Once initialized, you can deploy the Gridsome example with just a single command:
|
||||
|
||||
```shell
|
||||
$ vercel
|
||||
```
|
||||
@@ -1,10 +0,0 @@
|
||||
// This is where project configuration and plugin options are located.
|
||||
// Learn more: https://gridsome.org/docs/config
|
||||
|
||||
// Changes here require a server restart.
|
||||
// To restart press CTRL + C in terminal and run `gridsome develop`
|
||||
|
||||
module.exports = {
|
||||
siteName: 'Gridsome',
|
||||
plugins: []
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
// Server API makes it possible to hook into various parts of Gridsome
|
||||
// on server-side and add custom data to the GraphQL data layer.
|
||||
// Learn more: https://gridsome.org/docs/server-api
|
||||
|
||||
// Changes here require a server restart.
|
||||
// To restart press CTRL + C in terminal and run `gridsome develop`
|
||||
|
||||
module.exports = function (api) {
|
||||
api.loadSource(({ addContentType }) => {
|
||||
// Use the Data Store API here: https://gridsome.org/docs/data-store-api
|
||||
})
|
||||
|
||||
api.createPages(({ createPage }) => {
|
||||
// Use the Pages API here: https://gridsome.org/docs/pages-api
|
||||
})
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user