Compare commits

...
34 Commits
Author SHA1 Message Date
Szymon Dziedzic 734a071345 v13.2.2 2024-11-15 10:30:04 +00:00
Szymon Dziedzic 26fd7a7daa [ENG-14180][eas-cli] rename with-as-environment-variables-set eas update flag to environment (#2692)
<!-- 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

During dogfooding it came out that this flag is too long and confusing

# How

Just use `environment`

# Test Plan

Tests, types
2024-11-15 11:28:50 +01:00
Expo Bot df13e0433e Upgrade eas-build dependencies (#2691)
⬆️ Upgrades [`eas-build`](https://github.com/expo/eas-build) dependencies.
2024-11-14 22:14:45 +01:00
Expo CI fa72248d45 update CHANGELOG.md 2024-11-14 15:54:43 +00:00
Stanisław Chmiela 2b51db72db v13.2.1 2024-11-14 16:46:12 +01:00
Stanisław Chmiela 79696394be [eas-cli] Default update message to undefined in no-VCS client (#2690)
<!-- 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://staging.expo.dev/accounts/sjchmiela/projects/staging-app/workflows/01932b13-21af-780b-b531-1ed07e3d8228

`eas update --auto` fails in GCS update job because this flag is set to true.

# How

The comment says it can be `false`, so changed it to `false`.

https://github.com/expo/eas-cli/pull/2148/files#diff-a594e233350755033d45aa7b21b78781e4b36322e9312f60e71e7edc79c33a7f

# Test Plan

Update message should be changed to `undefined`.
2024-11-14 16:40:59 +01:00
Expo CI 86c99efdcb update CHANGELOG.md 2024-11-13 15:08:46 +00:00
Stanisław Chmiela ee500109f6 v13.2.0 2024-11-13 16:02:31 +01:00
Stanisław Chmiela 7eff738efe [eas-cli] Fix VCS client used for submit:internal (#2682)
<!-- 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

Counterpart of https://github.com/expo/eas-cli/pull/2677, applied to `submit:internal`.

# How

Copied the solution from `build:internal`.

# Test Plan

None.
2024-11-13 16:01:38 +01:00
Will Schurman fdb167df34 [build] Default build-logger-level to debug when EXPO_DEBUG is set (#2676) 2024-11-11 10:46:08 -08:00
Quinlan JungandWill Schurman 027d3629a6 [eas-cli] improve fingerprint UX (#2675)
* [eas-cli] improve UX and slow fingerprint logs

* [eas-cli] env var to skip fingerprint computation

* pr feedback

* Update packages/eas-cli/src/utils/fingerprintCli.ts

Co-authored-by: Will Schurman <[email protected]>

* Temporary Commit at 11/8/2024, 3:17:40 PM

---------

Co-authored-by: Will Schurman <[email protected]>
2024-11-09 13:09:08 -08:00
Expo CI c30c1cd5cf update CHANGELOG.md 2024-11-08 11:23:26 +00:00
Stanisław Chmiela a5d3ea8aba v13.1.1 2024-11-08 12:17:00 +01:00
Stanisław Chmiela 37f53e0976 [eas-cli] Honor EAS_NO_VCS in build:internal (#2677)
<!-- 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

We need to use `build:internal` to resolve build configuration in GCS workflow jobs which have no Git repository.

# How

I'm going to be adding `EAS_NO_VCS=1` to GCS workflow jobs. This should prevent `build:internal` from requiring Git repository.

# Test Plan

I have verified `EAS_BUILD_ID=d7fb9f5c-dce0-40e2-b459-cbc05ba1ed77 EAS_NO_VCS=1 easd build:internal -p android` prints the JSON output on my computer.
2024-11-08 12:15:34 +01:00
Expo CI 97a26dce40 update CHANGELOG.md 2024-11-07 21:35:43 +00:00
Stanisław Chmiela b0b14788dd v13.1.0 2024-11-07 22:29:56 +01:00
Stanisław ChmielaandSzymon Dziedzic b81c60e8a4 [eas-cli] Add workflow:run (#2669)
<!-- 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

We want to allow users to start workflows manually.

# How

I added a `createRunMutation` to GraphQL and used it here. We upload project archive, `eas.json` and use to start a new workflow run.

# Test Plan

```
Workflows are in beta and subject to breaking changes.

Compressing project files and uploading to EAS. Learn more: https://expo.fyi/eas-build-archive
✔ Uploaded eas.json to EAS 
✔ Uploaded project archive to EAS 1s

✔ Workflow started successfully. https://staging.expo.dev/accounts/sjchmiela/projects/staging-app/workflows/019301f1-b1b4-700d-9e3b-82dc97d76a32
```

Co-authored-by: Szymon Dziedzic <[email protected]>
2024-11-07 22:26:52 +01:00
Jon Samp d47b80a125 Adds workflow:validate command (#2650)
* adds validate command

* use yaml

* incorp feedback
2024-11-07 08:53:51 -06:00
Quinlan Jung 3f2dcc7e09 [eas-cli] compute fingerprint on each build (#2663)
* Temporary Commit at 11/4/2024, 4:33:33 PM

* Temporary Commit at 11/5/2024, 4:17:31 PM

* Temporary Commit at 11/5/2024, 4:22:18 PM
2024-11-05 19:20:44 -08:00
Expo CI b039da04e2 update CHANGELOG.md 2024-11-05 22:20:04 +00:00
Cedric van Putten 9e55fcbe7c v13.0.1 2024-11-05 23:02:06 +01:00
Cedric van Putten 281ae7bad6 fix(eas-cli): update EAS Metadata with new props for App Store 3.6.0 (#2671)
* refactor(eas-cli): upgrade eas metadata to support app store 3.6.0 advisory props

* chore(eas-cli): bump `@expo/apple-utils` to `2.1.0`

* fix(eas-cli): update eas metadata json schema

* docs(eas-cli): add changelog entry

* fix(eas-cli): fix typo in config version

* fix(eas-cli): resolve outdated fixtures

* chore(eas-cli): resolve linting issues
2024-11-05 23:01:14 +01:00
Expo CI 433c47b221 update CHANGELOG.md 2024-11-05 18:52:32 +00:00
Szymon Dziedzic 5be97c50ae v13.0.0 2024-11-05 19:46:57 +01:00
Szymon Dziedzic 2bc0e968cf upgrade eas-cli-local-build-plugin to 1.0.144 2024-11-05 19:46:44 +01:00
Szymon Dziedzic a426164e85 [eas-cli] update expo packages (#2530)
<!-- 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

update expo packages to SDK 51 versions

revert https://github.com/expo/eas-cli/pull/2524

# How

update expo packages to SDK 51 versions

# Test Plan

tests
2024-11-05 19:36:30 +01:00
Szymon Dziedzic ac799bbf76 [eas-cli] use npx expo config command to resolve expo config if available (#2529)
<!-- 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/C02123T524U/p1724970663050089?thread_ts=1724924614.773089&cid=C02123T524U
https://exponent-internal.slack.com/archives/C5ERY0TAR/p1725002816077089

Generally `@expo/config`, `@expo/prebuild-config`, and `@expo/config-plugins` are per SDK concept. Currently, in EAS CLI, we rely on one version of the `@expo/...` package to work well globally for all SDKs. It seems to sometimes bite us like in the case of https://exponent-internal.slack.com/archives/C02123T524U/p1724909908574979, because SDK 51 config wasn't compatible with SDK 50.

It's better to switch to using config-related functions shipped with `@expo/config`, `@expo/prebuild-config`, and `@expo/config-plugins`.  I believe we can assume that `getConfig`, `getPrebuildConfig`, and `compileModsAsync` shipped with these packages have stable API https://exponent-internal.slack.com/archives/C5ERY0TAR/p1725293002128849?thread_ts=1725002816.077089&cid=C5ERY0TAR.

# How

Use `getConfig`, `getPrebuildConfig`, and `compileModsAsync` from `@expo/config`, `@expo/prebuild-config`, and `@expo/config-plugins` shipped with Expo SDK installed in the user's project. If not available, fallback to versions installed per SDK. If we can assume that these guarantee stable API we can use types of these functions from packages installed for EAS CLI as well.

# Test Plan

Run builds for repro case of https://exponent-internal.slack.com/archives/C02123T524U/p1724909908574979 with SDK 51 config packages installed for EAS CLI (that previously broke it), see that it works and capabilities are correctly synced.

Initiate a new bare RN project using community CLI, and check that it works as well using fallback config loading.
2024-11-05 19:33:24 +01:00
Szymon Dziedzic cf8e715cd5 [eas-cli] add support for with-eas-environment-variables-set flag in eas update:configure command (#2668)
<!-- 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

Add support for `with-eas-environment-variables-set` flag in `eas update:configure` command

# How

Use the flag the same way we do for `eas update`.

# Test Plan

Run command.
2024-11-05 12:44:27 +01:00
Szymon Dziedzic 71ca181895 [eas-cli] improve with-eas-environment-variables-set flag handling in eas update command (#2667)
<!-- 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

Make the `with-eas-environment-variables-set` flag reusable and improve type safety and description.

# How

Extract `with-eas-environment-variables-set` to separate file. Improve validation and type safety.

# Test Plan

Run command locally.
2024-11-05 12:41:43 +01:00
Szymon Dziedzic 7c9970d279 [eas-json] add new Xcode 16.1 image and tag to (#2666)
<!-- 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

Add new Xcode 16.1 image and `sdk-52` tag to `eas.schema.json`

# How

Add new Xcode 16.1 image and `sdk-52` tag to `eas.schema.json`

# Test Plan

Tests
2024-10-31 13:57:35 +01:00
Piotr Szeremeta f40484ec4d env:* commands accept environment as an argument and a flag (#2654)
# Why

[ENG-13930: Allow passing environment without the flag](https://linear.app/expo/issue/ENG-13930/allow-passing-environment-without-the-flag)

Added capability to pass `environment` without `--environment` flag to `eas env:*` commands. This is often more intuitive.

This works only for a single environments. In case user wants to pass more than one, `--environment` flag should still be used.

# Changed commands

## `env:create`
* was only `env:create --name thisisvar --value thisinew --visibility plaintext --environment production`
* now also `env:create production --name thisisvar --value thisinew --visibility plaintext`

## `env:delete`
* was only `env:delete --variable-environment production --variable-name NEW_VAR`
* now also `env:delete production --variable-name NEW_VAR`

## `env:exec`
* was only `env:exec --environment development 'echo lol'`
* now also `eas env:exec development 'echo lol'`

## `env:get`
* was only `env:get --variable-environment development --variable-name HELLO`
* now also `env:get development --variable-name HELLO`

## `eas env:link`
* was only `eas env:link --environment preview --variable-name NAME`
* now also `eas env:link preview --variable-name NAME`

## `eas env:list`
* was only `eas env:list --environment preview`
* now also `eas env:list preview`

## `eas env:pull`
* was only `eas env:pull --environment production`
* now also `eas env:pull production`

## `eas env:push`
* was only `eas env:push --environment production`
* now also `eas env:push production`

## `eas env:unlink`
* was only `eas env:unlink --environment production --variable-name NAME`
* now also `eas env:unlink production --variable-name NAME`

## `eas env:update`
* was only `eas env:update --variable-environment production --variable-name HELLO --environment development`
* now also `eas env:update production --variable-name HELLO --environment production`

# Test Plan

Updated tests
2024-10-31 13:20:54 +01:00
Expo Bot 746d64ac30 Upgrade eas-build dependencies (#2665)
⬆️ Upgrades [`eas-build`](https://github.com/expo/eas-build) dependencies.
2024-10-30 22:14:23 +01:00
Expo Bot 3782767f9a Upgrade eas-build dependencies (#2662)
<img width="1336" alt="Zrzut ekranu 2024-10-29 o 19 57 03" src="https://github.com/user-attachments/assets/0fe1585c-bdaa-4ad5-bd5b-e64d624d4932">

https://github.com/expo/eas-build/pull/456 + https://github.com/expo/eas-build/pull/453
2024-10-29 19:58:30 +01:00
Expo CI efb1c87fe3 update CHANGELOG.md 2024-10-29 10:52:35 +00:00
71 changed files with 4109 additions and 714 deletions

No files matched your search

+39 -1
View File
@@ -10,10 +10,48 @@ This is the log of notable changes to EAS CLI and related packages.
### 🐛 Bug fixes
- Make email case insensitive during Apple authentication. ([#2659](https://github.com/expo/eas-cli/pull/2659) by [@byCedric](https://github.com/byCedric))
### 🧹 Chores
## [13.2.1](https://github.com/expo/eas-cli/releases/tag/v13.2.1) - 2024-11-14
## [13.2.0](https://github.com/expo/eas-cli/releases/tag/v13.2.0) - 2024-11-13
### 🎉 New features
- Add EAS_SKIP_AUTO_FINGERPRINT to skip fingerprint computation on build ([#2675](https://github.com/expo/eas-cli/pull/2675) by [@quinlanj](https://github.com/quinlanj))
- Default build-logger-level to debug when EXPO_DEBUG is set. ([#2676](https://github.com/expo/eas-cli/pull/2676) by [@wschurman](https://github.com/wschurman))
## [13.1.1](https://github.com/expo/eas-cli/releases/tag/v13.1.1) - 2024-11-08
## [13.1.0](https://github.com/expo/eas-cli/releases/tag/v13.1.0) - 2024-11-07
### 🎉 New features
- Compute fingerprint for builds with SDK 52 and higher ([#2663](https://github.com/expo/eas-cli/pull/2663) by [@quinlanj](https://github.com/quinlanj))
## [13.0.1](https://github.com/expo/eas-cli/releases/tag/v13.0.1) - 2024-11-05
### 🧹 Chores
- Upgrade EAS Metadata with new properties from App Store. ([#2671](https://github.com/expo/eas-cli/pull/2671) by [@byCedric](https://github.com/byCedric))
## [13.0.0](https://github.com/expo/eas-cli/releases/tag/v13.0.0) - 2024-11-05
### 🛠 Breaking changes
- Resolve versioned expo config using `npx expo config` command instead of using fixed `@expo/config` version shipped with EAS CLI, if available. ([#2529](https://github.com/expo/eas-cli/pull/2529) by [@szdziedzic](https://github.com/szdziedzic))
### 🧹 Chores
- Add `macos-sonoma-14.6-xcode-16.1` image and `sdk-52` image tag to `eas.schema.json`. ([#2666](https://github.com/expo/eas-cli/pull/2666) by [@szdziedzic](https://github.com/szdziedzic))
- Update `@expo` packages versions. ([#2530](https://github.com/expo/eas-cli/pull/2530) by [@szdziedzic](https://github.com/szdziedzic))
## [12.6.2](https://github.com/expo/eas-cli/releases/tag/v12.6.2) - 2024-10-29
### 🐛 Bug fixes
- Make email case insensitive during Apple authentication. ([#2659](https://github.com/expo/eas-cli/pull/2659) by [@byCedric](https://github.com/byCedric))
## [12.6.1](https://github.com/expo/eas-cli/releases/tag/v12.6.1) - 2024-10-25
### 🧹 Chores
+1 -1
View File
@@ -1,5 +1,5 @@
{
"npmClient": "yarn",
"version": "12.6.2",
"version": "13.2.2",
"$schema": "node_modules/lerna/schemas/lerna-schema.json"
}
+63 -63
View File
@@ -146,7 +146,7 @@ ALIASES
$ eas login
```
_See code: [packages/eas-cli/src/commands/account/login.ts](https://github.com/expo/eas-cli/blob/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/account/login.ts)_
## `eas account:logout`
@@ -163,7 +163,7 @@ ALIASES
$ eas logout
```
_See code: [packages/eas-cli/src/commands/account/logout.ts](https://github.com/expo/eas-cli/blob/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/account/logout.ts)_
## `eas account:view`
@@ -180,7 +180,7 @@ ALIASES
$ eas whoami
```
_See code: [packages/eas-cli/src/commands/account/view.ts](https://github.com/expo/eas-cli/blob/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/account/view.ts)_
## `eas analytics [STATUS]`
@@ -194,7 +194,7 @@ DESCRIPTION
display or change analytics settings
```
_See code: [packages/eas-cli/src/commands/analytics.ts](https://github.com/expo/eas-cli/blob/v12.6.2/packages/eas-cli/src/commands/analytics.ts)_
_See code: [packages/eas-cli/src/commands/analytics.ts](https://github.com/expo/eas-cli/blob/v13.2.2/packages/eas-cli/src/commands/analytics.ts)_
## `eas autocomplete [SHELL]`
@@ -246,7 +246,7 @@ DESCRIPTION
create a branch
```
_See code: [packages/eas-cli/src/commands/branch/create.ts](https://github.com/expo/eas-cli/blob/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/branch/create.ts)_
## `eas branch:delete [NAME]`
@@ -267,7 +267,7 @@ DESCRIPTION
delete a branch
```
_See code: [packages/eas-cli/src/commands/branch/delete.ts](https://github.com/expo/eas-cli/blob/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/branch/delete.ts)_
## `eas branch:list`
@@ -287,7 +287,7 @@ DESCRIPTION
list all branches
```
_See code: [packages/eas-cli/src/commands/branch/list.ts](https://github.com/expo/eas-cli/blob/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/branch/list.ts)_
## `eas branch:rename`
@@ -307,7 +307,7 @@ DESCRIPTION
rename a branch
```
_See code: [packages/eas-cli/src/commands/branch/rename.ts](https://github.com/expo/eas-cli/blob/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/branch/rename.ts)_
## `eas branch:view [NAME]`
@@ -330,7 +330,7 @@ DESCRIPTION
view a branch
```
_See code: [packages/eas-cli/src/commands/branch/view.ts](https://github.com/expo/eas-cli/blob/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/branch/view.ts)_
## `eas build`
@@ -367,7 +367,7 @@ DESCRIPTION
start a build
```
_See code: [packages/eas-cli/src/commands/build/index.ts](https://github.com/expo/eas-cli/blob/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/build/index.ts)_
## `eas build:cancel [BUILD_ID]`
@@ -386,7 +386,7 @@ DESCRIPTION
cancel a build
```
_See code: [packages/eas-cli/src/commands/build/cancel.ts](https://github.com/expo/eas-cli/blob/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/build/cancel.ts)_
## `eas build:configure`
@@ -403,7 +403,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/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/build/configure.ts)_
## `eas build:delete [BUILD_ID]`
@@ -422,7 +422,7 @@ DESCRIPTION
delete a build
```
_See code: [packages/eas-cli/src/commands/build/delete.ts](https://github.com/expo/eas-cli/blob/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/build/delete.ts)_
## `eas build:inspect`
@@ -457,7 +457,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/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/build/inspect.ts)_
## `eas build:list`
@@ -507,7 +507,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/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/build/list.ts)_
## `eas build:resign`
@@ -536,7 +536,7 @@ DESCRIPTION
re-sign a build archive
```
_See code: [packages/eas-cli/src/commands/build/resign.ts](https://github.com/expo/eas-cli/blob/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/build/resign.ts)_
## `eas build:run`
@@ -562,7 +562,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/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/build/run.ts)_
## `eas build:submit`
@@ -612,7 +612,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/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/build/version/get.ts)_
## `eas build:version:set`
@@ -631,7 +631,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/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/build/version/set.ts)_
## `eas build:version:sync`
@@ -650,7 +650,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/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/build/version/sync.ts)_
## `eas build:view [BUILD_ID]`
@@ -667,7 +667,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/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/build/view.ts)_
## `eas channel:create [NAME]`
@@ -688,7 +688,7 @@ DESCRIPTION
create a channel
```
_See code: [packages/eas-cli/src/commands/channel/create.ts](https://github.com/expo/eas-cli/blob/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/channel/create.ts)_
## `eas channel:edit [NAME]`
@@ -710,7 +710,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/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/channel/edit.ts)_
## `eas channel:list`
@@ -730,7 +730,7 @@ DESCRIPTION
list all channels
```
_See code: [packages/eas-cli/src/commands/channel/list.ts](https://github.com/expo/eas-cli/blob/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/channel/list.ts)_
## `eas channel:pause [NAME]`
@@ -752,7 +752,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/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/channel/pause.ts)_
## `eas channel:resume [NAME]`
@@ -774,7 +774,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/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/channel/resume.ts)_
## `eas channel:rollout [CHANNEL]`
@@ -807,7 +807,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/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/channel/rollout.ts)_
## `eas channel:view [NAME]`
@@ -830,7 +830,7 @@ DESCRIPTION
view a channel
```
_See code: [packages/eas-cli/src/commands/channel/view.ts](https://github.com/expo/eas-cli/blob/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/channel/view.ts)_
## `eas config`
@@ -851,7 +851,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/v12.6.2/packages/eas-cli/src/commands/config.ts)_
_See code: [packages/eas-cli/src/commands/config.ts](https://github.com/expo/eas-cli/blob/v13.2.2/packages/eas-cli/src/commands/config.ts)_
## `eas credentials`
@@ -868,7 +868,7 @@ DESCRIPTION
manage credentials
```
_See code: [packages/eas-cli/src/commands/credentials/index.ts](https://github.com/expo/eas-cli/blob/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/credentials/index.ts)_
## `eas credentials:configure-build`
@@ -886,7 +886,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/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/credentials/configure-build.ts)_
## `eas device:create`
@@ -900,7 +900,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/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/device/create.ts)_
## `eas device:delete`
@@ -920,7 +920,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/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/device/delete.ts)_
## `eas device:list`
@@ -941,7 +941,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/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/device/list.ts)_
## `eas device:rename`
@@ -962,7 +962,7 @@ DESCRIPTION
rename a registered device
```
_See code: [packages/eas-cli/src/commands/device/rename.ts](https://github.com/expo/eas-cli/blob/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/device/rename.ts)_
## `eas device:view [UDID]`
@@ -976,7 +976,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/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/device/view.ts)_
## `eas diagnostics`
@@ -990,7 +990,7 @@ DESCRIPTION
display environment info
```
_See code: [packages/eas-cli/src/commands/diagnostics.ts](https://github.com/expo/eas-cli/blob/v12.6.2/packages/eas-cli/src/commands/diagnostics.ts)_
_See code: [packages/eas-cli/src/commands/diagnostics.ts](https://github.com/expo/eas-cli/blob/v13.2.2/packages/eas-cli/src/commands/diagnostics.ts)_
## `eas help [COMMAND]`
@@ -1098,7 +1098,7 @@ DESCRIPTION
validate the local store configuration
```
_See code: [packages/eas-cli/src/commands/metadata/lint.ts](https://github.com/expo/eas-cli/blob/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/metadata/lint.ts)_
## `eas metadata:pull`
@@ -1115,7 +1115,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/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/metadata/pull.ts)_
## `eas metadata:push`
@@ -1132,7 +1132,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/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/metadata/push.ts)_
## `eas onboarding [TARGET_PROJECT_DIRECTORY]`
@@ -1162,7 +1162,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/v12.6.2/packages/eas-cli/src/commands/open.ts)_
_See code: [packages/eas-cli/src/commands/open.ts](https://github.com/expo/eas-cli/blob/v13.2.2/packages/eas-cli/src/commands/open.ts)_
## `eas project:info`
@@ -1176,7 +1176,7 @@ DESCRIPTION
information about the current project
```
_See code: [packages/eas-cli/src/commands/project/info.ts](https://github.com/expo/eas-cli/blob/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/project/info.ts)_
## `eas project:init`
@@ -1199,7 +1199,7 @@ ALIASES
$ eas init
```
_See code: [packages/eas-cli/src/commands/project/init.ts](https://github.com/expo/eas-cli/blob/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/project/init.ts)_
## `eas project:onboarding [TARGET_PROJECT_DIRECTORY]`
@@ -1217,7 +1217,7 @@ ALIASES
$ eas onboarding
```
_See code: [packages/eas-cli/src/commands/project/onboarding.ts](https://github.com/expo/eas-cli/blob/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/project/onboarding.ts)_
## `eas secret:create`
@@ -1240,7 +1240,7 @@ DESCRIPTION
create an environment secret on the current project or owner account
```
_See code: [packages/eas-cli/src/commands/secret/create.ts](https://github.com/expo/eas-cli/blob/v12.6.2/packages/eas-cli/src/commands/secret/create.ts)_
_See code: [packages/eas-cli/src/commands/secret/create.ts](https://github.com/expo/eas-cli/blob/v13.2.2/packages/eas-cli/src/commands/secret/create.ts)_
## `eas secret:delete`
@@ -1258,7 +1258,7 @@ DESCRIPTION
delete an environment secret by ID
```
_See code: [packages/eas-cli/src/commands/secret/delete.ts](https://github.com/expo/eas-cli/blob/v12.6.2/packages/eas-cli/src/commands/secret/delete.ts)_
_See code: [packages/eas-cli/src/commands/secret/delete.ts](https://github.com/expo/eas-cli/blob/v13.2.2/packages/eas-cli/src/commands/secret/delete.ts)_
## `eas secret:list`
@@ -1272,7 +1272,7 @@ DESCRIPTION
list environment secrets available for your current app
```
_See code: [packages/eas-cli/src/commands/secret/list.ts](https://github.com/expo/eas-cli/blob/v12.6.2/packages/eas-cli/src/commands/secret/list.ts)_
_See code: [packages/eas-cli/src/commands/secret/list.ts](https://github.com/expo/eas-cli/blob/v13.2.2/packages/eas-cli/src/commands/secret/list.ts)_
## `eas secret:push`
@@ -1292,7 +1292,7 @@ DESCRIPTION
read environment secrets from env file and store on the server
```
_See code: [packages/eas-cli/src/commands/secret/push.ts](https://github.com/expo/eas-cli/blob/v12.6.2/packages/eas-cli/src/commands/secret/push.ts)_
_See code: [packages/eas-cli/src/commands/secret/push.ts](https://github.com/expo/eas-cli/blob/v13.2.2/packages/eas-cli/src/commands/secret/push.ts)_
## `eas submit`
@@ -1323,7 +1323,7 @@ ALIASES
$ eas build:submit
```
_See code: [packages/eas-cli/src/commands/submit.ts](https://github.com/expo/eas-cli/blob/v12.6.2/packages/eas-cli/src/commands/submit.ts)_
_See code: [packages/eas-cli/src/commands/submit.ts](https://github.com/expo/eas-cli/blob/v13.2.2/packages/eas-cli/src/commands/submit.ts)_
## `eas update`
@@ -1361,7 +1361,7 @@ DESCRIPTION
publish an update group
```
_See code: [packages/eas-cli/src/commands/update/index.ts](https://github.com/expo/eas-cli/blob/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/update/index.ts)_
## `eas update:configure`
@@ -1379,7 +1379,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/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/update/configure.ts)_
## `eas update:delete GROUPID`
@@ -1400,7 +1400,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/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/update/delete.ts)_
## `eas update:edit [GROUPID]`
@@ -1424,7 +1424,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/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/update/edit.ts)_
## `eas update:list`
@@ -1446,7 +1446,7 @@ DESCRIPTION
view the recent updates
```
_See code: [packages/eas-cli/src/commands/update/list.ts](https://github.com/expo/eas-cli/blob/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/update/list.ts)_
## `eas update:republish`
@@ -1478,7 +1478,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/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/update/republish.ts)_
## `eas update:roll-back-to-embedded`
@@ -1506,7 +1506,7 @@ 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/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/update/roll-back-to-embedded.ts)_
## `eas update:rollback`
@@ -1526,7 +1526,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/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/update/rollback.ts)_
## `eas update:view GROUPID`
@@ -1546,7 +1546,7 @@ DESCRIPTION
update group details
```
_See code: [packages/eas-cli/src/commands/update/view.ts](https://github.com/expo/eas-cli/blob/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/update/view.ts)_
## `eas webhook:create`
@@ -1567,7 +1567,7 @@ DESCRIPTION
create a webhook
```
_See code: [packages/eas-cli/src/commands/webhook/create.ts](https://github.com/expo/eas-cli/blob/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/webhook/create.ts)_
## `eas webhook:delete [ID]`
@@ -1587,7 +1587,7 @@ DESCRIPTION
delete a webhook
```
_See code: [packages/eas-cli/src/commands/webhook/delete.ts](https://github.com/expo/eas-cli/blob/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/webhook/delete.ts)_
## `eas webhook:list`
@@ -1605,7 +1605,7 @@ DESCRIPTION
list webhooks
```
_See code: [packages/eas-cli/src/commands/webhook/list.ts](https://github.com/expo/eas-cli/blob/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/webhook/list.ts)_
## `eas webhook:update`
@@ -1627,7 +1627,7 @@ DESCRIPTION
update a webhook
```
_See code: [packages/eas-cli/src/commands/webhook/update.ts](https://github.com/expo/eas-cli/blob/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/webhook/update.ts)_
## `eas webhook:view ID`
@@ -1644,7 +1644,7 @@ DESCRIPTION
view a webhook
```
_See code: [packages/eas-cli/src/commands/webhook/view.ts](https://github.com/expo/eas-cli/blob/v12.6.2/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/v13.2.2/packages/eas-cli/src/commands/webhook/view.ts)_
## `eas whoami`
+2096 -137
View File
File diff suppressed because it is too large. Load diff
+15 -14
View File
@@ -1,34 +1,34 @@
{
"name": "eas-cli",
"description": "EAS command line tool",
"version": "12.6.2",
"version": "13.2.2",
"author": "Expo <[email protected]>",
"bin": {
"eas": "./bin/run"
},
"bugs": "https://github.com/expo/eas-cli/issues",
"dependencies": {
"@expo/apple-utils": "2.0.3",
"@expo/apple-utils": "2.1.0",
"@expo/code-signing-certificates": "0.0.5",
"@expo/config": "8.5.4",
"@expo/config-plugins": "7.8.4",
"@expo/eas-build-job": "1.0.141",
"@expo/eas-json": "12.6.2",
"@expo/config": "9.0.4",
"@expo/config-plugins": "8.0.10",
"@expo/eas-build-job": "1.0.149",
"@expo/eas-json": "13.2.2",
"@expo/env": "^0.3.0",
"@expo/json-file": "8.2.37",
"@expo/json-file": "8.3.3",
"@expo/logger": "1.0.117",
"@expo/multipart-body-parser": "1.1.0",
"@expo/osascript": "2.0.33",
"@expo/package-manager": "1.1.2",
"@expo/pkcs12": "0.0.8",
"@expo/plist": "0.0.20",
"@expo/osascript": "2.1.3",
"@expo/package-manager": "1.5.2",
"@expo/pkcs12": "0.1.2",
"@expo/plist": "0.1.3",
"@expo/plugin-help": "5.1.23",
"@expo/plugin-warn-if-update-available": "2.5.1",
"@expo/prebuild-config": "6.7.3",
"@expo/prebuild-config": "7.0.9",
"@expo/results": "1.0.0",
"@expo/rudder-sdk-node": "1.1.1",
"@expo/spawn-async": "1.7.0",
"@expo/steps": "1.0.141",
"@expo/spawn-async": "1.7.2",
"@expo/steps": "1.0.149",
"@expo/timeago.js": "1.0.0",
"@oclif/core": "^1.26.2",
"@oclif/plugin-autocomplete": "^2.3.10",
@@ -86,6 +86,7 @@
"untildify": "4.0.0",
"uuid": "9.0.1",
"wrap-ansi": "7.0.0",
"yaml": "2.6.0",
"zod": "^3.23.8"
},
"devDependencies": {
+53 -18
View File
@@ -1,6 +1,20 @@
{
"$schema": "http://json-schema.org/draft-06/schema",
"type": "object",
"properties": {
"configVersion": {
"enum": [0],
"description": "The EAS metadata store configuration version"
},
"apple": {
"$ref": "#/definitions/AppleConfig"
}
},
"additionalProperties": false,
"required": [
"configVersion",
"apple"
],
"definitions": {
"apple": {
"AppleKidsAge": {
@@ -323,7 +337,8 @@
"gambling",
"unrestrictedWebAccess",
"kidsAgeBand",
"seventeenPlus"
"ageRatingOverride",
"koreaAgeRatingOverride"
],
"defaultSnippets": [
{
@@ -345,7 +360,9 @@
"gambling": false,
"unrestrictedWebAccess": false,
"kidsAgeBand": null,
"seventeenPlus": false
"ageRatingOverride": "NONE",
"koreaAgeRatingOverride": "NONE",
"lootBox": false
}
},
{
@@ -367,7 +384,9 @@
"unrestrictedWebAccess": false,
"gambling": false,
"kidsAgeBand": null,
"seventeenPlus": false
"ageRatingOverride": "${13|NONE,SEVENTEEN_PLUS,UNRATED|}",
"koreaAgeRatingOverride": "${14|NONE,FIFTEEN_PLUS,NINETEEN_PLUS|}",
"lootBox": false
}
}
],
@@ -442,8 +461,24 @@
},
"seventeenPlus": {
"type": "boolean",
"deprecated": true,
"deprecationMessage": "This property is deprecated, use `ageRatingOverride` instead.",
"description": "If your app rates 12+ or lower, and you believe its content may not be suitable for children under 17, you can manually set the age rating to 17+.\n@see https://help.apple.com/app-store-connect/#/dev599d50efb",
"markdownDescription": "If your app rates 12+ or lower, and you believe its content may not be suitable for children under 17, you can manually set the age rating to 17+.\n\n[Learn more](https://help.apple.com/app-store-connect/#/dev599d50efb)"
},
"ageRatingOverride": {
"$ref": "#/definitions/apple/AppleAgeRatingOverride",
"description": "If your app rates 12+ or lower, and you believe its content may not be suitable for children under 17, you can manually set the age rating to 17+.\n\nIf your app will be distributed through alternative app marketplaces or websites in the European Union and you believe your app is [Unrated](https://developer.apple.com/help/app-store-connect/reference/age-ratings), set this to `UNRATED`.\n\n@see https://help.apple.com/app-store-connect/#/dev599d50efb",
"markdownDescription": "If your app rates 12+ or lower, and you believe its content may not be suitable for children under 17, you can manually set the age rating to 17+.\n\nIf your app will be distributed through alternative app marketplaces or websites in the European Union and you believe your app is [Unrated](https://developer.apple.com/help/app-store-connect/reference/age-ratings), set this to `UNRATED`.\n\n[Learn more](https://help.apple.com/app-store-connect/#/dev599d50efb)"
},
"koreaAgeRatingOverride": {
"$ref": "#/definitions/apple/AppleKoreaAgeRatingOverride",
"description": "If your app rates 12+ or lower, and you believe its content may not be suitable for children under 15 or 19, you can manually set the age rating to 15+ or 19+.\n\nIf your app will be distributed through alternative app marketplaces or websites in the European Union and you believe your app is [Unrated](https://developer.apple.com/help/app-store-connect/reference/age-ratings), set this to `UNRATED`.\n\n@see https://help.apple.com/app-store-connect/#/dev599d50efb",
"markdownDescription": "If your app rates 12+ or lower, and you believe its content may not be suitable for children under 15 or 19, you can manually set the age rating to 15+ or 19+.\n\nIf your app will be distributed through alternative app marketplaces or websites in the European Union and you believe your app is [Unrated](https://developer.apple.com/help/app-store-connect/reference/age-ratings), set this to `UNRATED`.\n\n[Learn more](https://help.apple.com/app-store-connect/#/dev599d50efb)"
},
"lootBox": {
"type": "boolean",
"description": "Does your app contain purchasable loot boxes? These virtual containers provide players with in-game items, including functional cards or cosmetic modifications, based on random chance."
}
}
},
@@ -565,6 +600,20 @@
"maxLength": 4000
}
}
},
"AppleAgeRatingOverride": {
"enum": [
"NONE",
"SEVENTEEN_PLUS",
"UNRATED"
]
},
"AppleKoreaAgeRatingOverride": {
"enum": [
"NONE",
"FIFTEEN_PLUS",
"NINETEEN_PLUS"
]
}
},
"AppleConfig": {
@@ -775,19 +824,5 @@
}
}
}
},
"properties": {
"configVersion": {
"enum": [0],
"description": "The EAS metadata store configuration version"
},
"apple": {
"$ref": "#/definitions/AppleConfig"
}
},
"additionalProperties": false,
"required": [
"configVersion",
"apple"
]
}
}
+69 -5
View File
@@ -66,6 +66,7 @@ import { maybeUploadFingerprintAsync } from '../project/maybeUploadFingerprintAs
import { resolveRuntimeVersionAsync } from '../project/resolveRuntimeVersionAsync';
import { uploadFileAtPathToGCSAsync } from '../uploads';
import { formatBytes } from '../utils/files';
import { createFingerprintAsync } from '../utils/fingerprintCli';
import { printJsonOnlyOutput } from '../utils/json';
import { createProgressTracker } from '../utils/progress';
import { sleepAsync } from '../utils/promise';
@@ -174,8 +175,9 @@ export async function prepareBuildRequestForPlatformAsync<
}
assert(projectArchive);
const runtimeMetadata = await createAndMaybeUploadFingerprintAsync(ctx);
const metadata = await collectMetadataAsync(ctx, runtimeMetadata);
const runtimeAndFingerprintMetadata =
await computeAndMaybeUploadRuntimeAndFingerprintMetadataAsync(ctx);
const metadata = await collectMetadataAsync(ctx, runtimeAndFingerprintMetadata);
const buildParams = resolveBuildParamsInput(ctx, metadata);
const job = await builder.prepareJobAsync(ctx, {
projectArchive,
@@ -660,11 +662,38 @@ function formatAccountBillingUrl(accountName: string): string {
return new URL(`/accounts/${accountName}/settings/billing`, getExpoWebsiteBaseUrl()).toString();
}
async function createAndMaybeUploadFingerprintAsync<T extends Platform>(
async function computeAndMaybeUploadRuntimeAndFingerprintMetadataAsync<T extends Platform>(
ctx: BuildContext<T>
): Promise<{
runtimeVersion?: string | undefined;
fingerprintHash?: string | undefined;
fingerprintSource?: FingerprintSource | undefined;
}> {
const runtimeAndFingerprintMetadata =
await computeAndMaybeUploadFingerprintFromExpoUpdatesAsync(ctx);
if (!runtimeAndFingerprintMetadata?.fingerprint) {
const fingerprint = await computeAndMaybeUploadFingerprintWithoutExpoUpdatesAsync(ctx);
return {
...runtimeAndFingerprintMetadata,
...fingerprint,
};
} else {
return {
...runtimeAndFingerprintMetadata,
fingerprintHash: runtimeAndFingerprintMetadata.runtimeVersion,
};
}
}
async function computeAndMaybeUploadFingerprintFromExpoUpdatesAsync<T extends Platform>(
ctx: BuildContext<T>
): Promise<{
runtimeVersion?: string;
fingerprintSource?: FingerprintSource;
fingerprint?: {
fingerprintSources: object[];
isDebugFingerprintSource: boolean;
};
}> {
const resolvedRuntimeVersion = await resolveRuntimeVersionAsync({
exp: ctx.exp,
@@ -689,10 +718,45 @@ async function createAndMaybeUploadFingerprintAsync<T extends Platform>(
};
}
return await maybeUploadFingerprintAsync({
runtimeVersion: resolvedRuntimeVersion.runtimeVersion,
const uploadedFingerprint = await maybeUploadFingerprintAsync({
hash: resolvedRuntimeVersion.runtimeVersion,
fingerprint: resolvedRuntimeVersion.fingerprint,
graphqlClient: ctx.graphqlClient,
localBuildMode: ctx.localBuildOptions.localBuildMode,
});
return {
runtimeVersion: uploadedFingerprint.hash,
fingerprintSource: uploadedFingerprint.fingerprintSource,
fingerprint: resolvedRuntimeVersion.fingerprint,
};
}
async function computeAndMaybeUploadFingerprintWithoutExpoUpdatesAsync<T extends Platform>(
ctx: BuildContext<T>,
{ debug }: { debug?: boolean } = {}
): Promise<{
fingerprintHash?: string;
fingerprintSource?: FingerprintSource;
}> {
const fingerprint = await createFingerprintAsync(ctx.projectDir, {
workflow: ctx.workflow,
platform: ctx.platform,
env: ctx.env,
});
if (!fingerprint) {
return {};
}
const uploadedFingerprint = await maybeUploadFingerprintAsync({
hash: fingerprint.hash,
fingerprint: {
fingerprintSources: fingerprint.sources,
isDebugFingerprintSource: debug ?? false,
},
graphqlClient: ctx.graphqlClient,
localBuildMode: ctx.localBuildOptions.localBuildMode,
});
return {
fingerprintHash: uploadedFingerprint.hash,
fingerprintSource: uploadedFingerprint.fingerprintSource,
};
}
+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.142';
const PLUGIN_PACKAGE_VERSION = '1.0.144';
export enum LocalBuildMode {
/**
+5 -3
View File
@@ -16,8 +16,9 @@ import { easCliVersion } from '../utils/easCli';
export async function collectMetadataAsync<T extends Platform>(
ctx: BuildContext<T>,
runtimeMetadata: {
runtimeAndFingerprintMetadata: {
runtimeVersion?: string | undefined;
fingerprintHash?: string | undefined;
fingerprintSource?: FingerprintSource | undefined;
}
): Promise<Metadata> {
@@ -30,8 +31,9 @@ export async function collectMetadataAsync<T extends Platform>(
workflow: ctx.workflow,
credentialsSource: ctx.buildProfile.credentialsSource,
sdkVersion: ctx.exp.sdkVersion,
runtimeVersion: runtimeMetadata?.runtimeVersion,
fingerprintSource: runtimeMetadata?.fingerprintSource,
runtimeVersion: runtimeAndFingerprintMetadata?.runtimeVersion,
fingerprintHash: runtimeAndFingerprintMetadata?.fingerprintHash,
fingerprintSource: runtimeAndFingerprintMetadata?.fingerprintSource,
reactNativeVersion: await getReactNativeVersionAsync(ctx.projectDir),
...channelObject,
distribution,
@@ -381,7 +381,7 @@ async function prepareAndStartBuildAsync({
vcsClient,
getDynamicPrivateProjectConfigAsync,
customBuildConfigMetadata,
buildLoggerLevel: flags.buildLoggerLevel,
buildLoggerLevel: flags.buildLoggerLevel ?? (Log.isDebug ? LoggerLevel.DEBUG : undefined),
freezeCredentials: flags.freezeCredentials,
repack: flags.repack,
env,
+13
View File
@@ -50,3 +50,16 @@ export function getUpdateGroupUrl(
getExpoWebsiteBaseUrl()
).toString();
}
export function getWorkflowRunUrl(
accountName: string,
projectName: string,
workflowRunId: string
): string {
return new URL(
`/accounts/${encodeURIComponent(accountName)}/projects/${encodeURIComponent(
projectName
)}/workflows/${workflowRunId}`,
getExpoWebsiteBaseUrl()
).toString();
}
@@ -7,8 +7,8 @@ import { getProjectIdAsync } from './contextUtils/getProjectIdAsync';
import { loadServerSideEnvironmentVariablesAsync } from './contextUtils/loadServerSideEnvironmentVariablesAsync';
import {
ExpoConfigOptions,
getPrivateExpoConfig,
getPublicExpoConfig,
getPrivateExpoConfigAsync,
getPublicExpoConfigAsync,
} from '../../project/expoConfig';
export type DynamicConfigContextFn = (options?: ExpoConfigOptions) => Promise<{
@@ -25,7 +25,7 @@ export class DynamicPublicProjectConfigContextField extends ContextField<Dynamic
}: ContextOptions): Promise<DynamicConfigContextFn> {
const projectDir = await findProjectDirAndVerifyProjectSetupAsync();
return async (options?: ExpoConfigOptions) => {
const expBefore = getPublicExpoConfig(projectDir, options);
const expBefore = await getPublicExpoConfigAsync(projectDir, options);
const projectId = await getProjectIdAsync(sessionManager, expBefore, {
nonInteractive,
env: options?.env,
@@ -48,7 +48,7 @@ export class DynamicPublicProjectConfigContextField extends ContextField<Dynamic
},
};
}
const exp = getPublicExpoConfig(projectDir, options);
const exp = await getPublicExpoConfigAsync(projectDir, options);
return {
exp,
projectDir,
@@ -66,7 +66,7 @@ export class DynamicPrivateProjectConfigContextField extends ContextField<Dynami
}: ContextOptions): Promise<DynamicConfigContextFn> {
const projectDir = await findProjectDirAndVerifyProjectSetupAsync();
return async (options?: ExpoConfigOptions) => {
const expBefore = getPrivateExpoConfig(projectDir, options);
const expBefore = await getPrivateExpoConfigAsync(projectDir, options);
const projectId = await getProjectIdAsync(sessionManager, expBefore, {
nonInteractive,
env: options?.env,
@@ -89,7 +89,7 @@ export class DynamicPrivateProjectConfigContextField extends ContextField<Dynami
},
};
}
const exp = getPrivateExpoConfig(projectDir, options);
const exp = await getPrivateExpoConfigAsync(projectDir, options);
return {
exp,
projectDir,
@@ -6,7 +6,7 @@ import { createGraphqlClient } from './contextUtils/createGraphqlClient';
import { findProjectDirAndVerifyProjectSetupAsync } from './contextUtils/findProjectDirAndVerifyProjectSetupAsync';
import { getProjectIdAsync } from './contextUtils/getProjectIdAsync';
import { loadServerSideEnvironmentVariablesAsync } from './contextUtils/loadServerSideEnvironmentVariablesAsync';
import { getPrivateExpoConfig } from '../../project/expoConfig';
import { getPrivateExpoConfigAsync } from '../../project/expoConfig';
export class OptionalPrivateProjectConfigContextField extends ContextField<
| {
@@ -41,7 +41,7 @@ export class OptionalPrivateProjectConfigContextField extends ContextField<
return undefined;
}
const expBefore = getPrivateExpoConfig(projectDir);
const expBefore = await getPrivateExpoConfigAsync(projectDir);
const projectId = await getProjectIdAsync(sessionManager, expBefore, {
nonInteractive,
});
@@ -58,7 +58,7 @@ export class OptionalPrivateProjectConfigContextField extends ContextField<
});
serverSideEnvVars = serverSideEnvironmentVariables;
}
const exp = getPrivateExpoConfig(projectDir, { env: serverSideEnvVars });
const exp = await getPrivateExpoConfigAsync(projectDir, { env: serverSideEnvVars });
return {
exp,
projectDir,
@@ -5,7 +5,7 @@ import { createGraphqlClient } from './contextUtils/createGraphqlClient';
import { findProjectDirAndVerifyProjectSetupAsync } from './contextUtils/findProjectDirAndVerifyProjectSetupAsync';
import { getProjectIdAsync } from './contextUtils/getProjectIdAsync';
import { loadServerSideEnvironmentVariablesAsync } from './contextUtils/loadServerSideEnvironmentVariablesAsync';
import { getPrivateExpoConfig } from '../../project/expoConfig';
import { getPrivateExpoConfigAsync } from '../../project/expoConfig';
export class PrivateProjectConfigContextField extends ContextField<{
projectId: string;
@@ -22,7 +22,7 @@ export class PrivateProjectConfigContextField extends ContextField<{
projectDir: string;
}> {
const projectDir = await findProjectDirAndVerifyProjectSetupAsync();
const expBefore = getPrivateExpoConfig(projectDir);
const expBefore = await getPrivateExpoConfigAsync(projectDir);
const projectId = await getProjectIdAsync(sessionManager, expBefore, {
nonInteractive,
});
@@ -39,7 +39,7 @@ export class PrivateProjectConfigContextField extends ContextField<{
});
serverSideEnvVars = serverSideEnvironmentVariables;
}
const exp = getPrivateExpoConfig(projectDir, { env: serverSideEnvVars });
const exp = await getPrivateExpoConfigAsync(projectDir, { env: serverSideEnvVars });
return {
projectId,
@@ -1,12 +1,12 @@
import ContextField, { ContextOptions } from './ContextField';
import { findProjectDirAndVerifyProjectSetupAsync } from './contextUtils/findProjectDirAndVerifyProjectSetupAsync';
import { getProjectIdAsync } from './contextUtils/getProjectIdAsync';
import { getPrivateExpoConfig } from '../../project/expoConfig';
import { getPrivateExpoConfigAsync } from '../../project/expoConfig';
export class ProjectIdContextField extends ContextField<string> {
async getValueAsync({ nonInteractive, sessionManager }: ContextOptions): Promise<string> {
const projectDir = await findProjectDirAndVerifyProjectSetupAsync();
const expBefore = getPrivateExpoConfig(projectDir);
const expBefore = await getPrivateExpoConfigAsync(projectDir);
const projectId = await getProjectIdAsync(sessionManager, expBefore, {
nonInteractive,
});
@@ -3,7 +3,7 @@ import { createGraphqlClient } from './contextUtils/createGraphqlClient';
import { findProjectDirAndVerifyProjectSetupAsync } from './contextUtils/findProjectDirAndVerifyProjectSetupAsync';
import { getProjectIdAsync } from './contextUtils/getProjectIdAsync';
import { loadServerSideEnvironmentVariablesAsync } from './contextUtils/loadServerSideEnvironmentVariablesAsync';
import { getPublicExpoConfig } from '../../project/expoConfig';
import { getPublicExpoConfigAsync } from '../../project/expoConfig';
type GetServerSideEnvironmentVariablesFn = (
maybeEnv?: Record<string, string>
@@ -22,7 +22,7 @@ export class ServerSideEnvironmentVariablesContextField extends ContextField<Get
'withServerSideEnvironment parameter is required to evaluate ServerSideEnvironmentVariablesContextField'
);
}
const exp = getPublicExpoConfig(projectDir, { env: maybeEnv });
const exp = await getPublicExpoConfigAsync(projectDir, { env: maybeEnv });
const projectId = await getProjectIdAsync(sessionManager, exp, {
nonInteractive,
env: maybeEnv,
@@ -6,6 +6,7 @@ import { Role } from '../../../../graphql/generated';
import { AppQuery } from '../../../../graphql/queries/AppQuery';
import { learnMore } from '../../../../log';
import { fetchOrCreateProjectIDForWriteToConfigWithConfirmationAsync } from '../../../../project/fetchOrCreateProjectIDForWriteToConfigWithConfirmationAsync';
import { isExpoInstalled } from '../../../../project/projectUtils';
import SessionManager from '../../../../user/SessionManager';
import { findProjectRootAsync } from '../findProjectDirAndVerifyProjectSetupAsync';
import { getProjectIdAsync } from '../getProjectIdAsync';
@@ -21,6 +22,7 @@ jest.mock('../../../../ora', () => ({
}),
}));
jest.mock('../../../../project/fetchOrCreateProjectIDForWriteToConfigWithConfirmationAsync');
jest.mock('../../../../project/projectUtils');
describe(getProjectIdAsync, () => {
let sessionManager: SessionManager;
@@ -71,6 +73,7 @@ describe(getProjectIdAsync, () => {
);
jest.mocked(findProjectRootAsync).mockResolvedValue('/app');
jest.mocked(isExpoInstalled).mockReturnValue(true);
});
it('gets the project ID from app config if exists', async () => {
@@ -7,7 +7,10 @@ import { findProjectRootAsync } from './findProjectDirAndVerifyProjectSetupAsync
import { AppQuery } from '../../../graphql/queries/AppQuery';
import Log, { learnMore } from '../../../log';
import { ora } from '../../../ora';
import { createOrModifyExpoConfigAsync, getPrivateExpoConfig } from '../../../project/expoConfig';
import {
createOrModifyExpoConfigAsync,
getPrivateExpoConfigAsync,
} from '../../../project/expoConfig';
import { fetchOrCreateProjectIDForWriteToConfigWithConfirmationAsync } from '../../../project/fetchOrCreateProjectIDForWriteToConfigWithConfirmationAsync';
import { toAppPrivacy } from '../../../project/projectUtils';
import SessionManager from '../../../user/SessionManager';
@@ -25,7 +28,7 @@ export async function saveProjectIdToAppConfigAsync(
options: { env?: Env } = {}
): Promise<void> {
// NOTE(cedric): we disable plugins to avoid writing plugin-generated content to `expo.extra`
const exp = getPrivateExpoConfig(projectDir, { skipPlugins: true, ...options });
const exp = await getPrivateExpoConfigAsync(projectDir, { skipPlugins: true, ...options });
const result = await createOrModifyExpoConfigAsync(
projectDir,
{
@@ -48,7 +48,7 @@ export async function loadServerSideEnvironmentVariablesAsync({
);
} else {
Log.log(
`No environment variables found for the "${environment.toLowerCase()}" environment on EAS servers.`
`No readable environment variables found for the "${environment.toLowerCase()}" environment on EAS servers.`
);
}
@@ -78,3 +78,15 @@ export const EasJsonOnlyFlag = {
description: 'Enable JSON output, non-JSON messages will be printed to stderr.',
}),
};
export const EasUpdateEnvironmentFlag = {
environment: Flags.enum<EnvironmentVariableEnvironment | null>({
description:
'Environment to use the server-side defined EAS environment variables for during command execution.',
options: mapToLowercase(Object.values(EnvironmentVariableEnvironment)),
parse: upperCaseAsync,
required: false,
hidden: true,
default: null,
}),
};
@@ -7,6 +7,7 @@ import EasCommand from '../../commandUtils/EasCommand';
import { RequestedPlatform } from '../../platform';
import { enableJsonOutput } from '../../utils/json';
import GitNoCommitClient from '../../vcs/clients/gitNoCommit';
import NoVcsClient from '../../vcs/clients/noVcs';
/**
* This command will be run on the EAS Build workers, when building
@@ -63,7 +64,7 @@ export default class BuildInternal extends EasCommand {
vcsClient,
} = await this.getContextAsync(BuildInternal, {
nonInteractive: true,
vcsClientOverride: new GitNoCommitClient(),
vcsClientOverride: process.env.EAS_NO_VCS ? new NoVcsClient() : new GitNoCommitClient(),
withServerSideEnvironment: null,
});
+38 -16
View File
@@ -32,7 +32,7 @@ import {
promptVariableValueAsync,
promptVariableVisibilityAsync,
} from '../../utils/prompts';
import { performForEnvironmentsAsync } from '../../utils/variableUtils';
import { isEnvironment, performForEnvironmentsAsync } from '../../utils/variableUtils';
type CreateFlags = {
name?: string;
@@ -52,6 +52,15 @@ export default class EnvironmentVariableCreate extends EasCommand {
static override hidden = true;
static override args = [
{
name: 'environment',
description:
"Environment to create the variable in. One of 'production', 'preview', or 'development'.",
required: false,
},
];
static override flags = {
name: Flags.string({
description: 'Name of the variable',
@@ -83,7 +92,7 @@ export default class EnvironmentVariableCreate extends EasCommand {
};
async runAsync(): Promise<void> {
const { flags } = await this.parse(EnvironmentVariableCreate);
const { args, flags } = await this.parse(EnvironmentVariableCreate);
const validatedFlags = this.validateFlags(flags);
@@ -98,7 +107,7 @@ export default class EnvironmentVariableCreate extends EasCommand {
force,
type,
fileName,
} = await this.promptForMissingFlagsAsync(validatedFlags);
} = await this.promptForMissingFlagsAsync(validatedFlags, args);
const {
projectId,
@@ -293,15 +302,18 @@ export default class EnvironmentVariableCreate extends EasCommand {
}
}
private async promptForMissingFlagsAsync({
name,
value,
environment,
visibility,
'non-interactive': nonInteractive,
type,
...rest
}: CreateFlags): Promise<
private async promptForMissingFlagsAsync(
{
name,
value,
environment: environments,
visibility,
'non-interactive': nonInteractive,
type,
...rest
}: CreateFlags,
{ environment }: { environment?: string }
): Promise<
Required<
Omit<CreateFlags, 'type' | 'visibility'> & {
type: EnvironmentSecretType | undefined;
@@ -351,10 +363,20 @@ export default class EnvironmentVariableCreate extends EasCommand {
value = environmentFilePath ? await fs.readFile(environmentFilePath, 'base64') : value;
if (!environment) {
environment = await promptVariableEnvironmentAsync({ nonInteractive, multiple: true });
if (environment && !isEnvironment(environment.toUpperCase())) {
throw new Error("Invalid environment. Use one of 'production', 'preview', or 'development'.");
}
if (!environment || environment.length === 0) {
let newEnvironments = environments
? environments
: environment
? [environment.toUpperCase() as EnvironmentVariableEnvironment]
: undefined;
if (!newEnvironments) {
newEnvironments = await promptVariableEnvironmentAsync({ nonInteractive, multiple: true });
if (!newEnvironments || newEnvironments.length === 0) {
throw new Error('No environments selected');
}
}
@@ -364,7 +386,7 @@ export default class EnvironmentVariableCreate extends EasCommand {
return {
name,
value,
environment,
environment: newEnvironments,
visibility: newVisibility,
link: rest.link ?? false,
force: rest.force ?? false,
+27 -4
View File
@@ -13,7 +13,7 @@ import { EnvironmentVariableMutation } from '../../graphql/mutations/Environment
import { EnvironmentVariablesQuery } from '../../graphql/queries/EnvironmentVariablesQuery';
import Log from '../../log';
import { promptAsync, toggleConfirmAsync } from '../../prompts';
import { formatVariableName } from '../../utils/variableUtils';
import { formatVariableName, isEnvironment } from '../../utils/variableUtils';
type DeleteFlags = {
'variable-name'?: string;
@@ -39,19 +39,28 @@ export default class EnvironmentVariableDelete extends EasCommand {
...EASNonInteractiveFlag,
};
static override args = [
{
name: 'environment',
description:
"Current environment of the variable to delete. One of 'production', 'preview', or 'development'.",
required: false,
},
];
static override contextDefinition = {
...this.ContextOptions.ProjectId,
...this.ContextOptions.LoggedIn,
};
async runAsync(): Promise<void> {
const { flags } = await this.parse(EnvironmentVariableDelete);
const { args, flags } = await this.parse(EnvironmentVariableDelete);
const {
'variable-name': name,
'variable-environment': environment,
'non-interactive': nonInteractive,
scope,
} = this.validateFlags(flags);
} = this.validateInputs(flags, args);
const {
projectId,
loggedIn: { graphqlClient },
@@ -130,7 +139,10 @@ export default class EnvironmentVariableDelete extends EasCommand {
Log.withTick(`️Deleted variable ${selectedVariable.name}".`);
}
private validateFlags(flags: DeleteFlags): DeleteFlags {
private validateInputs(
flags: DeleteFlags,
{ environment }: { environment?: string }
): DeleteFlags {
if (flags['non-interactive']) {
if (!flags['variable-name']) {
throw new Error(
@@ -141,6 +153,17 @@ export default class EnvironmentVariableDelete extends EasCommand {
}
}
if (environment) {
environment = environment.toUpperCase();
if (!isEnvironment(environment)) {
throw new Error(
"Invalid environment. Use one of 'production', 'preview', or 'development'."
);
}
return { ...flags, 'variable-environment': environment };
}
return flags;
}
}
+35 -24
View File
@@ -3,24 +3,26 @@ import chalk from 'chalk';
import EasCommand from '../../commandUtils/EasCommand';
import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
import { EASEnvironmentFlag, EASNonInteractiveFlag } from '../../commandUtils/flags';
import { EASNonInteractiveFlag } from '../../commandUtils/flags';
import { EnvironmentVariableEnvironment } from '../../graphql/generated';
import { EnvironmentVariablesQuery } from '../../graphql/queries/EnvironmentVariablesQuery';
import Log from '../../log';
import { promptVariableEnvironmentAsync } from '../../utils/prompts';
import { isEnvironment } from '../../utils/variableUtils';
type ParsedFlags =
| {
nonInteractive: true;
environment: EnvironmentVariableEnvironment;
command: string;
}
| {
nonInteractive: false;
environment?: EnvironmentVariableEnvironment;
command: string;
};
interface RawFlags {
environment?: EnvironmentVariableEnvironment;
'non-interactive': boolean;
}
@@ -36,25 +38,27 @@ export default class EnvExec extends EasCommand {
};
static override flags = {
...EASEnvironmentFlag,
...EASNonInteractiveFlag,
};
static override args = [
{
name: 'BASH_COMMAND',
name: 'environment',
required: true,
description:
"Environment to execute the command in. One of 'production', 'preview', or 'development'.",
},
{
name: 'bash_command',
required: true,
description: 'bash command to execute with the environment variables from the environment',
},
];
async runAsync(): Promise<void> {
const {
flags,
args: { BASH_COMMAND: command },
} = await this.parse(EnvExec);
const { flags, args } = await this.parse(EnvExec);
const parsedFlags = this.sanitizeFlags(flags);
const parsedFlags = this.sanitizeFlagsAndArgs(flags, args);
const {
projectId,
@@ -72,25 +76,32 @@ export default class EnvExec extends EasCommand {
environment,
});
await this.runCommandWithEnvVarsAsync({ command, environmentVariables });
await this.runCommandWithEnvVarsAsync({
command: parsedFlags.command,
environmentVariables,
});
}
private sanitizeFlags(rawFlags: RawFlags): ParsedFlags {
const environment = rawFlags.environment;
if (rawFlags['non-interactive']) {
if (!environment) {
throw new Error(
'You must specify an environment when running in non-interactive mode. Use the --environment flag.'
);
}
return {
nonInteractive: true,
environment,
};
private sanitizeFlagsAndArgs(
rawFlags: RawFlags,
{ bash_command, environment }: Record<string, string>
): ParsedFlags {
if (rawFlags['non-interactive'] && (!bash_command || !environment)) {
throw new Error(
"You must specify both environment and bash command when running in non-interactive mode. Run command as `eas env:exec ENVIRONMENT 'bash command'`."
);
}
environment = environment?.toUpperCase();
if (!isEnvironment(environment)) {
throw new Error("Invalid environment. Use one of 'production', 'preview', or 'development'.");
}
return {
nonInteractive: false,
environment: rawFlags.environment,
nonInteractive: rawFlags['non-interactive'],
environment,
command: bash_command,
};
}
+32 -5
View File
@@ -18,7 +18,7 @@ import {
import { EnvironmentVariablesQuery } from '../../graphql/queries/EnvironmentVariablesQuery';
import Log from '../../log';
import { promptVariableEnvironmentAsync, promptVariableNameAsync } from '../../utils/prompts';
import { formatVariable, formatVariableValue } from '../../utils/variableUtils';
import { formatVariable, formatVariableValue, isEnvironment } from '../../utils/variableUtils';
type GetFlags = {
'variable-name'?: string;
@@ -38,6 +38,15 @@ export default class EnvironmentVariableGet extends EasCommand {
...this.ContextOptions.LoggedIn,
};
static override args = [
{
name: 'environment',
description:
"Current environment of the variable. One of 'production', 'preview', or 'development'.",
required: false,
},
];
static override flags = {
'variable-name': Flags.string({
description: 'Name of the variable',
@@ -52,7 +61,7 @@ export default class EnvironmentVariableGet extends EasCommand {
};
async runAsync(): Promise<void> {
const { flags } = await this.parse(EnvironmentVariableGet);
const { args, flags } = await this.parse(EnvironmentVariableGet);
let {
'variable-environment': environment,
@@ -60,7 +69,7 @@ export default class EnvironmentVariableGet extends EasCommand {
'non-interactive': nonInteractive,
format,
scope,
} = this.validateFlags(flags);
} = this.validateInputs(flags, args);
const {
projectId,
@@ -117,7 +126,7 @@ export default class EnvironmentVariableGet extends EasCommand {
}
}
private validateFlags(flags: GetFlags): GetFlags {
private validateInputs(flags: GetFlags, { environment }: { environment?: string }): GetFlags {
if (flags['non-interactive']) {
if (!flags['variable-name']) {
throw new Error('Variable name is required. Run the command with --variable-name flag.');
@@ -125,10 +134,28 @@ export default class EnvironmentVariableGet extends EasCommand {
if (!flags.scope) {
throw new Error('Scope is required. Run the command with --scope flag.');
}
if (!flags['variable-environment']) {
if (!(flags['variable-environment'] ?? environment)) {
throw new Error('Environment is required.');
}
}
if (environment && flags['variable-environment']) {
throw new Error(
"You can't use both --variable-environment flag when environment is passed as an argument. Run `eas env:get --help` for more information."
);
}
if (environment) {
environment = environment.toUpperCase();
if (!isEnvironment(environment)) {
throw new Error(
"Invalid environment. Use one of 'production', 'preview', or 'development'."
);
}
return {
'variable-environment': environment,
...flags,
};
}
return flags;
}
}
+55 -8
View File
@@ -14,7 +14,14 @@ import Log from '../../log';
import { getDisplayNameForProjectIdAsync } from '../../project/projectUtils';
import { selectAsync } from '../../prompts';
import { promptVariableEnvironmentAsync } from '../../utils/prompts';
import { formatVariableName } from '../../utils/variableUtils';
import { formatVariableName, isEnvironment } from '../../utils/variableUtils';
type LinkFlags = {
'variable-name'?: string;
'variable-environment'?: EnvironmentVariableEnvironment;
'non-interactive': boolean;
environment?: EnvironmentVariableEnvironment[];
};
export default class EnvironmentVariableLink extends EasCommand {
static override description = 'link a shared environment variable to the current project';
@@ -33,20 +40,30 @@ export default class EnvironmentVariableLink extends EasCommand {
...EASNonInteractiveFlag,
};
static override args = [
{
name: 'environment',
description:
"Environment to pull variables from. One of 'production', 'preview', or 'development'.",
required: false,
},
];
static override contextDefinition = {
...this.ContextOptions.ProjectId,
...this.ContextOptions.LoggedIn,
};
async runAsync(): Promise<void> {
const { args, flags } = await this.parse(EnvironmentVariableLink);
let {
flags: {
'variable-name': name,
'variable-environment': currentEnvironment,
'non-interactive': nonInteractive,
environment: environments,
},
} = await this.parse(EnvironmentVariableLink);
'variable-name': name,
'variable-environment': currentEnvironment,
'non-interactive': nonInteractive,
environment: environments,
} = this.validateInputs(flags, args);
const {
projectId,
loggedIn: { graphqlClient },
@@ -155,4 +172,34 @@ export default class EnvironmentVariableLink extends EasCommand {
}
}
}
private validateInputs(flags: LinkFlags, { environment }: Record<string, string>): LinkFlags {
environment = environment?.toUpperCase();
if (environment && !isEnvironment(environment)) {
throw new Error("Invalid environment. Use one of 'production', 'preview', or 'development'.");
}
const environments = flags.environment
? flags.environment
: environment
? [environment as EnvironmentVariableEnvironment]
: undefined;
if (flags['non-interactive']) {
if (!flags['variable-name']) {
throw new Error(
`Environment variable needs 'name' to be specified when running in non-interactive mode. Run the command with ${chalk.bold(
'--variable-name VARIABLE_NAME'
)} flag to fix the issue`
);
}
}
return {
'variable-name': flags['variable-name'],
'variable-environment': flags['variable-environment'],
'non-interactive': flags['non-interactive'],
environment: environments,
};
}
}
+51 -10
View File
@@ -18,6 +18,7 @@ import { promptVariableEnvironmentAsync } from '../../utils/prompts';
import {
formatVariable,
formatVariableValue,
isEnvironment,
performForEnvironmentsAsync,
} from '../../utils/variableUtils';
@@ -65,6 +66,15 @@ async function getVariablesForScopeAsync(
});
}
type ListFlags = {
scope: EnvironmentVariableScope;
format: string;
environment: EnvironmentVariableEnvironment[] | undefined;
'include-sensitive': boolean;
'include-file-content': boolean;
'non-interactive'?: boolean;
};
export default class EnvironmentValueList extends EasCommand {
static override description = 'list environment variables for the current project';
@@ -84,22 +94,32 @@ export default class EnvironmentValueList extends EasCommand {
description: 'Display files content in the output',
default: false,
}),
...EASMultiEnvironmentFlag,
...EASVariableFormatFlag,
...EASVariableScopeFlag,
...EASMultiEnvironmentFlag,
};
static override args = [
{
name: 'environment',
description:
"Environment to list the variables from. One of 'production', 'preview', or 'development'.",
required: false,
},
];
async runAsync(): Promise<void> {
const { args, flags } = await this.parse(EnvironmentValueList);
let {
flags: {
environment: environments,
format,
scope,
'include-sensitive': includeSensitive,
'include-file-content': includeFileContent,
'non-interactive': nonInteractive,
},
} = await this.parse(EnvironmentValueList);
format,
environment: environments,
scope,
'include-sensitive': includeSensitive,
'include-file-content': includeFileContent,
'non-interactive': nonInteractive,
} = this.validateInputs(flags, args);
const {
projectId,
loggedIn: { graphqlClient },
@@ -146,4 +166,25 @@ export default class EnvironmentValueList extends EasCommand {
}
});
}
private validateInputs(
flags: ListFlags,
{ environment }: Record<string, string>
): ListFlags & { 'non-interactive': boolean } {
if (environment && !isEnvironment(environment.toUpperCase())) {
throw new Error("Invalid environment. Use one of 'production', 'preview', or 'development'.");
}
const environments = flags.environment
? flags.environment
: environment
? [environment.toUpperCase() as EnvironmentVariableEnvironment]
: undefined;
return {
...flags,
'non-interactive': flags['non-interactive'] ?? false,
environment: environments,
};
}
}
+20 -2
View File
@@ -13,6 +13,7 @@ import {
import Log from '../../log';
import { confirmAsync } from '../../prompts';
import { promptVariableEnvironmentAsync } from '../../utils/prompts';
import { isEnvironment } from '../../utils/variableUtils';
export default class EnvironmentVariablePull extends EasCommand {
static override description = 'pull env file';
@@ -25,9 +26,18 @@ export default class EnvironmentVariablePull extends EasCommand {
...this.ContextOptions.ProjectDir,
};
static override args = [
{
name: 'environment',
description:
"Environment to pull variables from. One of 'production', 'preview', or 'development'.",
required: false,
},
];
static override flags = {
...EASEnvironmentFlag,
...EASNonInteractiveFlag,
...EASEnvironmentFlag,
path: Flags.string({
description: 'Path to the result `.env` file',
default: '.env.local',
@@ -36,12 +46,20 @@ export default class EnvironmentVariablePull extends EasCommand {
async runAsync(): Promise<void> {
let {
flags: { environment, path: targetPath, 'non-interactive': nonInteractive },
args: { environment: argEnvironment },
flags: { environment: flagEnvironment, path: targetPath, 'non-interactive': nonInteractive },
} = await this.parse(EnvironmentVariablePull);
let environment = flagEnvironment?.toUpperCase() ?? argEnvironment?.toUpperCase();
if (!environment) {
environment = await promptVariableEnvironmentAsync({ nonInteractive });
}
if (!isEnvironment(environment)) {
throw new Error("Invalid environment. Use one of 'production', 'preview', or 'development'.");
}
const {
projectId,
loggedIn: { graphqlClient },
+31 -3
View File
@@ -19,6 +19,7 @@ import { EnvironmentVariablesQuery } from '../../graphql/queries/EnvironmentVari
import Log from '../../log';
import { confirmAsync, promptAsync } from '../../prompts';
import { promptVariableEnvironmentAsync } from '../../utils/prompts';
import { isEnvironment } from '../../utils/variableUtils';
export default class EnvironmentVariablePush extends EasCommand {
static override description = 'push env file';
@@ -38,10 +39,19 @@ export default class EnvironmentVariablePush extends EasCommand {
}),
};
static override args = [
{
name: 'environment',
description:
"Environment to push variables to. One of 'production', 'preview', or 'development'.",
required: false,
},
];
async runAsync(): Promise<void> {
let {
flags: { environment: environments, path: envPath },
} = await this.parse(EnvironmentVariablePush);
const { args, flags } = await this.parse(EnvironmentVariablePush);
let { environment: environments, path: envPath } = this.parseFlagsAndArgs(flags, args);
const {
projectId,
@@ -189,6 +199,24 @@ export default class EnvironmentVariablePush extends EasCommand {
Log.log(`Uploaded env file to ${environments.join(', ').toLocaleLowerCase()}.`);
}
parseFlagsAndArgs(
flags: { path: string; environment: EnvironmentVariableEnvironment[] | undefined },
{ environment }: Record<string, string>
): { environment?: EnvironmentVariableEnvironment[]; path: string } {
if (environment && !isEnvironment(environment.toUpperCase())) {
throw new Error("Invalid environment. Use one of 'production', 'preview', or 'development'.");
}
const environments =
flags.environment ??
(environment ? [environment.toUpperCase() as EnvironmentVariableEnvironment] : undefined);
return {
...flags,
environment: environments,
};
}
private async parseEnvFileAsync(
envPath: string,
environments: EnvironmentVariableEnvironment[]
+51 -7
View File
@@ -10,7 +10,13 @@ import Log from '../../log';
import { getDisplayNameForProjectIdAsync } from '../../project/projectUtils';
import { selectAsync } from '../../prompts';
import { promptVariableEnvironmentAsync } from '../../utils/prompts';
import { formatVariableName } from '../../utils/variableUtils';
import { formatVariableName, isEnvironment } from '../../utils/variableUtils';
type UnlinkFlags = {
'variable-name'?: string;
'non-interactive': boolean;
environment?: EnvironmentVariableEnvironment[];
};
export default class EnvironmentVariableUnlink extends EasCommand {
static override description = 'unlink a shared environment variable to the current project';
@@ -30,14 +36,24 @@ export default class EnvironmentVariableUnlink extends EasCommand {
...this.ContextOptions.LoggedIn,
};
static override args = [
{
name: 'environment',
description:
"Environment to unlink the variable from. One of 'production', 'preview', or 'development'.",
required: false,
},
];
async runAsync(): Promise<void> {
const { args, flags } = await this.parse(EnvironmentVariableUnlink);
let {
flags: {
'variable-name': name,
'non-interactive': nonInteractive,
environment: unlinkEnvironments,
},
} = await this.parse(EnvironmentVariableUnlink);
'variable-name': name,
'non-interactive': nonInteractive,
environment: unlinkEnvironments,
} = this.validateInputs(flags, args);
const {
projectId,
loggedIn: { graphqlClient },
@@ -143,4 +159,32 @@ export default class EnvironmentVariableUnlink extends EasCommand {
}
}
}
private validateInputs(
flags: UnlinkFlags,
{ environment }: { environment?: string }
): UnlinkFlags {
if (flags['non-interactive']) {
if (!flags['variable-name']) {
throw new Error(
'Current name is required in non-interactive mode. Run the command with --variable-name flag.'
);
}
}
if (environment) {
environment = environment.toUpperCase();
if (!isEnvironment(environment)) {
throw new Error(
"Invalid environment. Use one of 'production', 'preview', or 'development'."
);
}
return {
environment: [environment],
...flags,
};
}
return flags;
}
}
+29 -4
View File
@@ -35,7 +35,7 @@ import {
promptVariableValueAsync,
promptVariableVisibilityAsync,
} from '../../utils/prompts';
import { formatVariableName } from '../../utils/variableUtils';
import { formatVariableName, isEnvironment } from '../../utils/variableUtils';
type UpdateFlags = {
name?: string;
@@ -79,6 +79,15 @@ export default class EnvironmentVariableUpdate extends EasCommand {
...EASNonInteractiveFlag,
};
static override args = [
{
name: 'environment',
description:
"Current environment of the variable to update. One of 'production', 'preview', or 'development'.",
required: false,
},
];
static override contextDefinition = {
...this.ContextOptions.ProjectId,
...this.ContextOptions.Analytics,
@@ -86,7 +95,7 @@ export default class EnvironmentVariableUpdate extends EasCommand {
};
async runAsync(): Promise<void> {
const { flags } = await this.parse(EnvironmentVariableUpdate);
const { args, flags } = await this.parse(EnvironmentVariableUpdate);
const {
name,
value: rawValue,
@@ -97,7 +106,7 @@ export default class EnvironmentVariableUpdate extends EasCommand {
environment: environments,
type,
visibility,
} = this.validateFlags(flags);
} = this.validateFlags(flags, args);
const {
projectId,
@@ -185,7 +194,10 @@ export default class EnvironmentVariableUpdate extends EasCommand {
Log.withTick(`Updated variable ${chalk.bold(selectedVariable.name)} ${suffix}.`);
}
private validateFlags(flags: UpdateFlags): UpdateFlags {
private validateFlags(
flags: UpdateFlags,
{ environment }: { environment?: string }
): UpdateFlags {
if (flags['non-interactive']) {
if (!flags['variable-name']) {
throw new Error(
@@ -197,6 +209,19 @@ export default class EnvironmentVariableUpdate extends EasCommand {
}
}
if (environment) {
environment = environment.toUpperCase();
if (!isEnvironment(environment)) {
throw new Error(
"Invalid environment. Use one of 'production', 'preview', or 'development'."
);
}
return {
'variable-environment': environment,
...flags,
};
}
return flags;
}
@@ -14,6 +14,7 @@ import { AppMutation } from '../../../graphql/mutations/AppMutation';
import { AppQuery } from '../../../graphql/queries/AppQuery';
import { createOrModifyExpoConfigAsync } from '../../../project/expoConfig';
import { findProjectIdByAccountNameAndSlugNullableAsync } from '../../../project/fetchOrCreateProjectIDForWriteToConfigWithConfirmationAsync';
import { isExpoInstalled } from '../../../project/projectUtils';
import { confirmAsync, promptAsync } from '../../../prompts';
import ProjectInit from '../init';
@@ -34,6 +35,7 @@ jest.mock('../../../ora', () => ({
}));
jest.mock('../../../project/fetchOrCreateProjectIDForWriteToConfigWithConfirmationAsync');
jest.mock('../../../commandUtils/context/contextUtils/getProjectIdAsync');
jest.mock('../../../project/projectUtils');
let originalProcessArgv: string[];
@@ -92,6 +94,7 @@ function mockTestProject(options: {
graphqlClient,
authenticationInfo: { accessToken: null, sessionSecret: '1234' },
});
jest.mocked(isExpoInstalled).mockReturnValue(true);
}
const commandOptions = { root: '/test-project' } as any;
@@ -13,7 +13,7 @@ import { AppMutation } from '../../graphql/mutations/AppMutation';
import { AppQuery } from '../../graphql/queries/AppQuery';
import Log, { link } from '../../log';
import { ora } from '../../ora';
import { createOrModifyExpoConfigAsync, getPrivateExpoConfig } from '../../project/expoConfig';
import { createOrModifyExpoConfigAsync, getPrivateExpoConfigAsync } from '../../project/expoConfig';
import { findProjectIdByAccountNameAndSlugNullableAsync } from '../../project/fetchOrCreateProjectIDForWriteToConfigWithConfirmationAsync';
import { toAppPrivacy } from '../../project/projectUtils';
import { Choice, confirmAsync, promptAsync } from '../../prompts';
@@ -106,7 +106,7 @@ export default class ProjectInit extends EasCommand {
projectDir: string,
{ force, nonInteractive }: InitializeMethodOptions
): Promise<void> {
const exp = getPrivateExpoConfig(projectDir);
const exp = await getPrivateExpoConfigAsync(projectDir);
const appForProjectId = await AppQuery.byIdAsync(graphqlClient, projectId);
const correctOwner = appForProjectId.ownerAccount.name;
const correctSlug = appForProjectId.slug;
@@ -161,7 +161,7 @@ export default class ProjectInit extends EasCommand {
projectDir: string,
{ force, nonInteractive }: InitializeMethodOptions
): Promise<void> {
const exp = getPrivateExpoConfig(projectDir);
const exp = await getPrivateExpoConfigAsync(projectDir);
const existingProjectId = exp.extra?.eas?.projectId;
if (projectId === existingProjectId) {
@@ -218,7 +218,7 @@ export default class ProjectInit extends EasCommand {
projectDir: string,
{ force, nonInteractive }: InitializeMethodOptions
): Promise<string> {
const exp = getPrivateExpoConfig(projectDir);
const exp = await getPrivateExpoConfigAsync(projectDir);
const existingProjectId = exp.extra?.eas?.projectId;
if (existingProjectId) {
@@ -31,7 +31,7 @@ import {
import { installDependenciesAsync } from '../../onboarding/installDependencies';
import { runCommandAsync } from '../../onboarding/runCommand';
import { RequestedPlatform } from '../../platform';
import { ExpoConfigOptions, getPrivateExpoConfig } from '../../project/expoConfig';
import { ExpoConfigOptions, getPrivateExpoConfigAsync } from '../../project/expoConfig';
import { promptAsync } from '../../prompts';
import { Actor } from '../../user/User';
import { easCliVersion } from '../../utils/easCli';
@@ -339,7 +339,7 @@ async function getPrivateExpoConfigWithProjectIdAsync({
actor: Actor;
options?: ExpoConfigOptions;
}): Promise<CredentialsContextProjectInfo> {
const expBefore = getPrivateExpoConfig(projectDir, options);
const expBefore = await getPrivateExpoConfigAsync(projectDir, options);
const projectId = await validateOrSetProjectIdAsync({
exp: expBefore,
graphqlClient,
@@ -349,7 +349,7 @@ async function getPrivateExpoConfigWithProjectIdAsync({
},
cwd: projectDir,
});
const exp = getPrivateExpoConfig(projectDir, options);
const exp = await getPrivateExpoConfigAsync(projectDir, options);
return {
exp,
projectId,
@@ -19,6 +19,7 @@ import { SubmissionContext, createSubmissionContextAsync } from '../../submit/co
import IosSubmitCommand from '../../submit/ios/IosSubmitCommand';
import { enableJsonOutput, printJsonOnlyOutput } from '../../utils/json';
import GitNoCommitClient from '../../vcs/clients/gitNoCommit';
import NoVcsClient from '../../vcs/clients/noVcs';
/**
* This command will be run on the EAS workers.
@@ -64,7 +65,7 @@ export default class SubmitInternal extends EasCommand {
vcsClient,
} = await this.getContextAsync(SubmitInternal, {
nonInteractive: true,
vcsClientOverride: new GitNoCommitClient(),
vcsClientOverride: process.env.EAS_NO_VCS ? new NoVcsClient() : new GitNoCommitClient(),
withServerSideEnvironment: null,
});
@@ -140,18 +140,7 @@ describe(UpdatePublish.name, () => {
const flags = ['--non-interactive', '--branch=branch123', '--message=abc'];
// Add configuration to the project that should not be included in the update
const { appJson } = mockTestProject({
expoConfig: {
hooks: {
postPublish: [
{
file: 'custom-hook.js',
config: { some: 'config' },
},
],
},
},
});
const { appJson } = mockTestProject();
const { platforms, runtimeVersion } = mockTestExport({ platforms: ['ios'] });
@@ -145,18 +145,7 @@ describe(UpdateRollBackToEmbedded.name, () => {
const flags = ['--non-interactive', '--branch=branch123', '--message=abc'];
// Add configuration to the project that should not be included in the update
mockTestProject({
expoConfig: {
hooks: {
postPublish: [
{
file: 'custom-hook.js',
config: { some: 'config' },
},
],
},
},
});
mockTestProject();
const platforms = ['ios'];
const runtimeVersion = 'exposdk:47.0.0';
@@ -3,7 +3,7 @@ import chalk from 'chalk';
import { easJsonExistsAsync } from '../../build/configure';
import EasCommand from '../../commandUtils/EasCommand';
import { EASNonInteractiveFlag } from '../../commandUtils/flags';
import { EASNonInteractiveFlag, EasUpdateEnvironmentFlag } from '../../commandUtils/flags';
import Log, { learnMore } from '../../log';
import { RequestedPlatform } from '../../platform';
import {
@@ -15,12 +15,13 @@ export default class UpdateConfigure extends EasCommand {
static override description = 'configure the project to support EAS Update';
static override flags = {
platform: Flags.enum({
platform: Flags.enum<RequestedPlatform>({
description: 'Platform to configure',
char: 'p',
options: ['android', 'ios', 'all'],
default: 'all',
options: Object.values(RequestedPlatform),
default: RequestedPlatform.All,
}),
...EasUpdateEnvironmentFlag,
...EASNonInteractiveFlag,
};
@@ -32,13 +33,12 @@ export default class UpdateConfigure extends EasCommand {
async runAsync(): Promise<void> {
const { flags } = await this.parse(UpdateConfigure);
const platform = flags.platform as RequestedPlatform;
const {
privateProjectConfig: { projectId, exp, projectDir },
vcsClient,
} = await this.getContextAsync(UpdateConfigure, {
nonInteractive: flags['non-interactive'],
withServerSideEnvironment: null,
withServerSideEnvironment: flags['environment'],
});
Log.log(
@@ -51,7 +51,7 @@ export default class UpdateConfigure extends EasCommand {
exp,
projectId,
projectDir,
platform,
platform: flags['platform'],
vcsClient,
env: undefined,
});
+15 -49
View File
@@ -8,7 +8,7 @@ import { transformFingerprintSource } from '../../build/graphql';
import { ensureRepoIsCleanAsync } from '../../build/utils/repository';
import { getUpdateGroupUrl } from '../../build/utils/url';
import EasCommand from '../../commandUtils/EasCommand';
import { EasNonInteractiveAndJsonFlags } from '../../commandUtils/flags';
import { EasNonInteractiveAndJsonFlags, EasUpdateEnvironmentFlag } from '../../commandUtils/flags';
import { getPaginatedQueryOptions } from '../../commandUtils/pagination';
import fetch from '../../fetch';
import {
@@ -31,7 +31,6 @@ import {
buildBundlesAsync,
buildUnsortedUpdateInfoGroupAsync,
collectAssetsAsync,
defaultPublishPlatforms,
filterCollectedAssetsByRequestedPlatforms,
generateEasMetadataAsync,
getBranchNameForCommandAsync,
@@ -64,7 +63,7 @@ type RawUpdateFlags = {
branch?: string;
channel?: string;
message?: string;
platform: string;
platform: RequestedPlatform;
'input-dir': string;
'skip-bundler': boolean;
'clear-cache': boolean;
@@ -73,7 +72,7 @@ type RawUpdateFlags = {
'rollout-percentage'?: number;
'non-interactive': boolean;
json: boolean;
'with-eas-environment-variables-set'?: string;
environment: EnvironmentVariableEnvironment | null;
};
type UpdateFlags = {
@@ -90,7 +89,7 @@ type UpdateFlags = {
rolloutPercentage?: number;
json: boolean;
nonInteractive: boolean;
withEasEnvironmentVariablesSet?: EnvironmentVariableEnvironment;
environment: EnvironmentVariableEnvironment | null;
};
export default class UpdatePublish extends EasCommand {
@@ -133,14 +132,10 @@ export default class UpdatePublish extends EasCommand {
min: 0,
max: 100,
}),
platform: Flags.enum({
platform: Flags.enum<RequestedPlatform>({
char: 'p',
options: [
// TODO: Add web when it's fully supported
...defaultPublishPlatforms,
'all',
],
default: 'all',
options: Object.values(RequestedPlatform), // TODO: Add web when it's fully supported
default: RequestedPlatform.All,
required: false,
}),
auto: Flags.boolean({
@@ -152,18 +147,7 @@ export default class UpdatePublish extends EasCommand {
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,
}),
'with-eas-environment-variables-set': Flags.enum({
description: 'Environment to use for EAS environment variables',
options: [
EnvironmentVariableEnvironment.Development,
EnvironmentVariableEnvironment.Preview,
EnvironmentVariableEnvironment.Production,
].map(env => env.toLowerCase()),
// eslint-disable-next-line async-protect/async-suffix
parse: async input => input.toUpperCase(),
required: false,
hidden: true,
}),
...EasUpdateEnvironmentFlag,
...EasNonInteractiveAndJsonFlags,
};
@@ -191,7 +175,7 @@ export default class UpdatePublish extends EasCommand {
branchName: branchNameArg,
emitMetadata,
rolloutPercentage,
withEasEnvironmentVariablesSet,
environment,
} = this.sanitizeFlags(rawFlags);
const {
@@ -202,7 +186,7 @@ export default class UpdatePublish extends EasCommand {
getServerSideEnvironmentVariablesAsync,
} = await this.getContextAsync(UpdatePublish, {
nonInteractive,
withServerSideEnvironment: withEasEnvironmentVariablesSet ?? null,
withServerSideEnvironment: environment,
});
if (jsonFlag) {
@@ -262,7 +246,7 @@ export default class UpdatePublish extends EasCommand {
platformFlag: requestedPlatform,
clearCache,
extraEnv: {
...(withEasEnvironmentVariablesSet
...(environment
? { ...(await getServerSideEnvironmentVariablesAsync()), EXPO_NO_DOTENV: '1' }
: {}),
},
@@ -426,7 +410,7 @@ export default class UpdatePublish extends EasCommand {
fingerprintSource: info.fingerprint
? (
await maybeUploadFingerprintAsync({
runtimeVersion: info.runtimeVersion,
hash: info.runtimeVersion,
fingerprint: info.fingerprint,
graphqlClient,
})
@@ -661,22 +645,6 @@ export default class UpdatePublish extends EasCommand {
);
}
if (
flags['with-eas-environment-variables-set'] &&
!Object.values(EnvironmentVariableEnvironment).includes(
flags['with-eas-environment-variables-set'] as EnvironmentVariableEnvironment
)
) {
Errors.error(
`--with-eas-environment-variables-set must be one of ${Object.values(
EnvironmentVariableEnvironment
)
.map(env => `"${env.toLocaleLowerCase()}"`)
.join(', ')}`,
{ exit: 1 }
);
}
return {
auto,
branchName,
@@ -684,16 +652,14 @@ export default class UpdatePublish extends EasCommand {
updateMessage,
inputDir: flags['input-dir'],
skipBundler,
clearCache: flags['clear-cache'] ? true : !!flags['with-eas-environment-variables-set'],
platform: flags.platform as RequestedPlatform,
clearCache: flags['clear-cache'] ? true : !!flags['environment'],
platform: flags.platform,
privateKeyPath: flags['private-key-path'],
rolloutPercentage: flags['rollout-percentage'],
nonInteractive,
emitMetadata,
json: flags.json ?? false,
withEasEnvironmentVariablesSet: flags[
'with-eas-environment-variables-set'
] as EnvironmentVariableEnvironment,
environment: flags['environment'],
};
}
}
@@ -0,0 +1,115 @@
import fs from 'node:fs';
import * as path from 'node:path';
import { getWorkflowRunUrl } from '../../build/utils/url';
import EasCommand from '../../commandUtils/EasCommand';
import { EASNonInteractiveFlag } from '../../commandUtils/flags';
import { WorkflowProjectSourceType } from '../../graphql/generated';
import { WorkflowRunMutation } from '../../graphql/mutations/WorkflowRunMutation';
import Log, { link } from '../../log';
import { getOwnerAccountForProjectIdAsync } from '../../project/projectUtils';
import { uploadAccountScopedEasJsonAsync } from '../../project/uploadAccountScopedEasJsonAsync';
import { uploadAccountScopedProjectSourceAsync } from '../../project/uploadAccountScopedProjectSourceAsync';
export default class WorkflowRun extends EasCommand {
static override description = 'Run an EAS workflow';
// TODO(@sjchmiela): Keep command hidden until workflows are live
static override hidden = true;
static override state = 'beta';
static override args = [{ name: 'file', description: 'Path to the workflow file to run' }];
static override flags = {
...EASNonInteractiveFlag,
};
static override contextDefinition = {
...this.ContextOptions.DynamicProjectConfig,
...this.ContextOptions.ProjectDir,
...this.ContextOptions.Vcs,
...this.ContextOptions.LoggedIn,
};
async runAsync(): Promise<void> {
const { flags, args } = await this.parse(WorkflowRun);
Log.warn('Workflows are in beta and subject to breaking changes.');
const {
getDynamicPrivateProjectConfigAsync,
loggedIn: { graphqlClient },
vcsClient,
projectDir,
} = await this.getContextAsync(WorkflowRun, {
nonInteractive: flags['non-interactive'],
withServerSideEnvironment: null,
});
let yamlConfig: string;
try {
yamlConfig = await fs.promises.readFile(path.join(projectDir, args.file), 'utf8');
} catch (err) {
Log.error('Failed to read workflow file.');
throw err;
}
const {
projectId,
exp: { slug: projectName },
} = await getDynamicPrivateProjectConfigAsync();
const account = await getOwnerAccountForProjectIdAsync(graphqlClient, projectId);
let projectArchiveBucketKey: string;
let easJsonBucketKey: string;
try {
({ projectArchiveBucketKey } = await uploadAccountScopedProjectSourceAsync({
graphqlClient,
vcsClient,
accountId: account.id,
}));
({ easJsonBucketKey } = await uploadAccountScopedEasJsonAsync({
graphqlClient,
accountId: account.id,
projectDir,
}));
} catch (err) {
Log.error('Failed to upload project sources.');
throw err;
}
try {
const { id: workflowRunId } = await WorkflowRunMutation.createWorkflowRunAsync(
graphqlClient,
{
appId: projectId,
workflowRevisionInput: {
fileName: path.basename(args.file),
yamlConfig,
},
workflowRunInput: {
projectSource: {
type: WorkflowProjectSourceType.Gcs,
projectArchiveBucketKey,
easJsonBucketKey,
},
},
}
);
Log.newLine();
Log.succeed(
`Workflow started successfully. ${link(
getWorkflowRunUrl(account.name, projectName, workflowRunId)
)}`
);
} catch (err) {
Log.error('Failed to start the workflow with the API.');
throw err;
}
}
}
@@ -0,0 +1,98 @@
import fs from 'fs/promises';
import path from 'path';
import * as YAML from 'yaml';
import EasCommand from '../../commandUtils/EasCommand';
import Log from '../../log';
import { ora } from '../../ora';
export class WorkflowValidate extends EasCommand {
static override description = 'validate a workflow configuration yaml file';
static override hidden = true;
static override args = [
{
name: 'path',
description: 'Path to the workflow configuration YAML file (must end with .yml or .yaml)',
required: true,
},
];
async runAsync(): Promise<void> {
const {
args: { path: filePath },
} = await this.parse(WorkflowValidate);
const spinner = ora().start('Validating the workflow YAML file…');
try {
await validateYAMLAsync(filePath);
spinner.succeed('Workflow configuration YAML is valid.');
} catch (error) {
spinner.fail('Workflow configuration YAML is not valid.');
if (error instanceof YAML.YAMLParseError) {
Log.error(`YAML syntax error: ${error.message}`);
} else if (error instanceof Error) {
Log.error(error.message);
} else {
Log.error(`Unexpected error: ${String(error)}`);
}
process.exit(1);
}
}
}
async function checkIfFileExistsAsync(filePath: string): Promise<void> {
try {
await fs.access(filePath);
} catch {
throw new Error(`File does not exist: ${filePath}`);
}
}
function checkIfValidYAMLFileExtension(filePath: string): void {
const fileExtension = path.extname(filePath).toLowerCase();
if (fileExtension !== '.yml' && fileExtension !== '.yaml') {
throw new Error('File must have a .yml or .yaml extension');
}
}
async function validateYAMLAsync(filePath: string): Promise<void> {
await checkIfFileExistsAsync(filePath);
checkIfValidYAMLFileExtension(filePath);
try {
const fileContents = await fs.readFile(filePath, 'utf8');
// First check if the file is empty or only contains whitespace
if (!fileContents.trim()) {
throw new Error('YAML file is empty or contains only comments.');
}
const parsedYaml = YAML.parse(fileContents);
// Check if the parsed result is empty or null
if (
parsedYaml === null ||
parsedYaml === undefined ||
(typeof parsedYaml === 'object' && Object.keys(parsedYaml).length === 0)
) {
throw new Error('YAML file is empty or contains only comments.');
}
} catch (error) {
if (
error instanceof Error &&
error.message === 'YAML file is empty or contains only comments.'
) {
throw error;
}
if (error instanceof YAML.YAMLParseError || error instanceof Error) {
throw new Error(`YAML parsing error: ${error.message}`);
} else {
throw new Error(`YAML parsing error: ${String(error)}`);
}
}
}
@@ -21,8 +21,9 @@ export function createCtxMock(mockOverride: Record<string, any> = {}): Credentia
},
hasAppleCtx: jest.fn(() => true),
hasProjectContext: true,
exp: testAppJson,
getExpoConfigAsync: async () => testAppJson,
projectDir: '.',
getProjectIdAsync: async () => 'test-project-id',
};
return merge(defaultMock, mockOverride) as any;
}
@@ -101,14 +101,14 @@ export async function getAppLookupParamsFromContextAsync(
ctx: CredentialsContext,
gradleContext?: GradleBuildContext
): Promise<AppLookupParams> {
ctx.ensureProjectContext();
const projectName = ctx.exp.slug;
const projectId = ctx.projectId;
const exp = await ctx.getExpoConfigAsync();
const projectName = exp.slug;
const projectId = await ctx.getProjectIdAsync();
const account = await getOwnerAccountForProjectIdAsync(ctx.graphqlClient, projectId);
const androidApplicationIdentifier = await getApplicationIdAsync(
ctx.projectDir,
ctx.exp,
exp,
ctx.vcsClient,
gradleContext
);
@@ -16,7 +16,7 @@ export class CreateKeystore {
throw new Error(`New keystore cannot be created in non-interactive mode.`);
}
const projectId = ctx.projectId;
const projectId = await ctx.getProjectIdAsync();
const keystore = await this.provideOrGenerateAsync(ctx.graphqlClient, ctx.analytics, projectId);
const keystoreFragment = await ctx.android.createKeystoreAsync(
ctx.graphqlClient,
+7 -7
View File
@@ -10,7 +10,7 @@ import { AuthenticationMode } from './ios/appstore/authenticateTypes';
import { Analytics } from '../analytics/AnalyticsManager';
import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
import Log from '../log';
import { getPrivateExpoConfig } from '../project/expoConfig';
import { getPrivateExpoConfigAsync } from '../project/expoConfig';
import { confirmAsync } from '../prompts';
import { Actor } from '../user/User';
import { Client } from '../vcs/vcs';
@@ -67,22 +67,22 @@ export class CredentialsContext {
return !!this.projectInfo;
}
get exp(): ExpoConfig {
this.ensureProjectContext();
public async getExpoConfigAsync(): Promise<ExpoConfig> {
await this.ensureProjectContextAsync();
return this.projectInfo!.exp;
}
get projectId(): string {
this.ensureProjectContext();
public async getProjectIdAsync(): Promise<string> {
await this.ensureProjectContextAsync();
return this.projectInfo!.projectId;
}
public ensureProjectContext(): void {
public async ensureProjectContextAsync(): Promise<void> {
if (this.hasProjectContext) {
return;
}
// trigger getConfig error
getPrivateExpoConfig(this.options.projectDir);
await getPrivateExpoConfigAsync(this.options.projectDir);
}
async bestEffortAppStoreAuthenticateAsync(): Promise<void> {
@@ -91,9 +91,9 @@ export async function assignBuildCredentialsAsync(
}
export async function getAppFromContextAsync(ctx: CredentialsContext): Promise<App> {
ctx.ensureProjectContext();
const projectName = ctx.exp.slug;
const projectId = ctx.projectId;
const exp = await ctx.getExpoConfigAsync();
const projectName = exp.slug;
const projectId = await ctx.getProjectIdAsync();
const account = await getOwnerAccountForProjectIdAsync(ctx.graphqlClient, projectId);
return {
account,
@@ -94,7 +94,7 @@ export class ManageIos {
};
const account = ctx.hasProjectContext
? await getAccountForProjectAsync(ctx.projectId)
? await getAccountForProjectAsync(await ctx.getProjectIdAsync())
: ensureActorHasPrimaryAccount(ctx.user);
let app = null;
@@ -195,18 +195,19 @@ export class ManageIos {
}> {
assert(ctx.hasProjectContext, 'createProjectContextAsync: must have project context.');
const app = { account, projectName: ctx.exp.slug };
const exp = await ctx.getExpoConfigAsync();
const app = { account, projectName: exp.slug };
const xcodeBuildContext = await resolveXcodeBuildContextAsync(
{
projectDir: ctx.projectDir,
nonInteractive: ctx.nonInteractive,
exp: ctx.exp,
exp,
vcsClient: ctx.vcsClient,
},
buildProfile
);
const targets = await resolveTargetsAsync({
exp: ctx.exp,
exp,
projectDir: ctx.projectDir,
xcodeBuildContext,
env: buildProfile.env,
@@ -55,7 +55,7 @@ export class SetUpIosBuildCredentials extends ManageIos {
};
const account = ctx.hasProjectContext
? await getAccountForProjectAsync(ctx.projectId)
? await getAccountForProjectAsync(await ctx.getProjectIdAsync())
: ensureActorHasPrimaryAccount(ctx.user);
let app = null;
+308 -46
View File
@@ -710,6 +710,10 @@ export type AccountSsoConfigurationPublicDataQueryPublicDataByAccountNameArgs =
accountName: Scalars['String']['input'];
};
export enum AccountUploadSessionType {
WorkflowsProjectSources = 'WORKFLOWS_PROJECT_SOURCES'
}
export type AccountUsageEasBuildMetadata = {
__typename?: 'AccountUsageEASBuildMetadata';
billingResourceClass?: Maybe<EasBuildBillingResourceClass>;
@@ -1374,6 +1378,7 @@ export type App = Project & {
workerDeploymentsCrashes?: Maybe<WorkerDeploymentCrashes>;
workerDeploymentsRequest: WorkerDeploymentRequestEdge;
workerDeploymentsRequests?: Maybe<WorkerDeploymentRequests>;
workflowRunsPaginated: AppWorkflowRunsConnection;
workflows: Array<Workflow>;
};
@@ -1383,7 +1388,6 @@ export type AppActivityTimelineProjectActivitiesArgs = {
createdBefore?: InputMaybe<Scalars['DateTime']['input']>;
filterChannels?: InputMaybe<Array<Scalars['String']['input']>>;
filterPlatforms?: InputMaybe<Array<AppPlatform>>;
filterReleaseChannels?: InputMaybe<Array<Scalars['String']['input']>>;
filterTypes?: InputMaybe<Array<ActivityTimelineProjectActivityType>>;
limit: Scalars['Int']['input'];
};
@@ -1647,6 +1651,15 @@ export type AppWorkerDeploymentsRequestsArgs = {
timespan: DatasetTimespan;
};
/** Represents an Exponent App (or Experience in legacy terms) */
export type AppWorkflowRunsPaginatedArgs = {
after?: InputMaybe<Scalars['String']['input']>;
before?: InputMaybe<Scalars['String']['input']>;
first?: InputMaybe<Scalars['Int']['input']>;
last?: InputMaybe<Scalars['Int']['input']>;
};
export type AppBranchEdge = {
__typename?: 'AppBranchEdge';
cursor: Scalars['String']['output'];
@@ -2088,6 +2101,18 @@ export type AppWithGithubRepositoryInput = {
projectName: Scalars['String']['input'];
};
export type AppWorkflowRunEdge = {
__typename?: 'AppWorkflowRunEdge';
cursor: Scalars['String']['output'];
node: WorkflowRun;
};
export type AppWorkflowRunsConnection = {
__typename?: 'AppWorkflowRunsConnection';
edges: Array<AppWorkflowRunEdge>;
pageInfo: PageInfo;
};
export type AppleAppIdentifier = {
__typename?: 'AppleAppIdentifier';
account: Account;
@@ -2490,7 +2515,8 @@ export type AuditLog = {
metadata?: Maybe<Scalars['JSONObject']['output']>;
targetEntityId: Scalars['ID']['output'];
targetEntityMutationType: TargetEntityMutationType;
targetEntityTypeName: Scalars['String']['output'];
targetEntityTypeName: EntityTypeName;
targetEntityTypePublicName: Scalars['String']['output'];
websiteMessage: Scalars['String']['output'];
};
@@ -2535,6 +2561,7 @@ export type AuditLogQuery = {
__typename?: 'AuditLogQuery';
/** Audit logs for account */
byId: AuditLog;
typeNamesMap: Array<LogNameTypeMapping>;
};
@@ -2884,6 +2911,7 @@ export type BuildMetadataInput = {
developmentClient?: InputMaybe<Scalars['Boolean']['input']>;
distribution?: InputMaybe<DistributionType>;
environment?: InputMaybe<Scalars['String']['input']>;
fingerprintHash?: InputMaybe<Scalars['String']['input']>;
fingerprintSource?: InputMaybe<FingerprintSourceInput>;
gitCommitHash?: InputMaybe<Scalars['String']['input']>;
gitCommitMessage?: InputMaybe<Scalars['String']['input']>;
@@ -3147,7 +3175,9 @@ export enum BuildResourceClass {
IosMedium = 'IOS_MEDIUM',
IosMLarge = 'IOS_M_LARGE',
IosMMedium = 'IOS_M_MEDIUM',
Legacy = 'LEGACY'
Legacy = 'LEGACY',
LinuxLarge = 'LINUX_LARGE',
LinuxMedium = 'LINUX_MEDIUM'
}
export enum BuildRetryDisabledReason {
@@ -3298,8 +3328,8 @@ export type CreateEnvironmentSecretInput = {
};
export type CreateEnvironmentVariableInput = {
environment?: InputMaybe<EnvironmentVariableEnvironment>;
environments?: InputMaybe<Array<EnvironmentVariableEnvironment>>;
fileName?: InputMaybe<Scalars['String']['input']>;
name: Scalars['String']['input'];
overwrite?: InputMaybe<Scalars['Boolean']['input']>;
type?: InputMaybe<EnvironmentSecretType>;
@@ -3366,6 +3396,8 @@ export type CreateServerlessFunctionUploadUrlResult = {
export type CreateSharedEnvironmentVariableInput = {
environments?: InputMaybe<Array<EnvironmentVariableEnvironment>>;
fileName?: InputMaybe<Scalars['String']['input']>;
isGlobal?: InputMaybe<Scalars['Boolean']['input']>;
name: Scalars['String']['input'];
overwrite?: InputMaybe<Scalars['Boolean']['input']>;
type?: InputMaybe<EnvironmentSecretType>;
@@ -3381,8 +3413,8 @@ export type CreateSubmissionResult = {
export type CumulativeMetrics = {
__typename?: 'CumulativeMetrics';
/** Totals from the beginning of time till now */
totals: CumulativeMetricsTotals;
data: UpdatesMetricsData;
metricsAtLastTimestamp: CumulativeMetricsTotals;
};
export type CumulativeMetricsOverTimeData = {
@@ -3397,6 +3429,14 @@ export type CumulativeMetricsTotals = {
totalInstalls: Scalars['Int']['output'];
};
export type CumulativeUpdatesDataset = {
__typename?: 'CumulativeUpdatesDataset';
cumulative: Array<Scalars['Int']['output']>;
difference: Array<Scalars['Int']['output']>;
id: Scalars['String']['output'];
label: Scalars['String']['output'];
};
export type CustomBuildConfigInput = {
path: Scalars['String']['input'];
};
@@ -3863,25 +3903,25 @@ export type EmailSubscriptionMutationAddUserArgs = {
};
export enum EntityTypeName {
Account = 'Account',
AccountSsoConfiguration = 'AccountSSOConfiguration',
AndroidAppCredentials = 'AndroidAppCredentials',
AndroidKeystore = 'AndroidKeystore',
App = 'App',
AppStoreConnectApiKey = 'AppStoreConnectApiKey',
AppleDevice = 'AppleDevice',
AppleDistributionCertificate = 'AppleDistributionCertificate',
AppleProvisioningProfile = 'AppleProvisioningProfile',
AppleTeam = 'AppleTeam',
Branch = 'Branch',
Channel = 'Channel',
Customer = 'Customer',
GoogleServiceAccountKey = 'GoogleServiceAccountKey',
IosAppCredentials = 'IosAppCredentials',
UserInvitation = 'UserInvitation',
UserPermission = 'UserPermission',
Workflow = 'Workflow',
WorkflowRevision = 'WorkflowRevision'
AccountEntity = 'AccountEntity',
AccountSsoConfigurationEntity = 'AccountSSOConfigurationEntity',
AndroidAppCredentialsEntity = 'AndroidAppCredentialsEntity',
AndroidKeystoreEntity = 'AndroidKeystoreEntity',
AppEntity = 'AppEntity',
AppStoreConnectApiKeyEntity = 'AppStoreConnectApiKeyEntity',
AppleDeviceEntity = 'AppleDeviceEntity',
AppleDistributionCertificateEntity = 'AppleDistributionCertificateEntity',
AppleProvisioningProfileEntity = 'AppleProvisioningProfileEntity',
AppleTeamEntity = 'AppleTeamEntity',
BranchEntity = 'BranchEntity',
ChannelEntity = 'ChannelEntity',
CustomerEntity = 'CustomerEntity',
GoogleServiceAccountKeyEntity = 'GoogleServiceAccountKeyEntity',
IosAppCredentialsEntity = 'IosAppCredentialsEntity',
UserInvitationEntity = 'UserInvitationEntity',
UserPermissionEntity = 'UserPermissionEntity',
WorkflowEntity = 'WorkflowEntity',
WorkflowRevisionEntity = 'WorkflowRevisionEntity'
}
export type EnvironmentSecret = {
@@ -3929,9 +3969,10 @@ export type EnvironmentVariable = {
__typename?: 'EnvironmentVariable';
apps: Array<App>;
createdAt: Scalars['DateTime']['output'];
environment?: Maybe<EnvironmentVariableEnvironment>;
environments?: Maybe<Array<EnvironmentVariableEnvironment>>;
fileName?: Maybe<Scalars['String']['output']>;
id: Scalars['ID']['output'];
isGlobal?: Maybe<Scalars['Boolean']['output']>;
linkedEnvironments?: Maybe<Array<EnvironmentVariableEnvironment>>;
name: Scalars['String']['output'];
scope: EnvironmentVariableScope;
@@ -4048,9 +4089,10 @@ export type EnvironmentVariableWithSecret = {
__typename?: 'EnvironmentVariableWithSecret';
apps: Array<App>;
createdAt: Scalars['DateTime']['output'];
environment?: Maybe<EnvironmentVariableEnvironment>;
environments?: Maybe<Array<EnvironmentVariableEnvironment>>;
fileName?: Maybe<Scalars['String']['output']>;
id: Scalars['ID']['output'];
isGlobal: Scalars['Boolean']['output'];
linkedEnvironments?: Maybe<Array<EnvironmentVariableEnvironment>>;
name: Scalars['String']['output'];
scope: EnvironmentVariableScope;
@@ -5034,6 +5076,12 @@ export type LinkSharedEnvironmentVariableInput = {
environmentVariableId: Scalars['ID']['input'];
};
export type LogNameTypeMapping = {
__typename?: 'LogNameTypeMapping';
publicName: Scalars['String']['output'];
typeName: EntityTypeName;
};
export type LogsTimespan = {
end: Scalars['DateTime']['input'];
start?: InputMaybe<Scalars['DateTime']['input']>;
@@ -5041,7 +5089,9 @@ export type LogsTimespan = {
export enum MailchimpAudience {
ExpoDevelopers = 'EXPO_DEVELOPERS',
ExpoDeveloperOnboarding = 'EXPO_DEVELOPER_ONBOARDING'
ExpoDeveloperOnboarding = 'EXPO_DEVELOPER_ONBOARDING',
LaunchParty_2024 = 'LAUNCH_PARTY_2024',
NonprodExpoDevelopers = 'NONPROD_EXPO_DEVELOPERS'
}
export enum MailchimpTag {
@@ -5689,6 +5739,7 @@ export type RootMutation = {
/** Mutations that modify a websiteNotification */
websiteNotifications: WebsiteNotificationMutation;
workflowJob: WorkflowJobMutation;
workflowRun: WorkflowRunMutation;
};
@@ -5818,7 +5869,9 @@ export type RootQuery = {
/** Top-level query object for querying Webhooks. */
webhook: WebhookQuery;
workerDeployment: WorkerDeploymentQuery;
workflowJobs: WorkflowJobQuery;
workflowRevisions: WorkflowRevisionQuery;
workflowRuns: WorkflowRunQuery;
workflows: WorkflowQuery;
};
@@ -6112,6 +6165,8 @@ export type Snack = Project & {
/** Preview image of the running snack */
previewImage?: Maybe<Scalars['String']['output']>;
published: Scalars['Boolean']['output'];
/** SDK version of the snack */
sdkVersion: Scalars['String']['output'];
/** Slug name, e.g. "mysnack", "245631" */
slug: Scalars['String']['output'];
/** Date and time the Snack was last updated */
@@ -6666,7 +6721,9 @@ export type UpdateDeploymentsConnection = {
export type UpdateEnvironmentVariableInput = {
environments?: InputMaybe<Array<EnvironmentVariableEnvironment>>;
fileName?: InputMaybe<Scalars['String']['input']>;
id: Scalars['ID']['input'];
isGlobal?: InputMaybe<Scalars['Boolean']['input']>;
name?: InputMaybe<Scalars['String']['input']>;
type?: InputMaybe<EnvironmentSecretType>;
value?: InputMaybe<Scalars['String']['input']>;
@@ -6705,13 +6762,12 @@ export type UpdateInfoGroup = {
export type UpdateInsights = {
__typename?: 'UpdateInsights';
cumulativeMetrics: CumulativeMetrics;
cumulativeMetricsOverTime: CumulativeMetricsOverTimeData;
id: Scalars['ID']['output'];
totalUniqueUsers: Scalars['Int']['output'];
};
export type UpdateInsightsCumulativeMetricsOverTimeArgs = {
export type UpdateInsightsCumulativeMetricsArgs = {
timespan: InsightsTimespan;
};
@@ -6781,13 +6837,28 @@ export type UpdatesFilter = {
sdkVersions?: InputMaybe<Array<Scalars['String']['input']>>;
};
export type UpdatesMetricsData = {
__typename?: 'UpdatesMetricsData';
failedInstallsDataset: CumulativeUpdatesDataset;
installsDataset: CumulativeUpdatesDataset;
labels: Array<Scalars['String']['output']>;
};
export type UploadSession = {
__typename?: 'UploadSession';
/** Create an Upload Session for a specific account */
createAccountScopedUploadSession: Scalars['JSONObject']['output'];
/** Create an Upload Session */
createUploadSession: Scalars['JSONObject']['output'];
};
export type UploadSessionCreateAccountScopedUploadSessionArgs = {
accountID: Scalars['ID']['input'];
type: AccountUploadSessionType;
};
export type UploadSessionCreateUploadSessionArgs = {
type: UploadSessionType;
};
@@ -7152,7 +7223,8 @@ export type UserAuditLog = {
metadata?: Maybe<Scalars['JSONObject']['output']>;
targetEntityId: Scalars['ID']['output'];
targetEntityMutationType: TargetEntityMutationType;
targetEntityTypeName: Scalars['String']['output'];
targetEntityTypeName: UserEntityTypeName;
targetEntityTypePublicName: Scalars['String']['output'];
user: User;
websiteMessage: Scalars['String']['output'];
};
@@ -7199,6 +7271,7 @@ export type UserAuditLogQuery = {
/** Audit logs for user */
byId: UserAuditLog;
byUserIdPaginated: UserAuditLogConnection;
typeNamesMap: Array<UserLogNameTypeMapping>;
};
@@ -7227,15 +7300,15 @@ export type UserDataInput = {
};
export enum UserEntityTypeName {
AccessToken = 'AccessToken',
DiscordUser = 'DiscordUser',
GitHubUser = 'GitHubUser',
Password = 'Password',
SsoUser = 'SSOUser',
User = 'User',
UserPermission = 'UserPermission',
UserSecondFactorBackupCodes = 'UserSecondFactorBackupCodes',
UserSecondFactorDevice = 'UserSecondFactorDevice'
AccessTokenEntity = 'AccessTokenEntity',
DiscordUserEntity = 'DiscordUserEntity',
GitHubUserEntity = 'GitHubUserEntity',
PasswordEntity = 'PasswordEntity',
SsoUserEntity = 'SSOUserEntity',
UserEntity = 'UserEntity',
UserPermissionEntity = 'UserPermissionEntity',
UserSecondFactorBackupCodesEntity = 'UserSecondFactorBackupCodesEntity',
UserSecondFactorDeviceEntity = 'UserSecondFactorDeviceEntity'
}
/** An pending invitation sent to an email granting membership on an Account. */
@@ -7339,6 +7412,12 @@ export type UserInvitationPublicDataQueryByTokenArgs = {
token: Scalars['ID']['input'];
};
export type UserLogNameTypeMapping = {
__typename?: 'UserLogNameTypeMapping';
publicName: Scalars['String']['output'];
typeName: UserEntityTypeName;
};
export type UserPermission = {
__typename?: 'UserPermission';
actor: Actor;
@@ -7633,7 +7712,7 @@ export type WorkerDeploymentCrashesAggregationNode = {
distinctCrashes: Scalars['Int']['output'];
firstOccurredAt: Scalars['DateTime']['output'];
mostRecentlyOccurredAt: Scalars['DateTime']['output'];
sampleRate: Scalars['Float']['output'];
sampleRate?: Maybe<Scalars['Float']['output']>;
};
export type WorkerDeploymentCrashesHashEdge = {
@@ -7827,7 +7906,7 @@ export type WorkerDeploymentRequestsAggregationNode = {
durationP99: Scalars['Float']['output'];
requestsPerMs?: Maybe<Scalars['Float']['output']>;
requestsSum: Scalars['Int']['output'];
sampleRate: Scalars['Float']['output'];
sampleRate?: Maybe<Scalars['Float']['output']>;
serverErrorRatio: Scalars['Float']['output'];
serverErrorRatioP50: Scalars['Float']['output'];
serverErrorRatioP90: Scalars['Float']['output'];
@@ -7922,10 +8001,52 @@ export type Workflow = {
fileName: Scalars['String']['output'];
id: Scalars['ID']['output'];
name?: Maybe<Scalars['String']['output']>;
revisions: Array<WorkflowRevision>;
revisionsPaginated: WorkflowRevisionsConnection;
runsPaginated: WorkflowRunsConnection;
updatedAt: Scalars['DateTime']['output'];
};
export type WorkflowRevisionsPaginatedArgs = {
after?: InputMaybe<Scalars['String']['input']>;
before?: InputMaybe<Scalars['String']['input']>;
first?: InputMaybe<Scalars['Int']['input']>;
last?: InputMaybe<Scalars['Int']['input']>;
};
export type WorkflowRunsPaginatedArgs = {
after?: InputMaybe<Scalars['String']['input']>;
before?: InputMaybe<Scalars['String']['input']>;
first?: InputMaybe<Scalars['Int']['input']>;
last?: InputMaybe<Scalars['Int']['input']>;
};
export type WorkflowJob = {
__typename?: 'WorkflowJob';
createdAt: Scalars['DateTime']['output'];
credentialsAppleDeviceRegistrationRequest?: Maybe<AppleDeviceRegistrationRequest>;
errors: Array<WorkflowJobError>;
id: Scalars['ID']['output'];
key: Scalars['String']['output'];
name: Scalars['String']['output'];
outputs: Scalars['JSONObject']['output'];
requiredJobKeys: Array<Scalars['String']['output']>;
status: WorkflowJobStatus;
turtleBuild?: Maybe<Build>;
turtleJobRun?: Maybe<JobRun>;
turtleSubmission?: Maybe<Submission>;
type: WorkflowJobType;
updatedAt: Scalars['DateTime']['output'];
workflowRun: WorkflowRun;
};
export type WorkflowJobError = {
__typename?: 'WorkflowJobError';
message: Scalars['String']['output'];
title: Scalars['String']['output'];
};
export type WorkflowJobMutation = {
__typename?: 'WorkflowJobMutation';
approveWorkflowJob: Scalars['ID']['output'];
@@ -7936,6 +8057,46 @@ export type WorkflowJobMutationApproveWorkflowJobArgs = {
workflowJobId: Scalars['ID']['input'];
};
export type WorkflowJobQuery = {
__typename?: 'WorkflowJobQuery';
byId: WorkflowJob;
};
export type WorkflowJobQueryByIdArgs = {
workflowJobId: Scalars['ID']['input'];
};
export enum WorkflowJobStatus {
ActionRequired = 'ACTION_REQUIRED',
Canceled = 'CANCELED',
Failure = 'FAILURE',
InProgress = 'IN_PROGRESS',
New = 'NEW',
Skipped = 'SKIPPED',
Success = 'SUCCESS'
}
export enum WorkflowJobType {
AppleDeviceRegistrationRequest = 'APPLE_DEVICE_REGISTRATION_REQUEST',
Build = 'BUILD',
Custom = 'CUSTOM',
MaestroTest = 'MAESTRO_TEST',
RequireApproval = 'REQUIRE_APPROVAL',
Submission = 'SUBMISSION',
Update = 'UPDATE'
}
export type WorkflowProjectSourceInput = {
easJsonBucketKey: Scalars['String']['input'];
projectArchiveBucketKey: Scalars['String']['input'];
type: WorkflowProjectSourceType;
};
export enum WorkflowProjectSourceType {
Gcs = 'GCS'
}
/** Look up Workflow by ID */
export type WorkflowQuery = {
__typename?: 'WorkflowQuery';
@@ -7951,13 +8112,24 @@ export type WorkflowQueryByIdArgs = {
export type WorkflowRevision = {
__typename?: 'WorkflowRevision';
blobSha: Scalars['String']['output'];
commitSha: Scalars['String']['output'];
commitSha?: Maybe<Scalars['String']['output']>;
createdAt: Scalars['DateTime']['output'];
id: Scalars['ID']['output'];
workflow: Workflow;
yamlConfig: Scalars['String']['output'];
};
export type WorkflowRevisionEdge = {
__typename?: 'WorkflowRevisionEdge';
cursor: Scalars['String']['output'];
node: WorkflowRevision;
};
export type WorkflowRevisionInput = {
fileName: Scalars['String']['input'];
yamlConfig: Scalars['String']['input'];
};
export type WorkflowRevisionQuery = {
__typename?: 'WorkflowRevisionQuery';
byId: WorkflowRevision;
@@ -7968,6 +8140,77 @@ export type WorkflowRevisionQueryByIdArgs = {
workflowRevisionId: Scalars['ID']['input'];
};
export type WorkflowRevisionsConnection = {
__typename?: 'WorkflowRevisionsConnection';
edges: Array<WorkflowRevisionEdge>;
pageInfo: PageInfo;
};
export type WorkflowRun = {
__typename?: 'WorkflowRun';
createdAt: Scalars['DateTime']['output'];
gitCommitHash?: Maybe<Scalars['String']['output']>;
gitCommitMessage?: Maybe<Scalars['String']['output']>;
githubRepository?: Maybe<GitHubRepository>;
id: Scalars['ID']['output'];
initiatingUser?: Maybe<User>;
jobs: Array<WorkflowJob>;
name: Scalars['String']['output'];
pullRequestNumber?: Maybe<Scalars['Int']['output']>;
requestedGitRef?: Maybe<Scalars['String']['output']>;
status: WorkflowRunStatus;
updatedAt: Scalars['DateTime']['output'];
workflow: Workflow;
workflowRevision?: Maybe<WorkflowRevision>;
};
export type WorkflowRunEdge = {
__typename?: 'WorkflowRunEdge';
cursor: Scalars['String']['output'];
node: WorkflowRun;
};
export type WorkflowRunInput = {
projectSource: WorkflowProjectSourceInput;
};
export type WorkflowRunMutation = {
__typename?: 'WorkflowRunMutation';
createWorkflowRun: WorkflowRun;
};
export type WorkflowRunMutationCreateWorkflowRunArgs = {
appId: Scalars['ID']['input'];
workflowRevisionInput: WorkflowRevisionInput;
workflowRunInput: WorkflowRunInput;
};
export type WorkflowRunQuery = {
__typename?: 'WorkflowRunQuery';
byId: WorkflowRun;
};
export type WorkflowRunQueryByIdArgs = {
workflowRunId: Scalars['ID']['input'];
};
export enum WorkflowRunStatus {
ActionRequired = 'ACTION_REQUIRED',
Canceled = 'CANCELED',
Failure = 'FAILURE',
InProgress = 'IN_PROGRESS',
New = 'NEW',
Success = 'SUCCESS'
}
export type WorkflowRunsConnection = {
__typename?: 'WorkflowRunsConnection';
edges: Array<WorkflowRunEdge>;
pageInfo: PageInfo;
};
export type DeleteAndroidAppBuildCredentialsResult = {
__typename?: 'deleteAndroidAppBuildCredentialsResult';
id: Scalars['ID']['output'];
@@ -8686,6 +8929,14 @@ export type CreateUploadSessionMutationVariables = Exact<{
export type CreateUploadSessionMutation = { __typename?: 'RootMutation', uploadSession: { __typename?: 'UploadSession', createUploadSession: any } };
export type CreateAccountScopedUploadSessionMutationVariables = Exact<{
accountID: Scalars['ID']['input'];
type: AccountUploadSessionType;
}>;
export type CreateAccountScopedUploadSessionMutation = { __typename?: 'RootMutation', uploadSession: { __typename?: 'UploadSession', createAccountScopedUploadSession: any } };
export type MarkCliDoneInOnboardingUserPreferencesMutationVariables = Exact<{
preferences: UserPreferencesInput;
}>;
@@ -8716,6 +8967,15 @@ export type DeleteWebhookMutationVariables = Exact<{
export type DeleteWebhookMutation = { __typename?: 'RootMutation', webhook: { __typename?: 'WebhookMutation', deleteWebhook: { __typename?: 'DeleteWebhookResult', id: string } } };
export type CreateWorkflowRunMutationVariables = Exact<{
appId: Scalars['ID']['input'];
workflowRevisionInput: WorkflowRevisionInput;
workflowRunInput: WorkflowRunInput;
}>;
export type CreateWorkflowRunMutation = { __typename?: 'RootMutation', workflowRun: { __typename?: 'WorkflowRunMutation', createWorkflowRun: { __typename?: 'WorkflowRun', id: string } } };
export type AppByIdQueryVariables = Exact<{
appId: Scalars['String']['input'];
}>;
@@ -8862,7 +9122,7 @@ export type EnvironmentVariablesIncludingSensitiveByAppIdQueryVariables = Exact<
}>;
export type EnvironmentVariablesIncludingSensitiveByAppIdQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, environmentVariablesIncludingSensitive: Array<{ __typename?: 'EnvironmentVariableWithSecret', id: string, name: string, value?: string | null, environments?: Array<EnvironmentVariableEnvironment> | null, valueWithFileContent?: string | null }> } } };
export type EnvironmentVariablesIncludingSensitiveByAppIdQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, environmentVariablesIncludingSensitive: Array<{ __typename?: 'EnvironmentVariableWithSecret', id: string, name: string, value?: string | null, environments?: Array<EnvironmentVariableEnvironment> | null, createdAt: any, updatedAt: any, scope: EnvironmentVariableScope, visibility: EnvironmentVariableVisibility, type: EnvironmentSecretType, valueWithFileContent?: string | null }> } } };
export type EnvironmentVariablesByAppIdQueryVariables = Exact<{
appId: Scalars['String']['input'];
@@ -8892,7 +9152,7 @@ export type EnvironmentVariablesSharedWithSensitiveQueryVariables = Exact<{
}>;
export type EnvironmentVariablesSharedWithSensitiveQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, ownerAccount: { __typename?: 'Account', id: string, environmentVariablesIncludingSensitive: Array<{ __typename?: 'EnvironmentVariableWithSecret', id: string, name: string, value?: string | null, environments?: Array<EnvironmentVariableEnvironment> | null, valueWithFileContent?: string | null }> } } } };
export type EnvironmentVariablesSharedWithSensitiveQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, ownerAccount: { __typename?: 'Account', id: string, environmentVariablesIncludingSensitive: Array<{ __typename?: 'EnvironmentVariableWithSecret', id: string, name: string, value?: string | null, environments?: Array<EnvironmentVariableEnvironment> | null, createdAt: any, updatedAt: any, scope: EnvironmentVariableScope, visibility: EnvironmentVariableVisibility, type: EnvironmentSecretType, valueWithFileContent?: string | null }> } } } };
export type GoogleServiceAccountKeyByIdQueryVariables = Exact<{
ascApiKeyId: Scalars['ID']['input'];
@@ -9013,6 +9273,8 @@ export type EnvironmentSecretFragment = { __typename?: 'EnvironmentSecret', id:
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 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,6 +3,9 @@ import gql from 'graphql-tag';
import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
import { withErrorHandlingAsync } from '../client';
import {
AccountUploadSessionType,
CreateAccountScopedUploadSessionMutation,
CreateAccountScopedUploadSessionMutationVariables,
CreateUploadSessionMutation,
CreateUploadSessionMutationVariables,
UploadSessionType,
@@ -37,4 +40,39 @@ export const UploadSessionMutation = {
);
return data.uploadSession.createUploadSession;
},
async createAccountScopedUploadSessionAsync(
graphqlClient: ExpoGraphqlClient,
{
type,
accountID,
}: {
type: AccountUploadSessionType;
accountID: string;
}
): Promise<SignedUrl> {
const data = await withErrorHandlingAsync(
graphqlClient
.mutation<
CreateAccountScopedUploadSessionMutation,
CreateAccountScopedUploadSessionMutationVariables
>(
gql`
mutation CreateAccountScopedUploadSessionMutation(
$accountID: ID!
$type: AccountUploadSessionType!
) {
uploadSession {
createAccountScopedUploadSession(accountID: $accountID, type: $type)
}
}
`,
{
type,
accountID,
}
)
.toPromise()
);
return data.uploadSession.createAccountScopedUploadSession;
},
};
@@ -0,0 +1,55 @@
import gql from 'graphql-tag';
import { ExpoGraphqlClient } from '../../commandUtils/context/contextUtils/createGraphqlClient';
import { withErrorHandlingAsync } from '../client';
import {
CreateWorkflowRunMutation,
CreateWorkflowRunMutationVariables,
WorkflowRevisionInput,
WorkflowRunInput,
} from '../generated';
export namespace WorkflowRunMutation {
export async function createWorkflowRunAsync(
graphqlClient: ExpoGraphqlClient,
{
appId,
workflowRevisionInput,
workflowRunInput,
}: {
appId: string;
workflowRevisionInput: WorkflowRevisionInput;
workflowRunInput: WorkflowRunInput;
}
): Promise<{ id: string }> {
const data = await withErrorHandlingAsync(
graphqlClient
.mutation<CreateWorkflowRunMutation, CreateWorkflowRunMutationVariables>(
gql`
mutation CreateWorkflowRun(
$appId: ID!
$workflowRevisionInput: WorkflowRevisionInput!
$workflowRunInput: WorkflowRunInput!
) {
workflowRun {
createWorkflowRun(
appId: $appId
workflowRevisionInput: $workflowRevisionInput
workflowRunInput: $workflowRunInput
) {
id
}
}
}
`,
{
appId,
workflowRevisionInput,
workflowRunInput,
}
)
.toPromise()
);
return { id: data.workflowRun.createWorkflowRun.id };
}
}
@@ -1,10 +1,21 @@
import { AgeRatingDeclaration, KidsAge, Rating } from '@expo/apple-utils';
import {
AgeRatingDeclaration,
KidsAgeBand,
KoreaRatingOverride,
Rating,
RatingOverride,
} from '@expo/apple-utils';
import { AttributesOf } from '../../../../utils/asc';
// @ts-expect-error: Deprecated property `gamblingAndContests` needs to be deleted from the types
// Note, both `seventeenPlus` and `gamlingAndContests` are deprecated
type AgeRatingDeclarationProps = Omit<
AttributesOf<AgeRatingDeclaration>,
'seventeenPlus' | 'gamblingAndContests'
>;
// These attributes is what we get from the API when no questions are answered
export const emptyAdvisory: AttributesOf<AgeRatingDeclaration> = {
export const emptyAdvisory: AgeRatingDeclarationProps = {
alcoholTobaccoOrDrugUseOrReferences: null,
contests: null,
gamblingSimulated: null,
@@ -20,11 +31,12 @@ export const emptyAdvisory: AttributesOf<AgeRatingDeclaration> = {
gambling: false,
unrestrictedWebAccess: false,
kidsAgeBand: null,
seventeenPlus: false,
ageRatingOverride: null,
koreaAgeRatingOverride: null,
lootBox: null,
};
// @ts-expect-error: Deprecated property `gamblingAndContests` needs to be deleted from the types
export const leastRestrictiveAdvisory: AttributesOf<AgeRatingDeclaration> = {
export const leastRestrictiveAdvisory: AgeRatingDeclarationProps = {
alcoholTobaccoOrDrugUseOrReferences: Rating.NONE,
contests: Rating.NONE,
gamblingSimulated: Rating.NONE,
@@ -40,11 +52,12 @@ export const leastRestrictiveAdvisory: AttributesOf<AgeRatingDeclaration> = {
gambling: false,
unrestrictedWebAccess: false,
kidsAgeBand: null,
seventeenPlus: false,
ageRatingOverride: RatingOverride.NONE,
koreaAgeRatingOverride: KoreaRatingOverride.NONE,
lootBox: false,
};
// @ts-expect-error: Deprecated property `gamblingAndContests` needs to be deleted from the types
export const mostRestrictiveAdvisory: AttributesOf<AgeRatingDeclaration> = {
export const mostRestrictiveAdvisory: AgeRatingDeclarationProps = {
alcoholTobaccoOrDrugUseOrReferences: Rating.FREQUENT_OR_INTENSE,
contests: Rating.FREQUENT_OR_INTENSE,
gamblingSimulated: Rating.FREQUENT_OR_INTENSE,
@@ -60,11 +73,12 @@ export const mostRestrictiveAdvisory: AttributesOf<AgeRatingDeclaration> = {
gambling: true,
unrestrictedWebAccess: true,
kidsAgeBand: null,
seventeenPlus: true,
ageRatingOverride: RatingOverride.SEVENTEEN_PLUS,
koreaAgeRatingOverride: KoreaRatingOverride.NINETEEN_PLUS,
lootBox: true,
};
// @ts-expect-error: Deprecated property `gamblingAndContests` needs to be deleted from the types
export const kidsSixToEightAdvisory: AttributesOf<AgeRatingDeclaration> = {
export const kidsSixToEightAdvisory: AgeRatingDeclarationProps = {
alcoholTobaccoOrDrugUseOrReferences: Rating.NONE,
contests: Rating.NONE,
gamblingSimulated: Rating.NONE,
@@ -79,6 +93,8 @@ export const kidsSixToEightAdvisory: AttributesOf<AgeRatingDeclaration> = {
violenceRealisticProlongedGraphicOrSadistic: Rating.NONE,
gambling: false,
unrestrictedWebAccess: false,
kidsAgeBand: KidsAge.SIX_TO_EIGHT,
seventeenPlus: false,
kidsAgeBand: KidsAgeBand.SIX_TO_EIGHT,
ageRatingOverride: RatingOverride.NONE,
koreaAgeRatingOverride: KoreaRatingOverride.NONE,
lootBox: false,
};
@@ -1,4 +1,11 @@
import { AppStoreState, AppStoreVersion, Platform, ReleaseType } from '@expo/apple-utils';
import {
AppStoreState,
AppStoreVersion,
AppVersionState,
Platform,
ReleaseType,
ReviewType,
} from '@expo/apple-utils';
import { AttributesOf } from '../../../../utils/asc';
@@ -6,43 +13,43 @@ export const manualRelease: AttributesOf<AppStoreVersion> = {
platform: Platform.IOS,
versionString: '1.0.0',
appStoreState: AppStoreState.WAITING_FOR_REVIEW,
appVersionState: AppVersionState.WAITING_FOR_REVIEW,
storeIcon: null,
watchStoreIcon: null,
copyright: '2022 - ACME',
releaseType: ReleaseType.MANUAL,
earliestReleaseDate: null,
usesIdfa: null,
isWatchOnly: false,
downloadable: false,
createdDate: '2022-05-23T00:00:00.000Z',
reviewType: ReviewType.APP_STORE,
};
export const automaticRelease: AttributesOf<AppStoreVersion> = {
platform: Platform.IOS,
versionString: '2.0.0',
appStoreState: AppStoreState.WAITING_FOR_REVIEW,
appVersionState: AppVersionState.WAITING_FOR_REVIEW,
storeIcon: null,
watchStoreIcon: null,
copyright: '2022 - ACME',
releaseType: ReleaseType.AFTER_APPROVAL,
earliestReleaseDate: null,
usesIdfa: null,
isWatchOnly: false,
downloadable: false,
createdDate: '2022-05-23T00:00:00.000Z',
reviewType: ReviewType.APP_STORE,
};
export const scheduledRelease: AttributesOf<AppStoreVersion> = {
platform: Platform.IOS,
versionString: '3.0.0',
appStoreState: AppStoreState.READY_FOR_SALE,
appVersionState: AppVersionState.ACCEPTED,
storeIcon: null,
watchStoreIcon: null,
copyright: '2022 - ACME',
releaseType: ReleaseType.SCHEDULED,
earliestReleaseDate: '2022-05-29T00:00:00.000Z',
usesIdfa: null,
isWatchOnly: false,
downloadable: false,
createdDate: '2022-05-23T00:00:00.000Z',
reviewType: ReviewType.APP_STORE,
};
@@ -6,8 +6,10 @@ import {
AppStoreVersionLocalization,
AppStoreVersionPhasedRelease,
CategoryIds,
KoreaRatingOverride,
PhasedReleaseState,
Rating,
RatingOverride,
ReleaseType,
} from '@expo/apple-utils';
@@ -35,24 +37,26 @@ export class AppleConfigReader {
}
return {
ageRatingOverride: attributes.ageRatingOverride ?? RatingOverride.NONE,
alcoholTobaccoOrDrugUseOrReferences:
attributes.alcoholTobaccoOrDrugUseOrReferences ?? Rating.NONE,
contests: attributes.contests ?? Rating.NONE,
gambling: attributes.gambling ?? false,
gamblingSimulated: attributes.gamblingSimulated ?? Rating.NONE,
horrorOrFearThemes: attributes.horrorOrFearThemes ?? Rating.NONE,
kidsAgeBand: attributes.kidsAgeBand ?? null,
koreaAgeRatingOverride: attributes.koreaAgeRatingOverride ?? KoreaRatingOverride.NONE,
lootBox: attributes.lootBox ?? false,
matureOrSuggestiveThemes: attributes.matureOrSuggestiveThemes ?? Rating.NONE,
medicalOrTreatmentInformation: attributes.medicalOrTreatmentInformation ?? Rating.NONE,
profanityOrCrudeHumor: attributes.profanityOrCrudeHumor ?? Rating.NONE,
sexualContentGraphicAndNudity: attributes.sexualContentGraphicAndNudity ?? Rating.NONE,
sexualContentOrNudity: attributes.sexualContentOrNudity ?? Rating.NONE,
unrestrictedWebAccess: attributes.unrestrictedWebAccess ?? false,
violenceCartoonOrFantasy: attributes.violenceCartoonOrFantasy ?? Rating.NONE,
violenceRealistic: attributes.violenceRealistic ?? Rating.NONE,
violenceRealisticProlongedGraphicOrSadistic:
attributes.violenceRealisticProlongedGraphicOrSadistic ?? Rating.NONE,
gambling: attributes.gambling ?? false,
unrestrictedWebAccess: attributes.unrestrictedWebAccess ?? false,
kidsAgeBand: attributes.kidsAgeBand ?? null,
seventeenPlus: attributes.seventeenPlus ?? false,
};
}
@@ -6,7 +6,9 @@ import {
AppStoreVersion,
AppStoreVersionLocalization,
AppStoreVersionPhasedRelease,
KoreaRatingOverride,
Rating,
RatingOverride,
ReleaseType,
} from '@expo/apple-utils';
@@ -28,26 +30,31 @@ export class AppleConfigWriter {
};
}
public setAgeRating(attributes: AttributesOf<AgeRatingDeclaration>): void {
// Note, both `seventeenPlus` and `gamlingAndContests` are deprecated
public setAgeRating(
attributes: Omit<AttributesOf<AgeRatingDeclaration>, 'seventeenPlus' | 'gamblingAndContests'>
): void {
this.schema.advisory = {
ageRatingOverride: attributes.ageRatingOverride ?? RatingOverride.NONE,
alcoholTobaccoOrDrugUseOrReferences:
attributes.alcoholTobaccoOrDrugUseOrReferences ?? Rating.NONE,
contests: attributes.contests ?? Rating.NONE,
gambling: attributes.gambling ?? false,
gamblingSimulated: attributes.gamblingSimulated ?? Rating.NONE,
horrorOrFearThemes: attributes.horrorOrFearThemes ?? Rating.NONE,
kidsAgeBand: attributes.kidsAgeBand ?? null,
koreaAgeRatingOverride: attributes.koreaAgeRatingOverride ?? KoreaRatingOverride.NONE,
lootBox: attributes.lootBox ?? false,
matureOrSuggestiveThemes: attributes.matureOrSuggestiveThemes ?? Rating.NONE,
medicalOrTreatmentInformation: attributes.medicalOrTreatmentInformation ?? Rating.NONE,
profanityOrCrudeHumor: attributes.profanityOrCrudeHumor ?? Rating.NONE,
sexualContentGraphicAndNudity: attributes.sexualContentGraphicAndNudity ?? Rating.NONE,
sexualContentOrNudity: attributes.sexualContentOrNudity ?? Rating.NONE,
unrestrictedWebAccess: attributes.unrestrictedWebAccess ?? false,
violenceCartoonOrFantasy: attributes.violenceCartoonOrFantasy ?? Rating.NONE,
violenceRealistic: attributes.violenceRealistic ?? Rating.NONE,
violenceRealisticProlongedGraphicOrSadistic:
attributes.violenceRealisticProlongedGraphicOrSadistic ?? Rating.NONE,
gambling: attributes.gambling ?? false,
unrestrictedWebAccess: attributes.unrestrictedWebAccess ?? false,
kidsAgeBand: attributes.kidsAgeBand ?? null,
seventeenPlus: attributes.seventeenPlus ?? false,
};
}
+5 -1
View File
@@ -13,7 +13,11 @@ export interface AppleMetadata {
review?: AppleReview;
}
export type AppleAdvisory = Partial<AgeRatingDeclarationProps>;
// The omited properties are deprecated
export type AppleAdvisory = Omit<
Partial<AgeRatingDeclarationProps>,
'seventeenPlus' | 'gamblingAndContests'
>;
/** Apps can define up to two categories, or categories with up to two subcategories */
export type AppleCategory = (string | string[])[];
+55 -12
View File
@@ -1,9 +1,13 @@
import { ExpoConfig, getConfig, getConfigFilePaths, modifyConfigAsync } from '@expo/config';
import { Env } from '@expo/eas-build-job';
import spawnAsync from '@expo/spawn-async';
import fs from 'fs-extra';
import Joi from 'joi';
import path from 'path';
import { isExpoInstalled } from './projectUtils';
import Log from '../log';
export type PublicExpoConfig = Omit<
ExpoConfig,
'_internal' | 'hooks' | 'ios' | 'android' | 'updates'
@@ -37,21 +41,57 @@ export async function createOrModifyExpoConfigAsync(
}
}
function getExpoConfigInternal(
let wasExpoConfigWarnPrinted = false;
async function getExpoConfigInternalAsync(
projectDir: string,
opts: ExpoConfigOptionsInternal = {}
): ExpoConfig {
): Promise<ExpoConfig> {
const originalProcessEnv: NodeJS.ProcessEnv = process.env;
try {
process.env = {
...process.env,
...opts.env,
};
const { exp } = getConfig(projectDir, {
skipSDKVersionRequirement: true,
...(opts.isPublicConfig ? { isPublicConfig: true } : {}),
...(opts.skipPlugins ? { skipPlugins: true } : {}),
});
let exp: ExpoConfig;
if (isExpoInstalled(projectDir)) {
try {
const { stdout } = await spawnAsync(
'npx',
['expo', 'config', '--json', ...(opts.isPublicConfig ? ['--type', 'public'] : [])],
{
cwd: projectDir,
env: {
...process.env,
...opts.env,
EXPO_NO_DOTENV: '1',
},
}
);
exp = JSON.parse(stdout);
} catch (err: any) {
if (!wasExpoConfigWarnPrinted) {
Log.warn(
`Failed to read the app config from the project using "npx expo config" command: ${err.message}.`
);
Log.warn('Falling back to the version of "@expo/config" shipped with the EAS CLI.');
wasExpoConfigWarnPrinted = true;
}
exp = getConfig(projectDir, {
skipSDKVersionRequirement: true,
...(opts.isPublicConfig ? { isPublicConfig: true } : {}),
...(opts.skipPlugins ? { skipPlugins: true } : {}),
}).exp;
}
} else {
exp = getConfig(projectDir, {
skipSDKVersionRequirement: true,
...(opts.isPublicConfig ? { isPublicConfig: true } : {}),
...(opts.skipPlugins ? { skipPlugins: true } : {}),
}).exp;
}
const { error } = MinimalAppConfigSchema.validate(exp, {
allowUnknown: true,
@@ -78,10 +118,13 @@ const MinimalAppConfigSchema = Joi.object({
}),
});
export function getPrivateExpoConfig(projectDir: string, opts: ExpoConfigOptions = {}): ExpoConfig {
export async function getPrivateExpoConfigAsync(
projectDir: string,
opts: ExpoConfigOptions = {}
): Promise<ExpoConfig> {
ensureExpoConfigExists(projectDir);
return getExpoConfigInternal(projectDir, { ...opts, isPublicConfig: false });
return await getExpoConfigInternalAsync(projectDir, { ...opts, isPublicConfig: false });
}
export function ensureExpoConfigExists(projectDir: string): void {
@@ -97,11 +140,11 @@ export function isUsingStaticExpoConfig(projectDir: string): boolean {
return !!(paths.staticConfigPath?.endsWith('app.json') && !paths.dynamicConfigPath);
}
export function getPublicExpoConfig(
export async function getPublicExpoConfigAsync(
projectDir: string,
opts: ExpoConfigOptions = {}
): PublicExpoConfig {
): Promise<PublicExpoConfig> {
ensureExpoConfigExists(projectDir);
return getExpoConfigInternal(projectDir, { ...opts, isPublicConfig: true });
return await getExpoConfigInternalAsync(projectDir, { ...opts, isPublicConfig: true });
}
@@ -1,7 +1,9 @@
import { IOSConfig, compileModsAsync } from '@expo/config-plugins';
import { ExportedConfig, IOSConfig, compileModsAsync } from '@expo/config-plugins';
import { JSONObject } from '@expo/json-file';
import { getPrebuildConfigAsync } from '@expo/prebuild-config';
import spawnAsync from '@expo/spawn-async';
import Log from '../../log';
import { readPlistAsync } from '../../utils/plist';
import { Client } from '../../vcs/vcs';
import { hasIgnoredIosProjectAsync } from '../workflow';
@@ -10,6 +12,9 @@ interface Target {
buildConfiguration?: string;
targetName: string;
}
let wasExpoConfigPluginsWarnPrinted = false;
export async function getManagedApplicationTargetEntitlementsAsync(
projectDir: string,
env: Record<string, string>,
@@ -22,14 +27,39 @@ export async function getManagedApplicationTargetEntitlementsAsync(
...process.env,
...env,
};
const { exp } = await getPrebuildConfigAsync(projectDir, { platforms: ['ios'] });
const expWithMods = await compileModsAsync(exp, {
projectRoot: projectDir,
platforms: ['ios'],
introspect: true,
ignoreExistingNativeFiles: await hasIgnoredIosProjectAsync(projectDir, vcsClient),
});
let expWithMods: ExportedConfig;
try {
const { stdout } = await spawnAsync(
'npx',
['expo', 'config', '--json', '--type', 'introspect'],
{
cwd: projectDir,
env: {
...process.env,
...env,
EXPO_NO_DOTENV: '1',
},
}
);
expWithMods = JSON.parse(stdout);
} catch (err: any) {
if (!wasExpoConfigPluginsWarnPrinted) {
Log.warn(
`Failed to read the app config from the project using "npx expo config" command: ${err.message}.`
);
Log.warn('Falling back to the version of "@expo/config" shipped with the EAS CLI.');
wasExpoConfigPluginsWarnPrinted = true;
}
const { exp } = await getPrebuildConfigAsync(projectDir, { platforms: ['ios'] });
expWithMods = await compileModsAsync(exp, {
projectRoot: projectDir,
platforms: ['ios'],
introspect: true,
ignoreExistingNativeFiles: await hasIgnoredIosProjectAsync(projectDir, vcsClient),
});
}
return expWithMods.ios?.entitlements ?? {};
} finally {
process.env = originalProcessEnv;
@@ -11,12 +11,12 @@ import { uploadFileAtPathToGCSAsync } from '../uploads';
import { getTmpDirectory } from '../utils/paths';
export async function maybeUploadFingerprintAsync({
runtimeVersion,
hash,
fingerprint,
graphqlClient,
localBuildMode,
}: {
runtimeVersion: string;
hash: string;
fingerprint: {
fingerprintSources: object[];
isDebugFingerprintSource: boolean;
@@ -24,20 +24,20 @@ export async function maybeUploadFingerprintAsync({
graphqlClient: ExpoGraphqlClient;
localBuildMode?: LocalBuildMode;
}): Promise<{
runtimeVersion: string;
hash: string;
fingerprintSource?: FingerprintSource;
}> {
await fs.mkdirp(getTmpDirectory());
const fingerprintLocation = path.join(getTmpDirectory(), `${uuidv4()}-runtime-fingerprint.json`);
await fs.writeJSON(fingerprintLocation, {
hash: runtimeVersion,
hash,
sources: fingerprint.fingerprintSources,
});
if (localBuildMode === LocalBuildMode.LOCAL_BUILD_PLUGIN) {
return {
runtimeVersion,
hash,
fingerprintSource: {
type: FingerprintSourceType.PATH,
path: fingerprintLocation,
@@ -62,14 +62,14 @@ export async function maybeUploadFingerprintAsync({
Log.warn(errMessage);
return {
runtimeVersion,
hash,
};
} finally {
await fs.remove(fingerprintLocation);
}
return {
runtimeVersion,
hash,
fingerprintSource: {
type: FingerprintSourceType.GCS,
bucketKey: fingerprintGCSBucketKey,
@@ -72,6 +72,11 @@ export function isExpoNotificationsInstalled(projectDir: string): boolean {
return !!(packageJson.dependencies && 'expo-notifications' in packageJson.dependencies);
}
export function isExpoInstalled(projectDir: string): boolean {
const packageJson = getPackageJson(projectDir);
return !!(packageJson.dependencies && 'expo' in packageJson.dependencies);
}
export function isExpoUpdatesInstalledAsDevDependency(projectDir: string): boolean {
const packageJson = getPackageJson(projectDir);
return !!(packageJson.devDependencies && 'expo-updates' in packageJson.devDependencies);
@@ -0,0 +1,47 @@
import chalk from 'chalk';
import fs from 'node:fs';
import path from 'node:path';
import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
import { AccountUploadSessionType } from '../graphql/generated';
import { uploadAccountScopedFileAtPathToGCSAsync } from '../uploads';
import { formatBytes } from '../utils/files';
import { createProgressTracker } from '../utils/progress';
/**
* Uploads the `eas.json` file to GCS as account-scoped object.
* Used in workflows. Takes care of logging progress.
*/
export async function uploadAccountScopedEasJsonAsync({
graphqlClient,
accountId,
projectDir,
}: {
graphqlClient: ExpoGraphqlClient;
accountId: string;
projectDir: string;
}): Promise<{ easJsonBucketKey: string }> {
const easJsonFilePath = path.join(projectDir, 'eas.json');
const easJsonFileStat = await fs.promises.stat(easJsonFilePath);
if (easJsonFileStat.size > 1024 * 1024) {
throw new Error('eas.json is too big. Maximum allowed size is 1MB.');
}
const easJsonBucketKey = await uploadAccountScopedFileAtPathToGCSAsync(graphqlClient, {
accountId,
type: AccountUploadSessionType.WorkflowsProjectSources,
path: easJsonFilePath,
handleProgressEvent: createProgressTracker({
total: easJsonFileStat.size,
message: ratio =>
`Uploading eas.json to EAS (${formatBytes(easJsonFileStat.size * ratio)} / ${formatBytes(
easJsonFileStat.size
)})`,
completedMessage: (duration: string) => `Uploaded eas.json to EAS ${chalk.dim(duration)}`,
}),
});
return { easJsonBucketKey };
}
@@ -0,0 +1,74 @@
import chalk from 'chalk';
import fs from 'node:fs';
import { makeProjectTarballAsync } from '../build/utils/repository';
import { ExpoGraphqlClient } from '../commandUtils/context/contextUtils/createGraphqlClient';
import { AccountUploadSessionType } from '../graphql/generated';
import Log, { learnMore } from '../log';
import { uploadAccountScopedFileAtPathToGCSAsync } from '../uploads';
import { formatBytes } from '../utils/files';
import { createProgressTracker } from '../utils/progress';
import { Client } from '../vcs/vcs';
/**
* Archives the project and uploads it to GCS as account-scoped object.
* Used in workflows. Takes care of logging progress and cleaning up the tarball.
*/
export async function uploadAccountScopedProjectSourceAsync({
graphqlClient,
vcsClient,
accountId,
}: {
graphqlClient: ExpoGraphqlClient;
vcsClient: Client;
accountId: string;
}): Promise<{ projectArchiveBucketKey: string }> {
let projectTarballPath;
try {
Log.newLine();
Log.log(
`Compressing project files and uploading to EAS. ${learnMore(
'https://expo.fyi/eas-build-archive'
)}`
);
const projectTarball = await makeProjectTarballAsync(vcsClient);
projectTarballPath = projectTarball.path;
if (projectTarball.size > 1024 * 1024 * 100) {
Log.warn(
`Your project archive is ${formatBytes(
projectTarball.size
)}. You can reduce its size and the time it takes to upload by excluding files that are unnecessary for the build process in ${chalk.bold(
'.easignore'
)} file. ${learnMore('https://expo.fyi/eas-build-archive')}`
);
}
if (projectTarball.size > 2 * 1024 * 1024 * 1024) {
throw new Error('Project archive is too big. Maximum allowed size is 2GB.');
}
const projectArchiveBucketKey = await uploadAccountScopedFileAtPathToGCSAsync(graphqlClient, {
accountId,
type: AccountUploadSessionType.WorkflowsProjectSources,
path: projectTarball.path,
handleProgressEvent: createProgressTracker({
total: projectTarball.size,
message: ratio =>
`Uploading project archive to EAS (${formatBytes(
projectTarball.size * ratio
)} / ${formatBytes(projectTarball.size)})`,
completedMessage: (duration: string) =>
`Uploaded project archive to EAS ${chalk.dim(duration)}`,
}),
});
return { projectArchiveBucketKey };
} finally {
if (projectTarballPath) {
await fs.promises.rm(projectTarballPath);
}
}
}
+24 -1
View File
@@ -5,7 +5,7 @@ import promiseRetry from 'promise-retry';
import { ExpoGraphqlClient } from './commandUtils/context/contextUtils/createGraphqlClient';
import fetch from './fetch';
import { UploadSessionType } from './graphql/generated';
import { AccountUploadSessionType, UploadSessionType } from './graphql/generated';
import { SignedUrl, UploadSessionMutation } from './graphql/mutations/UploadSessionMutation';
import { ProgressHandler } from './utils/progress';
@@ -26,6 +26,29 @@ export async function uploadFileAtPathToGCSAsync(
return signedUrl.bucketKey;
}
export async function uploadAccountScopedFileAtPathToGCSAsync(
graphqlClient: ExpoGraphqlClient,
{
type,
accountId,
path,
handleProgressEvent,
}: {
type: AccountUploadSessionType;
accountId: string;
path: string;
handleProgressEvent: ProgressHandler;
}
): Promise<string> {
const signedUrl = await UploadSessionMutation.createAccountScopedUploadSessionAsync(
graphqlClient,
{ type, accountID: accountId }
);
await uploadWithSignedUrlWithProgressAsync(path, signedUrl, handleProgressEvent);
return signedUrl.bucketKey;
}
export async function uploadWithPresignedPostWithRetryAsync(
file: string,
presignedPost: PresignedPost,
@@ -0,0 +1,62 @@
import { Env, Workflow } from '@expo/eas-build-job';
import { silent as silentResolveFrom } from 'resolve-from';
import Log from '../log';
import { ora } from '../ora';
export async function createFingerprintAsync(
projectDir: string,
options: {
workflow: Workflow;
platform: string;
debug?: boolean;
env: Env | undefined;
cwd?: string;
}
): Promise<{
hash: string;
sources: object[];
isDebugSource: boolean;
} | null> {
// @expo/fingerprint is exported in the expo package for SDK 52+
const fingerprintPath = silentResolveFrom(projectDir, 'expo/fingerprint');
if (!fingerprintPath) {
return null;
}
if (process.env.EAS_SKIP_AUTO_FINGERPRINT) {
Log.log('Skipping project fingerprint');
return null;
}
const timeoutId = setTimeout(() => {
Log.log('⌛️ Computing the project fingerprint is taking longer than expected...');
Log.log('⏩ To skip this step, set the environment variable: EAS_SKIP_AUTO_FINGERPRINT=1');
}, 5000);
const spinner = ora(`Computing project fingerprint`).start();
try {
const Fingerprint = require(fingerprintPath);
const fingerprintOptions: Record<string, any> = {};
if (options.platform) {
fingerprintOptions.platforms = [options.platform];
}
if (options.workflow === Workflow.MANAGED) {
fingerprintOptions.ignorePaths = ['android/**/*', 'ios/**/*'];
}
if (options.debug) {
fingerprintOptions.debug = true;
}
const fingerprint = await Fingerprint.createFingerprintAsync(projectDir, fingerprintOptions);
spinner.succeed(`Computed project fingerprint`);
return fingerprint;
} catch (e) {
spinner.fail(`Failed to compute project fingerprint`);
Log.log('⏩ To skip this step, set the environment variable: EAS_SKIP_AUTO_FINGERPRINT=1');
throw e;
} finally {
// Clear the timeout if the operation finishes before the time limit
clearTimeout(timeoutId);
spinner.stop();
}
}
+2 -1
View File
@@ -1,4 +1,5 @@
import chalk from 'chalk';
import { randomUUID } from 'node:crypto';
import { endTimer, formatMilliseconds, startTimer } from './timer';
import { Ora, ora } from '../ora';
@@ -29,7 +30,7 @@ export function createProgressTracker({
let transferredSoFar = 0;
let current = 0;
const timerLabel = String(Date.now());
const timerLabel = String(randomUUID());
const getMessage = (v: number, total: number): string => {
const ratio = Math.min(Math.max(v, 0), 1);
@@ -10,6 +10,12 @@ import {
} from '../graphql/generated';
import { EnvironmentVariableWithFileContent } from '../graphql/queries/EnvironmentVariablesQuery';
export function isEnvironment(environment: string): environment is EnvironmentVariableEnvironment {
return Object.values(EnvironmentVariableEnvironment).includes(
environment as EnvironmentVariableEnvironment
);
}
export function formatVariableName(variable: EnvironmentVariableFragment): string {
const name = variable.name;
const scope = variable.scope === EnvironmentVariableScope.Project ? 'project' : 'shared';
+1 -1
View File
@@ -18,6 +18,6 @@ export default class NoVcsClient extends Client {
}
public override canGetLastCommitMessage(): boolean {
return true;
return false;
}
}
@@ -0,0 +1,109 @@
import fs from 'fs/promises';
import { vol } from 'memfs';
import { WorkflowValidate } from '../../commands/workflow/validate';
jest.mock('fs/promises');
jest.mock('../../log');
jest.mock('../../ora', () => ({
ora: () => ({
start: () => ({
succeed: jest.fn(),
fail: jest.fn(),
}),
}),
}));
describe('WorkflowValidate', () => {
const mockValidYaml = `
name: workflow
on: push
jobs:
build:
steps:
- run: echo "Hello"
`;
const mockInvalidYaml = `
name: workflow
on: : : : invalid
`;
let command: WorkflowValidate;
beforeEach(() => {
vol.reset();
jest.resetAllMocks();
process.exit = jest.fn(() => {
throw new Error();
});
});
describe('file validation', () => {
describe('when file exists', () => {
beforeEach(() => {
(fs.access as jest.Mock).mockResolvedValue(undefined);
});
it('validates a correct YAML file', async () => {
(fs.readFile as jest.Mock).mockResolvedValue(mockValidYaml);
command = new WorkflowValidate(['./workflow.yml'], {} as any);
await expect(command.runAsync()).resolves.not.toThrow();
});
it('accepts both .yml and .yaml extensions', async () => {
(fs.readFile as jest.Mock).mockResolvedValue(mockValidYaml);
command = new WorkflowValidate(['./workflow.yml'], {} as any);
await expect(command.runAsync()).resolves.not.toThrow();
command = new WorkflowValidate(['./workflow.yaml'], {} as any);
await expect(command.runAsync()).resolves.not.toThrow();
});
it('throws error for empty YAML file', async () => {
(fs.readFile as jest.Mock).mockResolvedValue('');
command = new WorkflowValidate(['./workflow.yml'], {} as any);
await expect(command.runAsync()).rejects.toThrow();
});
it('throws error for invalid YAML syntax', async () => {
(fs.readFile as jest.Mock).mockResolvedValue(mockInvalidYaml);
command = new WorkflowValidate(['./workflow.yml'], {} as any);
await expect(command.runAsync()).rejects.toThrow();
});
it('throws error for invalid file extension', async () => {
command = new WorkflowValidate(['./workflow.txt'], {} as any);
await expect(command.runAsync()).rejects.toThrow();
});
});
describe('when file does not exist', () => {
beforeEach(() => {
(fs.access as jest.Mock).mockRejectedValue(new Error('ENOENT'));
});
it('throws appropriate error', async () => {
command = new WorkflowValidate(['./nonexistent.yml'], {} as any);
await expect(command.runAsync()).rejects.toThrow();
});
});
});
describe('error handling', () => {
it('handles unexpected errors gracefully', async () => {
(fs.access as jest.Mock).mockResolvedValue(undefined);
(fs.readFile as jest.Mock).mockRejectedValue(new Error('Unexpected error'));
command = new WorkflowValidate(['./workflow.yml'], {} as any);
await expect(command.runAsync()).rejects.toThrow();
});
});
});
+2 -2
View File
@@ -1,12 +1,12 @@
{
"name": "@expo/eas-json",
"description": "A library for interacting with eas.json",
"version": "12.6.2",
"version": "13.2.2",
"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.141",
"@expo/eas-build-job": "1.0.149",
"chalk": "4.1.2",
"env-string": "1.0.1",
"fs-extra": "11.2.0",
+5 -10
View File
@@ -375,9 +375,11 @@
"enum": [
"auto",
"latest",
"sdk-52",
"sdk-51",
"sdk-50",
"sdk-49",
"macos-sonoma-14.6-xcode-16.1",
"macos-sonoma-14.6-xcode-16.0",
"macos-sonoma-14.5-xcode-15.4",
"macos-sonoma-14.4-xcode-15.3",
@@ -387,7 +389,8 @@
],
"markdownEnumDescriptions": [
"When using this option the build image is selected automatically based on the project configuration, detected Expo SDK and React Native versions.",
"The latest iOS image currently available. It is resolved to `macos-sonoma-14.6-xcode-16.0`. The `latest` to image mapping will be updated as new images are released.",
"The latest iOS image currently available. It is resolved to `macos-sonoma-14.6-xcode-16.1`. The `latest` to image mapping will be updated as new images are released.",
"The recommended image for SDK 52 builds",
"The recommended image for SDK 51 builds",
"The recommended image for SDK 50 builds",
"The recommended image for SDK 49 builds"
@@ -398,15 +401,7 @@
"enum": ["default", "stable"],
"markdownEnumDescriptions": [
"This image tag is deprecated, please use other image tags or images directly instead.",
"This image tag is deprecated, please use other image tags or images directly instead.",
"This image is using Xcode in version lower then 15. Apple's new requirement states that starting on April 29th, 2024, apps uploaded to App Store Connect must be built with Xcode 15 for iOS 17, iPadOS 17, tvOS 17, or watchOS 10. Start using Xcode 15 image today by setting `macos-sonoma-14.4-xcode-15.3` or `latest` as your image value. This image will be removed from EAS Build on May 29th, 2024. Learn more: https://expo.dev/changelog/2024/03-29-eas-build-upcoming-ios-images-updates.",
"This image is using Xcode in version lower then 15. Apple's new requirement states that starting on April 29th, 2024, apps uploaded to App Store Connect must be built with Xcode 15 for iOS 17, iPadOS 17, tvOS 17, or watchOS 10. Start using Xcode 15 image today by setting `macos-sonoma-14.4-xcode-15.3` or `latest` as your image value. This image will be removed from EAS Build on May 29th, 2024. Learn more: https://expo.dev/changelog/2024/03-29-eas-build-upcoming-ios-images-updates.",
"This image is using Xcode in version lower then 15. Apple's new requirement states that starting on April 29th, 2024, apps uploaded to App Store Connect must be built with Xcode 15 for iOS 17, iPadOS 17, tvOS 17, or watchOS 10. Start using Xcode 15 image today by setting `macos-sonoma-14.4-xcode-15.3` or `latest` as your image value. This image will be removed from EAS Build on May 29th, 2024. Learn more: https://expo.dev/changelog/2024/03-29-eas-build-upcoming-ios-images-updates.",
"This image is using Xcode in version lower then 15. Apple's new requirement states that starting on April 29th, 2024, apps uploaded to App Store Connect must be built with Xcode 15 for iOS 17, iPadOS 17, tvOS 17, or watchOS 10. Start using Xcode 15 image today by setting `macos-sonoma-14.4-xcode-15.3` or `latest` as your image value. This image will be removed from EAS Build on May 29th, 2024. Learn more: https://expo.dev/changelog/2024/03-29-eas-build-upcoming-ios-images-updates.",
"This image is using Xcode in version lower then 15. Apple's new requirement states that starting on April 29th, 2024, apps uploaded to App Store Connect must be built with Xcode 15 for iOS 17, iPadOS 17, tvOS 17, or watchOS 10. Start using Xcode 15 image today by setting `macos-sonoma-14.4-xcode-15.3` or `latest` as your image value. This image will be removed from EAS Build on May 29th, 2024. Learn more: https://expo.dev/changelog/2024/03-29-eas-build-upcoming-ios-images-updates.",
"This image is using Xcode in version lower then 15. Apple's new requirement states that starting on April 29th, 2024, apps uploaded to App Store Connect must be built with Xcode 15 for iOS 17, iPadOS 17, tvOS 17, or watchOS 10. Start using Xcode 15 image today by setting `macos-sonoma-14.4-xcode-15.3` or `latest` as your image value. This image will be removed from EAS Build on May 29th, 2024. Learn more: https://expo.dev/changelog/2024/03-29-eas-build-upcoming-ios-images-updates.",
"This image is using Xcode in version lower then 15. Apple's new requirement states that starting on April 29th, 2024, apps uploaded to App Store Connect must be built with Xcode 15 for iOS 17, iPadOS 17, tvOS 17, or watchOS 10. Start using Xcode 15 image today by setting `macos-sonoma-14.4-xcode-15.3` or `latest` as your image value. This image will be removed from EAS Build on May 29th, 2024. Learn more: https://expo.dev/changelog/2024/03-29-eas-build-upcoming-ios-images-updates.",
"This image is using Xcode in version lower then 15. Apple's new requirement states that starting on April 29th, 2024, apps uploaded to App Store Connect must be built with Xcode 15 for iOS 17, iPadOS 17, tvOS 17, or watchOS 10. Start using Xcode 15 image today by setting `macos-sonoma-14.4-xcode-15.3` or `latest` as your image value. This image will be removed from EAS Build on May 29th, 2024. Learn more: https://expo.dev/changelog/2024/03-29-eas-build-upcoming-ios-images-updates."
"This image tag is deprecated, please use other image tags or images directly instead."
]
}
]
Generated
+166 -139
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/apple-utils@2.0.3":
version "2.0.3"
resolved "https://registry.yarnpkg.com/@expo/apple-utils/-/apple-utils-2.0.3.tgz#558f185a44533ee7b33fc9da3a76ebb953ab8777"
integrity sha512-RvV6rCvwdYvCv9c/57XHDAUfTq3RM/wQMmurrLLuYADEurwRveltO7SQ/ajpa4SrTpCzQDx2L3WZGXah7Syr6Q==
"@expo/apple-utils@2.1.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/bunyan@^4.0.0":
version "4.0.0"
@@ -1382,95 +1382,96 @@
node-forge "^1.2.1"
nullthrows "^1.1.1"
"@expo/config-plugins@7.8.4":
version "7.8.4"
resolved "https://registry.yarnpkg.com/@expo/config-plugins/-/config-plugins-7.8.4.tgz#533b5d536c1dc8b5544d64878b51bda28f2e1a1f"
integrity sha512-hv03HYxb/5kX8Gxv/BTI8TLc9L06WzqAfHRRXdbar4zkLcP2oTzvsLEF4/L/TIpD3rsnYa0KU42d0gWRxzPCJg==
"@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==
dependencies:
"@expo/config-types" "^50.0.0-alpha.1"
"@expo/fingerprint" "^0.6.0"
"@expo/config-types" "^51.0.3"
"@expo/json-file" "~8.3.0"
"@expo/plist" "^0.1.0"
"@expo/sdk-runtime-versions" "^1.0.0"
"@react-native/normalize-color" "^2.0.0"
chalk "^4.1.2"
debug "^4.3.1"
find-up "~5.0.0"
getenv "^1.0.0"
glob "7.1.6"
resolve-from "^5.0.0"
semver "^7.5.3"
semver "^7.5.4"
slash "^3.0.0"
slugify "^1.6.6"
xcode "^3.0.1"
xml2js "0.6.0"
"@expo/config-plugins@~7.8.0", "@expo/config-plugins@~7.8.2":
version "7.8.2"
resolved "https://registry.yarnpkg.com/@expo/config-plugins/-/config-plugins-7.8.2.tgz#c00ce93c4d6c2cb9e345ed9cd56ceeea05ab8ddb"
integrity sha512-XM2eXA5EvcpmXFCui48+bVy8GTskYSjPf2yC+LliYv8PDcedu7+pdgmbnvH4eZCyHfTMO8/UiF+w8e5WgOEj5A==
"@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==
dependencies:
"@expo/config-types" "^50.0.0-alpha.1"
"@expo/fingerprint" "^0.6.0"
"@expo/config-types" "^51.0.0-unreleased"
"@expo/json-file" "~8.3.0"
"@expo/plist" "^0.1.0"
"@expo/sdk-runtime-versions" "^1.0.0"
"@react-native/normalize-color" "^2.0.0"
chalk "^4.1.2"
debug "^4.3.1"
find-up "~5.0.0"
getenv "^1.0.0"
glob "7.1.6"
resolve-from "^5.0.0"
semver "^7.5.3"
semver "^7.5.4"
slash "^3.0.0"
slugify "^1.6.6"
xcode "^3.0.1"
xml2js "0.6.0"
"@expo/config-types@^50.0.0", "@expo/config-types@^50.0.0-alpha.1":
version "50.0.0"
resolved "https://registry.yarnpkg.com/@expo/config-types/-/config-types-50.0.0.tgz#b534d3ec997ec60f8af24f6ad56244c8afc71a0b"
integrity sha512-0kkhIwXRT6EdFDwn+zTg9R2MZIAEYGn1MVkyRohAd+C9cXOb5RA8WLQi7vuxKF9m1SMtNAUrf0pO+ENK0+/KSw==
"@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@8.5.4":
version "8.5.4"
resolved "https://registry.yarnpkg.com/@expo/config/-/config-8.5.4.tgz#bb5eb06caa36e4e35dc8c7647fae63e147b830ca"
integrity sha512-ggOLJPHGzJSJHVBC1LzwXwR6qUn8Mw7hkc5zEKRIdhFRuIQ6s2FE4eOvP87LrNfDF7eZGa6tJQYsiHSmZKG+8Q==
"@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==
dependencies:
"@babel/code-frame" "~7.10.4"
"@expo/config-plugins" "~7.8.2"
"@expo/config-types" "^50.0.0"
"@expo/json-file" "^8.2.37"
"@expo/config-plugins" "~8.0.8"
"@expo/config-types" "^51.0.3"
"@expo/json-file" "^8.3.0"
getenv "^1.0.0"
glob "7.1.6"
require-from-string "^2.0.2"
resolve-from "^5.0.0"
semver "7.5.3"
semver "^7.6.0"
slugify "^1.3.4"
sucrase "3.34.0"
"@expo/config@~8.5.0":
version "8.5.2"
resolved "https://registry.yarnpkg.com/@expo/config/-/config-8.5.2.tgz#4a0de82279337a37b5f1f0958711fe56e8ea31c2"
integrity sha512-UYy9kWxjQAEDwlX7gwLk0+8IxGPcHJMLnYRYtR5C5xGIV+ML7tCA+qFz1p4gHZRPkJD+k7iZyqBtyqt8xm+zXw==
"@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==
dependencies:
"@babel/code-frame" "~7.10.4"
"@expo/config-plugins" "~7.8.2"
"@expo/config-types" "^50.0.0"
"@expo/json-file" "^8.2.37"
"@expo/config-plugins" "~8.0.8"
"@expo/config-types" "^51.0.0-unreleased"
"@expo/json-file" "^8.3.0"
getenv "^1.0.0"
glob "7.1.6"
require-from-string "^2.0.2"
resolve-from "^5.0.0"
semver "7.5.3"
semver "^7.6.0"
slugify "^1.3.4"
sucrase "^3.20.0"
sucrase "3.34.0"
"@expo/[email protected]1":
version "1.0.141"
resolved "https://registry.yarnpkg.com/@expo/eas-build-job/-/eas-build-job-1.0.141.tgz#9946a694d7a9602fc9827da66a6cbb625f8f7b6e"
integrity sha512-7BlmYxMGn/0sR9S5nCPHHDD0niiO9DZ2o1VsyqG0jk1butucL0iR0f4gf1FAsnT18f5bLdrvBaBKpmv5U/q3Rg==
"@expo/[email protected]9":
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==
dependencies:
"@expo/logger" "1.0.117"
joi "^17.13.1"
@@ -1488,25 +1489,12 @@
dotenv-expand "~11.0.6"
getenv "^1.0.0"
"@expo/fingerprint@^0.6.0":
version "0.6.0"
resolved "https://registry.yarnpkg.com/@expo/fingerprint/-/fingerprint-0.6.0.tgz#77366934673d4ecea37284109b4dd67f9e6a7487"
integrity sha512-KfpoVRTMwMNJ/Cf5o+Ou8M/Y0EGSTqK+rbi70M2Y0K2qgWNfMJ1gm6sYO9uc8lcTr7YSYM1Rme3dk7QXhpScNA==
"@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==
dependencies:
"@expo/spawn-async" "^1.5.0"
chalk "^4.1.2"
debug "^4.3.4"
find-up "^5.0.0"
minimatch "^3.0.4"
p-limit "^3.1.0"
resolve-from "^5.0.0"
"@expo/image-utils@^0.4.0":
version "0.4.1"
resolved "https://registry.yarnpkg.com/@expo/image-utils/-/image-utils-0.4.1.tgz#78c54b8aaa974d0ac37fee5285683b54ff161b2c"
integrity sha512-EZb+VHSmw+a5s2hS9qksTcWylY0FDaIAVufcxoaRS9tHIXLjW5zcKW7Rhj9dSEbZbRVy9yXXdHKa3GQdUQIOFw==
dependencies:
"@expo/spawn-async" "1.5.0"
"@expo/spawn-async" "^1.7.2"
chalk "^4.0.0"
fs-extra "9.0.0"
getenv "^1.0.0"
@@ -1514,13 +1502,13 @@
node-fetch "^2.6.0"
parse-png "^2.1.0"
resolve-from "^5.0.0"
semver "7.3.2"
semver "^7.6.0"
tempy "0.3.0"
"@expo/json-file@8.2.37", "@expo/json-file@^8.2.37":
version "8.2.37"
resolved "https://registry.yarnpkg.com/@expo/json-file/-/json-file-8.2.37.tgz#9c02d3b42134907c69cc0a027b18671b69344049"
integrity sha512-YaH6rVg11JoTS2P6LsW7ybS2CULjf40AbnAHw2F1eDPuheprNjARZMnyHFPkKv7GuxCy+B9GPcbOKgc4cgA80Q==
"@expo/json-file@8.3.3", "@expo/json-file@^8.3.0":
version "8.3.3"
resolved "https://registry.yarnpkg.com/@expo/json-file/-/json-file-8.3.3.tgz#7926e3592f76030ce63d6b1308ac8f5d4d9341f4"
integrity sha512-eZ5dld9AD0PrVRiIWpRkm5aIoWBw3kAyd8VkuWEy92sEthBKDDDHAnK2a0dw0Eil6j7rK7lS/Qaq/Zzngv2h5A==
dependencies:
"@babel/code-frame" "~7.10.4"
json5 "^2.2.2"
@@ -1552,21 +1540,21 @@
nullthrows "^1.1.1"
structured-headers "^0.4.1"
"@expo/osascript@2.0.33":
version "2.0.33"
resolved "https://registry.yarnpkg.com/@expo/osascript/-/osascript-2.0.33.tgz#e9dcc8da54466c11939074aa71a006024ea884b1"
integrity sha512-FQinlwHrTlJbntp8a7NAlCKedVXe06Va/0DSLXRO8lZVtgbEMrYYSUZWQNcOlNtc58c2elNph6z9dMOYwSo3JQ==
"@expo/osascript@2.1.3":
version "2.1.3"
resolved "https://registry.yarnpkg.com/@expo/osascript/-/osascript-2.1.3.tgz#912b74825cb83f3b958cad81034df9e19f1f2808"
integrity sha512-aOEkhPzDsaAfolSswObGiYW0Pf0ROfR9J2NBRLQACdQ6uJlyAMiPF45DVEVknAU9juKh0y8ZyvC9LXqLEJYohA==
dependencies:
"@expo/spawn-async" "^1.5.0"
"@expo/spawn-async" "^1.7.2"
exec-async "^2.2.0"
"@expo/package-manager@1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@expo/package-manager/-/package-manager-1.1.2.tgz#e58c9bed4cbb829ebf2cbb80b8542600a6609bd1"
integrity sha512-JI9XzrxB0QVXysyuJ996FPCJGDCYRkbUvgG4QmMTTMFA1T+mv8YzazC3T9C1pHQUAAveVCre1+Pqv0nZXN24Xg==
"@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==
dependencies:
"@expo/json-file" "^8.2.37"
"@expo/spawn-async" "^1.5.0"
"@expo/json-file" "^8.3.0"
"@expo/spawn-async" "^1.7.2"
ansi-regex "^5.0.0"
chalk "^4.0.0"
find-up "^5.0.0"
@@ -1574,20 +1562,21 @@
js-yaml "^3.13.1"
micromatch "^4.0.2"
npm-package-arg "^7.0.0"
ora "^3.4.0"
split "^1.0.1"
sudo-prompt "9.1.1"
"@expo/pkcs12@0.0.8":
version "0.0.8"
resolved "https://registry.yarnpkg.com/@expo/pkcs12/-/pkcs12-0.0.8.tgz#40ddde3007d90d4fd58779670f1aabfa82ce2950"
integrity sha512-VNZnmsu3PgdvZRqYLB0Ja8dNjKrgKpcqMvtUPINI4fJbF/ihDNI0A/LkHvnR2/21WRMHk2tm4QgMIkOQTfZ5kg==
"@expo/pkcs12@0.1.2":
version "0.1.2"
resolved "https://registry.yarnpkg.com/@expo/pkcs12/-/pkcs12-0.1.2.tgz#9d88ed0d980e211690a9580fed425d9e3cc4c5b7"
integrity sha512-CLoOKm35mcIJHV11bR7DunfAtw0HcQ2ir7fWWCw9gwvhrhi75cer2xlLqeHPhmvXDad437Mh8L1Bz+B1EIKdMA==
dependencies:
node-forge "^1.2.1"
"@expo/plist@0.0.20":
version "0.0.20"
resolved "https://registry.yarnpkg.com/@expo/plist/-/plist-0.0.20.tgz#a6b3124438031c02b762bad5a47b70584d3c0072"
integrity sha512-UXQ4LXCfTZ580LDHGJ5q62jSTwJFFJ1GqBu8duQMThiHKWbMJ+gajJh6rsB6EJ3aLUr9wcauxneL5LVRFxwBEA==
"@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"
@@ -1623,20 +1612,21 @@
semver "^7.3.7"
tslib "^2.4.0"
"@expo/prebuild-config@6.7.3":
version "6.7.3"
resolved "https://registry.yarnpkg.com/@expo/prebuild-config/-/prebuild-config-6.7.3.tgz#8444c1630bd92931c2d1a510791535b7282d8fa6"
integrity sha512-jZIHzlnvdg4Gnln06XR9tvirL3hSp/Jh48COhLKs51vb3THCWumUytZBS4DSMdvGwf8btnaB01Zg00xQhSDBsA==
"@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==
dependencies:
"@expo/config" "~8.5.0"
"@expo/config-plugins" "~7.8.0"
"@expo/config-types" "^50.0.0-alpha.1"
"@expo/image-utils" "^0.4.0"
"@expo/json-file" "^8.2.37"
"@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"
debug "^4.3.1"
fs-extra "^9.0.0"
resolve-from "^5.0.0"
semver "7.5.3"
semver "^7.6.0"
xml2js "0.6.0"
"@expo/[email protected]":
@@ -1662,33 +1652,19 @@
resolved "https://registry.yarnpkg.com/@expo/sdk-runtime-versions/-/sdk-runtime-versions-1.0.0.tgz#d7ebd21b19f1c6b0395e50d78da4416941c57f7c"
integrity sha512-Doz2bfiPndXYFPMRwPyGa1k5QaKDVpY806UJj570epIiMzWaYyCtobasyfC++qfIXVb5Ocy7r3tP9d62hAQ7IQ==
"@expo/spawn-async@1.5.0":
version "1.5.0"
resolved "https://registry.yarnpkg.com/@expo/spawn-async/-/spawn-async-1.5.0.tgz#799827edd8c10ef07eb1a2ff9dcfe081d596a395"
integrity sha512-LB7jWkqrHo+5fJHNrLAFdimuSXQ2MQ4lA7SQW5bf/HbsXuV2VrT/jN/M8f/KoWt0uJMGN4k/j7Opx4AvOOxSew==
dependencies:
cross-spawn "^6.0.5"
"@expo/[email protected]", "@expo/spawn-async@^1.5.0":
version "1.7.0"
resolved "https://registry.yarnpkg.com/@expo/spawn-async/-/spawn-async-1.7.0.tgz#3ab6082b24318cccc4e73b13464da91325555500"
integrity sha512-sqPAjOEFTrjaTybrh9SnPFLInDXcoMC06psEFmH68jLTmoipSQCq8GCEfIoHhxRDALWB+DsiwXJSbXlE/iVIIQ==
dependencies:
cross-spawn "^7.0.3"
"@expo/spawn-async@^1.7.2":
"@expo/spawn-async@1.7.2", "@expo/spawn-async@^1.7.2":
version "1.7.2"
resolved "https://registry.yarnpkg.com/@expo/spawn-async/-/spawn-async-1.7.2.tgz#fcfe66c3e387245e72154b1a7eae8cada6a47f58"
integrity sha512-QdWi16+CHB9JYP7gma19OVVg0BFkvU8zNj9GjWorYI8Iv8FUxjOCcYRuAmX4s/h91e4e7BPsskc8cSrZYho9Ew==
dependencies:
cross-spawn "^7.0.3"
"@expo/[email protected]1":
version "1.0.141"
resolved "https://registry.yarnpkg.com/@expo/steps/-/steps-1.0.141.tgz#36be4e1f8b6d73acfef2128f40dd09b301daa12e"
integrity sha512-B9unlCJQHMlaE82I00W/mFTJ8H6RMThsldsbydZQFeLgif60q7eyAtnB2xbRJwCMoGZ9p72QSkQQFtG5waFMJw==
"@expo/[email protected]9":
version "1.0.149"
resolved "https://registry.yarnpkg.com/@expo/steps/-/steps-1.0.149.tgz#48a27cd6a2e94ce1e8e92101d1d9bca9390f2a14"
integrity sha512-1PKIiwlzSf4/zqu80jLJgzMPFshUZrQP/U8/Q6VRP1EBEgGTffr6+GxQBD17fQfsQ7yKKrMcO6f9O82B9dxj3w==
dependencies:
"@expo/eas-build-job" "1.0.141"
"@expo/eas-build-job" "1.0.149"
"@expo/logger" "1.0.117"
"@expo/spawn-async" "^1.7.2"
arg "^5.0.2"
@@ -3473,10 +3449,10 @@
resolved "https://registry.yarnpkg.com/@pkgr/core/-/core-0.1.0.tgz#7d8dacb7fdef0e4387caf7396cbd77f179867d06"
integrity sha512-Zwq5OCzuwJC2jwqmpEQt7Ds1DTi6BWSwoGkbb1n9pO3hzb35BoJELx7c0T23iDkBGkh2e7tvOtjF3tr3OaQHDQ==
"@react-native/normalize-color@^2.0.0":
version "2.0.0"
resolved "https://registry.yarnpkg.com/@react-native/normalize-color/-/normalize-color-2.0.0.tgz#da955909432474a9a0fe1cbffc66576a0447f567"
integrity sha512-Wip/xsc5lw8vsBlmY2MO/gFLp3MvuZ2baBZjDeTjjndMgM0h5sxz7AZR62RDPGgstp8Np7JzjvVqVT7tpFZqsw==
"@react-native/normalize-color[email protected]":
version "0.74.85"
resolved "https://registry.yarnpkg.com/@react-native/normalize-colors/-/normalize-colors-0.74.85.tgz#62bcb9ab1b10b822ca0278fdfdf23d3b18e125da"
integrity sha512-pcE4i0X7y3hsAE0SpIl7t6dUc0B0NZLd1yv7ssm4FrLhWG+CGyIq4eFDXpmPU1XHmL5PPySxTAjEMiwv6tAmOw==
"@repeaterjs/repeater@^3.0.4":
version "3.0.5"
@@ -4341,6 +4317,11 @@ ansi-escapes@^6.0.0:
dependencies:
type-fest "^3.0.0"
ansi-regex@^4.1.0:
version "4.1.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.1.tgz#164daac87ab2d6f6db3a29875e2d1766582dabed"
integrity sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==
ansi-regex@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
@@ -5276,7 +5257,7 @@ [email protected], chalk@^4, chalk@^4.0.2, chalk@^4.1.1, chalk@^4.1.2:
ansi-styles "^4.1.0"
supports-color "^7.1.0"
chalk@^2.0.0, chalk@^2.4.2:
chalk@^2.0.0, chalk@^2.0.1, chalk@^2.4.2:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
@@ -5383,6 +5364,13 @@ [email protected], cli-cursor@^3.1.0:
dependencies:
restore-cursor "^3.1.0"
cli-cursor@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5"
integrity sha512-8lgKz8LmCRYZZQDpRyT2m5rKJ08TnU4tR9FFFW2rxpxR1FzWi4PQ/NfyODchAatHaUgnSPVcx/R5w6NuTBzFiw==
dependencies:
restore-cursor "^2.0.0"
[email protected], cli-progress@^3.10.0, cli-progress@^3.12.0:
version "3.12.0"
resolved "https://registry.yarnpkg.com/cli-progress/-/cli-progress-3.12.0.tgz#807ee14b66bcc086258e444ad0f19e7d42577942"
@@ -5395,6 +5383,11 @@ [email protected], cli-spinners@^2.5.0:
resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.1.tgz#adc954ebe281c37a6319bfa401e6dd2488ffb70d"
integrity sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==
cli-spinners@^2.0.0:
version "2.9.2"
resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.2.tgz#1773a8f4b9c4d6ac31563df53b3fc1d79462fe41"
integrity sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==
cli-spinners@^2.4.0:
version "2.4.0"
resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.4.0.tgz#c6256db216b878cfba4720e719cec7cf72685d7f"
@@ -10105,6 +10098,13 @@ [email protected], log-symbols@^4.1.0:
chalk "^4.1.0"
is-unicode-supported "^0.1.0"
log-symbols@^2.2.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a"
integrity sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==
dependencies:
chalk "^2.0.1"
log-symbols@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.0.0.tgz#69b3cc46d20f448eccdb75ea1fa733d9e821c920"
@@ -10445,6 +10445,11 @@ [email protected]:
resolved "https://registry.yarnpkg.com/mime/-/mime-3.0.0.tgz#b374550dca3a0c18443b0c950a6a58f1931cf7a7"
integrity sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==
mimic-fn@^1.0.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022"
integrity sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==
mimic-fn@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
@@ -11386,6 +11391,13 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0:
dependencies:
wrappy "1"
onetime@^2.0.0:
version "2.0.1"
resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4"
integrity sha512-oyyPpiMaKARvvcgip+JV+7zci5L8D1W9RZIz2l1o08AM3pfspitVWnPt3mzHcBPp12oYMTy0pqrFs/C+m3EwsQ==
dependencies:
mimic-fn "^1.0.0"
onetime@^5.1.0, onetime@^5.1.2:
version "5.1.2"
resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e"
@@ -11428,6 +11440,18 @@ [email protected]:
strip-ansi "^6.0.0"
wcwidth "^1.0.1"
ora@^3.4.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/ora/-/ora-3.4.0.tgz#bf0752491059a3ef3ed4c85097531de9fdbcd318"
integrity sha512-eNwHudNbO1folBP3JsZ19v9azXWtQZjICdr3Q0TDPIaeBQ3mXLrh54wM+er0+hSp+dWKf+Z8KM58CYzEyIYxYg==
dependencies:
chalk "^2.4.2"
cli-cursor "^2.1.0"
cli-spinners "^2.0.0"
log-symbols "^2.2.0"
strip-ansi "^5.2.0"
wcwidth "^1.0.1"
ora@^5.4.1:
version "5.4.1"
resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18"
@@ -12491,6 +12515,14 @@ responselike@^2.0.0:
dependencies:
lowercase-keys "^2.0.0"
restore-cursor@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf"
integrity sha512-6IzJLuGi4+R14vwagDHX+JrXmPVtPpn4mffDJ1UdR7/Edm87fl6yi8mMBIVvFtJaNTUvjughmW4hwLhRG7gC1Q==
dependencies:
onetime "^2.0.0"
signal-exit "^3.0.2"
restore-cursor@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e"
@@ -12661,11 +12693,6 @@ scuid@^1.1.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
[email protected]:
version "7.3.2"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938"
integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==
[email protected]:
version "7.5.2"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.2.tgz#5b851e66d1be07c1cdaf37dfc856f543325a2beb"
@@ -13358,6 +13385,13 @@ string_decoder@~1.1.1:
dependencies:
ansi-regex "^5.0.1"
strip-ansi@^5.2.0:
version "5.2.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae"
integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==
dependencies:
ansi-regex "^4.1.0"
strip-ansi@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532"
@@ -13466,18 +13500,6 @@ [email protected]:
pirates "^4.0.1"
ts-interface-checker "^0.1.9"
sucrase@^3.20.0:
version "3.20.1"
resolved "https://registry.yarnpkg.com/sucrase/-/sucrase-3.20.1.tgz#1c055e97d0fab2f9857f02461364075b3a4ab226"
integrity sha512-BIG59HaJOxNct9Va6KvT5yzBA/rcMGetzvZyTx0ZdCcspIbpJTPS64zuAfYlJuOj+3WaI5JOdA+F0bJQQi8ZiQ==
dependencies:
commander "^4.0.0"
glob "7.1.6"
lines-and-columns "^1.1.6"
mz "^2.7.0"
pirates "^4.0.1"
ts-interface-checker "^0.1.9"
[email protected]:
version "9.1.1"
resolved "https://registry.yarnpkg.com/sudo-prompt/-/sudo-prompt-9.1.1.tgz#73853d729770392caec029e2470db9c221754db0"
@@ -14787,6 +14809,11 @@ yaml-ast-parser@^0.0.43:
resolved "https://registry.yarnpkg.com/yaml-ast-parser/-/yaml-ast-parser-0.0.43.tgz#e8a23e6fb4c38076ab92995c5dca33f3d3d7c9bb"
integrity sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==
[email protected]:
version "2.6.0"
resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.6.0.tgz#14059ad9d0b1680d0f04d3a60fe00f3a857303c3"
integrity sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==
yaml@^1.7.2:
version "1.10.0"
resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.0.tgz#3b593add944876077d4d683fee01081bd9fff31e"