mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-23 18:59:59 +00:00
Compare commits
38 Commits
@vercel/bu
...
@vercel/fr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8cfac4cf86 | ||
|
|
4f20783000 | ||
|
|
968b7c3fb5 | ||
|
|
407c4ec5f4 | ||
|
|
bcf393d125 | ||
|
|
115ae0a229 | ||
|
|
d149489c9e | ||
|
|
5b2e6052fc | ||
|
|
38cb5a3b99 | ||
|
|
84e828a0ca | ||
|
|
157ce5346d | ||
|
|
0256157391 | ||
|
|
a45b3d0982 | ||
|
|
26af6dbc03 | ||
|
|
38130103a0 | ||
|
|
978485818a | ||
|
|
0270784cbb | ||
|
|
345e514924 | ||
|
|
df62ec6ed0 | ||
|
|
f7f81fb896 | ||
|
|
a210c6e4f0 | ||
|
|
50080e4b92 | ||
|
|
5845bebe2d | ||
|
|
3e18146846 | ||
|
|
dbde60f47f | ||
|
|
aa3db23cad | ||
|
|
60a5b0a586 | ||
|
|
8b682ccc41 | ||
|
|
50055963af | ||
|
|
43fa6e6d97 | ||
|
|
98c0b9b573 | ||
|
|
8b8541f4aa | ||
|
|
59cc2bf0f2 | ||
|
|
30e078062f | ||
|
|
4d015a60ef | ||
|
|
ad0e66242d | ||
|
|
044f956de2 | ||
|
|
d26ed43d26 |
2
.github/workflows/publish.yml
vendored
2
.github/workflows/publish.yml
vendored
@@ -17,7 +17,7 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
node-version: 12
|
node-version: 12
|
||||||
- name: Install
|
- name: Install
|
||||||
run: yarn install --check-files --frozen-lockfile
|
run: yarn install --check-files --frozen-lockfile --network-timeout 1000000
|
||||||
- name: Build
|
- name: Build
|
||||||
run: yarn build
|
run: yarn build
|
||||||
env:
|
env:
|
||||||
|
|||||||
4
.github/workflows/test-integration-cli.yml
vendored
4
.github/workflows/test-integration-cli.yml
vendored
@@ -16,7 +16,7 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest]
|
os: [ubuntu-latest]
|
||||||
node: [10, 12]
|
node: [12]
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
@@ -26,7 +26,7 @@ jobs:
|
|||||||
- run: git fetch origin master --depth=100
|
- run: git fetch origin master --depth=100
|
||||||
- run: git fetch origin ${{ github.ref }} --depth=100
|
- run: git fetch origin ${{ github.ref }} --depth=100
|
||||||
- run: git diff origin/master...HEAD --name-only
|
- run: git diff origin/master...HEAD --name-only
|
||||||
- run: yarn install
|
- run: yarn install --network-timeout 1000000
|
||||||
- run: yarn run build
|
- run: yarn run build
|
||||||
- uses: actions/setup-node@v1
|
- uses: actions/setup-node@v1
|
||||||
with:
|
with:
|
||||||
|
|||||||
4
.github/workflows/test-integration-dev.yml
vendored
4
.github/workflows/test-integration-dev.yml
vendored
@@ -16,7 +16,7 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, macos-latest]
|
os: [ubuntu-latest, macos-latest]
|
||||||
node: [10, 12]
|
node: [12]
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
@@ -29,7 +29,7 @@ jobs:
|
|||||||
- name: Install Hugo
|
- name: Install Hugo
|
||||||
if: matrix.os == 'macos-latest'
|
if: matrix.os == 'macos-latest'
|
||||||
run: curl -L -O https://github.com/gohugoio/hugo/releases/download/v0.56.0/hugo_0.56.0_macOS-64bit.tar.gz && tar -xzf hugo_0.56.0_macOS-64bit.tar.gz && mv ./hugo packages/now-cli/test/dev/fixtures/08-hugo/
|
run: curl -L -O https://github.com/gohugoio/hugo/releases/download/v0.56.0/hugo_0.56.0_macOS-64bit.tar.gz && tar -xzf hugo_0.56.0_macOS-64bit.tar.gz && mv ./hugo packages/now-cli/test/dev/fixtures/08-hugo/
|
||||||
- run: yarn install
|
- run: yarn install --network-timeout 1000000
|
||||||
- run: yarn run build
|
- run: yarn run build
|
||||||
- uses: actions/setup-node@v1
|
- uses: actions/setup-node@v1
|
||||||
with:
|
with:
|
||||||
|
|||||||
2
.github/workflows/test-integration-once.yml
vendored
2
.github/workflows/test-integration-once.yml
vendored
@@ -21,7 +21,7 @@ jobs:
|
|||||||
- run: git fetch origin master --depth=100
|
- run: git fetch origin master --depth=100
|
||||||
- run: git fetch origin ${{ github.ref }} --depth=100
|
- run: git fetch origin ${{ github.ref }} --depth=100
|
||||||
- run: git diff origin/master...HEAD --name-only
|
- run: git diff origin/master...HEAD --name-only
|
||||||
- run: yarn install
|
- run: yarn install --network-timeout 1000000
|
||||||
- run: yarn run build
|
- run: yarn run build
|
||||||
- run: yarn test-integration-once --clean false
|
- run: yarn test-integration-once --clean false
|
||||||
env:
|
env:
|
||||||
|
|||||||
4
.github/workflows/test-unit.yml
vendored
4
.github/workflows/test-unit.yml
vendored
@@ -16,7 +16,7 @@ jobs:
|
|||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-latest, macos-latest, windows-latest]
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
||||||
node: [10, 12]
|
node: [12]
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v2
|
||||||
@@ -29,7 +29,7 @@ jobs:
|
|||||||
- uses: actions/setup-node@v1
|
- uses: actions/setup-node@v1
|
||||||
with:
|
with:
|
||||||
node-version: ${{ matrix.node }}
|
node-version: ${{ matrix.node }}
|
||||||
- run: yarn install
|
- run: yarn install --network-timeout 1000000
|
||||||
- run: yarn run build
|
- run: yarn run build
|
||||||
- run: yarn run lint
|
- run: yarn run lint
|
||||||
if: matrix.os == 'ubuntu-latest' && matrix.node == 12 # only run lint once
|
if: matrix.os == 'ubuntu-latest' && matrix.node == 12 # only run lint once
|
||||||
|
|||||||
5
examples/jekyll/.gitignore
vendored
5
examples/jekyll/.gitignore
vendored
@@ -1,6 +1,9 @@
|
|||||||
_site
|
_site
|
||||||
public
|
|
||||||
.sass-cache
|
.sass-cache
|
||||||
|
.jekyll-cache
|
||||||
.jekyll-metadata
|
.jekyll-metadata
|
||||||
|
vendor
|
||||||
|
public
|
||||||
.env
|
.env
|
||||||
.env.build
|
.env.build
|
||||||
|
.vercel
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
README.md
|
|
||||||
yarn.lock
|
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
---
|
---
|
||||||
|
permalink: /404.html
|
||||||
layout: default
|
layout: default
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
source "https://rubygems.org"
|
source "https://rubygems.org"
|
||||||
|
|
||||||
# Hello! This is where you manage which Jekyll version is used to run.
|
# Hello! This is where you manage which Jekyll version is used to run.
|
||||||
# When you want to use a different version, change it below, save the
|
# When you want to use a different version, change it below, save the
|
||||||
# file and run `bundle install`. Run Jekyll with `bundle exec`, like so:
|
# file and run `bundle install`. Run Jekyll with `bundle exec`, like so:
|
||||||
@@ -8,27 +7,23 @@ source "https://rubygems.org"
|
|||||||
#
|
#
|
||||||
# This will help ensure the proper Jekyll version is running.
|
# This will help ensure the proper Jekyll version is running.
|
||||||
# Happy Jekylling!
|
# Happy Jekylling!
|
||||||
gem "jekyll", "~> 3.8.6"
|
gem "jekyll", "~> 4.2.0"
|
||||||
|
|
||||||
# This is the default theme for new Jekyll sites. You may change this to anything you like.
|
# This is the default theme for new Jekyll sites. You may change this to anything you like.
|
||||||
gem "minima", "~> 2.0"
|
gem "minima", "~> 2.5"
|
||||||
|
|
||||||
# If you want to use GitHub Pages, remove the "gem "jekyll"" above and
|
# If you want to use GitHub Pages, remove the "gem "jekyll"" above and
|
||||||
# uncomment the line below. To upgrade, run `bundle update github-pages`.
|
# uncomment the line below. To upgrade, run `bundle update github-pages`.
|
||||||
# gem "github-pages", group: :jekyll_plugins
|
# gem "github-pages", group: :jekyll_plugins
|
||||||
|
|
||||||
# If you have any plugins, put them here!
|
# If you have any plugins, put them here!
|
||||||
group :jekyll_plugins do
|
group :jekyll_plugins do
|
||||||
gem "jekyll-feed", "~> 0.6"
|
gem "jekyll-feed", "~> 0.12"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
|
# Windows and JRuby does not include zoneinfo files, so bundle the tzinfo-data gem
|
||||||
# and associated library.
|
# and associated library.
|
||||||
install_if -> { RUBY_PLATFORM =~ %r!mingw|mswin|java! } do
|
platforms :mingw, :x64_mingw, :mswin, :jruby do
|
||||||
gem "tzinfo", "~> 1.2"
|
gem "tzinfo", "~> 1.2"
|
||||||
gem "tzinfo-data"
|
gem "tzinfo-data"
|
||||||
end
|
end
|
||||||
|
|
||||||
# Performance-booster for watching directories on Windows
|
# Performance-booster for watching directories on Windows
|
||||||
gem "wdm", "~> 0.1.0", :install_if => Gem.win_platform?
|
gem "wdm", "~> 0.1.1", :platforms => [:mingw, :x64_mingw, :mswin]
|
||||||
|
|
||||||
|
|||||||
@@ -1,82 +1,80 @@
|
|||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
addressable (2.6.0)
|
addressable (2.7.0)
|
||||||
public_suffix (>= 2.0.2, < 4.0)
|
public_suffix (>= 2.0.2, < 5.0)
|
||||||
colorator (1.1.0)
|
colorator (1.1.0)
|
||||||
concurrent-ruby (1.1.5)
|
concurrent-ruby (1.1.8)
|
||||||
em-websocket (0.5.1)
|
em-websocket (0.5.2)
|
||||||
eventmachine (>= 0.12.9)
|
eventmachine (>= 0.12.9)
|
||||||
http_parser.rb (~> 0.6.0)
|
http_parser.rb (~> 0.6.0)
|
||||||
eventmachine (1.2.7)
|
eventmachine (1.2.7)
|
||||||
ffi (1.11.1)
|
ffi (1.14.2)
|
||||||
forwardable-extended (2.6.0)
|
forwardable-extended (2.6.0)
|
||||||
http_parser.rb (0.6.0)
|
http_parser.rb (0.6.0)
|
||||||
i18n (0.9.5)
|
i18n (1.8.9)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
jekyll (3.8.6)
|
jekyll (4.2.0)
|
||||||
addressable (~> 2.4)
|
addressable (~> 2.4)
|
||||||
colorator (~> 1.0)
|
colorator (~> 1.0)
|
||||||
em-websocket (~> 0.5)
|
em-websocket (~> 0.5)
|
||||||
i18n (~> 0.7)
|
i18n (~> 1.0)
|
||||||
jekyll-sass-converter (~> 1.0)
|
jekyll-sass-converter (~> 2.0)
|
||||||
jekyll-watch (~> 2.0)
|
jekyll-watch (~> 2.0)
|
||||||
kramdown (~> 1.14)
|
kramdown (~> 2.3)
|
||||||
|
kramdown-parser-gfm (~> 1.0)
|
||||||
liquid (~> 4.0)
|
liquid (~> 4.0)
|
||||||
mercenary (~> 0.3.3)
|
mercenary (~> 0.4.0)
|
||||||
pathutil (~> 0.9)
|
pathutil (~> 0.9)
|
||||||
rouge (>= 1.7, < 4)
|
rouge (~> 3.0)
|
||||||
safe_yaml (~> 1.0)
|
safe_yaml (~> 1.0)
|
||||||
jekyll-feed (0.12.1)
|
terminal-table (~> 2.0)
|
||||||
|
jekyll-feed (0.15.1)
|
||||||
jekyll (>= 3.7, < 5.0)
|
jekyll (>= 3.7, < 5.0)
|
||||||
jekyll-sass-converter (1.5.2)
|
jekyll-sass-converter (2.1.0)
|
||||||
sass (~> 3.4)
|
sassc (> 2.0.1, < 3.0)
|
||||||
jekyll-seo-tag (2.6.1)
|
jekyll-seo-tag (2.7.1)
|
||||||
jekyll (>= 3.3, < 5.0)
|
jekyll (>= 3.8, < 5.0)
|
||||||
jekyll-watch (2.2.1)
|
jekyll-watch (2.2.1)
|
||||||
listen (~> 3.0)
|
listen (~> 3.0)
|
||||||
kramdown (1.17.0)
|
kramdown (2.3.0)
|
||||||
|
rexml
|
||||||
|
kramdown-parser-gfm (1.1.0)
|
||||||
|
kramdown (~> 2.0)
|
||||||
liquid (4.0.3)
|
liquid (4.0.3)
|
||||||
listen (3.1.5)
|
listen (3.4.1)
|
||||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||||
rb-inotify (~> 0.9, >= 0.9.7)
|
rb-inotify (~> 0.9, >= 0.9.10)
|
||||||
ruby_dep (~> 1.2)
|
mercenary (0.4.0)
|
||||||
mercenary (0.3.6)
|
minima (2.5.1)
|
||||||
minima (2.5.0)
|
jekyll (>= 3.5, < 5.0)
|
||||||
jekyll (~> 3.5)
|
|
||||||
jekyll-feed (~> 0.9)
|
jekyll-feed (~> 0.9)
|
||||||
jekyll-seo-tag (~> 2.1)
|
jekyll-seo-tag (~> 2.1)
|
||||||
pathutil (0.16.2)
|
pathutil (0.16.2)
|
||||||
forwardable-extended (~> 2.6)
|
forwardable-extended (~> 2.6)
|
||||||
public_suffix (3.1.1)
|
public_suffix (4.0.6)
|
||||||
rb-fsevent (0.10.3)
|
rb-fsevent (0.10.4)
|
||||||
rb-inotify (0.10.0)
|
rb-inotify (0.10.1)
|
||||||
ffi (~> 1.0)
|
ffi (~> 1.0)
|
||||||
rouge (3.6.0)
|
rexml (3.2.4)
|
||||||
ruby_dep (1.5.0)
|
rouge (3.26.0)
|
||||||
safe_yaml (1.0.5)
|
safe_yaml (1.0.5)
|
||||||
sass (3.7.4)
|
sassc (2.4.0)
|
||||||
sass-listen (~> 4.0.0)
|
ffi (~> 1.9)
|
||||||
sass-listen (4.0.0)
|
terminal-table (2.0.0)
|
||||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
unicode-display_width (~> 1.1, >= 1.1.1)
|
||||||
rb-inotify (~> 0.9, >= 0.9.7)
|
unicode-display_width (1.7.0)
|
||||||
thread_safe (0.3.6)
|
|
||||||
tzinfo (1.2.5)
|
|
||||||
thread_safe (~> 0.1)
|
|
||||||
tzinfo-data (1.2019.2)
|
|
||||||
tzinfo (>= 1.0.0)
|
|
||||||
wdm (0.1.1)
|
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
ruby
|
x86_64-linux
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
jekyll (~> 3.8.6)
|
jekyll (~> 4.2.0)
|
||||||
jekyll-feed (~> 0.6)
|
jekyll-feed (~> 0.12)
|
||||||
minima (~> 2.0)
|
minima (~> 2.5)
|
||||||
tzinfo (~> 1.2)
|
tzinfo (~> 1.2)
|
||||||
tzinfo-data
|
tzinfo-data
|
||||||
wdm (~> 0.1.0)
|
wdm (~> 0.1.1)
|
||||||
|
|
||||||
BUNDLED WITH
|
BUNDLED WITH
|
||||||
2.1.4
|
2.2.4
|
||||||
|
|||||||
@@ -7,12 +7,17 @@
|
|||||||
#
|
#
|
||||||
# For technical reasons, this file is *NOT* reloaded automatically when you use
|
# For technical reasons, this file is *NOT* reloaded automatically when you use
|
||||||
# 'bundle exec jekyll serve'. If you change this file, please restart the server process.
|
# 'bundle exec jekyll serve'. If you change this file, please restart the server process.
|
||||||
|
#
|
||||||
|
# If you need help with YAML syntax, here are some quick references for you:
|
||||||
|
# https://learn-the-web.algonquindesign.ca/topics/markdown-yaml-cheat-sheet/#yaml
|
||||||
|
# https://learnxinyminutes.com/docs/yaml/
|
||||||
|
#
|
||||||
# Site settings
|
# Site settings
|
||||||
# These are used to personalize your new site. If you look in the HTML files,
|
# These are used to personalize your new site. If you look in the HTML files,
|
||||||
# you will see them accessed via {{ site.title }}, {{ site.email }}, and so on.
|
# you will see them accessed via {{ site.title }}, {{ site.email }}, and so on.
|
||||||
# You can create any custom variable you would like, and they will be accessible
|
# You can create any custom variable you would like, and they will be accessible
|
||||||
# in the templates via {{ site.myvariable }}.
|
# in the templates via {{ site.myvariable }}.
|
||||||
|
|
||||||
title: Your awesome title
|
title: Your awesome title
|
||||||
email: your-email@example.com
|
email: your-email@example.com
|
||||||
description: >- # this means to ignore newlines until "baseurl:"
|
description: >- # this means to ignore newlines until "baseurl:"
|
||||||
@@ -23,21 +28,27 @@ baseurl: "" # the subpath of your site, e.g. /blog
|
|||||||
url: "" # the base hostname & protocol for your site, e.g. http://example.com
|
url: "" # the base hostname & protocol for your site, e.g. http://example.com
|
||||||
twitter_username: jekyllrb
|
twitter_username: jekyllrb
|
||||||
github_username: jekyll
|
github_username: jekyll
|
||||||
permalink: pretty
|
|
||||||
|
|
||||||
# Build settings
|
# Build settings
|
||||||
markdown: kramdown
|
|
||||||
theme: minima
|
theme: minima
|
||||||
plugins:
|
plugins:
|
||||||
- jekyll-feed
|
- jekyll-feed
|
||||||
|
|
||||||
# Exclude from processing.
|
# Exclude from processing.
|
||||||
# The following items will not be processed, by default. Create a custom list
|
# The following items will not be processed, by default.
|
||||||
# to override the default setting.
|
# Any item listed under the `exclude:` key here will be automatically added to
|
||||||
|
# the internal "default list".
|
||||||
|
#
|
||||||
|
# Excluded items can be processed by explicitly listing the directories or
|
||||||
|
# their entries' file path in the `include:` list.
|
||||||
|
#
|
||||||
# exclude:
|
# exclude:
|
||||||
|
# - .sass-cache/
|
||||||
|
# - .jekyll-cache/
|
||||||
|
# - gemfiles/
|
||||||
# - Gemfile
|
# - Gemfile
|
||||||
# - Gemfile.lock
|
# - Gemfile.lock
|
||||||
# - node_modules
|
# - node_modules/
|
||||||
# - vendor/bundle/
|
# - vendor/bundle/
|
||||||
# - vendor/cache/
|
# - vendor/cache/
|
||||||
# - vendor/gems/
|
# - vendor/gems/
|
||||||
|
|||||||
@@ -1,18 +1,23 @@
|
|||||||
---
|
---
|
||||||
layout: post
|
layout: post
|
||||||
title: "Welcome to Jekyll!"
|
title: 'Welcome to Jekyll!'
|
||||||
date: 2019-07-18 00:15:52 +0100
|
date: 2021-02-19 23:17:16 +0000
|
||||||
categories: jekyll update
|
categories: jekyll update
|
||||||
---
|
---
|
||||||
|
|
||||||
You’ll find this post in your `_posts` directory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different ways, but the most common way is to run `jekyll serve`, which launches a web server and auto-regenerates your site when a file is updated.
|
You’ll find this post in your `_posts` directory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different ways, but the most common way is to run `jekyll serve`, which launches a web server and auto-regenerates your site when a file is updated.
|
||||||
|
|
||||||
To add new posts, simply add a file in the `_posts` directory that follows the convention `YYYY-MM-DD-name-of-post.ext` and includes the necessary front matter. Take a look at the source for this post to get an idea about how it works.
|
Jekyll requires blog post files to be named according to the following format:
|
||||||
|
|
||||||
|
`YEAR-MONTH-DAY-title.MARKUP`
|
||||||
|
|
||||||
|
Where `YEAR` is a four-digit number, `MONTH` and `DAY` are both two-digit numbers, and `MARKUP` is the file extension representing the format used in the file. After that, include the necessary front matter. Take a look at the source for this post to get an idea about how it works.
|
||||||
|
|
||||||
Jekyll also offers powerful support for code snippets:
|
Jekyll also offers powerful support for code snippets:
|
||||||
|
|
||||||
{% highlight ruby %}
|
{% highlight ruby %}
|
||||||
def print_hi(name)
|
def print_hi(name)
|
||||||
puts "Hi, #{name}"
|
puts "Hi, #{name}"
|
||||||
end
|
end
|
||||||
print_hi('Tom')
|
print_hi('Tom')
|
||||||
#=> prints 'Hi, Tom' to STDOUT.
|
#=> prints 'Hi, Tom' to STDOUT.
|
||||||
@@ -21,5 +26,5 @@ print_hi('Tom')
|
|||||||
Check out the [Jekyll docs][jekyll-docs] for more info on how to get the most out of Jekyll. File all bugs/feature requests at [Jekyll’s GitHub repo][jekyll-gh]. If you have questions, you can ask them on [Jekyll Talk][jekyll-talk].
|
Check out the [Jekyll docs][jekyll-docs] for more info on how to get the most out of Jekyll. File all bugs/feature requests at [Jekyll’s GitHub repo][jekyll-gh]. If you have questions, you can ask them on [Jekyll Talk][jekyll-talk].
|
||||||
|
|
||||||
[jekyll-docs]: https://jekyllrb.com/docs/home
|
[jekyll-docs]: https://jekyllrb.com/docs/home
|
||||||
[jekyll-gh]: https://github.com/jekyll/jekyll
|
[jekyll-gh]: https://github.com/jekyll/jekyll
|
||||||
[jekyll-talk]: https://talk.jekyllrb.com/
|
[jekyll-talk]: https://talk.jekyllrb.com/
|
||||||
1
examples/middleman/.gitignore
vendored
1
examples/middleman/.gitignore
vendored
@@ -3,3 +3,4 @@
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
.sass-cache
|
.sass-cache
|
||||||
build/
|
build/
|
||||||
|
.vercel
|
||||||
|
|||||||
@@ -1,29 +1,29 @@
|
|||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
activesupport (5.0.7.2)
|
activesupport (5.2.4.5)
|
||||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||||
i18n (>= 0.7, < 2)
|
i18n (>= 0.7, < 2)
|
||||||
minitest (~> 5.1)
|
minitest (~> 5.1)
|
||||||
tzinfo (~> 1.1)
|
tzinfo (~> 1.1)
|
||||||
addressable (2.7.0)
|
addressable (2.7.0)
|
||||||
public_suffix (>= 2.0.2, < 5.0)
|
public_suffix (>= 2.0.2, < 5.0)
|
||||||
autoprefixer-rails (9.6.1.1)
|
autoprefixer-rails (9.8.6.5)
|
||||||
execjs
|
execjs
|
||||||
backports (3.15.0)
|
backports (3.20.2)
|
||||||
coffee-script (2.4.1)
|
coffee-script (2.4.1)
|
||||||
coffee-script-source
|
coffee-script-source
|
||||||
execjs
|
execjs
|
||||||
coffee-script-source (1.12.2)
|
coffee-script-source (1.12.2)
|
||||||
concurrent-ruby (1.1.5)
|
concurrent-ruby (1.1.8)
|
||||||
contracts (0.13.0)
|
contracts (0.13.0)
|
||||||
dotenv (2.7.5)
|
dotenv (2.7.6)
|
||||||
erubis (2.7.0)
|
erubis (2.7.0)
|
||||||
execjs (2.7.0)
|
execjs (2.7.0)
|
||||||
fast_blank (1.0.0)
|
fast_blank (1.0.0)
|
||||||
fastimage (2.1.7)
|
fastimage (2.2.2)
|
||||||
ffi (1.11.1)
|
ffi (1.14.2)
|
||||||
haml (5.1.2)
|
haml (5.2.1)
|
||||||
temple (>= 0.8.0)
|
temple (>= 0.8.0)
|
||||||
tilt
|
tilt
|
||||||
hamster (3.0.0)
|
hamster (3.0.0)
|
||||||
@@ -31,24 +31,25 @@ GEM
|
|||||||
hashie (3.6.0)
|
hashie (3.6.0)
|
||||||
i18n (0.9.5)
|
i18n (0.9.5)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
kramdown (1.17.0)
|
kramdown (2.3.0)
|
||||||
|
rexml
|
||||||
listen (3.0.8)
|
listen (3.0.8)
|
||||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||||
rb-inotify (~> 0.9, >= 0.9.7)
|
rb-inotify (~> 0.9, >= 0.9.7)
|
||||||
memoist (0.16.0)
|
memoist (0.16.2)
|
||||||
middleman (4.3.5)
|
middleman (4.3.11)
|
||||||
coffee-script (~> 2.2)
|
coffee-script (~> 2.2)
|
||||||
haml (>= 4.0.5)
|
haml (>= 4.0.5)
|
||||||
kramdown (~> 1.2)
|
kramdown (>= 2.3.0)
|
||||||
middleman-cli (= 4.3.5)
|
middleman-cli (= 4.3.11)
|
||||||
middleman-core (= 4.3.5)
|
middleman-core (= 4.3.11)
|
||||||
middleman-autoprefixer (2.10.1)
|
middleman-autoprefixer (2.10.1)
|
||||||
autoprefixer-rails (~> 9.1)
|
autoprefixer-rails (~> 9.1)
|
||||||
middleman-core (>= 3.3.3)
|
middleman-core (>= 3.3.3)
|
||||||
middleman-cli (4.3.5)
|
middleman-cli (4.3.11)
|
||||||
thor (>= 0.17.0, < 2.0)
|
thor (>= 0.17.0, < 2.0)
|
||||||
middleman-core (4.3.5)
|
middleman-core (4.3.11)
|
||||||
activesupport (>= 4.2, < 5.1)
|
activesupport (>= 4.2, < 6.0)
|
||||||
addressable (~> 2.3)
|
addressable (~> 2.3)
|
||||||
backports (~> 3.6)
|
backports (~> 3.6)
|
||||||
bundler
|
bundler
|
||||||
@@ -70,33 +71,34 @@ GEM
|
|||||||
servolux
|
servolux
|
||||||
tilt (~> 2.0.9)
|
tilt (~> 2.0.9)
|
||||||
uglifier (~> 3.0)
|
uglifier (~> 3.0)
|
||||||
minitest (5.12.2)
|
minitest (5.14.3)
|
||||||
padrino-helpers (0.13.3.4)
|
padrino-helpers (0.13.3.4)
|
||||||
i18n (~> 0.6, >= 0.6.7)
|
i18n (~> 0.6, >= 0.6.7)
|
||||||
padrino-support (= 0.13.3.4)
|
padrino-support (= 0.13.3.4)
|
||||||
tilt (>= 1.4.1, < 3)
|
tilt (>= 1.4.1, < 3)
|
||||||
padrino-support (0.13.3.4)
|
padrino-support (0.13.3.4)
|
||||||
activesupport (>= 3.1)
|
activesupport (>= 3.1)
|
||||||
parallel (1.17.0)
|
parallel (1.20.1)
|
||||||
public_suffix (4.0.1)
|
public_suffix (4.0.6)
|
||||||
rack (2.0.7)
|
rack (2.2.3)
|
||||||
rb-fsevent (0.10.3)
|
rb-fsevent (0.10.4)
|
||||||
rb-inotify (0.10.0)
|
rb-inotify (0.10.1)
|
||||||
ffi (~> 1.0)
|
ffi (~> 1.0)
|
||||||
sassc (2.2.1)
|
rexml (3.2.4)
|
||||||
|
sassc (2.4.0)
|
||||||
ffi (~> 1.9)
|
ffi (~> 1.9)
|
||||||
servolux (0.13.0)
|
servolux (0.13.0)
|
||||||
temple (0.8.2)
|
temple (0.8.2)
|
||||||
thor (0.20.3)
|
thor (1.1.0)
|
||||||
thread_safe (0.3.6)
|
thread_safe (0.3.6)
|
||||||
tilt (2.0.10)
|
tilt (2.0.10)
|
||||||
tzinfo (1.2.5)
|
tzinfo (1.2.9)
|
||||||
thread_safe (~> 0.1)
|
thread_safe (~> 0.1)
|
||||||
uglifier (3.2.0)
|
uglifier (3.2.0)
|
||||||
execjs (>= 0.3.0, < 3)
|
execjs (>= 0.3.0, < 3)
|
||||||
|
|
||||||
PLATFORMS
|
PLATFORMS
|
||||||
ruby
|
x86_64-linux
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
middleman (~> 4.2)
|
middleman (~> 4.2)
|
||||||
@@ -105,4 +107,4 @@ DEPENDENCIES
|
|||||||
wdm (~> 0.1)
|
wdm (~> 0.1)
|
||||||
|
|
||||||
BUNDLED WITH
|
BUNDLED WITH
|
||||||
2.1.4
|
2.2.4
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
README.md
|
|
||||||
yarn.lock
|
|
||||||
@@ -1,2 +1 @@
|
|||||||
README.md
|
README.md
|
||||||
build
|
|
||||||
@@ -13,6 +13,6 @@
|
|||||||
"nuxt": "^2.0.0"
|
"nuxt": "^2.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"nodemon": "^1.18.9"
|
"nodemon": "^2.0.7"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
8116
examples/nuxtjs/yarn.lock
Normal file
8116
examples/nuxtjs/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,10 +0,0 @@
|
|||||||
# editorconfig.org
|
|
||||||
root = true
|
|
||||||
|
|
||||||
[*]
|
|
||||||
charset = utf-8
|
|
||||||
end_of_line = lf
|
|
||||||
indent_size = 2
|
|
||||||
indent_style = space
|
|
||||||
insert_final_newline = true
|
|
||||||
trim_trailing_whitespace = true
|
|
||||||
@@ -3,5 +3,11 @@
|
|||||||
# system. Any custom values should go in .env and .env should *not* be checked
|
# system. Any custom values should go in .env and .env should *not* be checked
|
||||||
# into version control.
|
# into version control.
|
||||||
|
|
||||||
|
# schema.prisma defaults
|
||||||
DATABASE_URL=file:./dev.db
|
DATABASE_URL=file:./dev.db
|
||||||
BINARY_TARGET=native
|
|
||||||
|
# location of the test database for api service scenarios (defaults to ./.redwood/test.db if not set)
|
||||||
|
# TEST_DATABASE_URL=file:./.redwood/test.db
|
||||||
|
|
||||||
|
# disables Prisma CLI update notifier
|
||||||
|
PRISMA_HIDE_UPDATE_MESSAGE=true
|
||||||
|
|||||||
3
examples/redwoodjs/.gitignore
vendored
3
examples/redwoodjs/.gitignore
vendored
@@ -1,10 +1,13 @@
|
|||||||
|
.idea
|
||||||
.DS_Store
|
.DS_Store
|
||||||
.env
|
.env
|
||||||
.netlify
|
.netlify
|
||||||
|
.redwood
|
||||||
dev.db
|
dev.db
|
||||||
dist
|
dist
|
||||||
dist-babel
|
dist-babel
|
||||||
node_modules
|
node_modules
|
||||||
yarn-error.log
|
yarn-error.log
|
||||||
|
web/public/mockServiceWorker.js
|
||||||
|
|
||||||
.vercel
|
.vercel
|
||||||
@@ -1 +0,0 @@
|
|||||||
lts/*
|
|
||||||
@@ -5,11 +5,11 @@ datasource DS {
|
|||||||
|
|
||||||
generator client {
|
generator client {
|
||||||
provider = "prisma-client-js"
|
provider = "prisma-client-js"
|
||||||
binaryTargets = env("BINARY_TARGET")
|
binaryTargets = "native"
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define your own datamodels here and run `yarn redwood db save` to create
|
// Define your own datamodels here and run `yarn redwood prisma migrate dev`
|
||||||
// migrations for them.
|
// to create migrations for them and apply to your dev DB.
|
||||||
// TODO: Please remove the following example:
|
// TODO: Please remove the following example:
|
||||||
model UserExample {
|
model UserExample {
|
||||||
id Int @id @default(autoincrement())
|
id Int @id @default(autoincrement())
|
||||||
@@ -6,6 +6,8 @@ dotenv.config()
|
|||||||
const db = new PrismaClient()
|
const db = new PrismaClient()
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
|
// https://www.prisma.io/docs/guides/prisma-guides/seed-database
|
||||||
|
//
|
||||||
// Seed data is database data that needs to exist for your app to run.
|
// Seed data is database data that needs to exist for your app to run.
|
||||||
// Ideally this file should be idempotent: running it multiple times
|
// Ideally this file should be idempotent: running it multiple times
|
||||||
// will result in the same database state (usually by checking for the
|
// will result in the same database state (usually by checking for the
|
||||||
@@ -16,11 +18,11 @@ async function main() {
|
|||||||
// await db.user.create({ data: { name: 'Admin', email: 'admin@email.com' }})
|
// await db.user.create({ data: { name: 'Admin', email: 'admin@email.com' }})
|
||||||
// }
|
// }
|
||||||
|
|
||||||
console.info('No data to seed. See api/prisma/seeds.js for info.')
|
console.info('No data to seed. See api/db/seed.js for info.')
|
||||||
}
|
}
|
||||||
|
|
||||||
main()
|
main()
|
||||||
.catch((e) => console.error(e))
|
.catch((e) => console.error(e))
|
||||||
.finally(async () => {
|
.finally(async () => {
|
||||||
await db.disconnect()
|
await db.$disconnect()
|
||||||
})
|
})
|
||||||
6
examples/redwoodjs/api/jest.config.js
Normal file
6
examples/redwoodjs/api/jest.config.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
const { getConfig } = require('@redwoodjs/core')
|
||||||
|
|
||||||
|
const config = getConfig({ type: 'jest', target: 'node' })
|
||||||
|
config.displayName.name = 'api'
|
||||||
|
|
||||||
|
module.exports = config
|
||||||
@@ -5,5 +5,5 @@
|
|||||||
"src/*": ["./src/*"]
|
"src/*": ["./src/*"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"include": ["src/**/*"]
|
"include": ["src/**/*", "../.redwood/index.d.ts"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,6 @@
|
|||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@redwoodjs/api": "0.15.0"
|
"@redwoodjs/api": "^0.25.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,17 +3,18 @@ import {
|
|||||||
makeMergedSchema,
|
makeMergedSchema,
|
||||||
makeServices,
|
makeServices,
|
||||||
} from '@redwoodjs/api'
|
} from '@redwoodjs/api'
|
||||||
import importAll from '@redwoodjs/api/importAll.macro'
|
|
||||||
|
|
||||||
|
import schemas from 'src/graphql/**/*.{js,ts}'
|
||||||
import { db } from 'src/lib/db'
|
import { db } from 'src/lib/db'
|
||||||
|
import services from 'src/services/**/*.{js,ts}'
|
||||||
const schemas = importAll('api', 'graphql')
|
|
||||||
const services = importAll('api', 'services')
|
|
||||||
|
|
||||||
export const handler = createGraphQLHandler({
|
export const handler = createGraphQLHandler({
|
||||||
schema: makeMergedSchema({
|
schema: makeMergedSchema({
|
||||||
schemas,
|
schemas,
|
||||||
services: makeServices({ services }),
|
services: makeServices({ services }),
|
||||||
}),
|
}),
|
||||||
db,
|
onException: () => {
|
||||||
|
// Disconnect from your database with an unhandled exception.
|
||||||
|
db.$disconnect()
|
||||||
|
},
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// See https://github.com/prisma/prisma2/blob/master/docs/prisma-client-js/api.md#constructor
|
// See https://www.prisma.io/docs/reference/tools-and-interfaces/prisma-client/constructor
|
||||||
// for options.
|
// for options.
|
||||||
|
|
||||||
import { PrismaClient } from '@prisma/client'
|
import { PrismaClient } from '@prisma/client'
|
||||||
|
|||||||
7
examples/redwoodjs/graphql.config.js
Normal file
7
examples/redwoodjs/graphql.config.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
const { getConfig } = require('@redwoodjs/internal')
|
||||||
|
|
||||||
|
const config = getConfig()
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
schema: `http://${config.api.host}:${config.api.port}/graphql`,
|
||||||
|
}
|
||||||
@@ -3,11 +3,12 @@
|
|||||||
"workspaces": {
|
"workspaces": {
|
||||||
"packages": [
|
"packages": [
|
||||||
"api",
|
"api",
|
||||||
"web"
|
"web",
|
||||||
|
"packages/*"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@redwoodjs/core": "0.15.0"
|
"@redwoodjs/core": "^0.25.0"
|
||||||
},
|
},
|
||||||
"eslintConfig": {
|
"eslintConfig": {
|
||||||
"extends": "@redwoodjs/eslint-config"
|
"extends": "@redwoodjs/eslint-config"
|
||||||
|
|||||||
@@ -6,4 +6,12 @@ module.exports = {
|
|||||||
semi: false,
|
semi: false,
|
||||||
singleQuote: true,
|
singleQuote: true,
|
||||||
arrowParens: 'always',
|
arrowParens: 'always',
|
||||||
|
overrides: [
|
||||||
|
{
|
||||||
|
files: 'Routes.js',
|
||||||
|
options: {
|
||||||
|
printWidth: 200,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,15 @@
|
|||||||
|
# This file contains the configuration settings for your Redwood app.
|
||||||
|
# This file is also what makes your Redwood app a Redwood app.
|
||||||
|
# If you remove it and try to run `yarn rw dev`, you'll get an error.
|
||||||
|
#
|
||||||
|
# For the full list of options, see the "App Configuration: redwood.toml" doc:
|
||||||
|
# https://redwoodjs.com/docs/app-configuration-redwood-toml
|
||||||
|
|
||||||
[web]
|
[web]
|
||||||
port = 8910
|
port = 8910
|
||||||
apiProxyPath = "/api"
|
apiProxyPath = "/api"
|
||||||
[api]
|
[api]
|
||||||
port = 8911
|
port = 8911
|
||||||
|
schemaPath = "./api/db/schema.prisma"
|
||||||
[browser]
|
[browser]
|
||||||
open = false
|
open = false
|
||||||
|
|||||||
6
examples/redwoodjs/web/jest.config.js
Normal file
6
examples/redwoodjs/web/jest.config.js
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
const { getConfig } = require('@redwoodjs/core')
|
||||||
|
|
||||||
|
const config = getConfig({ type: 'jest', target: 'browser' })
|
||||||
|
config.displayName.name = 'web'
|
||||||
|
|
||||||
|
module.exports = config
|
||||||
@@ -6,5 +6,5 @@
|
|||||||
},
|
},
|
||||||
"jsx": "preserve"
|
"jsx": "preserve"
|
||||||
},
|
},
|
||||||
"include": ["src/**/*"]
|
"include": ["src/**/*", "../.redwood/index.d.ts"]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,12 +2,20 @@
|
|||||||
"name": "web",
|
"name": "web",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"browserslist": [
|
"browserslist": {
|
||||||
"defaults"
|
"development": [
|
||||||
],
|
"last 1 version"
|
||||||
|
],
|
||||||
|
"production": [
|
||||||
|
"defaults",
|
||||||
|
"not IE 11",
|
||||||
|
"not IE_Mob 11"
|
||||||
|
]
|
||||||
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@redwoodjs/router": "0.15.0",
|
"@redwoodjs/forms": "^0.25.0",
|
||||||
"@redwoodjs/web": "0.15.0",
|
"@redwoodjs/router": "^0.25.0",
|
||||||
|
"@redwoodjs/web": "^0.25.0",
|
||||||
"prop-types": "^15.7.2",
|
"prop-types": "^15.7.2",
|
||||||
"react": "^16.13.1",
|
"react": "^16.13.1",
|
||||||
"react-dom": "^16.13.1"
|
"react-dom": "^16.13.1"
|
||||||
|
|||||||
@@ -1,13 +1,19 @@
|
|||||||
# Static Assets
|
# Static Assets
|
||||||
|
|
||||||
Use this folder to add static files directly to your app. All included files and folders will be copied directly into the `/dist` folder (created when Webpack builds for production). They will also be available during development when you run `yarn rw dev`.
|
Use this folder to add static files directly to your app. All included files and folders will be copied directly into the `/dist` folder (created when Webpack builds for production). They will also be available during development when you run `yarn rw dev`.
|
||||||
>Note: files will *not* hot reload while the development server is running. You'll need to manually stop/start to access file changes.
|
|
||||||
|
> Note: files will _not_ hot reload while the development server is running. You'll need to manually stop/start to access file changes.
|
||||||
|
|
||||||
### Example Use
|
### Example Use
|
||||||
|
|
||||||
A file like `favicon.png` will be copied to `/dist/favicon.png`. A folder containing a file such as `static-files/my-logo.jpg` will be copied to `/dist/static-files/my-logo.jpg`. These can be referenced in your code directly without any special handling, e.g.
|
A file like `favicon.png` will be copied to `/dist/favicon.png`. A folder containing a file such as `static-files/my-logo.jpg` will be copied to `/dist/static-files/my-logo.jpg`. These can be referenced in your code directly without any special handling, e.g.
|
||||||
|
|
||||||
```
|
```
|
||||||
<link rel="icon" type="image/png" href="/favicon.png" />
|
<link rel="icon" type="image/png" href="/favicon.png" />
|
||||||
```
|
```
|
||||||
|
|
||||||
and
|
and
|
||||||
|
|
||||||
```
|
```
|
||||||
<img src="/static-files/my-logo.jpg"> alt="Logo" />
|
<img src="/static-files/my-logo.jpg"> alt="Logo" />
|
||||||
```
|
```
|
||||||
@@ -15,12 +21,15 @@ and
|
|||||||
Behind the scenes, we are using Webpack's ["copy-webpack-plugin"](https://github.com/webpack-contrib/copy-webpack-plugin).
|
Behind the scenes, we are using Webpack's ["copy-webpack-plugin"](https://github.com/webpack-contrib/copy-webpack-plugin).
|
||||||
|
|
||||||
## Best Practices
|
## Best Practices
|
||||||
|
|
||||||
Because assets in this folder are bypassing the javascript module system, **this folder should be used sparingly** for assets such as favicons, robots.txt, manifests, libraries incompatible with Webpack, etc.
|
Because assets in this folder are bypassing the javascript module system, **this folder should be used sparingly** for assets such as favicons, robots.txt, manifests, libraries incompatible with Webpack, etc.
|
||||||
|
|
||||||
In general, it's best to import files directly into a template, page, or component. This allows Webpack to include that file in the bundle, which ensures Webpack will correctly process and move assets into the distribution folder, providing error checks and correct paths along the way.
|
In general, it's best to import files directly into a template, page, or component. This allows Webpack to include that file in the bundle, which ensures Webpack will correctly process and move assets into the distribution folder, providing error checks and correct paths along the way.
|
||||||
|
|
||||||
### Example Asset Import with Webpack
|
### Example Asset Import with Webpack
|
||||||
|
|
||||||
Instead of handling our logo image as a static file per the example above, we can do the following:
|
Instead of handling our logo image as a static file per the example above, we can do the following:
|
||||||
|
|
||||||
```
|
```
|
||||||
import React from "react"
|
import React from "react"
|
||||||
import logo from "./my-logo.jpg"
|
import logo from "./my-logo.jpg"
|
||||||
|
|||||||
@@ -1,16 +1,18 @@
|
|||||||
import ReactDOM from 'react-dom'
|
import ReactDOM from 'react-dom'
|
||||||
import { RedwoodProvider, FatalErrorBoundary } from '@redwoodjs/web'
|
|
||||||
import FatalErrorPage from 'src/pages/FatalErrorPage'
|
|
||||||
|
|
||||||
|
import { FatalErrorBoundary } from '@redwoodjs/web'
|
||||||
|
import { RedwoodApolloProvider } from '@redwoodjs/web/apollo'
|
||||||
|
|
||||||
|
import FatalErrorPage from 'src/pages/FatalErrorPage'
|
||||||
import Routes from 'src/Routes'
|
import Routes from 'src/Routes'
|
||||||
|
|
||||||
import './index.css'
|
import './index.css'
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<FatalErrorBoundary page={FatalErrorPage}>
|
<FatalErrorBoundary page={FatalErrorPage}>
|
||||||
<RedwoodProvider>
|
<RedwoodApolloProvider>
|
||||||
<Routes />
|
<Routes />
|
||||||
</RedwoodProvider>
|
</RedwoodApolloProvider>
|
||||||
</FatalErrorBoundary>,
|
</FatalErrorBoundary>,
|
||||||
document.getElementById('redwood-app')
|
document.getElementById('redwood-app')
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
export default () => (
|
import { Link, routes } from '@redwoodjs/router'
|
||||||
|
|
||||||
|
const AboutPage = () => (
|
||||||
<main>
|
<main>
|
||||||
<style
|
<style
|
||||||
dangerouslySetInnerHTML={{
|
dangerouslySetInnerHTML={{
|
||||||
@@ -36,9 +38,16 @@ export default () => (
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<section>
|
<section>
|
||||||
<h1>
|
<h1>About</h1>
|
||||||
<span>About RedwoodJS</span>
|
<p>
|
||||||
</h1>
|
Find me in <code>./web/src/pages/AboutPage/AboutPage.js</code>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
My default route is named <code>about</code>, link to me with `
|
||||||
|
<Link to={routes.about()}>About</Link>`
|
||||||
|
</p>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
export default AboutPage
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
export default () => (
|
import { Link, routes } from '@redwoodjs/router'
|
||||||
|
|
||||||
|
const HomePage = () => (
|
||||||
<main>
|
<main>
|
||||||
<style
|
<style
|
||||||
dangerouslySetInnerHTML={{
|
dangerouslySetInnerHTML={{
|
||||||
@@ -36,9 +38,16 @@ export default () => (
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<section>
|
<section>
|
||||||
<h1>
|
<h1>Welcome to RedwoodJS!</h1>
|
||||||
<span>Welcome to RedwoodJS!</span>
|
<p>
|
||||||
</h1>
|
Find me in <code>./web/src/pages/HomePage/HomePage.js</code>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
My default route is named <code>home</code>, link to me with `
|
||||||
|
<Link to={routes.home()}>Home</Link>`
|
||||||
|
</p>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
)
|
)
|
||||||
|
|
||||||
|
export default HomePage
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import HomePage from './HomePage'
|
||||||
|
|
||||||
|
export const generated = () => {
|
||||||
|
return <HomePage />
|
||||||
|
}
|
||||||
|
|
||||||
|
export default { title: 'Pages/HomePage' }
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vercel/frameworks",
|
"name": "@vercel/frameworks",
|
||||||
"version": "0.2.1-canary.1",
|
"version": "0.3.0",
|
||||||
"main": "./dist/frameworks.js",
|
"main": "./dist/frameworks.js",
|
||||||
"types": "./dist/frameworks.d.ts",
|
"types": "./dist/frameworks.d.ts",
|
||||||
"files": [
|
"files": [
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
"@types/js-yaml": "3.12.1",
|
"@types/js-yaml": "3.12.1",
|
||||||
"@types/node": "12.0.4",
|
"@types/node": "12.0.4",
|
||||||
"@types/node-fetch": "2.5.8",
|
"@types/node-fetch": "2.5.8",
|
||||||
"@vercel/routing-utils": "1.9.3-canary.0",
|
"@vercel/routing-utils": "1.10.0",
|
||||||
"ajv": "6.12.2",
|
"ajv": "6.12.2",
|
||||||
"jest": "24.9.0",
|
"jest": "24.9.0",
|
||||||
"ts-jest": "24.1.0",
|
"ts-jest": "24.1.0",
|
||||||
|
|||||||
@@ -1320,8 +1320,7 @@ export const frameworks = [
|
|||||||
placeholder: '`yarn install` or `npm install`',
|
placeholder: '`yarn install` or `npm install`',
|
||||||
},
|
},
|
||||||
buildCommand: {
|
buildCommand: {
|
||||||
value:
|
value: 'yarn rw deploy vercel',
|
||||||
'yarn rw build && yarn rw db up --no-db-client --auto-approve && yarn rw dataMigrate up',
|
|
||||||
},
|
},
|
||||||
devCommand: {
|
devCommand: {
|
||||||
value: 'yarn rw dev --fwd="--port=$PORT --open=false"',
|
value: 'yarn rw dev --fwd="--port=$PORT --open=false"',
|
||||||
@@ -1331,8 +1330,7 @@ export const frameworks = [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
devCommand: 'yarn rw dev --fwd="--port=$PORT --open=false',
|
devCommand: 'yarn rw dev --fwd="--port=$PORT --open=false',
|
||||||
buildCommand:
|
buildCommand: 'yarn rw deploy vercel',
|
||||||
'yarn rw build && yarn rw db up --no-db-client --auto-approve && yarn rw dataMigrate up',
|
|
||||||
getOutputDirName: async () => 'public',
|
getOutputDirName: async () => 'public',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -1350,12 +1348,15 @@ export const frameworks = [
|
|||||||
some: [
|
some: [
|
||||||
{
|
{
|
||||||
path: 'config.yaml',
|
path: 'config.yaml',
|
||||||
|
matchContent: 'baseURL',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'config.toml',
|
path: 'config.toml',
|
||||||
|
matchContent: 'baseURL',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: 'config.json',
|
path: 'config.json',
|
||||||
|
matchContent: 'baseURL',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
@@ -1385,11 +1386,12 @@ export const frameworks = [
|
|||||||
|
|
||||||
return (config && config.publishDir) || 'public';
|
return (config && config.publishDir) || 'public';
|
||||||
},
|
},
|
||||||
|
defaultVersion: '0.58.2',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Jekyll',
|
name: 'Jekyll',
|
||||||
slug: 'jekyll',
|
slug: 'jekyll',
|
||||||
demo: 'https://jekyll.now-examples.now.sh',
|
demo: 'https://jekyll.now-examples.vercel.app',
|
||||||
logo:
|
logo:
|
||||||
'https://raw.githubusercontent.com/vercel/vercel/master/packages/frameworks/logos/jekyll.svg',
|
'https://raw.githubusercontent.com/vercel/vercel/master/packages/frameworks/logos/jekyll.svg',
|
||||||
tagline:
|
tagline:
|
||||||
@@ -1426,6 +1428,7 @@ export const frameworks = [
|
|||||||
);
|
);
|
||||||
return (config && config.destination) || '_site';
|
return (config && config.destination) || '_site';
|
||||||
},
|
},
|
||||||
|
cachePattern: '{vendor/bin,vendor/cache,vendor/bundle}/**',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Brunch',
|
name: 'Brunch',
|
||||||
@@ -1465,7 +1468,7 @@ export const frameworks = [
|
|||||||
{
|
{
|
||||||
name: 'Middleman',
|
name: 'Middleman',
|
||||||
slug: 'middleman',
|
slug: 'middleman',
|
||||||
demo: 'https://middleman.now-examples.now.sh',
|
demo: 'https://middleman.now-examples.vercel.app',
|
||||||
logo:
|
logo:
|
||||||
'https://raw.githubusercontent.com/vercel/vercel/master/packages/frameworks/logos/middleman.svg',
|
'https://raw.githubusercontent.com/vercel/vercel/master/packages/frameworks/logos/middleman.svg',
|
||||||
tagline:
|
tagline:
|
||||||
@@ -1496,6 +1499,7 @@ export const frameworks = [
|
|||||||
devCommand: 'bundle exec middleman server -p $PORT',
|
devCommand: 'bundle exec middleman server -p $PORT',
|
||||||
buildCommand: 'bundle exec middleman build',
|
buildCommand: 'bundle exec middleman build',
|
||||||
getOutputDirName: async () => 'build',
|
getOutputDirName: async () => 'build',
|
||||||
|
cachePattern: '{vendor/bin,vendor/cache,vendor/bundle}/**',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Zola',
|
name: 'Zola',
|
||||||
@@ -1506,6 +1510,14 @@ export const frameworks = [
|
|||||||
tagline: 'Everything you need to make a static site engine in one binary.',
|
tagline: 'Everything you need to make a static site engine in one binary.',
|
||||||
description: 'A Zola app, created with the "Getting Started" tutorial.',
|
description: 'A Zola app, created with the "Getting Started" tutorial.',
|
||||||
website: 'https://www.getzola.org',
|
website: 'https://www.getzola.org',
|
||||||
|
detectors: {
|
||||||
|
every: [
|
||||||
|
{
|
||||||
|
path: 'config.toml',
|
||||||
|
matchContent: 'base_url',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
settings: {
|
settings: {
|
||||||
installCommand: {
|
installCommand: {
|
||||||
placeholder: 'None',
|
placeholder: 'None',
|
||||||
@@ -1523,6 +1535,7 @@ export const frameworks = [
|
|||||||
devCommand: 'zola serve --port $PORT',
|
devCommand: 'zola serve --port $PORT',
|
||||||
buildCommand: 'zola build',
|
buildCommand: 'zola build',
|
||||||
getOutputDirName: async () => 'public',
|
getOutputDirName: async () => 'public',
|
||||||
|
defaultVersion: '0.13.0',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'Other',
|
name: 'Other',
|
||||||
|
|||||||
@@ -170,4 +170,10 @@ export interface Framework {
|
|||||||
* @example "next dev"
|
* @example "next dev"
|
||||||
*/
|
*/
|
||||||
devCommand: string | null;
|
devCommand: string | null;
|
||||||
|
/**
|
||||||
|
* The default version of the framework command that is available within the
|
||||||
|
* build image. Usually an environment variable can be set to override this.
|
||||||
|
* @example "0.13.0"
|
||||||
|
*/
|
||||||
|
defaultVersion?: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vercel/build-utils",
|
"name": "@vercel/build-utils",
|
||||||
"version": "2.9.1-canary.1",
|
"version": "2.10.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"types": "./dist/index.d.js",
|
"types": "./dist/index.d.js",
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
"@types/node-fetch": "^2.1.6",
|
"@types/node-fetch": "^2.1.6",
|
||||||
"@types/semver": "6.0.0",
|
"@types/semver": "6.0.0",
|
||||||
"@types/yazl": "^2.4.1",
|
"@types/yazl": "^2.4.1",
|
||||||
"@vercel/frameworks": "0.2.1-canary.1",
|
"@vercel/frameworks": "0.3.0",
|
||||||
"@vercel/ncc": "0.24.0",
|
"@vercel/ncc": "0.24.0",
|
||||||
"aggregate-error": "3.0.1",
|
"aggregate-error": "3.0.1",
|
||||||
"async-retry": "1.2.3",
|
"async-retry": "1.2.3",
|
||||||
|
|||||||
@@ -311,11 +311,16 @@ export async function detectBuilders(
|
|||||||
if (frontendBuilder) {
|
if (frontendBuilder) {
|
||||||
builders.push(frontendBuilder);
|
builders.push(frontendBuilder);
|
||||||
|
|
||||||
if (hasNextApiFiles && apiBuilders.length) {
|
if (
|
||||||
|
hasNextApiFiles &&
|
||||||
|
apiBuilders.some(b => isOfficialRuntime('node', b.use))
|
||||||
|
) {
|
||||||
warnings.push({
|
warnings.push({
|
||||||
code: 'conflicting_files',
|
code: 'conflicting_files',
|
||||||
message:
|
message:
|
||||||
'It is not possible to use `api` and `pages/api` at the same time, please only use one option',
|
'When using Next.js, it is recommended to place Node.js Serverless Functions inside of the `pages/api` (provided by Next.js) directory instead of `api` (provided by Vercel).',
|
||||||
|
link: 'https://nextjs.org/docs/api-routes/introduction',
|
||||||
|
action: 'Learn More',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -944,8 +949,8 @@ function getRouteResult(
|
|||||||
const rewriteRoutes: Route[] = [];
|
const rewriteRoutes: Route[] = [];
|
||||||
const errorRoutes: Route[] = [];
|
const errorRoutes: Route[] = [];
|
||||||
const framework = frontendBuilder?.config?.framework || '';
|
const framework = frontendBuilder?.config?.framework || '';
|
||||||
const use = frontendBuilder?.use || '';
|
const isNextjs =
|
||||||
const isNextjs = framework === 'nextjs' || use.startsWith('@vercel/next');
|
framework === 'nextjs' || isOfficialRuntime('next', frontendBuilder?.use);
|
||||||
const ignoreRuntimes = slugToFramework.get(framework)?.ignoreRuntimes;
|
const ignoreRuntimes = slugToFramework.get(framework)?.ignoreRuntimes;
|
||||||
|
|
||||||
if (apiRoutes && apiRoutes.length > 0) {
|
if (apiRoutes && apiRoutes.length > 0) {
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import { DetectorFilesystem } from './detectors/filesystem';
|
|||||||
|
|
||||||
export interface DetectFrameworkOptions {
|
export interface DetectFrameworkOptions {
|
||||||
fs: DetectorFilesystem;
|
fs: DetectorFilesystem;
|
||||||
frameworkList: Framework[];
|
frameworkList: readonly Framework[];
|
||||||
}
|
}
|
||||||
|
|
||||||
async function matches(fs: DetectorFilesystem, framework: Framework) {
|
async function matches(fs: DetectorFilesystem, framework: Framework) {
|
||||||
|
|||||||
@@ -51,8 +51,8 @@ export default async function glob(
|
|||||||
stat,
|
stat,
|
||||||
`statCache does not contain value for ${relativePath} (resolved to ${fsPath})`
|
`statCache does not contain value for ${relativePath} (resolved to ${fsPath})`
|
||||||
);
|
);
|
||||||
if (stat.isFile()) {
|
const isSymlink = options.symlinks![fsPath];
|
||||||
const isSymlink = options.symlinks![fsPath];
|
if (isSymlink || stat.isFile()) {
|
||||||
if (isSymlink) {
|
if (isSymlink) {
|
||||||
stat = await lstat(fsPath);
|
stat = await lstat(fsPath);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { intersects, validRange } from 'semver';
|
import { intersects, validRange } from 'semver';
|
||||||
import boxen from 'boxen';
|
|
||||||
import { NodeVersion } from '../types';
|
import { NodeVersion } from '../types';
|
||||||
import { NowBuildError } from '../errors';
|
import { NowBuildError } from '../errors';
|
||||||
import debug from '../debug';
|
import debug from '../debug';
|
||||||
@@ -11,7 +10,7 @@ const allOptions = [
|
|||||||
major: 10,
|
major: 10,
|
||||||
range: '10.x',
|
range: '10.x',
|
||||||
runtime: 'nodejs10.x',
|
runtime: 'nodejs10.x',
|
||||||
discontinueDate: new Date('2021-03-30'),
|
discontinueDate: new Date('2021-04-20'),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
major: 8,
|
major: 8,
|
||||||
@@ -21,15 +20,15 @@ const allOptions = [
|
|||||||
},
|
},
|
||||||
] as const;
|
] as const;
|
||||||
|
|
||||||
const pleaseSet =
|
function getHint(isAuto: boolean) {
|
||||||
'Please change your Project Settings or set "engines": { "node": "' +
|
const { major, range } = getLatestNodeVersion();
|
||||||
getLatestNodeVersion().range +
|
return isAuto
|
||||||
'" } in your `package.json` file to use Node.js ' +
|
? `Please set Node.js Version to ${range} in your Project Settings to use Node.js ${major}.`
|
||||||
getLatestNodeVersion().major +
|
: `Please set "engines": { "node": "${range}" } in your \`package.json\` file to use Node.js ${major}.`;
|
||||||
'.';
|
}
|
||||||
|
|
||||||
const upstreamProvider =
|
const upstreamProvider =
|
||||||
'This change is the result of a decision made by an upstream infrastructure provider (AWS).' +
|
'This change is the result of a decision made by an upstream infrastructure provider (AWS).';
|
||||||
'\nRead more: https://docs.aws.amazon.com/lambda/latest/dg/runtime-support-policy.html';
|
|
||||||
|
|
||||||
export function getLatestNodeVersion() {
|
export function getLatestNodeVersion() {
|
||||||
return allOptions[0];
|
return allOptions[0];
|
||||||
@@ -40,8 +39,8 @@ export function getDiscontinuedNodeVersions(): NodeVersion[] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getSupportedNodeVersion(
|
export async function getSupportedNodeVersion(
|
||||||
engineRange?: string,
|
engineRange: string | undefined,
|
||||||
isAuto?: boolean
|
isAuto: boolean
|
||||||
): Promise<NodeVersion> {
|
): Promise<NodeVersion> {
|
||||||
let selection: NodeVersion = getLatestNodeVersion();
|
let selection: NodeVersion = getLatestNodeVersion();
|
||||||
|
|
||||||
@@ -55,60 +54,35 @@ export async function getSupportedNodeVersion(
|
|||||||
return intersects(o.range, engineRange);
|
return intersects(o.range, engineRange);
|
||||||
});
|
});
|
||||||
if (!found) {
|
if (!found) {
|
||||||
const intro =
|
|
||||||
isAuto || !engineRange
|
|
||||||
? 'This project is using an invalid version of Node.js and must be changed.'
|
|
||||||
: 'Found `engines` in `package.json` with an invalid Node.js version range: "' +
|
|
||||||
engineRange +
|
|
||||||
'".';
|
|
||||||
throw new NowBuildError({
|
throw new NowBuildError({
|
||||||
code: 'BUILD_UTILS_NODE_VERSION_INVALID',
|
code: 'BUILD_UTILS_NODE_VERSION_INVALID',
|
||||||
link:
|
link: 'http://vercel.link/node-version',
|
||||||
'https://vercel.com/docs/runtimes#official-runtimes/node-js/node-js-version',
|
message: `Found invalid Node.js Version: "${engineRange}". ${getHint(
|
||||||
message: intro + '\n' + pleaseSet,
|
isAuto
|
||||||
|
)}`,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isDiscontinued(selection)) {
|
if (isDiscontinued(selection)) {
|
||||||
const intro =
|
const intro = `Node.js Version "${selection.range}" is discontinued and must be upgraded.`;
|
||||||
isAuto || !engineRange
|
|
||||||
? 'This project is using a discontinued version of Node.js (' +
|
|
||||||
selection.range +
|
|
||||||
') and must be upgraded.'
|
|
||||||
: 'Found `engines` in `package.json` with a discontinued Node.js version range: "' +
|
|
||||||
engineRange +
|
|
||||||
'".';
|
|
||||||
throw new NowBuildError({
|
throw new NowBuildError({
|
||||||
code: 'BUILD_UTILS_NODE_VERSION_DISCONTINUED',
|
code: 'BUILD_UTILS_NODE_VERSION_DISCONTINUED',
|
||||||
link:
|
link: 'http://vercel.link/node-version',
|
||||||
'https://vercel.com/docs/runtimes#official-runtimes/node-js/node-js-version',
|
message: `${intro} ${getHint(isAuto)} ${upstreamProvider}`,
|
||||||
message: intro + '\n' + pleaseSet + '\n' + upstreamProvider,
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
debug(
|
debug(`Selected Node.js ${selection.range}`);
|
||||||
isAuto || !engineRange
|
|
||||||
? 'Using default Node.js range: "' + selection.range + '".'
|
|
||||||
: 'Found `engines` in `package.json`, selecting range: "' +
|
|
||||||
selection.range +
|
|
||||||
'".'
|
|
||||||
);
|
|
||||||
|
|
||||||
if (selection.discontinueDate) {
|
if (selection.discontinueDate) {
|
||||||
const d = selection.discontinueDate.toISOString().split('T')[0];
|
const d = selection.discontinueDate.toISOString().split('T')[0];
|
||||||
console.warn(
|
console.warn(
|
||||||
boxen(
|
`Error: Node.js version ${
|
||||||
'NOTICE' +
|
selection.range
|
||||||
'\n' +
|
} is deprecated. Deployments created on or after ${d} will fail to build. ${getHint(
|
||||||
`\nNode.js version ${selection.range} has reached end-of-life.` +
|
isAuto
|
||||||
`\nAs a result, deployments created on or after ${d} will fail to build.` +
|
)} ${upstreamProvider}`
|
||||||
'\n' +
|
|
||||||
pleaseSet +
|
|
||||||
'\n' +
|
|
||||||
upstreamProvider,
|
|
||||||
{ padding: 1 }
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import debug from '../debug';
|
|||||||
import spawn from 'cross-spawn';
|
import spawn from 'cross-spawn';
|
||||||
import { SpawnOptions } from 'child_process';
|
import { SpawnOptions } from 'child_process';
|
||||||
import { deprecate } from 'util';
|
import { deprecate } from 'util';
|
||||||
import { cpus } from 'os';
|
|
||||||
import { NowBuildError } from '../errors';
|
import { NowBuildError } from '../errors';
|
||||||
import { Meta, PackageJson, NodeVersion, Config } from '../types';
|
import { Meta, PackageJson, NodeVersion, Config } from '../types';
|
||||||
import { getSupportedNodeVersion, getLatestNodeVersion } from './node-version';
|
import { getSupportedNodeVersion, getLatestNodeVersion } from './node-version';
|
||||||
@@ -177,16 +176,13 @@ export async function getNodeVersion(
|
|||||||
let { nodeVersion } = config;
|
let { nodeVersion } = config;
|
||||||
let isAuto = true;
|
let isAuto = true;
|
||||||
if (packageJson && packageJson.engines && packageJson.engines.node) {
|
if (packageJson && packageJson.engines && packageJson.engines.node) {
|
||||||
if (
|
const { node } = packageJson.engines;
|
||||||
nodeVersion &&
|
if (nodeVersion && nodeVersion !== node && !meta.isDev) {
|
||||||
nodeVersion !== packageJson.engines.node &&
|
|
||||||
!meta.isDev
|
|
||||||
) {
|
|
||||||
console.warn(
|
console.warn(
|
||||||
'Warning: Due to `engines` existing in your `package.json` file, the Node.js Version defined in your Project Settings will not apply. Learn More: http://vercel.link/node-version'
|
`Warning: Due to "engines": { "node": "${node}" } in your \`package.json\` file, the Node.js Version defined in your Project Settings ("${nodeVersion}") will not apply. Learn More: http://vercel.link/node-version`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
nodeVersion = packageJson.engines.node;
|
nodeVersion = node;
|
||||||
isAuto = false;
|
isAuto = false;
|
||||||
}
|
}
|
||||||
return getSupportedNodeVersion(nodeVersion, isAuto);
|
return getSupportedNodeVersion(nodeVersion, isAuto);
|
||||||
@@ -328,18 +324,7 @@ export async function runBundleInstall(
|
|||||||
assert(path.isAbsolute(destPath));
|
assert(path.isAbsolute(destPath));
|
||||||
const opts = { ...spawnOpts, cwd: destPath, prettyCommand: 'bundle install' };
|
const opts = { ...spawnOpts, cwd: destPath, prettyCommand: 'bundle install' };
|
||||||
|
|
||||||
await spawnAsync(
|
await spawnAsync('bundle', args.concat(['install']), opts);
|
||||||
'bundle',
|
|
||||||
args.concat([
|
|
||||||
'install',
|
|
||||||
'--no-prune',
|
|
||||||
'--retry',
|
|
||||||
'3',
|
|
||||||
'--jobs',
|
|
||||||
String(cpus().length || 1),
|
|
||||||
]),
|
|
||||||
opts
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function runPipInstall(
|
export async function runPipInstall(
|
||||||
@@ -403,7 +388,7 @@ export async function runPackageJsonScript(
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
// Yarn v2 PnP mode may be activated, so force "node-modules" linker style
|
// Yarn v2 PnP mode may be activated, so force "node-modules" linker style
|
||||||
const env: typeof process.env = { ...spawnOpts?.env };
|
const env: typeof process.env = { ...process.env, ...spawnOpts?.env };
|
||||||
if (!env.YARN_NODE_LINKER) {
|
if (!env.YARN_NODE_LINKER) {
|
||||||
env.YARN_NODE_LINKER = 'node-modules';
|
env.YARN_NODE_LINKER = 'node-modules';
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/env.txt
|
||||||
/node_modules/
|
/node_modules/
|
||||||
/public/build/
|
/public/build/
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,8 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "rollup -c",
|
"build": "rollup -c",
|
||||||
"dev": "rollup -c -w",
|
"dev": "rollup -c -w",
|
||||||
"start": "sirv public"
|
"start": "sirv public",
|
||||||
|
"env": "echo \"$PATH\" > env.txt"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@rollup/plugin-commonjs": "^12.0.0",
|
"@rollup/plugin-commonjs": "^12.0.0",
|
||||||
|
|||||||
1
packages/now-build-utils/test/symlinks/dir/b.txt
Normal file
1
packages/now-build-utils/test/symlinks/dir/b.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
contents
|
||||||
1
packages/now-build-utils/test/symlinks/link-dir
Symbolic link
1
packages/now-build-utils/test/symlinks/link-dir
Symbolic link
@@ -0,0 +1 @@
|
|||||||
|
dir
|
||||||
@@ -2572,6 +2572,101 @@ it('Test `detectRoutes` with `featHandleMiss=true`', async () => {
|
|||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const files = ['api/external.js', 'pages/api/internal.js'];
|
||||||
|
const { builders, warnings } = await detectBuilders(files, null, {
|
||||||
|
featHandleMiss,
|
||||||
|
projectSettings: { framework: 'nextjs' },
|
||||||
|
});
|
||||||
|
expect(builders).toStrictEqual([
|
||||||
|
{
|
||||||
|
config: {
|
||||||
|
zeroConfig: true,
|
||||||
|
},
|
||||||
|
src: 'api/external.js',
|
||||||
|
use: '@vercel/node',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
config: {
|
||||||
|
framework: 'nextjs',
|
||||||
|
zeroConfig: true,
|
||||||
|
},
|
||||||
|
src: 'package.json',
|
||||||
|
use: '@vercel/next',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
expect(warnings).toStrictEqual([
|
||||||
|
{
|
||||||
|
code: 'conflicting_files',
|
||||||
|
message:
|
||||||
|
'When using Next.js, it is recommended to place Node.js Serverless Functions inside of the `pages/api` (provided by Next.js) directory instead of `api` (provided by Vercel).',
|
||||||
|
link: 'https://nextjs.org/docs/api-routes/introduction',
|
||||||
|
action: 'Learn More',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const files = ['api/external.js', 'pages/api/internal.js'];
|
||||||
|
const { builders, warnings } = await detectBuilders(files, null, {
|
||||||
|
featHandleMiss,
|
||||||
|
tag: 'canary',
|
||||||
|
projectSettings: { framework: 'nextjs' },
|
||||||
|
});
|
||||||
|
expect(builders).toStrictEqual([
|
||||||
|
{
|
||||||
|
config: {
|
||||||
|
zeroConfig: true,
|
||||||
|
},
|
||||||
|
src: 'api/external.js',
|
||||||
|
use: '@vercel/node@canary',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
config: {
|
||||||
|
framework: 'nextjs',
|
||||||
|
zeroConfig: true,
|
||||||
|
},
|
||||||
|
src: 'package.json',
|
||||||
|
use: '@vercel/next@canary',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
expect(warnings).toStrictEqual([
|
||||||
|
{
|
||||||
|
code: 'conflicting_files',
|
||||||
|
message:
|
||||||
|
'When using Next.js, it is recommended to place Node.js Serverless Functions inside of the `pages/api` (provided by Next.js) directory instead of `api` (provided by Vercel).',
|
||||||
|
link: 'https://nextjs.org/docs/api-routes/introduction',
|
||||||
|
action: 'Learn More',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const files = ['api/external.go', 'pages/api/internal.js'];
|
||||||
|
const { builders, warnings } = await detectBuilders(files, null, {
|
||||||
|
featHandleMiss,
|
||||||
|
projectSettings: { framework: 'nextjs' },
|
||||||
|
});
|
||||||
|
expect(builders).toStrictEqual([
|
||||||
|
{
|
||||||
|
config: {
|
||||||
|
zeroConfig: true,
|
||||||
|
},
|
||||||
|
src: 'api/external.go',
|
||||||
|
use: '@vercel/go',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
config: {
|
||||||
|
framework: 'nextjs',
|
||||||
|
zeroConfig: true,
|
||||||
|
},
|
||||||
|
src: 'package.json',
|
||||||
|
use: '@vercel/next',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
expect(warnings).toStrictEqual([]);
|
||||||
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
const files = ['public/index.html'];
|
const files = ['public/index.html'];
|
||||||
|
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ describe('#detectFramework', () => {
|
|||||||
|
|
||||||
it('Detect Hugo #1', async () => {
|
it('Detect Hugo #1', async () => {
|
||||||
const fs = new VirtualFilesystem({
|
const fs = new VirtualFilesystem({
|
||||||
'config.yaml': 'config',
|
'config.yaml': 'baseURL: http://example.org/',
|
||||||
'content/post.md': '# hello world',
|
'content/post.md': '# hello world',
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -99,7 +99,7 @@ describe('#detectFramework', () => {
|
|||||||
|
|
||||||
it('Detect Hugo #2', async () => {
|
it('Detect Hugo #2', async () => {
|
||||||
const fs = new VirtualFilesystem({
|
const fs = new VirtualFilesystem({
|
||||||
'config.json': 'config',
|
'config.json': '{ "baseURL": "http://example.org/" }',
|
||||||
'content/post.md': '# hello world',
|
'content/post.md': '# hello world',
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@ describe('#detectFramework', () => {
|
|||||||
|
|
||||||
it('Detect Hugo #3', async () => {
|
it('Detect Hugo #3', async () => {
|
||||||
const fs = new VirtualFilesystem({
|
const fs = new VirtualFilesystem({
|
||||||
'config.toml': 'config',
|
'config.toml': 'baseURL = "http://example.org/"',
|
||||||
'content/post.md': '# hello world',
|
'content/post.md': '# hello world',
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -143,4 +143,12 @@ describe('#detectFramework', () => {
|
|||||||
|
|
||||||
expect(await detectFramework({ fs, frameworkList })).toBe('scully');
|
expect(await detectFramework({ fs, frameworkList })).toBe('scully');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Detect Zola', async () => {
|
||||||
|
const fs = new VirtualFilesystem({
|
||||||
|
'config.toml': 'base_url = "/"',
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(await detectFramework({ fs, frameworkList })).toBe('zola');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
78
packages/now-build-utils/test/unit.test.js
vendored
78
packages/now-build-utils/test/unit.test.js
vendored
@@ -1,3 +1,4 @@
|
|||||||
|
const ms = require('ms');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
const fs = require('fs-extra');
|
const fs = require('fs-extra');
|
||||||
const assert = require('assert').strict;
|
const assert = require('assert').strict;
|
||||||
@@ -8,6 +9,8 @@ const {
|
|||||||
getNodeVersion,
|
getNodeVersion,
|
||||||
getLatestNodeVersion,
|
getLatestNodeVersion,
|
||||||
getDiscontinuedNodeVersions,
|
getDiscontinuedNodeVersions,
|
||||||
|
runNpmInstall,
|
||||||
|
runPackageJsonScript,
|
||||||
} = require('../dist');
|
} = require('../dist');
|
||||||
|
|
||||||
async function expectBuilderError(promise, pattern) {
|
async function expectBuilderError(promise, pattern) {
|
||||||
@@ -19,7 +22,11 @@ async function expectBuilderError(promise, pattern) {
|
|||||||
}
|
}
|
||||||
assert('message' in result, `Expected error message but found ${result}`);
|
assert('message' in result, `Expected error message but found ${result}`);
|
||||||
assert(
|
assert(
|
||||||
pattern.test(result.message),
|
typeof result.message === 'string',
|
||||||
|
`Expected error to be a string but found ${typeof result.message}`
|
||||||
|
);
|
||||||
|
assert(
|
||||||
|
result.message.includes(pattern),
|
||||||
`Expected ${pattern} but found "${result.message}"`
|
`Expected ${pattern} but found "${result.message}"`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -43,19 +50,21 @@ it('should re-create symlinks properly', async () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const files = await glob('**', path.join(__dirname, 'symlinks'));
|
const files = await glob('**', path.join(__dirname, 'symlinks'));
|
||||||
assert.equal(Object.keys(files).length, 2);
|
assert.equal(Object.keys(files).length, 4);
|
||||||
|
|
||||||
const outDir = path.join(__dirname, 'symlinks-out');
|
const outDir = path.join(__dirname, 'symlinks-out');
|
||||||
await fs.remove(outDir);
|
await fs.remove(outDir);
|
||||||
|
|
||||||
const files2 = await download(files, outDir);
|
const files2 = await download(files, outDir);
|
||||||
assert.equal(Object.keys(files2).length, 2);
|
assert.equal(Object.keys(files2).length, 4);
|
||||||
|
|
||||||
const [linkStat, aStat] = await Promise.all([
|
const [linkStat, linkDirStat, aStat] = await Promise.all([
|
||||||
fs.lstat(path.join(outDir, 'link.txt')),
|
fs.lstat(path.join(outDir, 'link.txt')),
|
||||||
|
fs.lstat(path.join(outDir, 'link-dir')),
|
||||||
fs.lstat(path.join(outDir, 'a.txt')),
|
fs.lstat(path.join(outDir, 'a.txt')),
|
||||||
]);
|
]);
|
||||||
assert(linkStat.isSymbolicLink());
|
assert(linkStat.isSymbolicLink());
|
||||||
|
assert(linkDirStat.isSymbolicLink());
|
||||||
assert(aStat.isFile());
|
assert(aStat.isFile());
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -65,7 +74,7 @@ it('should create zip files with symlinks properly', async () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const files = await glob('**', path.join(__dirname, 'symlinks'));
|
const files = await glob('**', path.join(__dirname, 'symlinks'));
|
||||||
assert.equal(Object.keys(files).length, 2);
|
assert.equal(Object.keys(files).length, 4);
|
||||||
|
|
||||||
const outFile = path.join(__dirname, 'symlinks.zip');
|
const outFile = path.join(__dirname, 'symlinks.zip');
|
||||||
await fs.remove(outFile);
|
await fs.remove(outFile);
|
||||||
@@ -77,15 +86,17 @@ it('should create zip files with symlinks properly', async () => {
|
|||||||
await fs.writeFile(outFile, await createZip(files));
|
await fs.writeFile(outFile, await createZip(files));
|
||||||
await spawnAsync('unzip', [outFile], { cwd: outDir });
|
await spawnAsync('unzip', [outFile], { cwd: outDir });
|
||||||
|
|
||||||
const [linkStat, aStat] = await Promise.all([
|
const [linkStat, linkDirStat, aStat] = await Promise.all([
|
||||||
fs.lstat(path.join(outDir, 'link.txt')),
|
fs.lstat(path.join(outDir, 'link.txt')),
|
||||||
|
fs.lstat(path.join(outDir, 'link-dir')),
|
||||||
fs.lstat(path.join(outDir, 'a.txt')),
|
fs.lstat(path.join(outDir, 'a.txt')),
|
||||||
]);
|
]);
|
||||||
assert(linkStat.isSymbolicLink());
|
assert(linkStat.isSymbolicLink());
|
||||||
|
assert(linkDirStat.isSymbolicLink());
|
||||||
assert(aStat.isFile());
|
assert(aStat.isFile());
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should only match supported node versions', async () => {
|
it('should only match supported node versions, otherwise throw an error', async () => {
|
||||||
expect(await getSupportedNodeVersion('10.x', false)).toHaveProperty(
|
expect(await getSupportedNodeVersion('10.x', false)).toHaveProperty(
|
||||||
'major',
|
'major',
|
||||||
10
|
10
|
||||||
@@ -98,12 +109,9 @@ it('should only match supported node versions', async () => {
|
|||||||
'major',
|
'major',
|
||||||
14
|
14
|
||||||
);
|
);
|
||||||
expect(getSupportedNodeVersion('8.11.x', false)).rejects.toThrow();
|
|
||||||
expect(getSupportedNodeVersion('6.x', false)).rejects.toThrow();
|
|
||||||
expect(getSupportedNodeVersion('999.x', false)).rejects.toThrow();
|
|
||||||
expect(getSupportedNodeVersion('foo', false)).rejects.toThrow();
|
|
||||||
|
|
||||||
const autoMessage = /This project is using an invalid version of Node.js and must be changed/;
|
const autoMessage =
|
||||||
|
'Please set Node.js Version to 14.x in your Project Settings to use Node.js 14.';
|
||||||
await expectBuilderError(
|
await expectBuilderError(
|
||||||
getSupportedNodeVersion('8.11.x', true),
|
getSupportedNodeVersion('8.11.x', true),
|
||||||
autoMessage
|
autoMessage
|
||||||
@@ -125,7 +133,9 @@ it('should only match supported node versions', async () => {
|
|||||||
'major',
|
'major',
|
||||||
14
|
14
|
||||||
);
|
);
|
||||||
const foundMessage = /Found `engines` in `package\.json` with an invalid Node\.js version range/;
|
|
||||||
|
const foundMessage =
|
||||||
|
'Please set "engines": { "node": "14.x" } in your `package.json` file to use Node.js 14.';
|
||||||
await expectBuilderError(
|
await expectBuilderError(
|
||||||
getSupportedNodeVersion('8.11.x', false),
|
getSupportedNodeVersion('8.11.x', false),
|
||||||
foundMessage
|
foundMessage
|
||||||
@@ -188,7 +198,7 @@ it('should prefer package.json engines over project setting from config and warn
|
|||||||
)
|
)
|
||||||
).toHaveProperty('range', '14.x');
|
).toHaveProperty('range', '14.x');
|
||||||
expect(warningMessages).toStrictEqual([
|
expect(warningMessages).toStrictEqual([
|
||||||
'Warning: Due to `engines` existing in your `package.json` file, the Node.js Version defined in your Project Settings will not apply. Learn More: http://vercel.link/node-version',
|
'Warning: Due to "engines": { "node": "14.x" } in your `package.json` file, the Node.js Version defined in your Project Settings ("12.x") will not apply. Learn More: http://vercel.link/node-version',
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -209,9 +219,9 @@ it('should get latest node version', async () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should throw for discontinued versions', async () => {
|
it('should throw for discontinued versions', async () => {
|
||||||
// Mock a future date so that Node 8 becomes discontinued
|
// Mock a future date so that Node 8 and 10 become discontinued
|
||||||
const realDateNow = Date.now.bind(global.Date);
|
const realDateNow = Date.now.bind(global.Date);
|
||||||
global.Date.now = () => new Date('2021-04-01').getTime();
|
global.Date.now = () => new Date('2021-05-01').getTime();
|
||||||
|
|
||||||
expect(getSupportedNodeVersion('8.10.x', false)).rejects.toThrow();
|
expect(getSupportedNodeVersion('8.10.x', false)).rejects.toThrow();
|
||||||
expect(getSupportedNodeVersion('8.10.x', true)).rejects.toThrow();
|
expect(getSupportedNodeVersion('8.10.x', true)).rejects.toThrow();
|
||||||
@@ -226,6 +236,27 @@ it('should throw for discontinued versions', async () => {
|
|||||||
global.Date.now = realDateNow;
|
global.Date.now = realDateNow;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should warn for deprecated versions, soon to be discontinued', async () => {
|
||||||
|
// Mock a future date so that Node 10 warns
|
||||||
|
const realDateNow = Date.now.bind(global.Date);
|
||||||
|
global.Date.now = () => new Date('2021-02-23').getTime();
|
||||||
|
|
||||||
|
expect(await getSupportedNodeVersion('10.x', false)).toHaveProperty(
|
||||||
|
'major',
|
||||||
|
10
|
||||||
|
);
|
||||||
|
expect(await getSupportedNodeVersion('10.x', true)).toHaveProperty(
|
||||||
|
'major',
|
||||||
|
10
|
||||||
|
);
|
||||||
|
expect(warningMessages).toStrictEqual([
|
||||||
|
'Error: Node.js version 10.x is deprecated. Deployments created on or after 2021-04-20 will fail to build. Please set "engines": { "node": "14.x" } in your `package.json` file to use Node.js 14. This change is the result of a decision made by an upstream infrastructure provider (AWS).',
|
||||||
|
'Error: Node.js version 10.x is deprecated. Deployments created on or after 2021-04-20 will fail to build. Please set Node.js Version to 14.x in your Project Settings to use Node.js 14. This change is the result of a decision made by an upstream infrastructure provider (AWS).',
|
||||||
|
]);
|
||||||
|
|
||||||
|
global.Date.now = realDateNow;
|
||||||
|
});
|
||||||
|
|
||||||
it('should support require by path for legacy builders', () => {
|
it('should support require by path for legacy builders', () => {
|
||||||
const index = require('@vercel/build-utils');
|
const index = require('@vercel/build-utils');
|
||||||
|
|
||||||
@@ -255,3 +286,18 @@ it('should support require by path for legacy builders', () => {
|
|||||||
expect(FileRef2).toBe(index.FileRef);
|
expect(FileRef2).toBe(index.FileRef);
|
||||||
expect(Lambda2).toBe(index.Lambda);
|
expect(Lambda2).toBe(index.Lambda);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it(
|
||||||
|
'should have correct $PATH when running `runPackageJsonScript()` with yarn',
|
||||||
|
async () => {
|
||||||
|
const fixture = path.join(__dirname, 'fixtures', '19-yarn-v2');
|
||||||
|
await runNpmInstall(fixture);
|
||||||
|
await runPackageJsonScript(fixture, 'env');
|
||||||
|
|
||||||
|
// `yarn` was failing with ENOENT before, so as long as the
|
||||||
|
// script was invoked at all is enough to verify the fix
|
||||||
|
const out = await fs.readFile(path.join(fixture, 'env.txt'), 'utf8');
|
||||||
|
expect(out.trim()).toBeTruthy();
|
||||||
|
},
|
||||||
|
ms('1m')
|
||||||
|
);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "vercel",
|
"name": "vercel",
|
||||||
"version": "21.2.4-canary.1",
|
"version": "21.3.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",
|
||||||
@@ -61,8 +61,8 @@
|
|||||||
"node": ">= 10"
|
"node": ">= 10"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vercel/build-utils": "2.9.1-canary.1",
|
"@vercel/build-utils": "2.10.0",
|
||||||
"@vercel/go": "1.1.8",
|
"@vercel/go": "1.2.0",
|
||||||
"@vercel/node": "1.9.1-canary.0",
|
"@vercel/node": "1.9.1-canary.0",
|
||||||
"@vercel/python": "1.2.5-canary.1",
|
"@vercel/python": "1.2.5-canary.1",
|
||||||
"@vercel/ruby": "1.2.6-canary.0",
|
"@vercel/ruby": "1.2.6-canary.0",
|
||||||
@@ -100,7 +100,7 @@
|
|||||||
"@types/universal-analytics": "0.4.2",
|
"@types/universal-analytics": "0.4.2",
|
||||||
"@types/which": "1.3.2",
|
"@types/which": "1.3.2",
|
||||||
"@types/write-json-file": "2.2.1",
|
"@types/write-json-file": "2.2.1",
|
||||||
"@vercel/frameworks": "0.2.1-canary.1",
|
"@vercel/frameworks": "0.3.0",
|
||||||
"@vercel/ncc": "0.24.0",
|
"@vercel/ncc": "0.24.0",
|
||||||
"@zeit/fun": "0.11.2",
|
"@zeit/fun": "0.11.2",
|
||||||
"@zeit/source-map-support": "0.6.2",
|
"@zeit/source-map-support": "0.6.2",
|
||||||
|
|||||||
@@ -248,10 +248,19 @@ async function run({ client, contextName }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const [name] = args;
|
const [name] = args;
|
||||||
await client.fetch('/projects/ensure-project', {
|
try {
|
||||||
method: 'POST',
|
await client.fetch('/projects', {
|
||||||
body: { name },
|
method: 'POST',
|
||||||
});
|
body: { name },
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
if (error.status === 409) {
|
||||||
|
// project already exists, so we can
|
||||||
|
// show a success message
|
||||||
|
} else {
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
}
|
||||||
const elapsed = ms(new Date() - start);
|
const elapsed = ms(new Date() - start);
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
|
|||||||
@@ -141,6 +141,7 @@ async function run({ output, token, contextName, currentTeam, ctx }) {
|
|||||||
const secrets = new NowSecrets({ apiUrl, token, debug, currentTeam, output });
|
const secrets = new NowSecrets({ apiUrl, token, debug, currentTeam, output });
|
||||||
const args = argv._.slice(1);
|
const args = argv._.slice(1);
|
||||||
const start = Date.now();
|
const start = Date.now();
|
||||||
|
const { 'test-warning': testWarningFlag } = argv;
|
||||||
|
|
||||||
if (subcommand === 'ls' || subcommand === 'list') {
|
if (subcommand === 'ls' || subcommand === 'list') {
|
||||||
if (args.length > 1) {
|
if (args.length > 1) {
|
||||||
@@ -154,7 +155,10 @@ async function run({ output, token, contextName, currentTeam, ctx }) {
|
|||||||
return exit(1);
|
return exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { secrets: list, pagination } = await secrets.ls(nextTimestamp);
|
const { secrets: list, pagination } = await secrets.ls(
|
||||||
|
nextTimestamp,
|
||||||
|
testWarningFlag
|
||||||
|
);
|
||||||
const elapsed = ms(Date.now() - start);
|
const elapsed = ms(Date.now() - start);
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import retry, { RetryFunction, Options as RetryOptions } from 'async-retry';
|
|||||||
import createOutput, { Output } from './output/create-output';
|
import createOutput, { Output } from './output/create-output';
|
||||||
import responseError from './response-error';
|
import responseError from './response-error';
|
||||||
import ua from './ua';
|
import ua from './ua';
|
||||||
|
import printIndications from './print-indications';
|
||||||
|
|
||||||
export interface FetchOptions {
|
export interface FetchOptions {
|
||||||
body?: NodeJS.ReadableStream | object | string;
|
body?: NodeJS.ReadableStream | object | string;
|
||||||
@@ -119,6 +120,8 @@ export default class Client extends EventEmitter {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
printIndications(res);
|
||||||
|
|
||||||
return res.headers.get('content-type').includes('application/json')
|
return res.headers.get('content-type').includes('application/json')
|
||||||
? res.json()
|
? res.json()
|
||||||
: res;
|
: res;
|
||||||
|
|||||||
@@ -17,29 +17,12 @@ import { prependEmoji, emoji } from '../emoji';
|
|||||||
|
|
||||||
function printInspectUrl(
|
function printInspectUrl(
|
||||||
output: Output,
|
output: Output,
|
||||||
deploymentUrl: string,
|
inspectorUrl: string,
|
||||||
deployStamp: () => string,
|
deployStamp: () => string
|
||||||
orgSlug: string
|
|
||||||
) {
|
) {
|
||||||
const url = deploymentUrl.replace('https://', '');
|
|
||||||
|
|
||||||
// example urls:
|
|
||||||
// lucim-fyulaijvg.now.sh
|
|
||||||
// s-66p6vb23x.n8.io (custom domain suffix)
|
|
||||||
const [sub, ...p] = url.split('.');
|
|
||||||
const apex = p.join('.');
|
|
||||||
|
|
||||||
const q = sub.split('-');
|
|
||||||
const deploymentShortId = q.pop();
|
|
||||||
const projectName = q.join('-');
|
|
||||||
|
|
||||||
const inspectUrl = `https://vercel.com/${orgSlug}/${projectName}/${deploymentShortId}${
|
|
||||||
apex !== 'now.sh' && apex !== 'vercel.app' ? `/${apex}` : ''
|
|
||||||
}`;
|
|
||||||
|
|
||||||
output.print(
|
output.print(
|
||||||
prependEmoji(
|
prependEmoji(
|
||||||
`Inspect: ${chalk.bold(inspectUrl)} ${deployStamp()}`,
|
`Inspect: ${chalk.bold(inspectorUrl)} ${deployStamp()}`,
|
||||||
emoji('inspect')
|
emoji('inspect')
|
||||||
) + `\n`
|
) + `\n`
|
||||||
);
|
);
|
||||||
@@ -178,7 +161,7 @@ export default async function processDeployment({
|
|||||||
|
|
||||||
output.stopSpinner();
|
output.stopSpinner();
|
||||||
|
|
||||||
printInspectUrl(output, event.payload.url, deployStamp, org.slug);
|
printInspectUrl(output, event.payload.inspectorUrl, deployStamp);
|
||||||
|
|
||||||
if (quiet) {
|
if (quiet) {
|
||||||
process.stdout.write(`https://${event.payload.url}`);
|
process.stdout.write(`https://${event.payload.url}`);
|
||||||
|
|||||||
@@ -589,7 +589,9 @@ export default class DevServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (warnings && warnings.length > 0) {
|
if (warnings && warnings.length > 0) {
|
||||||
warnings.forEach(warning => this.output.warn(warning.message));
|
warnings.forEach(warning =>
|
||||||
|
this.output.warn(warning.message, null, warning.link, warning.action)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (builders) {
|
if (builders) {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import createOutput from './output';
|
|||||||
import { responseError } from './error';
|
import { responseError } from './error';
|
||||||
import stamp from './output/stamp';
|
import stamp from './output/stamp';
|
||||||
import { BuildError } from './errors-ts';
|
import { BuildError } from './errors-ts';
|
||||||
|
import printIndications from './print-indications.ts';
|
||||||
|
|
||||||
export default class Now extends EventEmitter {
|
export default class Now extends EventEmitter {
|
||||||
constructor({
|
constructor({
|
||||||
@@ -225,7 +226,7 @@ export default class Now extends EventEmitter {
|
|||||||
return new Error(error.message);
|
return new Error(error.message);
|
||||||
}
|
}
|
||||||
|
|
||||||
async listSecrets(next) {
|
async listSecrets(next, testWarningFlag) {
|
||||||
const payload = await this.retry(async bail => {
|
const payload = await this.retry(async bail => {
|
||||||
let secretsUrl = '/v3/now/secrets?limit=20';
|
let secretsUrl = '/v3/now/secrets?limit=20';
|
||||||
|
|
||||||
@@ -233,6 +234,10 @@ export default class Now extends EventEmitter {
|
|||||||
secretsUrl += `&until=${next}`;
|
secretsUrl += `&until=${next}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (testWarningFlag) {
|
||||||
|
secretsUrl += '&testWarning=1';
|
||||||
|
}
|
||||||
|
|
||||||
const res = await this._fetch(secretsUrl);
|
const res = await this._fetch(secretsUrl);
|
||||||
|
|
||||||
if (res.status === 200) {
|
if (res.status === 200) {
|
||||||
@@ -427,7 +432,7 @@ export default class Now extends EventEmitter {
|
|||||||
return this._syncAmount;
|
return this._syncAmount;
|
||||||
}
|
}
|
||||||
|
|
||||||
_fetch(_url, opts = {}) {
|
async _fetch(_url, opts = {}) {
|
||||||
if (opts.useCurrentTeam !== false && this.currentTeam) {
|
if (opts.useCurrentTeam !== false && this.currentTeam) {
|
||||||
const parsedUrl = parseUrl(_url, true);
|
const parsedUrl = parseUrl(_url, true);
|
||||||
const query = parsedUrl.query;
|
const query = parsedUrl.query;
|
||||||
@@ -450,11 +455,12 @@ export default class Now extends EventEmitter {
|
|||||||
opts.body = JSON.stringify(opts.body);
|
opts.body = JSON.stringify(opts.body);
|
||||||
opts.headers['Content-Type'] = 'application/json';
|
opts.headers['Content-Type'] = 'application/json';
|
||||||
}
|
}
|
||||||
|
const res = await this._output.time(
|
||||||
return this._output.time(
|
|
||||||
`${opts.method || 'GET'} ${this._apiUrl}${_url} ${opts.body || ''}`,
|
`${opts.method || 'GET'} ${this._apiUrl}${_url} ${opts.body || ''}`,
|
||||||
fetch(`${this._apiUrl}${_url}`, opts)
|
fetch(`${this._apiUrl}${_url}`, opts)
|
||||||
);
|
);
|
||||||
|
printIndications(res);
|
||||||
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
// public retry with built-in retrying that can be
|
// public retry with built-in retrying that can be
|
||||||
|
|||||||
32
packages/now-cli/src/util/print-indications.ts
Normal file
32
packages/now-cli/src/util/print-indications.ts
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
import chalk from 'chalk';
|
||||||
|
import { Response } from 'node-fetch';
|
||||||
|
import { emoji, EmojiLabel, prependEmoji } from './emoji';
|
||||||
|
import createOutput from './output';
|
||||||
|
import linkStyle from './output/link';
|
||||||
|
|
||||||
|
export default function printIndications(res: Response) {
|
||||||
|
const _output = createOutput();
|
||||||
|
const indications = new Set(['warning', 'notice', 'tip']);
|
||||||
|
const regex = /^x-(?:vercel|now)-(warning|notice|tip)-(.*)$/;
|
||||||
|
|
||||||
|
for (const [name, payload] of res.headers) {
|
||||||
|
const match = name.match(regex);
|
||||||
|
if (match) {
|
||||||
|
const [, type, identifier] = match;
|
||||||
|
const action = res.headers.get(`x-vercel-action-${identifier}`);
|
||||||
|
const link = res.headers.get(`x-vercel-link-${identifier}`);
|
||||||
|
if (indications.has(type)) {
|
||||||
|
const newline = '\n';
|
||||||
|
const message =
|
||||||
|
prependEmoji(chalk.dim(payload), emoji(type as EmojiLabel)) + newline;
|
||||||
|
let finalLink = '';
|
||||||
|
if (link) {
|
||||||
|
finalLink =
|
||||||
|
chalk.dim(`${action || 'Learn More'}: ${linkStyle(link)}`) +
|
||||||
|
newline;
|
||||||
|
}
|
||||||
|
_output.print(message + finalLink);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
import Now from '.';
|
import Now from '.';
|
||||||
|
|
||||||
export default class Secrets extends Now {
|
export default class Secrets extends Now {
|
||||||
ls(next) {
|
ls(next, testWarningFlag) {
|
||||||
return this.listSecrets(next);
|
return this.listSecrets(next, testWarningFlag);
|
||||||
}
|
}
|
||||||
|
|
||||||
getSecretByNameOrId(nameOrId) {
|
getSecretByNameOrId(nameOrId) {
|
||||||
|
|||||||
@@ -425,7 +425,7 @@ test(
|
|||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: '{"query":"{redwood{version}}"}',
|
body: '{"query":"{redwood{version}}"}',
|
||||||
};
|
};
|
||||||
const resBody = '{"data":{"redwood":{"version":"0.15.0"}}}';
|
const resBody = '{"data":{"redwood":{"version":"0.25.0"}}}';
|
||||||
await testPath(200, '/api/graphql', resBody, {}, fetchOpts);
|
await testPath(200, '/api/graphql', resBody, {}, fetchOpts);
|
||||||
},
|
},
|
||||||
{ isExample: true }
|
{ isExample: true }
|
||||||
@@ -1692,6 +1692,9 @@ test(
|
|||||||
expectHeader('image/webp'),
|
expectHeader('image/webp'),
|
||||||
fetchOpts('image/webp')
|
fetchOpts('image/webp')
|
||||||
);
|
);
|
||||||
|
/*
|
||||||
|
* Disabled gif in https://github.com/vercel/next.js/pull/22253
|
||||||
|
* Eventually we should enable again when `next dev` supports it
|
||||||
await testPath(
|
await testPath(
|
||||||
200,
|
200,
|
||||||
toUrl('/test.gif', 64, 80),
|
toUrl('/test.gif', 64, 80),
|
||||||
@@ -1699,6 +1702,7 @@ test(
|
|||||||
expectHeader('image/webp'),
|
expectHeader('image/webp'),
|
||||||
fetchOpts('image/webp')
|
fetchOpts('image/webp')
|
||||||
);
|
);
|
||||||
|
*/
|
||||||
await testPath(
|
await testPath(
|
||||||
200,
|
200,
|
||||||
toUrl('/test.svg', 64, 70),
|
toUrl('/test.svg', 64, 70),
|
||||||
@@ -1706,12 +1710,13 @@ test(
|
|||||||
expectHeader('image/svg+xml'),
|
expectHeader('image/svg+xml'),
|
||||||
fetchOpts('image/webp')
|
fetchOpts('image/webp')
|
||||||
);
|
);
|
||||||
|
// animated gif should bypass: serve as-is
|
||||||
await testPath(
|
await testPath(
|
||||||
200,
|
200,
|
||||||
toUrl('/animated.gif', 64, 60),
|
toUrl('/animated.gif', 64, 60),
|
||||||
null,
|
null,
|
||||||
expectHeader('image/gif'),
|
expectHeader('image/gif'),
|
||||||
fetchOpts('image/gif')
|
fetchOpts('image/webp')
|
||||||
);
|
);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|||||||
59
packages/now-cli/test/integration.js
vendored
59
packages/now-cli/test/integration.js
vendored
@@ -1029,6 +1029,41 @@ test('Deploy `api-env` fixture and test `vercel env` command', async t => {
|
|||||||
await nowEnvLsIsEmpty();
|
await nowEnvLsIsEmpty();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('[vc projects] should create a project successfully', async t => {
|
||||||
|
const projectName = `vc-projects-add-${
|
||||||
|
Math.random().toString(36).split('.')[1]
|
||||||
|
}`;
|
||||||
|
|
||||||
|
const vc = execa(binaryPath, [
|
||||||
|
'projects',
|
||||||
|
'add',
|
||||||
|
projectName,
|
||||||
|
...defaultArgs,
|
||||||
|
]);
|
||||||
|
|
||||||
|
await waitForPrompt(vc, chunk =>
|
||||||
|
chunk.includes(`Success! Project ${projectName} added`)
|
||||||
|
);
|
||||||
|
|
||||||
|
const { exitCode, stderr, stdout } = await vc;
|
||||||
|
t.is(exitCode, 0, formatOutput({ stderr, stdout }));
|
||||||
|
|
||||||
|
// creating the same project again should succeed
|
||||||
|
const vc2 = execa(binaryPath, [
|
||||||
|
'projects',
|
||||||
|
'add',
|
||||||
|
projectName,
|
||||||
|
...defaultArgs,
|
||||||
|
]);
|
||||||
|
|
||||||
|
await waitForPrompt(vc2, chunk =>
|
||||||
|
chunk.includes(`Success! Project ${projectName} added`)
|
||||||
|
);
|
||||||
|
|
||||||
|
const { exitCode: exitCode2, stderr: stderr2, stdout: stdout2 } = await vc;
|
||||||
|
t.is(exitCode2, 0, formatOutput({ stderr2, stdout2 }));
|
||||||
|
});
|
||||||
|
|
||||||
test('deploy with metadata containing "=" in the value', async t => {
|
test('deploy with metadata containing "=" in the value', async t => {
|
||||||
const target = fixture('static-v2-meta');
|
const target = fixture('static-v2-meta');
|
||||||
|
|
||||||
@@ -1904,6 +1939,11 @@ test('create a production deployment', async t => {
|
|||||||
/Setting target to production/gm,
|
/Setting target to production/gm,
|
||||||
formatOutput(targetCall)
|
formatOutput(targetCall)
|
||||||
);
|
);
|
||||||
|
t.regex(
|
||||||
|
targetCall.stderr,
|
||||||
|
/Inspect: https:\/\/vercel.com\//gm,
|
||||||
|
formatOutput(targetCall)
|
||||||
|
);
|
||||||
t.regex(targetCall.stdout, /https:\/\//gm);
|
t.regex(targetCall.stdout, /https:\/\//gm);
|
||||||
|
|
||||||
const { host: targetHost } = new URL(targetCall.stdout);
|
const { host: targetHost } = new URL(targetCall.stdout);
|
||||||
@@ -2558,6 +2598,19 @@ test('vercel secret ls', async t => {
|
|||||||
t.regex(output.stdout, new RegExp(), formatOutput(output));
|
t.regex(output.stdout, new RegExp(), formatOutput(output));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('vercel secret ls --test-warning', async t => {
|
||||||
|
const output = await execute(['secret', 'ls', '--test-warning']);
|
||||||
|
|
||||||
|
t.is(output.exitCode, 0, formatOutput(output));
|
||||||
|
t.regex(output.stderr, /Test warning message./gm, formatOutput(output));
|
||||||
|
t.regex(
|
||||||
|
output.stderr,
|
||||||
|
/Learn more: https:\/\/vercel.com/gm,
|
||||||
|
formatOutput(output)
|
||||||
|
);
|
||||||
|
t.regex(output.stdout, /No secrets found under/gm, formatOutput(output));
|
||||||
|
});
|
||||||
|
|
||||||
test('vercel secret rename', async t => {
|
test('vercel secret rename', async t => {
|
||||||
const nextName = `renamed-secret-${Date.now().toString(36)}`;
|
const nextName = `renamed-secret-${Date.now().toString(36)}`;
|
||||||
const output = await execute([
|
const output = await execute([
|
||||||
@@ -2626,7 +2679,7 @@ test('deploy a Lambda with 3 seconds of maxDuration', async t => {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
t.is(response1.status, 200, url);
|
t.is(response1.status, 200, url);
|
||||||
t.is(response2.status, 502, url);
|
t.is(response2.status, 504, url);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('fail to deploy a Lambda with an incorrect value for maxDuration', async t => {
|
test('fail to deploy a Lambda with an incorrect value for maxDuration', async t => {
|
||||||
@@ -2678,7 +2731,7 @@ test('fail to deploy a Lambda with a specific runtime but without a locked versi
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('fail to add a domain without a project', async t => {
|
test('fail to add a domain without a project', async t => {
|
||||||
const output = await execute(['domains', 'add', 'my-domain.now.sh']);
|
const output = await execute(['domains', 'add', 'my-domain.vercel.app']);
|
||||||
t.is(output.exitCode, 1, formatOutput(output));
|
t.is(output.exitCode, 1, formatOutput(output));
|
||||||
t.regex(output.stderr, /expects two arguments/gm, formatOutput(output));
|
t.regex(output.stderr, /expects two arguments/gm, formatOutput(output));
|
||||||
});
|
});
|
||||||
@@ -2711,7 +2764,7 @@ test('change user', async t => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('assign a domain to a project', async t => {
|
test('assign a domain to a project', async t => {
|
||||||
const domain = `project-domain.${contextName}.now.sh`;
|
const domain = `project-domain.${contextName}.vercel.app`;
|
||||||
const directory = fixture('static-deployment');
|
const directory = fixture('static-deployment');
|
||||||
|
|
||||||
const deploymentOutput = await execute([directory, '--public', '--confirm']);
|
const deploymentOutput = await execute([directory, '--public', '--confirm']);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vercel/client",
|
"name": "@vercel/client",
|
||||||
"version": "9.0.7-canary.1",
|
"version": "9.0.7",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"typings": "dist/index.d.ts",
|
"typings": "dist/index.d.ts",
|
||||||
"homepage": "https://vercel.com",
|
"homepage": "https://vercel.com",
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vercel/build-utils": "2.9.1-canary.1",
|
"@vercel/build-utils": "2.10.0",
|
||||||
"@zeit/fetch": "5.2.0",
|
"@zeit/fetch": "5.2.0",
|
||||||
"async-retry": "1.2.3",
|
"async-retry": "1.2.3",
|
||||||
"async-sema": "3.0.0",
|
"async-sema": "3.0.0",
|
||||||
|
|||||||
@@ -26,30 +26,6 @@ async function main() {
|
|||||||
stdio: 'inherit',
|
stdio: 'inherit',
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const installDir = join(outDir, 'install');
|
|
||||||
await execa(
|
|
||||||
'ncc',
|
|
||||||
[
|
|
||||||
'build',
|
|
||||||
'install.ts',
|
|
||||||
'-e',
|
|
||||||
'@vercel/build-utils',
|
|
||||||
'-e',
|
|
||||||
'@now/build-utils',
|
|
||||||
'-o',
|
|
||||||
installDir,
|
|
||||||
],
|
|
||||||
{
|
|
||||||
stdio: 'inherit',
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
// Move compiled ncc file to out dir
|
|
||||||
await fs.rename(join(installDir, 'index.js'), join(outDir, 'install.js'));
|
|
||||||
|
|
||||||
// Delete leftover "install" dir
|
|
||||||
await fs.remove(installDir);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
main().catch(err => {
|
main().catch(err => {
|
||||||
|
|||||||
@@ -1,19 +1,26 @@
|
|||||||
import tar from 'tar';
|
import tar from 'tar';
|
||||||
import execa from 'execa';
|
import execa from 'execa';
|
||||||
import fetch from 'node-fetch';
|
import fetch from 'node-fetch';
|
||||||
import { mkdirp, pathExists } from 'fs-extra';
|
import { mkdirp, pathExists, readFile } from 'fs-extra';
|
||||||
import { dirname, join } from 'path';
|
import { join } from 'path';
|
||||||
import buildUtils from './build-utils';
|
import buildUtils from './build-utils';
|
||||||
import stringArgv from 'string-argv';
|
import stringArgv from 'string-argv';
|
||||||
const { debug } = buildUtils;
|
const { debug } = buildUtils;
|
||||||
const archMap = new Map([['x64', 'amd64'], ['x86', '386']]);
|
const versionMap = new Map([
|
||||||
|
['1.16', '1.16'],
|
||||||
|
['1.15', '1.15.8'],
|
||||||
|
['1.14', '1.14.15'],
|
||||||
|
['1.13', '1.13.15'],
|
||||||
|
]);
|
||||||
|
const archMap = new Map([
|
||||||
|
['x64', 'amd64'],
|
||||||
|
['x86', '386'],
|
||||||
|
]);
|
||||||
const platformMap = new Map([['win32', 'windows']]);
|
const platformMap = new Map([['win32', 'windows']]);
|
||||||
|
export const cacheDir = join('.vercel', 'cache', 'golang');
|
||||||
// Location where the `go` binary will be installed after `postinstall`
|
const getGoDir = (workPath: string) => join(workPath, cacheDir);
|
||||||
const GO_DIR = join(__dirname, 'go');
|
|
||||||
const GO_BIN = join(GO_DIR, 'bin', 'go');
|
|
||||||
const GO_FLAGS = process.platform === 'win32' ? [] : ['-ldflags', '-s -w'];
|
const GO_FLAGS = process.platform === 'win32' ? [] : ['-ldflags', '-s -w'];
|
||||||
|
const GO_MIN_VERSION = 13;
|
||||||
const getPlatform = (p: string) => platformMap.get(p) || p;
|
const getPlatform = (p: string) => platformMap.get(p) || p;
|
||||||
const getArch = (a: string) => archMap.get(a) || a;
|
const getArch = (a: string) => archMap.get(a) || a;
|
||||||
const getGoUrl = (version: string, platform: string, arch: string) => {
|
const getGoUrl = (version: string, platform: string, arch: string) => {
|
||||||
@@ -25,14 +32,18 @@ const getGoUrl = (version: string, platform: string, arch: string) => {
|
|||||||
|
|
||||||
export const OUT_EXTENSION = process.platform === 'win32' ? '.exe' : '';
|
export const OUT_EXTENSION = process.platform === 'win32' ? '.exe' : '';
|
||||||
|
|
||||||
export async function getAnalyzedEntrypoint(filePath: string, modulePath = '') {
|
export async function getAnalyzedEntrypoint(
|
||||||
debug('Analyzing entrypoint %o', filePath);
|
workPath: string,
|
||||||
|
filePath: string,
|
||||||
|
modulePath: string
|
||||||
|
) {
|
||||||
|
debug('Analyzing entrypoint %o with modulePath %o', filePath, modulePath);
|
||||||
const bin = join(__dirname, `analyze${OUT_EXTENSION}`);
|
const bin = join(__dirname, `analyze${OUT_EXTENSION}`);
|
||||||
|
|
||||||
const isAnalyzeExist = await pathExists(bin);
|
const isAnalyzeExist = await pathExists(bin);
|
||||||
if (!isAnalyzeExist) {
|
if (!isAnalyzeExist) {
|
||||||
const src = join(__dirname, 'util', 'analyze.go');
|
const src = join(__dirname, 'util', 'analyze.go');
|
||||||
const go = await downloadGo();
|
const go = await downloadGo(workPath, modulePath);
|
||||||
await go.build(src, bin);
|
await go.build(src, bin);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,13 +111,16 @@ class GoWrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function createGo(
|
export async function createGo(
|
||||||
|
workPath: string,
|
||||||
goPath: string,
|
goPath: string,
|
||||||
platform = process.platform,
|
platform = process.platform,
|
||||||
arch = process.arch,
|
arch = process.arch,
|
||||||
opts: execa.Options = {},
|
opts: execa.Options = {},
|
||||||
goMod = false
|
goMod = false
|
||||||
) {
|
) {
|
||||||
const path = `${dirname(GO_BIN)}:${process.env.PATH}`;
|
const binPath = join(getGoDir(workPath), 'bin');
|
||||||
|
debug(`Adding ${binPath} to PATH`);
|
||||||
|
const path = `${binPath}:${process.env.PATH}`;
|
||||||
const env: { [key: string]: string } = {
|
const env: { [key: string]: string } = {
|
||||||
...process.env,
|
...process.env,
|
||||||
PATH: path,
|
PATH: path,
|
||||||
@@ -120,21 +134,20 @@ export async function createGo(
|
|||||||
return new GoWrapper(env, opts);
|
return new GoWrapper(env, opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function downloadGo(
|
export async function downloadGo(workPath: string, modulePath: string) {
|
||||||
dir = GO_DIR,
|
const dir = getGoDir(workPath);
|
||||||
version = '1.13.7',
|
const { platform, arch } = process;
|
||||||
platform = process.platform,
|
const version = await parseGoVersion(modulePath);
|
||||||
arch = process.arch
|
|
||||||
) {
|
|
||||||
// Check if `go` is already installed in user's `$PATH`
|
// Check if `go` is already installed in user's `$PATH`
|
||||||
const { failed, stdout } = await execa('go', ['version'], { reject: false });
|
const { failed, stdout } = await execa('go', ['version'], { reject: false });
|
||||||
|
|
||||||
if (!failed && parseInt(stdout.split('.')[1]) >= 11) {
|
if (!failed && parseInt(stdout.split('.')[1]) >= GO_MIN_VERSION) {
|
||||||
debug('Using system installed version of `go`: %o', stdout.trim());
|
debug('Using system installed version of `go`: %o', stdout.trim());
|
||||||
return createGo(dir, platform, arch);
|
return createGo(workPath, dir, platform, arch);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check `go` bin in builder CWD
|
// Check `go` bin in cacheDir
|
||||||
const isGoExist = await pathExists(join(dir, 'bin'));
|
const isGoExist = await pathExists(join(dir, 'bin'));
|
||||||
if (!isGoExist) {
|
if (!isGoExist) {
|
||||||
debug('Installing `go` v%s to %o for %s %s', version, dir, platform, arch);
|
debug('Installing `go` v%s to %o for %s %s', version, dir, platform, arch);
|
||||||
@@ -156,5 +169,32 @@ export async function downloadGo(
|
|||||||
.on('finish', resolve);
|
.on('finish', resolve);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return createGo(dir, platform, arch);
|
return createGo(workPath, dir, platform, arch);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function parseGoVersion(modulePath: string): Promise<string> {
|
||||||
|
// default to newest (first)
|
||||||
|
let version = Array.from(versionMap.values())[0];
|
||||||
|
const file = join(modulePath, 'go.mod');
|
||||||
|
try {
|
||||||
|
const content = await readFile(file, 'utf8');
|
||||||
|
const matches = /^go (\d+)\.(\d+)\.?$/gm.exec(content) || [];
|
||||||
|
const major = parseInt(matches[1], 10);
|
||||||
|
const minor = parseInt(matches[2], 10);
|
||||||
|
const full = versionMap.get(`${major}.${minor}`);
|
||||||
|
if (major === 1 && minor >= GO_MIN_VERSION && full) {
|
||||||
|
version = full;
|
||||||
|
} else {
|
||||||
|
console.log(`Warning: Unknown Go version in ${file}`);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
if (err.code === 'ENOENT') {
|
||||||
|
debug(`File not found: ${file}`);
|
||||||
|
} else {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
debug(`Selected Go version ${version}`);
|
||||||
|
return version;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import {
|
|||||||
BuildOptions,
|
BuildOptions,
|
||||||
Meta,
|
Meta,
|
||||||
Files,
|
Files,
|
||||||
|
PrepareCacheOptions,
|
||||||
StartDevServerOptions,
|
StartDevServerOptions,
|
||||||
StartDevServerResult,
|
StartDevServerResult,
|
||||||
} from '@vercel/build-utils';
|
} from '@vercel/build-utils';
|
||||||
@@ -33,7 +34,12 @@ const {
|
|||||||
|
|
||||||
const TMP = tmpdir();
|
const TMP = tmpdir();
|
||||||
|
|
||||||
import { createGo, getAnalyzedEntrypoint, OUT_EXTENSION } from './go-helpers';
|
import {
|
||||||
|
createGo,
|
||||||
|
getAnalyzedEntrypoint,
|
||||||
|
cacheDir,
|
||||||
|
OUT_EXTENSION,
|
||||||
|
} from './go-helpers';
|
||||||
const handlerFileName = `handler${OUT_EXTENSION}`;
|
const handlerFileName = `handler${OUT_EXTENSION}`;
|
||||||
|
|
||||||
export { shouldServe };
|
export { shouldServe };
|
||||||
@@ -125,7 +131,7 @@ Learn more: https://github.com/golang/go/wiki/Modules
|
|||||||
|
|
||||||
const forceMove = Boolean(meta.isDev);
|
const forceMove = Boolean(meta.isDev);
|
||||||
const srcPath = join(goPath, 'src', 'lambda');
|
const srcPath = join(goPath, 'src', 'lambda');
|
||||||
let downloadPath = (meta.isDev || meta.skipDownload) ? workPath : srcPath;
|
let downloadPath = meta.isDev || meta.skipDownload ? workPath : srcPath;
|
||||||
let downloadedFiles = await download(files, downloadPath, meta);
|
let downloadedFiles = await download(files, downloadPath, meta);
|
||||||
|
|
||||||
debug(`Parsing AST for "${entrypoint}"`);
|
debug(`Parsing AST for "${entrypoint}"`);
|
||||||
@@ -136,8 +142,12 @@ Learn more: https://github.com/golang/go/wiki/Modules
|
|||||||
if (fileName in downloadedFiles) {
|
if (fileName in downloadedFiles) {
|
||||||
goModAbsPathDir = dirname(downloadedFiles[fileName].fsPath);
|
goModAbsPathDir = dirname(downloadedFiles[fileName].fsPath);
|
||||||
debug(`Found ${fileName} file in "${goModAbsPathDir}"`);
|
debug(`Found ${fileName} file in "${goModAbsPathDir}"`);
|
||||||
|
} else if ('api/go.mod' in downloadedFiles) {
|
||||||
|
goModAbsPathDir = dirname(downloadedFiles['api/go.mod'].fsPath);
|
||||||
|
debug(`Found ${fileName} file in "${goModAbsPathDir}"`);
|
||||||
}
|
}
|
||||||
analyzed = await getAnalyzedEntrypoint(
|
analyzed = await getAnalyzedEntrypoint(
|
||||||
|
workPath,
|
||||||
downloadedFiles[entrypoint].fsPath,
|
downloadedFiles[entrypoint].fsPath,
|
||||||
goModAbsPathDir
|
goModAbsPathDir
|
||||||
);
|
);
|
||||||
@@ -244,6 +254,7 @@ Learn more: https://vercel.com/docs/runtimes#official-runtimes/go
|
|||||||
|
|
||||||
if (packageName !== 'main') {
|
if (packageName !== 'main') {
|
||||||
const go = await createGo(
|
const go = await createGo(
|
||||||
|
workPath,
|
||||||
goPath,
|
goPath,
|
||||||
process.platform,
|
process.platform,
|
||||||
process.arch,
|
process.arch,
|
||||||
@@ -392,6 +403,7 @@ Learn more: https://vercel.com/docs/runtimes#official-runtimes/go
|
|||||||
// we need `main.go` in the same dir as the entrypoint,
|
// we need `main.go` in the same dir as the entrypoint,
|
||||||
// otherwise `go build` will refuse to build
|
// otherwise `go build` will refuse to build
|
||||||
const go = await createGo(
|
const go = await createGo(
|
||||||
|
workPath,
|
||||||
goPath,
|
goPath,
|
||||||
process.platform,
|
process.platform,
|
||||||
process.arch,
|
process.arch,
|
||||||
@@ -515,6 +527,7 @@ export async function startDevServer(
|
|||||||
goModAbsPathDir = workPath;
|
goModAbsPathDir = workPath;
|
||||||
}
|
}
|
||||||
const analyzedRaw = await getAnalyzedEntrypoint(
|
const analyzedRaw = await getAnalyzedEntrypoint(
|
||||||
|
workPath,
|
||||||
entrypointWithExt,
|
entrypointWithExt,
|
||||||
goModAbsPathDir
|
goModAbsPathDir
|
||||||
);
|
);
|
||||||
@@ -620,3 +633,10 @@ async function waitForPortFile_(opts: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function prepareCache({
|
||||||
|
workPath,
|
||||||
|
}: PrepareCacheOptions): Promise<Files> {
|
||||||
|
const cache = await glob(`${cacheDir}/**`, workPath);
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
import { downloadGo } from './go-helpers';
|
|
||||||
|
|
||||||
downloadGo().catch(err => {
|
|
||||||
console.error(err);
|
|
||||||
process.exit(1);
|
|
||||||
});
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vercel/go",
|
"name": "@vercel/go",
|
||||||
"version": "1.1.8",
|
"version": "1.2.0",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "./dist/index",
|
"main": "./dist/index",
|
||||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/go",
|
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/go",
|
||||||
@@ -12,8 +12,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "node build",
|
"build": "node build",
|
||||||
"test-integration-once": "jest --env node --verbose --runInBand --bail",
|
"test-integration-once": "jest --env node --verbose --runInBand --bail",
|
||||||
"prepublish": "node build",
|
"prepublishOnly": "node build"
|
||||||
"now-postinstall": "node dist/install.js"
|
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"dist"
|
"dist"
|
||||||
|
|||||||
@@ -3,11 +3,12 @@ package cowsay
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
say "github.com/dhruvbird/go-cowsay"
|
say "github.com/dhruvbird/go-cowsay"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Handler function
|
// Handler function
|
||||||
func Handler(w http.ResponseWriter, r *http.Request) {
|
func Handler(w http.ResponseWriter, r *http.Request) {
|
||||||
fmt.Fprintf(w, say.Format("cow:RANDOMNESS_PLACEHOLDER"))
|
fmt.Fprintf(w, say.Format("cow:" + runtime.Version() + ":RANDOMNESS_PLACEHOLDER"))
|
||||||
}
|
}
|
||||||
|
|||||||
11
packages/now-go/test/fixtures/01-cowsay/now.json
vendored
11
packages/now-go/test/fixtures/01-cowsay/now.json
vendored
@@ -1,11 +0,0 @@
|
|||||||
{
|
|
||||||
"version": 2,
|
|
||||||
"builds": [
|
|
||||||
{ "src": "index.go", "use": "@vercel/go" },
|
|
||||||
{ "src": "subdirectory/index.go", "use": "@vercel/go" }
|
|
||||||
],
|
|
||||||
"probes": [
|
|
||||||
{ "path": "/", "mustContain": "cow:RANDOMNESS_PLACEHOLDER" },
|
|
||||||
{ "path": "/subdirectory", "mustContain": "subcow:RANDOMNESS_PLACEHOLDER" }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -3,11 +3,12 @@ package subcow
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
say "github.com/dhruvbird/go-cowsay"
|
say "github.com/dhruvbird/go-cowsay"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Handler function
|
// Handler function
|
||||||
func Handler(w http.ResponseWriter, r *http.Request) {
|
func Handler(w http.ResponseWriter, r *http.Request) {
|
||||||
fmt.Fprintf(w, say.Format("subcow:RANDOMNESS_PLACEHOLDER"))
|
fmt.Fprintf(w, say.Format("subcow:" + runtime.Version() + ":RANDOMNESS_PLACEHOLDER"))
|
||||||
}
|
}
|
||||||
|
|||||||
14
packages/now-go/test/fixtures/01-cowsay/vercel.json
vendored
Normal file
14
packages/now-go/test/fixtures/01-cowsay/vercel.json
vendored
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"version": 2,
|
||||||
|
"builds": [
|
||||||
|
{ "src": "index.go", "use": "@vercel/go" },
|
||||||
|
{ "src": "subdirectory/index.go", "use": "@vercel/go" }
|
||||||
|
],
|
||||||
|
"probes": [
|
||||||
|
{ "path": "/", "mustContain": "cow:go1.16:RANDOMNESS_PLACEHOLDER" },
|
||||||
|
{
|
||||||
|
"path": "/subdirectory",
|
||||||
|
"mustContain": "subcow:go1.16:RANDOMNESS_PLACEHOLDER"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
module go-mod
|
module go-mod
|
||||||
|
|
||||||
go 1.12
|
go 1.15
|
||||||
|
|||||||
@@ -3,9 +3,10 @@ package handler
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"runtime"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Handler func
|
// Handler func
|
||||||
func Handler(w http.ResponseWriter, r *http.Request) {
|
func Handler(w http.ResponseWriter, r *http.Request) {
|
||||||
fmt.Fprintf(w, "RANDOMNESS_PLACEHOLDER")
|
fmt.Fprintf(w, "version:%s:RANDOMNESS_PLACEHOLDER", runtime.Version())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"version": 2,
|
|
||||||
"builds": [{ "src": "index.go", "use": "@vercel/go" }],
|
|
||||||
"probes": [{ "path": "/", "mustContain": "RANDOMNESS_PLACEHOLDER" }]
|
|
||||||
}
|
|
||||||
7
packages/now-go/test/fixtures/10-go-mod/vercel.json
vendored
Normal file
7
packages/now-go/test/fixtures/10-go-mod/vercel.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"version": 2,
|
||||||
|
"builds": [{ "src": "index.go", "use": "@vercel/go" }],
|
||||||
|
"probes": [
|
||||||
|
{ "path": "/", "mustContain": "version:go1.15.8:RANDOMNESS_PLACEHOLDER" }
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -3,10 +3,11 @@ package api
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"runtime"
|
||||||
"with-shared/shared"
|
"with-shared/shared"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Handler func
|
// Handler func
|
||||||
func Handler(w http.ResponseWriter, r *http.Request) {
|
func Handler(w http.ResponseWriter, r *http.Request) {
|
||||||
fmt.Fprintf(w, shared.Say("RANDOMNESS_PLACEHOLDER"))
|
fmt.Fprintf(w, "version:%s:%s", runtime.Version(), shared.Say("RANDOMNESS_PLACEHOLDER"))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
module with-shared
|
module with-shared
|
||||||
|
|
||||||
go 1.12
|
go 1.13
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
{
|
|
||||||
"version": 2,
|
|
||||||
"builds": [{ "src": "api/*.go", "use": "@vercel/go" }],
|
|
||||||
"probes": [{ "path": "/api", "mustContain": "RANDOMNESS_PLACEHOLDER" }]
|
|
||||||
}
|
|
||||||
10
packages/now-go/test/fixtures/11-go-mod-shared/vercel.json
vendored
Normal file
10
packages/now-go/test/fixtures/11-go-mod-shared/vercel.json
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"version": 2,
|
||||||
|
"builds": [{ "src": "api/*.go", "use": "@vercel/go" }],
|
||||||
|
"probes": [
|
||||||
|
{
|
||||||
|
"path": "/api",
|
||||||
|
"mustContain": "version:go1.13.15:RANDOMNESS_PLACEHOLDER"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,3 +1,3 @@
|
|||||||
module custom-flag
|
module custom-flag
|
||||||
|
|
||||||
go 1.12
|
go 1.14
|
||||||
|
|||||||
@@ -3,11 +3,12 @@ package handler
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
"custom-flag/custom"
|
"custom-flag/custom"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Index func
|
// Index func
|
||||||
func Index(w http.ResponseWriter, req *http.Request) {
|
func Index(w http.ResponseWriter, req *http.Request) {
|
||||||
fmt.Fprintf(w, custom.Random)
|
fmt.Fprintf(w, "version:%v:%v", runtime.Version(), custom.Random)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,5 +2,10 @@
|
|||||||
"version": 2,
|
"version": 2,
|
||||||
"builds": [{ "src": "index.go", "use": "@vercel/go" }],
|
"builds": [{ "src": "index.go", "use": "@vercel/go" }],
|
||||||
"build": { "env": { "GO_BUILD_FLAGS": "-tags first -ldflags '-s -w'" } },
|
"build": { "env": { "GO_BUILD_FLAGS": "-tags first -ldflags '-s -w'" } },
|
||||||
"probes": [{ "path": "/", "mustContain": "first:RANDOMNESS_PLACEHOLDER" }]
|
"probes": [
|
||||||
|
{
|
||||||
|
"path": "/",
|
||||||
|
"mustContain": "version:go1.14.15:first:RANDOMNESS_PLACEHOLDER"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
@@ -3,10 +3,11 @@ package routes
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
"github.com/vercel/does-not-exist/api/_pkg/somepackage"
|
"github.com/vercel/does-not-exist/api/_pkg/somepackage"
|
||||||
)
|
)
|
||||||
|
|
||||||
func Handler(w http.ResponseWriter, r *http.Request) {
|
func Handler(w http.ResponseWriter, r *http.Request) {
|
||||||
fmt.Fprintf(w, "Hello %v", somepackage.Foo)
|
fmt.Fprintf(w, "version:%v:%v", runtime.Version(), somepackage.Foo)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"version": 2,
|
"version": 2,
|
||||||
"builds": [
|
"builds": [
|
||||||
{
|
{
|
||||||
"src": "api/v1/**/*.go",
|
"src": "api/v1/routes/**/*.go",
|
||||||
"use": "@vercel/go",
|
"use": "@vercel/go",
|
||||||
"config": { "zeroConfig": true }
|
"config": { "zeroConfig": true }
|
||||||
}
|
}
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
"probes": [
|
"probes": [
|
||||||
{
|
{
|
||||||
"path": "/api/v1/routes/someroute.go",
|
"path": "/api/v1/routes/someroute.go",
|
||||||
"mustContain": "Hello Dependency:RANDOMNESS_PLACEHOLDER"
|
"mustContain": "version:go1.13.15:Dependency:RANDOMNESS_PLACEHOLDER"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -13,6 +13,6 @@
|
|||||||
"noImplicitThis": false,
|
"noImplicitThis": false,
|
||||||
"types": ["node"],
|
"types": ["node"],
|
||||||
"strict": true,
|
"strict": true,
|
||||||
"target": "esnext"
|
"target": "es2018"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vercel/routing-utils",
|
"name": "@vercel/routing-utils",
|
||||||
"version": "1.9.3-canary.0",
|
"version": "1.10.0",
|
||||||
"description": "Vercel routing utilities",
|
"description": "Vercel routing utilities",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"types": "./dist/index.d.ts",
|
"types": "./dist/index.d.ts",
|
||||||
|
|||||||
Reference in New Issue
Block a user