Compare commits

...

24 Commits

Author SHA1 Message Date
Nathan Rajlich
f2d396caae Publish Stable
- @vercel/build-utils@2.11.0
 - vercel@23.0.0
 - @vercel/client@10.1.0
 - @vercel/frameworks@0.4.0
 - @vercel/node@1.11.0
 - @vercel/python@2.0.3
 - @vercel/routing-utils@1.11.1
2021-05-25 14:56:11 -07:00
Matheus Fernandes
001f2f60b8 Use proper Apache License format (#6189)
The existing LICENSE file was missing the Appendix, and also
used weird formatting. Now it's an exact copy of the original:

https://www.apache.org/licenses/LICENSE-2.0.txt.
2021-05-25 13:27:32 -07:00
Nathan Rajlich
78ca930287 [cli] Show user's name in vc switch command (#6288)
This more closely matches the Team picker on vercel.com.

Will still show "email" if no "name" is defined.
2021-05-25 13:18:14 -07:00
Nathan Rajlich
b03e18df12 Publish Canary
- vercel@22.0.2-canary.7
 - @vercel/python@2.0.3-canary.0
2021-05-25 11:07:16 -07:00
Nathan Rajlich
3a6b8b072c [cli] Reauthenticate scopes with limited access in vc switch (#6280)
In the `vc switch` command, if your current access token results in
"limited" Team information being returned, then show a lock emoji
next to the team/user name in the select input.

When a locked scope is selected, then pre-emptively prompt the
user to re-authenticate using a valid login method in relation to
the desired scope.

https://user-images.githubusercontent.com/71256/119441172-87abae80-bcda-11eb-801a-cb6837bae353.mov

[ch21964]
2021-05-25 11:03:06 -07:00
Steven
d480cd6bbd [cli] Bump codecov to 3.8.2 (#6279)
Closes #5814
2021-05-24 23:16:02 +00:00
Nathan Rajlich
181b624bf4 [cli] Add SAML reauthentication logic when using different scope (#6263)
When the API returns a SAML error, then show the proper reauthentication prompt depending on the scope being requested:

Team with SAML enforced, shows only SSO login option:

<img width="476" alt="Screen Shot 2021-05-24 at 1 50 29 PM" src="https://user-images.githubusercontent.com/71256/119406131-31694c00-bc97-11eb-858a-52e5fe7052d1.png">

Team with SAML enabled, but not enforced, prompts with all login methods:

<img width="352" alt="Screen Shot 2021-05-24 at 1 50 36 PM" src="https://user-images.githubusercontent.com/71256/119406134-3201e280-bc97-11eb-9166-60fbfec47ee0.png">

Team without SAML enabled, or User scope, shows prompt with SSO option removed:

<img width="366" alt="Screen Shot 2021-05-24 at 1 50 44 PM" src="https://user-images.githubusercontent.com/71256/119406137-3201e280-bc97-11eb-8c5c-b88eb9983500.png">

[ch21964]
2021-05-24 15:16:24 -07:00
Nathan Rajlich
200495e4ce [cli] Use ts-eager to execute build script (#6278)
* [cli] Use `ts-eager` to execute build script

* Use `node -r ts-eager/register` to workaround Windows issue
2021-05-24 18:14:55 -04:00
Steven
9178f14c40 Publish Stable
- @vercel/python@2.0.2
2021-05-24 16:46:49 -04:00
Nathan Rajlich
9a790f5352 [cli] Set tokenName query param for Git provider login methods (#6277)
We're not currently setting the `tokenName` when logging in via a
Git provider, so the name becomes the default "Website" one which
is confusing / incorrect.
2021-05-24 13:38:55 -07:00
Steven
33d8be7f8f [cli] Fix vc logout retry (#6276)
* [cli] Fix `vc logout` retry

* Fix logout message
2021-05-24 16:26:01 -04:00
JJ Kasper
82aa86b786 Apply dependabot changes (#6275)
* Bump elliptic in /packages/cli/test/dev/fixtures/02-angular-node

Bumps [elliptic](https://github.com/indutny/elliptic) from 6.5.2 to 6.5.4.
- [Release notes](https://github.com/indutny/elliptic/releases)
- [Commits](https://github.com/indutny/elliptic/compare/v6.5.2...v6.5.4)

Signed-off-by: dependabot[bot] <support@github.com>

* Bump node-fetch from 2.6.0 to 2.6.1 in /api

Bumps [node-fetch](https://github.com/bitinn/node-fetch) from 2.6.0 to 2.6.1.
- [Release notes](https://github.com/bitinn/node-fetch/releases)
- [Changelog](https://github.com/node-fetch/node-fetch/blob/master/docs/CHANGELOG.md)
- [Commits](https://github.com/bitinn/node-fetch/compare/v2.6.0...v2.6.1)

Signed-off-by: dependabot[bot] <support@github.com>

* Bump ssri from 6.0.1 to 6.0.2 in /examples/blitzjs

Bumps [ssri](https://github.com/npm/ssri) from 6.0.1 to 6.0.2.
- [Release notes](https://github.com/npm/ssri/releases)
- [Changelog](https://github.com/npm/ssri/blob/v6.0.2/CHANGELOG.md)
- [Commits](https://github.com/npm/ssri/compare/v6.0.1...v6.0.2)

Signed-off-by: dependabot[bot] <support@github.com>

* Bump hosted-git-info from 2.8.8 to 2.8.9 in /examples/angular

Bumps [hosted-git-info](https://github.com/npm/hosted-git-info) from 2.8.8 to 2.8.9.
- [Release notes](https://github.com/npm/hosted-git-info/releases)
- [Changelog](https://github.com/npm/hosted-git-info/blob/v2.8.9/CHANGELOG.md)
- [Commits](https://github.com/npm/hosted-git-info/compare/v2.8.8...v2.8.9)

Signed-off-by: dependabot[bot] <support@github.com>

* Bump hosted-git-info from 2.8.8 to 2.8.9 in /examples/blitzjs

Bumps [hosted-git-info](https://github.com/npm/hosted-git-info) from 2.8.8 to 2.8.9.
- [Release notes](https://github.com/npm/hosted-git-info/releases)
- [Changelog](https://github.com/npm/hosted-git-info/blob/v2.8.9/CHANGELOG.md)
- [Commits](https://github.com/npm/hosted-git-info/compare/v2.8.8...v2.8.9)

Signed-off-by: dependabot[bot] <support@github.com>

* Bump ssri in /packages/cli/test/dev/fixtures/02-angular-node

Bumps [ssri](https://github.com/npm/ssri) from 6.0.1 to 6.0.2.
- [Release notes](https://github.com/npm/ssri/releases)
- [Changelog](https://github.com/npm/ssri/blob/v6.0.2/CHANGELOG.md)
- [Commits](https://github.com/npm/ssri/compare/v6.0.1...v6.0.2)

Signed-off-by: dependabot[bot] <support@github.com>

* Bump ssri in /packages/cli/test/dev/fixtures/04-create-react-app

Bumps [ssri](https://github.com/npm/ssri) from 6.0.1 to 6.0.2.
- [Release notes](https://github.com/npm/ssri/releases)
- [Changelog](https://github.com/npm/ssri/blob/v6.0.2/CHANGELOG.md)
- [Commits](https://github.com/npm/ssri/compare/v6.0.1...v6.0.2)

Signed-off-by: dependabot[bot] <support@github.com>

* Bump ssri in /packages/cli/test/dev/fixtures/03-aurelia

Bumps [ssri](https://github.com/npm/ssri) from 6.0.1 to 6.0.2.
- [Release notes](https://github.com/npm/ssri/releases)
- [Changelog](https://github.com/npm/ssri/blob/v6.0.2/CHANGELOG.md)
- [Commits](https://github.com/npm/ssri/compare/v6.0.1...v6.0.2)

Signed-off-by: dependabot[bot] <support@github.com>

* Bump hosted-git-info in /packages/cli/test/dev/fixtures/02-angular-node

Bumps [hosted-git-info](https://github.com/npm/hosted-git-info) from 2.8.8 to 2.8.9.
- [Release notes](https://github.com/npm/hosted-git-info/releases)
- [Changelog](https://github.com/npm/hosted-git-info/blob/v2.8.9/CHANGELOG.md)
- [Commits](https://github.com/npm/hosted-git-info/compare/v2.8.8...v2.8.9)

Signed-off-by: dependabot[bot] <support@github.com>

* Bump url-parse in /packages/cli/test/dev/fixtures/04-create-react-app

Bumps [url-parse](https://github.com/unshiftio/url-parse) from 1.4.7 to 1.5.1.
- [Release notes](https://github.com/unshiftio/url-parse/releases)
- [Commits](https://github.com/unshiftio/url-parse/compare/1.4.7...1.5.1)

Signed-off-by: dependabot[bot] <support@github.com>

* Bump url-parse in /packages/cli/test/dev/fixtures/03-aurelia

Bumps [url-parse](https://github.com/unshiftio/url-parse) from 1.4.7 to 1.5.1.
- [Release notes](https://github.com/unshiftio/url-parse/releases)
- [Commits](https://github.com/unshiftio/url-parse/compare/1.4.7...1.5.1)

Signed-off-by: dependabot[bot] <support@github.com>

* Bump handlebars in /packages/cli/test/dev/fixtures/02-angular-node

Bumps [handlebars](https://github.com/wycats/handlebars.js) from 4.7.6 to 4.7.7.
- [Release notes](https://github.com/wycats/handlebars.js/releases)
- [Changelog](https://github.com/handlebars-lang/handlebars.js/blob/master/release-notes.md)
- [Commits](https://github.com/wycats/handlebars.js/compare/v4.7.6...v4.7.7)

Signed-off-by: dependabot[bot] <support@github.com>

* Bump lodash in /packages/cli/test/dev/fixtures/02-angular-node

Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.21.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.21)

Signed-off-by: dependabot[bot] <support@github.com>

* Bump hosted-git-info in /packages/cli/test/dev/fixtures/03-aurelia

Bumps [hosted-git-info](https://github.com/npm/hosted-git-info) from 2.8.8 to 2.8.9.
- [Release notes](https://github.com/npm/hosted-git-info/releases)
- [Changelog](https://github.com/npm/hosted-git-info/blob/v2.8.9/CHANGELOG.md)
- [Commits](https://github.com/npm/hosted-git-info/compare/v2.8.8...v2.8.9)

Signed-off-by: dependabot[bot] <support@github.com>

* Bump hosted-git-info

Bumps [hosted-git-info](https://github.com/npm/hosted-git-info) from 2.8.8 to 2.8.9.
- [Release notes](https://github.com/npm/hosted-git-info/releases)
- [Changelog](https://github.com/npm/hosted-git-info/blob/v2.8.9/CHANGELOG.md)
- [Commits](https://github.com/npm/hosted-git-info/compare/v2.8.8...v2.8.9)

Signed-off-by: dependabot[bot] <support@github.com>

* Bump lodash in /packages/cli/test/dev/fixtures/03-aurelia

Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.21.
- [Release notes](https://github.com/lodash/lodash/releases)
- [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.21)

Signed-off-by: dependabot[bot] <support@github.com>

* Bump url-parse in /packages/cli/test/dev/fixtures/02-angular-node

Bumps [url-parse](https://github.com/unshiftio/url-parse) from 1.4.7 to 1.5.1.
- [Release notes](https://github.com/unshiftio/url-parse/releases)
- [Commits](https://github.com/unshiftio/url-parse/compare/1.4.7...1.5.1)

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Steven <steven@ceriously.com>
2021-05-24 15:49:31 -04:00
Steven
6288d5ef43 Publish Canary
- vercel@22.0.2-canary.6
 - @vercel/client@10.0.1-canary.5
 - @vercel/node@1.10.1-canary.2
 - @vercel/python@2.0.2-canary.0
2021-05-24 13:37:57 -04:00
Steven
00a97b7ae2 [node] Bump nft to 0.12.2 (#6274) 2021-05-24 13:34:28 -04:00
Steven
a19fb3aa0f [python] Fix installRequirement to use explicit version (#6272)
* [python] Fix installRequirement to use explicit version

* Remove `--upgrade`
2021-05-24 11:41:57 -04:00
Nathan Rajlich
93fae76f9c [cli] Simplify emoji module (#6260) 2021-05-21 13:53:13 -07:00
Nathan Rajlich
e5131d5557 [cli] Update NowConfig references to VercelConfig (#6256)
The `NowConfig` interface is deprecated.
2021-05-21 12:21:38 -07:00
Nathan Rajlich
930063638c [cli] Refactor vc logs command (#6259) 2021-05-21 11:36:58 -07:00
Nathan Rajlich
7b509ae672 [cli] Refactor vc switch command (#6257)
Refactors the `vc switch` command to more closely match how the team picker works on the Vercel dashboard:

 * Converts to TypeScript
 * Adds separator between user scope and team scopes
 * Sorts teams by name
 * No longer places the current scope at the top of the list (but the current scope is still selected by default)
2021-05-20 11:19:38 -07:00
Nathan Rajlich
711da37771 [cli] Refactor vc inspect command (#6258) 2021-05-20 10:30:33 -07:00
Steven
5e50b96994 Publish Canary
- vercel@22.0.2-canary.5
 - @vercel/node@1.10.1-canary.1
2021-05-13 16:40:36 -04:00
Steven
35d2f5950f [node] Bump nft to 0.12.0 (#6229) 2021-05-13 16:22:58 -04:00
Steven
37f969416c Publish Canary
- @vercel/build-utils@2.10.3-canary.4
 - vercel@22.0.2-canary.4
 - @vercel/client@10.0.1-canary.4
 - @vercel/node@1.10.1-canary.0
2021-05-10 14:01:41 -04:00
Steven
75630e0982 [node] Bump nft to 0.11.2 (#6211)
* [node] Bump nft to 0.11.2

* Fix tests since node 10.x is discontinued
2021-05-10 14:01:02 -04:00
77 changed files with 1246 additions and 1066 deletions

332
LICENSE
View File

@@ -1,190 +1,202 @@
Apache License
Version 2.0, January 2004
https://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
1. Definitions. TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
"License" shall mean the terms and conditions for use, reproduction, 1. Definitions.
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by "License" shall mean the terms and conditions for use, reproduction,
the copyright owner that is granting the License. and distribution as defined by Sections 1 through 9 of this document.
"Legal Entity" shall mean the union of the acting entity and all "Licensor" shall mean the copyright owner or entity authorized by
other entities that control, are controlled by, or are under common the copyright owner that is granting the License.
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity "Legal Entity" shall mean the union of the acting entity and all
exercising permissions granted by this License. other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"Source" form shall mean the preferred form for making modifications, "You" (or "Your") shall mean an individual or Legal Entity
including but not limited to software source code, documentation exercising permissions granted by this License.
source, and configuration files.
"Object" form shall mean any form resulting from mechanical "Source" form shall mean the preferred form for making modifications,
transformation or translation of a Source form, including but including but not limited to software source code, documentation
not limited to compiled object code, generated documentation, source, and configuration files.
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or "Object" form shall mean any form resulting from mechanical
Object form, made available under the License, as indicated by a transformation or translation of a Source form, including but
copyright notice that is included in or attached to the work not limited to compiled object code, generated documentation,
(an example is provided in the Appendix below). and conversions to other media types.
"Derivative Works" shall mean any work, whether in Source or Object "Work" shall mean the work of authorship, whether in Source or
form, that is based on (or derived from) the Work and for which the Object form, made available under the License, as indicated by a
editorial revisions, annotations, elaborations, or other modifications copyright notice that is included in or attached to the work
represent, as a whole, an original work of authorship. For the purposes (an example is provided in the Appendix below).
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including "Derivative Works" shall mean any work, whether in Source or Object
the original version of the Work and any modifications or additions form, that is based on (or derived from) the Work and for which the
to that Work or Derivative Works thereof, that is intentionally editorial revisions, annotations, elaborations, or other modifications
submitted to Licensor for inclusion in the Work by the copyright owner represent, as a whole, an original work of authorship. For the purposes
or by an individual or Legal Entity authorized to submit on behalf of of this License, Derivative Works shall not include works that remain
the copyright owner. For the purposes of this definition, "submitted" separable from, or merely link (or bind by name) to the interfaces of,
means any form of electronic, verbal, or written communication sent the Work and Derivative Works thereof.
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity "Contribution" shall mean any work of authorship, including
on behalf of whom a Contribution has been received by Licensor and the original version of the Work and any modifications or additions
subsequently incorporated within the Work. to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
2. Grant of Copyright License. Subject to the terms and conditions of "Contributor" shall mean Licensor and any individual or Legal Entity
this License, each Contributor hereby grants to You a perpetual, on behalf of whom a Contribution has been received by Licensor and
worldwide, non-exclusive, no-charge, royalty-free, irrevocable subsequently incorporated within the Work.
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of 2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual, this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made, copyright license to reproduce, prepare Derivative Works of,
use, offer to sell, sell, import, and otherwise transfer the Work, publicly display, publicly perform, sublicense, and distribute the
where such license applies only to those patent claims licensable Work and such Derivative Works in Source or Object form.
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the 3. Grant of Patent License. Subject to the terms and conditions of
Work or Derivative Works thereof in any medium, with or without this License, each Contributor hereby grants to You a perpetual,
modifications, and in Source or Object form, provided that You worldwide, non-exclusive, no-charge, royalty-free, irrevocable
meet the following conditions: (except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
(a) You must give any other recipients of the Work or 4. Redistribution. You may reproduce and distribute copies of the
Derivative Works a copy of this License; and Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(b) You must cause any modified files to carry prominent notices (a) You must give any other recipients of the Work or
stating that You changed the files; and Derivative Works a copy of this License; and
(c) You must retain, in the Source form of any Derivative Works (b) You must cause any modified files to carry prominent notices
that You distribute, all copyright, patent, trademark, and stating that You changed the files; and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its (c) You must retain, in the Source form of any Derivative Works
distribution, then any Derivative Works that You distribute must that You distribute, all copyright, patent, trademark, and
include a readable copy of the attribution notices contained attribution notices from the Source form of the Work,
within such NOTICE file, excluding those notices that do not excluding those notices that do not pertain to any part of
pertain to any part of the Derivative Works, in at least one the Derivative Works; and
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and (d) If the Work includes a "NOTICE" text file as part of its
may provide additional or different license terms and conditions distribution, then any Derivative Works that You distribute must
for use, reproduction, or distribution of Your modifications, or include a readable copy of the attribution notices contained
for any such Derivative Works as a whole, provided Your use, within such NOTICE file, excluding those notices that do not
reproduction, and distribution of the Work otherwise complies with pertain to any part of the Derivative Works, in at least one
the conditions stated in this License. of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
5. Submission of Contributions. Unless You explicitly state otherwise, You may add Your own copyright statement to Your modifications and
any Contribution intentionally submitted for inclusion in the Work may provide additional or different license terms and conditions
by You to the Licensor shall be under the terms and conditions of for use, reproduction, or distribution of Your modifications, or
this License, without any additional terms or conditions. for any such Derivative Works as a whole, provided Your use,
Notwithstanding the above, nothing herein shall supersede or modify reproduction, and distribution of the Work otherwise complies with
the terms of any separate license agreement you may have executed the conditions stated in this License.
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade 5. Submission of Contributions. Unless You explicitly state otherwise,
names, trademarks, service marks, or product names of the Licensor, any Contribution intentionally submitted for inclusion in the Work
except as required for reasonable and customary use in describing the by You to the Licensor shall be under the terms and conditions of
origin of the Work and reproducing the content of the NOTICE file. this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
7. Disclaimer of Warranty. Unless required by applicable law or 6. Trademarks. This License does not grant permission to use the trade
agreed to in writing, Licensor provides the Work (and each names, trademarks, service marks, or product names of the Licensor,
Contributor provides its Contributions) on an "AS IS" BASIS, except as required for reasonable and customary use in describing the
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or origin of the Work and reproducing the content of the NOTICE file.
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory, 7. Disclaimer of Warranty. Unless required by applicable law or
whether in tort (including negligence), contract, or otherwise, agreed to in writing, Licensor provides the Work (and each
unless required by applicable law (such as deliberate and grossly Contributor provides its Contributions) on an "AS IS" BASIS,
negligent acts) or agreed to in writing, shall any Contributor be WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
liable to You for damages, including any direct, indirect, special, implied, including, without limitation, any warranties or conditions
incidental, or consequential damages of any character arising as a of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
result of this License or out of the use or inability to use the PARTICULAR PURPOSE. You are solely responsible for determining the
Work (including but not limited to damages for loss of goodwill, appropriateness of using or redistributing the Work and assume any
work stoppage, computer failure or malfunction, or any and all risks associated with Your exercise of permissions under this License.
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing 8. Limitation of Liability. In no event and under no legal theory,
the Work or Derivative Works thereof, You may choose to offer, whether in tort (including negligence), contract, or otherwise,
and charge a fee for, acceptance of support, warranty, indemnity, unless required by applicable law (such as deliberate and grossly
or other liability obligations and/or rights consistent with this negligent acts) or agreed to in writing, shall any Contributor be
License. However, in accepting such obligations, You may act only liable to You for damages, including any direct, indirect, special,
on Your own behalf and on Your sole responsibility, not on behalf incidental, or consequential damages of any character arising as a
of any other Contributor, and only if You agree to indemnify, result of this License or out of the use or inability to use the
defend, and hold each Contributor harmless for any liability Work (including but not limited to damages for loss of goodwill,
incurred by, or claims asserted against, such Contributor by reason work stoppage, computer failure or malfunction, or any and all
of your accepting any such warranty or additional liability. other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
END OF TERMS AND CONDITIONS 9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
Copyright 2017 Vercel, Inc. END OF TERMS AND CONDITIONS
Licensed under the Apache License, Version 2.0 (the "License"); APPENDIX: How to apply the Apache License to your work.
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0 To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Unless required by applicable law or agreed to in writing, software Copyright 2017 Vercel, Inc.
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Licensed under the Apache License, Version 2.0 (the "License");
See the License for the specific language governing permissions and you may not use this file except in compliance with the License.
limitations under the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -10,7 +10,7 @@
"dependencies": { "dependencies": {
"@sentry/node": "5.11.1", "@sentry/node": "5.11.1",
"got": "10.2.1", "got": "10.2.1",
"node-fetch": "2.6.0", "node-fetch": "2.6.1",
"parse-github-url": "1.0.2", "parse-github-url": "1.0.2",
"tar-fs": "2.0.0", "tar-fs": "2.0.0",
"unzip-stream": "0.3.0" "unzip-stream": "0.3.0"

View File

@@ -362,10 +362,10 @@ ms@^2.1.1:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
node-fetch@2.6.0: node-fetch@2.6.1:
version "2.6.0" version "2.6.1"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA== integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
normalize-url@^4.1.0: normalize-url@^4.1.0:
version "4.5.0" version "4.5.0"

View File

@@ -3073,9 +3073,9 @@ hmac-drbg@^1.0.1:
minimalistic-crypto-utils "^1.0.1" minimalistic-crypto-utils "^1.0.1"
hosted-git-info@^2.1.4, hosted-git-info@^2.6.0, hosted-git-info@^2.7.1: hosted-git-info@^2.1.4, hosted-git-info@^2.6.0, hosted-git-info@^2.7.1:
version "2.8.8" version "2.8.9"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9"
integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==
hpack.js@^2.1.6: hpack.js@^2.1.6:
version "2.1.6" version "2.1.6"

View File

@@ -4681,9 +4681,9 @@ hmac-drbg@^1.0.1:
minimalistic-crypto-utils "^1.0.1" minimalistic-crypto-utils "^1.0.1"
hosted-git-info@^2.1.4: hosted-git-info@^2.1.4:
version "2.8.8" version "2.8.9"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9"
integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==
hsl-regex@^1.0.0: hsl-regex@^1.0.0:
version "1.0.0" version "1.0.0"
@@ -8195,9 +8195,9 @@ sprintf-js@~1.0.2:
integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=
ssri@^6.0.1: ssri@^6.0.1:
version "6.0.1" version "6.0.2"
resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.2.tgz#157939134f20464e7301ddba3e90ffa8f7728ac5"
integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== integrity sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==
dependencies: dependencies:
figgy-pudding "^3.5.1" figgy-pudding "^3.5.1"

View File

@@ -2,7 +2,7 @@
"name": "vercel-monorepo", "name": "vercel-monorepo",
"version": "0.0.0", "version": "0.0.0",
"private": true, "private": true,
"license": "MIT", "license": "Apache-2.0",
"workspaces": { "workspaces": {
"packages": [ "packages": [
"packages/*" "packages/*"

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/build-utils", "name": "@vercel/build-utils",
"version": "2.10.3-canary.3", "version": "2.11.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.3.3-canary.3", "@vercel/frameworks": "0.4.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",

View File

@@ -1 +0,0 @@
declare module 'inquirer';

View File

@@ -0,0 +1,5 @@
declare module 'jsonlines' {
import { Transform } from 'stream';
function parse(): Transform;
}

View File

@@ -1,6 +1,6 @@
{ {
"name": "vercel", "name": "vercel",
"version": "22.0.2-canary.3", "version": "23.0.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",
@@ -17,8 +17,8 @@
"test-integration-dev": "ava test/dev/integration.js --serial --fail-fast --verbose", "test-integration-dev": "ava test/dev/integration.js --serial --fail-fast --verbose",
"prepublishOnly": "yarn build", "prepublishOnly": "yarn build",
"coverage": "nyc report --reporter=text-lcov > coverage.lcov && codecov", "coverage": "nyc report --reporter=text-lcov > coverage.lcov && codecov",
"build": "ts-node ./scripts/build.ts", "build": "node -r ts-eager/register ./scripts/build.ts",
"build-dev": "ts-node ./scripts/build.ts --dev" "build-dev": "node -r ts-eager/register ./scripts/build.ts --dev"
}, },
"nyc": { "nyc": {
"include": [ "include": [
@@ -61,10 +61,10 @@
"node": ">= 12" "node": ">= 12"
}, },
"dependencies": { "dependencies": {
"@vercel/build-utils": "2.10.3-canary.3", "@vercel/build-utils": "2.11.0",
"@vercel/go": "1.2.2", "@vercel/go": "1.2.2",
"@vercel/node": "1.10.0", "@vercel/node": "1.11.0",
"@vercel/python": "2.0.1", "@vercel/python": "2.0.3",
"@vercel/ruby": "1.2.6", "@vercel/ruby": "1.2.6",
"update-notifier": "4.1.0" "update-notifier": "4.1.0"
}, },
@@ -82,13 +82,14 @@
"@types/fs-extra": "5.0.5", "@types/fs-extra": "5.0.5",
"@types/glob": "7.1.1", "@types/glob": "7.1.1",
"@types/http-proxy": "1.16.2", "@types/http-proxy": "1.16.2",
"@types/inquirer": "7.3.1",
"@types/load-json-file": "2.0.7", "@types/load-json-file": "2.0.7",
"@types/mime-types": "2.1.0", "@types/mime-types": "2.1.0",
"@types/minimatch": "3.0.3", "@types/minimatch": "3.0.3",
"@types/mri": "1.1.0", "@types/mri": "1.1.0",
"@types/ms": "0.7.30", "@types/ms": "0.7.30",
"@types/node": "11.11.0", "@types/node": "11.11.0",
"@types/node-fetch": "2.1.4", "@types/node-fetch": "2.5.10",
"@types/npm-package-arg": "6.1.0", "@types/npm-package-arg": "6.1.0",
"@types/pluralize": "0.0.29", "@types/pluralize": "0.0.29",
"@types/progress": "2.0.3", "@types/progress": "2.0.3",
@@ -99,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.3.3-canary.3", "@vercel/frameworks": "0.4.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",
@@ -116,7 +117,7 @@
"chalk": "4.1.0", "chalk": "4.1.0",
"chokidar": "3.3.1", "chokidar": "3.3.1",
"clipboardy": "2.1.0", "clipboardy": "2.1.0",
"codecov": "3.7.1", "codecov": "3.8.2",
"cpy": "7.2.0", "cpy": "7.2.0",
"credit-card": "3.0.1", "credit-card": "3.0.1",
"date-fns": "1.29.0", "date-fns": "1.29.0",
@@ -168,6 +169,7 @@
"title": "3.4.1", "title": "3.4.1",
"tmp-promise": "1.0.3", "tmp-promise": "1.0.3",
"tree-kill": "1.2.2", "tree-kill": "1.2.2",
"ts-eager": "2.0.2",
"ts-node": "8.3.0", "ts-node": "8.3.0",
"typescript": "3.9.3", "typescript": "3.9.3",
"universal-analytics": "0.4.20", "universal-analytics": "0.4.20",

View File

@@ -19,7 +19,7 @@ import link from '../../util/output/link';
import { User } from '../../types'; import { User } from '../../types';
import { getCommandName } from '../../util/pkg-name'; import { getCommandName } from '../../util/pkg-name';
import toHost from '../../util/to-host'; import toHost from '../../util/to-host';
import { NowConfig } from '../../util/dev/types'; import { VercelConfig } from '../../util/dev/types';
type Options = { type Options = {
'--debug': boolean; '--debug': boolean;
@@ -421,7 +421,7 @@ function handleCreateAliasError<T>(
return error; return error;
} }
function getTargetsForAlias(args: string[], { alias }: NowConfig) { function getTargetsForAlias(args: string[], { alias }: VercelConfig) {
if (args.length) { if (args.length) {
return [args[args.length - 1]] return [args[args.length - 1]]
.map(target => (target.indexOf('.') !== -1 ? toHost(target) : target)) .map(target => (target.indexOf('.') !== -1 ? toHost(target) : target))

View File

@@ -111,7 +111,6 @@ async function chooseFromDropdown(message: string, exampleList: string[]) {
return listInput({ return listInput({
message, message,
separator: false,
choices, choices,
}); });
} }

View File

@@ -3,12 +3,14 @@ import getArgs from '../util/get-args';
import buildsList from '../util/output/builds'; import buildsList from '../util/output/builds';
import routesList from '../util/output/routes'; import routesList from '../util/output/routes';
import indent from '../util/output/indent'; import indent from '../util/output/indent';
import Now from '../util';
import logo from '../util/output/logo'; import logo from '../util/output/logo';
import elapsed from '../util/output/elapsed.ts'; import elapsed from '../util/output/elapsed';
import { handleError } from '../util/error'; import { handleError } from '../util/error';
import getScope from '../util/get-scope.ts'; import getScope from '../util/get-scope';
import { getPkgName, getCommandName } from '../util/pkg-name.ts'; import { getPkgName, getCommandName } from '../util/pkg-name';
import Client from '../util/client';
import { getDeployment } from '../util/get-deployment';
import { Deployment } from '@vercel/client';
const help = () => { const help = () => {
console.log(` console.log(`
@@ -33,15 +35,15 @@ const help = () => {
${chalk.gray('')} Get information about a deployment by its unique URL ${chalk.gray('')} Get information about a deployment by its unique URL
${chalk.cyan(`$ ${getPkgName()} inspect my-deployment-ji2fjij2.now.sh`)} ${chalk.cyan(`$ ${getPkgName()} inspect my-deployment-ji2fjij2.vercel.app`)}
${chalk.gray('-')} Get information about the deployment an alias points to ${chalk.gray('-')} Get information about the deployment an alias points to
${chalk.cyan(`$ ${getPkgName()} inspect my-deployment.now.sh`)} ${chalk.cyan(`$ ${getPkgName()} inspect my-deployment.vercel.app`)}
`); `);
}; };
export default async function main(client) { export default async function main(client: Client) {
let deployment; let deployment;
let argv; let argv;
@@ -57,14 +59,7 @@ export default async function main(client) {
return 2; return 2;
} }
const { const { print, log, error } = client.output;
apiUrl,
output,
authConfig: { token },
config,
} = client;
const debugEnabled = argv['--debug'];
const { print, log, error } = output;
// extract the first parameter // extract the first parameter
const [, deploymentIdOrHost] = argv._; const [, deploymentIdOrHost] = argv._;
@@ -75,9 +70,7 @@ export default async function main(client) {
return 1; return 1;
} }
const { currentTeam } = config; let contextName: string | null = null;
let contextName = null;
try { try {
({ contextName } = await getScope(client)); ({ contextName } = await getScope(client));
@@ -90,22 +83,14 @@ export default async function main(client) {
throw err; throw err;
} }
const now = new Now({
apiUrl,
token,
debug: debugEnabled,
currentTeam,
output,
});
// resolve the deployment, since we might have been given an alias // resolve the deployment, since we might have been given an alias
const depFetchStart = Date.now(); const depFetchStart = Date.now();
output.spinner( client.output.spinner(
`Fetching deployment "${deploymentIdOrHost}" in ${chalk.bold(contextName)}` `Fetching deployment "${deploymentIdOrHost}" in ${chalk.bold(contextName)}`
); );
try { try {
deployment = await now.findDeployment(deploymentIdOrHost); deployment = await getDeployment(client, deploymentIdOrHost);
} catch (err) { } catch (err) {
if (err.status === 404) { if (err.status === 404) {
error( error(
@@ -127,11 +112,11 @@ export default async function main(client) {
throw err; throw err;
} }
const { id, name, url, created, routes, readyState } = deployment; const { id, name, url, createdAt, routes, readyState } = deployment;
const { builds } = const { builds } =
deployment.version === 2 deployment.version === 2
? await now.fetch(`/v1/now/deployments/${id}/builds`) ? await client.fetch(`/v1/now/deployments/${id}/builds`)
: { builds: [] }; : { builds: [] };
log( log(
@@ -146,10 +131,10 @@ export default async function main(client) {
print(` ${chalk.cyan('name')}\t${name}\n`); print(` ${chalk.cyan('name')}\t${name}\n`);
print(` ${chalk.cyan('readyState')}\t${stateString(readyState)}\n`); print(` ${chalk.cyan('readyState')}\t${stateString(readyState)}\n`);
print(` ${chalk.cyan('url')}\t\t${url}\n`); print(` ${chalk.cyan('url')}\t\t${url}\n`);
if (created) { if (createdAt) {
print( print(
` ${chalk.cyan('createdAt')}\t${new Date(created)} ${elapsed( ` ${chalk.cyan('createdAt')}\t${new Date(createdAt)} ${elapsed(
Date.now() - created, Date.now() - createdAt,
true true
)}\n` )}\n`
); );
@@ -157,7 +142,7 @@ export default async function main(client) {
print('\n\n'); print('\n\n');
if (builds.length > 0) { if (builds.length > 0) {
const times = {}; const times: { [id: string]: string | null } = {};
for (const build of builds) { for (const build of builds) {
const { id, createdAt, readyStateAt } = build; const { id, createdAt, readyStateAt } = build;
@@ -179,7 +164,7 @@ export default async function main(client) {
} }
// renders the state string // renders the state string
function stateString(s) { function stateString(s: Deployment['readyState']) {
switch (s) { switch (s) {
case 'INITIALIZING': case 'INITIALIZING':
return chalk.yellow(s); return chalk.yellow(s);

View File

@@ -73,9 +73,9 @@ export default async function login(client: Client): Promise<number> {
if (input) { if (input) {
// Email or Team slug was provided via command line // Email or Team slug was provided via command line
if (validateEmail(input)) { if (validateEmail(input)) {
result = await doEmailLogin(input, params); result = await doEmailLogin(params, input);
} else { } else {
result = await doSsoLogin(input, params); result = await doSsoLogin(params, input);
} }
} else { } else {
// Interactive mode // Interactive mode

View File

@@ -1,5 +1,4 @@
import chalk from 'chalk'; import chalk from 'chalk';
import fetch from 'node-fetch';
import logo from '../util/output/logo'; import logo from '../util/output/logo';
// @ts-ignore // @ts-ignore
import { handleError } from '../util/error'; import { handleError } from '../util/error';
@@ -48,10 +47,9 @@ export default async function main(client: Client): Promise<number> {
return 2; return 2;
} }
const { authConfig, config, apiUrl, output } = client; const { authConfig, config, output } = client;
const { token } = authConfig;
if (!token) { if (!authConfig.token) {
output.note( output.note(
`Not currently logged in, so ${getCommandName('logout')} did nothing` `Not currently logged in, so ${getCommandName('logout')} did nothing`
); );
@@ -59,6 +57,20 @@ export default async function main(client: Client): Promise<number> {
} }
output.spinner('Logging out…', 200); output.spinner('Logging out…', 200);
let exitCode = 0;
try {
await client.fetch(`/v3/user/tokens/current`, {
method: 'DELETE',
});
} catch (err) {
if (err.status === 403) {
output.debug('Token is invalid so it cannot be revoked');
} else if (err.status !== 200) {
output.debug(err?.message ?? '');
exitCode = 1;
}
}
delete config.currentTeam; delete config.currentTeam;
@@ -75,26 +87,15 @@ export default async function main(client: Client): Promise<number> {
writeToAuthConfigFile(authConfig); writeToAuthConfigFile(authConfig);
output.debug('Configuration has been deleted'); output.debug('Configuration has been deleted');
} catch (err) { } catch (err) {
output.error(`Couldn't remove config while logging out`); output.debug(err?.message ?? '');
return 1; exitCode = 1;
} }
const res = await fetch(`${apiUrl}/v3/user/tokens/current`, { if (exitCode === 0) {
method: 'DELETE', output.log('Logged out!');
headers: { } else {
Authorization: `Bearer ${token}`, output.error(`Failed during logout`);
},
});
if (res.status === 403) {
output.debug('Token is invalid so it cannot be revoked');
} else if (res.status !== 200) {
const err = await res.json();
output.error('Failed to revoke token');
output.debug(err ? err.message : '');
return 1;
} }
output.log('Logged out!'); return exitCode;
return 0;
} }

View File

@@ -1,13 +1,13 @@
import chalk from 'chalk'; import chalk from 'chalk';
import Now from '../util';
import logo from '../util/output/logo'; import logo from '../util/output/logo';
import elapsed from '../util/output/elapsed.ts'; import elapsed from '../util/output/elapsed';
import { maybeURL, normalizeURL } from '../util/url'; import { maybeURL, normalizeURL } from '../util/url';
import printEvents from '../util/events'; import printEvents, { DeploymentEvent } from '../util/events';
import getScope from '../util/get-scope.ts'; import getScope from '../util/get-scope';
import { getPkgName } from '../util/pkg-name.ts'; import { getPkgName } from '../util/pkg-name';
import getArgs from '../util/get-args.ts'; import getArgs from '../util/get-args';
import handleError from '../util/handle-error.ts'; import Client from '../util/client';
import { getDeployment } from '../util/get-deployment';
const help = () => { const help = () => {
console.log(` console.log(`
@@ -53,35 +53,25 @@ const help = () => {
`); `);
}; };
export default async function main(client) { export default async function main(client: Client) {
let argv;
let deploymentIdOrURL;
let debug;
let head; let head;
let limit; let limit;
let follow; let follow;
let outputMode;
let since; let since;
let until; let until;
let deploymentIdOrURL;
try { const argv = getArgs(client.argv.slice(2), {
argv = getArgs(client.argv.slice(2), { '--since': String,
'--since': String, '--until': String,
'--until': String, '--output': String,
'--output': String, '--limit': Number,
'--limit': Number, '--head': Boolean,
'--head': Boolean, '--follow': Boolean,
'--follow': Boolean, '-f': '--follow',
'-f': '--follow', '-o': '--output',
'-o': '--output', '-n': '--limit',
'-n': '--limit', });
});
} catch (error) {
handleError(error);
return 1;
}
argv._ = argv._.slice(1); argv._ = argv._.slice(1);
deploymentIdOrURL = argv._[0]; deploymentIdOrURL = argv._[0];
@@ -91,12 +81,7 @@ export default async function main(client) {
return 2; return 2;
} }
const { const { output } = client;
authConfig: { token },
apiUrl,
output,
config,
} = client;
try { try {
since = argv['--since'] ? toTimestamp(argv['--since']) : 0; since = argv['--since'] ? toTimestamp(argv['--since']) : 0;
@@ -124,40 +109,24 @@ export default async function main(client) {
deploymentIdOrURL = normalizedURL; deploymentIdOrURL = normalizedURL;
} }
debug = argv['--debug'];
head = argv['--head']; head = argv['--head'];
limit = argv['--limit'] || 100; limit = argv['--limit'] || 100;
follow = argv['--follow']; follow = argv['--follow'];
if (follow) until = 0; if (follow) until = 0;
outputMode = argv['--output'] in logPrinters ? argv['--output'] : 'short'; const logPrinter = getLogPrinter(argv['--output'], 'short');
const { currentTeam } = config; const { contextName } = await getScope(client);
const now = new Now({ apiUrl, token, debug, currentTeam, output });
let contextName = null;
try {
({ contextName } = await getScope(client));
} catch (err) {
if (err.code === 'NOT_AUTHORIZED' || err.code === 'TEAM_DELETED') {
output.error(err.message);
return 1;
}
throw err;
}
let deployment;
const id = deploymentIdOrURL; const id = deploymentIdOrURL;
const depFetchStart = Date.now(); const depFetchStart = Date.now();
output.spinner(`Fetching deployment "${id}" in ${chalk.bold(contextName)}`); output.spinner(`Fetching deployment "${id}" in ${chalk.bold(contextName)}`);
let deployment;
try { try {
deployment = await now.findDeployment(id); deployment = await getDeployment(client, id);
} catch (err) { } catch (err) {
output.stopSpinner(); output.stopSpinner();
now.close();
if (err.status === 404) { if (err.status === 404) {
output.error( output.error(
@@ -183,31 +152,28 @@ export default async function main(client) {
)} ${elapsed(Date.now() - depFetchStart)}` )} ${elapsed(Date.now() - depFetchStart)}`
); );
let direction = head ? 'forward' : 'backward'; const storage: DeploymentEvent[] = [];
if (since && !until) direction = 'forward';
const findOpts1 = {
direction,
limit,
since,
until,
}; // no follow
const storage = [];
const storeEvent = event => storage.push(event);
await printEvents(now, deployment.uid || deployment.id, currentTeam, { let direction = head ? ('forward' as const) : ('backward' as const);
if (since && !until) direction = 'forward';
await printEvents(client, deployment.id, {
mode: 'logs', mode: 'logs',
onEvent: storeEvent, onEvent: event => storage.push(event),
quiet: false, quiet: false,
debug, findOpts: {
findOpts: findOpts1, direction,
output, limit,
since,
until,
},
}); });
const printedEventIds = new Set(); const printedEventIds = new Set<string>();
const printEvent = event => { const printEvent = (event: DeploymentEvent) => {
if (printedEventIds.has(event.id)) return 0; if (printedEventIds.has(event.id)) return 0;
printedEventIds.add(event.id); printedEventIds.add(event.id);
return logPrinters[outputMode](event); return logPrinter(event);
}; };
storage.sort(compareEvents).forEach(printEvent); storage.sort(compareEvents).forEach(printEvent);
@@ -216,26 +182,22 @@ export default async function main(client) {
// NOTE: the API ignores `since` on follow mode. // NOTE: the API ignores `since` on follow mode.
// (but not sure if it's always true on legacy deployments) // (but not sure if it's always true on legacy deployments)
const since2 = lastEvent ? lastEvent.date : Date.now(); const since2 = lastEvent ? lastEvent.date : Date.now();
const findOpts2 = { await printEvents(client, deployment.id, {
direction: 'forward',
since: since2,
follow: true,
};
await printEvents(now, deployment.uid || deployment.id, currentTeam, {
mode: 'logs', mode: 'logs',
onEvent: printEvent, onEvent: printEvent,
quiet: false, quiet: false,
debug, findOpts: {
findOpts: findOpts2, direction: 'forward',
output, since: since2,
follow: true,
},
}); });
} }
now.close();
return 0; return 0;
} }
function compareEvents(d1, d2) { function compareEvents(d1: DeploymentEvent, d2: DeploymentEvent) {
const c1 = d1.date || d1.created; const c1 = d1.date || d1.created;
const c2 = d2.date || d2.created; const c2 = d2.date || d2.created;
if (c1 !== c2) return c1 - c2; if (c1 !== c2) return c1 - c2;
@@ -246,10 +208,10 @@ function compareEvents(d1, d2) {
return d1.created - d2.created; // if date are equal and no serial return d1.created - d2.created; // if date are equal and no serial
} }
function printLogShort(log) { function printLogShort(log: any) {
if (!log.created) return; // keepalive if (!log.created) return; // keepalive
let data; let data: string;
const obj = log.object; const obj = log.object;
if (log.type === 'request') { if (log.type === 'request') {
data = data =
@@ -315,7 +277,7 @@ function printLogShort(log) {
return 0; return 0;
} }
function printLogRaw(log) { function printLogRaw(log: any) {
if (!log.created) return; // keepalive if (!log.created) return; // keepalive
if (log.object) { if (log.object) {
@@ -340,7 +302,27 @@ const logPrinters = {
raw: printLogRaw, raw: printLogRaw,
}; };
function toTimestamp(datestr) { type OutputMode = keyof typeof logPrinters;
const isLogPrinter = (v: any): v is OutputMode => {
return v && v in logPrinters;
};
const getLogPrinter = (mode: string | undefined, def: OutputMode) => {
if (mode) {
if (isLogPrinter(mode)) {
return logPrinters[mode];
}
throw new TypeError(
`Invalid output mode "${mode}". Must be one of: ${Object.keys(
logPrinters
).join(', ')}`
);
}
return logPrinters[def];
};
function toTimestamp(datestr: string) {
const t = Date.parse(datestr); const t = Date.parse(datestr);
if (isNaN(t)) { if (isNaN(t)) {
throw new TypeError('Invalid date string'); throw new TypeError('Invalid date string');

View File

@@ -115,8 +115,6 @@ export default async function main(client) {
try { try {
({ contextName } = await getScope(client)); ({ contextName } = await getScope(client));
} catch (err) { } catch (err) {
client.close();
if (err.code === 'NOT_AUTHORIZED' || err.code === 'TEAM_DELETED') { if (err.code === 'NOT_AUTHORIZED' || err.code === 'TEAM_DELETED') {
output.error(err.message); output.error(err.message);
return 1; return 1;
@@ -210,7 +208,6 @@ export default async function main(client) {
.map(id => chalk.bold(`"${id}"`)) .map(id => chalk.bold(`"${id}"`))
.join(', ')}. Run ${getCommandName('ls')} to list.` .join(', ')}. Run ${getCommandName('ls')} to list.`
); );
client.close();
return 1; return 1;
} }
@@ -233,7 +230,6 @@ export default async function main(client) {
if (confirmation !== 'y' && confirmation !== 'yes') { if (confirmation !== 'y' && confirmation !== 'yes') {
output.log('Aborted'); output.log('Aborted');
client.close();
return 1; return 1;
} }
} }
@@ -265,7 +261,6 @@ export default async function main(client) {
console.log(`${chalk.gray('-')} ${chalk.bold(project.name)}`); console.log(`${chalk.gray('-')} ${chalk.bold(project.name)}`);
}); });
client.close();
return 0; return 0;
} }

View File

@@ -1,14 +1,15 @@
import chalk from 'chalk'; import chalk from 'chalk';
import error from '../util/output/error'; import error from '../../util/output/error';
import NowTeams from '../util/teams'; import NowTeams from '../../util/teams';
import logo from '../util/output/logo'; import logo from '../../util/output/logo';
import list from './teams/list'; import list from './list';
import add from './teams/add'; import add from './add';
import change from './teams/switch'; import change from './switch';
import invite from './teams/invite'; import invite from './invite';
import { getPkgName } from '../util/pkg-name.ts'; import { getPkgName } from '../../util/pkg-name';
import getArgs from '../util/get-args.ts'; import getArgs from '../../util/get-args';
import handleError from '../util/handle-error.ts'; import handleError from '../../util/handle-error';
import Client from '../../util/client';
const help = () => { const help = () => {
console.log(` console.log(`
@@ -65,7 +66,7 @@ let debug;
let apiUrl; let apiUrl;
let subcommand; let subcommand;
const main = async client => { export default async (client: Client) => {
try { try {
argv = getArgs(client.argv.slice(2), { argv = getArgs(client.argv.slice(2), {
'--since': String, '--since': String,
@@ -113,7 +114,7 @@ const main = async client => {
} }
case 'switch': case 'switch':
case 'change': { case 'change': {
exitCode = await change(client, argv); exitCode = await change(client, argv._[0]);
break; break;
} }
case 'add': case 'add':
@@ -139,13 +140,3 @@ const main = async client => {
teams.close(); teams.close();
return exitCode || 0; return exitCode || 0;
}; };
export default async client => {
try {
return await main(client);
} catch (err) {
console.error(err);
handleError(err);
return 1;
}
};

View File

@@ -1,190 +0,0 @@
// Packages
import chalk from 'chalk';
// Utilities
import listInput from '../../util/input/list';
import success from '../../util/output/success';
import info from '../../util/output/info';
import error from '../../util/output/error';
import param from '../../util/output/param.ts';
import { writeToConfigFile } from '../../util/config/files';
import getUser from '../../util/get-user.ts';
import NowTeams from '../../util/teams';
const updateCurrentTeam = (config, newTeam) => {
if (newTeam) {
config.currentTeam = newTeam.id;
} else {
delete config.currentTeam;
}
writeToConfigFile(config);
};
export default async function change(client, argv) {
const {
apiUrl,
authConfig: { token },
debug,
config,
output,
} = client;
output.spinner('Fetching teams');
// We're loading the teams here without `currentTeam`, so that
// people can use `vercel switch` in the case that their
// current team was deleted.
const teams = new NowTeams({ apiUrl, token, debug, output });
const list = (await teams.ls()).teams;
let { currentTeam } = config;
const accountIsCurrent = !currentTeam;
output.spinner('Fetching user information');
let user;
try {
user = await getUser(client);
} catch (err) {
if (err.code === 'NOT_AUTHORIZED' || err.code === 'TEAM_DELETED') {
output.error(err.message);
return 1;
}
throw err;
}
if (accountIsCurrent) {
currentTeam = {
slug: user.username || user.email,
};
} else {
currentTeam = list.find(team => team.id === currentTeam);
if (!currentTeam) {
output.error(`You are not a part of the current team anymore`);
return 1;
}
}
if (argv._.length !== 0) {
const desiredSlug = argv._[0];
const newTeam = list.find(team => team.slug === desiredSlug);
if (newTeam) {
updateCurrentTeam(config, newTeam);
console.log(
success(
`The team ${chalk.bold(newTeam.name)} (${
newTeam.slug
}) is now active!`
)
);
return 0;
}
if (desiredSlug === user.username) {
output.spinner('Saving');
updateCurrentTeam(config);
output.stopSpinner();
console.log(
success(`Your account (${chalk.bold(desiredSlug)}) is now active!`)
);
return 0;
}
console.error(
error(`Could not find membership for team ${param(desiredSlug)}`)
);
return 1;
}
const choices = list.map(({ id, slug, name }) => {
name = `${slug} (${name})`;
if (id === currentTeam.id) {
name += ` ${chalk.bold('(current)')}`;
}
return {
name,
value: slug,
short: slug,
};
});
const suffix = accountIsCurrent ? ` ${chalk.bold('(current)')}` : '';
const userEntryName = user.username
? `${user.username} (${user.email})${suffix}`
: user.email;
choices.unshift({
name: userEntryName,
value: user.email,
short: user.username,
});
// Let's bring the current team to the beginning of the list
if (!accountIsCurrent) {
const index = choices.findIndex(
choice => choice.value === currentTeam.slug
);
const choice = choices.splice(index, 1)[0];
choices.unshift(choice);
}
output.stopSpinner();
let message;
if (currentTeam) {
message = `Switch to:`;
}
const choice = await listInput({
message,
choices,
separator: false,
eraseFinalAnswer: true,
});
// Abort
if (!choice) {
console.log(info('No changes made'));
return 0;
}
const newTeam = list.find(item => item.slug === choice);
// Switch to account
if (!newTeam) {
if (currentTeam.slug === user.username || currentTeam.slug === user.email) {
console.log(info('No changes made'));
return 0;
}
output.spinner('Saving');
updateCurrentTeam(config);
output.stopSpinner();
console.log(success(`Your account (${chalk.bold(choice)}) is now active!`));
return 0;
}
if (newTeam.slug === currentTeam.slug) {
console.log(info('No changes made'));
return 0;
}
output.spinner('Saving');
updateCurrentTeam(config, newTeam);
output.stopSpinner();
console.log(
success(
`The team ${chalk.bold(newTeam.name)} (${newTeam.slug}) is now active!`
)
);
return 0;
}

View File

@@ -0,0 +1,151 @@
// Packages
import chalk from 'chalk';
// Utilities
import Client from '../../util/client';
import { emoji } from '../../util/emoji';
import getUser from '../../util/get-user';
import getTeams from '../../util/get-teams';
import listInput from '../../util/input/list';
import { Team, GlobalConfig } from '../../types';
import { writeToConfigFile } from '../../util/config/files';
const updateCurrentTeam = (config: GlobalConfig, team?: Team) => {
if (team) {
config.currentTeam = team.id;
} else {
delete config.currentTeam;
}
writeToConfigFile(config);
};
export default async function main(client: Client, desiredSlug?: string) {
const { config, output } = client;
const personalScopeSelected = !config.currentTeam;
output.spinner('Fetching teams information');
const [user, teams] = await Promise.all([getUser(client), getTeams(client)]);
const currentTeam = personalScopeSelected
? undefined
: teams.find(team => team.id === config.currentTeam);
if (!personalScopeSelected && !currentTeam) {
output.error(`You are not a member of the current team anymore.`);
return 1;
}
if (!desiredSlug) {
const teamChoices = teams
.slice(0)
.sort((a, b) => {
return a.name.toLowerCase().localeCompare(b.name.toLowerCase());
})
.map(team => {
let title = `${team.name} (${team.slug})`;
const selected = team.id === currentTeam?.id;
if (selected) {
title += ` ${chalk.bold('(current)')}`;
}
if (team.limited) {
title += ` ${emoji('locked')}`;
}
return {
name: title,
value: team.slug,
short: team.slug,
selected,
};
});
// Add the User scope entry at the top
let suffix = personalScopeSelected ? ` ${chalk.bold('(current)')}` : '';
// SAML tokens can not interact with the user scope
if (user.limited) {
suffix += ` ${emoji('locked')}`;
}
const choices = [
{ separator: 'Personal Account' },
{
name: `${user.name || user.email} (${user.username})${suffix}`,
value: user.username,
short: user.username,
selected: personalScopeSelected,
},
{ separator: 'Teams' },
...teamChoices,
];
output.stopSpinner();
desiredSlug = await listInput({
message: 'Switch to:',
choices,
eraseFinalAnswer: true,
});
}
// Abort
if (!desiredSlug) {
output.log('No changes made.');
return 0;
}
if (desiredSlug === user.username || desiredSlug === user.email) {
// Switch to user's personal account
if (personalScopeSelected) {
output.log('No changes made');
return 0;
}
if (user.limited) {
await client.reauthenticate({
scope: user.username,
teamId: null,
});
}
updateCurrentTeam(config);
output.success(
`Your account (${chalk.bold(user.username)}) is now active!`
);
return 0;
}
// Switch to selected team
const newTeam = teams.find(team => team.slug === desiredSlug);
if (!newTeam) {
output.error(
`You do not have permission to access scope ${chalk.bold(desiredSlug)}.`
);
return 1;
}
if (newTeam.slug === currentTeam?.slug) {
output.log('No changes made');
return 0;
}
if (newTeam.limited) {
const samlEnabled = newTeam.saml?.connection?.state === 'active';
await client.reauthenticate({
teamId: samlEnabled ? newTeam.id : null,
scope: newTeam.slug,
enforced: samlEnabled && newTeam.saml?.enforced === true,
});
}
updateCurrentTeam(config, newTeam);
output.success(
`The team ${chalk.bold(newTeam.name)} (${newTeam.slug}) is now active!`
);
return 0;
}

View File

@@ -587,10 +587,10 @@ const main = async () => {
const eventCategory = 'Exit Code'; const eventCategory = 'Exit Code';
try { try {
const start = new Date(); const start = Date.now();
const full = require(`./commands/${targetCommand}`).default; const full = require(`./commands/${targetCommand}`).default;
exitCode = await full(client); exitCode = await full(client);
const end = new Date() - start; const end = Date.now() - start;
if (shouldCollectMetrics) { if (shouldCollectMetrics) {
const category = 'Command Invocation'; const category = 'Command Invocation';

View File

@@ -1,3 +1,20 @@
export type Primitive =
| bigint
| boolean
| null
| number
| string
| symbol
| undefined;
export type JSONArray = JSONValue[];
export type JSONValue = Primitive | JSONObject | JSONArray;
export interface JSONObject {
[key: string]: JSONValue;
}
export interface AuthConfig { export interface AuthConfig {
token: string; token: string;
skipWrite?: boolean; skipWrite?: boolean;
@@ -45,18 +62,26 @@ export type User = {
updatedAt: number; updatedAt: number;
}; };
name?: string; name?: string;
limited?: boolean;
}; };
export type Team = { export interface Team {
id: string; id: string;
avatar?: string; avatar?: string | null;
billing: Billing; billing: Billing;
created: string; created: string;
creatorId: string; creatorId: string;
membership: { uid: string; role: 'MEMBER' | 'OWNER'; created: number }; membership: { uid: string; role: 'MEMBER' | 'OWNER'; created: number };
name: string; name: string;
slug: string; slug: string;
}; limited?: boolean;
saml?: {
enforced: boolean;
connection?: {
state: string;
};
};
}
export type Domain = { export type Domain = {
id: string; id: string;
@@ -268,3 +293,13 @@ export type ProjectLinkResult =
| { status: 'linked'; org: Org; project: Project } | { status: 'linked'; org: Org; project: Project }
| { status: 'not_linked'; org: null; project: null } | { status: 'not_linked'; org: null; project: null }
| { status: 'error'; exitCode: number }; | { status: 'error'; exitCode: number };
export interface Token {
id: string;
name: string;
type: string;
origin?: string;
activeAt: number;
createdAt: number;
teamId?: string;
}

View File

@@ -3,7 +3,7 @@ import chalk from 'chalk';
import Client from '../client'; import Client from '../client';
import { Output } from '../output'; import { Output } from '../output';
import { User } from '../../types'; import { User } from '../../types';
import { NowConfig } from '../dev/types'; import { VercelConfig } from '../dev/types';
import getDeploymentsByAppName from '../deploy/get-deployments-by-appname'; import getDeploymentsByAppName from '../deploy/get-deployments-by-appname';
import getDeploymentByIdOrHost from '../deploy/get-deployment-by-id-or-host'; import getDeploymentByIdOrHost from '../deploy/get-deployment-by-id-or-host';
@@ -35,7 +35,7 @@ export async function getDeploymentForAlias(
localConfigPath: string | undefined, localConfigPath: string | undefined,
user: User, user: User,
contextName: string, contextName: string,
localConfig: NowConfig localConfig: VercelConfig
) { ) {
output.spinner(`Fetching deployment to alias in ${chalk.bold(contextName)}`); output.spinner(`Fetching deployment to alias in ${chalk.bold(contextName)}`);

View File

@@ -1,22 +1,28 @@
import { URLSearchParams } from 'url';
import { EventEmitter } from 'events'; import { EventEmitter } from 'events';
import { URLSearchParams } from 'url';
import { parse as parseUrl } from 'url'; import { parse as parseUrl } from 'url';
import fetch, { RequestInit } from 'node-fetch'; import { VercelConfig } from '@vercel/client';
import retry, { RetryFunction, Options as RetryOptions } from 'async-retry'; import retry, { RetryFunction, Options as RetryOptions } from 'async-retry';
import fetch, { BodyInit, Headers, RequestInit, Response } from 'node-fetch';
import ua from './ua';
import { Output } from './output/create-output'; import { Output } from './output/create-output';
import responseError from './response-error'; import responseError from './response-error';
import ua from './ua';
import printIndications from './print-indications'; import printIndications from './print-indications';
import { AuthConfig, GlobalConfig } from '../types'; import reauthenticate from './login/reauthenticate';
import { NowConfig } from './dev/types'; import { SAMLError } from './login/types';
import doSsoLogin from './login/sso';
import { writeToAuthConfigFile } from './config/files'; import { writeToAuthConfigFile } from './config/files';
import { AuthConfig, GlobalConfig, JSONObject } from '../types';
import { sharedPromise } from './promise';
import { APIError } from './errors-ts';
import { bold } from 'chalk';
export interface FetchOptions { const isSAMLError = (v: any): v is SAMLError => {
body?: NodeJS.ReadableStream | object | string; return v && v.saml;
headers?: { [key: string]: string }; };
export interface FetchOptions extends Omit<RequestInit, 'body'> {
body?: BodyInit | JSONObject;
json?: boolean; json?: boolean;
method?: 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE';
retry?: RetryOptions; retry?: RetryOptions;
useCurrentTeam?: boolean; useCurrentTeam?: boolean;
accountId?: string; accountId?: string;
@@ -28,16 +34,20 @@ export interface ClientOptions {
authConfig: AuthConfig; authConfig: AuthConfig;
output: Output; output: Output;
config: GlobalConfig; config: GlobalConfig;
localConfig: NowConfig; localConfig: VercelConfig;
} }
const isJSONObject = (v: any): v is JSONObject => {
return v && typeof v == 'object' && v.constructor === Object;
};
export default class Client extends EventEmitter { export default class Client extends EventEmitter {
argv: string[]; argv: string[];
apiUrl: string; apiUrl: string;
authConfig: AuthConfig; authConfig: AuthConfig;
output: Output; output: Output;
config: GlobalConfig; config: GlobalConfig;
localConfig: NowConfig; localConfig: VercelConfig;
constructor(opts: ClientOptions) { constructor(opts: ClientOptions) {
super(); super();
@@ -47,7 +57,6 @@ export default class Client extends EventEmitter {
this.output = opts.output; this.output = opts.output;
this.config = opts.config; this.config = opts.config;
this.localConfig = opts.localConfig; this.localConfig = opts.localConfig;
this._onRetry = this._onRetry.bind(this);
} }
retry<T>(fn: RetryFunction<T>, { retries = 3, maxTimeout = Infinity } = {}) { retry<T>(fn: RetryFunction<T>, { retries = 3, maxTimeout = Infinity } = {}) {
@@ -78,51 +87,43 @@ export default class Client extends EventEmitter {
} }
_url = `${apiUrl}${parsedUrl.pathname}?${query}`; _url = `${apiUrl}${parsedUrl.pathname}?${query}`;
delete opts.useCurrentTeam;
delete opts.accountId;
} }
if (opts.json !== false && opts.body && typeof opts.body === 'object') { const headers = new Headers(opts.headers);
Object.assign(opts, { headers.set('authorization', `Bearer ${this.authConfig.token}`);
body: JSON.stringify(opts.body), headers.set('user-agent', ua);
headers: Object.assign({}, opts.headers, {
'Content-Type': 'application/json',
}),
});
}
opts.headers = opts.headers || {}; let body;
opts.headers.Authorization = `Bearer ${this.authConfig.token}`; if (isJSONObject(opts.body)) {
opts.headers['user-agent'] = ua; body = JSON.stringify(opts.body);
headers.set('content-type', 'application/json; charset=utf8');
} else {
body = opts.body;
}
const url = `${apiUrl ? '' : this.apiUrl}${_url}`; const url = `${apiUrl ? '' : this.apiUrl}${_url}`;
return this.output.time( return this.output.time(
`${opts.method || 'GET'} ${url} ${JSON.stringify(opts.body) || ''}`, `${opts.method || 'GET'} ${url} ${JSON.stringify(opts.body) || ''}`,
fetch(url, opts as RequestInit) fetch(url, { ...opts, headers, body })
); );
} }
async fetch<T>(url: string, opts: FetchOptions = {}): Promise<T> { fetch(url: string, opts: { json: false }): Promise<Response>;
fetch<T>(url: string, opts?: FetchOptions): Promise<T>;
fetch(url: string, opts: FetchOptions = {}) {
return this.retry(async bail => { return this.retry(async bail => {
const res = await this._fetch(url, opts); const res = await this._fetch(url, opts);
printIndications(res);
if (!res.ok) { if (!res.ok) {
const error = await responseError(res); const error = await responseError(res);
if (error.saml && error.teamId) { if (isSAMLError(error)) {
// If a SAML error is encountered then we re-trigger the SAML // A SAML error means the token is expired, or is not
// authentication flow for the team specified in the error. // designated for the requested team, so the user needs
const result = await doSsoLogin(error.teamId, this); // to re-authenticate
await this.reauthenticate(error);
if (typeof result === 'number') {
this.output.prettyError(error);
process.exit(1);
return;
}
this.authConfig.token = result;
writeToAuthConfigFile(this.authConfig);
} else if (res.status >= 400 && res.status < 500) { } else if (res.status >= 400 && res.status < 500) {
// Any other 4xx should bail without retrying // Any other 4xx should bail without retrying
return bail(error); return bail(error);
@@ -136,21 +137,37 @@ export default class Client extends EventEmitter {
return res; return res;
} }
if (!res.headers.get('content-type')) { const contentType = res.headers.get('content-type');
if (!contentType) {
return null; return null;
} }
printIndications(res); return contentType.includes('application/json') ? res.json() : res;
return res.headers.get('content-type').includes('application/json')
? res.json()
: res;
}, opts.retry); }, opts.retry);
} }
_onRetry(error: Error) { reauthenticate = sharedPromise(async function (
this.output.debug(`Retrying: ${error}\n${error.stack}`); this: Client,
} error: SAMLError
) {
const result = await reauthenticate(this, error);
close() {} if (typeof result === 'number') {
if (error instanceof APIError) {
this.output.prettyError(error);
} else {
this.output.error(
`Failed to re-authenticate for ${bold(error.scope)} scope`
);
}
process.exit(1);
}
this.authConfig.token = result;
writeToAuthConfigFile(this.authConfig);
});
_onRetry = (error: Error) => {
this.output.debug(`Retrying: ${error}\n${error.stack}`);
};
} }

View File

@@ -8,7 +8,7 @@ import getLocalPathConfig from './local-path';
import { NowError } from '../now-error'; import { NowError } from '../now-error';
import error from '../output/error'; import error from '../output/error';
import highlight from '../output/highlight'; import highlight from '../output/highlight';
import { NowConfig } from '../dev/types'; import { VercelConfig } from '../dev/types';
import { AuthConfig, GlobalConfig } from '../../types'; import { AuthConfig, GlobalConfig } from '../../types';
const VERCEL_DIR = getGlobalPathConfig(); const VERCEL_DIR = getGlobalPathConfig();
@@ -100,8 +100,8 @@ export function getAuthConfigFilePath() {
export function readLocalConfig( export function readLocalConfig(
prefix: string = process.cwd() prefix: string = process.cwd()
): NowConfig | null { ): VercelConfig | null {
let config: NowConfig | null = null; let config: VercelConfig | null = null;
let target = ''; let target = '';
try { try {

View File

@@ -1,7 +1,7 @@
import { join } from 'path'; import { join } from 'path';
import { CantParseJSONFile } from '../errors-ts'; import { CantParseJSONFile } from '../errors-ts';
import readJSONFile from '../read-json-file'; import readJSONFile from '../read-json-file';
import { NowConfig } from '../dev/types'; import { VercelConfig } from '../dev/types';
import getLocalConfigPath from './local-path'; import getLocalConfigPath from './local-path';
export default async function readConfig(dir: string) { export default async function readConfig(dir: string) {
@@ -13,7 +13,7 @@ export default async function readConfig(dir: string) {
} }
if (result) { if (result) {
return result as NowConfig; return result as VercelConfig;
} }
return null; return null;

View File

@@ -39,7 +39,9 @@ export default async function getDeploymentsByProjectId(
query.set('from', options.from.toString()); query.set('from', options.from.toString());
} }
const { deployments } = await client.fetch<Response>(`/v4/now/deployments?${query}`); const { deployments } = await client.fetch<Response>(
`/v4/now/deployments?${query}`
);
total += deployments.length; total += deployments.length;
if (options.max && total >= options.max) { if (options.max && total >= options.max) {
@@ -49,15 +51,15 @@ export default async function getDeploymentsByProjectId(
if (options.continue && deployments.length === limit) { if (options.continue && deployments.length === limit) {
const nextFrom = deployments[deployments.length - 1].created; const nextFrom = deployments[deployments.length - 1].created;
const nextOptions = Object.assign({}, options, { from: nextFrom }); const nextOptions = Object.assign({}, options, { from: nextFrom });
deployments.push(...(await getDeploymentsByProjectId(client, projectId, nextOptions, total))); deployments.push(
...(await getDeploymentsByProjectId(
client,
projectId,
nextOptions,
total
))
);
} }
return deployments; return deployments;
} }
export async function getAllDeploymentsByProjectId(
client: Client,
projectId: string
) {
return getDeploymentsByProjectId(client, projectId, { from: null, limit: 100, continue: true });
}

View File

@@ -9,7 +9,7 @@ import {
import { Output } from '../output'; import { Output } from '../output';
// @ts-ignore // @ts-ignore
import Now from '../../util'; import Now from '../../util';
import { NowConfig } from '../dev/types'; import { VercelConfig } from '../dev/types';
import { Org } from '../../types'; import { Org } from '../../types';
import ua from '../ua'; import ua from '../ua';
import { linkFolderToProject } from '../projects/link'; import { linkFolderToProject } from '../projects/link';
@@ -43,7 +43,7 @@ export default async function processDeployment({
uploadStamp: () => string; uploadStamp: () => string;
deployStamp: () => string; deployStamp: () => string;
quiet: boolean; quiet: boolean;
nowConfig?: NowConfig; nowConfig?: VercelConfig;
force?: boolean; force?: boolean;
withCache?: boolean; withCache?: boolean;
org: Org; org: Org;

View File

@@ -27,7 +27,7 @@ import { LambdaSizeExceededError } from '../errors-ts';
import DevServer from './server'; import DevServer from './server';
import { getBuilder } from './builder-cache'; import { getBuilder } from './builder-cache';
import { import {
NowConfig, VercelConfig,
BuildMatch, BuildMatch,
BuildResult, BuildResult,
BuilderInputs, BuilderInputs,
@@ -96,7 +96,7 @@ async function createBuildProcess(
} }
export async function executeBuild( export async function executeBuild(
nowConfig: NowConfig, nowConfig: VercelConfig,
devServer: DevServer, devServer: DevServer,
files: BuilderInputs, files: BuilderInputs,
match: BuildMatch, match: BuildMatch,
@@ -383,7 +383,7 @@ export async function executeBuild(
} }
export async function getBuildMatches( export async function getBuildMatches(
nowConfig: NowConfig, nowConfig: VercelConfig,
cwd: string, cwd: string,
output: Output, output: Output,
devServer: DevServer, devServer: DevServer,

View File

@@ -4,7 +4,7 @@ import PCRE from 'pcre-to-regexp';
import isURL from './is-url'; import isURL from './is-url';
import DevServer from './server'; import DevServer from './server';
import { NowConfig, HttpHeadersConfig, RouteResult } from './types'; import { VercelConfig, HttpHeadersConfig, RouteResult } from './types';
import { isHandler, Route, HandleValue } from '@vercel/routing-utils'; import { isHandler, Route, HandleValue } from '@vercel/routing-utils';
export function resolveRouteParameters( export function resolveRouteParameters(
@@ -50,7 +50,7 @@ export async function devRouter(
reqMethod?: string, reqMethod?: string,
routes?: Route[], routes?: Route[],
devServer?: DevServer, devServer?: DevServer,
nowConfig?: NowConfig, nowConfig?: VercelConfig,
previousHeaders?: HttpHeadersConfig, previousHeaders?: HttpHeadersConfig,
missRoutes?: Route[], missRoutes?: Route[],
phase?: HandleValue | null phase?: HandleValue | null

View File

@@ -49,7 +49,7 @@ import sleep from '../sleep';
import { Output } from '../output'; import { Output } from '../output';
import { relative } from '../path-helpers'; import { relative } from '../path-helpers';
import { getDistTag } from '../get-dist-tag'; import { getDistTag } from '../get-dist-tag';
import getNowConfigPath from '../config/local-path'; import getVercelConfigPath from '../config/local-path';
import { MissingDotenvVarsError } from '../errors-ts'; import { MissingDotenvVarsError } from '../errors-ts';
import cliPkg from '../pkg'; import cliPkg from '../pkg';
import { getVercelDirectory } from '../projects/link'; import { getVercelDirectory } from '../projects/link';
@@ -73,7 +73,7 @@ import errorTemplate502 from './templates/error_502';
import redirectTemplate from './templates/redirect'; import redirectTemplate from './templates/redirect';
import { import {
NowConfig, VercelConfig,
DevServerOptions, DevServerOptions,
BuildMatch, BuildMatch,
BuildResult, BuildResult,
@@ -145,7 +145,7 @@ export default class DevServer {
private devServerPids: Set<number>; private devServerPids: Set<number>;
private projectSettings?: ProjectSettings; private projectSettings?: ProjectSettings;
private getNowConfigPromise: Promise<NowConfig> | null; private getVercelConfigPromise: Promise<VercelConfig> | null;
private blockingBuildsPromise: Promise<void> | null; private blockingBuildsPromise: Promise<void> | null;
private updateBuildersPromise: Promise<void> | null; private updateBuildersPromise: Promise<void> | null;
private updateBuildersTimeout: NodeJS.Timeout | undefined; private updateBuildersTimeout: NodeJS.Timeout | undefined;
@@ -181,7 +181,7 @@ export default class DevServer {
this.inProgressBuilds = new Map(); this.inProgressBuilds = new Map();
this.devCacheDir = join(getVercelDirectory(cwd), 'cache'); this.devCacheDir = join(getVercelDirectory(cwd), 'cache');
this.getNowConfigPromise = null; this.getVercelConfigPromise = null;
this.blockingBuildsPromise = null; this.blockingBuildsPromise = null;
this.updateBuildersPromise = null; this.updateBuildersPromise = null;
this.startPromise = null; this.startPromise = null;
@@ -244,7 +244,7 @@ export default class DevServer {
} }
} }
const nowConfig = await this.getNowConfig(); const nowConfig = await this.getVercelConfig();
// Update the build matches in case an entrypoint was created or deleted // Update the build matches in case an entrypoint was created or deleted
await this.updateBuildMatches(nowConfig); await this.updateBuildMatches(nowConfig);
@@ -375,7 +375,7 @@ export default class DevServer {
} }
async updateBuildMatches( async updateBuildMatches(
nowConfig: NowConfig, nowConfig: VercelConfig,
isInitial = false isInitial = false
): Promise<void> { ): Promise<void> {
const fileList = this.resolveBuildFiles(this.files); const fileList = this.resolveBuildFiles(this.files);
@@ -460,7 +460,7 @@ export default class DevServer {
} }
async invalidateBuildMatches( async invalidateBuildMatches(
nowConfig: NowConfig, nowConfig: VercelConfig,
updatedBuilders: string[] updatedBuilders: string[]
): Promise<void> { ): Promise<void> {
if (updatedBuilders.length === 0) { if (updatedBuilders.length === 0) {
@@ -516,25 +516,25 @@ export default class DevServer {
return {}; return {};
} }
clearNowConfigPromise = () => { clearVercelConfigPromise = () => {
this.getNowConfigPromise = null; this.getVercelConfigPromise = null;
}; };
getNowConfig(): Promise<NowConfig> { getVercelConfig(): Promise<VercelConfig> {
if (this.getNowConfigPromise) { if (this.getVercelConfigPromise) {
return this.getNowConfigPromise; return this.getVercelConfigPromise;
} }
this.getNowConfigPromise = this._getNowConfig(); this.getVercelConfigPromise = this._getVercelConfig();
// Clean up the promise once it has resolved // Clean up the promise once it has resolved
const clear = this.clearNowConfigPromise; const clear = this.clearVercelConfigPromise;
this.getNowConfigPromise.finally(clear); this.getVercelConfigPromise.finally(clear);
return this.getNowConfigPromise; return this.getVercelConfigPromise;
} }
async _getNowConfig(): Promise<NowConfig> { async _getVercelConfig(): Promise<VercelConfig> {
const configPath = getNowConfigPath(this.cwd); const configPath = getVercelConfigPath(this.cwd);
const [ const [
pkg = null, pkg = null,
@@ -543,10 +543,10 @@ export default class DevServer {
config = { version: 2, [fileNameSymbol]: 'vercel.json' }, config = { version: 2, [fileNameSymbol]: 'vercel.json' },
] = await Promise.all([ ] = await Promise.all([
this.readJsonFile<PackageJson>('package.json'), this.readJsonFile<PackageJson>('package.json'),
this.readJsonFile<NowConfig>(configPath), this.readJsonFile<VercelConfig>(configPath),
]); ]);
await this.validateNowConfig(config); await this.validateVercelConfig(config);
const { error: routeError, routes: maybeRoutes } = getTransformedRoutes({ const { error: routeError, routes: maybeRoutes } = getTransformedRoutes({
nowConfig: config, nowConfig: config,
}); });
@@ -634,7 +634,7 @@ export default class DevServer {
config.builds.sort(sortBuilders); config.builds.sort(sortBuilders);
} }
await this.validateNowConfig(config); await this.validateVercelConfig(config);
this.caseSensitive = hasNewRoutingProperties(config); this.caseSensitive = hasNewRoutingProperties(config);
this.apiDir = detectApiDirectory(config.builds || []); this.apiDir = detectApiDirectory(config.builds || []);
@@ -710,8 +710,8 @@ export default class DevServer {
} }
async tryValidateOrExit( async tryValidateOrExit(
config: NowConfig, config: VercelConfig,
validate: (c: NowConfig) => string | null validate: (c: VercelConfig) => string | null
): Promise<void> { ): Promise<void> {
const message = validate(config); const message = validate(config);
@@ -721,7 +721,7 @@ export default class DevServer {
} }
} }
async validateNowConfig(config: NowConfig): Promise<void> { async validateVercelConfig(config: VercelConfig): Promise<void> {
if (config.version === 1) { if (config.version === 1) {
this.output.error('Cannot run `version: 1` projects.'); this.output.error('Cannot run `version: 1` projects.');
await this.exit(1); await this.exit(1);
@@ -855,7 +855,7 @@ export default class DevServer {
.replace('[::]', 'localhost') .replace('[::]', 'localhost')
.replace('127.0.0.1', 'localhost'); .replace('127.0.0.1', 'localhost');
const nowConfig = await this.getNowConfig(); const nowConfig = await this.getVercelConfig();
const devCommandPromise = this.runDevCommand(); const devCommandPromise = this.runDevCommand();
const files = await getFiles(this.cwd, { output: this.output }); const files = await getFiles(this.cwd, { output: this.output });
@@ -982,7 +982,7 @@ export default class DevServer {
if (devProcess) { if (devProcess) {
ops.push( ops.push(
new Promise((resolve, reject) => { new Promise<void>((resolve, reject) => {
devProcess.once('exit', () => resolve()); devProcess.once('exit', () => resolve());
try { try {
process.kill(devProcess.pid); process.kill(devProcess.pid);
@@ -1201,7 +1201,7 @@ export default class DevServer {
match: BuildMatch, match: BuildMatch,
requestPath: string | null, requestPath: string | null,
req: http.IncomingMessage | null, req: http.IncomingMessage | null,
nowConfig: NowConfig, nowConfig: VercelConfig,
previousBuildResult?: BuildResult, previousBuildResult?: BuildResult,
filesChanged?: string[], filesChanged?: string[],
filesRemoved?: string[] filesRemoved?: string[]
@@ -1290,7 +1290,7 @@ export default class DevServer {
this.output.debug(`${chalk.bold(method)} ${req.url}`); this.output.debug(`${chalk.bold(method)} ${req.url}`);
try { try {
const nowConfig = await this.getNowConfig(); const nowConfig = await this.getVercelConfig();
await this.serveProjectAsNowV2(req, res, nowRequestId, nowConfig); await this.serveProjectAsNowV2(req, res, nowRequestId, nowConfig);
} catch (err) { } catch (err) {
console.error(err); console.error(err);
@@ -1339,7 +1339,7 @@ export default class DevServer {
req: http.IncomingMessage, req: http.IncomingMessage,
res: http.ServerResponse, res: http.ServerResponse,
nowRequestId: string, nowRequestId: string,
nowConfig: NowConfig, nowConfig: VercelConfig,
routes: Route[] | undefined = nowConfig.routes, routes: Route[] | undefined = nowConfig.routes,
callLevel: number = 0 callLevel: number = 0
) => { ) => {
@@ -1992,7 +1992,7 @@ export default class DevServer {
return true; return true;
} }
async hasFilesystem(dest: string, nowConfig: NowConfig): Promise<boolean> { async hasFilesystem(dest: string, nowConfig: VercelConfig): Promise<boolean> {
if ( if (
await findBuildMatch( await findBuildMatch(
this.buildMatches, this.buildMatches,
@@ -2181,7 +2181,7 @@ async function findBuildMatch(
files: BuilderInputs, files: BuilderInputs,
requestPath: string, requestPath: string,
devServer: DevServer, devServer: DevServer,
nowConfig: NowConfig, nowConfig: VercelConfig,
isFilesystem = false isFilesystem = false
): Promise<BuildMatch | null> { ): Promise<BuildMatch | null> {
requestPath = requestPath.replace(/^\//, ''); requestPath = requestPath.replace(/^\//, '');
@@ -2219,7 +2219,7 @@ async function shouldServe(
files: BuilderInputs, files: BuilderInputs,
requestPath: string, requestPath: string,
devServer: DevServer, devServer: DevServer,
nowConfig: NowConfig, nowConfig: VercelConfig,
isFilesystem = false isFilesystem = false
): Promise<boolean> { ): Promise<boolean> {
const { const {
@@ -2284,7 +2284,7 @@ async function findMatchingRoute(
match: BuildMatch, match: BuildMatch,
requestPath: string, requestPath: string,
devServer: DevServer, devServer: DevServer,
nowConfig: NowConfig nowConfig: VercelConfig
): Promise<RouteResult | void> { ): Promise<RouteResult | void> {
const reqUrl = `/${requestPath}`; const reqUrl = `/${requestPath}`;
for (const buildResult of match.buildResults.values()) { for (const buildResult of match.buildResults.values()) {
@@ -2305,7 +2305,7 @@ async function findMatchingRoute(
function findAsset( function findAsset(
match: BuildMatch, match: BuildMatch,
requestPath: string, requestPath: string,
nowConfig: NowConfig nowConfig: VercelConfig
): { asset: BuilderOutput; assetKey: string } | void { ): { asset: BuilderOutput; assetKey: string } | void {
if (!match.buildOutput) { if (!match.buildOutput) {
return; return;
@@ -2397,7 +2397,7 @@ function filterFrontendBuilds(build: Builder) {
return !frontendRuntimeSet.has(name || ''); return !frontendRuntimeSet.has(name || '');
} }
function hasNewRoutingProperties(nowConfig: NowConfig) { function hasNewRoutingProperties(nowConfig: VercelConfig) {
return ( return (
typeof nowConfig.cleanUrls !== undefined || typeof nowConfig.cleanUrls !== undefined ||
typeof nowConfig.headers !== undefined || typeof nowConfig.headers !== undefined ||

View File

@@ -14,12 +14,12 @@ import {
Lambda, Lambda,
PackageJson, PackageJson,
} from '@vercel/build-utils'; } from '@vercel/build-utils';
import { NowConfig } from '@vercel/client'; import { VercelConfig } from '@vercel/client';
import { HandleValue, Route } from '@vercel/routing-utils'; import { HandleValue, Route } from '@vercel/routing-utils';
import { Output } from '../output'; import { Output } from '../output';
import { ProjectEnvVariable, ProjectSettings } from '../../types'; import { ProjectEnvVariable, ProjectSettings } from '../../types';
export { NowConfig }; export { VercelConfig };
export interface DevServerOptions { export interface DevServerOptions {
output: Output; output: Output;

View File

@@ -7,7 +7,7 @@ import {
rewritesSchema, rewritesSchema,
trailingSlashSchema, trailingSlashSchema,
} from '@vercel/routing-utils'; } from '@vercel/routing-utils';
import { NowConfig } from './types'; import { VercelConfig } from './types';
import { import {
functionsSchema, functionsSchema,
buildsSchema, buildsSchema,
@@ -36,7 +36,7 @@ const vercelConfigSchema = {
const ajv = new Ajv(); const ajv = new Ajv();
const validate = ajv.compile(vercelConfigSchema); const validate = ajv.compile(vercelConfigSchema);
export function validateConfig(config: NowConfig): NowBuildError | null { export function validateConfig(config: VercelConfig): NowBuildError | null {
if (!validate(config)) { if (!validate(config)) {
if (validate.errors && validate.errors[0]) { if (validate.errors && validate.errors[0]) {
const error = validate.errors[0]; const error = validate.errors[0];

View File

@@ -1,28 +1,17 @@
export type EmojiLabel = export const emojiLabels = {
| 'notice' notice: '📝',
| 'tip' tip: '💡',
| 'warning' warning: '❗️',
| 'link' link: '🔗',
| 'inspect' inspect: '🔍',
| 'success'; success: '✅',
locked: '🔒',
} as const;
export function emoji(label: EmojiLabel): string | undefined { export type EmojiLabel = keyof typeof emojiLabels;
switch (label) {
case 'notice': export function emoji(label: EmojiLabel) {
return '📝'; return emojiLabels[label];
case 'tip':
return '💡';
case 'warning':
return '❗️';
case 'link':
return '🔗';
case 'inspect':
return '🔍';
case 'success':
return '✅';
default:
return undefined;
}
} }
export function prependEmoji(message: string, emoji?: string): string { export function prependEmoji(message: string, emoji?: string): string {

View File

@@ -2,52 +2,41 @@
import { URLSearchParams } from 'url'; import { URLSearchParams } from 'url';
// Packages // Packages
import retry from 'async-retry';
import jsonlines from 'jsonlines';
import { eraseLines } from 'ansi-escapes'; import { eraseLines } from 'ansi-escapes';
import jsonlines from 'jsonlines'; import Client from './client';
import retry from 'async-retry'; import { getDeployment } from './get-deployment';
export interface FindOpts {
direction: 'forward' | 'backward';
limit?: number;
since?: number;
until?: number;
follow?: boolean;
}
export interface PrintEventsOptions {
mode: string;
onEvent: (event: DeploymentEvent) => void;
quiet?: boolean;
findOpts: FindOpts;
}
export interface DeploymentEvent {
id: string;
created: number;
date?: number;
serial?: string;
}
async function printEvents( async function printEvents(
now, client: Client,
deploymentIdOrURL, deploymentIdOrURL: string,
currentTeam = null, { mode, onEvent, quiet, findOpts }: PrintEventsOptions
{
mode,
onOpen = () => {},
onEvent,
quiet,
debugEnabled,
findOpts,
output,
} = {}
) { ) {
const { log, debug } = output; const { log, debug } = client.output;
let onOpenCalled = false;
function callOnOpenOnce() {
if (onOpenCalled) return;
onOpenCalled = true;
onOpen();
}
const query = new URLSearchParams({
direction: findOpts.direction,
limit: findOpts.limit,
since: findOpts.since,
until: findOpts.until,
follow: findOpts.follow ? '1' : '',
format: 'lines',
});
let eventsUrl = `/v1/now/deployments/${deploymentIdOrURL}/events?${query}`;
let pollUrl = `/v3/now/deployments/${deploymentIdOrURL}`;
if (currentTeam) {
eventsUrl += `&teamId=${currentTeam.id}`;
pollUrl += `?teamId=${currentTeam.id}`;
}
debug(`Events ${eventsUrl}`);
// we keep track of how much we log in case we // we keep track of how much we log in case we
// drop the connection and have to start over // drop the connection and have to start over
@@ -59,29 +48,34 @@ async function printEvents(
debug('Retrying events'); debug('Retrying events');
} }
const eventsRes = await now._fetch(eventsUrl); const query = new URLSearchParams({
direction: findOpts.direction,
follow: findOpts.follow ? '1' : '',
format: 'lines',
});
if (findOpts.limit) query.set('limit', String(findOpts.limit));
if (findOpts.since) query.set('since', String(findOpts.since));
if (findOpts.until) query.set('until', String(findOpts.until));
const eventsUrl = `/v1/now/deployments/${deploymentIdOrURL}/events?${query}`;
const eventsRes = await client.fetch(eventsUrl, { json: false });
if (eventsRes.ok) { if (eventsRes.ok) {
const readable = eventsRes.readable const readable = eventsRes.body;
? await eventsRes.readable()
: eventsRes.body;
// handle the event stream and make the promise get rejected // handle the event stream and make the promise get rejected
// if errors occur so we can retry // if errors occur so we can retry
return new Promise((resolve, reject) => { return new Promise<void>((resolve, reject) => {
const stream = readable.pipe(jsonlines.parse()); const stream = readable.pipe(jsonlines.parse());
let poller; let poller: ReturnType<typeof setTimeout>;
if (mode === 'deploy') { if (mode === 'deploy') {
poller = (function startPoller() { poller = (function startPoller() {
return setTimeout(async () => { return setTimeout(async () => {
try { try {
const pollRes = await now._fetch(pollUrl); const json = await getDeployment(client, deploymentIdOrURL);
if (!pollRes.ok) if (json.readyState === 'READY') {
throw new Error(`Response ${pollRes.status}`);
const json = await pollRes.json();
if (json.state === 'READY') {
stream.end(); stream.end();
finish(); finish();
return; return;
@@ -96,10 +90,9 @@ async function printEvents(
} }
let finishCalled = false; let finishCalled = false;
function finish(error) { function finish(error?: Error) {
if (finishCalled) return; if (finishCalled) return;
finishCalled = true; finishCalled = true;
callOnOpenOnce();
clearTimeout(poller); clearTimeout(poller);
if (error) { if (error) {
reject(error); reject(error);
@@ -110,26 +103,24 @@ async function printEvents(
let latestLogDate = 0; let latestLogDate = 0;
const onData = data => { const onData = (data: any) => {
const { event } = data; const { event, payload, date } = data;
if (event === 'state' && data.payload.value === 'READY') { if (event === 'state' && payload.value === 'READY') {
if (mode === 'deploy') { if (mode === 'deploy') {
stream.end(); stream.end();
finish(); finish();
} }
} else { } else {
latestLogDate = Math.max(latestLogDate, data.date); latestLogDate = Math.max(latestLogDate, date);
const linesPrinted = onEvent(data, callOnOpenOnce); onEvent(data);
o += linesPrinted || 0;
} }
}; };
let onErrorCalled = false; let onErrorCalled = false;
const onError = err => { const onError = (err: Error) => {
if (finishCalled || onErrorCalled) return; if (finishCalled || onErrorCalled) return;
onErrorCalled = true; onErrorCalled = true;
o++; o++;
callOnOpenOnce();
const errorMessage = `Deployment event stream error: ${err.message}`; const errorMessage = `Deployment event stream error: ${err.message}`;
if (!findOpts.follow) { if (!findOpts.follow) {
@@ -140,7 +131,6 @@ async function printEvents(
debug(errorMessage); debug(errorMessage);
clearTimeout(poller); clearTimeout(poller);
stream.destroy(err); stream.destroy(err);
readable.destroy(err);
const retryFindOpts = { const retryFindOpts = {
...findOpts, ...findOpts,
@@ -149,12 +139,10 @@ async function printEvents(
setTimeout(() => { setTimeout(() => {
// retry without maximum amount nor clear past logs etc // retry without maximum amount nor clear past logs etc
printEvents(now, deploymentIdOrURL, currentTeam, { printEvents(client, deploymentIdOrURL, {
mode, mode,
onOpen,
onEvent, onEvent,
quiet, quiet,
debugEnabled,
findOpts: retryFindOpts, findOpts: retryFindOpts,
}).then(resolve, reject); }).then(resolve, reject);
}, 2000); }, 2000);
@@ -166,7 +154,6 @@ async function printEvents(
readable.on('error', onError); readable.on('error', onError);
}); });
} }
callOnOpenOnce();
const err = new Error(`Deployment events status ${eventsRes.status}`); const err = new Error(`Deployment events status ${eventsRes.status}`);
if (eventsRes.status < 500) { if (eventsRes.status < 500) {

View File

@@ -9,15 +9,15 @@ import {
import humanizePath from './humanize-path'; import humanizePath from './humanize-path';
import readJSONFile from './read-json-file'; import readJSONFile from './read-json-file';
import readPackage from './read-package'; import readPackage from './read-package';
import { NowConfig } from './dev/types'; import { VercelConfig } from './dev/types';
import { Output } from './output'; import { Output } from './output';
let config: NowConfig; let config: VercelConfig;
export default async function getConfig( export default async function getConfig(
output: Output, output: Output,
configFile?: string configFile?: string
): Promise<NowConfig | Error> { ): Promise<VercelConfig | Error> {
// If config was already read, just return it // If config was already read, just return it
if (config) { if (config) {
return config; return config;
@@ -44,7 +44,7 @@ export default async function getConfig(
return localConfig; return localConfig;
} }
if (localConfig !== null) { if (localConfig !== null) {
config = localConfig as NowConfig; config = localConfig as VercelConfig;
config[fileNameSymbol] = configFile; config[fileNameSymbol] = configFile;
return config; return config;
} }
@@ -68,13 +68,13 @@ export default async function getConfig(
} }
if (vercelConfig !== null) { if (vercelConfig !== null) {
output.debug(`Found config in file "${vercelFilePath}"`); output.debug(`Found config in file "${vercelFilePath}"`);
config = vercelConfig as NowConfig; config = vercelConfig as VercelConfig;
config[fileNameSymbol] = 'vercel.json'; config[fileNameSymbol] = 'vercel.json';
return config; return config;
} }
if (nowConfig !== null) { if (nowConfig !== null) {
output.debug(`Found config in file "${nowFilePath}"`); output.debug(`Found config in file "${nowFilePath}"`);
config = nowConfig as NowConfig; config = nowConfig as VercelConfig;
config[fileNameSymbol] = 'now.json'; config[fileNameSymbol] = 'now.json';
return config; return config;
} }
@@ -87,7 +87,7 @@ export default async function getConfig(
} }
if (pkgConfig) { if (pkgConfig) {
output.debug(`Found config in package ${pkgFilePath}`); output.debug(`Found config in package ${pkgFilePath}`);
config = pkgConfig as NowConfig; config = pkgConfig as VercelConfig;
config[fileNameSymbol] = 'package.json'; config[fileNameSymbol] = 'package.json';
return config; return config;
} }

View File

@@ -0,0 +1,27 @@
import { stringify } from 'querystring';
import { Deployment } from '@vercel/client';
import Client from './client';
export async function getDeployment(
client: Client,
hostOrId: string
): Promise<Deployment> {
let url = `/v13/deployments`;
if (hostOrId.includes('.')) {
let host = hostOrId.replace(/^https:\/\//i, '');
if (host.slice(-1) === '/') {
host = host.slice(0, -1);
}
url += `/get?${stringify({
url: host,
})}`;
} else {
url += `/${encodeURIComponent(hostOrId)}`;
}
const deployment = await client.fetch<Deployment>(url);
return deployment;
}

View File

@@ -1,8 +1,6 @@
import Client from './client'; import Client from './client';
import { APIError, InvalidToken } from './errors-ts';
import { Team } from '../types'; import { Team } from '../types';
// @ts-ignore import { APIError, InvalidToken } from './errors-ts';
import NowTeams from './teams.js';
let teams: Team[] | undefined; let teams: Team[] | undefined;
@@ -10,15 +8,11 @@ export default async function getTeams(client: Client): Promise<Team[]> {
if (teams) return teams; if (teams) return teams;
try { try {
// we're using NowTeams because `client.fetch` hangs on windows const body = await client.fetch<{ teams: Team[] }>('/v1/teams', {
const teamClient = new NowTeams({ useCurrentTeam: false,
apiUrl: client.apiUrl,
token: client.authConfig.token,
debug: client.output.isDebugEnabled(),
}); });
teams = body.teams || [];
teams = (await teamClient.ls()).teams; return teams;
return teams || [];
} catch (error) { } catch (error) {
if (error instanceof APIError && error.status === 403) { if (error instanceof APIError && error.status === 403) {
throw new InvalidToken(); throw new InvalidToken();

View File

@@ -6,15 +6,12 @@ export default async function confirm(
): Promise<boolean> { ): Promise<boolean> {
require('./patch-inquirer'); require('./patch-inquirer');
const name = `${Date.now()}`;
const answers = await inquirer.prompt({ const answers = await inquirer.prompt({
type: 'confirm', type: 'confirm',
name, name: 'value',
message, message,
default: preferred, default: preferred,
}); });
const answer = answers[name] as boolean; return answers.value;
return answer;
} }

View File

@@ -1,82 +0,0 @@
import inquirer from 'inquirer';
import stripAnsi from 'strip-ansi';
import eraseLines from '../output/erase-lines';
function getLength(string) {
let biggestLength = 0;
string.split('\n').map(str => {
str = stripAnsi(str);
if (str.length > biggestLength) {
biggestLength = str.length;
}
return undefined;
});
return biggestLength;
}
export default async function({
message = 'the question',
// eslint-disable-line no-unused-vars
choices = [
{
name: 'something\ndescription\ndetails\netc',
value: 'something unique',
short: 'generally the first line of `name`',
},
],
pageSize = 15, // Show 15 lines without scrolling (~4 credit cards)
separator = true, // Puts a blank separator between each choice
abort = 'end', // Wether the `abort` option will be at the `start` or the `end`,
eraseFinalAnswer = false, // If true, the line with the final answee that inquirer prints will be erased before returning
}) {
require('./patch-inquirer-legacy');
let biggestLength = 0;
choices = choices.map(choice => {
if (choice.name) {
const length = getLength(choice.name);
if (length > biggestLength) {
biggestLength = length;
}
return choice;
}
throw new Error('Invalid choice');
});
if (separator === true) {
choices = choices.reduce(
(prev, curr) => prev.concat(new inquirer.Separator(' '), curr),
[]
);
}
const abortSeparator = new inquirer.Separator('─'.repeat(biggestLength));
const _abort = {
name: 'Abort',
value: undefined,
};
if (abort === 'start') {
const blankSep = choices.shift();
choices.unshift(abortSeparator);
choices.unshift(_abort);
choices.unshift(blankSep);
} else {
choices.push(abortSeparator);
choices.push(_abort);
}
const nonce = Date.now();
const answer = await inquirer.prompt({
name: nonce,
type: 'list',
message,
choices,
pageSize,
});
if (eraseFinalAnswer === true) {
process.stdout.write(eraseLines(2));
}
return answer[nonce];
}

View File

@@ -0,0 +1,123 @@
import inquirer from 'inquirer';
import stripAnsi from 'strip-ansi';
import eraseLines from '../output/erase-lines';
interface ListEntry {
name: string;
value: string;
short: string;
selected?: boolean;
}
interface ListSeparator {
separator: string;
}
type ListChoice = ListEntry | ListSeparator | typeof inquirer.Separator;
interface ListOptions {
message: string;
choices: ListChoice[];
pageSize?: number;
separator?: boolean;
abort?: 'start' | 'end';
eraseFinalAnswer?: boolean;
}
function getLength(input: string): number {
let biggestLength = 0;
for (const line of input.split('\n')) {
const str = stripAnsi(line);
if (str.length > biggestLength) {
biggestLength = str.length;
}
}
return biggestLength;
}
export default async function list({
message = 'the question',
// eslint-disable-line no-unused-vars
choices: _choices = [
{
name: 'something\ndescription\ndetails\netc',
value: 'something unique',
short: 'generally the first line of `name`',
},
],
pageSize = 15, // Show 15 lines without scrolling (~4 credit cards)
separator = false, // Puts a blank separator between each choice
abort = 'end', // Whether the `abort` option will be at the `start` or the `end`,
eraseFinalAnswer = false, // If true, the line with the final answer that inquirer prints will be erased before returning
}: ListOptions): Promise<string> {
require('./patch-inquirer-legacy');
let biggestLength = 0;
let selected: string | undefined;
// First calculate the biggest length
for (const choice of _choices) {
if ('name' in choice) {
const length = getLength(choice.name);
if (length > biggestLength) {
biggestLength = length;
}
}
}
const choices = _choices.map(choice => {
if (choice instanceof inquirer.Separator) {
return choice;
}
if ('separator' in choice) {
const prefix = `── ${choice.separator} `;
const suffix = '─'.repeat(biggestLength - getLength(prefix));
return new inquirer.Separator(`${prefix}${suffix}`);
}
if ('short' in choice) {
if (choice.selected) {
if (selected) throw new Error('Only one choice may be selected');
selected = choice.short;
}
return choice;
}
throw new Error('Invalid choice');
});
if (separator) {
for (let i = 0; i < choices.length; i += 2) {
choices.splice(i, 0, new inquirer.Separator(' '));
}
}
const abortSeparator = new inquirer.Separator('─'.repeat(biggestLength));
const _abort = {
name: 'Abort',
value: '',
short: '',
};
if (abort === 'start') {
choices.unshift(_abort, abortSeparator);
} else {
choices.push(abortSeparator, _abort);
}
const answer = await inquirer.prompt({
name: 'value',
type: 'list',
default: selected,
message,
choices,
pageSize,
});
if (eraseFinalAnswer === true) {
process.stdout.write(eraseLines(2));
}
return answer.value;
}

View File

@@ -2,7 +2,7 @@ import { join, basename } from 'path';
import chalk from 'chalk'; import chalk from 'chalk';
import { remove } from 'fs-extra'; import { remove } from 'fs-extra';
import { ProjectLinkResult, ProjectSettings } from '../../types'; import { ProjectLinkResult, ProjectSettings } from '../../types';
import { NowConfig } from '../dev/types'; import { VercelConfig } from '../dev/types';
import { import {
getLinkedProject, getLinkedProject,
linkFolderToProject, linkFolderToProject,
@@ -134,7 +134,7 @@ export default async function setupAndLink(
return { status: 'error', exitCode: 1 }; return { status: 'error', exitCode: 1 };
} }
let localConfig: NowConfig = {}; let localConfig: VercelConfig = {};
if (client.localConfig && !(client.localConfig instanceof Error)) { if (client.localConfig && !(client.localConfig instanceof Error)) {
localConfig = client.localConfig; localConfig = client.localConfig;
} }

View File

@@ -9,5 +9,5 @@ export default function doBitbucketLogin(params: LoginParams) {
// cookie that the OAuth callback URL depends on // cookie that the OAuth callback URL depends on
'https://vercel.com' 'https://vercel.com'
); );
return doOauthLogin(url, 'Bitbucket', params); return doOauthLogin(params, url, 'Bitbucket');
} }

View File

@@ -7,8 +7,8 @@ import executeLogin from './login';
import { LoginParams } from './types'; import { LoginParams } from './types';
export default async function doEmailLogin( export default async function doEmailLogin(
email: string, params: LoginParams,
params: LoginParams email: string
): Promise<number | string> { ): Promise<number | string> {
let securityCode; let securityCode;
let verificationToken; let verificationToken;

View File

@@ -9,5 +9,5 @@ export default function doGithubLogin(params: LoginParams) {
// cookie that the OAuth callback URL depends on // cookie that the OAuth callback URL depends on
'https://vercel.com' 'https://vercel.com'
); );
return doOauthLogin(url, 'GitHub', params); return doOauthLogin(params, url, 'GitHub');
} }

View File

@@ -6,5 +6,5 @@ export default function doGitlabLogin(params: LoginParams) {
// Can't use `apiUrl` here because this URL sets a // Can't use `apiUrl` here because this URL sets a
// cookie that the OAuth callback URL depends on // cookie that the OAuth callback URL depends on
const url = new URL('/api/registration/gitlab/connect', 'https://vercel.com'); const url = new URL('/api/registration/gitlab/connect', 'https://vercel.com');
return doOauthLogin(url, 'GitLab', params); return doOauthLogin(params, url, 'GitLab');
} }

View File

@@ -2,15 +2,17 @@ import http from 'http';
import open from 'open'; import open from 'open';
import { URL } from 'url'; import { URL } from 'url';
import listen from 'async-listen'; import listen from 'async-listen';
import { hostname } from 'os';
import { LoginParams } from './types'; import { LoginParams } from './types';
import prompt from './prompt'; import prompt from './prompt';
import verify from './verify'; import verify from './verify';
import { getTitleName } from '../pkg-name';
import highlight from '../output/highlight'; import highlight from '../output/highlight';
export default async function doOauthLogin( export default async function doOauthLogin(
params: LoginParams,
url: URL, url: URL,
provider: string, provider: string
params: LoginParams
): Promise<number | string> { ): Promise<number | string> {
const { output } = params; const { output } = params;
@@ -24,6 +26,12 @@ export default async function doOauthLogin(
url.searchParams.append('mode', 'login'); url.searchParams.append('mode', 'login');
url.searchParams.append('next', `http://localhost:${port}`); url.searchParams.append('next', `http://localhost:${port}`);
// Append token name param
const hyphens = new RegExp('-', 'g');
const host = hostname().replace(hyphens, ' ').replace('.local', '');
const tokenName = `${getTitleName()} CLI on ${host} via ${provider}`;
url.searchParams.append('tokenName', tokenName);
try { try {
const [query] = await Promise.all([ const [query] = await Promise.all([
new Promise<URL['searchParams']>((resolve, reject) => { new Promise<URL['searchParams']>((resolve, reject) => {

View File

@@ -2,14 +2,17 @@ import inquirer from 'inquirer';
import error from '../output/error'; import error from '../output/error';
import listInput from '../input/list'; import listInput from '../input/list';
import { getCommandName } from '../pkg-name'; import { getCommandName } from '../pkg-name';
import { LoginParams } from './types'; import { LoginParams, SAMLError } from './types';
import doSsoLogin from './sso'; import doSsoLogin from './sso';
import doEmailLogin from './email'; import doEmailLogin from './email';
import doGithubLogin from './github'; import doGithubLogin from './github';
import doGitlabLogin from './gitlab'; import doGitlabLogin from './gitlab';
import doBitbucketLogin from './bitbucket'; import doBitbucketLogin from './bitbucket';
export default async function prompt(params: LoginParams) { export default async function prompt(
params: LoginParams,
error?: Pick<SAMLError, 'teamId'>
) {
let result: number | string = 1; let result: number | string = 1;
const choices = [ const choices = [
@@ -17,17 +20,17 @@ export default async function prompt(params: LoginParams) {
{ name: 'Continue with GitLab', value: 'gitlab', short: 'gitlab' }, { name: 'Continue with GitLab', value: 'gitlab', short: 'gitlab' },
{ name: 'Continue with Bitbucket', value: 'bitbucket', short: 'bitbucket' }, { name: 'Continue with Bitbucket', value: 'bitbucket', short: 'bitbucket' },
{ name: 'Continue with Email', value: 'email', short: 'email' }, { name: 'Continue with Email', value: 'email', short: 'email' },
{ name: 'Continue with SAML Single Sign-On', value: 'saml', short: 'saml' }, { name: 'Continue with SAML Single Sign-On', value: 'sso', short: 'sso' },
]; ];
if (params.ssoUserId) { if (params.ssoUserId || (error && !error.teamId)) {
// Remove SAML login option if we're connecting SAML Profile // Remove SAML login option if we're connecting SAML Profile,
// or if this is a SAML error for a user / team without SAML
choices.pop(); choices.pop();
} }
const choice = await listInput({ const choice = await listInput({
message: 'Log in to Vercel', message: 'Log in to Vercel',
separator: false,
choices, choices,
}); });
@@ -39,10 +42,10 @@ export default async function prompt(params: LoginParams) {
result = await doBitbucketLogin(params); result = await doBitbucketLogin(params);
} else if (choice === 'email') { } else if (choice === 'email') {
const email = await readInput('Enter your email address'); const email = await readInput('Enter your email address');
result = await doEmailLogin(email, params); result = await doEmailLogin(params, email);
} else if (choice === 'saml') { } else if (choice === 'sso') {
const slug = await readInput('Enter your Team slug'); const slug = error?.teamId || (await readInput('Enter your Team slug'));
result = await doSsoLogin(slug, params); result = await doSsoLogin(params, slug);
} }
return result; return result;

View File

@@ -0,0 +1,28 @@
import { bold } from 'chalk';
import doSsoLogin from './sso';
import showLoginPrompt from './prompt';
import { LoginParams, SAMLError } from './types';
import confirm from '../input/confirm';
export default async function reauthenticate(
params: LoginParams,
error: Pick<SAMLError, 'enforced' | 'scope' | 'teamId'>
): Promise<string | number> {
let result: string | number = 1;
if (error.teamId && error.enforced) {
// If team has SAML enforced then trigger the SSO login directly
params.output.log(
`You must re-authenticate with SAML to use ${bold(error.scope)} scope.`
);
if (await confirm(`Log in with SAML?`, true)) {
result = await doSsoLogin(params, error.teamId);
}
} else {
// Personal account, or team that does not have SAML enforced
params.output.log(
`You must re-authenticate to use ${bold(error.scope)} scope.`
);
result = await showLoginPrompt(params, error);
}
return result;
}

View File

@@ -1,17 +1,9 @@
import { URL } from 'url'; import { URL } from 'url';
import { hostname } from 'os';
import { getTitleName } from '../pkg-name';
import { LoginParams } from './types'; import { LoginParams } from './types';
import doOauthLogin from './oauth'; import doOauthLogin from './oauth';
export default function doSsoLogin(teamIdOrSlug: string, params: LoginParams) { export default function doSsoLogin(params: LoginParams, teamIdOrSlug: string) {
const hyphens = new RegExp('-', 'g');
const host = hostname().replace(hyphens, ' ').replace('.local', '');
const tokenName = `${getTitleName()} CLI on ${host}`;
const url = new URL('/auth/sso', params.apiUrl); const url = new URL('/auth/sso', params.apiUrl);
url.searchParams.append('teamId', teamIdOrSlug); url.searchParams.append('teamId', teamIdOrSlug);
url.searchParams.append('tokenName', tokenName); return doOauthLogin(params, url, 'SAML Single Sign-On');
return doOauthLogin(url, 'SAML Single Sign-On', params);
} }

View File

@@ -10,3 +10,10 @@ export interface LoginData {
token: string; token: string;
securityCode: string; securityCode: string;
} }
export interface SAMLError {
saml?: true;
teamId: string | null;
scope: string;
enforced?: boolean;
}

View File

@@ -0,0 +1,24 @@
/**
* Wraps a function such that only one in-flight invocation is active at a time.
*
* That is, if the returned function is invoked more that one time before the
* promise returned from the initial invocation resolves, then the same promise
* is returned for subsequent invocations.
*
* Once the promise has resolved, the next invocation of the returned function
* will re-invoke the original function again.
*/
export function sharedPromise<P extends any[], V, T>(
fn: (this: T, ...args: P) => Promise<V>
) {
let promise: Promise<V> | null = null;
return function (this: T, ...args: P) {
if (!promise) {
promise = fn.apply(this, args);
promise.finally(() => {
promise = null;
});
}
return promise;
};
}

View File

@@ -1,11 +1,11 @@
import path from 'path'; import path from 'path';
import { CantParseJSONFile } from './errors-ts'; import { CantParseJSONFile } from './errors-ts';
import readJSONFile from './read-json-file'; import readJSONFile from './read-json-file';
import { NowConfig } from './dev/types'; import { VercelConfig } from './dev/types';
import { PackageJson } from '@vercel/build-utils'; import { PackageJson } from '@vercel/build-utils';
interface CustomPackage extends PackageJson { interface CustomPackage extends PackageJson {
now?: NowConfig; now?: VercelConfig;
} }
export default async function readPackage(file?: string) { export default async function readPackage(file?: string) {

View File

@@ -7,9 +7,9 @@ import { parse } from 'url';
* google.com => google.com * google.com => google.com
*/ */
function toHost(url: string) { function toHost(url: string): string {
if (/^https?:\/\//.test(url)) { if (/^https?:\/\//.test(url)) {
return parse(url).host; return parse(url).host!;
} }
// Remove any path if present // Remove any path if present

View File

@@ -9,9 +9,6 @@
"lint": "ng lint", "lint": "ng lint",
"e2e": "ng e2e" "e2e": "ng e2e"
}, },
"engines": {
"node": "10.x"
},
"private": true, "private": true,
"dependencies": { "dependencies": {
"@angular/animations": "8.1.0", "@angular/animations": "8.1.0",

View File

@@ -997,10 +997,10 @@ bluebird@^3.3.0, bluebird@^3.5.1, bluebird@^3.5.3, bluebird@^3.5.5:
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f"
integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==
bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.4.0: bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9:
version "4.11.8" version "4.12.0"
resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88"
integrity sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA== integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==
bn.js@^5.1.1: bn.js@^5.1.1:
version "5.1.1" version "5.1.1"
@@ -1066,7 +1066,7 @@ braces@~3.0.2:
dependencies: dependencies:
fill-range "^7.0.1" fill-range "^7.0.1"
brorand@^1.0.1: brorand@^1.0.1, brorand@^1.1.0:
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=
@@ -1529,7 +1529,7 @@ combined-stream@^1.0.6, combined-stream@~1.0.6:
dependencies: dependencies:
delayed-stream "~1.0.0" delayed-stream "~1.0.0"
commander@^2.11.0, commander@^2.12.1, commander@^2.20.0, commander@~2.20.3: commander@^2.11.0, commander@^2.12.1, commander@^2.20.0:
version "2.20.3" version "2.20.3"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
@@ -2088,17 +2088,17 @@ electron-to-chromium@^1.3.164, electron-to-chromium@^1.3.413:
integrity sha512-FtEGg/wRKT765QehmpRqMDaUbRam03Y3brE+6nUfoxCr9XgyEl+zAgN4+EraOJeyTGTGh27u7Mdx5Hl9qAhJPQ== integrity sha512-FtEGg/wRKT765QehmpRqMDaUbRam03Y3brE+6nUfoxCr9XgyEl+zAgN4+EraOJeyTGTGh27u7Mdx5Hl9qAhJPQ==
elliptic@^6.0.0, elliptic@^6.5.2: elliptic@^6.0.0, elliptic@^6.5.2:
version "6.5.2" version "6.5.4"
resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb"
integrity sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw== integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==
dependencies: dependencies:
bn.js "^4.4.0" bn.js "^4.11.9"
brorand "^1.0.1" brorand "^1.1.0"
hash.js "^1.0.0" hash.js "^1.0.0"
hmac-drbg "^1.0.0" hmac-drbg "^1.0.1"
inherits "^2.0.1" inherits "^2.0.4"
minimalistic-assert "^1.0.0" minimalistic-assert "^1.0.1"
minimalistic-crypto-utils "^1.0.0" minimalistic-crypto-utils "^1.0.1"
emoji-regex@^7.0.1: emoji-regex@^7.0.1:
version "7.0.3" version "7.0.3"
@@ -2842,9 +2842,9 @@ handle-thing@^2.0.0:
integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==
handlebars@^4.0.3: handlebars@^4.0.3:
version "4.7.6" version "4.7.7"
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.6.tgz#d4c05c1baf90e9945f77aa68a7a219aa4a7df74e" resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1"
integrity sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA== integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==
dependencies: dependencies:
minimist "^1.2.5" minimist "^1.2.5"
neo-async "^2.6.0" neo-async "^2.6.0"
@@ -2955,7 +2955,7 @@ hash.js@^1.0.0, hash.js@^1.0.3:
inherits "^2.0.3" inherits "^2.0.3"
minimalistic-assert "^1.0.1" minimalistic-assert "^1.0.1"
hmac-drbg@^1.0.0: hmac-drbg@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1"
integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE= integrity sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=
@@ -2965,9 +2965,9 @@ hmac-drbg@^1.0.0:
minimalistic-crypto-utils "^1.0.1" minimalistic-crypto-utils "^1.0.1"
hosted-git-info@^2.1.4, hosted-git-info@^2.6.0, hosted-git-info@^2.7.1: hosted-git-info@^2.1.4, hosted-git-info@^2.6.0, hosted-git-info@^2.7.1:
version "2.8.8" version "2.8.9"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9"
integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==
hpack.js@^2.1.6: hpack.js@^2.1.6:
version "2.1.6" version "2.1.6"
@@ -3948,9 +3948,9 @@ lodash.tail@^4.1.1:
integrity sha1-0jM6NtnncXyK0vfKyv7HwytERmQ= integrity sha1-0jM6NtnncXyK0vfKyv7HwytERmQ=
lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.4, lodash@^4.17.5: lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.4, lodash@^4.17.5:
version "4.17.15" version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
log4js@^4.0.0: log4js@^4.0.0:
version "4.5.1" version "4.5.1"
@@ -4181,7 +4181,7 @@ minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1:
resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7"
integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==
minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: minimalistic-crypto-utils@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a"
integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=
@@ -4330,9 +4330,9 @@ negotiator@0.6.2:
integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==
neo-async@^2.5.0, neo-async@^2.6.0: neo-async@^2.5.0, neo-async@^2.6.0:
version "2.6.1" version "2.6.2"
resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f"
integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==
nice-try@^1.0.4: nice-try@^1.0.4:
version "1.0.5" version "1.0.5"
@@ -5192,9 +5192,9 @@ querystring@0.2.0:
integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=
querystringify@^2.1.1: querystringify@^2.1.1:
version "2.1.1" version "2.2.0"
resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.1.tgz#60e5a5fd64a7f8bfa4d2ab2ed6fdf4c85bad154e" resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6"
integrity sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA== integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==
randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5:
version "2.1.0" version "2.1.0"
@@ -6109,9 +6109,9 @@ sshpk@^1.7.0:
tweetnacl "~0.14.0" tweetnacl "~0.14.0"
ssri@^6.0.0, ssri@^6.0.1: ssri@^6.0.0, ssri@^6.0.1:
version "6.0.1" version "6.0.2"
resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.2.tgz#157939134f20464e7301ddba3e90ffa8f7728ac5"
integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== integrity sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==
dependencies: dependencies:
figgy-pudding "^3.5.1" figgy-pudding "^3.5.1"
@@ -6601,11 +6601,9 @@ typescript@3.4.5:
integrity sha512-YycBxUb49UUhdNMU5aJ7z5Ej2XGmaIBL0x34vZ82fn3hGvD+bgrMrVDpatgz2f7YxUMJxMkbWxJZeAvDxVe7Vw== integrity sha512-YycBxUb49UUhdNMU5aJ7z5Ej2XGmaIBL0x34vZ82fn3hGvD+bgrMrVDpatgz2f7YxUMJxMkbWxJZeAvDxVe7Vw==
uglify-js@^3.1.4: uglify-js@^3.1.4:
version "3.9.3" version "3.13.7"
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.9.3.tgz#4a285d1658b8a2ebaef9e51366b3a0f7acd79ec2" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.13.7.tgz#25468a3b39b1c875df03f0937b2b7036a93f3fee"
integrity sha512-r5ImcL6QyzQGVimQoov3aL2ZScywrOgBXGndbWrdehKoSvGe/RmiE5Jpw/v+GvxODt6l2tpBXwA7n+qZVlHBMA== integrity sha512-1Psi2MmnZJbnEsgJJIlfnd7tFlJfitusmR7zDI8lXlFI0ACD4/Rm/xdrU8bh6zF0i74aiVoBtkRiFulkrmh3AA==
dependencies:
commander "~2.20.3"
ultron@~1.1.0: ultron@~1.1.0:
version "1.1.1" version "1.1.1"
@@ -6704,9 +6702,9 @@ urix@^0.1.0:
integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=
url-parse@^1.4.3: url-parse@^1.4.3:
version "1.4.7" version "1.5.1"
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278" resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.1.tgz#d5fa9890af8a5e1f274a2c98376510f6425f6e3b"
integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg== integrity sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==
dependencies: dependencies:
querystringify "^2.1.1" querystringify "^2.1.1"
requires-port "^1.0.0" requires-port "^1.0.0"

View File

@@ -4571,9 +4571,9 @@ hoopy@^0.1.4:
integrity sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ== integrity sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==
hosted-git-info@^2.1.4: hosted-git-info@^2.1.4:
version "2.8.8" version "2.8.9"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9"
integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==
hpack.js@^2.1.6: hpack.js@^2.1.6:
version "2.1.6" version "2.1.6"
@@ -6056,9 +6056,9 @@ lodash.sortby@^4.7.0:
integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=
lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.3, lodash@^4.17.4: lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.3, lodash@^4.17.4:
version "4.17.15" version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
loglevel@^1.6.3: loglevel@^1.6.3:
version "1.6.8" version "1.6.8"
@@ -7324,9 +7324,9 @@ querystring@0.2.0:
integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=
querystringify@^2.1.1: querystringify@^2.1.1:
version "2.1.1" version "2.2.0"
resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.1.tgz#60e5a5fd64a7f8bfa4d2ab2ed6fdf4c85bad154e" resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6"
integrity sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA== integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==
randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5:
version "2.1.0" version "2.1.0"
@@ -8207,9 +8207,9 @@ sshpk@^1.7.0:
tweetnacl "~0.14.0" tweetnacl "~0.14.0"
ssri@^6.0.1: ssri@^6.0.1:
version "6.0.1" version "6.0.2"
resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.2.tgz#157939134f20464e7301ddba3e90ffa8f7728ac5"
integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== integrity sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==
dependencies: dependencies:
figgy-pudding "^3.5.1" figgy-pudding "^3.5.1"
@@ -8903,9 +8903,9 @@ url-loader@1.1.2:
schema-utils "^1.0.0" schema-utils "^1.0.0"
url-parse@^1.4.3: url-parse@^1.4.3:
version "1.4.7" version "1.5.1"
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278" resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.1.tgz#d5fa9890af8a5e1f274a2c98376510f6425f6e3b"
integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg== integrity sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==
dependencies: dependencies:
querystringify "^2.1.1" querystringify "^2.1.1"
requires-port "^1.0.0" requires-port "^1.0.0"

View File

@@ -4580,9 +4580,9 @@ hmac-drbg@^1.0.1:
minimalistic-crypto-utils "^1.0.1" minimalistic-crypto-utils "^1.0.1"
hosted-git-info@^2.1.4: hosted-git-info@^2.1.4:
version "2.8.8" version "2.8.9"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9"
integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg== integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==
hpack.js@^2.1.6: hpack.js@^2.1.6:
version "2.1.6" version "2.1.6"
@@ -7896,9 +7896,9 @@ querystring@0.2.0:
integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=
querystringify@^2.1.1: querystringify@^2.1.1:
version "2.1.1" version "2.2.0"
resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.1.1.tgz#60e5a5fd64a7f8bfa4d2ab2ed6fdf4c85bad154e" resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6"
integrity sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA== integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==
raf@^3.4.1: raf@^3.4.1:
version "3.4.1" version "3.4.1"
@@ -8898,9 +8898,9 @@ sshpk@^1.7.0:
tweetnacl "~0.14.0" tweetnacl "~0.14.0"
ssri@^6.0.1: ssri@^6.0.1:
version "6.0.1" version "6.0.2"
resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.1.tgz#2a3c41b28dd45b62b63676ecb74001265ae9edd8" resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.2.tgz#157939134f20464e7301ddba3e90ffa8f7728ac5"
integrity sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA== integrity sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q==
dependencies: dependencies:
figgy-pudding "^3.5.1" figgy-pudding "^3.5.1"
@@ -9529,9 +9529,9 @@ url-loader@1.1.2:
schema-utils "^1.0.0" schema-utils "^1.0.0"
url-parse@^1.4.3: url-parse@^1.4.3:
version "1.4.7" version "1.5.1"
resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.4.7.tgz#a8a83535e8c00a316e403a5db4ac1b9b853ae278" resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.1.tgz#d5fa9890af8a5e1f274a2c98376510f6425f6e3b"
integrity sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg== integrity sha512-HOfCOUJt7iSYzEx/UqgtwKRMC6EU91NFhsCHMv9oM03VJcVo2Qrp8T8kI9D7amFf1cu+/3CEhgb3rF9zL7k85Q==
dependencies: dependencies:
querystringify "^2.1.1" querystringify "^2.1.1"
requires-port "^1.0.0" requires-port "^1.0.0"

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/client", "name": "@vercel/client",
"version": "10.0.1-canary.3", "version": "10.1.0",
"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",
@@ -40,7 +40,7 @@
] ]
}, },
"dependencies": { "dependencies": {
"@vercel/build-utils": "2.10.3-canary.3", "@vercel/build-utils": "2.11.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",

View File

@@ -55,7 +55,7 @@ export interface Deployment {
| 'DEPLOYING' | 'DEPLOYING'
| 'READY' | 'READY'
| 'ERROR'; | 'ERROR';
createdAt: string; createdAt: number;
createdIn: string; createdIn: string;
env: Dictionary<string>; env: Dictionary<string>;
build: { build: {

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/frameworks", "name": "@vercel/frameworks",
"version": "0.3.3-canary.3", "version": "0.4.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.11.1-canary.1", "@vercel/routing-utils": "1.11.1",
"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",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/node", "name": "@vercel/node",
"version": "1.10.0", "version": "1.11.0",
"license": "MIT", "license": "MIT",
"main": "./dist/index", "main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/node-js", "homepage": "https://vercel.com/docs/runtimes#official-runtimes/node-js",
@@ -33,7 +33,7 @@
"@types/etag": "1.8.0", "@types/etag": "1.8.0",
"@types/test-listen": "1.1.0", "@types/test-listen": "1.1.0",
"@vercel/ncc": "0.24.0", "@vercel/ncc": "0.24.0",
"@vercel/nft": "0.10.0", "@vercel/nft": "0.12.2",
"content-type": "1.0.4", "content-type": "1.0.4",
"cookie": "0.4.0", "cookie": "0.4.0",
"etag": "1.8.1", "etag": "1.8.1",

View File

@@ -1,5 +1,3 @@
{ {
"engines": { "private": true
"node": "10.x"
}
} }

View File

@@ -1,5 +1,3 @@
{ {
"engines": { "private": true
"node": "10.x"
}
} }

View File

@@ -26,7 +26,7 @@ async function getResult(url) {
} }
module.exports = async (req, res) => { module.exports = async (req, res) => {
const result = await getResult('https://vercel.com/about'); const result = await getResult('https://vercel.com/docs');
if (req && result && result.lhr && result.lhr.categories) { if (req && result && result.lhr && result.lhr.categories) {
res.end('lighthouse:RANDOMNESS_PLACEHOLDER'); res.end('lighthouse:RANDOMNESS_PLACEHOLDER');
} else { } else {

View File

@@ -1,10 +1,10 @@
{ {
"engines": { "engines": {
"node": "10.x" "node": "14.x"
}, },
"dependencies": { "dependencies": {
"chrome-aws-lambda": "1.20.4", "chrome-aws-lambda": "7.0.0",
"lighthouse": "5.6.0", "lighthouse": "7.4.0",
"puppeteer-core": "1.20.0" "puppeteer-core": "7.0.0"
} }
} }

View File

@@ -7,7 +7,8 @@
"config": { "config": {
"functions": { "functions": {
"**/*.js": { "**/*.js": {
"memory": 3008 "memory": 3008,
"maxDuration": 30
} }
} }
} }

View File

@@ -3,8 +3,5 @@
"dependencies": { "dependencies": {
"@builders-transpiled-test/lib": "*" "@builders-transpiled-test/lib": "*"
}, },
"engines": {
"node": "10.x"
},
"version": "1.0.0" "version": "1.0.0"
} }

View File

@@ -3,8 +3,5 @@
"dependencies": { "dependencies": {
"@builders-typescript-test/lib": "*" "@builders-typescript-test/lib": "*"
}, },
"engines": {
"node": "10.x"
},
"version": "1.0.0" "version": "1.0.0"
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/python", "name": "@vercel/python",
"version": "2.0.1", "version": "2.0.3",
"main": "./dist/index.js", "main": "./dist/index.js",
"license": "MIT", "license": "MIT",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/python", "homepage": "https://vercel.com/docs/runtimes#official-runtimes/python",

View File

@@ -86,6 +86,7 @@ export const build = async ({
await installRequirement({ await installRequirement({
dependency: 'werkzeug', dependency: 'werkzeug',
version: '1.0.1',
workPath, workPath,
meta, meta,
}); });
@@ -109,6 +110,7 @@ export const build = async ({
const tempDir = await getWriteableDirectory(); const tempDir = await getWriteableDirectory();
await installRequirement({ await installRequirement({
dependency: 'pipfile-requirements', dependency: 'pipfile-requirements',
version: '0.3.0',
workPath: tempDir, workPath: tempDir,
meta, meta,
args: ['--no-warn-script-location'], args: ['--no-warn-script-location'],

View File

@@ -61,39 +61,28 @@ async function pipInstall(workPath: string, args: string[]) {
// distutils.errors.DistutilsOptionError: can't combine user with // distutils.errors.DistutilsOptionError: can't combine user with
// prefix, exec_prefix/home, or install_(plat)base // prefix, exec_prefix/home, or install_(plat)base
process.env.PIP_USER = '0'; process.env.PIP_USER = '0';
debug( const cmdArgs = [
`Running "pip install --disable-pip-version-check --target ${target} --upgrade ${args.join( 'install',
' ' '--disable-pip-version-check',
)}"...` '--target',
); target,
...args,
];
debug(`Running "pip3 ${cmdArgs.join(' ')}"...`);
try { try {
await execa( await execa(pipPath, cmdArgs, {
pipPath, cwd: workPath,
[ stdio: 'pipe',
'install', });
'--disable-pip-version-check',
'--target',
target,
'--upgrade',
...args,
],
{
cwd: workPath,
stdio: 'pipe',
}
);
} catch (err) { } catch (err) {
console.log( console.log(`Failed to run "pip3 ${cmdArgs.join(' ')}"`);
`Failed to run "pip install --disable-pip-version-check --target ${target} --upgrade ${args.join(
' '
)}"...`
);
throw err; throw err;
} }
} }
interface InstallRequirementArg { interface InstallRequirementArg {
dependency: string; dependency: string;
version: string;
workPath: string; workPath: string;
meta: Meta; meta: Meta;
args?: string[]; args?: string[];
@@ -101,6 +90,7 @@ interface InstallRequirementArg {
export async function installRequirement({ export async function installRequirement({
dependency, dependency,
version,
workPath, workPath,
meta, meta,
args = [], args = [],
@@ -111,7 +101,8 @@ export async function installRequirement({
); );
return; return;
} }
await pipInstall(workPath, [dependency, ...args]); const exact = `${dependency}==${version}`;
await pipInstall(workPath, [exact, ...args]);
} }
interface InstallRequirementsFileArg { interface InstallRequirementsFileArg {

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/routing-utils", "name": "@vercel/routing-utils",
"version": "1.11.1-canary.1", "version": "1.11.1",
"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",

192
yarn.lock
View File

@@ -1265,6 +1265,21 @@
npmlog "^4.1.2" npmlog "^4.1.2"
write-file-atomic "^2.3.0" write-file-atomic "^2.3.0"
"@mapbox/node-pre-gyp@^1.0.5":
version "1.0.5"
resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.5.tgz#2a0b32fcb416fb3f2250fd24cb2a81421a4f5950"
integrity sha512-4srsKPXWlIxp5Vbqz5uLfBN+du2fJChBoYn/f2h991WLdk7jUvcSk/McVLSv/X+xQIPI8eGD5GjrnygdyHnhPA==
dependencies:
detect-libc "^1.0.3"
https-proxy-agent "^5.0.0"
make-dir "^3.1.0"
node-fetch "^2.6.1"
nopt "^5.0.0"
npmlog "^4.1.2"
rimraf "^3.0.2"
semver "^7.3.4"
tar "^6.1.0"
"@mrmlnc/readdir-enhanced@^2.2.1": "@mrmlnc/readdir-enhanced@^2.2.1":
version "2.2.1" version "2.2.1"
resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde"
@@ -1737,6 +1752,14 @@
"@types/events" "*" "@types/events" "*"
"@types/node" "*" "@types/node" "*"
"@types/inquirer@7.3.1":
version "7.3.1"
resolved "https://registry.yarnpkg.com/@types/inquirer/-/inquirer-7.3.1.tgz#1f231224e7df11ccfaf4cf9acbcc3b935fea292d"
integrity sha512-osD38QVIfcdgsPCT0V3lD7eH0OFurX71Jft18bZrsVQWVRt6TuxRzlr0GJLrxoHZR2V5ph7/qP8se/dcnI7o0g==
dependencies:
"@types/through" "*"
rxjs "^6.4.0"
"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0":
version "2.0.2" version "2.0.2"
resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.2.tgz#79d7a78bad4219f4c03d6557a1c72d9ca6ba62d5" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.2.tgz#79d7a78bad4219f4c03d6557a1c72d9ca6ba62d5"
@@ -1837,12 +1860,13 @@
dependencies: dependencies:
"@types/node" "*" "@types/node" "*"
"@types/node-fetch@2.1.4": "@types/node-fetch@2.5.10":
version "2.1.4" version "2.5.10"
resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.1.4.tgz#093d1beae11541aef25999d70aa09286fd025b1a" resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.10.tgz#9b4d4a0425562f9fcea70b12cb3fcdd946ca8132"
integrity sha512-tR1ekaXUGpmzOcDXWU9BW73YfA2/VW1DF1FH+wlJ82BbCSnWTbdX+JkqWQXWKIGsFPnPsYadbXfNgz28g+ccWg== integrity sha512-IpkX0AasN44hgEad0gEF/V6EgR5n69VEqPEgnmoM8GsIGro3PowbWs4tR6IhxUTyPLpOn+fiGG6nrQhcmoCuIQ==
dependencies: dependencies:
"@types/node" "*" "@types/node" "*"
form-data "^3.0.0"
"@types/node-fetch@2.5.4": "@types/node-fetch@2.5.4":
version "2.5.4" version "2.5.4"
@@ -1978,6 +2002,13 @@
resolved "https://registry.yarnpkg.com/@types/text-table/-/text-table-0.2.0.tgz#cec067b522598bbb37186375b834ac30411c9af6" resolved "https://registry.yarnpkg.com/@types/text-table/-/text-table-0.2.0.tgz#cec067b522598bbb37186375b834ac30411c9af6"
integrity sha512-om4hNWnI01IKUFCjGQG33JqFcnmt0W5C3WX0G1FVBaucr7oRnL29aAz2hnxpbZnE2t9f8/BR5VOtgcOtsonpLA== integrity sha512-om4hNWnI01IKUFCjGQG33JqFcnmt0W5C3WX0G1FVBaucr7oRnL29aAz2hnxpbZnE2t9f8/BR5VOtgcOtsonpLA==
"@types/through@*":
version "0.0.30"
resolved "https://registry.yarnpkg.com/@types/through/-/through-0.0.30.tgz#e0e42ce77e897bd6aead6f6ea62aeb135b8a3895"
integrity sha512-FvnCJljyxhPM3gkRgWmxmDZyAQSiBQQWLI0A0VFL0K7W1oRUrPJSqNO0NvTnLkBcotdlp3lKvaT0JrnyRDkzOg==
dependencies:
"@types/node" "*"
"@types/universal-analytics@0.4.2": "@types/universal-analytics@0.4.2":
version "0.4.2" version "0.4.2"
resolved "https://registry.yarnpkg.com/@types/universal-analytics/-/universal-analytics-0.4.2.tgz#d21a122a984bf8261eb206bcb7ccb1c0e8353d04" resolved "https://registry.yarnpkg.com/@types/universal-analytics/-/universal-analytics-0.4.2.tgz#d21a122a984bf8261eb206bcb7ccb1c0e8353d04"
@@ -2085,11 +2116,12 @@
resolved "https://registry.yarnpkg.com/@vercel/ncc/-/ncc-0.24.0.tgz#a2e8783a185caa99b5d8961a57dfc9665de16296" resolved "https://registry.yarnpkg.com/@vercel/ncc/-/ncc-0.24.0.tgz#a2e8783a185caa99b5d8961a57dfc9665de16296"
integrity sha512-crqItMcIwCkvdXY/V3/TzrHJQx6nbIaRqE1cOopJhgGX6izvNov40SmD//nS5flfEvdK54YGjwVVq+zG6crjOg== integrity sha512-crqItMcIwCkvdXY/V3/TzrHJQx6nbIaRqE1cOopJhgGX6izvNov40SmD//nS5flfEvdK54YGjwVVq+zG6crjOg==
"@vercel/nft@0.10.0": "@vercel/nft@0.12.2":
version "0.10.0" version "0.12.2"
resolved "https://registry.yarnpkg.com/@vercel/nft/-/nft-0.10.0.tgz#6dc99c28abd073633467371a1855f08820460d45" resolved "https://registry.yarnpkg.com/@vercel/nft/-/nft-0.12.2.tgz#67ea9f231d24639b3783e3e69bef173659972d3b"
integrity sha512-0WABTmfebmYDR9GKuM9uFNr6MCayfl/zB6uXzkMsWlXrd7LN/ZI7sdbC/Ua+h4HEzJtvEMOrxLkIYYKqfeUf9A== integrity sha512-H8n44GboVnJaVVX4+WfuOTAaNLDnUIYH4KpMZcXll7KMNIcg0JTd0IFRsIBe/uvuXisqm6nEANp8Tr3/1dlRQw==
dependencies: dependencies:
"@mapbox/node-pre-gyp" "^1.0.5"
acorn "^8.1.0" acorn "^8.1.0"
acorn-class-fields "^1.0.0" acorn-class-fields "^1.0.0"
acorn-static-class-features "^1.0.0" acorn-static-class-features "^1.0.0"
@@ -2263,11 +2295,6 @@ agent-base@4, agent-base@^4.1.0, agent-base@^4.3.0:
dependencies: dependencies:
es6-promisify "^5.0.0" es6-promisify "^5.0.0"
agent-base@5:
version "5.1.1"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-5.1.1.tgz#e8fb3f242959db44d63be665db7a8e739537a32c"
integrity sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==
agent-base@6: agent-base@6:
version "6.0.0" version "6.0.0"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.0.tgz#5d0101f19bbfaed39980b22ae866de153b93f09a" resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.0.tgz#5d0101f19bbfaed39980b22ae866de153b93f09a"
@@ -3300,6 +3327,11 @@ chownr@^1.0.1, chownr@^1.1.1, chownr@^1.1.2:
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b"
integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==
chownr@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece"
integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==
chunkd@^1.0.0: chunkd@^1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/chunkd/-/chunkd-1.0.0.tgz#4ead4a3704bcce510c4bb4d4a8be30c557836dd1" resolved "https://registry.yarnpkg.com/chunkd/-/chunkd-1.0.0.tgz#4ead4a3704bcce510c4bb4d4a8be30c557836dd1"
@@ -3443,15 +3475,15 @@ code-point-at@^1.0.0:
resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77"
integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c= integrity sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
codecov@3.7.1: codecov@3.8.2:
version "3.7.1" version "3.8.2"
resolved "https://registry.yarnpkg.com/codecov/-/codecov-3.7.1.tgz#434cb8d55f18ef01672e5739d3d266696bebc202" resolved "https://registry.yarnpkg.com/codecov/-/codecov-3.8.2.tgz#ab24f18783998c39e809ea210af899f8dbcc790e"
integrity sha512-JHWxyPTkMLLJn9SmKJnwAnvY09kg2Os2+Ux+GG7LwZ9g8gzDDISpIN5wAsH1UBaafA/yGcd3KofMaorE8qd6Lw== integrity sha512-6w/kt/xvmPsWMfDFPE/T054txA9RTgcJEw36PNa6MYX+YV29jCHCRFXwbQ3QZBTOgnex1J2WP8bo2AT8TWWz9g==
dependencies: dependencies:
argv "0.0.2" argv "0.0.2"
ignore-walk "3.0.3" ignore-walk "3.0.3"
js-yaml "3.13.1" js-yaml "3.14.1"
teeny-request "6.0.1" teeny-request "7.0.1"
urlgrey "0.4.4" urlgrey "0.4.4"
collection-visit@^1.0.0: collection-visit@^1.0.0:
@@ -4110,7 +4142,7 @@ detect-indent@^5.0.0:
resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d"
integrity sha1-OHHMCmoALow+Wzz38zYmRnXwa50= integrity sha1-OHHMCmoALow+Wzz38zYmRnXwa50=
detect-libc@^1.0.2: detect-libc@^1.0.2, detect-libc@^1.0.3:
version "1.0.3" version "1.0.3"
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups= integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=
@@ -4438,6 +4470,11 @@ es6-promisify@^5.0.0:
dependencies: dependencies:
es6-promise "^4.0.3" es6-promise "^4.0.3"
esbuild@^0.11.20:
version "0.11.23"
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.11.23.tgz#c42534f632e165120671d64db67883634333b4b8"
integrity sha512-iaiZZ9vUF5wJV8ob1tl+5aJTrwDczlvGP0JoMmnpC2B0ppiMCu8n8gmy5ZTGl5bcG081XBVn+U+jP+mPFm5T5Q==
escape-goat@^2.0.0: escape-goat@^2.0.0:
version "2.1.1" version "2.1.1"
resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675" resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675"
@@ -5125,6 +5162,13 @@ fs-minipass@^1.2.5:
dependencies: dependencies:
minipass "^2.6.0" minipass "^2.6.0"
fs-minipass@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb"
integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==
dependencies:
minipass "^3.0.0"
fs-write-stream-atomic@^1.0.8: fs-write-stream-atomic@^1.0.8:
version "1.0.10" version "1.0.10"
resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9"
@@ -5693,12 +5737,12 @@ https-proxy-agent@^2.2.3:
agent-base "^4.3.0" agent-base "^4.3.0"
debug "^3.1.0" debug "^3.1.0"
https-proxy-agent@^4.0.0: https-proxy-agent@^5.0.0:
version "4.0.0" version "5.0.0"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz#702b71fb5520a132a66de1f67541d9e62154d82b" resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2"
integrity sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg== integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==
dependencies: dependencies:
agent-base "5" agent-base "6"
debug "4" debug "4"
human-signals@^1.1.1: human-signals@^1.1.1:
@@ -6779,6 +6823,14 @@ js-yaml@3.13.1:
argparse "^1.0.7" argparse "^1.0.7"
esprima "^4.0.0" esprima "^4.0.0"
js-yaml@3.14.1:
version "3.14.1"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537"
integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==
dependencies:
argparse "^1.0.7"
esprima "^4.0.0"
js-yaml@^3.10.0, js-yaml@^3.13.1: js-yaml@^3.10.0, js-yaml@^3.13.1:
version "3.14.0" version "3.14.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.0.tgz#a7a34170f26a21bb162424d8adacb4113a69e482"
@@ -7315,6 +7367,13 @@ lru-cache@^4.0.1:
pseudomap "^1.0.2" pseudomap "^1.0.2"
yallist "^2.1.2" yallist "^2.1.2"
lru-cache@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94"
integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==
dependencies:
yallist "^4.0.0"
lru_map@0.3.3: lru_map@0.3.3:
version "0.3.3" version "0.3.3"
resolved "https://registry.yarnpkg.com/lru_map/-/lru_map-0.3.3.tgz#b5c8351b9464cbd750335a79650a0ec0e56118dd" resolved "https://registry.yarnpkg.com/lru_map/-/lru_map-0.3.3.tgz#b5c8351b9464cbd750335a79650a0ec0e56118dd"
@@ -7340,7 +7399,7 @@ make-dir@^2.0.0, make-dir@^2.1.0:
pify "^4.0.1" pify "^4.0.1"
semver "^5.6.0" semver "^5.6.0"
make-dir@^3.0.0: make-dir@^3.0.0, make-dir@^3.1.0:
version "3.1.0" version "3.1.0"
resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f"
integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==
@@ -7656,6 +7715,13 @@ minipass@^2.3.3, minipass@^2.3.4, minipass@^2.3.5, minipass@^2.6.0, minipass@^2.
safe-buffer "^5.1.2" safe-buffer "^5.1.2"
yallist "^3.0.0" yallist "^3.0.0"
minipass@^3.0.0:
version "3.1.3"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd"
integrity sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==
dependencies:
yallist "^4.0.0"
minizlib@^1.1.0, minizlib@^1.1.1, minizlib@^1.2.1: minizlib@^1.1.0, minizlib@^1.1.1, minizlib@^1.2.1:
version "1.3.3" version "1.3.3"
resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d"
@@ -7663,6 +7729,14 @@ minizlib@^1.1.0, minizlib@^1.1.1, minizlib@^1.2.1:
dependencies: dependencies:
minipass "^2.9.0" minipass "^2.9.0"
minizlib@^2.1.1:
version "2.1.2"
resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931"
integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==
dependencies:
minipass "^3.0.0"
yallist "^4.0.0"
mississippi@^3.0.0: mississippi@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022"
@@ -7694,7 +7768,7 @@ mkdirp-promise@5.0.1, mkdirp-promise@^5.0.1:
dependencies: dependencies:
mkdirp "*" mkdirp "*"
mkdirp@*: mkdirp@*, mkdirp@^1.0.3:
version "1.0.4" version "1.0.4"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
@@ -7856,7 +7930,7 @@ node-fetch@2.6.0:
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd"
integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA== integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==
node-fetch@2.6.1, node-fetch@^2.2.0, node-fetch@^2.2.1, node-fetch@^2.3.0, node-fetch@^2.5.0: node-fetch@2.6.1, node-fetch@^2.2.1, node-fetch@^2.3.0, node-fetch@^2.5.0, node-fetch@^2.6.1:
version "2.6.1" version "2.6.1"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
@@ -7928,6 +8002,13 @@ nopt@^4.0.1:
abbrev "1" abbrev "1"
osenv "^0.1.4" osenv "^0.1.4"
nopt@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88"
integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==
dependencies:
abbrev "1"
normalize-package-data@^2.0.0, normalize-package-data@^2.3.0, normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.3.5, normalize-package-data@^2.4.0, normalize-package-data@^2.5.0: normalize-package-data@^2.0.0, normalize-package-data@^2.3.0, normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.3.5, normalize-package-data@^2.4.0, normalize-package-data@^2.5.0:
version "2.5.0" version "2.5.0"
resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8"
@@ -9401,7 +9482,7 @@ rimraf@2.6.3:
dependencies: dependencies:
glob "^7.1.3" glob "^7.1.3"
rimraf@3.0.2, rimraf@^3.0.0: rimraf@3.0.2, rimraf@^3.0.0, rimraf@^3.0.2:
version "3.0.2" version "3.0.2"
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a"
integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==
@@ -9553,6 +9634,13 @@ semver@^7.3.2:
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938"
integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==
semver@^7.3.4:
version "7.3.5"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7"
integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==
dependencies:
lru-cache "^6.0.0"
serialize-error@^2.1.0: serialize-error@^2.1.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-2.1.0.tgz#50b679d5635cdf84667bdc8e59af4e5b81d5f60a" resolved "https://registry.yarnpkg.com/serialize-error/-/serialize-error-2.1.0.tgz#50b679d5635cdf84667bdc8e59af4e5b81d5f60a"
@@ -9771,7 +9859,7 @@ source-map-support@0.5.12:
buffer-from "^1.0.0" buffer-from "^1.0.0"
source-map "^0.6.0" source-map "^0.6.0"
source-map-support@^0.5.12, source-map-support@^0.5.17, source-map-support@^0.5.6: source-map-support@^0.5.12, source-map-support@^0.5.17, source-map-support@^0.5.19, source-map-support@^0.5.6:
version "0.5.19" version "0.5.19"
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61"
integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==
@@ -10285,16 +10373,28 @@ tar@^4, tar@^4.4.10, tar@^4.4.12, tar@^4.4.8:
safe-buffer "^5.1.2" safe-buffer "^5.1.2"
yallist "^3.0.3" yallist "^3.0.3"
teeny-request@6.0.1: tar@^6.1.0:
version "6.0.1" version "6.1.0"
resolved "https://registry.yarnpkg.com/teeny-request/-/teeny-request-6.0.1.tgz#9b1f512cef152945827ba7e34f62523a4ce2c5b0" resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.0.tgz#d1724e9bcc04b977b18d5c573b333a2207229a83"
integrity sha512-TAK0c9a00ELOqLrZ49cFxvPVogMUFaWY8dUsQc/0CuQPGF+BOxOQzXfE413BAk2kLomwNplvdtMpeaeGWmoc2g== integrity sha512-DUCttfhsnLCjwoDoFcI+B2iJgYa93vBnDUATYEeRx6sntCTdN01VnqsIuTlALXla/LWooNg0yEGeB+Y8WdFxGA==
dependencies:
chownr "^2.0.0"
fs-minipass "^2.0.0"
minipass "^3.0.0"
minizlib "^2.1.1"
mkdirp "^1.0.3"
yallist "^4.0.0"
teeny-request@7.0.1:
version "7.0.1"
resolved "https://registry.yarnpkg.com/teeny-request/-/teeny-request-7.0.1.tgz#bdd41fdffea5f8fbc0d29392cb47bec4f66b2b4c"
integrity sha512-sasJmQ37klOlplL4Ia/786M5YlOcoLGQyq2TE4WHSRupbAuDaQW0PfVxV4MtdBtRJ4ngzS+1qim8zP6Zp35qCw==
dependencies: dependencies:
http-proxy-agent "^4.0.0" http-proxy-agent "^4.0.0"
https-proxy-agent "^4.0.0" https-proxy-agent "^5.0.0"
node-fetch "^2.2.0" node-fetch "^2.6.1"
stream-events "^1.0.5" stream-events "^1.0.5"
uuid "^3.3.2" uuid "^8.0.0"
temp-dir@^1.0.0: temp-dir@^1.0.0:
version "1.0.0" version "1.0.0"
@@ -10538,6 +10638,14 @@ trim-right@^1.0.1:
resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003"
integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM= integrity sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=
ts-eager@2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/ts-eager/-/ts-eager-2.0.2.tgz#2c1a4d37529effa321f3438793650a84028a87d5"
integrity sha512-xzFPL2z7mgLs0brZXaIHTm91Pjl/Cuu9AMKprgSuK+kIS2LjiG8fqqg4eqz3tgBy9OIdupb9w55pr7ea3JBB+Q==
dependencies:
esbuild "^0.11.20"
source-map-support "^0.5.19"
ts-jest@24.1.0: ts-jest@24.1.0:
version "24.1.0" version "24.1.0"
resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-24.1.0.tgz#2eaa813271a2987b7e6c3fefbda196301c131734" resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-24.1.0.tgz#2eaa813271a2987b7e6c3fefbda196301c131734"
@@ -10893,6 +11001,11 @@ uuid@^3.0.0, uuid@^3.0.1, uuid@^3.3.2:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
uuid@^8.0.0:
version "8.3.2"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
v8-compile-cache@^2.0.3: v8-compile-cache@^2.0.3:
version "2.1.1" version "2.1.1"
resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz#54bc3cdd43317bca91e35dcaf305b1a7237de745" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz#54bc3cdd43317bca91e35dcaf305b1a7237de745"
@@ -11215,6 +11328,11 @@ yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3:
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
yallist@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
yargs-parser@10.x, yargs-parser@^10.0.0: yargs-parser@10.x, yargs-parser@^10.0.0:
version "10.1.0" version "10.1.0"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-10.1.0.tgz#7202265b89f7e9e9f2e5765e0fe735a905edbaa8"