Compare commits

..
Author SHA1 Message Date
Kudo Chien e7b7eacd4e fix lint errors 2024-12-19 00:20:26 +08:00
Kudo Chien ec43906005 update changelog 2024-12-19 00:19:03 +08:00
Kudo Chien b71f324c83 [eas-cli] support platform version 2024-12-19 00:11:52 +08:00
Expo Bot 4bb550e3bb Upgrade eas-build dependencies (#2776) 2024-12-18 13:12:27 +01:00
Kadi Kraman 6a55c65908 [eas-cli] show deployment errors (#2771)
* Show upload errors

* Add changelog

* Fix changelog

* Show error from request body when applicable
2024-12-13 17:08:53 +00:00
Expo CI ab3495da5e update CHANGELOG.md 2024-12-13 15:25:41 +00:00
Szymon Dziedzic 63b67635e0 v14.2.0 2024-12-13 16:20:07 +01:00
Szymon Dziedzic 4b5cda3bbc [eas-cli] fix request for switching providers (#2769)
* [eas-cli] fix request for switching providers

* add changelog entry
2024-12-13 16:19:04 +01:00
Szymon Dziedzic 63e3c1f2ab [eas-cli] improvements to eas env:exec command (#2762)
* [eas-cli] improvements to eas env:exec command

* add changelog
2024-12-13 16:05:02 +01:00
Expo Bot 3f1543989f Upgrade eas-build dependencies (#2768) 2024-12-13 16:04:25 +01:00
Piotr Szeremeta 1c964d2ab1 [ENG-14328] Pass environment to PublishMutation.publishUpdateGroupAsync (#2757)
<!-- If this PR requires a changelog entry, add it by commenting the PR with the command `/changelog-entry [breaking-change|new-feature|bug-fix|chore] [message]`. -->
<!-- You can skip the changelog check by labeling the PR with "no changelog". -->

# Why

[ENG-14328: store `environment` info on update entity](https://linear.app/expo/issue/ENG-14328/store-environment-info-on-update-entity)

Pass `environment` to `PublishMutation.publishUpdateGroupAsync` to store in the db.

Waits for changes on the `www`. https://github.com/expo/universe/pull/17921
2024-12-13 10:41:08 +01:00
Kadi Kraman bc282b6262 [eas-cli] Add environment flag to deploy script (#2763)
* Ensure worker env flag is passed through

* Add changelog
2024-12-11 16:43:43 +00:00
Phil Pluckthun 17661d1cf0 feat(eas-cli): Add --dry-run flag to deploy command (#2761)
* Add dry-run option to deploy command

* Add `--dry-run` flag to deploy command

* Update CHANGELOG
2024-12-11 16:28:12 +00:00
Will Schurman 8d35745124 [eas-cli] Upgrade @expo/multipart-body-parser (#2751) 2024-12-10 10:10:25 -08:00
Will Schurman 3740ee4ef9 [eas-cli] Remove random branch name generation for --auto branch name non-vcs fallback (#2747) 2024-12-10 08:56:01 -08:00
Expo CI 751d3d1287 update CHANGELOG.md 2024-12-10 10:30:23 +00:00
Szymon Dziedzic 1fd14c07e1 v14.1.0 2024-12-10 11:24:35 +01:00
Szymon Dziedzic 39ea1705d8 [eas-cli] add support for broadcast push notifications option for push notifications capability (#2748)
* [eas-cli] add support for broadcast push notifications option for push notifications capability

* Apply suggestions from code review

* bump apple utils

* simplify logic

* add changelog

* add tests
2024-12-10 11:23:21 +01:00
dependabot[bot] 2c96b9929d Bump nanoid from 3.3.4 to 3.3.8 in /packages/eas-cli (#2754)
Bumps [nanoid](https://github.com/ai/nanoid) from 3.3.4 to 3.3.8.
- [Release notes](https://github.com/ai/nanoid/releases)
- [Changelog](https://github.com/ai/nanoid/blob/main/CHANGELOG.md)
- [Commits](https://github.com/ai/nanoid/compare/3.3.4...3.3.8)

---
updated-dependencies:
- dependency-name: nanoid
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-12-10 10:01:17 +01:00
Szymon Dziedzic 0dae24ae47 [eas-cli] bump @expo/apple-utils to add fyi link for apple 2fa sms failure (#2752)
* [eas-cli] bump @expo/apple-utils to add fyi link for apple 2fa sms failure

* add changelog
2024-12-10 09:51:05 +01:00
Expo CI a63efe01a1 update CHANGELOG.md 2024-12-09 20:37:15 +00:00
Szymon Dziedzic 803457b37a v14.0.3 2024-12-09 20:57:35 +01:00
Evan Bacon dcb1305501 fix SMS TFA for Apple authentication (#2750)
* fix SMS TFA for Apple authentication

* Update CHANGELOG.md
2024-12-09 20:53:25 +01:00
Szymon Dziedzic 97fe2d62d2 add changelog entry 2024-12-06 15:41:15 +01:00
JonLuca De Caro ca0850b82b Change package.json update message to allow faster copy and paste (#2661) 2024-12-06 15:38:51 +01:00
Szymon Dziedzic 039a7b408b add changelog entry 2024-12-06 15:10:55 +01:00
Saiichi Shayan Hashimoto 68660ae845 Allow $schema in eas.json (#2624)
* Allow $schema in eas.json

* Add $schema to eas.schema.json
2024-12-06 15:08:11 +01:00
Expo CI 34bb2c8a75 update CHANGELOG.md 2024-12-06 12:48:28 +00:00
Szymon Dziedzic ac5cf3d7dd v14.0.2 2024-12-06 13:41:10 +01:00
Szymon Dziedzic 8d686b855b [eas-cli] make version/CFBundleShortVersionString validation logic show warn instead of throwing an error (#2741)
* [eas-cli] make version/CFBundleShortVersionString validation logic show warn instead of throwing an error

* fix tests

* add changelog entry
2024-12-06 13:39:52 +01:00
Expo CI 19973bb86f update CHANGELOG.md 2024-12-06 12:24:10 +00:00
Szymon Dziedzic d132ac09de v14.0.1 2024-12-06 13:18:24 +01:00
Szymon Dziedzic 4c5e5d4ded upgrade eas-cli-local-build-plugin to 1.0.152 2024-12-06 13:17:22 +01:00
Szymon Dziedzic 44af16efe1 bump @expo/apple-utils to improve error handling and input validation and change auth headers (#2745)
* bump @expo/apple-utils to improve error handling and input validation and change auth headers

* add changelog entry
2024-12-06 12:28:12 +01:00
Expo CI f34487cc8e update CHANGELOG.md 2024-12-06 09:10:27 +00:00
Szymon Dziedzic 7ea1c5de17 v14.0.0 2024-12-06 10:04:57 +01:00
Szymon Dziedzic 261f611770 [ENG-14410] update @expo/config and @expo/config-plugins to fix eas build command for bare iOS projects on Windows (#2744)
* [ENG-14410] update @expo/config and @expo/config-plugins to fix eas build command for bare iOS projects on Windows

* add changelog entry
2024-12-06 10:04:00 +01:00
Bartosz Kaszubowski f9337f419a [eas-cli] tweak message related to channel creation (#2735) 2024-12-05 12:01:57 +01:00
Szymon Dziedzic 4280e10836 [codemention] make codemention.yml up to date (#2740)
<!-- If this PR requires a changelog entry, add it by commenting the PR with the command `/changelog-entry [breaking-change|new-feature|bug-fix|chore] [message]`. -->
<!-- You can skip the changelog check by labeling the PR with "no changelog". -->

# Why

It seems like this file includes redundant entries + is not up to date

# How

Remove redundant entries, add @radoslawkrzemien to global codeowners, make @wschurman and @quinlanj codeowners of everything EAS Update related (including channel commands), remove @byCedric and @EvanBacon from EAS Update codeowners

# Test Plan

Review
2024-12-05 10:16:58 +01:00
Quinlan Jung a2fe99c97e [eas-cli] fingerprint:compare (#2736)
* [eas-cli] fingerprint:compare

* Temporary Commit at 12/2/2024, 1:43:01 PM

* brent feedback

* Temporary Commit at 12/3/2024, 4:46:13 PM
2024-12-03 17:06:16 -08:00
Szymon Dziedzic 868fd399a4 [eas-cli] fix warning for gitignored google services file (#2730)
<!-- If this PR requires a changelog entry, add it by commenting the PR with the command `/changelog-entry [breaking-change|new-feature|bug-fix|chore] [message]`. -->
<!-- You can skip the changelog check by labeling the PR with "no changelog". -->

# Why

https://discord.com/channels/695411232856997968/1309202098591633458/1311040361040183429

# How

Make warning up to date after recent env vars changes
2024-12-02 20:04:00 +01:00
Expo Bot 7d60ba2cea Upgrade eas-build dependencies (#2734)
⬆️ Upgrades [`eas-build`](https://github.com/expo/eas-build) dependencies.
2024-12-02 13:23:37 +01:00
Will Schurman db7461a569 [eas-cli][eas-update] Change behavior of roll-back-to-embedded to not use current project state (#2722) 2024-11-25 10:56:10 -08:00
Expo CI facffbdcd7 update CHANGELOG.md 2024-11-25 11:57:06 +00:00
Szymon Dziedzic dbdefa0e3d v13.4.2 2024-11-25 12:51:08 +01:00
Szymon Dziedzic 66daeade84 [eas-cli] update expo packages to SDK 52 versions (#2706)
# Why

Update `@expo` packages to SDK 52 versions

# How

Update `@expo` packages to SDK 52 versions

Fixes #2696

It seems like the `privacy` field was removed from the expo config in the SDK 52 update: https://expo.dev/changelog/2024/11-12-sdk-52. 

I used `AppPrivay.Unlisted` for the `createApp` mutation input for which this is still required. It was an option selected for an app when `exp.privacy` was undefined.

It also seems that `findWorkspaceRoot` function in `@expo/package-manager` was changed to `resolveWorkspaceRoot`.

# Test Plan

Tests, test commands manually
2024-11-25 12:44:30 +01:00
Expo CI 48ebd9bb78 update CHANGELOG.md 2024-11-22 15:17:53 +00:00
Szymon Dziedzic 3d3574d351 v13.4.1 2024-11-22 15:59:13 +01:00
Szymon Dziedzic 8da6adf4da [eas-cli] improve eas env:pull logging (#2720)
<!-- If this PR requires a changelog entry, add it by commenting the PR with the command `/changelog-entry [breaking-change|new-feature|bug-fix|chore] [message]`. -->
<!-- You can skip the changelog check by labeling the PR with "no changelog". -->

# Why

https://exponent-internal.slack.com/archives/C06FK950085/p1732258126230829

# How

Improve logs

# Test Plan

Tests
2024-11-22 15:58:28 +01:00
Expo CI bd2d39f26b update CHANGELOG.md 2024-11-22 13:12:02 +00:00
65 changed files with 2250 additions and 712 deletions

No files matched your search

+6 -12
View File
@@ -3,24 +3,18 @@ commentConfiguration:
epilogue: 'Generated by [CodeMention](https://github.com/expo/expo/actions/workflows/codemention.yaml)'
rules:
- patterns: ['**/*']
mentions: ['szdziedzic', 'khamilowicz', 'sjchmiela']
- patterns: ['packages/eas-cli/src/build/**']
mentions: ['szdziedzic', 'khamilowicz', 'sjchmiela']
- patterns: ['packages/eas-cli/src/commands/build/**']
mentions: ['szdziedzic', 'khamilowicz', 'sjchmiela']
- patterns: ['packages/eas-cli/src/submit/**']
mentions: ['szdziedzic', 'khamilowicz', 'sjchmiela']
- patterns: ['packages/eas-cli/src/commands/submit.ts']
mentions: ['szdziedzic', 'khamilowicz', 'sjchmiela', 'radoslawkrzemien']
- patterns: ['packages/eas-cli/src/update/**']
mentions: ['EvanBacon', 'byCedric', 'wschurman']
mentions: ['wschurman', 'quinlanj']
- patterns: ['packages/eas-cli/src/commands/update/**']
mentions: ['EvanBacon', 'byCedric', 'wschurman']
mentions: ['wschurman', 'quinlanj']
- patterns: ['packages/eas-cli/src/channel/**']
mentions: ['wschurman', 'quinlanj']
- patterns: ['packages/eas-cli/src/commands/channel/**']
mentions: ['wschurman', 'quinlanj']
- patterns: ['packages/eas-cli/schema/**']
mentions: ['bycedric']
- patterns: ['packages/eas-cli/src/metadata/**']
mentions: ['bycedric']
- patterns: ['packages/eas-cli/src/commands/metadata/**']
mentions: ['bycedric']
- patterns: ['packages/eas-json/**']
mentions: ['szdziedzic', 'khamilowicz', 'sjchmiela']
+92 -2
View File
@@ -8,6 +8,98 @@ This is the log of notable changes to EAS CLI and related packages.
### 🎉 New features
- Added support to read platform version from `app.json`. ([#2778](https://github.com/expo/eas-cli/pull/2778) by [@kudo](https://github.com/kudo))
### 🐛 Bug fixes
- Show `eas deploy` upload error messages. ([#2771](https://github.com/expo/eas-cli/pull/2771) by [@kadikraman](https://github.com/kadikraman))
### 🧹 Chores
## [14.2.0](https://github.com/expo/eas-cli/releases/tag/v14.2.0) - 2024-12-13
### 🎉 New features
- Add `eas deploy --dry-run` flag to output tarball. ([#2761](https://github.com/expo/eas-cli/pull/2761) by [@kitten](https://github.com/kitten))
### 🐛 Bug fixes
- Remove random branch name generation for --auto branch name non-vcs fallback. ([#2747](https://github.com/expo/eas-cli/pull/2747) by [@wschurman](https://github.com/wschurman))
- Upgrade @expo/multipart-body-parser. ([#2751](https://github.com/expo/eas-cli/pull/2751) by [@wschurman](https://github.com/wschurman))
- Pass env var flag to worker deployments. ([#2763](https://github.com/expo/eas-cli/pull/2763) by [@kadikraman](https://github.com/kadikraman))
- Fix request for switching providers when doing Apple auth. ([#2769](https://github.com/expo/eas-cli/pull/2769) by [@szdziedzic](https://github.com/szdziedzic))
### 🧹 Chores
- Improve logging and validation in `eas env:exec` command. ([#2762](https://github.com/expo/eas-cli/pull/2762) by [@szdziedzic](https://github.com/szdziedzic))
## [14.1.0](https://github.com/expo/eas-cli/releases/tag/v14.1.0) - 2024-12-10
### 🎉 New features
- Add support for enabeling broadcast Push Notifications capability option, by setting `ios.usesBroadcastPushNotifications` to `true` in app config. ([#2748](https://github.com/expo/eas-cli/pull/2748) by [@szdziedzic](https://github.com/szdziedzic))
### 🧹 Chores
- Add link to FYI page mentioning the workaround for Apple SMS 2FA issue. ([#2752](https://github.com/expo/eas-cli/pull/2752) by [@szdziedzic](https://github.com/szdziedzic))
## [14.0.3](https://github.com/expo/eas-cli/releases/tag/v14.0.3) - 2024-12-09
### 🐛 Bug fixes
- Bump `@expo/apple-utils` to fix sending two-factor authentication codes via SMS. ([#2750](https://github.com/expo/eas-cli/pull/2750) by [@EvanBacon](https://github.com/EvanBacon))
### 🧹 Chores
- Change update message to allow faster copy and paste. ([#2661](https://github.com/expo/eas-cli/pull/2661) by [@jonluca](https://github.com/jonluca))
- Allow using `$schema` field in `eas.json`. ([#2624](https://github.com/expo/eas-cli/pull/2624) by [@saiichihashimoto](https://github.com/saiichihashimoto))
## [14.0.2](https://github.com/expo/eas-cli/releases/tag/v14.0.2) - 2024-12-06
### 🧹 Chores
- Print warning instead of throwing an error when validating `CFBundleShortVersionString` against App Store requirements. ([#2741](https://github.com/expo/eas-cli/pull/2741) by [@szdziedzic](https://github.com/szdziedzic))
## [14.0.1](https://github.com/expo/eas-cli/releases/tag/v14.0.1) - 2024-12-06
### 🧹 Chores
- Bump `@expo/apple-utils` to improve error handling and input validation and change auth headers. ([#2745](https://github.com/expo/eas-cli/pull/2745) by [@szdziedzic](https://github.com/szdziedzic))
## [14.0.0](https://github.com/expo/eas-cli/releases/tag/v14.0.0) - 2024-12-06
### 🛠 Breaking changes
- Change behavior of roll-back-to-embedded to not use current project state. ([#2722](https://github.com/expo/eas-cli/pull/2722) by [@wschurman](https://github.com/wschurman))
### 🎉 New features
- Add hidden fingerprint:compare feature. ([#2736](https://github.com/expo/eas-cli/pull/2736) by [@quinlanj](https://github.com/quinlanj))
### 🐛 Bug fixes
- Update `@expo/config` and `@expo/config-plugins` to fix `eas build` command for bare iOS projects on Windows. ([#2744](https://github.com/expo/eas-cli/pull/2744) by [@szdziedzic](https://github.com/szdziedzic))
### 🧹 Chores
- Fix outdated gitignored Google services file warning. ([#2730](https://github.com/expo/eas-cli/pull/2730) by [@szdziedzic](https://github.com/szdziedzic))
## [13.4.2](https://github.com/expo/eas-cli/releases/tag/v13.4.2) - 2024-11-25
### 🧹 Chores
- Upgrade `@expo` packages to SDK 52 versions. ([#2706](https://github.com/expo/eas-cli/pull/2706) by [@szdziedzic](https://github.com/szdziedzic))
## [13.4.1](https://github.com/expo/eas-cli/releases/tag/v13.4.1) - 2024-11-22
### 🧹 Chores
- Improve logging in `eas env:pull`. ([#2720](https://github.com/expo/eas-cli/pull/2720) by [@szdziedzic](https://github.com/szdziedzic))
## [13.4.0](https://github.com/expo/eas-cli/releases/tag/v13.4.0) - 2024-11-22
### 🎉 New features
- Calculate fingerprint on each update. ([#2687](https://github.com/expo/eas-cli/pull/2687) by [@quinlanj](https://github.com/quinlanj))
- Calculate fingerprint on each update republish. ([#2708](https://github.com/expo/eas-cli/pull/2708) by [@quinlanj](https://github.com/quinlanj))
- Add `eas env` commands. ([#2711](https://github.com/expo/eas-cli/pull/2711) by [@szdziedzic](https://github.com/szdziedzic))
@@ -15,8 +107,6 @@ This is the log of notable changes to EAS CLI and related packages.
- Load readable environment variables from EAS servers on every build. ([#2644](https://github.com/expo/eas-cli/pull/2644) by [@szdziedzic](https://github.com/szdziedzic))
- Add environment field to `eas.schema.json`. ([#2719](https://github.com/expo/eas-cli/pull/2719) by [@szdziedzic](https://github.com/szdziedzic))
### 🐛 Bug fixes
### 🧹 Chores
- Deprecate `eas secret` commands. ([#2705](https://github.com/expo/eas-cli/pull/2705) by [@szdziedzic](https://github.com/szdziedzic))
+1 -1
View File
@@ -1,5 +1,5 @@
{
"npmClient": "yarn",
"version": "13.4.0",
"version": "14.2.0",
"$schema": "node_modules/lerna/schemas/lerna-schema.json"
}
+73 -73
View File
@@ -153,7 +153,7 @@ ALIASES
$ eas login
```
_See code: [packages/eas-cli/src/commands/account/login.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/account/login.ts)_
_See code: [packages/eas-cli/src/commands/account/login.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/account/login.ts)_
## `eas account:logout`
@@ -170,7 +170,7 @@ ALIASES
$ eas logout
```
_See code: [packages/eas-cli/src/commands/account/logout.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/account/logout.ts)_
_See code: [packages/eas-cli/src/commands/account/logout.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/account/logout.ts)_
## `eas account:view`
@@ -187,7 +187,7 @@ ALIASES
$ eas whoami
```
_See code: [packages/eas-cli/src/commands/account/view.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/account/view.ts)_
_See code: [packages/eas-cli/src/commands/account/view.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/account/view.ts)_
## `eas analytics [STATUS]`
@@ -201,7 +201,7 @@ DESCRIPTION
display or change analytics settings
```
_See code: [packages/eas-cli/src/commands/analytics.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/analytics.ts)_
_See code: [packages/eas-cli/src/commands/analytics.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/analytics.ts)_
## `eas autocomplete [SHELL]`
@@ -253,7 +253,7 @@ DESCRIPTION
create a branch
```
_See code: [packages/eas-cli/src/commands/branch/create.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/branch/create.ts)_
_See code: [packages/eas-cli/src/commands/branch/create.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/branch/create.ts)_
## `eas branch:delete [NAME]`
@@ -274,7 +274,7 @@ DESCRIPTION
delete a branch
```
_See code: [packages/eas-cli/src/commands/branch/delete.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/branch/delete.ts)_
_See code: [packages/eas-cli/src/commands/branch/delete.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/branch/delete.ts)_
## `eas branch:list`
@@ -294,7 +294,7 @@ DESCRIPTION
list all branches
```
_See code: [packages/eas-cli/src/commands/branch/list.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/branch/list.ts)_
_See code: [packages/eas-cli/src/commands/branch/list.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/branch/list.ts)_
## `eas branch:rename`
@@ -314,7 +314,7 @@ DESCRIPTION
rename a branch
```
_See code: [packages/eas-cli/src/commands/branch/rename.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/branch/rename.ts)_
_See code: [packages/eas-cli/src/commands/branch/rename.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/branch/rename.ts)_
## `eas branch:view [NAME]`
@@ -337,7 +337,7 @@ DESCRIPTION
view a branch
```
_See code: [packages/eas-cli/src/commands/branch/view.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/branch/view.ts)_
_See code: [packages/eas-cli/src/commands/branch/view.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/branch/view.ts)_
## `eas build`
@@ -374,7 +374,7 @@ DESCRIPTION
start a build
```
_See code: [packages/eas-cli/src/commands/build/index.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/build/index.ts)_
_See code: [packages/eas-cli/src/commands/build/index.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/build/index.ts)_
## `eas build:cancel [BUILD_ID]`
@@ -393,7 +393,7 @@ DESCRIPTION
cancel a build
```
_See code: [packages/eas-cli/src/commands/build/cancel.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/build/cancel.ts)_
_See code: [packages/eas-cli/src/commands/build/cancel.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/build/cancel.ts)_
## `eas build:configure`
@@ -410,7 +410,7 @@ DESCRIPTION
configure the project to support EAS Build
```
_See code: [packages/eas-cli/src/commands/build/configure.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/build/configure.ts)_
_See code: [packages/eas-cli/src/commands/build/configure.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/build/configure.ts)_
## `eas build:delete [BUILD_ID]`
@@ -429,7 +429,7 @@ DESCRIPTION
delete a build
```
_See code: [packages/eas-cli/src/commands/build/delete.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/build/delete.ts)_
_See code: [packages/eas-cli/src/commands/build/delete.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/build/delete.ts)_
## `eas build:inspect`
@@ -464,7 +464,7 @@ DESCRIPTION
inspect the state of the project at specific build stages, useful for troubleshooting
```
_See code: [packages/eas-cli/src/commands/build/inspect.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/build/inspect.ts)_
_See code: [packages/eas-cli/src/commands/build/inspect.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/build/inspect.ts)_
## `eas build:list`
@@ -514,7 +514,7 @@ DESCRIPTION
list all builds for your project
```
_See code: [packages/eas-cli/src/commands/build/list.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/build/list.ts)_
_See code: [packages/eas-cli/src/commands/build/list.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/build/list.ts)_
## `eas build:resign`
@@ -543,7 +543,7 @@ DESCRIPTION
re-sign a build archive
```
_See code: [packages/eas-cli/src/commands/build/resign.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/build/resign.ts)_
_See code: [packages/eas-cli/src/commands/build/resign.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/build/resign.ts)_
## `eas build:run`
@@ -569,7 +569,7 @@ DESCRIPTION
run simulator/emulator builds from eas-cli
```
_See code: [packages/eas-cli/src/commands/build/run.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/build/run.ts)_
_See code: [packages/eas-cli/src/commands/build/run.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/build/run.ts)_
## `eas build:submit`
@@ -619,7 +619,7 @@ DESCRIPTION
get the latest version from EAS servers
```
_See code: [packages/eas-cli/src/commands/build/version/get.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/build/version/get.ts)_
_See code: [packages/eas-cli/src/commands/build/version/get.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/build/version/get.ts)_
## `eas build:version:set`
@@ -638,7 +638,7 @@ DESCRIPTION
update version of an app
```
_See code: [packages/eas-cli/src/commands/build/version/set.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/build/version/set.ts)_
_See code: [packages/eas-cli/src/commands/build/version/set.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/build/version/set.ts)_
## `eas build:version:sync`
@@ -657,7 +657,7 @@ DESCRIPTION
update a version in native code with a value stored on EAS servers
```
_See code: [packages/eas-cli/src/commands/build/version/sync.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/build/version/sync.ts)_
_See code: [packages/eas-cli/src/commands/build/version/sync.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/build/version/sync.ts)_
## `eas build:view [BUILD_ID]`
@@ -674,7 +674,7 @@ DESCRIPTION
view a build for your project
```
_See code: [packages/eas-cli/src/commands/build/view.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/build/view.ts)_
_See code: [packages/eas-cli/src/commands/build/view.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/build/view.ts)_
## `eas channel:create [NAME]`
@@ -695,7 +695,7 @@ DESCRIPTION
create a channel
```
_See code: [packages/eas-cli/src/commands/channel/create.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/channel/create.ts)_
_See code: [packages/eas-cli/src/commands/channel/create.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/channel/create.ts)_
## `eas channel:edit [NAME]`
@@ -717,7 +717,7 @@ DESCRIPTION
point a channel at a new branch
```
_See code: [packages/eas-cli/src/commands/channel/edit.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/channel/edit.ts)_
_See code: [packages/eas-cli/src/commands/channel/edit.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/channel/edit.ts)_
## `eas channel:list`
@@ -737,7 +737,7 @@ DESCRIPTION
list all channels
```
_See code: [packages/eas-cli/src/commands/channel/list.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/channel/list.ts)_
_See code: [packages/eas-cli/src/commands/channel/list.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/channel/list.ts)_
## `eas channel:pause [NAME]`
@@ -759,7 +759,7 @@ DESCRIPTION
pause a channel to stop it from sending updates
```
_See code: [packages/eas-cli/src/commands/channel/pause.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/channel/pause.ts)_
_See code: [packages/eas-cli/src/commands/channel/pause.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/channel/pause.ts)_
## `eas channel:resume [NAME]`
@@ -781,7 +781,7 @@ DESCRIPTION
resume a channel to start sending updates
```
_See code: [packages/eas-cli/src/commands/channel/resume.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/channel/resume.ts)_
_See code: [packages/eas-cli/src/commands/channel/resume.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/channel/resume.ts)_
## `eas channel:rollout [CHANNEL]`
@@ -814,7 +814,7 @@ DESCRIPTION
Roll a new branch out on a channel incrementally.
```
_See code: [packages/eas-cli/src/commands/channel/rollout.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/channel/rollout.ts)_
_See code: [packages/eas-cli/src/commands/channel/rollout.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/channel/rollout.ts)_
## `eas channel:view [NAME]`
@@ -837,7 +837,7 @@ DESCRIPTION
view a channel
```
_See code: [packages/eas-cli/src/commands/channel/view.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/channel/view.ts)_
_See code: [packages/eas-cli/src/commands/channel/view.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/channel/view.ts)_
## `eas config`
@@ -858,7 +858,7 @@ DESCRIPTION
display project configuration (app.json + eas.json)
```
_See code: [packages/eas-cli/src/commands/config.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/config.ts)_
_See code: [packages/eas-cli/src/commands/config.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/config.ts)_
## `eas credentials`
@@ -875,7 +875,7 @@ DESCRIPTION
manage credentials
```
_See code: [packages/eas-cli/src/commands/credentials/index.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/credentials/index.ts)_
_See code: [packages/eas-cli/src/commands/credentials/index.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/credentials/index.ts)_
## `eas credentials:configure-build`
@@ -893,7 +893,7 @@ DESCRIPTION
Set up credentials for building your project.
```
_See code: [packages/eas-cli/src/commands/credentials/configure-build.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/credentials/configure-build.ts)_
_See code: [packages/eas-cli/src/commands/credentials/configure-build.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/credentials/configure-build.ts)_
## `eas device:create`
@@ -907,7 +907,7 @@ DESCRIPTION
register new Apple Devices to use for internal distribution
```
_See code: [packages/eas-cli/src/commands/device/create.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/device/create.ts)_
_See code: [packages/eas-cli/src/commands/device/create.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/device/create.ts)_
## `eas device:delete`
@@ -927,7 +927,7 @@ DESCRIPTION
remove a registered device from your account
```
_See code: [packages/eas-cli/src/commands/device/delete.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/device/delete.ts)_
_See code: [packages/eas-cli/src/commands/device/delete.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/device/delete.ts)_
## `eas device:list`
@@ -948,7 +948,7 @@ DESCRIPTION
list all registered devices for your account
```
_See code: [packages/eas-cli/src/commands/device/list.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/device/list.ts)_
_See code: [packages/eas-cli/src/commands/device/list.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/device/list.ts)_
## `eas device:rename`
@@ -969,7 +969,7 @@ DESCRIPTION
rename a registered device
```
_See code: [packages/eas-cli/src/commands/device/rename.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/device/rename.ts)_
_See code: [packages/eas-cli/src/commands/device/rename.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/device/rename.ts)_
## `eas device:view [UDID]`
@@ -983,7 +983,7 @@ DESCRIPTION
view a device for your project
```
_See code: [packages/eas-cli/src/commands/device/view.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/device/view.ts)_
_See code: [packages/eas-cli/src/commands/device/view.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/device/view.ts)_
## `eas diagnostics`
@@ -997,7 +997,7 @@ DESCRIPTION
display environment info
```
_See code: [packages/eas-cli/src/commands/diagnostics.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/diagnostics.ts)_
_See code: [packages/eas-cli/src/commands/diagnostics.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/diagnostics.ts)_
## `eas env:create [ENVIRONMENT]`
@@ -1026,7 +1026,7 @@ DESCRIPTION
create an environment variable for the current project or account
```
_See code: [packages/eas-cli/src/commands/env/create.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/env/create.ts)_
_See code: [packages/eas-cli/src/commands/env/create.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/env/create.ts)_
## `eas env:delete [ENVIRONMENT]`
@@ -1050,7 +1050,7 @@ DESCRIPTION
delete an environment variable for the current project or account
```
_See code: [packages/eas-cli/src/commands/env/delete.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/env/delete.ts)_
_See code: [packages/eas-cli/src/commands/env/delete.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/env/delete.ts)_
## `eas env:exec ENVIRONMENT BASH_COMMAND`
@@ -1071,7 +1071,7 @@ DESCRIPTION
execute a command with environment variables from the selected environment
```
_See code: [packages/eas-cli/src/commands/env/exec.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/env/exec.ts)_
_See code: [packages/eas-cli/src/commands/env/exec.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/env/exec.ts)_
## `eas env:get [ENVIRONMENT]`
@@ -1096,7 +1096,7 @@ DESCRIPTION
view an environment variable for the current project or account
```
_See code: [packages/eas-cli/src/commands/env/get.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/env/get.ts)_
_See code: [packages/eas-cli/src/commands/env/get.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/env/get.ts)_
## `eas env:list [ENVIRONMENT]`
@@ -1121,7 +1121,7 @@ DESCRIPTION
list environment variables for the current project or account
```
_See code: [packages/eas-cli/src/commands/env/list.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/env/list.ts)_
_See code: [packages/eas-cli/src/commands/env/list.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/env/list.ts)_
## `eas env:pull [ENVIRONMENT]`
@@ -1144,7 +1144,7 @@ DESCRIPTION
pull environment variables for the selected environment to .env file
```
_See code: [packages/eas-cli/src/commands/env/pull.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/env/pull.ts)_
_See code: [packages/eas-cli/src/commands/env/pull.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/env/pull.ts)_
## `eas env:push [ENVIRONMENT]`
@@ -1165,7 +1165,7 @@ DESCRIPTION
push environment variables from .env file to the selected environment
```
_See code: [packages/eas-cli/src/commands/env/push.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/env/push.ts)_
_See code: [packages/eas-cli/src/commands/env/push.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/env/push.ts)_
## `eas env:update [ENVIRONMENT]`
@@ -1196,7 +1196,7 @@ DESCRIPTION
update an environment variable on the current project or account
```
_See code: [packages/eas-cli/src/commands/env/update.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/env/update.ts)_
_See code: [packages/eas-cli/src/commands/env/update.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/env/update.ts)_
## `eas help [COMMAND]`
@@ -1304,7 +1304,7 @@ DESCRIPTION
validate the local store configuration
```
_See code: [packages/eas-cli/src/commands/metadata/lint.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/metadata/lint.ts)_
_See code: [packages/eas-cli/src/commands/metadata/lint.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/metadata/lint.ts)_
## `eas metadata:pull`
@@ -1321,7 +1321,7 @@ DESCRIPTION
generate the local store configuration from the app stores
```
_See code: [packages/eas-cli/src/commands/metadata/pull.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/metadata/pull.ts)_
_See code: [packages/eas-cli/src/commands/metadata/pull.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/metadata/pull.ts)_
## `eas metadata:push`
@@ -1338,7 +1338,7 @@ DESCRIPTION
sync the local store configuration to the app stores
```
_See code: [packages/eas-cli/src/commands/metadata/push.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/metadata/push.ts)_
_See code: [packages/eas-cli/src/commands/metadata/push.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/metadata/push.ts)_
## `eas onboarding [TARGET_PROJECT_DIRECTORY]`
@@ -1368,7 +1368,7 @@ DESCRIPTION
open the project page in a web browser
```
_See code: [packages/eas-cli/src/commands/open.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/open.ts)_
_See code: [packages/eas-cli/src/commands/open.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/open.ts)_
## `eas project:info`
@@ -1382,7 +1382,7 @@ DESCRIPTION
information about the current project
```
_See code: [packages/eas-cli/src/commands/project/info.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/project/info.ts)_
_See code: [packages/eas-cli/src/commands/project/info.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/project/info.ts)_
## `eas project:init`
@@ -1405,7 +1405,7 @@ ALIASES
$ eas init
```
_See code: [packages/eas-cli/src/commands/project/init.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/project/init.ts)_
_See code: [packages/eas-cli/src/commands/project/init.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/project/init.ts)_
## `eas project:onboarding [TARGET_PROJECT_DIRECTORY]`
@@ -1423,7 +1423,7 @@ ALIASES
$ eas onboarding
```
_See code: [packages/eas-cli/src/commands/project/onboarding.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/project/onboarding.ts)_
_See code: [packages/eas-cli/src/commands/project/onboarding.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/project/onboarding.ts)_
## `eas submit`
@@ -1454,7 +1454,7 @@ ALIASES
$ eas build:submit
```
_See code: [packages/eas-cli/src/commands/submit.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/submit.ts)_
_See code: [packages/eas-cli/src/commands/submit.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/submit.ts)_
## `eas update`
@@ -1496,7 +1496,7 @@ DESCRIPTION
publish an update group
```
_See code: [packages/eas-cli/src/commands/update/index.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/update/index.ts)_
_See code: [packages/eas-cli/src/commands/update/index.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/update/index.ts)_
## `eas update:configure`
@@ -1516,7 +1516,7 @@ DESCRIPTION
configure the project to support EAS Update
```
_See code: [packages/eas-cli/src/commands/update/configure.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/update/configure.ts)_
_See code: [packages/eas-cli/src/commands/update/configure.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/update/configure.ts)_
## `eas update:delete GROUPID`
@@ -1537,7 +1537,7 @@ DESCRIPTION
delete all the updates in an update group
```
_See code: [packages/eas-cli/src/commands/update/delete.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/update/delete.ts)_
_See code: [packages/eas-cli/src/commands/update/delete.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/update/delete.ts)_
## `eas update:edit [GROUPID]`
@@ -1561,7 +1561,7 @@ DESCRIPTION
edit all the updates in an update group
```
_See code: [packages/eas-cli/src/commands/update/edit.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/update/edit.ts)_
_See code: [packages/eas-cli/src/commands/update/edit.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/update/edit.ts)_
## `eas update:list`
@@ -1583,7 +1583,7 @@ DESCRIPTION
view the recent updates
```
_See code: [packages/eas-cli/src/commands/update/list.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/update/list.ts)_
_See code: [packages/eas-cli/src/commands/update/list.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/update/list.ts)_
## `eas update:republish`
@@ -1615,7 +1615,7 @@ DESCRIPTION
roll back to an existing update
```
_See code: [packages/eas-cli/src/commands/update/republish.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/update/republish.ts)_
_See code: [packages/eas-cli/src/commands/update/republish.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/update/republish.ts)_
## `eas update:roll-back-to-embedded`
@@ -1623,12 +1623,11 @@ roll back to the embedded update
```
USAGE
$ eas update:roll-back-to-embedded [--branch <value>] [--channel <value>] [--message <value>] [-p android|ios|all] [--auto]
[--private-key-path <value>] [--json --non-interactive]
$ eas update:roll-back-to-embedded [--branch <value>] [--channel <value>] [--runtime-version <value>] [--message <value>] [-p
android|ios|all] [--private-key-path <value>] [--json --non-interactive]
FLAGS
-p, --platform=(android|ios|all) [default: all]
--auto Use the current git branch and commit message for the EAS branch and update message
--branch=<value> Branch to publish the rollback to embedded update group on
--channel=<value> Channel that the published rollback to embedded update should affect
--json Enable JSON output, non-JSON messages will be printed to stderr.
@@ -1638,12 +1637,13 @@ FLAGS
expo-updates' configuration. Defaults to a file named "private-key.pem" in the
certificate's directory. Only relevant if you are using code signing:
https://docs.expo.dev/eas-update/code-signing/
--runtime-version=<value> Runtime version that the rollback to embedded update should target
DESCRIPTION
roll back to the embedded update
```
_See code: [packages/eas-cli/src/commands/update/roll-back-to-embedded.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/update/roll-back-to-embedded.ts)_
_See code: [packages/eas-cli/src/commands/update/roll-back-to-embedded.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/update/roll-back-to-embedded.ts)_
## `eas update:rollback`
@@ -1663,7 +1663,7 @@ DESCRIPTION
roll back to an embedded update or an existing update
```
_See code: [packages/eas-cli/src/commands/update/rollback.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/update/rollback.ts)_
_See code: [packages/eas-cli/src/commands/update/rollback.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/update/rollback.ts)_
## `eas update:view GROUPID`
@@ -1683,7 +1683,7 @@ DESCRIPTION
update group details
```
_See code: [packages/eas-cli/src/commands/update/view.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/update/view.ts)_
_See code: [packages/eas-cli/src/commands/update/view.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/update/view.ts)_
## `eas webhook:create`
@@ -1704,7 +1704,7 @@ DESCRIPTION
create a webhook
```
_See code: [packages/eas-cli/src/commands/webhook/create.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/webhook/create.ts)_
_See code: [packages/eas-cli/src/commands/webhook/create.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/webhook/create.ts)_
## `eas webhook:delete [ID]`
@@ -1724,7 +1724,7 @@ DESCRIPTION
delete a webhook
```
_See code: [packages/eas-cli/src/commands/webhook/delete.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/webhook/delete.ts)_
_See code: [packages/eas-cli/src/commands/webhook/delete.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/webhook/delete.ts)_
## `eas webhook:list`
@@ -1742,7 +1742,7 @@ DESCRIPTION
list webhooks
```
_See code: [packages/eas-cli/src/commands/webhook/list.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/webhook/list.ts)_
_See code: [packages/eas-cli/src/commands/webhook/list.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/webhook/list.ts)_
## `eas webhook:update`
@@ -1764,7 +1764,7 @@ DESCRIPTION
update a webhook
```
_See code: [packages/eas-cli/src/commands/webhook/update.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/webhook/update.ts)_
_See code: [packages/eas-cli/src/commands/webhook/update.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/webhook/update.ts)_
## `eas webhook:view ID`
@@ -1781,7 +1781,7 @@ DESCRIPTION
view a webhook
```
_See code: [packages/eas-cli/src/commands/webhook/view.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/webhook/view.ts)_
_See code: [packages/eas-cli/src/commands/webhook/view.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/webhook/view.ts)_
## `eas whoami`
@@ -1816,7 +1816,7 @@ DESCRIPTION
create a new workflow configuration YAML file
```
_See code: [packages/eas-cli/src/commands/workflow/create.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/workflow/create.ts)_
_See code: [packages/eas-cli/src/commands/workflow/create.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/workflow/create.ts)_
## `eas workflow:run [FILE]`
@@ -1836,7 +1836,7 @@ DESCRIPTION
Run an EAS workflow
```
_See code: [packages/eas-cli/src/commands/workflow/run.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/workflow/run.ts)_
_See code: [packages/eas-cli/src/commands/workflow/run.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/workflow/run.ts)_
## `eas workflow:validate PATH`
@@ -1856,5 +1856,5 @@ DESCRIPTION
validate a workflow configuration yaml file
```
_See code: [packages/eas-cli/src/commands/workflow/validate.ts](https://github.com/expo/eas-cli/blob/v13.4.0/packages/eas-cli/src/commands/workflow/validate.ts)_
_See code: [packages/eas-cli/src/commands/workflow/validate.ts](https://github.com/expo/eas-cli/blob/v14.2.0/packages/eas-cli/src/commands/workflow/validate.ts)_
<!-- commandsstop -->
+123 -35
View File
@@ -4201,6 +4201,12 @@
"inputFields": null,
"interfaces": null,
"enumValues": [
{
"name": "PROFILE_IMAGE_UPLOAD",
"description": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "WORKFLOWS_PROJECT_SOURCES",
"description": null,
@@ -9438,7 +9444,7 @@
}
},
"isDeprecated": true,
"deprecationReason": "Use 'privacySetting' instead."
"deprecationReason": "No longer supported"
},
{
"name": "privacySetting",
@@ -9453,8 +9459,8 @@
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
"isDeprecated": true,
"deprecationReason": "No longer supported"
},
{
"name": "published",
@@ -11450,22 +11456,6 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "privacy",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "ENUM",
"name": "AppPrivacy",
"ofType": null
}
},
"defaultValue": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "projectName",
"description": null,
@@ -13397,6 +13387,23 @@
"enumValues": null,
"possibleTypes": null
},
{
"kind": "ENUM",
"name": "AppUploadSessionType",
"description": null,
"fields": null,
"inputFields": null,
"interfaces": null,
"enumValues": [
{
"name": "PROFILE_IMAGE_UPLOAD",
"description": null,
"isDeprecated": false,
"deprecationReason": null
}
],
"possibleTypes": null
},
{
"kind": "OBJECT",
"name": "AppVersion",
@@ -13693,22 +13700,6 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "privacy",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "ENUM",
"name": "AppPrivacy",
"ofType": null
}
},
"defaultValue": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "projectName",
"description": null,
@@ -18070,6 +18061,18 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "fingerprint",
"description": null,
"args": [],
"type": {
"kind": "OBJECT",
"name": "Fingerprint",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "gitCommitHash",
"description": null,
@@ -18446,6 +18449,18 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "resolvedEnvironment",
"description": null,
"args": [],
"type": {
"kind": "ENUM",
"name": "EnvironmentVariableEnvironment",
"ofType": null
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "resourceClass",
"description": "The builder resource class requested by the developer",
@@ -19470,6 +19485,18 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "hasFingerprint",
"description": null,
"type": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
},
"defaultValue": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "platform",
"description": null,
@@ -19585,6 +19612,18 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "hasFingerprint",
"description": null,
"type": {
"kind": "SCALAR",
"name": "Boolean",
"ofType": null
},
"defaultValue": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "platforms",
"description": null,
@@ -47725,6 +47764,55 @@
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "createAppScopedUploadSession",
"description": "Create an Upload Session for a specific app",
"args": [
{
"name": "appID",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "ID",
"ofType": null
}
},
"defaultValue": null,
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "type",
"description": null,
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "ENUM",
"name": "AppUploadSessionType",
"ofType": null
}
},
"defaultValue": null,
"isDeprecated": false,
"deprecationReason": null
}
],
"type": {
"kind": "NON_NULL",
"name": null,
"ofType": {
"kind": "SCALAR",
"name": "JSONObject",
"ofType": null
}
},
"isDeprecated": false,
"deprecationReason": null
},
{
"name": "createUploadSession",
"description": "Create an Upload Session",
+18 -16
View File
@@ -1,34 +1,34 @@
{
"name": "eas-cli",
"description": "EAS command line tool",
"version": "13.4.0",
"version": "14.2.0",
"author": "Expo <[email protected]>",
"bin": {
"eas": "./bin/run"
},
"bugs": "https://github.com/expo/eas-cli/issues",
"dependencies": {
"@expo/apple-utils": "2.1.0",
"@expo/apple-utils": "2.1.5",
"@expo/code-signing-certificates": "0.0.5",
"@expo/config": "9.0.4",
"@expo/config-plugins": "8.0.10",
"@expo/eas-build-job": "1.0.149",
"@expo/eas-json": "13.4.0",
"@expo/env": "^0.3.0",
"@expo/config": "10.0.6",
"@expo/config-plugins": "9.0.12",
"@expo/eas-build-job": "1.0.156",
"@expo/eas-json": "14.2.0",
"@expo/env": "^0.4.0",
"@expo/json-file": "8.3.3",
"@expo/logger": "1.0.117",
"@expo/multipart-body-parser": "1.1.0",
"@expo/osascript": "2.1.3",
"@expo/package-manager": "1.5.2",
"@expo/pkcs12": "0.1.2",
"@expo/plist": "0.1.3",
"@expo/multipart-body-parser": "2.0.0",
"@expo/osascript": "2.1.4",
"@expo/package-manager": "1.6.1",
"@expo/pkcs12": "0.1.3",
"@expo/plist": "0.2.0",
"@expo/plugin-help": "5.1.23",
"@expo/plugin-warn-if-update-available": "2.5.1",
"@expo/prebuild-config": "7.0.9",
"@expo/prebuild-config": "8.0.17",
"@expo/results": "1.0.0",
"@expo/rudder-sdk-node": "1.1.1",
"@expo/spawn-async": "1.7.2",
"@expo/steps": "1.0.150",
"@expo/steps": "1.0.156",
"@expo/timeago.js": "1.0.0",
"@oclif/core": "^1.26.2",
"@oclif/plugin-autocomplete": "^2.3.10",
@@ -41,6 +41,7 @@
"chalk": "4.1.2",
"cli-progress": "3.12.0",
"dateformat": "4.6.3",
"diff": "7.0.0",
"dotenv": "16.3.1",
"env-paths": "2.2.0",
"envinfo": "7.11.0",
@@ -64,7 +65,7 @@
"mime": "3.0.0",
"minimatch": "5.1.2",
"minizlib": "3.0.1",
"nanoid": "3.3.4",
"nanoid": "3.3.8",
"node-fetch": "2.6.7",
"node-forge": "1.3.1",
"nullthrows": "1.1.1",
@@ -96,6 +97,7 @@
"@graphql-codegen/typescript-operations": "4.0.1",
"@types/cli-progress": "3.11.5",
"@types/dateformat": "3.0.1",
"@types/diff": "6.0.0",
"@types/envinfo": "7.8.3",
"@types/express": "4.17.15",
"@types/fs-extra": "11.0.4",
@@ -192,7 +194,7 @@
},
"warn-if-update-available": {
"timeoutInDays": 0.5,
"message": "<%= chalk('★') %> <%= chalk.bold(config.name + '@' + latest) %> <%= chalk.bold('is now available.') %>\n<%= chalk.dim('To upgrade, run ') %><%= chalk.dim(chalk.bold('npm install -g eas-cli')) %><%= chalk.dim('.') %>\n<%= chalk.dim('Proceeding with outdated version.') %>\n"
"message": "<%= chalk('★') %> <%= chalk.bold(config.name + '@' + latest) %> <%= chalk.bold('is now available.') %>\n<%= chalk.dim('To upgrade, run:') %>\n<%= chalk.dim(chalk.bold('npm install -g eas-cli')) %>\n<%= chalk.dim('Proceeding with outdated version.') %>\n"
},
"update": {
"node": {
+11 -8
View File
@@ -1,4 +1,5 @@
import chalk from 'chalk';
import { print } from 'graphql';
import gql from 'graphql-tag';
import { BranchNotFoundError } from './utils';
@@ -8,10 +9,11 @@ import { withErrorHandlingAsync } from '../graphql/client';
import {
CreateUpdateBranchForAppMutation,
CreateUpdateBranchForAppMutationVariables,
UpdateBranch,
UpdateBranchBasicInfoFragment,
UpdateBranchFragment,
} from '../graphql/generated';
import { BranchQuery } from '../graphql/queries/BranchQuery';
import { UpdateBranchBasicInfoFragmentNode } from '../graphql/types/UpdateBranchBasicInfo';
import Log from '../log';
import { formatBranch, getBranchDescription } from '../update/utils';
import { printJsonOnlyOutput } from '../utils/json';
@@ -126,7 +128,7 @@ function renderPageOfBranches(
export async function createUpdateBranchOnAppAsync(
graphqlClient: ExpoGraphqlClient,
{ appId, name }: CreateUpdateBranchForAppMutationVariables
): Promise<Pick<UpdateBranch, 'id' | 'name'>> {
): Promise<UpdateBranchBasicInfoFragment> {
const result = await withErrorHandlingAsync(
graphqlClient
.mutation<CreateUpdateBranchForAppMutation, CreateUpdateBranchForAppMutationVariables>(
@@ -135,15 +137,17 @@ export async function createUpdateBranchOnAppAsync(
updateBranch {
createUpdateBranchForApp(appId: $appId, name: $name) {
id
name
...UpdateBranchBasicInfoFragment
}
}
}
${print(UpdateBranchBasicInfoFragmentNode)}
`,
{
appId,
name,
}
},
{ additionalTypenames: ['UpdateBranch'] }
)
.toPromise()
);
@@ -163,22 +167,21 @@ export async function ensureBranchExistsAsync(
appId: string;
branchName: string;
}
): Promise<{ branchId: string; createdBranch: boolean }> {
): Promise<{ branch: UpdateBranchBasicInfoFragment; createdBranch: boolean }> {
try {
const updateBranch = await BranchQuery.getBranchByNameAsync(graphqlClient, {
appId,
name: branchName,
});
const { id } = updateBranch;
return { branchId: id, createdBranch: false };
return { branch: updateBranch, createdBranch: false };
} catch (error) {
if (error instanceof BranchNotFoundError) {
const newUpdateBranch = await createUpdateBranchOnAppAsync(graphqlClient, {
appId,
name: branchName,
});
return { branchId: newUpdateBranch.id, createdBranch: true };
return { branch: newUpdateBranch, createdBranch: true };
} else {
throw error;
}
+2 -4
View File
@@ -1,9 +1,7 @@
import { Client } from '../vcs/vcs';
export async function getDefaultBranchNameAsync(vcsClient: Client): Promise<string> {
return (
(await vcsClient.getBranchNameAsync()) || `branch-${Math.random().toString(36).substring(2, 4)}`
);
export async function getDefaultBranchNameAsync(vcsClient: Client): Promise<string | null> {
return await vcsClient.getBranchNameAsync();
}
export class BranchNotFoundError extends Error {
+15 -6
View File
@@ -20,7 +20,11 @@ import { getNextVersionCode } from '../../project/android/versions';
import { resolveWorkflowAsync } from '../../project/workflow';
import { Client } from '../../vcs/vcs';
import { updateAppJsonConfigAsync } from '../utils/appJson';
import { bumpAppVersionAsync, ensureStaticConfigExists } from '../utils/version';
import {
bumpAppVersionAsync,
ensureStaticConfigExists,
getVersionConfigTarget,
} from '../utils/version';
export enum BumpStrategy {
APP_VERSION,
@@ -53,9 +57,11 @@ export async function bumpVersionAsync({
await bumpVersionInAppJsonAsync({ bumpStrategy, projectDir, exp });
Log.log('Updated versions in app.json');
const { versionGetter } = getVersionConfigTarget({ exp, platform: Platform.ANDROID });
const version = versionGetter(exp);
await updateNativeVersionsAsync({
projectDir,
version: exp.version,
version,
versionCode: exp.android?.versionCode,
});
Log.log('Synchronized versions with build gradle');
@@ -79,7 +85,7 @@ export async function bumpVersionInAppJsonAsync({
if (bumpStrategy === BumpStrategy.APP_VERSION) {
const appVersion = AndroidConfig.Version.getVersionName(exp) ?? '1.0.0';
await bumpAppVersionAsync({ appVersion, projectDir, exp });
await bumpAppVersionAsync({ appVersion, projectDir, exp, platform: Platform.ANDROID });
} else {
const versionCode = AndroidConfig.Version.getVersionCode(exp);
const bumpedVersionCode = getNextVersionCode(versionCode);
@@ -118,9 +124,11 @@ export async function maybeResolveVersionsAsync(
return {};
}
} else {
const { versionGetter } = getVersionConfigTarget({ exp, platform: Platform.ANDROID });
const appVersion = versionGetter(exp);
return {
appBuildVersion: String(AndroidConfig.Version.getVersionCode(exp)),
appVersion: exp.version,
appVersion,
};
}
}
@@ -202,6 +210,7 @@ export async function resolveRemoteVersionCodeAsync(
applicationId
);
const { versionGetter } = getVersionConfigTarget({ exp, platform: Platform.ANDROID });
const localVersions = await maybeResolveVersionsAsync(projectDir, exp, buildProfile, vcsClient);
let currentBuildVersion: string;
if (remoteVersions?.buildVersion) {
@@ -230,7 +239,7 @@ export async function resolveRemoteVersionCodeAsync(
appId: projectId,
platform: AppPlatform.Android,
applicationIdentifier: applicationId,
storeVersion: localVersions.appVersion ?? exp.version ?? '1.0.0',
storeVersion: localVersions.appVersion ?? versionGetter(exp) ?? '1.0.0',
buildVersion: currentBuildVersion,
runtimeVersion:
(await Updates.getRuntimeVersionNullableAsync(projectDir, exp, Platform.ANDROID)) ??
@@ -254,7 +263,7 @@ export async function resolveRemoteVersionCodeAsync(
appId: projectId,
platform: AppPlatform.Android,
applicationIdentifier: applicationId,
storeVersion: localVersions.appVersion ?? exp.version ?? '1.0.0',
storeVersion: localVersions.appVersion ?? versionGetter(exp) ?? '1.0.0',
buildVersion: String(nextBuildVersion),
runtimeVersion:
(await Updates.getRuntimeVersionNullableAsync(projectDir, exp, Platform.ANDROID)) ??
@@ -5,7 +5,6 @@ import { vol } from 'memfs';
import os from 'os';
import type { XCBuildConfiguration } from 'xcode';
import { learnMore } from '../../../log';
import { readPlistAsync } from '../../../utils/plist';
import { resolveVcsClient } from '../../../vcs';
import {
@@ -301,27 +300,6 @@ describe(readShortVersionAsync, () => {
);
expect(buildNumber).toBe('1.0.0');
});
it('fails when build number is invalid', async () => {
const exp = initBareWorkflowProject({
appVersion: '$(CURRENT_PROJECT_VERSION)',
});
await expect(
readShortVersionAsync(
'/app',
exp,
{
CURRENT_PROJECT_VERSION: '0.0.7.1.028',
},
vcsClient
)
).rejects.toThrowError(
`The required format for "CFBundleShortVersionString" in Info.plist is one to three period-separated integers, such as 10.14.1. The string can only contain numeric characters (0-9) and periods. Current value: 0.0.7.1.028. Edit the "CFBundleShortVersionString" in your Info.plist to match the required format. ${learnMore(
'https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleshortversionstring'
)}`
);
});
});
describe('managed project', () => {
+17 -9
View File
@@ -21,7 +21,11 @@ import uniqBy from '../../utils/expodash/uniqBy';
import { readPlistAsync, writePlistAsync } from '../../utils/plist';
import { Client } from '../../vcs/vcs';
import { updateAppJsonConfigAsync } from '../utils/appJson';
import { bumpAppVersionAsync, ensureStaticConfigExists } from '../utils/version';
import {
bumpAppVersionAsync,
ensureStaticConfigExists,
getVersionConfigTarget,
} from '../utils/version';
const SHORT_VERSION_REGEX = /^\d+(\.\d+){0,2}$/;
@@ -48,9 +52,11 @@ export async function bumpVersionAsync({
ensureStaticConfigExists(projectDir);
await bumpVersionInAppJsonAsync({ bumpStrategy, projectDir, exp });
Log.log('Updated versions in app.json');
const { versionGetter } = getVersionConfigTarget({ exp, platform: Platform.IOS });
const version = versionGetter(exp);
await updateNativeVersionsAsync({
projectDir,
version: exp.version,
version,
buildNumber: exp.ios?.buildNumber,
targets,
});
@@ -73,7 +79,7 @@ export async function bumpVersionInAppJsonAsync({
Log.addNewLineIfNone();
if (bumpStrategy === BumpStrategy.APP_VERSION) {
const appVersion = IOSConfig.Version.getVersion(exp);
await bumpAppVersionAsync({ appVersion, projectDir, exp });
await bumpAppVersionAsync({ appVersion, projectDir, exp, platform: Platform.IOS });
} else {
const buildNumber = IOSConfig.Version.getBuildNumber(exp);
if (isValidBuildNumber(buildNumber)) {
@@ -109,14 +115,14 @@ function validateShortVersion({
}): void {
if (shortVersion && !SHORT_VERSION_REGEX.test(shortVersion)) {
if (workflow === Workflow.MANAGED) {
throw new Error(
`The required format for "version" field from app.json/app.config.ts is one to three period-separated integers, such as 10.14.1. The string can only contain numeric characters (0-9) and periods. Current value: ${shortVersion}. Edit the "version" field in your app.json/app.config.ts to match the required format. ${learnMore(
Log.warn(
`The required format for "version" field from app.json/app.config.ts for App Store iOS builds is one to three period-separated integers, such as 10.14.1. The string can only contain numeric characters (0-9) and periods. Current value: ${shortVersion}. Edit the "version" field in your app.json/app.config.ts to match the format required by Apple. ${learnMore(
'https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleshortversionstring'
)}`
);
} else {
throw new Error(
`The required format for "CFBundleShortVersionString" in Info.plist is one to three period-separated integers, such as 10.14.1. The string can only contain numeric characters (0-9) and periods. Current value: ${shortVersion}. Edit the "CFBundleShortVersionString" in your Info.plist to match the required format. ${learnMore(
Log.warn(
`The required format for "CFBundleShortVersionString" in Info.plist for App Store iOS builds is one to three period-separated integers, such as 10.14.1. The string can only contain numeric characters (0-9) and periods. Current value: ${shortVersion}. Edit the "CFBundleShortVersionString" in your Info.plist to match the format required by Apple. ${learnMore(
'https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleshortversionstring'
)}`
);
@@ -141,8 +147,10 @@ export async function readShortVersionAsync(
validateShortVersion({ shortVersion, workflow });
return shortVersion;
} else {
validateShortVersion({ shortVersion: exp.version, workflow });
return exp.version;
const { versionGetter } = getVersionConfigTarget({ exp, platform: Platform.IOS });
const shortVersion = versionGetter(exp);
validateShortVersion({ shortVersion, workflow });
return shortVersion;
}
}
+1 -1
View File
@@ -7,7 +7,7 @@ import Log from '../log';
import { ora } from '../ora';
const PLUGIN_PACKAGE_NAME = 'eas-cli-local-build-plugin';
const PLUGIN_PACKAGE_VERSION = '1.0.144';
const PLUGIN_PACKAGE_VERSION = '1.0.152';
export enum LocalBuildMode {
/**
@@ -0,0 +1,148 @@
import { ExpoConfig } from '@expo/config';
import { Platform } from '@expo/eas-build-job';
import { updateAppJsonConfigAsync } from '../appJson';
import { bumpAppVersionAsync, getVersionConfigTarget } from '../version';
jest.mock('../appJson', () => ({
__esModule: true,
updateAppJsonConfigAsync: jest.fn().mockImplementation(
async (
{
exp,
}: {
projectDir: string;
exp: ExpoConfig;
},
modifyConfig: (config: any) => void
) => {
// a mocked implementation that only mutates the config object without writing to disk
modifyConfig(exp);
}
),
}));
describe(bumpAppVersionAsync, () => {
const name = 'test';
const slug = 'test';
const projectDir = '/app';
const mockUpdateAppJsonConfigAsync = updateAppJsonConfigAsync as jest.MockedFunction<
typeof updateAppJsonConfigAsync
>;
it('should bump expo.version for valid semver', async () => {
const appVersion = '1.0.0';
const exp: ExpoConfig = {
name,
slug,
version: appVersion,
};
await bumpAppVersionAsync({ appVersion, projectDir, exp, platform: Platform.IOS });
expect(mockUpdateAppJsonConfigAsync).toHaveBeenCalled();
expect(exp.version).toBe('1.0.1');
});
it('should bump expo.android.version if the expo.android.version exists', async () => {
const exp: ExpoConfig = {
name,
slug,
version: '0.0.0',
android: {
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
version: '1.0.0',
},
ios: {
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
version: '2.0.0',
},
};
await bumpAppVersionAsync({ appVersion: '1.0.0', projectDir, exp, platform: Platform.ANDROID });
expect(mockUpdateAppJsonConfigAsync).toHaveBeenCalled();
expect(exp.version).toBe('0.0.0');
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
expect(exp.android.version).toBe('1.0.1');
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
expect(exp.ios.version).toBe('2.0.0');
});
it('should bump expo.ios.version if the expo.ios.version exists', async () => {
const exp: ExpoConfig = {
name,
slug,
version: '0.0.0',
android: {
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
version: '1.0.0',
},
ios: {
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
version: '2.0.0',
},
};
await bumpAppVersionAsync({ appVersion: '2.0.0', projectDir, exp, platform: Platform.IOS });
expect(mockUpdateAppJsonConfigAsync).toHaveBeenCalled();
expect(exp.version).toBe('0.0.0');
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
expect(exp.android.version).toBe('1.0.0');
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
expect(exp.ios.version).toBe('2.0.1');
});
});
describe(getVersionConfigTarget, () => {
const exp: ExpoConfig = {
name: 'test',
slug: 'test',
version: '0.0.0',
android: {
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
version: '1.0.0',
},
ios: {
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
version: '2.0.0',
},
};
it('should return the correct config target for the android platform', () => {
const { fieldName, versionGetter, versionUpdater } = getVersionConfigTarget({
exp,
platform: Platform.ANDROID,
});
expect(fieldName).toBe('expo.android.version');
expect(versionGetter(exp)).toBe('1.0.0');
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
expect(versionUpdater(exp, '3.3.3').android.version).toBe('3.3.3');
expect(versionUpdater(exp, '0.0.0').version).toBe('0.0.0');
});
it('should return the correct config target for the ios platform', () => {
const { fieldName, versionGetter, versionUpdater } = getVersionConfigTarget({
exp,
platform: Platform.IOS,
});
expect(fieldName).toBe('expo.ios.version');
expect(versionGetter(exp)).toBe('2.0.0');
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
expect(versionUpdater(exp, '3.3.3').ios.version).toBe('3.3.3');
expect(versionUpdater(exp, '0.0.0').version).toBe('0.0.0');
});
it('should return the correct config target for common version', () => {
const exp: ExpoConfig = {
name: 'test',
slug: 'test',
version: '0.0.0',
};
const { fieldName, versionGetter, versionUpdater } = getVersionConfigTarget({
exp,
platform: Platform.IOS,
});
expect(fieldName).toBe('expo.version');
expect(versionGetter(exp)).toBe('0.0.0');
expect(versionUpdater(exp, '3.3.3').version).toBe('3.3.3');
});
});
+58 -3
View File
@@ -1,4 +1,5 @@
import { ExpoConfig, getConfigFilePaths } from '@expo/config';
import { Platform } from '@expo/eas-build-job';
import chalk from 'chalk';
import nullthrows from 'nullthrows';
import semver from 'semver';
@@ -18,21 +19,25 @@ export async function bumpAppVersionAsync({
appVersion,
projectDir,
exp,
platform,
}: {
appVersion: string;
projectDir: string;
exp: ExpoConfig;
platform: Platform;
}): Promise<void> {
const { fieldName, versionUpdater } = getVersionConfigTarget({ exp, platform });
let bumpedAppVersion: string;
if (semver.valid(appVersion)) {
bumpedAppVersion = nullthrows(semver.inc(appVersion, 'patch'));
Log.log(
`Bumping ${chalk.bold('expo.version')} from ${chalk.bold(appVersion)} to ${chalk.bold(
`Bumping ${chalk.bold(fieldName)} from ${chalk.bold(appVersion)} to ${chalk.bold(
bumpedAppVersion
)}`
);
} else {
Log.log(`${chalk.bold('expo.version')} = ${chalk.bold(appVersion)} is not a valid semver`);
Log.log(`${chalk.bold(fieldName)} = ${chalk.bold(appVersion)} is not a valid semver`);
bumpedAppVersion = (
await promptAsync({
type: 'text',
@@ -42,6 +47,56 @@ export async function bumpAppVersionAsync({
).bumpedAppVersion;
}
await updateAppJsonConfigAsync({ projectDir, exp }, config => {
config.version = bumpedAppVersion;
versionUpdater(config, bumpedAppVersion);
});
}
/**
* Get the target version field from ExpoConfig based on the platform.
*/
export function getVersionConfigTarget({
exp,
platform,
}: {
exp: ExpoConfig;
platform: Platform;
}): {
fieldName: string;
versionGetter: (config: ExpoConfig) => string | undefined;
versionUpdater: (config: ExpoConfig, version: string) => ExpoConfig;
} {
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
if (platform === Platform.ANDROID && typeof exp.android?.version === 'string') {
return {
fieldName: 'expo.android.version',
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
versionGetter: config => config.android?.version,
versionUpdater: (config, version) => {
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
config.android = { ...config.android, version };
return config;
},
};
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
} else if (platform === Platform.IOS && typeof exp.ios?.version === 'string') {
return {
fieldName: 'expo.ios.version',
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
versionGetter: config => config.ios?.version,
versionUpdater: (config, version) => {
// @ts-expect-error: Resolve type errors after upgrading `@expo/config`
config.ios = { ...config.ios, version };
return config;
},
};
}
return {
fieldName: 'expo.version',
versionGetter: config => config.version,
versionUpdater: (config, version) => {
config.version = version;
return config;
},
};
}
+10 -6
View File
@@ -27,24 +27,28 @@ export async function checkGoogleServicesFileAsync<T extends Platform>(
if (!googleServicesFilePath) {
return;
}
const googleServicesEnvVar =
ctx.platform === Platform.ANDROID
? ctx.env.GOOGLE_SERVICES_JSON
: ctx.env.GOOGLE_SERVICES_INFO_PLIST;
const rootDir = path.normalize(await ctx.vcsClient.getRootPathAsync());
const absGoogleServicesFilePath = path.resolve(ctx.projectDir, googleServicesFilePath);
if (
(await fs.pathExists(absGoogleServicesFilePath)) &&
(!isInsideDirectory(absGoogleServicesFilePath, rootDir) ||
(await ctx.vcsClient.isFileIgnoredAsync(path.relative(rootDir, absGoogleServicesFilePath))))
(await ctx.vcsClient.isFileIgnoredAsync(
path.relative(rootDir, absGoogleServicesFilePath)
))) &&
!googleServicesEnvVar
) {
Log.warn(
`File specified via "${ctx.platform}.googleServicesFile" field in your app.json is not checked in to your repository and won't be uploaded to the builder.`
);
Log.warn(
`Use EAS Secret to pass all values that you don't want to include in your version control. ${learnMore(
'https://docs.expo.dev/build-reference/variables/#using-secrets-in-environment-variables'
`Use EAS file environment variables with secret or sensitive visibility to pass all values that you don't want to include in your version control to build process. ${learnMore(
'https://docs.expo.dev/eas/environment-variables/#file-environment-variables'
)}`
);
Log.warn(
`If you are using that file for compatibility with the classic build service (expo build) you can silence this warning by setting your build profile's env.GOOGLE_SERVICES_FILE in eas.json to any non-empty string.`
);
Log.newLine();
}
}
+21 -24
View File
@@ -19,7 +19,7 @@ import {
import { BranchQuery, UpdateBranchOnChannelObject } from '../graphql/queries/BranchQuery';
import { ChannelQuery, UpdateChannelObject } from '../graphql/queries/ChannelQuery';
import { UpdateChannelBasicInfoFragmentNode } from '../graphql/types/UpdateChannelBasicInfo';
import Log from '../log';
import Log, { learnMore } from '../log';
import { getDisplayNameForProjectIdAsync } from '../project/projectUtils';
import formatFields from '../utils/formatFields';
import { printJsonOnlyOutput } from '../utils/json';
@@ -303,7 +303,6 @@ export async function doesChannelExistAsync(
}
/**
*
* Creates a channel and links it to a branch with the same name.
*
* @param appId the app ID, also known as the project ID
@@ -319,7 +318,7 @@ export async function createAndLinkChannelAsync(
}: { appId: string; channelName: string; shouldPrintJson?: boolean }
): Promise<ChannelBasicInfo> {
let branchId: string;
let branchMessage: string;
let hasCreatedBranch = false;
try {
const branch = await BranchQuery.getBranchByNameAsync(graphqlClient, {
@@ -327,7 +326,6 @@ export async function createAndLinkChannelAsync(
name: channelName,
});
branchId = branch.id;
branchMessage = `We found a branch with the same name`;
} catch (error) {
if (error instanceof BranchNotFoundError) {
const newBranch = await createUpdateBranchOnAppAsync(graphqlClient, {
@@ -335,7 +333,7 @@ export async function createAndLinkChannelAsync(
name: channelName,
});
branchId = newBranch.id;
branchMessage = `We also went ahead and made a branch with the same name`;
hasCreatedBranch = true;
} else {
throw error;
}
@@ -358,26 +356,25 @@ export async function createAndLinkChannelAsync(
if (shouldPrintJson) {
printJsonOnlyOutput(newChannel);
} else {
const projectDisplayName = await getDisplayNameForProjectIdAsync(graphqlClient, appId);
const learnMoreLink = learnMore('https://docs.expo.dev/eas-update/eas-cli/');
Log.addNewLineIfNone();
Log.withTick(
`Created a new channel on project ${chalk.bold(
await getDisplayNameForProjectIdAsync(graphqlClient, appId)
)}`
);
Log.log(
formatFields([
{ label: 'Name', value: newChannel.name },
{ label: 'ID', value: newChannel.id },
])
);
Log.addNewLineIfNone();
Log.withTick(`${branchMessage} and have pointed the channel at it.`);
Log.log(
formatFields([
{ label: 'Name', value: newChannel.name },
{ label: 'ID', value: branchId },
])
);
if (hasCreatedBranch) {
Log.withTick(
`Created update channel ${chalk.bold(`"${newChannel.name}"`)} and branch ${chalk.bold(
`"${newChannel.name}"`
)} on ${chalk.bold(projectDisplayName)} project. ${learnMoreLink}`
);
} else {
Log.withTick(
`Created update channel ${chalk.bold(`"${newChannel.name}"`)} on ${chalk.bold(
projectDisplayName
)} project and connected it with existing ${chalk.bold(
`"${newChannel.name}"`
)} branch. ${learnMoreLink}`
);
}
}
return newChannel;
}
+9 -1
View File
@@ -38,7 +38,12 @@ export async function fetchBuildsAsync({
}: {
graphqlClient: ExpoGraphqlClient;
projectId: string;
filters?: { statuses?: BuildStatus[]; platform?: RequestedPlatform; profile?: string };
filters?: {
statuses?: BuildStatus[];
platform?: RequestedPlatform;
profile?: string;
hasFingerprint?: boolean;
};
}): Promise<BuildFragment[]> {
let builds: BuildFragment[];
const queryFilters: InputMaybe<BuildFilter> = {};
@@ -48,6 +53,9 @@ export async function fetchBuildsAsync({
if (filters?.profile) {
queryFilters['buildProfile'] = filters.profile;
}
if (filters?.hasFingerprint) {
queryFilters['hasFingerprint'] = filters.hasFingerprint;
}
if (!filters?.statuses) {
builds = await BuildQuery.viewBuildsOnAppAsync(graphqlClient, {
appId: projectId,
@@ -225,7 +225,7 @@ describe(getProjectIdAsync, () => {
jest.mocked(getConfig).mockReturnValue({ exp: { name: 'test', slug: 'test' } } as any);
jest.mocked(modifyConfigAsync).mockResolvedValue({
type: 'success',
config: { expo: { name: 'test', slug: 'test', extra: { eas: { projectId: '2345' } } } },
config: { name: 'test', slug: 'test', extra: { eas: { projectId: '2345' } } },
});
jest
.mocked(fetchOrCreateProjectIDForWriteToConfigWithConfirmationAsync)
@@ -42,7 +42,7 @@ async function ensureEasCliIsNotInDependenciesAsync(projectDir: string): Promise
consoleWarn(`Found ${chalk.bold('eas-cli')} in your project dependencies.`);
}
const maybeRepoRoot = PackageManagerUtils.findWorkspaceRoot(projectDir) ?? projectDir;
const maybeRepoRoot = PackageManagerUtils.resolveWorkspaceRoot(projectDir) ?? projectDir;
if (maybeRepoRoot !== projectDir && (await isEasCliInDependenciesAsync(maybeRepoRoot))) {
printCliVersionWarning = true;
consoleWarn(`Found ${chalk.bold('eas-cli')} in your monorepo dependencies.`);
@@ -12,7 +12,6 @@ import {
getPrivateExpoConfigAsync,
} from '../../../project/expoConfig';
import { fetchOrCreateProjectIDForWriteToConfigWithConfirmationAsync } from '../../../project/fetchOrCreateProjectIDForWriteToConfigWithConfirmationAsync';
import { toAppPrivacy } from '../../../project/projectUtils';
import SessionManager from '../../../user/SessionManager';
import { Actor, getActorUsername } from '../../../user/User';
@@ -197,7 +196,6 @@ export async function validateOrSetProjectIdAsync({
{
accountName: getAccountNameForEASProjectSync(exp, actor),
projectName: exp.slug,
privacy: toAppPrivacy(exp.privacy),
},
{
nonInteractive: options.nonInteractive,
@@ -58,7 +58,7 @@ export default class BranchCreate extends EasCommand {
type: 'text',
name: 'name',
message: 'Provide a branch name:',
initial: await getDefaultBranchNameAsync(vcsClient),
initial: (await getDefaultBranchNameAsync(vcsClient)) ?? undefined,
validate: value => (value ? true : validationMessage),
}));
}
@@ -5,6 +5,7 @@ import { Flags } from '@oclif/core';
import chalk from 'chalk';
import { evaluateConfigWithEnvVarsAsync } from '../../../build/evaluateConfigWithEnvVarsAsync';
import { getVersionConfigTarget } from '../../../build/utils/version';
import EasCommand from '../../../commandUtils/EasCommand';
import { AppVersionMutation } from '../../../graphql/mutations/AppVersionMutation';
import { AppVersionQuery } from '../../../graphql/queries/AppVersionQuery';
@@ -111,6 +112,7 @@ export default class BuildVersionSetView extends EasCommand {
: `What version would you like to initialize it with?`;
Log.log(currentStateMessage);
const { versionGetter } = getVersionConfigTarget({ exp, platform });
const { version } = await promptAsync({
type: platform === Platform.ANDROID ? 'number' : 'text',
name: 'version',
@@ -124,7 +126,7 @@ export default class BuildVersionSetView extends EasCommand {
appId: projectId,
platform: toAppPlatform(platform),
applicationIdentifier,
storeVersion: exp.version ?? '1.0.0',
storeVersion: versionGetter(exp) ?? '1.0.0',
buildVersion: String(version),
runtimeVersion:
(await getRuntimeVersionNullableAsync(projectDir, exp, platform)) ?? undefined,
+11 -20
View File
@@ -158,29 +158,20 @@ export default class EnvExec extends EasCommand {
environment,
});
const secretEnvironmentVariables = environmentVariablesQueryResult.filter(
({ value }) => !value
);
if (secretEnvironmentVariables.length > 0) {
Log.warn(`The following environment variables are secret and cannot be downloaded locally:`);
for (const { name } of secretEnvironmentVariables) {
Log.warn(`- ${name}`);
}
Log.warn('Proceeding with the rest of the environment variables.');
Log.newLine();
}
const nonSecretEnvironmentVariables = environmentVariablesQueryResult.filter(
({ value }) => !!value
);
if (nonSecretEnvironmentVariables.length === 0) {
throw new Error('No readable environment variables found for the selected environment.');
}
Log.log(
`Loaded environment variables for the selected environment "${environment.toLowerCase()}":`
);
for (const { name } of nonSecretEnvironmentVariables) {
Log.log(`- ${name}`);
if (nonSecretEnvironmentVariables.length > 0) {
Log.log(
`Environment variables with visibility "Plain text" and "Sensitive" loaded from the "${environment.toLowerCase()}" environment on EAS: ${nonSecretEnvironmentVariables
.map(e => e.name)
.join(', ')}.`
);
} else {
Log.log(
`No environment variables with visibility "Plain text" and "Sensitive" found for the "${environment.toLowerCase()}" environment on EAS servers.`
);
}
Log.newLine();
+7 -7
View File
@@ -116,7 +116,7 @@ export default class EnvPull extends EasCommand {
return `${variable.name}=${currentEnvLocal[variable.name]}`;
}
skippedSecretVariables.push(variable.name);
return `# ${variable.name}=***** (secret variables are not available for reading)`;
return `# ${variable.name}=***** (secret)`;
}
if (variable.type === EnvironmentSecretType.FileBase64 && variable.valueWithFileContent) {
const filePath = path.join(envDir, variable.name);
@@ -130,20 +130,20 @@ export default class EnvPull extends EasCommand {
await fs.writeFile(targetPath, filePrefix + envFileContentLines.join('\n'));
Log.log(
`Pulled environment variables from ${environment.toLowerCase()} environment to ${targetPath}.`
`Pulled plain text and sensitive environment variables from "${environment.toLowerCase()}" environment to ${targetPath}.`
);
if (overridenSecretVariables.length > 0) {
Log.addNewLineIfNone();
Log.log(`Reused local values for following secrets: ${overridenSecretVariables.join('\n')}`);
Log.log(`Reused local values for following secrets: ${overridenSecretVariables.join('\n')}.`);
}
if (skippedSecretVariables.length > 0) {
Log.addNewLineIfNone();
Log.warn(
`The following variables have the secret visibility and can not be read outside of EAS servers. Set their values manually in .env.local: ${skippedSecretVariables.join(
'\n'
)}`
Log.log(
`The following variables have the secret visibility and can't be read outside of EAS servers. Set their values manually in your .env file: ${skippedSecretVariables.join(
', '
)}.`
);
}
}
@@ -0,0 +1,378 @@
import { Platform } from '@expo/eas-build-job';
import { Flags } from '@oclif/core';
import chalk from 'chalk';
import EasCommand from '../../commandUtils/EasCommand';
import { fetchBuildsAsync, formatBuild } from '../../commandUtils/builds';
import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
import { EasNonInteractiveAndJsonFlags } from '../../commandUtils/flags';
import { AppPlatform, BuildStatus } from '../../graphql/generated';
import { BuildQuery } from '../../graphql/queries/BuildQuery';
import Log from '../../log';
import { ora } from '../../ora';
import { RequestedPlatform } from '../../platform';
import { getDisplayNameForProjectIdAsync } from '../../project/projectUtils';
import { resolveWorkflowPerPlatformAsync } from '../../project/workflow';
import { selectAsync } from '../../prompts';
import { Fingerprint, FingerprintDiffItem } from '../../utils/fingerprint';
import { createFingerprintAsync, diffFingerprint } from '../../utils/fingerprintCli';
import { abridgedDiff } from '../../utils/fingerprintDiff';
import formatFields, { FormatFieldsItem } from '../../utils/formatFields';
import { enableJsonOutput } from '../../utils/json';
export default class FingerprintCompare extends EasCommand {
static override description = 'compare fingerprints of the current project, builds and updates';
static override hidden = true;
static override flags = {
'build-id': Flags.string({
aliases: ['buildId'],
description: 'Compare the fingerprint with the build with the specified ID',
}),
...EasNonInteractiveAndJsonFlags,
};
static override contextDefinition = {
...this.ContextOptions.ProjectId,
...this.ContextOptions.ProjectConfig,
...this.ContextOptions.LoggedIn,
...this.ContextOptions.Vcs,
};
async runAsync(): Promise<void> {
const { flags } = await this.parse(FingerprintCompare);
const { json: jsonFlag, 'non-interactive': nonInteractive, buildId: buildIdFromArg } = flags;
const {
projectId,
privateProjectConfig: { projectDir },
loggedIn: { graphqlClient },
vcsClient,
} = await this.getContextAsync(FingerprintCompare, {
nonInteractive,
withServerSideEnvironment: null,
});
if (jsonFlag) {
enableJsonOutput();
}
const displayName = await getDisplayNameForProjectIdAsync(graphqlClient, projectId);
let buildId: string | null = buildIdFromArg;
if (!buildId) {
if (nonInteractive) {
throw new Error('Build ID must be provided in non-interactive mode');
}
buildId = await selectBuildToCompareAsync(graphqlClient, projectId, displayName, {
filters: { hasFingerprint: true },
});
if (!buildId) {
return;
}
}
Log.log(`Comparing fingerprints of the current project and build ${buildId}…`);
const buildWithFingerprint = await BuildQuery.withFingerprintByIdAsync(graphqlClient, buildId);
const fingerprintDebugUrl = buildWithFingerprint.fingerprint?.debugInfoUrl;
if (!fingerprintDebugUrl) {
Log.error('A fingerprint for the build could not be found.');
return;
}
const fingerprintResponse = await fetch(fingerprintDebugUrl);
const fingerprint = (await fingerprintResponse.json()) as Fingerprint;
const workflows = await resolveWorkflowPerPlatformAsync(projectDir, vcsClient);
const buildPlatform = buildWithFingerprint.platform;
const workflow = workflows[appPlatformToPlatform(buildPlatform)];
const projectFingerprint = await createFingerprintAsync(projectDir, {
workflow,
platforms: [appPlatformToString(buildPlatform)],
debug: true,
env: undefined,
});
if (!projectFingerprint) {
Log.error('Project fingerprints can only be computed for projects with SDK 52 or higher');
return;
}
if (fingerprint.hash === projectFingerprint.hash) {
Log.log(`✅ Project fingerprint matches build`);
return;
} else {
Log.log(`🔄 Project fingerprint differs from build`);
}
const fingerprintDiffs = diffFingerprint(projectDir, fingerprint, projectFingerprint);
if (!fingerprintDiffs) {
Log.error('Fingerprint diffs can only be computed for projects with SDK 52 or higher');
return;
}
const filePathDiffs = fingerprintDiffs.filter(diff => {
let sourceType;
if (diff.op === 'added') {
sourceType = diff.addedSource.type;
} else if (diff.op === 'removed') {
sourceType = diff.removedSource.type;
} else if (diff.op === 'changed') {
sourceType = diff.beforeSource.type;
}
return sourceType === 'dir' || sourceType === 'file';
});
if (filePathDiffs.length > 0) {
Log.newLine();
Log.log('📁 Paths with native dependencies:');
}
const fields = [];
for (const diff of filePathDiffs) {
const field = getDiffFilePathFields(diff);
if (!field) {
throw new Error(`Unsupported diff: ${JSON.stringify(diff)}`);
}
fields.push(field);
}
Log.log(
formatFields(fields, {
labelFormat: label => ` ${chalk.dim(label)}:`,
})
);
const contentDiffs = fingerprintDiffs.filter(diff => {
let sourceType;
if (diff.op === 'added') {
sourceType = diff.addedSource.type;
} else if (diff.op === 'removed') {
sourceType = diff.removedSource.type;
} else if (diff.op === 'changed') {
sourceType = diff.beforeSource.type;
}
return sourceType === 'contents';
});
for (const diff of contentDiffs) {
printContentDiff(diff);
}
}
}
function printContentDiff(diff: FingerprintDiffItem): void {
if (diff.op === 'added') {
const sourceType = diff.addedSource.type;
if (sourceType === 'contents') {
printContentSource({
op: diff.op,
sourceType,
contentsId: diff.addedSource.id,
contentsAfter: diff.addedSource.contents,
});
}
} else if (diff.op === 'removed') {
const sourceType = diff.removedSource.type;
if (sourceType === 'contents') {
printContentSource({
op: diff.op,
sourceType,
contentsId: diff.removedSource.id,
contentsBefore: diff.removedSource.contents,
});
}
} else if (diff.op === 'changed') {
const sourceType = diff.beforeSource.type;
if (sourceType === 'contents') {
if (diff.afterSource.type !== 'contents') {
throw new Error(
`Changed fingerprint source types must be the same, received ${diff.beforeSource.type}, ${diff.afterSource.type}`
);
}
printContentSource({
op: diff.op,
sourceType: diff.beforeSource.type, // before and after source types should be the same
contentsId: diff.beforeSource.id, // before and after content ids should be the same
contentsBefore: diff.beforeSource.contents,
contentsAfter: diff.afterSource.contents,
});
}
}
}
function getDiffFilePathFields(diff: FingerprintDiffItem): FormatFieldsItem | null {
if (diff.op === 'added') {
const sourceType = diff.addedSource.type;
if (sourceType !== 'contents') {
return getFilePathSourceFields({
op: diff.op,
sourceType,
filePath: diff.addedSource.filePath,
});
}
} else if (diff.op === 'removed') {
const sourceType = diff.removedSource.type;
if (sourceType !== 'contents') {
return getFilePathSourceFields({
op: diff.op,
sourceType,
filePath: diff.removedSource.filePath,
});
}
} else if (diff.op === 'changed') {
const sourceType = diff.beforeSource.type;
if (sourceType !== 'contents') {
return getFilePathSourceFields({
op: diff.op,
sourceType: diff.beforeSource.type, // before and after source types should be the same
filePath: diff.beforeSource.filePath, // before and after filePaths should be the same
});
}
}
return null;
}
function getFilePathSourceFields({
op,
sourceType,
filePath,
}: {
op: 'added' | 'removed' | 'changed';
sourceType: 'dir' | 'file';
filePath: string;
}): FormatFieldsItem {
if (sourceType === 'dir') {
if (op === 'added') {
return { label: 'new directory', value: filePath };
} else if (op === 'removed') {
return { label: 'removed directory', value: filePath };
} else if (op === 'changed') {
return { label: 'modified directory', value: filePath };
}
} else if (sourceType === 'file') {
if (op === 'added') {
return { label: 'new file', value: filePath };
} else if (op === 'removed') {
return { label: 'removed file', value: filePath };
} else if (op === 'changed') {
return { label: 'modified file', value: filePath };
}
}
throw new Error(`Unsupported source and op: ${sourceType}, ${op}`);
}
const PRETTY_CONTENT_ID: Record<string, string> = {
'expoAutolinkingConfig:ios': 'Expo autolinking config (iOS)',
'expoAutolinkingConfig:android': 'Expo autolinking config (Android)',
'packageJson:scripts': 'package.json scripts',
expoConfig: 'Expo config',
};
function printContentSource({
op,
contentsBefore,
contentsAfter,
contentsId,
}: {
op: 'added' | 'removed' | 'changed';
sourceType: 'contents';
contentsBefore?: string | Buffer;
contentsAfter?: string | Buffer;
contentsId: string;
}): void {
Log.newLine();
const prettyContentId = PRETTY_CONTENT_ID[contentsId] ?? contentsId;
if (op === 'added') {
Log.log(`${chalk.dim('📝 New content')}: ${prettyContentId}`);
} else if (op === 'removed') {
Log.log(`${chalk.dim('📝 Removed content')}: ${prettyContentId}`);
} else if (op === 'changed') {
Log.log(`${chalk.dim('📝 Modified content')}: ${prettyContentId}`);
}
printContentsDiff(contentsBefore ?? '', contentsAfter ?? '');
}
function printContentsDiff(contents1: string | Buffer, contents2: string | Buffer): void {
const stringifiedContents1 = Buffer.isBuffer(contents1) ? contents1.toString() : contents1;
const stringifiedContents2 = Buffer.isBuffer(contents2) ? contents2.toString() : contents2;
const isStr1JSON = isJSON(stringifiedContents1);
const isStr2JSON = isJSON(stringifiedContents2);
const prettifiedContents1 = isStr1JSON
? JSON.stringify(JSON.parse(stringifiedContents1), null, 2)
: stringifiedContents1;
const prettifiedContents2 = isStr2JSON
? JSON.stringify(JSON.parse(stringifiedContents2), null, 2)
: stringifiedContents2;
abridgedDiff(prettifiedContents1, prettifiedContents2, 0);
}
function isJSON(str: string): boolean {
try {
JSON.parse(str);
return true;
} catch {
return false;
}
}
function appPlatformToPlatform(platform: AppPlatform): Platform {
switch (platform) {
case AppPlatform.Android:
return Platform.ANDROID;
case AppPlatform.Ios:
return Platform.IOS;
default:
throw new Error(`Unsupported platform: ${platform}`);
}
}
function appPlatformToString(platform: AppPlatform): string {
switch (platform) {
case AppPlatform.Android:
return 'android';
case AppPlatform.Ios:
return 'ios';
default:
throw new Error(`Unsupported platform: ${platform}`);
}
}
export async function selectBuildToCompareAsync(
graphqlClient: ExpoGraphqlClient,
projectId: string,
projectDisplayName: string,
{
filters,
}: {
filters?: {
statuses?: BuildStatus[];
platform?: RequestedPlatform;
profile?: string;
hasFingerprint?: boolean;
};
} = {}
): Promise<string | null> {
const spinner = ora().start('Fetching builds…');
let builds;
try {
builds = await fetchBuildsAsync({ graphqlClient, projectId, filters });
spinner.stop();
} catch (error) {
spinner.fail(
`Something went wrong and we couldn't fetch the builds for the project ${projectDisplayName}.`
);
throw error;
}
if (builds.length === 0) {
Log.warn(`No fingerprints have been computed for builds of project ${projectDisplayName}.`);
return null;
} else {
const build = await selectAsync<string>(
'Which build do you want to compare?',
builds.map(build => ({
title: formatBuild(build),
value: build.id,
}))
);
return build;
}
}
@@ -8,14 +8,13 @@ import EasCommand from '../../commandUtils/EasCommand';
import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
import { saveProjectIdToAppConfigAsync } from '../../commandUtils/context/contextUtils/getProjectIdAsync';
import { EASNonInteractiveFlag } from '../../commandUtils/flags';
import { AppPrivacy, Role } from '../../graphql/generated';
import { Role } from '../../graphql/generated';
import { AppMutation } from '../../graphql/mutations/AppMutation';
import { AppQuery } from '../../graphql/queries/AppQuery';
import Log, { link } from '../../log';
import { ora } from '../../ora';
import { createOrModifyExpoConfigAsync, getPrivateExpoConfigAsync } from '../../project/expoConfig';
import { findProjectIdByAccountNameAndSlugNullableAsync } from '../../project/fetchOrCreateProjectIDForWriteToConfigWithConfirmationAsync';
import { toAppPrivacy } from '../../project/projectUtils';
import { Choice, confirmAsync, promptAsync } from '../../prompts';
import { Actor } from '../../user/User';
@@ -337,7 +336,6 @@ export default class ProjectInit extends EasCommand {
createdProjectId = await AppMutation.createAppAsync(graphqlClient, {
accountId: account.id,
projectName,
privacy: toAppPrivacy(exp.privacy) ?? AppPrivacy.Public,
});
spinner.succeed(`Created ${chalk.bold(projectLink)}`);
} catch (err) {
@@ -88,7 +88,10 @@ describe(UpdatePublish.name, () => {
const { platforms, runtimeVersion } = mockTestExport();
jest.mocked(ensureBranchExistsAsync).mockResolvedValue({
branchId: 'branch123',
branch: {
id: 'branch123',
name: 'wat',
},
createdBranch: false,
});
@@ -111,7 +114,10 @@ describe(UpdatePublish.name, () => {
.mocked(getBranchFromChannelNameAndCreateAndLinkIfNotExistsAsync)
.mockResolvedValue({ branchId: 'branch123', branchName: 'branchFromChannel' });
jest.mocked(ensureBranchExistsAsync).mockResolvedValue({
branchId: 'branch123',
branch: {
id: 'branch123',
name: 'wat',
},
createdBranch: false,
});
@@ -146,7 +152,10 @@ describe(UpdatePublish.name, () => {
// Mock an existing branch, so we don't create a new one
jest.mocked(ensureBranchExistsAsync).mockResolvedValue({
branchId: 'branch123',
branch: {
id: 'branch123',
name: 'wat',
},
createdBranch: false,
});
@@ -1,5 +1,4 @@
import { AppJSONConfig, ExpoConfig, PackageJSONConfig, getConfig } from '@expo/config';
import { Updates } from '@expo/config-plugins';
import { vol } from 'memfs';
import nullthrows from 'nullthrows';
import path from 'path';
@@ -82,16 +81,23 @@ describe(UpdateRollBackToEmbedded.name, () => {
);
});
it('creates a roll back to embedded with --non-interactive, --branch, and --message', async () => {
const flags = ['--non-interactive', '--branch=branch123', '--message=abc'];
it('creates a roll back to embedded with --non-interactive, --branch, --message, and --runtime-version', async () => {
const flags = [
'--non-interactive',
'--branch=branch123',
'--message=abc',
'--runtime-version=exposdk:47.0.0',
];
mockTestProject();
const platforms = ['android', 'ios'];
const runtimeVersion = 'exposdk:47.0.0';
jest.mocked(Updates.getRuntimeVersionAsync).mockResolvedValue(runtimeVersion);
jest.mocked(ensureBranchExistsAsync).mockResolvedValue({
branchId: 'branch123',
branch: {
id: 'branch123',
name: 'wat',
},
createdBranch: false,
});
@@ -104,19 +110,26 @@ describe(UpdateRollBackToEmbedded.name, () => {
expect(PublishMutation.publishUpdateGroupAsync).toHaveBeenCalled();
});
it('creates a roll back to embedded with --non-interactive, --channel, and --message', async () => {
const flags = ['--non-interactive', '--channel=channel123', '--message=abc'];
it('creates a roll back to embedded with --non-interactive, --channel, --message, and --runtime-version', async () => {
const flags = [
'--non-interactive',
'--channel=channel123',
'--message=abc',
'--runtime-version=exposdk:47.0.0',
];
const { projectId } = mockTestProject();
const platforms = ['android', 'ios'];
const runtimeVersion = 'exposdk:47.0.0';
jest.mocked(Updates.getRuntimeVersionAsync).mockResolvedValue(runtimeVersion);
jest
.mocked(getBranchFromChannelNameAndCreateAndLinkIfNotExistsAsync)
.mockResolvedValue({ branchId: updateStub.branch.id, branchName: 'branchFromChannel' });
jest.mocked(ensureBranchExistsAsync).mockResolvedValue({
branchId: 'branch123',
branch: {
id: 'branch123',
name: 'wat',
},
createdBranch: false,
});
@@ -142,18 +155,25 @@ describe(UpdateRollBackToEmbedded.name, () => {
});
it('creates a roll back to embedded with the public expo config', async () => {
const flags = ['--non-interactive', '--branch=branch123', '--message=abc'];
const flags = [
'--non-interactive',
'--branch=branch123',
'--message=abc',
'--runtime-version=exposdk:47.0.0',
];
// Add configuration to the project that should not be included in the update
mockTestProject();
const platforms = ['ios'];
const runtimeVersion = 'exposdk:47.0.0';
jest.mocked(Updates.getRuntimeVersionAsync).mockResolvedValue(runtimeVersion);
// Mock an existing branch, so we don't create a new one
jest.mocked(ensureBranchExistsAsync).mockResolvedValue({
branchId: 'branch123',
branch: {
id: 'branch123',
name: 'wat',
},
createdBranch: false,
});
@@ -400,7 +400,7 @@ export default class UpdatePublish extends EasCommand {
runtimeVersionInfoObjects
);
const { branchId } = await ensureBranchExistsAsync(graphqlClient, {
const { branch } = await ensureBranchExistsAsync(graphqlClient, {
appId: projectId,
branchName,
});
@@ -482,7 +482,7 @@ export default class UpdatePublish extends EasCommand {
);
return {
branchId,
branchId: branch.id,
updateInfoGroup: localUpdateInfoGroup,
rolloutInfoGroup: localRolloutInfoGroup,
runtimeFingerprintSource: fingerprintSource
@@ -494,6 +494,7 @@ export default class UpdatePublish extends EasCommand {
gitCommitHash,
isGitWorkingTreeDirty,
awaitingCodeSigningInfo: !!codeSigningInfo,
environment: environment ?? null,
};
}
);
@@ -1,5 +1,4 @@
import { Platform as PublishPlatform } from '@expo/config';
import { Workflow } from '@expo/eas-build-job';
import { Errors, Flags } from '@oclif/core';
import nullthrows from 'nullthrows';
@@ -12,10 +11,12 @@ import { getPaginatedQueryOptions } from '../../commandUtils/pagination';
import fetch from '../../fetch';
import {
PublishUpdateGroupInput,
RuntimeFragment,
StatuspageServiceName,
UpdatePublishMutation,
} from '../../graphql/generated';
import { PublishMutation } from '../../graphql/mutations/PublishMutation';
import { RuntimeQuery } from '../../graphql/queries/RuntimeQuery';
import Log, { link } from '../../log';
import { ora } from '../../ora';
import { RequestedPlatform } from '../../platform';
@@ -29,10 +30,8 @@ import {
defaultPublishPlatforms,
getBranchNameForCommandAsync,
getRuntimeToPlatformsAndFingerprintInfoMappingFromRuntimeVersionInfoObjects,
getRuntimeVersionInfoObjectsAsync,
getUpdateMessageForCommandAsync,
} from '../../project/publish';
import { resolveWorkflowPerPlatformAsync } from '../../project/workflow';
import { ensureEASUpdateIsConfiguredAsync } from '../../update/configure';
import { getUpdateJsonInfosForUpdates } from '../../update/utils';
import {
@@ -45,12 +44,13 @@ import {
import uniqBy from '../../utils/expodash/uniqBy';
import formatFields from '../../utils/formatFields';
import { enableJsonOutput, printJsonOnlyOutput } from '../../utils/json';
import { Connection, QueryParams, selectPaginatedAsync } from '../../utils/relay';
import { maybeWarnAboutEasOutagesAsync } from '../../utils/statuspageService';
type RawUpdateFlags = {
auto: boolean;
branch?: string;
channel?: string;
'runtime-version'?: string;
message?: string;
platform: string;
'private-key-path'?: string;
@@ -59,10 +59,10 @@ type RawUpdateFlags = {
};
type UpdateFlags = {
auto: boolean;
platform: RequestedPlatform;
branchName?: string;
channelName?: string;
runtimeVersion?: string;
updateMessage?: string;
privateKeyPath?: string;
json: boolean;
@@ -81,6 +81,10 @@ export default class UpdateRollBackToEmbedded extends EasCommand {
description: 'Channel that the published rollback to embedded update should affect',
required: false,
}),
'runtime-version': Flags.string({
description: 'Runtime version that the rollback to embedded update should target',
required: false,
}),
message: Flags.string({
description: 'A short message describing the rollback to embedded update',
required: false,
@@ -95,11 +99,6 @@ export default class UpdateRollBackToEmbedded extends EasCommand {
default: 'all',
required: false,
}),
auto: Flags.boolean({
description:
'Use the current git branch and commit message for the EAS branch and update message',
default: false,
}),
'private-key-path': Flags.string({
description: `File containing the PEM-encoded private key corresponding to the certificate in expo-updates' configuration. Defaults to a file named "private-key.pem" in the certificate's directory. Only relevant if you are using code signing: https://docs.expo.dev/eas-update/code-signing/`,
required: false,
@@ -117,10 +116,10 @@ export default class UpdateRollBackToEmbedded extends EasCommand {
const { flags: rawFlags } = await this.parse(UpdateRollBackToEmbedded);
const paginatedQueryOptions = getPaginatedQueryOptions(rawFlags);
const {
auto: autoFlag,
platform: platformFlag,
channelName: channelNameArg,
updateMessage: updateMessageArg,
runtimeVersion: runtimeVersionArg,
privateKeyPath,
json: jsonFlag,
nonInteractive,
@@ -171,14 +170,14 @@ export default class UpdateRollBackToEmbedded extends EasCommand {
projectId,
channelNameArg,
branchNameArg,
autoFlag,
autoFlag: false,
nonInteractive,
paginatedQueryOptions,
});
const updateMessage = await getUpdateMessageForCommandAsync(vcsClient, {
updateMessageArg,
autoFlag,
autoFlag: false,
nonInteractive,
jsonFlag,
});
@@ -186,28 +185,33 @@ export default class UpdateRollBackToEmbedded extends EasCommand {
const realizedPlatforms: UpdatePublishPlatform[] =
platformFlag === 'all' ? defaultPublishPlatforms : [platformFlag];
const { branchId } = await ensureBranchExistsAsync(graphqlClient, {
const { branch } = await ensureBranchExistsAsync(graphqlClient, {
appId: projectId,
branchName,
});
const gitCommitHash = await vcsClient.getCommitHashAsync();
const isGitWorkingTreeDirty = await vcsClient.hasUncommittedChangesAsync();
const selectedRuntime =
runtimeVersionArg ??
(
await UpdateRollBackToEmbedded.selectRuntimeAsync(graphqlClient, {
appId: projectId,
branchName,
})
)?.version;
if (!selectedRuntime) {
Errors.error('Must select a runtime or provide the --runtimeVersion flag', { exit: 1 });
}
const workflows = await resolveWorkflowPerPlatformAsync(projectDir, vcsClient);
const runtimeVersionInfoObjects = await getRuntimeVersionInfoObjectsAsync({
exp,
platforms: realizedPlatforms,
projectDir,
workflows: {
...workflows,
web: Workflow.UNKNOWN,
},
env: undefined,
});
const runtimeToPlatformsAndFingerprintInfoMapping =
getRuntimeToPlatformsAndFingerprintInfoMappingFromRuntimeVersionInfoObjects(
runtimeVersionInfoObjects
realizedPlatforms.map(platform => ({
platform,
runtimeVersionInfo: {
runtimeVersion: selectedRuntime,
fingerprint: null,
fingerprintHash: null,
},
}))
);
let newUpdates: UpdatePublishMutation['updateBranch']['publishUpdateGroups'];
@@ -215,10 +219,8 @@ export default class UpdateRollBackToEmbedded extends EasCommand {
try {
newUpdates = await this.publishRollbacksAsync({
graphqlClient,
isGitWorkingTreeDirty,
gitCommitHash,
updateMessage,
branchId,
branchId: branch.id,
codeSigningInfo,
runtimeToPlatformsAndFingerprintInfoMapping,
realizedPlatforms,
@@ -232,13 +234,6 @@ export default class UpdateRollBackToEmbedded extends EasCommand {
if (jsonFlag) {
printJsonOnlyOutput(getUpdateJsonInfosForUpdates(newUpdates));
} else {
if (new Set(newUpdates.map(update => update.group)).size > 1) {
Log.addNewLineIfNone();
Log.log(
'👉 Since multiple runtime versions are defined, multiple update groups have been published.'
);
}
Log.addNewLineIfNone();
for (const runtime of uniqBy(
@@ -276,14 +271,6 @@ export default class UpdateRollBackToEmbedded extends EasCommand {
: []),
...(newIosUpdate ? [{ label: 'iOS update ID', value: newIosUpdate.id }] : []),
{ label: 'Message', value: updateMessage ?? '' },
...(gitCommitHash
? [
{
label: 'Commit',
value: `${gitCommitHash}${isGitWorkingTreeDirty ? '*' : ''}`,
},
]
: []),
{ label: 'EAS Dashboard', value: updateGroupLink },
])
);
@@ -294,8 +281,6 @@ export default class UpdateRollBackToEmbedded extends EasCommand {
private async publishRollbacksAsync({
graphqlClient,
isGitWorkingTreeDirty,
gitCommitHash,
updateMessage,
branchId,
codeSigningInfo,
@@ -303,8 +288,6 @@ export default class UpdateRollBackToEmbedded extends EasCommand {
realizedPlatforms,
}: {
graphqlClient: ExpoGraphqlClient;
isGitWorkingTreeDirty: boolean | undefined;
gitCommitHash: string | undefined;
updateMessage: string | undefined;
branchId: string;
codeSigningInfo: CodeSigningInfo | undefined;
@@ -329,8 +312,6 @@ export default class UpdateRollBackToEmbedded extends EasCommand {
rollBackToEmbeddedInfoGroup: localRollbackInfoGroup,
runtimeVersion,
message: updateMessage,
gitCommitHash,
isGitWorkingTreeDirty,
awaitingCodeSigningInfo: !!codeSigningInfo,
};
}
@@ -381,22 +362,63 @@ export default class UpdateRollBackToEmbedded extends EasCommand {
return newUpdates;
}
private static async selectRuntimeAsync(
graphqlClient: ExpoGraphqlClient,
{
appId,
branchName,
batchSize = 5,
}: {
appId: string;
branchName: string;
batchSize?: number;
}
): Promise<RuntimeFragment | null> {
const queryAsync = async (queryParams: QueryParams): Promise<Connection<RuntimeFragment>> => {
return await RuntimeQuery.getRuntimesOnBranchAsync(graphqlClient, {
appId,
name: branchName,
first: queryParams.first,
after: queryParams.after,
last: queryParams.last,
before: queryParams.before,
});
};
const getTitleAsync = async (runtime: RuntimeFragment): Promise<string> => {
return runtime.version;
};
return await selectPaginatedAsync({
queryAsync,
getTitleAsync,
printedType: 'target runtime',
pageSize: batchSize,
});
}
private sanitizeFlags(flags: RawUpdateFlags): UpdateFlags {
const nonInteractive = flags['non-interactive'] ?? false;
const { auto, branch: branchName, channel: channelName, message: updateMessage } = flags;
if (nonInteractive && !auto && !(updateMessage && (branchName || channelName))) {
const {
branch: branchName,
channel: channelName,
message: updateMessage,
'runtime-version': runtimeVersion,
} = flags;
if (nonInteractive && !(updateMessage && (branchName || channelName))) {
Errors.error(
'--branch and --message, or --channel and --message are required when updating in non-interactive mode unless --auto is specified',
'--branch and --message, or --channel and --message are required in non-interactive mode',
{ exit: 1 }
);
}
if (nonInteractive && !runtimeVersion) {
Errors.error('--runtimeVersion is required in non-interactive mode', { exit: 1 });
}
return {
auto,
branchName,
channelName,
updateMessage,
runtimeVersion,
platform: flags.platform as RequestedPlatform,
privateKeyPath: flags['private-key-path'],
nonInteractive,
+20 -5
View File
@@ -43,16 +43,18 @@ interface DeployFlags {
environment?: EnvironmentVariableEnvironment;
deploymentIdentifier?: string;
exportDir: string;
dryRun: boolean;
}
interface RawDeployFlags {
'non-interactive': boolean;
environment?: string;
environment?: EnvironmentVariableEnvironment;
json: boolean;
prod: boolean;
alias?: string;
id?: string;
'export-dir': string;
'dry-run': boolean;
}
interface DeployInProgressParams {
@@ -90,10 +92,11 @@ export default class WorkerDeploy extends EasCommand {
helpValue: 'dir',
default: 'dist',
}),
environment: {
...EASEnvironmentFlag.environment,
description: 'Deploy with EAS Environment Variables matching the specified environment.',
},
'dry-run': Flags.boolean({
description: 'Outputs a tarball of the new deployment instead of uploading it.',
default: false,
}),
...EASEnvironmentFlag,
...EasNonInteractiveAndJsonFlags,
};
@@ -268,6 +271,16 @@ export default class WorkerDeploy extends EasCommand {
})
);
if (flags.dryRun) {
const DRY_RUN_OUTPUT_PATH = 'deploy.tar.gz';
await fs.promises.copyFile(tarPath, DRY_RUN_OUTPUT_PATH);
progress.succeed('Saved deploy.tar.gz tarball');
if (flags.json) {
printJsonOnlyOutput({ tarPath: DRY_RUN_OUTPUT_PATH });
}
return;
}
const uploadUrl = await getSignedDeploymentUrlAsync(graphqlClient, {
appId: projectId,
deploymentIdentifier: flags.deploymentIdentifier,
@@ -382,6 +395,8 @@ export default class WorkerDeploy extends EasCommand {
aliasName: flags.alias?.trim().toLowerCase(),
deploymentIdentifier: flags.id?.trim(),
exportDir: flags['export-dir'],
environment: flags['environment'],
dryRun: flags['dry-run'],
};
}
}
@@ -32,6 +32,7 @@ export class CredentialsContext {
public readonly analytics: Analytics;
public readonly vcsClient: Client;
public readonly easJsonCliConfig?: EasJson['cli'];
public readonly usesBroadcastPushNotifications: boolean;
private shouldAskAuthenticateAppStore: boolean = true;
@@ -61,6 +62,8 @@ export class CredentialsContext {
this.nonInteractive = options.nonInteractive ?? false;
this.projectInfo = options.projectInfo;
this.freezeCredentials = options.freezeCredentials ?? false;
this.usesBroadcastPushNotifications =
options.projectInfo?.exp.ios?.usesBroadcastPushNotifications ?? false;
}
get hasProjectContext(): boolean {
@@ -35,7 +35,7 @@ export class SetUpTargetBuildCredentials {
bundleIdentifier: app.bundleIdentifier,
projectName: app.projectName,
},
{ entitlements }
{ entitlements, usesBroadcastPushNotifications: ctx.usesBroadcastPushNotifications }
);
}
try {
@@ -45,7 +45,9 @@ describe(syncCapabilitiesForEntitlementsAsync, () => {
id: 'XXX',
} as any;
await syncCapabilitiesForEntitlementsAsync(bundleId, entitlements);
await syncCapabilitiesForEntitlementsAsync(bundleId, entitlements, {
usesBroadcastPushNotifications: false,
});
expect(bundleId.updateBundleIdCapabilityAsync).toBeCalledWith([
{
@@ -62,63 +64,70 @@ describe(syncCapabilitiesForEntitlementsAsync, () => {
id: 'XXX',
} as any;
const results = await syncCapabilitiesForEntitlementsAsync(bundleId, {
'com.apple.developer.healthkit': true,
// 'com.apple.developer.healthkit.access': [],
'com.apple.developer.in-app-payments': ['merchant.com.example.development'],
'com.apple.developer.icloud-container-identifiers': [],
'com.apple.developer.ClassKit-environment': 'development',
'com.apple.developer.default-data-protection':
'NSFileProtectionCompleteUntilFirstUserAuthentication',
'com.apple.developer.networking.networkextension': ['dns-proxy'],
'com.apple.developer.networking.vpn.api': ['allow-vpn'],
'com.apple.developer.networking.HotspotConfiguration': true,
'com.apple.developer.kernel.extended-virtual-addressing': true,
'com.apple.developer.homekit': true,
'com.apple.developer.networking.multipath': true,
'com.apple.external-accessory.wireless-configuration': true,
'inter-app-audio': true,
'com.apple.developer.pass-type-identifiers': ['$(TeamIdentifierPrefix)*'],
'com.apple.developer.user-fonts': ['app-usage'],
'com.apple.developer.devicecheck.appattest-environment': 'development',
'com.apple.developer.nfc.readersession.formats': ['NDEF', 'TAG'],
'com.apple.developer.applesignin': ['Default'],
'com.apple.developer.siri': true,
'com.apple.developer.networking.wifi-info': true,
'com.apple.developer.usernotifications.communication': true,
'com.apple.developer.usernotifications.time-sensitive': true,
'com.apple.developer.group-session': true,
'com.apple.developer.family-controls': true,
'com.apple.developer.authentication-services.autofill-credential-provider': true,
// 'com.apple.developer.game-center': true,
'com.apple.security.application-groups': [
'group.CY-A5149AC2-49FC-11E7-B3F3-0335A16FFB8D.com.cydia.Extender',
],
const results = await syncCapabilitiesForEntitlementsAsync(
bundleId,
{
'com.apple.developer.healthkit': true,
// 'com.apple.developer.healthkit.access': [],
'com.apple.developer.in-app-payments': ['merchant.com.example.development'],
'com.apple.developer.icloud-container-identifiers': [],
'com.apple.developer.ClassKit-environment': 'development',
'com.apple.developer.default-data-protection':
'NSFileProtectionCompleteUntilFirstUserAuthentication',
'com.apple.developer.networking.networkextension': ['dns-proxy'],
'com.apple.developer.networking.vpn.api': ['allow-vpn'],
'com.apple.developer.networking.HotspotConfiguration': true,
'com.apple.developer.kernel.extended-virtual-addressing': true,
'com.apple.developer.homekit': true,
'com.apple.developer.networking.multipath': true,
'com.apple.external-accessory.wireless-configuration': true,
'inter-app-audio': true,
'com.apple.developer.pass-type-identifiers': ['$(TeamIdentifierPrefix)*'],
'com.apple.developer.user-fonts': ['app-usage'],
'com.apple.developer.devicecheck.appattest-environment': 'development',
'com.apple.developer.nfc.readersession.formats': ['NDEF', 'TAG'],
'com.apple.developer.applesignin': ['Default'],
'com.apple.developer.siri': true,
'com.apple.developer.networking.wifi-info': true,
'com.apple.developer.usernotifications.communication': true,
'com.apple.developer.usernotifications.time-sensitive': true,
'com.apple.developer.group-session': true,
'com.apple.developer.family-controls': true,
'com.apple.developer.authentication-services.autofill-credential-provider': true,
// 'com.apple.developer.game-center': true,
'com.apple.security.application-groups': [
'group.CY-A5149AC2-49FC-11E7-B3F3-0335A16FFB8D.com.cydia.Extender',
],
'com.apple.developer.fileprovider.testing-mode': true,
'com.apple.developer.healthkit.recalibrate-estimates': true,
'com.apple.developer.maps': true,
'com.apple.developer.user-management': true,
'com.apple.developer.networking.custom-protocol': true,
'com.apple.developer.system-extension.install': true,
'com.apple.developer.push-to-talk': true,
'com.apple.developer.driverkit.transport.usb': true,
'com.apple.developer.kernel.increased-memory-limit': true,
'com.apple.developer.driverkit.communicates-with-drivers': true,
'com.apple.developer.media-device-discovery-extension': true,
'com.apple.developer.driverkit.allow-third-party-userclients': true,
'com.apple.developer.weatherkit': true,
'com.apple.developer.on-demand-install-capable': true,
'com.apple.developer.driverkit.family.scsicontroller': true,
'com.apple.developer.driverkit.family.serial': true,
'com.apple.developer.driverkit.family.networking': true,
'com.apple.developer.driverkit.family.hid.eventservice': true,
'com.apple.developer.driverkit.family.hid.device': true,
'com.apple.developer.driverkit': true,
'com.apple.developer.driverkit.transport.hid': true,
'com.apple.developer.driverkit.family.audio': true,
'com.apple.developer.shared-with-you': true,
});
'com.apple.developer.fileprovider.testing-mode': true,
'com.apple.developer.healthkit.recalibrate-estimates': true,
'com.apple.developer.maps': true,
'com.apple.developer.user-management': true,
'com.apple.developer.networking.custom-protocol': true,
'com.apple.developer.system-extension.install': true,
'com.apple.developer.push-to-talk': true,
'com.apple.developer.driverkit.transport.usb': true,
'com.apple.developer.kernel.increased-memory-limit': true,
'com.apple.developer.driverkit.communicates-with-drivers': true,
'com.apple.developer.media-device-discovery-extension': true,
'com.apple.developer.driverkit.allow-third-party-userclients': true,
'com.apple.developer.weatherkit': true,
'com.apple.developer.on-demand-install-capable': true,
'com.apple.developer.driverkit.family.scsicontroller': true,
'com.apple.developer.driverkit.family.serial': true,
'com.apple.developer.driverkit.family.networking': true,
'com.apple.developer.driverkit.family.hid.eventservice': true,
'com.apple.developer.driverkit.family.hid.device': true,
'com.apple.developer.driverkit': true,
'com.apple.developer.driverkit.transport.hid': true,
'com.apple.developer.driverkit.family.audio': true,
'com.apple.developer.shared-with-you': true,
'aps-environment': 'production',
},
{
usesBroadcastPushNotifications: false,
}
);
expect(bundleId.updateBundleIdCapabilityAsync).toBeCalledWith([
{ capabilityType: 'HEALTHKIT', option: 'ON' },
@@ -251,6 +260,10 @@ describe(syncCapabilitiesForEntitlementsAsync, () => {
capabilityType: 'SHARED_WITH_YOU',
option: 'ON',
},
{
capabilityType: 'PUSH_NOTIFICATIONS',
option: 'ON',
},
]);
expect(results.enabled).toMatchInlineSnapshot(`
@@ -304,6 +317,7 @@ describe(syncCapabilitiesForEntitlementsAsync, () => {
"DriverKit Transport HID (development)",
"DriverKit Family Audio (development)",
"Shared with You",
"Push Notifications",
]
`);
expect(results.disabled).toStrictEqual([]);
@@ -318,9 +332,15 @@ describe(syncCapabilitiesForEntitlementsAsync, () => {
id: 'XXX',
} as any;
const results = await syncCapabilitiesForEntitlementsAsync(bundleId, {
'com.apple.developer.healthkit': true,
});
const results = await syncCapabilitiesForEntitlementsAsync(
bundleId,
{
'com.apple.developer.healthkit': true,
},
{
usesBroadcastPushNotifications: false,
}
);
expect(bundleId.updateBundleIdCapabilityAsync).not.toBeCalled();
@@ -344,9 +364,15 @@ describe(syncCapabilitiesForEntitlementsAsync, () => {
} as any;
await expect(
syncCapabilitiesForEntitlementsAsync(bundleId, {
'com.apple.developer.healthkit': true,
})
syncCapabilitiesForEntitlementsAsync(
bundleId,
{
'com.apple.developer.healthkit': true,
},
{
usesBroadcastPushNotifications: false,
}
)
).rejects.toThrowError(
`https://developer-mdn.apple.com/account/resources/identifiers/bundleId/edit/XXX333`
);
@@ -361,9 +387,15 @@ describe(syncCapabilitiesForEntitlementsAsync, () => {
id: 'XXX',
} as any;
const results = await syncCapabilitiesForEntitlementsAsync(bundleId, {
'com.apple.developer.healthkit': true,
});
const results = await syncCapabilitiesForEntitlementsAsync(
bundleId,
{
'com.apple.developer.healthkit': true,
},
{
usesBroadcastPushNotifications: false,
}
);
expect(bundleId.updateBundleIdCapabilityAsync).toBeCalledWith([
{ capabilityType: 'HEALTHKIT', option: 'ON' },
@@ -382,9 +414,15 @@ describe(syncCapabilitiesForEntitlementsAsync, () => {
id: 'XXX',
} as any;
const results = await syncCapabilitiesForEntitlementsAsync(bundleId, {
'com.apple.developer.healthkit': true,
});
const results = await syncCapabilitiesForEntitlementsAsync(
bundleId,
{
'com.apple.developer.healthkit': true,
},
{
usesBroadcastPushNotifications: false,
}
);
expect(bundleId.updateBundleIdCapabilityAsync).toBeCalledWith([
{ capabilityType: 'HEALTHKIT', option: 'ON' },
@@ -406,7 +444,13 @@ describe(syncCapabilitiesForEntitlementsAsync, () => {
id: 'XXX',
} as any;
const results = await syncCapabilitiesForEntitlementsAsync(bundleId, {});
const results = await syncCapabilitiesForEntitlementsAsync(
bundleId,
{},
{
usesBroadcastPushNotifications: false,
}
);
expect(bundleId.updateBundleIdCapabilityAsync).not.toBeCalled();
@@ -423,9 +467,15 @@ describe(syncCapabilitiesForEntitlementsAsync, () => {
id: 'XXX',
} as any;
const results = await syncCapabilitiesForEntitlementsAsync(bundleId, {
'com.apple.developer.healthkit': true,
});
const results = await syncCapabilitiesForEntitlementsAsync(
bundleId,
{
'com.apple.developer.healthkit': true,
},
{
usesBroadcastPushNotifications: false,
}
);
expect(bundleId.updateBundleIdCapabilityAsync).toBeCalledWith([
{ capabilityType: 'HEALTHKIT', option: 'ON' },
@@ -434,4 +484,164 @@ describe(syncCapabilitiesForEntitlementsAsync, () => {
expect(results.enabled).toStrictEqual(['HealthKit']);
expect(results.disabled).toStrictEqual([]);
});
it('enables push notifications capability with broadcast option when the capability is disabled and usesBroadcastPushNotifications is true', async () => {
const bundleId = {
getBundleIdCapabilitiesAsync: jest.fn(() => []),
updateBundleIdCapabilityAsync: jest.fn(),
id: 'XXX',
} as any;
const results = await syncCapabilitiesForEntitlementsAsync(
bundleId,
{
'aps-environment': 'production',
},
{
usesBroadcastPushNotifications: true,
}
);
expect(bundleId.updateBundleIdCapabilityAsync).toBeCalledWith([
{ capabilityType: 'PUSH_NOTIFICATIONS', option: 'PUSH_NOTIFICATION_FEATURE_BROADCAST' },
]);
expect(results.enabled).toStrictEqual(['Push Notifications']);
expect(results.disabled).toStrictEqual([]);
});
it('updates push notifications capability with broadcast option when the capability is enabled without settings and usesBroadcastPushNotifications is true', async () => {
const bundleId = {
getBundleIdCapabilitiesAsync: jest.fn(() => [
new BundleIdCapability({}, 'XXX_PUSH_NOTIFICATIONS', { settings: null }),
]),
updateBundleIdCapabilityAsync: jest.fn(),
id: 'XXX',
} as any;
const results = await syncCapabilitiesForEntitlementsAsync(
bundleId,
{
'aps-environment': 'production',
},
{
usesBroadcastPushNotifications: true,
}
);
expect(bundleId.updateBundleIdCapabilityAsync).toBeCalledWith([
{ capabilityType: 'PUSH_NOTIFICATIONS', option: 'PUSH_NOTIFICATION_FEATURE_BROADCAST' },
]);
expect(results.enabled).toStrictEqual(['Push Notifications']);
expect(results.disabled).toStrictEqual([]);
});
it('disables push notifications capability', async () => {
const bundleId = {
getBundleIdCapabilitiesAsync: jest.fn(() => [
new BundleIdCapability({}, 'XXX_PUSH_NOTIFICATIONS', { settings: null }),
]),
updateBundleIdCapabilityAsync: jest.fn(),
id: 'XXX',
} as any;
const results = await syncCapabilitiesForEntitlementsAsync(
bundleId,
{},
{
usesBroadcastPushNotifications: true,
}
);
expect(bundleId.updateBundleIdCapabilityAsync).toBeCalledWith([
{ capabilityType: 'PUSH_NOTIFICATIONS', option: 'OFF' },
]);
expect(results.disabled).toStrictEqual(['Push Notifications']);
expect(results.enabled).toStrictEqual([]);
});
it('does nothing when push notifications capability is enabled with broadcast options and usesBroadcastPushNotifications is true', async () => {
const bundleId = {
getBundleIdCapabilitiesAsync: jest.fn(() => [
new BundleIdCapability({}, 'XXX_PUSH_NOTIFICATIONS', {
settings: [],
}),
]),
updateBundleIdCapabilityAsync: jest.fn(),
id: 'XXX',
} as any;
const results = await syncCapabilitiesForEntitlementsAsync(
bundleId,
{
'aps-environment': 'production',
},
{
usesBroadcastPushNotifications: true,
}
);
expect(bundleId.updateBundleIdCapabilityAsync).not.toBeCalled();
expect(results.disabled).toStrictEqual([]);
expect(results.enabled).toStrictEqual([]);
});
it('does nothing when push notifications capability is enabled without broadcast options and usesBroadcastPushNotifications is false', async () => {
const bundleId = {
getBundleIdCapabilitiesAsync: jest.fn(() => [
new BundleIdCapability({}, 'XXX_PUSH_NOTIFICATIONS', {
settings: null,
}),
]),
updateBundleIdCapabilityAsync: jest.fn(),
id: 'XXX',
} as any;
const results = await syncCapabilitiesForEntitlementsAsync(
bundleId,
{
'aps-environment': 'production',
},
{
usesBroadcastPushNotifications: false,
}
);
expect(bundleId.updateBundleIdCapabilityAsync).not.toBeCalled();
expect(results.disabled).toStrictEqual([]);
expect(results.enabled).toStrictEqual([]);
});
it('updates push notifications capability without broadcast options when it is enabled and usesBroadcastPushNotifications is false', async () => {
const bundleId = {
getBundleIdCapabilitiesAsync: jest.fn(() => [
new BundleIdCapability({}, 'XXX_PUSH_NOTIFICATIONS', {
settings: [],
}),
]),
updateBundleIdCapabilityAsync: jest.fn(),
id: 'XXX',
} as any;
const results = await syncCapabilitiesForEntitlementsAsync(
bundleId,
{
'aps-environment': 'production',
},
{
usesBroadcastPushNotifications: false,
}
);
expect(bundleId.updateBundleIdCapabilityAsync).toBeCalledWith([
{ capabilityType: 'PUSH_NOTIFICATIONS', option: 'ON' },
]);
expect(results.disabled).toStrictEqual([]);
expect(results.enabled).toStrictEqual(['Push Notifications']);
});
});
@@ -6,6 +6,7 @@ import {
CapabilityType,
CapabilityTypeDataProtectionOption,
CapabilityTypeOption,
CapabilityTypePushNotificationsOption,
CloudContainer,
MerchantId,
} from '@expo/apple-utils';
@@ -19,7 +20,10 @@ export const EXPO_NO_CAPABILITY_SYNC = getenv.boolish('EXPO_NO_CAPABILITY_SYNC',
type GetOptionsMethod<T extends CapabilityType = any> = (
entitlement: JSONValue,
entitlementsJson: JSONObject
entitlementsJson: JSONObject,
additionalOptions: {
usesBroadcastPushNotifications?: boolean;
}
) => CapabilityOptionMap[T];
const validateBooleanOptions = (options: any): boolean => {
@@ -78,7 +82,10 @@ const getDefinedOptions: GetOptionsMethod = entitlement => {
*/
export async function syncCapabilitiesForEntitlementsAsync(
bundleId: BundleId,
entitlements: JSONObject = {}
entitlements: JSONObject = {},
additionalOptions: {
usesBroadcastPushNotifications: boolean;
}
): Promise<{ enabled: string[]; disabled: string[] }> {
if (EXPO_NO_CAPABILITY_SYNC) {
return { enabled: [], disabled: [] };
@@ -91,7 +98,8 @@ export async function syncCapabilitiesForEntitlementsAsync(
const { enabledCapabilityNames, request, remainingCapabilities } = getCapabilitiesToEnable(
currentCapabilities,
entitlements
entitlements,
additionalOptions
);
const { disabledCapabilityNames, request: modifiedRequest } = getCapabilitiesToDisable(
@@ -125,9 +133,25 @@ interface CapabilitiesRequest {
option: any;
}
function shouldSkipPushNotificationsCapabilityUpdate(
existing: BundleIdCapability,
additionalOptions: {
usesBroadcastPushNotifications: boolean;
}
): boolean {
// For push notifications, we should always update the capabaility if
// - settings are not defined in the existing capability, but usesBroadcastPushNotifications is enabled (we want to add settings for this capability)
// - settings are defined in the existing capability, but usesBroadcastPushNotifications is disabled (we want to remove settings for this capability)
const noSettingsAttributes = existing.attributes.settings == null;
return !noSettingsAttributes === additionalOptions.usesBroadcastPushNotifications;
}
function getCapabilitiesToEnable(
currentCapabilities: BundleIdCapability[],
entitlements: JSONObject
entitlements: JSONObject,
additionalOptions: {
usesBroadcastPushNotifications: boolean;
}
): {
enabledCapabilityNames: string[];
request: CapabilitiesRequest[];
@@ -156,7 +180,17 @@ function getCapabilitiesToEnable(
// Only skip if the existing capability is a simple boolean value,
// if it has more complex settings then we should always update it.
// If the `existing.attributes.settings` object is defined, then we can determine that it has extra configuration.
if (existing && existing?.attributes.settings == null) {
// For push notifications, we should always update the capabaility if
// - settings are not defined in the existing capability, but usesBroadcastPushNotifications is enabled (we want to add settings for this capability)
// - settings are defined in the existing capability, but usesBroadcastPushNotifications is disabled (we want to remove settings for this capability)
const isPushNotificationsCapability =
staticCapabilityInfo.capability === CapabilityType.PUSH_NOTIFICATIONS;
if (
existing &&
((!isPushNotificationsCapability && existing.attributes.settings == null) ||
(isPushNotificationsCapability &&
shouldSkipPushNotificationsCapabilityUpdate(existing, additionalOptions)))
) {
// Remove the item from the list of capabilities so we don't disable it.
remainingCapabilities.splice(existingIndex, 1);
if (Log.isDebug) {
@@ -173,7 +207,7 @@ function getCapabilitiesToEnable(
enabledCapabilityNames.push(staticCapabilityInfo.name);
const option = staticCapabilityInfo.getOptions(value, entitlements);
const option = staticCapabilityInfo.getOptions(value, entitlements, additionalOptions);
request.push({
capabilityType: staticCapabilityInfo.capability,
@@ -488,7 +522,13 @@ export const CapabilityMapping: CapabilityClassifier[] = [
entitlement: 'aps-environment',
capability: CapabilityType.PUSH_NOTIFICATIONS,
validateOptions: validateDevProdString,
getOptions: getDefinedOptions,
getOptions(entitlement, _entitlementsJson, { usesBroadcastPushNotifications }) {
const option = entitlement ? CapabilityTypeOption.ON : CapabilityTypeOption.OFF;
if (option === CapabilityTypeOption.ON && usesBroadcastPushNotifications) {
return CapabilityTypePushNotificationsOption.PUSH_NOTIFICATION_FEATURE_BROADCAST;
}
return option;
},
},
{
name: 'Wallet',
@@ -12,6 +12,7 @@ import { ora } from '../../../ora';
export interface IosCapabilitiesOptions {
entitlements: JSONObject;
usesBroadcastPushNotifications: boolean;
}
export interface AppLookupParams {
@@ -93,7 +94,7 @@ export async function ensureBundleIdExistsWithNameAsync(
export async function syncCapabilitiesAsync(
bundleId: BundleId,
{ entitlements }: IosCapabilitiesOptions
{ entitlements, ...rest }: IosCapabilitiesOptions
): Promise<void> {
const spinner = ora(`Syncing capabilities`).start();
@@ -105,7 +106,8 @@ export async function syncCapabilitiesAsync(
try {
const { enabled, disabled } = await syncCapabilitiesForEntitlementsAsync(
bundleId,
entitlements
entitlements,
rest
);
const results =
[buildMessage('Enabled', enabled), buildMessage('Disabled', disabled)]
@@ -119,7 +121,7 @@ export async function syncCapabilitiesAsync(
}
// Always run this after syncing the capabilities...
await syncCapabilityIdentifiersAsync(bundleId, { entitlements });
await syncCapabilityIdentifiersAsync(bundleId, { entitlements, ...rest });
}
const buildMessage = (title: string, items: string[]): string =>
+30 -3
View File
@@ -711,6 +711,7 @@ export type AccountSsoConfigurationPublicDataQueryPublicDataByAccountNameArgs =
};
export enum AccountUploadSessionType {
ProfileImageUpload = 'PROFILE_IMAGE_UPLOAD',
WorkflowsProjectSources = 'WORKFLOWS_PROJECT_SOURCES'
}
@@ -1310,8 +1311,9 @@ export type App = Project & {
* @deprecated Classic updates have been deprecated.
*/
playStoreUrl?: Maybe<Scalars['String']['output']>;
/** @deprecated Use 'privacySetting' instead. */
/** @deprecated No longer supported */
privacy: Scalars['String']['output'];
/** @deprecated No longer supported */
privacySetting: AppPrivacy;
/**
* Whether there have been any classic update publishes
@@ -1746,7 +1748,6 @@ export type AppInfoInput = {
export type AppInput = {
accountId: Scalars['ID']['input'];
appInfo?: InputMaybe<AppInfoInput>;
privacy: AppPrivacy;
projectName: Scalars['String']['input'];
};
@@ -2048,6 +2049,10 @@ export type AppUpdatesConnection = {
pageInfo: PageInfo;
};
export enum AppUploadSessionType {
ProfileImageUpload = 'PROFILE_IMAGE_UPLOAD'
}
/** Represents Play Store/App Store version of an application */
export type AppVersion = {
__typename?: 'AppVersion';
@@ -2098,7 +2103,6 @@ export type AppWithGithubRepositoryInput = {
accountId: Scalars['ID']['input'];
appInfo?: InputMaybe<AppInfoInput>;
installationIdentifier?: InputMaybe<Scalars['String']['input']>;
privacy: AppPrivacy;
projectName: Scalars['String']['input'];
};
@@ -2690,6 +2694,7 @@ export type Build = ActivityTimelineProjectActivity & BuildOrBuildJob & {
error?: Maybe<BuildError>;
estimatedWaitTimeLeftSeconds?: Maybe<Scalars['Int']['output']>;
expirationDate?: Maybe<Scalars['DateTime']['output']>;
fingerprint?: Maybe<Fingerprint>;
gitCommitHash?: Maybe<Scalars['String']['output']>;
gitCommitMessage?: Maybe<Scalars['String']['output']>;
gitRef?: Maybe<Scalars['String']['output']>;
@@ -2723,6 +2728,7 @@ export type Build = ActivityTimelineProjectActivity & BuildOrBuildJob & {
reactNativeVersion?: Maybe<Scalars['String']['output']>;
releaseChannel?: Maybe<Scalars['String']['output']>;
requiredPackageManager?: Maybe<Scalars['String']['output']>;
resolvedEnvironment?: Maybe<EnvironmentVariableEnvironment>;
/**
* The builder resource class requested by the developer
* @deprecated Use resourceClassDisplayName instead
@@ -2865,6 +2871,7 @@ export type BuildFilter = {
channel?: InputMaybe<Scalars['String']['input']>;
distribution?: InputMaybe<DistributionType>;
gitCommitHash?: InputMaybe<Scalars['String']['input']>;
hasFingerprint?: InputMaybe<Scalars['Boolean']['input']>;
platform?: InputMaybe<AppPlatform>;
runtimeVersion?: InputMaybe<Scalars['String']['input']>;
sdkVersion?: InputMaybe<Scalars['String']['input']>;
@@ -2876,6 +2883,7 @@ export type BuildFilterInput = {
channel?: InputMaybe<Scalars['String']['input']>;
developmentClient?: InputMaybe<Scalars['Boolean']['input']>;
distributions?: InputMaybe<Array<DistributionType>>;
hasFingerprint?: InputMaybe<Scalars['Boolean']['input']>;
platforms?: InputMaybe<Array<AppPlatform>>;
releaseChannel?: InputMaybe<Scalars['String']['input']>;
runtimeVersion?: InputMaybe<Scalars['String']['input']>;
@@ -6856,6 +6864,8 @@ export type UploadSession = {
__typename?: 'UploadSession';
/** Create an Upload Session for a specific account */
createAccountScopedUploadSession: Scalars['JSONObject']['output'];
/** Create an Upload Session for a specific app */
createAppScopedUploadSession: Scalars['JSONObject']['output'];
/** Create an Upload Session */
createUploadSession: Scalars['JSONObject']['output'];
};
@@ -6867,6 +6877,12 @@ export type UploadSessionCreateAccountScopedUploadSessionArgs = {
};
export type UploadSessionCreateAppScopedUploadSessionArgs = {
appID: Scalars['ID']['input'];
type: AppUploadSessionType;
};
export type UploadSessionCreateUploadSessionArgs = {
type: UploadSessionType;
};
@@ -9119,6 +9135,13 @@ export type BuildsWithSubmissionsByIdQueryVariables = Exact<{
export type BuildsWithSubmissionsByIdQuery = { __typename?: 'RootQuery', builds: { __typename?: 'BuildQuery', byId: { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, gitCommitMessage?: string | null, initialQueuePosition?: number | null, queuePosition?: number | null, estimatedWaitTimeLeftSeconds?: number | null, priority: BuildPriority, createdAt: any, updatedAt: any, message?: string | null, completedAt?: any | null, expirationDate?: any | null, isForIosSimulator: boolean, submissions: Array<{ __typename?: 'Submission', id: string, status: SubmissionStatus, platform: AppPlatform, logFiles: Array<string>, app: { __typename?: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } }, androidConfig?: { __typename?: 'AndroidSubmissionConfig', applicationIdentifier?: string | null, track: SubmissionAndroidTrack, releaseStatus?: SubmissionAndroidReleaseStatus | null, rollout?: number | null } | null, iosConfig?: { __typename?: 'IosSubmissionConfig', ascAppIdentifier: string, appleIdUsername?: string | null } | null, error?: { __typename?: 'SubmissionError', errorCode?: string | null, message?: string | null } | null }>, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null, applicationArchiveUrl?: string | null, buildArtifactsUrl?: string | null } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'SSOUser', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string } } } };
export type BuildsWithFingerprintByIdQueryVariables = Exact<{
buildId: Scalars['ID']['input'];
}>;
export type BuildsWithFingerprintByIdQuery = { __typename?: 'RootQuery', builds: { __typename?: 'BuildQuery', byId: { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, gitCommitMessage?: string | null, initialQueuePosition?: number | null, queuePosition?: number | null, estimatedWaitTimeLeftSeconds?: number | null, priority: BuildPriority, createdAt: any, updatedAt: any, message?: string | null, completedAt?: any | null, expirationDate?: any | null, isForIosSimulator: boolean, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null } | null, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null, applicationArchiveUrl?: string | null, buildArtifactsUrl?: string | null } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'SSOUser', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string } } } };
export type ViewBuildsOnAppQueryVariables = Exact<{
appId: Scalars['String']['input'];
offset: Scalars['Int']['input'];
@@ -9320,12 +9343,16 @@ export type BuildFragment = { __typename?: 'Build', id: string, status: BuildSta
export type BuildWithSubmissionsFragment = { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, gitCommitMessage?: string | null, initialQueuePosition?: number | null, queuePosition?: number | null, estimatedWaitTimeLeftSeconds?: number | null, priority: BuildPriority, createdAt: any, updatedAt: any, message?: string | null, completedAt?: any | null, expirationDate?: any | null, isForIosSimulator: boolean, submissions: Array<{ __typename?: 'Submission', id: string, status: SubmissionStatus, platform: AppPlatform, logFiles: Array<string>, app: { __typename?: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } }, androidConfig?: { __typename?: 'AndroidSubmissionConfig', applicationIdentifier?: string | null, track: SubmissionAndroidTrack, releaseStatus?: SubmissionAndroidReleaseStatus | null, rollout?: number | null } | null, iosConfig?: { __typename?: 'IosSubmissionConfig', ascAppIdentifier: string, appleIdUsername?: string | null } | null, error?: { __typename?: 'SubmissionError', errorCode?: string | null, message?: string | null } | null }>, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null, applicationArchiveUrl?: string | null, buildArtifactsUrl?: string | null } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'SSOUser', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string } };
export type BuildWithFingerprintFragment = { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, gitCommitMessage?: string | null, initialQueuePosition?: number | null, queuePosition?: number | null, estimatedWaitTimeLeftSeconds?: number | null, priority: BuildPriority, createdAt: any, updatedAt: any, message?: string | null, completedAt?: any | null, expirationDate?: any | null, isForIosSimulator: boolean, fingerprint?: { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null } | null, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null, applicationArchiveUrl?: string | null, buildArtifactsUrl?: string | null } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'SSOUser', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string } };
export type EnvironmentSecretFragment = { __typename?: 'EnvironmentSecret', id: string, name: string, type: EnvironmentSecretType, createdAt: any };
export type EnvironmentVariableFragment = { __typename?: 'EnvironmentVariable', id: string, name: string, value?: string | null, environments?: Array<EnvironmentVariableEnvironment> | null, createdAt: any, updatedAt: any, scope: EnvironmentVariableScope, visibility?: EnvironmentVariableVisibility | null, type: EnvironmentSecretType };
export type EnvironmentVariableWithSecretFragment = { __typename?: 'EnvironmentVariableWithSecret', id: string, name: string, value?: string | null, environments?: Array<EnvironmentVariableEnvironment> | null, createdAt: any, updatedAt: any, scope: EnvironmentVariableScope, visibility: EnvironmentVariableVisibility, type: EnvironmentSecretType };
export type FingerprintFragment = { __typename?: 'Fingerprint', id: string, hash: string, debugInfoUrl?: string | null };
export type RuntimeFragment = { __typename?: 'Runtime', id: string, version: string };
export type StatuspageServiceFragment = { __typename?: 'StatuspageService', id: string, name: StatuspageServiceName, status: StatuspageServiceStatus, incidents: Array<{ __typename?: 'StatuspageIncident', id: string, status: StatuspageIncidentStatus, name: string, impact: StatuspageIncidentImpact, shortlink: string }> };
@@ -3,7 +3,7 @@ import gql from 'graphql-tag';
import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
import { withErrorHandlingAsync } from '../client';
import { AppPrivacy, CreateAppMutation, CreateAppMutationVariables } from '../generated';
import { CreateAppMutation, CreateAppMutationVariables } from '../generated';
export const AppMutation = {
async createAppAsync(
@@ -11,7 +11,6 @@ export const AppMutation = {
appInput: {
accountId: string;
projectName: string;
privacy: AppPrivacy;
}
): Promise<string> {
const data = await withErrorHandlingAsync(
@@ -5,15 +5,22 @@ import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/creat
import { withErrorHandlingAsync } from '../client';
import {
BuildFragment,
BuildWithFingerprintFragment,
BuildWithSubmissionsFragment,
BuildsByIdQuery,
BuildsByIdQueryVariables,
BuildsWithFingerprintByIdQuery,
BuildsWithFingerprintByIdQueryVariables,
BuildsWithSubmissionsByIdQuery,
BuildsWithSubmissionsByIdQueryVariables,
ViewBuildsOnAppQuery,
ViewBuildsOnAppQueryVariables,
} from '../generated';
import { BuildFragmentNode, BuildFragmentWithSubmissionsNode } from '../types/Build';
import {
BuildFragmentNode,
BuildFragmentWithFingerprintNode,
BuildFragmentWithSubmissionsNode,
} from '../types/Build';
export const BuildQuery = {
async byIdAsync(
@@ -76,6 +83,36 @@ export const BuildQuery = {
return data.builds.byId;
},
async withFingerprintByIdAsync(
graphqlClient: ExpoGraphqlClient,
buildId: string,
{ useCache = true }: { useCache?: boolean } = {}
): Promise<BuildWithFingerprintFragment> {
const data = await withErrorHandlingAsync(
graphqlClient
.query<BuildsWithFingerprintByIdQuery, BuildsWithFingerprintByIdQueryVariables>(
gql`
query BuildsWithFingerprintByIdQuery($buildId: ID!) {
builds {
byId(buildId: $buildId) {
id
...BuildWithFingerprintFragment
}
}
}
${print(BuildFragmentWithFingerprintNode)}
`,
{ buildId },
{
requestPolicy: useCache ? 'cache-first' : 'network-only',
additionalTypenames: ['Build'],
}
)
.toPromise()
);
return data.builds.byId;
},
async viewBuildsOnAppAsync(
graphqlClient: ExpoGraphqlClient,
{ appId, limit, offset, filter }: ViewBuildsOnAppQueryVariables
@@ -1,6 +1,7 @@
import { print } from 'graphql';
import gql from 'graphql-tag';
import { FingerprintFragmentNode } from './Fingerprint';
import { SubmissionFragmentNode } from './Submission';
export const BuildFragmentNode = gql`
@@ -72,3 +73,17 @@ export const BuildFragmentWithSubmissionsNode = gql`
}
}
`;
export const BuildFragmentWithFingerprintNode = gql`
${print(FingerprintFragmentNode)}
${print(BuildFragmentNode)}
fragment BuildWithFingerprintFragment on Build {
id
...BuildFragment
fingerprint {
id
...FingerprintFragment
}
}
`;
@@ -0,0 +1,9 @@
import gql from 'graphql-tag';
export const FingerprintFragmentNode = gql`
fragment FingerprintFragment on Fingerprint {
id
hash
debugInfoUrl
}
`;
@@ -2,7 +2,7 @@ import chalk from 'chalk';
import { getProjectDashboardUrl } from '../build/utils/url';
import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
import { AppPrivacy, Role } from '../graphql/generated';
import { Role } from '../graphql/generated';
import { AppMutation } from '../graphql/mutations/AppMutation';
import { AppQuery } from '../graphql/queries/AppQuery';
import { link } from '../log';
@@ -21,7 +21,6 @@ export async function fetchOrCreateProjectIDForWriteToConfigWithConfirmationAsyn
projectInfo: {
accountName: string;
projectName: string;
privacy?: AppPrivacy;
},
options: {
nonInteractive: boolean;
@@ -90,7 +89,6 @@ export async function fetchOrCreateProjectIDForWriteToConfigWithConfirmationAsyn
const id = await AppMutation.createAppAsync(graphqlClient, {
accountId: account.id,
projectName,
privacy: projectInfo.privacy ?? AppPrivacy.Public,
});
spinner.succeed(`Created ${chalk.bold(projectLink)} on Expo`);
return id;
+1 -11
View File
@@ -7,7 +7,7 @@ import semver from 'semver';
import { getEASUpdateURL } from '../api';
import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
import { AccountFragment, AppPrivacy } from '../graphql/generated';
import { AccountFragment } from '../graphql/generated';
import { AppQuery } from '../graphql/queries/AppQuery';
import Log, { learnMore } from '../log';
import { Actor } from '../user/User';
@@ -31,16 +31,6 @@ export function getUsername(exp: ExpoConfig, user: Actor): string | undefined {
}
}
export const toAppPrivacy = (privacy: ExpoConfig['privacy']): AppPrivacy => {
if (privacy === 'public') {
return AppPrivacy.Public;
} else if (privacy === 'hidden') {
return AppPrivacy.Hidden;
} else {
return AppPrivacy.Unlisted;
}
};
/**
* Return a useful name describing the project config.
* - dynamic: app.config.js
+8 -2
View File
@@ -634,7 +634,13 @@ export async function getBranchNameForCommandAsync({
}
if (autoFlag) {
return await getDefaultBranchNameAsync(vcsClient);
const defaultBranchNameFromVcs = await getDefaultBranchNameAsync(vcsClient);
if (!defaultBranchNameFromVcs) {
throw new Error(
'Must supply --branch or --channel for branch name as auto-detection of branch name via --auto is not supported when no VCS is present.'
);
}
return defaultBranchNameFromVcs;
} else if (nonInteractive) {
throw new Error('Must supply --channel, --branch or --auto when in non-interactive mode.');
} else {
@@ -658,7 +664,7 @@ export async function getBranchNameForCommandAsync({
type: 'text',
name: 'name',
message: 'No branches found. Provide a branch name:',
initial: await getDefaultBranchNameAsync(vcsClient),
initial: (await getDefaultBranchNameAsync(vcsClient)) ?? undefined,
validate: value => (value ? true : 'Branch name may not be empty.'),
});
branchName = name;
@@ -149,7 +149,7 @@ export class CreateRollout implements EASUpdateAction<UpdateChannelBasicInfoFrag
return newChannelInfo;
}
async confirmCreationAsync(ctx: EASUpdateContext): Promise<boolean> {
private async confirmCreationAsync(ctx: EASUpdateContext): Promise<boolean> {
const { nonInteractive } = ctx;
if (nonInteractive) {
return true;
@@ -159,7 +159,7 @@ export class CreateRollout implements EASUpdateAction<UpdateChannelBasicInfoFrag
});
}
async getChannelObjectAsync(
private async getChannelObjectAsync(
ctx: EASUpdateContext,
runtimeVersion: string
): Promise<UpdateChannelObject> {
@@ -172,7 +172,7 @@ export class CreateRollout implements EASUpdateAction<UpdateChannelBasicInfoFrag
});
}
async getLatestUpdateGroupOnBranchAsync(
private async getLatestUpdateGroupOnBranchAsync(
ctx: EASUpdateContext,
branchInfo: UpdateBranchBasicInfoFragment,
runtimeVersion: string
@@ -195,7 +195,7 @@ export class CreateRollout implements EASUpdateAction<UpdateChannelBasicInfoFrag
return updateGroups[0] ?? null;
}
async selectRuntimeVersionAsync(
private async selectRuntimeVersionAsync(
ctx: EASUpdateContext,
branchToRollout: UpdateBranchBasicInfoFragment,
defaultBranchId: string
@@ -223,7 +223,7 @@ export class CreateRollout implements EASUpdateAction<UpdateChannelBasicInfoFrag
);
}
async selectRuntimeVersionFromAlternativeSourceAsync(
private async selectRuntimeVersionFromAlternativeSourceAsync(
ctx: EASUpdateContext,
branchToRollout: UpdateBranchBasicInfoFragment,
defaultBranch: UpdateBranchBasicInfoFragment
@@ -271,7 +271,7 @@ export class CreateRollout implements EASUpdateAction<UpdateChannelBasicInfoFrag
);
}
async selectRuntimeVersionFromProjectConfigAsync(ctx: EASUpdateContext): Promise<string> {
private async selectRuntimeVersionFromProjectConfigAsync(ctx: EASUpdateContext): Promise<string> {
const platforms: ('ios' | 'android')[] = ['ios', 'android'];
const workflows = await resolveWorkflowPerPlatformAsync(ctx.app.projectDir, ctx.vcsClient);
const runtimes = (
@@ -313,7 +313,7 @@ export class CreateRollout implements EASUpdateAction<UpdateChannelBasicInfoFrag
return selectedRuntime;
}
async selectBranchAsync(
private async selectBranchAsync(
ctx: EASUpdateContext,
defaultBranchId: string
): Promise<UpdateBranchBasicInfoFragment> {
@@ -333,7 +333,7 @@ export class CreateRollout implements EASUpdateAction<UpdateChannelBasicInfoFrag
return branchInfo;
}
async resolveBranchNameAsync(
private async resolveBranchNameAsync(
ctx: EASUpdateContext,
branchName: string
): Promise<UpdateBranchBasicInfoFragment> {
@@ -86,7 +86,7 @@ export class EditRollout implements EASUpdateAction<UpdateChannelBasicInfoFragme
return newChannelInfo;
}
async confirmEditAsync(ctx: EASUpdateContext): Promise<boolean> {
private async confirmEditAsync(ctx: EASUpdateContext): Promise<boolean> {
const { nonInteractive } = ctx;
if (nonInteractive) {
return true;
@@ -96,7 +96,7 @@ export class EditRollout implements EASUpdateAction<UpdateChannelBasicInfoFragme
});
}
async getChannelObjectAsync(ctx: EASUpdateContext): Promise<UpdateChannelObject> {
private async getChannelObjectAsync(ctx: EASUpdateContext): Promise<UpdateChannelObject> {
const { graphqlClient, app } = ctx;
const { projectId } = app;
if (!isRollout(this.channelInfo)) {
@@ -87,7 +87,7 @@ export class EndRollout implements EASUpdateAction<UpdateChannelBasicInfoFragmen
return await this.performOutcomeAsync(ctx, rollout, outcome);
}
async getChannelObjectAsync(ctx: EASUpdateContext): Promise<UpdateChannelObject> {
private async getChannelObjectAsync(ctx: EASUpdateContext): Promise<UpdateChannelObject> {
const { graphqlClient, app } = ctx;
const { projectId } = app;
if (!isRollout(this.channelInfo)) {
@@ -107,7 +107,7 @@ export class EndRollout implements EASUpdateAction<UpdateChannelBasicInfoFragmen
});
}
async selectOutcomeAsync(rollout: Rollout<UpdateBranchObject>): Promise<EndOutcome> {
private async selectOutcomeAsync(rollout: Rollout<UpdateBranchObject>): Promise<EndOutcome> {
const { rolledOutBranch, percentRolledOut, defaultBranch } = rollout;
const rolledOutUpdateGroup = rolledOutBranch.updateGroups[0];
const defaultUpdateGroup = defaultBranch.updateGroups[0];
@@ -144,7 +144,7 @@ export class EndRollout implements EASUpdateAction<UpdateChannelBasicInfoFragmen
return selectedOutcome;
}
async performOutcomeAsync(
private async performOutcomeAsync(
ctx: EASUpdateContext,
rollout: Rollout<UpdateBranchObject>,
outcome: EndOutcome
@@ -185,7 +185,7 @@ export class EndRollout implements EASUpdateAction<UpdateChannelBasicInfoFragmen
return newChannelInfo;
}
async confirmOutcomeAsync(
private async confirmOutcomeAsync(
ctx: EASUpdateContext,
selectedOutcome: EndOutcome,
rollout: Rollout<UpdateBranchObject>
@@ -61,7 +61,7 @@ export class ManageRollout implements EASUpdateAction<EASUpdateAction> {
}
}
async selectActionAsync(): Promise<ManageRolloutActions> {
private async selectActionAsync(): Promise<ManageRolloutActions> {
const manageOptions = [ManageRolloutActions.EDIT, ManageRolloutActions.END];
if (this.options.callingAction) {
manageOptions.push(ManageRolloutActions.GO_BACK);
@@ -78,7 +78,7 @@ export class ManageRollout implements EASUpdateAction<EASUpdateAction> {
return selectedManageOption;
}
async getChannelObjectAsync(ctx: EASUpdateContext): Promise<UpdateChannelObject> {
private async getChannelObjectAsync(ctx: EASUpdateContext): Promise<UpdateChannelObject> {
const { graphqlClient, app } = ctx;
const { projectId } = app;
if (!isRollout(this.channelInfo)) {
@@ -91,7 +91,7 @@ export class NonInteractiveRollout implements EASUpdateAction<void> {
}
}
async runActionAsync(
private async runActionAsync(
ctx: EASUpdateContext,
action: RolloutActions,
channelObject: UpdateChannelObject
@@ -108,7 +108,7 @@ export class NonInteractiveRollout implements EASUpdateAction<void> {
}
}
viewRollout(channelObject: UpdateChannelObject): UpdateChannelObject {
private viewRollout(channelObject: UpdateChannelObject): UpdateChannelObject {
if (!this.options.json) {
printRollout(channelObject);
Log.warn('For formatted output, add the --json flag to your command.');
@@ -116,7 +116,7 @@ export class NonInteractiveRollout implements EASUpdateAction<void> {
return channelObject;
}
async getJsonAsync({
private async getJsonAsync({
originalChannelObject,
updatedChannelObject,
}: {
@@ -134,7 +134,9 @@ export class NonInteractiveRollout implements EASUpdateAction<void> {
};
}
async getRolloutJsonAsync(channelObject: UpdateChannelObject): Promise<JSONRolloutOutput> {
private async getRolloutJsonAsync(
channelObject: UpdateChannelObject
): Promise<JSONRolloutOutput> {
const rollout = getRollout(channelObject);
return {
defaultBranch: rollout.defaultBranch,
@@ -145,7 +147,7 @@ export class NonInteractiveRollout implements EASUpdateAction<void> {
};
}
getRuntimeVersion(channelInfo: UpdateChannelBasicInfoFragment): string | undefined {
private getRuntimeVersion(channelInfo: UpdateChannelBasicInfoFragment): string | undefined {
if (isRollout(channelInfo)) {
const updatedRolloutInfo = getRolloutInfo(channelInfo);
if (isConstrainedRolloutInfo(updatedRolloutInfo)) {
@@ -155,7 +157,7 @@ export class NonInteractiveRollout implements EASUpdateAction<void> {
return undefined;
}
async getChannelObjectAsync(
private async getChannelObjectAsync(
ctx: EASUpdateContext,
{ channelName, runtimeVersion }: { channelName: string; runtimeVersion?: string }
): Promise<UpdateChannelObject> {
@@ -54,7 +54,7 @@ export class RolloutMainMenu implements EASUpdateAction<void> {
await this.runActionAsync(ctx, menuOption);
}
async runActionAsync(ctx: EASUpdateContext, menuAction: MainMenuActions): Promise<null> {
private async runActionAsync(ctx: EASUpdateContext, menuAction: MainMenuActions): Promise<null> {
const { channelName } = this.options;
switch (menuAction) {
case MainMenuActions.CREATE_NEW: {
@@ -87,13 +87,15 @@ export class RolloutMainMenu implements EASUpdateAction<void> {
}
}
async selectRolloutAsync(ctx: EASUpdateContext): Promise<UpdateChannelBasicInfoFragment | null> {
private async selectRolloutAsync(
ctx: EASUpdateContext
): Promise<UpdateChannelBasicInfoFragment | null> {
const selectRollout = new SelectRollout();
const channelInfo = await selectRollout.runAsync(ctx);
return channelInfo;
}
async selectChannelToRolloutAsync(
private async selectChannelToRolloutAsync(
ctx: EASUpdateContext
): Promise<UpdateChannelBasicInfoFragment> {
let hasSomeChannel = false;
@@ -113,7 +115,7 @@ export class RolloutMainMenu implements EASUpdateAction<void> {
return channelInfo;
}
async resolveChannelNameAsync(
private async resolveChannelNameAsync(
ctx: EASUpdateContext,
channelName: string
): Promise<UpdateChannelBasicInfoFragment> {
@@ -124,7 +126,7 @@ export class RolloutMainMenu implements EASUpdateAction<void> {
});
}
toMainMenuAction(action: RolloutActions): MainMenuActions {
private toMainMenuAction(action: RolloutActions): MainMenuActions {
if (action === MainMenuActions.CREATE_NEW) {
return MainMenuActions.CREATE_NEW;
} else if (
@@ -138,7 +140,7 @@ export class RolloutMainMenu implements EASUpdateAction<void> {
}
}
async promptMenuActionAsync(): Promise<MainMenuActions> {
private async promptMenuActionAsync(): Promise<MainMenuActions> {
const menuOptions = [MainMenuActions.CREATE_NEW, MainMenuActions.MANAGE_EXISTING];
const { menuOption: selectedMenuOption } = await promptAsync({
type: 'select',
@@ -27,7 +27,7 @@ export class SelectRuntime implements EASUpdateAction<string | null> {
: `runtime`;
}
warnNoRuntime(): void {
private warnNoRuntime(): void {
if (this.options.anotherBranchToIntersectRuntimesBy) {
const intersectBranchName = this.options.anotherBranchToIntersectRuntimesBy.name;
Log.warn(
@@ -42,7 +42,7 @@ export class SelectRuntime implements EASUpdateAction<string | null> {
}
}
formatCantFindRuntime(): string {
private formatCantFindRuntime(): string {
return `🕵️ Not finding the update you were looking for? ${learnMore(
'https://expo.fyi/eas-update-rollouts'
)}`;
@@ -104,7 +104,7 @@ export class SelectRuntime implements EASUpdateAction<string | null> {
return selectedRuntime.version;
}
async getNewestRuntimeAsync(
private async getNewestRuntimeAsync(
graphqlClient: ExpoGraphqlClient,
{
appId,
@@ -126,7 +126,7 @@ export class SelectRuntime implements EASUpdateAction<string | null> {
});
}
async displayLatestUpdateGroupAsync({
private async displayLatestUpdateGroupAsync({
graphqlClient,
appId,
branchName,
@@ -153,7 +153,7 @@ export class SelectRuntime implements EASUpdateAction<string | null> {
return formatRuntimeWithUpdateGroup(updateGroups[0], runtime, branchName);
}
async selectRuntimesAsync(
private async selectRuntimesAsync(
graphqlClient: ExpoGraphqlClient,
{
appId,
+2 -1
View File
@@ -3,6 +3,7 @@ import { Env, Platform, Workflow } from '@expo/eas-build-job';
import { EasJsonAccessor } from '@expo/eas-json';
import chalk from 'chalk';
import fs from 'fs-extra';
import nullthrows from 'nullthrows';
import semver from 'semver';
import { syncUpdatesConfigurationAsync as syncAndroidUpdatesConfigurationAsync } from './android/UpdatesModule';
@@ -149,7 +150,7 @@ async function ensureEASUpdatesIsConfiguredInExpoConfigAsync({
return {
projectChanged: true,
// TODO(cedric): fix return type of `modifyConfigAsync` to avoid `null` for type === success repsonses
exp: result.config?.expo!,
exp: nullthrows(result.config, 'Expected config to be defined'),
};
case 'warn':
@@ -34,7 +34,7 @@ export async function getBranchFromChannelNameAndCreateAndLinkIfNotExistsAsync(
throw error;
}
const { branchId } = await ensureBranchExistsAsync(graphqlClient, {
const { branch } = await ensureBranchExistsAsync(graphqlClient, {
appId: projectId,
branchName: channelName,
});
@@ -43,7 +43,7 @@ export async function getBranchFromChannelNameAndCreateAndLinkIfNotExistsAsync(
} = await createChannelOnAppAsync(graphqlClient, {
appId: projectId,
channelName,
branchId,
branchId: branch.id,
});
if (!newChannel) {
@@ -52,7 +52,7 @@ export async function getBranchFromChannelNameAndCreateAndLinkIfNotExistsAsync(
);
}
branchInfo = { branchId, branchName: channelName };
branchInfo = { branchId: branch.id, branchName: channelName };
}
return branchInfo;
@@ -0,0 +1,119 @@
import Log from '../../log';
import { abridgedDiff } from '../fingerprintDiff';
jest.mock('chalk', () => ({
red: jest.fn(text => `red(${text})`),
green: jest.fn(text => `green(${text})`),
gray: jest.fn(text => `gray(${text})`),
cyan: jest.fn(text => `cyan(${text})`),
}));
jest.spyOn(Log, 'log').mockImplementation(jest.fn());
describe('abridgedDiff', () => {
beforeEach(() => {
jest.clearAllMocks();
});
it('should output the diff for added and removed lines with context', () => {
const str1 = 'Line1\nLine2\nLine3';
const str2 = 'Line1\nLineX\nLine3';
abridgedDiff(str1, str2, 1);
const expectedOutput = [
'cyan(@@ -2,1 +2,1 @@)',
' gray(Line1)',
'red(-Line2)',
'green(+LineX)',
' gray(Line3)',
].join('\n');
expect(Log.log).toHaveBeenCalledTimes(1);
expect(Log.log).toHaveBeenCalledWith(expectedOutput);
});
it('should output the diff for completely different strings', () => {
const str1 = 'LineA\nLineB';
const str2 = 'LineC\nLineD';
abridgedDiff(str1, str2, 0);
const expectedOutput = [
'cyan(@@ -1,2 +1,2 @@)',
'red(-LineA)',
'red(-LineB)',
'green(+LineC)',
'green(+LineD)',
].join('\n');
expect(Log.log).toHaveBeenCalledTimes(1);
expect(Log.log).toHaveBeenCalledWith(expectedOutput);
});
it('should not include context lines if contextLines is 0', () => {
const str1 = 'Line1\nLine2\nLine3';
const str2 = 'Line1\nLineX\nLine3';
abridgedDiff(str1, str2, 0);
const expectedOutput = ['cyan(@@ -2,1 +2,1 @@)', 'red(-Line2)', 'green(+LineX)'].join('\n');
expect(Log.log).toHaveBeenCalledTimes(1);
expect(Log.log).toHaveBeenCalledWith(expectedOutput);
});
it('should handle strings with no differences', () => {
const str1 = 'SameLine1\nSameLine2';
const str2 = 'SameLine1\nSameLine2';
abridgedDiff(str1, str2, 1);
expect(Log.log).toHaveBeenCalledTimes(1);
expect(Log.log).toHaveBeenCalledWith('');
});
it('should handle empty input strings', () => {
const str1 = '';
const str2 = 'NewLine1\nNewLine2';
abridgedDiff(str1, str2, 1);
const expectedOutput = ['cyan(@@ -1,0 +1,2 @@)', 'green(+NewLine1)', 'green(+NewLine2)'].join(
'\n'
);
expect(Log.log).toHaveBeenCalledTimes(1);
expect(Log.log).toHaveBeenCalledWith(expectedOutput);
});
it('should handle strings with only removed lines', () => {
const str1 = 'OldLine1\nOldLine2';
const str2 = '';
abridgedDiff(str1, str2, 1);
const expectedOutput = ['cyan(@@ -1,2 +1,0 @@)', 'red(-OldLine1)', 'red(-OldLine2)'].join('\n');
expect(Log.log).toHaveBeenCalledTimes(1);
expect(Log.log).toHaveBeenCalledWith(expectedOutput);
});
it('should handle strings with mixed changes and context lines', () => {
const str1 = 'Header\nLine1\nLine2\nFooter';
const str2 = 'Header\nLine1\nLineX\nFooter';
abridgedDiff(str1, str2, 1);
const expectedOutput = [
'cyan(@@ -3,1 +3,1 @@)',
' gray(Line1)',
'red(-Line2)',
'green(+LineX)',
' gray(Footer)',
].join('\n');
expect(Log.log).toHaveBeenCalledTimes(1);
expect(Log.log).toHaveBeenCalledWith(expectedOutput);
});
});
+114
View File
@@ -0,0 +1,114 @@
/**
* DO NOT EDIT unless the same change is made in `@expo/fingerprint`
*/
export interface HashSourceFile {
type: 'file';
filePath: string;
/**
* Reasons of this source coming from
*/
reasons: string[];
}
export interface HashSourceDir {
type: 'dir';
filePath: string;
/**
* Reasons of this source coming from
*/
reasons: string[];
}
export interface HashSourceContents {
type: 'contents';
id: string;
contents: string | Buffer;
/**
* Reasons of this source coming from
*/
reasons: string[];
}
export type HashSource = HashSourceFile | HashSourceDir | HashSourceContents;
export interface Fingerprint {
/**
* Sources and their hash values to generate a fingerprint
*/
sources: FingerprintSource[];
/**
* The final hash value of the whole fingerprint
*/
hash: string;
}
export interface DebugInfoFile {
path: string;
hash: string;
}
export interface DebugInfoDir {
path: string;
hash: string;
children: (DebugInfoFile | DebugInfoDir | undefined)[];
}
export interface DebugInfoContents {
hash: string;
}
export type DebugInfo = DebugInfoFile | DebugInfoDir | DebugInfoContents;
export type FingerprintSource = HashSource & {
/**
* Hash value of the `source`.
* If the source is excluding by `Options.dirExcludes`, the value will be null.
*/
hash: string | null;
/**
* Debug info from the hashing process. Differs based on source type. Designed to be consumed by humans
* as opposed to programmatically.
*/
debugInfo?: DebugInfo;
};
export type FingerprintDiffItem =
| {
/**
* The operation type of the diff item.
*/
op: 'added';
/**
* The added source.
*/
addedSource: FingerprintSource;
}
| {
/**
* The operation type of the diff item.
*/
op: 'removed';
/**
* The removed source.
*/
removedSource: FingerprintSource;
}
| {
/**
* The operation type of the diff item.
*/
op: 'changed';
/**
* The source before.
*/
beforeSource: FingerprintSource;
/**
* The source after.
*/
afterSource: FingerprintSource;
};
+28 -13
View File
@@ -2,6 +2,7 @@ import { Env, Workflow } from '@expo/eas-build-job';
import { silent as silentResolveFrom } from 'resolve-from';
import mapMapAsync from './expodash/mapMapAsync';
import { Fingerprint, FingerprintDiffItem } from './fingerprint';
import Log from '../log';
import { ora } from '../ora';
@@ -13,14 +14,30 @@ export type FingerprintOptions = {
cwd?: string;
};
export function diffFingerprint(
projectDir: string,
fingerprint1: Fingerprint,
fingerprint2: Fingerprint
): FingerprintDiffItem[] | null {
// @expo/fingerprint is exported in the expo package for SDK 52+
const fingerprintPath = silentResolveFrom(projectDir, 'expo/fingerprint');
if (!fingerprintPath) {
return null;
}
const Fingerprint = require(fingerprintPath);
return Fingerprint.diffFingerprints(fingerprint1, fingerprint2);
}
export async function createFingerprintAsync(
projectDir: string,
options: FingerprintOptions
): Promise<{
hash: string;
sources: object[];
isDebugSource: boolean;
} | null> {
): Promise<
| (Fingerprint & {
isDebugSource: boolean;
})
| null
> {
// @expo/fingerprint is exported in the expo package for SDK 52+
const fingerprintPath = silentResolveFrom(projectDir, 'expo/fingerprint');
if (!fingerprintPath) {
@@ -61,11 +78,11 @@ async function createFingerprintWithoutLoggingAsync(
projectDir: string,
fingerprintPath: string,
options: FingerprintOptions
): Promise<{
hash: string;
sources: object[];
isDebugSource: boolean;
}> {
): Promise<
Fingerprint & {
isDebugSource: boolean;
}
> {
const Fingerprint = require(fingerprintPath);
const fingerprintOptions: Record<string, any> = {};
if (options.platforms) {
@@ -99,9 +116,7 @@ export async function createFingerprintsByKeyAsync(
): Promise<
Map<
string,
{
hash: string;
sources: object[];
Fingerprint & {
isDebugSource: boolean;
}
>
@@ -0,0 +1,127 @@
import chalk from 'chalk';
import { diffLines } from 'diff';
import Log from '../log';
/**
* Computes and prints a line-based diff between two strings, displaying changes as chunks.
*
* Each chunk contains lines that were added or removed, prefixed with contextual lines
* from the unchanged parts of the strings. The output is styled similarly to `git diff`
* with headers indicating line ranges for the changes in the original and modified strings.
*
* @param {string} str1 - The original string to compare.
* @param {string} str2 - The modified string to compare against the original.
* @param {number} [contextLines=2] - The number of unchanged lines to display before and after each chunk of changes.
*
* ### Output:
* - Each chunk begins with a header in the format `@@ -<original range> +<modified range> @@`.
* - Removed lines are prefixed with a red `-` and the original line number.
* - Added lines are prefixed with a green `+` and the modified line number.
* - Context lines are displayed in gray without a `+` or `-` prefix.
*
* ### Notes:
* - Consecutive changes are grouped into a single chunk if separated by no more than the specified number of context lines.
*
* ### Example:
* ```typescript
* abridgedDiff("Line1\nLine2\nLine3", "Line1\nLineX\nLine3", 1);
*
* Output:
* `@@ -2,1 +2,1 @@`
* Line1
* -Line2
* +LineX
* Line3
* ```
*/
export function abridgedDiff(str1: string, str2: string, contextLines: number = 2): void {
const changes = diffLines(str1, str2);
const output: string[] = [];
let lineNumberOriginal = 1;
let lineNumberModified = 1;
let currentChunk: string[] = [];
let currentChunkPriorContext: string[] = [];
let currentChunkAfterContext: string[] = [];
let startOriginal: number | null = null; // Start line in the original for the current chunk
let startModified: number | null = null; // Start line in the modified for the current chunk
let addedLines = 0;
let removedLines = 0;
const flushChunk = (): void => {
if (currentChunk.length > 0) {
const originalRange = `${startOriginal},${removedLines || 0}`;
const modifiedRange = `${startModified},${addedLines || 0}`;
// `git diff` style header
output.push(chalk.cyan(`@@ -${originalRange} +${modifiedRange} @@`));
output.push(...currentChunkPriorContext);
output.push(...currentChunk);
output.push(...currentChunkAfterContext);
currentChunk = [];
currentChunkPriorContext = [];
currentChunkAfterContext = [];
addedLines = 0;
removedLines = 0;
}
};
for (const change of changes) {
const lines = change.value.split('\n').filter(line => line);
if (change.added || change.removed) {
// Initialize start lines for the chunk if not already set
if (startOriginal === null) {
startOriginal = lineNumberOriginal;
}
if (startModified === null) {
startModified = lineNumberModified;
}
if (change.removed) {
lines.forEach(line => {
currentChunk.push(`${chalk.red(`-${line}`)}`);
lineNumberOriginal++;
removedLines++;
});
}
if (change.added) {
lines.forEach(line => {
currentChunk.push(`${chalk.green(`+${line}`)}`);
lineNumberModified++;
addedLines++;
});
}
} else {
// Unchanged lines (context)
lines.forEach((line, i) => {
if (currentChunk.length > 0) {
// Add leading context after a change
if (i < contextLines) {
currentChunkAfterContext.push(` ${chalk.gray(line)}`);
}
} else {
// Add trailing context before a change
if (lines.length - 1 - contextLines < i) {
currentChunkPriorContext.push(` ${chalk.gray(line)}`);
}
}
const isFinalLineOfAfterContext = i === contextLines - 1 || i === lines.length - 1;
if (currentChunk.length > 0 && isFinalLineOfAfterContext) {
flushChunk();
}
lineNumberOriginal++;
lineNumberModified++;
});
startOriginal = null;
startModified = null;
}
}
flushChunk(); // Flush any remaining chunk
Log.log(output.join('\n'));
}
+1 -1
View File
@@ -60,7 +60,7 @@ export default class GitClient extends Client {
Log.warn('EAS requires you to use a git repository for your project.');
const cwd = process.cwd();
const repoRoot = PackageManagerUtils.findWorkspaceRoot(cwd) ?? cwd;
const repoRoot = PackageManagerUtils.resolveWorkspaceRoot(cwd) ?? cwd;
const confirmInit = await confirmAsync({
message: `Would you like us to run 'git init' in ${
this.maybeCwdOverride ?? repoRoot
+5 -4
View File
@@ -109,20 +109,21 @@ export async function uploadAsync(params: UploadParams): Promise<UploadResult> {
return retry(error);
}
const body = await response.json().catch(() => null);
const errorMessage = body?.error ?? `Upload of "${filePath}" failed: ${response.statusText}`;
if (
response.status === 408 ||
response.status === 409 ||
response.status === 429 ||
(response.status >= 500 && response.status <= 599)
) {
const message = `Upload of "${filePath}" failed: ${response.statusText}`;
const text = await response.text().catch(() => null);
return retry(new Error(text ? `${message}\n${text}` : message));
return retry(new Error(errorMessage));
} else if (response.status === 413) {
const message = `Upload of "${filePath}" failed: File size exceeded the upload limit`;
throw new Error(message);
} else if (!response.ok) {
throw new Error(`Upload of "${filePath}" failed: ${response.statusText}`);
throw new Error(errorMessage);
}
return {
+1 -1
View File
@@ -10,7 +10,7 @@
"noUnusedLocals": true,
"noUnusedParameters": true,
"strict": true,
"target": "ES2021",
"target": "ES2022",
"outDir": "build",
"rootDir": "src",
"typeRoots": ["../../ts-declarations", "../../node_modules/@types", "./node_modules/@types"]
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "@expo/eas-json",
"description": "A library for interacting with eas.json",
"version": "13.4.0",
"version": "14.2.0",
"author": "Expo <[email protected]>",
"bugs": "https://github.com/expo/eas-cli/issues",
"dependencies": {
"@babel/code-frame": "7.23.5",
"@expo/eas-build-job": "1.0.149",
"@expo/eas-build-job": "1.0.156",
"chalk": "4.1.2",
"env-string": "1.0.1",
"fs-extra": "11.2.0",
+3
View File
@@ -6,6 +6,9 @@
"updatedAt": "2022-07-18T15:00:00.000Z"
},
"properties": {
"$schema": {
"type": "string"
},
"cli": {
"$ref": "#/definitions/Cli"
},
+1
View File
@@ -5,6 +5,7 @@ import { UnresolvedSubmitProfileSchema } from './submit/schema';
import { AppVersionSource } from './types';
export const EasJsonSchema = Joi.object({
$schema: Joi.string(),
cli: Joi.object({
version: Joi.string(),
requireCommit: Joi.boolean(),
+1 -1
View File
@@ -10,7 +10,7 @@
"noUnusedLocals": true,
"noUnusedParameters": true,
"strict": true,
"target": "ES2021",
"target": "ES2022",
"outDir": "build",
"rootDir": "src",
"typeRoots": ["../../node_modules/@types", "../../ts-declarations", "./node_modules/@types"]
Generated
+211 -210
View File
@@ -1359,10 +1359,10 @@
resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.56.0.tgz#ef20350fec605a7f7035a01764731b2de0f3782b"
integrity sha512-gMsVel9D7f2HLkBma9VbtzZRehRogVRfbr++f06nL2vnCGCNlzOD+/MUov/F4p8myyAHspEhVobgjpX64q5m6A==
"@expo/[email protected].0":
version "2.1.0"
resolved "https://registry.yarnpkg.com/@expo/apple-utils/-/apple-utils-2.1.0.tgz#9cabfb9fc9dab5e7835b499804ecd6da289eb3fd"
integrity sha512-RzZkPiPtdBuswnTM44LowiScej5M9J/OqTPjWTKSIXhB8veJwb1f5iAE1aqzsceXibOaz0F+4135XahRaPjVvw==
"@expo/[email protected].5":
version "2.1.5"
resolved "https://registry.yarnpkg.com/@expo/apple-utils/-/apple-utils-2.1.5.tgz#a947697f10a7ab0f07f2d2fd075efdae9825e85e"
integrity sha512-Yy4BWVoViYePwQk8rqvhosolS5MTTMgcsl9Aq3rzJrd1BH8C1V/h6N5xelqo+/V+ww2k8Bom7UTE1NlGcKHxRw==
"@expo/bunyan@^4.0.0":
version "4.0.0"
@@ -1382,20 +1382,19 @@
node-forge "^1.2.1"
nullthrows "^1.1.1"
"@expo/config-plugins@8.0.10":
version "8.0.10"
resolved "https://registry.yarnpkg.com/@expo/config-plugins/-/config-plugins-8.0.10.tgz#5cda076f38bc04675cb42d8acdd23d6e460a62de"
integrity sha512-KG1fnSKRmsudPU9BWkl59PyE0byrE2HTnqbOrgwr2FAhqh7tfr9nRs6A9oLS/ntpGzmFxccTEcsV0L4apsuxxg==
"@expo/config-plugins@9.0.12", "@expo/config-plugins@~9.0.10":
version "9.0.12"
resolved "https://registry.yarnpkg.com/@expo/config-plugins/-/config-plugins-9.0.12.tgz#f122b2dca22e135eadf6e73442da3ced0ce8aa0a"
integrity sha512-/Ko/NM+GzvJyRkq8PITm8ms0KY5v0wmN1OQFYRMkcJqOi3PjlhndW+G6bHpJI9mkQXBaUnHwAiGLqIC3+MQ5Wg==
dependencies:
"@expo/config-types" "^51.0.3"
"@expo/json-file" "~8.3.0"
"@expo/plist" "^0.1.0"
"@expo/config-types" "^52.0.0"
"@expo/json-file" "~9.0.0"
"@expo/plist" "^0.2.0"
"@expo/sdk-runtime-versions" "^1.0.0"
chalk "^4.1.2"
debug "^4.3.1"
find-up "~5.0.0"
debug "^4.3.5"
getenv "^1.0.0"
glob "7.1.6"
glob "^10.4.2"
resolve-from "^5.0.0"
semver "^7.5.4"
slash "^3.0.0"
@@ -1403,20 +1402,19 @@
xcode "^3.0.1"
xml2js "0.6.0"
"@expo/config-plugins@~8.0.8":
version "8.0.8"
resolved "https://registry.yarnpkg.com/@expo/config-plugins/-/config-plugins-8.0.8.tgz#294a71905a498ea02c8b79bea950b5e37ab5d748"
integrity sha512-Fvu6IO13EUw0R9WeqxUO37FkM62YJBNcZb9DyJAOgMz7Ez/vaKQGEjKt9cwT+Q6uirtCATMgaq6VWAW7YW8xXw==
"@expo/config-plugins@~9.0.0":
version "9.0.9"
resolved "https://registry.yarnpkg.com/@expo/config-plugins/-/config-plugins-9.0.9.tgz#3765c310c112e200c6715365d6023f6a05b001ed"
integrity sha512-pbgbY3SwCMwkijhfe163J05BrTx4MqzeaV+nVgUMs7vRcjHY1tfM57Pdv6SPtgeDvZ8fvdXFXXzkJva+a7C9Bw==
dependencies:
"@expo/config-types" "^51.0.0-unreleased"
"@expo/json-file" "~8.3.0"
"@expo/plist" "^0.1.0"
"@expo/config-types" "^52.0.0"
"@expo/json-file" "~9.0.0"
"@expo/plist" "^0.2.0"
"@expo/sdk-runtime-versions" "^1.0.0"
chalk "^4.1.2"
debug "^4.3.1"
find-up "~5.0.0"
debug "^4.3.5"
getenv "^1.0.0"
glob "7.1.6"
glob "^10.4.2"
resolve-from "^5.0.0"
semver "^7.5.4"
slash "^3.0.0"
@@ -1424,64 +1422,63 @@
xcode "^3.0.1"
xml2js "0.6.0"
"@expo/config-types@^51.0.0-unreleased":
version "51.0.2"
resolved "https://registry.yarnpkg.com/@expo/config-types/-/config-types-51.0.2.tgz#7385451b180d34d8f2a4eeb5feabe1fe3c5d4f32"
integrity sha512-IglkIoiDwJMY01lYkF/ZSBoe/5cR+O3+Gx6fpLFjLfgZGBTdyPkKa1g8NWoWQCk+D3cKL2MDbszT2DyRRB0YqQ==
"@expo/config-types@^52.0.0":
version "52.0.1"
resolved "https://registry.yarnpkg.com/@expo/config-types/-/config-types-52.0.1.tgz#327af1b72a3a9d4556f41e083e0e284dd8198b96"
integrity sha512-vD8ZetyKV7U29lR6+NJohYeoLYTH+eNYXJeNiSOrWCz0witJYY11meMmEnpEaVbN89EfC6uauSUOa6wihtbyPQ==
"@expo/config-types@^51.0.3":
version "51.0.3"
resolved "https://registry.yarnpkg.com/@expo/config-types/-/config-types-51.0.3.tgz#520bdce5fd75f9d234fd81bd0347443086419450"
integrity sha512-hMfuq++b8VySb+m9uNNrlpbvGxYc8OcFCUX9yTmi9tlx6A4k8SDabWFBgmnr4ao3wEArvWrtUQIfQCVtPRdpKA==
"@expo/[email protected]":
version "9.0.4"
resolved "https://registry.yarnpkg.com/@expo/config/-/config-9.0.4.tgz#52f0a94edd0e2c36dfb5e284cc1a6d99d9d2af97"
integrity sha512-g5ns5u1JSKudHYhjo1zaSfkJ/iZIcWmUmIQptMJZ6ag1C0ShL2sj8qdfU8MmAMuKLOgcIfSaiWlQnm4X3VJVkg==
"@expo/config@10.0.6":
version "10.0.6"
resolved "https://registry.yarnpkg.com/@expo/config/-/config-10.0.6.tgz#85830491bc8cce2af3f19276922a13f5578d2aa8"
integrity sha512-xXkfPElrtxznkOZxFASJ7OPa6E9IHSjcZwj5BQ6XUF2dz5M7AFa2h5sXM8AalSaDU5tEBSgoUOjTh5957TlR8g==
dependencies:
"@babel/code-frame" "~7.10.4"
"@expo/config-plugins" "~8.0.8"
"@expo/config-types" "^51.0.3"
"@expo/json-file" "^8.3.0"
"@expo/config-plugins" "~9.0.10"
"@expo/config-types" "^52.0.0"
"@expo/json-file" "^9.0.0"
deepmerge "^4.3.1"
getenv "^1.0.0"
glob "7.1.6"
glob "^10.4.2"
require-from-string "^2.0.2"
resolve-from "^5.0.0"
resolve-workspace-root "^2.0.0"
semver "^7.6.0"
slugify "^1.3.4"
sucrase "3.34.0"
sucrase "3.35.0"
"@expo/config@~9.0.0-beta.0":
version "9.0.3"
resolved "https://registry.yarnpkg.com/@expo/config/-/config-9.0.3.tgz#4bc2ec654145e6242f4b1964db2962ee0fee1270"
integrity sha512-eOTNM8eOC8gZNHgenySRlc/lwmYY1NOgvjwA8LHuvPT7/eUwD93zrxu3lPD1Cc/P6C/2BcVdfH4hf0tLmDxnsg==
"@expo/config@~10.0.4":
version "10.0.4"
resolved "https://registry.yarnpkg.com/@expo/config/-/config-10.0.4.tgz#a58ec3baef123e77584fbae769484bae2ee74f37"
integrity sha512-pkvdPqKTaP6+Qvc8aTmDLQ9Dfwp98P1GO37MFKwsF5XormfN/9/eN8HfIRoM6d3uSIVKCcWW3X2yAEbNmOyfXw==
dependencies:
"@babel/code-frame" "~7.10.4"
"@expo/config-plugins" "~8.0.8"
"@expo/config-types" "^51.0.0-unreleased"
"@expo/json-file" "^8.3.0"
"@expo/config-plugins" "~9.0.0"
"@expo/config-types" "^52.0.0"
"@expo/json-file" "^9.0.0"
deepmerge "^4.3.1"
getenv "^1.0.0"
glob "7.1.6"
glob "^10.4.2"
require-from-string "^2.0.2"
resolve-from "^5.0.0"
resolve-workspace-root "^2.0.0"
semver "^7.6.0"
slugify "^1.3.4"
sucrase "3.34.0"
sucrase "3.35.0"
"@expo/[email protected]49":
version "1.0.149"
resolved "https://registry.yarnpkg.com/@expo/eas-build-job/-/eas-build-job-1.0.149.tgz#5105f5083ecc9508fd419b6223c5c0b522743f97"
integrity sha512-GW21oUHfX8gNEZYEH9PV2Zh7WpAXjrc6sHn9ycOGXCfnHMvdDzXp62j+Jv5KloIu4PnKul8lPzdxumPpfqPvRQ==
"@expo/[email protected]56":
version "1.0.156"
resolved "https://registry.yarnpkg.com/@expo/eas-build-job/-/eas-build-job-1.0.156.tgz#c8e1f34a480eba217e6aa37e5d178f440065a7e7"
integrity sha512-pD3vWO7fIaQ4wmJy/x6L2dVK2rwf1qNzTE/4I5JI4r6vYSKrSCv8EIoE87xDBaRUBMk72ZdzyznJe516pMyTaw==
dependencies:
"@expo/logger" "1.0.117"
joi "^17.13.1"
semver "^7.6.2"
zod "^3.23.8"
"@expo/env@^0.3.0":
version "0.3.0"
resolved "https://registry.yarnpkg.com/@expo/env/-/env-0.3.0.tgz#a66064e5656e0e48197525f47f3398034fdf579e"
integrity sha512-OtB9XVHWaXidLbHvrVDeeXa09yvTl3+IQN884sO6PhIi2/StXfgSH/9zC7IvzrDB8kW3EBJ1PPLuCUJ2hxAT7Q==
"@expo/env@^0.4.0":
version "0.4.0"
resolved "https://registry.yarnpkg.com/@expo/env/-/env-0.4.0.tgz#1ff3a15084566d12ca92cb67e5b0a9796a9f0aa7"
integrity sha512-g2JYFqck3xKIwJyK+8LxZ2ENZPWtRgjFWpeht9abnKgzXVXBeSNECFBkg+WQjQocSIdxXhEWM6hz4ZAe7Tc4ng==
dependencies:
chalk "^4.0.0"
debug "^4.3.4"
@@ -1489,23 +1486,23 @@
dotenv-expand "~11.0.6"
getenv "^1.0.0"
"@expo/image-utils@^0.5.0":
version "0.5.1"
resolved "https://registry.yarnpkg.com/@expo/image-utils/-/image-utils-0.5.1.tgz#06fade141facebcd8431355923d30f3839309942"
integrity sha512-U/GsFfFox88lXULmFJ9Shfl2aQGcwoKPF7fawSCLixIKtMCpsI+1r0h+5i0nQnmt9tHuzXZDL8+Dg1z6OhkI9A==
"@expo/image-utils@^0.6.0":
version "0.6.3"
resolved "https://registry.yarnpkg.com/@expo/image-utils/-/image-utils-0.6.3.tgz#89c744460beefc686989b969121357bbd5520c8a"
integrity sha512-v/JbCKBrHeudxn1gN1TgfPE/pWJSlLPrl29uXJBgrJFQVkViQvUHQNDhaS+UEa9wYI5HHh7XYmtzAehyG4L+GA==
dependencies:
"@expo/spawn-async" "^1.7.2"
chalk "^4.0.0"
fs-extra "9.0.0"
getenv "^1.0.0"
jimp-compact "0.16.1"
node-fetch "^2.6.0"
parse-png "^2.1.0"
resolve-from "^5.0.0"
semver "^7.6.0"
tempy "0.3.0"
temp-dir "~2.0.0"
unique-string "~2.0.0"
"@expo/[email protected]", "@expo/json-file@^8.3.0":
"@expo/[email protected]":
version "8.3.3"
resolved "https://registry.yarnpkg.com/@expo/json-file/-/json-file-8.3.3.tgz#7926e3592f76030ce63d6b1308ac8f5d4d9341f4"
integrity sha512-eZ5dld9AD0PrVRiIWpRkm5aIoWBw3kAyd8VkuWEy92sEthBKDDDHAnK2a0dw0Eil6j7rK7lS/Qaq/Zzngv2h5A==
@@ -1514,13 +1511,13 @@
json5 "^2.2.2"
write-file-atomic "^2.3.0"
"@expo/json-file@~8.3.0":
version "8.3.0"
resolved "https://registry.yarnpkg.com/@expo/json-file/-/json-file-8.3.0.tgz#fc84af77b532a4e9bfb5beafd0e3b7f692b6bd7e"
integrity sha512-yROUeXJXR5goagB8c3muFLCzLmdGOvoPpR5yDNaXrnTp4euNykr9yW0wWhJx4YVRTNOPtGBnEbbJBW+a9q+S6g==
"@expo/json-file@^9.0.0", "@expo/json-file@~9.0.0":
version "9.0.0"
resolved "https://registry.yarnpkg.com/@expo/json-file/-/json-file-9.0.0.tgz#e3688c9b108cfd7e819f1354a9458ba6e93fc943"
integrity sha512-M+55xFVrFzDcgMDf+52lPDLjKB5xwRfStWlv/b/Vu2OLgxGZLWpxoPYjlRoHqxjPbCQIi2ZCbobK+0KuNhsELg==
dependencies:
"@babel/code-frame" "~7.10.4"
json5 "^2.2.2"
json5 "^2.2.3"
write-file-atomic "^2.3.0"
"@expo/[email protected]":
@@ -1531,61 +1528,50 @@
"@types/bunyan" "^1.8.11"
bunyan "^1.8.15"
"@expo/multipart-body-parser@1.1.0":
version "1.1.0"
resolved "https://registry.yarnpkg.com/@expo/multipart-body-parser/-/multipart-body-parser-1.1.0.tgz#ba402b3047cf14ef17b4d785ec030dd6474ae6e4"
integrity sha512-XOaS79wFIJgx0J7oUzRb+kZsnZmFqGpisu0r8RPO3b0wjbW7xpWgiXmRR4RavKeGiVAPauZOi4vad7cJ3KCspg==
"@expo/multipart-body-parser@2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@expo/multipart-body-parser/-/multipart-body-parser-2.0.0.tgz#dcd2034f3bbc29b9a6fa6ff31e5ba0caea0a2b38"
integrity sha512-yS/wsqlj0d8ZKETEN7ro3dZtjdMhpte8wp+xUzjUQC3jizxcE0E62xgvGquJObiYUMGoCF5qRYr2t78STPEaSw==
dependencies:
dicer "^0.3.1"
nullthrows "^1.1.1"
structured-headers "^0.4.1"
multipasta "^0.2.5"
"@expo/[email protected].3":
version "2.1.3"
resolved "https://registry.yarnpkg.com/@expo/osascript/-/osascript-2.1.3.tgz#912b74825cb83f3b958cad81034df9e19f1f2808"
integrity sha512-aOEkhPzDsaAfolSswObGiYW0Pf0ROfR9J2NBRLQACdQ6uJlyAMiPF45DVEVknAU9juKh0y8ZyvC9LXqLEJYohA==
"@expo/[email protected].4":
version "2.1.4"
resolved "https://registry.yarnpkg.com/@expo/osascript/-/osascript-2.1.4.tgz#4918d16ba09d8b01cb393bc5997055e61d31246f"
integrity sha512-LcPjxJ5FOFpqPORm+5MRLV0CuYWMthJYV6eerF+lQVXKlvgSn3EOqaHC3Vf3H+vmB0f6G4kdvvFtg40vG4bIhA==
dependencies:
"@expo/spawn-async" "^1.7.2"
exec-async "^2.2.0"
"@expo/package-manager@1.5.2":
version "1.5.2"
resolved "https://registry.yarnpkg.com/@expo/package-manager/-/package-manager-1.5.2.tgz#6015963669977a188bbbac930aa0dc103162ee73"
integrity sha512-IuA9XtGBilce0q8cyxtWINqbzMB1Fia0Yrug/O53HNuRSwQguV/iqjV68bsa4z8mYerePhcFgtvISWLAlNEbUA==
"@expo/package-manager@1.6.1":
version "1.6.1"
resolved "https://registry.yarnpkg.com/@expo/package-manager/-/package-manager-1.6.1.tgz#ab845238dec10bb48bca2b90e060dfe8c1525602"
integrity sha512-4rT46wP/94Ll+CWXtFKok1Lbo9XncSUtErFOo/9/3FVughGbIfdG4SKZOAWIpr9wxwEfkyhHfAP9q71ONlWODw==
dependencies:
"@expo/json-file" "^8.3.0"
"@expo/json-file" "^9.0.0"
"@expo/spawn-async" "^1.7.2"
ansi-regex "^5.0.0"
chalk "^4.0.0"
find-up "^5.0.0"
find-yarn-workspace-root "~2.0.0"
js-yaml "^3.13.1"
micromatch "^4.0.2"
npm-package-arg "^7.0.0"
micromatch "^4.0.8"
npm-package-arg "^11.0.0"
ora "^3.4.0"
resolve-workspace-root "^2.0.0"
split "^1.0.1"
sudo-prompt "9.1.1"
"@expo/[email protected].2":
version "0.1.2"
resolved "https://registry.yarnpkg.com/@expo/pkcs12/-/pkcs12-0.1.2.tgz#9d88ed0d980e211690a9580fed425d9e3cc4c5b7"
integrity sha512-CLoOKm35mcIJHV11bR7DunfAtw0HcQ2ir7fWWCw9gwvhrhi75cer2xlLqeHPhmvXDad437Mh8L1Bz+B1EIKdMA==
"@expo/[email protected].3":
version "0.1.3"
resolved "https://registry.yarnpkg.com/@expo/pkcs12/-/pkcs12-0.1.3.tgz#ee56af9bc14d2c17a9015026348cdadb8a53ce4f"
integrity sha512-96MePEGppKi08vawrTPw8kMCRdsbrDbV900MlI8rrP9F57DfDl/y1P52bwIDBYCEHE3XtPMo7s1xkG0BKOLCVg==
dependencies:
node-forge "^1.2.1"
"@expo/plist@0.1.3":
version "0.1.3"
resolved "https://registry.yarnpkg.com/@expo/plist/-/plist-0.1.3.tgz#b4fbee2c4f7a88512a4853d85319f4d95713c529"
integrity sha512-GW/7hVlAylYg1tUrEASclw1MMk9FP4ZwyFAY/SUTJIhPDQHtfOlXREyWV3hhrHdX/K+pS73GNgdfT6E/e+kBbg==
dependencies:
"@xmldom/xmldom" "~0.7.7"
base64-js "^1.2.3"
xmlbuilder "^14.0.0"
"@expo/plist@^0.1.0":
version "0.1.0"
resolved "https://registry.yarnpkg.com/@expo/plist/-/plist-0.1.0.tgz#eabc95f951d14e10c87fd0443ee01d567371f058"
integrity sha512-xWD+8vIFif0wKyuqe3fmnmnSouXYucciZXFzS0ZD5OV9eSAS1RGQI5FaGGJ6zxJ4mpdy/4QzbLdBjnYE5vxA0g==
"@expo/plist@0.2.0", "@expo/plist@^0.2.0":
version "0.2.0"
resolved "https://registry.yarnpkg.com/@expo/plist/-/plist-0.2.0.tgz#beb014c0bfd56a993086c0972ec1ca3ef3f9d36c"
integrity sha512-F/IZJQaf8OIVnVA6XWUeMPC3OH6MV00Wxf0WC0JhTQht2QgjyHUa3U5Gs3vRtDq8tXNsZneOQRDVwpaOnd4zTQ==
dependencies:
"@xmldom/xmldom" "~0.7.7"
base64-js "^1.2.3"
@@ -1612,17 +1598,17 @@
semver "^7.3.7"
tslib "^2.4.0"
"@expo/prebuild-config@7.0.9":
version "7.0.9"
resolved "https://registry.yarnpkg.com/@expo/prebuild-config/-/prebuild-config-7.0.9.tgz#7abd489e18ed6514a0c9cd214eb34c0d5efda799"
integrity sha512-9i6Cg7jInpnGEHN0jxnW0P+0BexnePiBzmbUvzSbRXpdXihYUX2AKMu73jgzxn5P1hXOSkzNS7umaY+BZ+aBag==
"@expo/prebuild-config@8.0.17":
version "8.0.17"
resolved "https://registry.yarnpkg.com/@expo/prebuild-config/-/prebuild-config-8.0.17.tgz#a2ac262e070b58bc071afefa7fe627c7b2ad7bb4"
integrity sha512-HM+XpDox3fAZuXZXvy55VRcBbsZSDijGf8jI8i/pexgWvtsnt1ouelPXRuE1pXDicMX+lZO83QV+XkyLmBEXYQ==
dependencies:
"@expo/config" "~9.0.0-beta.0"
"@expo/config-plugins" "~8.0.8"
"@expo/config-types" "^51.0.3"
"@expo/image-utils" "^0.5.0"
"@expo/json-file" "^8.3.0"
"@react-native/normalize-colors" "0.74.85"
"@expo/config" "~10.0.4"
"@expo/config-plugins" "~9.0.0"
"@expo/config-types" "^52.0.0"
"@expo/image-utils" "^0.6.0"
"@expo/json-file" "^9.0.0"
"@react-native/normalize-colors" "0.76.2"
debug "^4.3.1"
fs-extra "^9.0.0"
resolve-from "^5.0.0"
@@ -1659,12 +1645,12 @@
dependencies:
cross-spawn "^7.0.3"
"@expo/[email protected]0":
version "1.0.150"
resolved "https://registry.yarnpkg.com/@expo/steps/-/steps-1.0.150.tgz#ea148a186689575f2b33a83cd648ee2a60590aa8"
integrity sha512-I9Urfph3e0tcIkZFlzYvMO8WBXJE5Fk3+PanbTvWkwY88aB5IMXrYM7ifHlLf0kpMK4/a9fP9arcVhbAaD/DMg==
"@expo/[email protected]6":
version "1.0.156"
resolved "https://registry.yarnpkg.com/@expo/steps/-/steps-1.0.156.tgz#79a043a7dd4f5c098c954ed7a013c407631f515a"
integrity sha512-fa2rMaWqF0DaqqyDXy2Dy5pBbXTPfnMD1ALQid3ApjokMV5Gq+CTyr7sYFGqr1vywK0sftpmKVAOMJzHV95dDg==
dependencies:
"@expo/eas-build-job" "1.0.149"
"@expo/eas-build-job" "1.0.156"
"@expo/logger" "1.0.117"
"@expo/spawn-async" "^1.7.2"
arg "^5.0.2"
@@ -3449,10 +3435,10 @@
resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.1.0.tgz#7d8dacb7fdef0e4387caf7396cbd77f179867d06"
integrity sha512-Zwq5OCzuwJC2jwqmpEQt7Ds1DTi6BWSwoGkbb1n9pO3hzb35BoJELx7c0T23iDkBGkh2e7tvOtjF3tr3OaQHDQ==
"@react-native/[email protected]4.85":
version "0.74.85"
resolved "https://registry.yarnpkg.com/@react-native/normalize-colors/-/normalize-colors-0.74.85.tgz#62bcb9ab1b10b822ca0278fdfdf23d3b18e125da"
integrity sha512-pcE4i0X7y3hsAE0SpIl7t6dUc0B0NZLd1yv7ssm4FrLhWG+CGyIq4eFDXpmPU1XHmL5PPySxTAjEMiwv6tAmOw==
"@react-native/[email protected]6.2":
version "0.76.2"
resolved "https://registry.yarnpkg.com/@react-native/normalize-colors/-/normalize-colors-0.76.2.tgz#015fa1d454ec605153c8af05666185026e682e66"
integrity sha512-ICoOpaTLPsFQjNLSM00NgQr6wal300cZZonHVSDXKntX+BfkLeuCHRtr/Mn+klTtW+/1v2/2FRm9dXjvyGf9Dw==
"@repeaterjs/repeater@^3.0.4":
version "3.0.5"
@@ -3691,6 +3677,11 @@
resolved "https://registry.yarnpkg.com/@types/dateformat/-/dateformat-3.0.1.tgz#98d747a2e5e9a56070c6bf14e27bff56204e34cc"
integrity sha512-KlPPdikagvL6ELjWsljbyDIPzNCeliYkqRpI+zea99vBBbCIA5JNshZAwQKTON139c87y9qvTFVgkFd14rtS4g==
"@types/[email protected]":
version "6.0.0"
resolved "https://registry.yarnpkg.com/@types/diff/-/diff-6.0.0.tgz#031f27cf57564f3cce825f38fb19fdd4349ad07a"
integrity sha512-dhVCYGv3ZSbzmQaBSagrv1WJ6rXCdkyTcDyoNu1MD8JohI7pR7k8wdZEm+mvdxRKXyHVwckFzWU1vJc+Z29MlA==
"@types/[email protected]":
version "7.8.3"
resolved "https://registry.yarnpkg.com/@types/envinfo/-/envinfo-7.8.3.tgz#6fccc3425e300ee377aad15423e555dc6fc12fa1"
@@ -5854,10 +5845,10 @@ [email protected]:
resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=
crypto-random-string@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e"
integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=
crypto-random-string@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-2.0.0.tgz#ef2a7a966ec11083388369baa02ebead229b30d5"
integrity sha512-v1plID3y9r/lPhviJ1wrXpLeyUIGAZ2SHNYTEapm7/8A9nLPoyvVp3RK/EPFqn5kEznyWgYZNsRtYYIWbuG8KA==
d@1, d@^1.0.1:
version "1.0.1"
@@ -5952,6 +5943,13 @@ debug@^3.2.7:
dependencies:
ms "^2.1.1"
debug@^4.3.5:
version "4.3.7"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52"
integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==
dependencies:
ms "^2.1.3"
debuglog@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492"
@@ -6002,6 +6000,11 @@ deepmerge@^4.2.2:
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955"
integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==
deepmerge@^4.3.1:
version "4.3.1"
resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a"
integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==
defaults@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.3.tgz#c656051e9817d9ff08ed881477f3fe4019f3ef7d"
@@ -6119,13 +6122,6 @@ dezalgo@^1.0.0:
asap "^2.0.0"
wrappy "1"
dicer@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/dicer/-/dicer-0.3.1.tgz#abf28921e3475bc5e801e74e0159fd94f927ba97"
integrity sha512-ObioMtXnmjYs3aRtpIJt9rgQSPCIhKVkFPip+E9GUDyWl8N435znUxK/JfNwGZJ2wnn5JKQ7Ly3vOK5Q5dylGA==
dependencies:
streamsearch "^1.1.0"
diff-sequences@^29.2.0:
version "29.2.0"
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.2.0.tgz#4c55b5b40706c7b5d2c5c75999a50c56d214e8f6"
@@ -6136,6 +6132,11 @@ diff-sequences@^29.6.3:
resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921"
integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==
[email protected]:
version "7.0.0"
resolved "https://registry.yarnpkg.com/diff/-/diff-7.0.0.tgz#3fb34d387cd76d803f6eebea67b921dab0182a9a"
integrity sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==
diff@^4.0.1:
version "4.0.2"
resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d"
@@ -7257,7 +7258,7 @@ find-up@^4.0.0, find-up@^4.1.0:
locate-path "^5.0.0"
path-exists "^4.0.0"
find-up@^5.0.0, find-up@~5.0.0:
find-up@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc"
integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==
@@ -7273,7 +7274,7 @@ [email protected]:
micromatch "^4.0.2"
pkg-dir "^4.2.0"
find-yarn-workspace-root@^2.0.0, find-yarn-workspace-root@~2.0.0:
find-yarn-workspace-root@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/find-yarn-workspace-root/-/find-yarn-workspace-root-2.0.0.tgz#f47fb8d239c900eb78179aa81b66673eac88f7bd"
integrity sha512-1IMnbjt4KzsQfnhnzNd8wUEgXZ44IzZaZmnLYx7D5FZlaHt2gW20Cri8Q+E/t5tIj4+epTBub+2Zxu/vNILzqQ==
@@ -7734,18 +7735,6 @@ [email protected]:
once "^1.3.0"
path-is-absolute "^1.0.0"
[email protected]:
version "7.1.6"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^3.0.4"
once "^1.3.0"
path-is-absolute "^1.0.0"
glob@^10.2.2:
version "10.3.10"
resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b"
@@ -7757,6 +7746,18 @@ glob@^10.2.2:
minipass "^5.0.0 || ^6.0.2 || ^7.0.0"
path-scurry "^1.10.1"
glob@^10.3.10, glob@^10.4.2:
version "10.4.5"
resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.5.tgz#f4d9f0b90ffdbab09c9d77f5f29b4262517b0956"
integrity sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==
dependencies:
foreground-child "^3.1.0"
jackspeak "^3.1.2"
minimatch "^9.0.4"
minipass "^7.1.2"
package-json-from-dist "^1.0.0"
path-scurry "^1.11.1"
glob@^10.3.7:
version "10.4.2"
resolved "https://registry.yarnpkg.com/glob/-/glob-10.4.2.tgz#bed6b95dade5c1f80b4434daced233aee76160e5"
@@ -8123,7 +8124,7 @@ hosted-git-info@^2.1.4:
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9"
integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==
hosted-git-info@^3.0.2, hosted-git-info@^3.0.6:
hosted-git-info@^3.0.6:
version "3.0.8"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-3.0.8.tgz#6e35d4cc87af2c5f816e4cb9ce350ba87a3f370d"
integrity sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw==
@@ -8144,6 +8145,13 @@ hosted-git-info@^6.0.0:
dependencies:
lru-cache "^7.5.1"
hosted-git-info@^7.0.0:
version "7.0.2"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-7.0.2.tgz#9b751acac097757667f30114607ef7b661ff4f17"
integrity sha512-puUZAUKT5m8Zzvs72XWy3HtvVbTWljRE66cP60bxJzAqf2DgICo7lYTY2IHUmLnNpjYvw5bvmoHvPc0QO2a62w==
dependencies:
lru-cache "^10.0.1"
html-escaper@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453"
@@ -10155,6 +10163,11 @@ lowercase-keys@^2.0.0:
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479"
integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==
lru-cache@^10.0.1:
version "10.4.3"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119"
integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==
lru-cache@^10.2.0:
version "10.3.0"
resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.3.0.tgz#4a4aaf10c84658ab70f79a85a9a3f1e1fb11196b"
@@ -10403,7 +10416,7 @@ methods@~1.1.2:
resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee"
integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==
micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5:
micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5, micromatch@^4.0.8:
version "4.0.8"
resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202"
integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==
@@ -10712,7 +10725,7 @@ [email protected]:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
[email protected], ms@^2.0.0, ms@^2.1.1:
[email protected], ms@^2.0.0, ms@^2.1.1, ms@^2.1.3:
version "2.1.3"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
@@ -10728,6 +10741,11 @@ [email protected], multimatch@^5.0.0:
arrify "^2.0.1"
minimatch "^3.0.4"
multipasta@^0.2.5:
version "0.2.5"
resolved "https://registry.yarnpkg.com/multipasta/-/multipasta-0.2.5.tgz#fb3564c4c619b73f98e72e2a4bbd4f7fba153edf"
integrity sha512-c8eMDb1WwZcE02WVjHoOmUVk7fnKU/RmUcosHACglrWAuPQsEJv+E8430sXj6jNc1jHw0zrS16aCjQh4BcEb4A==
[email protected]:
version "0.0.8"
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d"
@@ -10761,10 +10779,10 @@ nan@^2.14.0:
resolved "https://registry.yarnpkg.com/nan/-/nan-2.17.0.tgz#c0150a2368a182f033e9aa5195ec76ea41a199cb"
integrity sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==
[email protected].4:
version "3.3.4"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab"
integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==
[email protected].8:
version "3.3.8"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.8.tgz#b1be3030bee36aaff18bacb375e5cce521684baf"
integrity sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w==
natural-compare@^1.4.0:
version "1.4.0"
@@ -10841,7 +10859,7 @@ [email protected]:
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
[email protected], node-fetch@^2.6.0, node-fetch@^2.6.1, node-fetch@^2.6.7:
[email protected], node-fetch@^2.6.1, node-fetch@^2.6.7:
version "2.6.7"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad"
integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==
@@ -11055,15 +11073,15 @@ npm-package-arg@^10.0.0, npm-package-arg@^10.1.0:
semver "^7.3.5"
validate-npm-package-name "^5.0.0"
npm-package-arg@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-7.0.0.tgz#52cdf08b491c0c59df687c4c925a89102ef794a5"
integrity sha512-xXxr8y5U0kl8dVkz2oK7yZjPBvqM2fwaO5l3Yg13p03v8+E3qQcD0JNhHzjL1vyGgxcKkD0cco+NLR72iuPk3g==
npm-package-arg@^11.0.0:
version "11.0.3"
resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-11.0.3.tgz#dae0c21199a99feca39ee4bfb074df3adac87e2d"
integrity sha512-sHGJy8sOC1YraBywpzQlIKBE4pBbGbiF95U6Auspzyem956E0+FtDtsx1ZxlOJkQCZ1AFXAY/yuvtFYrOxF+Bw==
dependencies:
hosted-git-info "^3.0.2"
osenv "^0.1.5"
semver "^5.6.0"
validate-npm-package-name "^3.0.0"
hosted-git-info "^7.0.0"
proc-log "^4.0.0"
semver "^7.3.5"
validate-npm-package-name "^5.0.0"
npm-package-arg@^8.0.0, npm-package-arg@^8.0.1, npm-package-arg@^8.1.2, npm-package-arg@^8.1.5:
version "8.1.5"
@@ -11467,24 +11485,11 @@ ora@^5.4.1:
strip-ansi "^6.0.0"
wcwidth "^1.0.1"
os-homedir@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
integrity sha1-/7xJiDNuDoM94MFox+8VISGqf7M=
os-tmpdir@^1.0.0, os-tmpdir@~1.0.2:
os-tmpdir@~1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=
osenv@^0.1.5:
version "0.1.5"
resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410"
integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==
dependencies:
os-homedir "^1.0.0"
os-tmpdir "^1.0.0"
p-cancelable@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.1.1.tgz#aab7fbd416582fa32a3db49859c122487c5ed2cf"
@@ -11996,6 +12001,11 @@ proc-log@^3.0.0:
resolved "https://registry.yarnpkg.com/proc-log/-/proc-log-3.0.0.tgz#fb05ef83ccd64fd7b20bbe9c8c1070fc08338dd8"
integrity sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==
proc-log@^4.0.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/proc-log/-/proc-log-4.2.0.tgz#b6f461e4026e75fdfe228b265e9f7a00779d7034"
integrity sha512-g8+OnU/L2v+wyiVK+D5fA34J7EH8jZ8DDlvwhRCMxmMj7UCBvxiO1mGeN+36JXIKF4zevU4kRBd8lVgG9vLelA==
process-nextick-args@^2.0.0, process-nextick-args@~2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
@@ -12470,6 +12480,11 @@ resolve-from@^4.0.0:
resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
resolve-workspace-root@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/resolve-workspace-root/-/resolve-workspace-root-2.0.0.tgz#a0098daa0067cd0efa6eb525c57c8fb4a61e78f8"
integrity sha512-IsaBUZETJD5WsI11Wt8PKHwaIe45or6pwNc8yflvLJ4DWtImK9kuLoH5kUva/2Mmx/RdIyr4aONNSa2v9LTJsw==
resolve.exports@^2.0.0:
version "2.0.2"
resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-2.0.2.tgz#f8c934b8e6a13f539e38b7098e2e36134f01e800"
@@ -13471,11 +13486,6 @@ [email protected], strong-log-transformer@^2.1.0:
minimist "^1.2.0"
through "^2.3.4"
structured-headers@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/structured-headers/-/structured-headers-0.4.1.tgz#77abd9410622c6926261c09b9d16cf10592694d1"
integrity sha512-0MP/Cxx5SzeeZ10p/bZI0S6MpgD+yxAhi1BOQ34jgnMXsCq3j1t6tQnZu+KdlL7dvJTLT3g9xN8tl10TqgFMcg==
[email protected]:
version "0.9.18"
resolved "https://registry.yarnpkg.com/subscriptions-transport-ws/-/subscriptions-transport-ws-0.9.18.tgz#bcf02320c911fbadb054f7f928e51c6041a37b97"
@@ -13487,14 +13497,14 @@ [email protected]:
symbol-observable "^1.0.4"
ws "^5.2.0"
[email protected]4.0:
version "3.34.0"
resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.34.0.tgz#1e0e2d8fcf07f8b9c3569067d92fbd8690fb576f"
integrity sha512-70/LQEZ07TEcxiU2dz51FKaE6hCTWC6vr7FOk3Gr0U60C3shtAN+H+BFr9XlYe5xqf3RA8nrc+VIwzCfnxuXJw==
[email protected]5.0:
version "3.35.0"
resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.35.0.tgz#57f17a3d7e19b36d8995f06679d121be914ae263"
integrity sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==
dependencies:
"@jridgewell/gen-mapping" "^0.3.2"
commander "^4.0.0"
glob "7.1.6"
glob "^10.3.10"
lines-and-columns "^1.1.6"
mz "^2.7.0"
pirates "^4.0.1"
@@ -13619,19 +13629,15 @@ [email protected], tar@^6.0.2, tar@^6.1.0, tar@^6.1.11, tar@^6.1.2:
mkdirp "^1.0.3"
yallist "^4.0.0"
[email protected], temp-dir@^1.0.0:
[email protected]:
version "1.0.0"
resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d"
integrity sha512-xZFXEGbG7SNC3itwBzI3RYjq/cEhBkx2hJuKGIUOcEULmkQExXiHat2z/qkISYsuR+IKumhEfKKbV5qXmhICFQ==
temp[email protected].0:
version "0.3.0"
resolved "https://registry.yarnpkg.com/tempy/-/tempy-0.3.0.tgz#6f6c5b295695a16130996ad5ab01a8bd726e8bf8"
integrity sha512-WrH/pui8YCwmeiAoxV+lpRH9HpRtgBhSR2ViBPgpGb/wnYDzp21R4MN45fsCGvLROvY67o3byhJRYRONJyImVQ==
dependencies:
temp-dir "^1.0.0"
type-fest "^0.3.1"
unique-string "^1.0.0"
temp-dir@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-2.0.0.tgz#bde92b05bdfeb1516e804c9c00ad45177f31321e"
integrity sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg==
[email protected]:
version "2.1.1"
@@ -13966,11 +13972,6 @@ type-fest@^0.21.3:
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37"
integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==
type-fest@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.3.1.tgz#63d00d204e059474fe5e1b7c011112bbd1dc29e1"
integrity sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==
type-fest@^0.4.1:
version "0.4.1"
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.4.1.tgz#8bdf77743385d8a4f13ba95f610f5ccd68c728f8"
@@ -14201,12 +14202,12 @@ unique-slug@^4.0.0:
dependencies:
imurmurhash "^0.1.4"
unique-string@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-1.0.0.tgz#9e1057cca851abb93398f8b33ae187b99caec11a"
integrity sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=
unique-string@~2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/unique-string/-/unique-string-2.0.0.tgz#39c6451f81afb2749de2b233e3f7c5e8843bd89d"
integrity sha512-uNaeirEPvpZWSgzwsPGtU2zVSTrn/8L5q/IexZmH0eH6SA73CmAA5U4GwORTxQAZs95TAXLNqeLoPPNO5gZfWg==
dependencies:
crypto-random-string "^1.0.0"
crypto-random-string "^2.0.0"
universal-user-agent@^6.0.0:
version "6.0.0"