Compare commits

..
49 Commits
Author SHA1 Message Date
Wojciech Kozyra 1eae0c75ee v0.48.2 2022-03-21 12:19:03 +01:00
Wojciech Kozyra 483e0f2dca upgrade eas-cli-local-build-plugin to 0.0.67 2022-03-21 12:18:51 +01:00
Wojciech Kozyra 6ee843e41c [eas-cli] proxy support (#1005)
* [eas-cli] proxy support

* update CHANGELOG.md

* review feedback
2022-03-21 12:14:15 +01:00
Wojciech Kozyra 5402ebdc5c [eas-cli] do not retry build requests (#1024)
* do not retry build requests

* update CHANGELOG.md
2022-03-18 13:03:25 +01:00
Giau. Tran Minh 1b5119d818 fix: Add project slug to the BuildFragment (#1021)
* fix: Add project slug to the BuildFragment

* chore: update CHANGELOG

* fix: format URL using URL object
2022-03-16 11:47:35 +01:00
Expo CI 8a82365680 update CHANGELOG.md 2022-03-15 22:30:11 +00:00
kbrandwijk 9c55621719 v0.48.1 2022-03-15 23:23:27 +01:00
Wojciech Kozyra 1afc3093ec [eas-cli] Improve apple login prompt for internal distribution builds. (#1016)
* [eas-cli] improve messaging about apple login requirement

* update CHANGELOG.md
2022-03-15 10:48:55 +01:00
Will Schurman 790c3d776e [eas-cli] Fix code signing error when not yet configured (#1018) 2022-03-14 20:28:14 -07:00
Expo CI be84ffd62a update CHANGELOG.md 2022-03-14 13:32:52 +00:00
Dominik Sokal fa812f448f v0.48.0 2022-03-14 14:25:56 +01:00
Dominik Sokal d09161b745 upgrade eas-cli-local-build-plugin to 0.0.66 2022-03-14 14:25:41 +01:00
Dominik Sokal 653f26257b upgrade dependencies (#1015)
* upgrade dependencies

* [eas-cli] regenerate GraphQL code

* update CHANGELOG.md
2022-03-14 13:26:06 +01:00
Wojciech Kozyra b1e874966c [eas-cli] Fix build status when build is canceled (#1012)
* [eas-cli] Fix build status when build is canceled

* update CHANGELOG.md
2022-03-14 11:04:54 +01:00
Jérémy Barbet 315abf0a03 docs: both platforms can be used (#1013) 2022-03-14 11:04:41 +01:00
Wojciech Kozyra 89a9255929 [eas-cli] Fix login request + update CHANGELOG (#1004) 2022-03-09 14:51:17 +01:00
Wojciech Kozyra cae0ba21eb [eas-cli] Fix code signing error on unconfigured eas project (#1002) 2022-03-08 16:32:40 +01:00
Wojciech KozyraandKim Brandwijk ed52e291cb [eas-cli] replace got with node-fetch (#1000)
* [eas-cli] replace got with node-fetch

* Update packages/eas-cli/src/api.ts

Co-authored-by: Kim Brandwijk <[email protected]>

* review feedback

* convert ApiV2 class into plain object

Co-authored-by: Kim Brandwijk <[email protected]>
2022-03-08 15:24:03 +01:00
dependabot[bot] 6db7ac617b Bump plist from 3.0.1 to 3.0.4 (#996)
Bumps [plist](https://github.com/TooTallNate/node-plist) from 3.0.1 to 3.0.4.
- [Release notes](https://github.com/TooTallNate/node-plist/releases)
- [Changelog](https://github.com/TooTallNate/plist.js/blob/master/History.md)
- [Commits](https://github.com/TooTallNate/node-plist/commits)

---
updated-dependencies:
- dependency-name: plist
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-03-04 15:41:49 +01:00
Wojciech KozyraandDominik Sokal 1dd9614dbe [eas-cli] remove unused flag (#995)
* [eas-cli] remove unused flag

* update CHANGELOG.md

* Update packages/eas-cli/src/commands/build/index.ts

Co-authored-by: Dominik Sokal <[email protected]>

Co-authored-by: Dominik Sokal <[email protected]>
2022-03-01 11:54:10 +01:00
Kim Brandwijk 67c58a75d9 [chore] update issue template for expo-env-info (#986) 2022-02-27 10:19:44 +01:00
jkh 5b3e4cb3e1 [eas-cli] make eas update:configure work with native files (#978) 2022-02-21 14:50:57 -05:00
dependabot[bot] caf257ce9c Bump follow-redirects from 1.14.7 to 1.14.8 (#976)
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.14.7 to 1.14.8.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.14.7...v1.14.8)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-02-21 12:08:28 +01:00
Kim Brandwijk 31122623fa docs: changelog typo 2022-02-21 10:07:14 +01:00
kbrandwijk eb36dd0fef chore: linting fix 2022-02-17 21:14:09 +01:00
Kim Brandwijk bb0723354f [update] make runtime version warning more descriptive (#979) 2022-02-17 21:09:52 +01:00
jkh 1b9feed040 [eas-cli] install expo-updates when running update:configure (#977) 2022-02-15 16:15:55 -05:00
Will Schurman 0220ca17a6 [eas-cli] Update @expo/config-types and related packages (#974) 2022-02-11 13:54:49 -08:00
Will Schurman 74cec12c23 [eas-cli] Add code signing (#964) 2022-02-11 12:48:33 -08:00
Wojciech Kozyra e807fc105d [eas-cli] check if package.json is inside git repo (#971)
* [eas-cli] check if package.json is inside git repo

* update CHANGELOG.md

* fix try catch
2022-02-11 14:50:51 +01:00
jkh ae30c4c7db [eas-cli] add tsconfig unused var rules (#961) 2022-02-09 15:50:25 -05:00
jkh 35b9fda122 [eas-cli] import getRuntimeVersionNullabe from config-plugins (#962) 2022-02-09 08:38:00 -05:00
jkh 8d010ad7e8 [eas-cli] remove unnecessary casting (#963) 2022-02-09 08:37:51 -05:00
Expo CI d7181478c8 update CHANGELOG.md 2022-02-08 11:15:55 +00:00
Dominik Sokal 70ed1a482a v0.47.0 2022-02-08 12:05:54 +01:00
Dominik Sokal 920e5ee8a2 upgrade deps (#946)
* upgrade deps

* update CHANGELOG.md
2022-02-08 11:42:25 +01:00
Dominik Sokal f334f2c019 update CHANGELOG.md 2022-02-08 11:31:33 +01:00
jkh b145a7d98c [eas-cli] assert expo-updates is installed before a publish (#953) 2022-02-07 10:06:01 -05:00
jkh 3c750b60c0 [eas-cli] update error message to new publish command (#952) 2022-02-03 10:44:09 -05:00
jkh b3a9f1af70 [eas-cli] return an informative error if rollout channel dne (#930) 2022-01-28 11:18:34 -05:00
jkh 39d8ab65d1 [eas-cli] fix get branchByNameAsync typing (#929) 2022-01-26 11:23:26 -05:00
Expo CI 1ff2274d8d update CHANGELOG.md 2022-01-26 09:43:42 +00:00
Dominik Sokal 5ed4b65133 v0.46.0 2022-01-26 10:33:41 +01:00
Dominik Sokal 10aca5208f fix url placeholder for iOS submits (#941)
* fix url placeholder for iOS submits

* update CHANGELOG.md
2022-01-25 15:26:20 +01:00
dependabot[bot] b2da80d5ea Bump node-fetch from 2.6.1 to 2.6.7 (#940)
Bumps [node-fetch](https://github.com/node-fetch/node-fetch) from 2.6.1 to 2.6.7.
- [Release notes](https://github.com/node-fetch/node-fetch/releases)
- [Commits](https://github.com/node-fetch/node-fetch/compare/v2.6.1...v2.6.7)

---
updated-dependencies:
- dependency-name: node-fetch
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <[email protected]>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-25 15:21:45 +01:00
Dominik Sokal b9457d71f9 upgrade deps (#939)
* upgrade deps

* update CHANGELOG.md
2022-01-25 14:48:02 +01:00
Dominik Sokalandjkh 5fd3149a95 unify command descriptions (#925)
* unify command descriptions

* fix lint warnings

* Apply suggestions from code review

Co-authored-by: jkh <[email protected]>

* address PR feedback

* update CHANGELOG.md

Co-authored-by: jkh <[email protected]>
2022-01-21 12:13:40 +01:00
dependabot[bot] 5f83724833 Bump trim-off-newlines from 1.0.1 to 1.0.3 (#923)
Bumps [trim-off-newlines](https://github.com/stevemao/trim-off-newlines) from 1.0.1 to 1.0.3.
- [Release notes](https://github.com/stevemao/trim-off-newlines/releases)
- [Commits](https://github.com/stevemao/trim-off-newlines/compare/v1.0.1...v1.0.3)

---
updated-dependencies:
- dependency-name: trim-off-newlines
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <[email protected]>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2022-01-20 09:56:09 +01:00
Expo CI 7df558d713 update CHANGELOG.md 2022-01-19 15:50:30 +00:00
100 changed files with 4164 additions and 3622 deletions

No files matched your search

-4
View File
@@ -26,10 +26,6 @@ module.exports = {
name: 'lodash',
message: "Don't use lodash, it's heavy!",
},
{
name: 'node-fetch',
message: 'Use got instead, node-fetch is used only for the GraphQL client.',
},
],
},
],
+1 -1
View File
@@ -37,7 +37,7 @@ body:
required: true
attributes:
label: Environment
description: Run `eas diagnostics` and paste the output here.
description: Run `npx expo-env-info` and paste the output here.
- type: textarea
validations:
required: false
+69 -2
View File
@@ -8,11 +8,78 @@ This is the log of notable changes to EAS CLI and related packages.
### 🎉 New features
- Add json output for started builds when using `--no-wait`. ([#921](https://github.com/expo/eas-cli/pull/921) by [@kbrandwijk](https://github.com/kbrandwijk))
- Add support to `eas build` for specifying a custom `prebuildCommand` in `eas.json`. ([#919](https://github.com/expo/eas-cli/pull/919) by [@kbrandwijk](https://github.com/kbrandwijk))
- Add proxy support. ([#1005](https://github.com/expo/eas-cli/pull/1005) by [@wkozyra95](https://github.com/wkozyra95))
### 🐛 Bug fixes
- Do not retry build requests. ([#1024](https://github.com/expo/eas-cli/pull/1024) by [@wkozyra95](https://github.com/wkozyra95))
### 🧹 Chores
## [0.48.1](https://github.com/expo/eas-cli/releases/tag/v0.48.1) - 2022-03-15
### 🐛 Bug fixes
- Fix code signing error when not yet configured. ([#1018](https://github.com/expo/eas-cli/pull/1018) by [@wschurman](https://github.com/wschurman))
- Fix link to build details page to use `project.slug`. ([#1021](https://github.com/expo/eas-cli/pull/1021) by [@giautm](https://github.com/giautm))
### 🧹 Chores
- Improve apple login prompt for internal distribution builds. ([#1016](https://github.com/expo/eas-cli/pull/1016) by [@wkozyra95](https://github.com/wkozyra95))
## [0.48.0](https://github.com/expo/eas-cli/releases/tag/v0.48.0) - 2022-03-14
### 🎉 New features
- Add code signing. ([#964](https://github.com/expo/eas-cli/pull/964) by [@wschurman](https://github.com/wschurman))
- Install expo-updates when running update:configure. ([#977](https://github.com/expo/eas-cli/pull/977) by [@jkhales](https://github.com/jkhales))
- Make `update:configure` work on native files. ([#978](https://github.com/expo/eas-cli/pull/978) by [@jkhales](https://github.com/jkhales))
### 🐛 Bug fixes
- Fix `"Unknown status"` error when a build is canceled. ([#1012](https://github.com/expo/eas-cli/pull/1012) by [@wkozyra95](https://github.com/wkozyra95))
### 🧹 Chores
- Add error message when package.json is outside git repository. ([#971](https://github.com/expo/eas-cli/pull/971) by [@wkozyra95](https://github.com/wkozyra95))
- Make runtime version policy warning on the update command more descriptive. ([#979](https://github.com/expo/eas-cli/pull/979) by [@kbrandwijk](https://github.com/kbrandwijk))
- Remove unused flag. ([#995](https://github.com/expo/eas-cli/pull/995) by [@wkozyra95](https://github.com/wkozyra95))
- Replace `got` with `node-fetch`. ([#1000](https://github.com/expo/eas-cli/pull/1000) by [@wkozyra95](https://github.com/wkozyra95))
- Upgrade dependencies. ([#1015](https://github.com/expo/eas-cli/pull/1015) by [@dsokal](https://github.com/dsokal))
## [0.47.0](https://github.com/expo/eas-cli/releases/tag/v0.47.0) - 2022-02-08
### 🐛 Bug fixes
- Return informative error when running `eas channel:rollout` with a channel that does not exist. ([#930](https://github.com/expo/eas-cli/pull/930) by [@jkhales](https://github.com/jkhales))
- Check if `expo-updates` is installed before publish. ([#953](https://github.com/expo/eas-cli/pull/953) by [@jkhales](https://github.com/jkhales))
### 🧹 Chores
- Upgrade dependencies. ([#946](https://github.com/expo/eas-cli/pull/946) by [@dsokal](https://github.com/dsokal))
## [0.46.0](https://github.com/expo/eas-cli/releases/tag/v0.46.0) - 2022-01-26
### 🛠 Breaking changes
- Drop support for building iOS builds on macOS Catalina. ([#939](https://github.com/expo/eas-cli/pull/939) by [@dsokal](https://github.com/dsokal))
### 🐛 Bug fixes
- Fix URL placeholder for iOS submits. ([#941](https://github.com/expo/eas-cli/pull/941) by [@dsokal](https://github.com/dsokal))
### 🧹 Chores
- Unify EAS command descriptions style. ([#925](https://github.com/expo/eas-cli/pull/925) by [@dsokal](https://github.com/dsokal))
- Upgrade dependencies. ([#939](https://github.com/expo/eas-cli/pull/939) by [@dsokal](https://github.com/dsokal))
## [0.45.1](https://github.com/expo/eas-cli/releases/tag/v0.45.1) - 2022-01-19
### 🎉 New features
- Add json output for started builds when using `--no-wait`. ([#921](https://github.com/expo/eas-cli/pull/921) by [@kbrandwijk](https://github.com/kbrandwijk))
- Add support to `eas build` for specifying a custom `prebuildCommand` in `eas.json`. ([#919](https://github.com/expo/eas-cli/pull/919) by [@kbrandwijk](https://github.com/kbrandwijk))
### 🧹 Chores
- Add macOS Monterey image. ([#922](https://github.com/expo/eas-cli/pull/922) by [@wkozyra95](https://github.com/wkozyra95))
+1 -1
View File
@@ -1,5 +1,5 @@
{
"npmClient": "yarn",
"useWorkspaces": true,
"version": "0.45.1"
"version": "0.48.2"
}
+5 -5
View File
@@ -17,19 +17,19 @@
"clean": "lerna run clean && rm -rf node_modules coverage"
},
"devDependencies": {
"@types/jest": "27.4.0",
"@types/jest": "27.4.1",
"@types/node": "16.7.8",
"eslint": "8.7.0",
"eslint": "8.11.0",
"eslint-config-universe": "10.0.0",
"eslint-plugin-async-protect": "1.1.0",
"eslint-plugin-node": "11.1.0",
"jest": "27.4.7",
"jest": "27.5.1",
"jest-watch-typeahead": "1.0.0",
"lerna": "4.0.0",
"oclif": "2.2.0",
"oclif": "2.5.0",
"prettier": "2.5.1",
"ts-jest": "27.1.3",
"typescript": "4.5.4"
"typescript": "4.6.2"
},
"volta": {
"node": "16.10.0",
+117 -117
View File
@@ -93,7 +93,7 @@ ALIASES
$ eas login
```
_See code: [src/commands/account/login.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/account/login.ts)_
_See code: [src/commands/account/login.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/account/login.ts)_
## `eas account:logout`
@@ -110,7 +110,7 @@ ALIASES
$ eas logout
```
_See code: [src/commands/account/logout.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/account/logout.ts)_
_See code: [src/commands/account/logout.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/account/logout.ts)_
## `eas account:view`
@@ -127,21 +127,21 @@ ALIASES
$ eas whoami
```
_See code: [src/commands/account/view.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/account/view.ts)_
_See code: [src/commands/account/view.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/account/view.ts)_
## `eas analytics [STATUS]`
view or change analytics settings
display or change analytics settings
```
USAGE
$ eas analytics [STATUS]
DESCRIPTION
view or change analytics settings
display or change analytics settings
```
_See code: [src/commands/analytics.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/analytics.ts)_
_See code: [src/commands/analytics.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/analytics.ts)_
## `eas autocomplete [SHELL]`
@@ -170,11 +170,11 @@ EXAMPLES
$ eas autocomplete --refresh-cache
```
_See code: [@oclif/plugin-autocomplete](https://github.com/oclif/plugin-autocomplete/blob/v1.1.1/src/commands/autocomplete/index.ts)_
_See code: [@oclif/plugin-autocomplete](https://github.com/oclif/plugin-autocomplete/blob/v1.2.0/src/commands/autocomplete/index.ts)_
## `eas branch:create [NAME]`
Create a branch on the current project.
create a branch
```
USAGE
@@ -187,14 +187,14 @@ FLAGS
--json return a json with the new branch ID and name.
DESCRIPTION
Create a branch on the current project.
create a branch
```
_See code: [src/commands/branch/create.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/branch/create.ts)_
_See code: [src/commands/branch/create.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/branch/create.ts)_
## `eas branch:delete [NAME]`
Delete a branch on the current project
delete a branch
```
USAGE
@@ -207,14 +207,14 @@ FLAGS
--json return JSON with the edited branch's ID and name.
DESCRIPTION
Delete a branch on the current project
delete a branch
```
_See code: [src/commands/branch/delete.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/branch/delete.ts)_
_See code: [src/commands/branch/delete.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/branch/delete.ts)_
## `eas branch:list`
List all branches on this project.
list all branches
```
USAGE
@@ -224,14 +224,14 @@ FLAGS
--json return output as JSON
DESCRIPTION
List all branches on this project.
list all branches
```
_See code: [src/commands/branch/list.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/branch/list.ts)_
_See code: [src/commands/branch/list.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/branch/list.ts)_
## `eas branch:rename`
Rename a branch.
rename a branch
```
USAGE
@@ -243,14 +243,14 @@ FLAGS
--to=<value> new name of the branch.
DESCRIPTION
Rename a branch.
rename a branch
```
_See code: [src/commands/branch/rename.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/branch/rename.ts)_
_See code: [src/commands/branch/rename.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/branch/rename.ts)_
## `eas branch:view [NAME]`
View a branch.
view a branch
```
USAGE
@@ -263,20 +263,19 @@ FLAGS
--json return a json with the branch's ID name and recent update groups.
DESCRIPTION
View a branch.
view a branch
```
_See code: [src/commands/branch/view.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/branch/view.ts)_
_See code: [src/commands/branch/view.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/branch/view.ts)_
## `eas build`
Start a build
start a build
```
USAGE
$ eas build [-p android|ios|all] [--json] [--skip-project-configuration] [--profile <value>]
[--non-interactive] [--local] [--output <value>] [--wait] [--clear-cache] [--auto-submit |
--auto-submit-with-profile <value>]
$ eas build [-p android|ios|all] [--json] [--profile <value>] [--non-interactive] [--local] [--output
<value>] [--wait] [--clear-cache] [--auto-submit | --auto-submit-with-profile <value>]
FLAGS
-p, --platform=(android|ios|all)
@@ -290,32 +289,31 @@ FLAGS
--output=<value> Output path for local build
--profile=PROFILE_NAME Name of the build profile from eas.json. Defaults to "production" if defined
in eas.json.
--skip-project-configuration Skip project configuration
--[no-]wait Wait for build(s) to complete
DESCRIPTION
Start a build
start a build
```
_See code: [src/commands/build/index.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/build/index.ts)_
_See code: [src/commands/build/index.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/build/index.ts)_
## `eas build:cancel [BUILD_ID]`
Cancel a build.
cancel a build
```
USAGE
$ eas build:cancel [BUILD_ID]
DESCRIPTION
Cancel a build.
cancel a build
```
_See code: [src/commands/build/cancel.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/build/cancel.ts)_
_See code: [src/commands/build/cancel.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/build/cancel.ts)_
## `eas build:configure`
Configure the project to support EAS Build.
configure the project to support EAS Build
```
USAGE
@@ -325,14 +323,14 @@ FLAGS
-p, --platform=(android|ios|all) Platform to configure
DESCRIPTION
Configure the project to support EAS Build.
configure the project to support EAS Build
```
_See code: [src/commands/build/configure.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/build/configure.ts)_
_See code: [src/commands/build/configure.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/build/configure.ts)_
## `eas build:inspect`
Inspect the state of the project at specific build stages. Useful for troubleshooting.
inspect the state of the project at specific build stages, useful for troubleshooting
```
USAGE
@@ -360,10 +358,10 @@ FLAGS
Name of the build profile from eas.json. Defaults to "production" if defined in eas.json.
DESCRIPTION
Inspect the state of the project at specific build stages. Useful for troubleshooting.
inspect the state of the project at specific build stages, useful for troubleshooting
```
_See code: [src/commands/build/inspect.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/build/inspect.ts)_
_See code: [src/commands/build/inspect.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/build/inspect.ts)_
## `eas build:list`
@@ -396,7 +394,7 @@ DESCRIPTION
list all builds for your project
```
_See code: [src/commands/build/list.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/build/list.ts)_
_See code: [src/commands/build/list.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/build/list.ts)_
## `eas build:view [BUILD_ID]`
@@ -413,11 +411,11 @@ DESCRIPTION
view a build for your project
```
_See code: [src/commands/build/view.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/build/view.ts)_
_See code: [src/commands/build/view.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/build/view.ts)_
## `eas channel:create [NAME]`
Create a channel on the current project.
create a channel
```
USAGE
@@ -430,14 +428,14 @@ FLAGS
--json print output as a JSON object with the new channel ID, name and branch mapping.
DESCRIPTION
Create a channel on the current project.
create a channel
```
_See code: [src/commands/channel/create.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/channel/create.ts)_
_See code: [src/commands/channel/create.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/channel/create.ts)_
## `eas channel:edit [NAME]`
Point a channel at a new branch.
point a channel at a new branch
```
USAGE
@@ -448,17 +446,17 @@ ARGUMENTS
FLAGS
--branch=<value> Name of the branch to point to
--json print output as a JSON object with the channel ID, name and branch mapping.
--json Print output as a JSON object with the channel ID, name and branch mapping
DESCRIPTION
Point a channel at a new branch.
point a channel at a new branch
```
_See code: [src/commands/channel/edit.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/channel/edit.ts)_
_See code: [src/commands/channel/edit.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/channel/edit.ts)_
## `eas channel:list`
List all channels on the current project.
list all channels
```
USAGE
@@ -468,14 +466,14 @@ FLAGS
--json print output as a JSON object with the channel ID, name and branch mapping.
DESCRIPTION
List all channels on the current project.
list all channels
```
_See code: [src/commands/channel/list.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/channel/list.ts)_
_See code: [src/commands/channel/list.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/channel/list.ts)_
## `eas channel:view [NAME]`
View a channel on the current project.
view a channel
```
USAGE
@@ -488,14 +486,14 @@ FLAGS
--json print output as a JSON object with the channel ID, name and branch mapping.
DESCRIPTION
View a channel on the current project.
view a channel
```
_See code: [src/commands/channel/view.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/channel/view.ts)_
_See code: [src/commands/channel/view.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/channel/view.ts)_
## `eas config`
show the eas.json config
display project configuration (app.json + eas.json)
```
USAGE
@@ -506,24 +504,24 @@ FLAGS
--profile=<value>
DESCRIPTION
show the eas.json config
display project configuration (app.json + eas.json)
```
_See code: [src/commands/config.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/config.ts)_
_See code: [src/commands/config.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/config.ts)_
## `eas credentials`
manage your credentials
manage credentials
```
USAGE
$ eas credentials
DESCRIPTION
manage your credentials
manage credentials
```
_See code: [src/commands/credentials.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/credentials.ts)_
_See code: [src/commands/credentials.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/credentials.ts)_
## `eas device:create`
@@ -537,7 +535,7 @@ DESCRIPTION
register new Apple Devices to use for internal distribution
```
_See code: [src/commands/device/create.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/device/create.ts)_
_See code: [src/commands/device/create.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/device/create.ts)_
## `eas device:delete`
@@ -555,7 +553,7 @@ DESCRIPTION
remove a registered device from your account
```
_See code: [src/commands/device/delete.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/device/delete.ts)_
_See code: [src/commands/device/delete.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/device/delete.ts)_
## `eas device:list`
@@ -572,7 +570,7 @@ DESCRIPTION
list all registered devices for your account
```
_See code: [src/commands/device/list.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/device/list.ts)_
_See code: [src/commands/device/list.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/device/list.ts)_
## `eas device:view [UDID]`
@@ -586,21 +584,21 @@ DESCRIPTION
view a device for your project
```
_See code: [src/commands/device/view.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/device/view.ts)_
_See code: [src/commands/device/view.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/device/view.ts)_
## `eas diagnostics`
log environment info to the console
display environment info
```
USAGE
$ eas diagnostics
DESCRIPTION
log environment info to the console
display environment info
```
_See code: [src/commands/diagnostics.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/diagnostics.ts)_
_See code: [src/commands/diagnostics.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/diagnostics.ts)_
## `eas help [COMMAND]`
@@ -620,7 +618,7 @@ DESCRIPTION
Display help for eas.
```
_See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v5.1.10/src/commands/help.ts)_
_See code: [@oclif/plugin-help](https://github.com/oclif/plugin-help/blob/v5.1.12/src/commands/help.ts)_
## `eas project:info`
@@ -634,7 +632,7 @@ DESCRIPTION
information about the current project
```
_See code: [src/commands/project/info.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/project/info.ts)_
_See code: [src/commands/project/info.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/project/info.ts)_
## `eas project:init`
@@ -651,11 +649,11 @@ ALIASES
$ eas init
```
_See code: [src/commands/project/init.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/project/init.ts)_
_See code: [src/commands/project/init.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/project/init.ts)_
## `eas secret:create`
Create an environment secret on the current project or owner account.
create an environment secret on the current project or owner account
```
USAGE
@@ -668,14 +666,14 @@ FLAGS
--value=<value> Value of the secret
DESCRIPTION
Create an environment secret on the current project or owner account.
create an environment secret on the current project or owner account
```
_See code: [src/commands/secret/create.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/secret/create.ts)_
_See code: [src/commands/secret/create.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/secret/create.ts)_
## `eas secret:delete`
Delete an environment secret by ID.
delete an environment secret by ID
```
USAGE
@@ -685,30 +683,28 @@ FLAGS
--id=<value> ID of the secret to delete
DESCRIPTION
Delete an environment secret by ID.
Unsure where to find the secret's ID? Run eas secret:list
delete an environment secret by ID
```
_See code: [src/commands/secret/delete.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/secret/delete.ts)_
_See code: [src/commands/secret/delete.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/secret/delete.ts)_
## `eas secret:list`
Lists environment secrets available for your current app
list environment secrets available for your current app
```
USAGE
$ eas secret:list
DESCRIPTION
Lists environment secrets available for your current app
list environment secrets available for your current app
```
_See code: [src/commands/secret/list.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/secret/list.ts)_
_See code: [src/commands/secret/list.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/secret/list.ts)_
## `eas submit`
Submit build archive to App Store Connect
submit app binary to App Store and/or Play Store
```
USAGE
@@ -728,24 +724,22 @@ FLAGS
--[no-]wait Wait for submission to complete
DESCRIPTION
Submit build archive to App Store Connect
See how to configure submits with eas.json: https://docs.expo.dev/submit/eas-json/
submit app binary to App Store and/or Play Store
ALIASES
$ eas build:submit
```
_See code: [src/commands/submit.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/submit.ts)_
_See code: [src/commands/submit.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/submit.ts)_
## `eas update`
Publish an update group.
publish an update group
```
USAGE
$ eas update [--branch <value>] [--message <value>] [--republish | --input-dir <value> | --skip-bundler]
[--group <value> | | ] [-p android|ios|all] [--json] [--auto]
[--group <value> | | ] [-p android|ios|all] [--json] [--auto] [--private-key-path <value>]
FLAGS
-p, --platform=(android|ios|all) [default: all]
@@ -755,32 +749,38 @@ FLAGS
--input-dir=<value> [default: dist] Location of the bundle
--json Enable JSON output, non-JSON messages will be printed to stderr
--message=<value> A short message describing the update
--private-key-path=<value> 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.
--republish Republish an update group
--skip-bundler Skip running Expo CLI to bundle the app before publishing
DESCRIPTION
Publish an update group.
publish an update group
```
_See code: [src/commands/update/index.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/update/index.ts)_
_See code: [src/commands/update/index.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/update/index.ts)_
## `eas update:configure`
Configure the project to support EAS Update.
configure the project to support EAS Update
```
USAGE
$ eas update:configure
$ eas update:configure [-p android|ios|all]
FLAGS
-p, --platform=(android|ios|all) [default: all] Platform to configure
DESCRIPTION
Configure the project to support EAS Update.
configure the project to support EAS Update
```
_See code: [src/commands/update/configure.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/update/configure.ts)_
_See code: [src/commands/update/configure.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/update/configure.ts)_
## `eas update:delete GROUPID`
Delete all the updates in an update Group.
delete all the updates in an update group
```
USAGE
@@ -793,14 +793,14 @@ FLAGS
--json Return a json with the group ID of the deleted updates.
DESCRIPTION
Delete all the updates in an update Group.
delete all the updates in an update group
```
_See code: [src/commands/update/delete.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/update/delete.ts)_
_See code: [src/commands/update/delete.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/update/delete.ts)_
## `eas update:list`
View the recent updates for a branch
view the recent updates for a branch
```
USAGE
@@ -812,14 +812,14 @@ FLAGS
--json Return a json with all of the recent update groups.
DESCRIPTION
View the recent updates for a branch
view the recent updates for a branch
```
_See code: [src/commands/update/list.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/update/list.ts)_
_See code: [src/commands/update/list.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/update/list.ts)_
## `eas update:view GROUPID`
Update group details.
update group details
```
USAGE
@@ -832,14 +832,14 @@ FLAGS
--json Return a json with the updates belonging to the group.
DESCRIPTION
Update group details.
update group details
```
_See code: [src/commands/update/view.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/update/view.ts)_
_See code: [src/commands/update/view.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/update/view.ts)_
## `eas webhook:create`
Create a webhook on the current project.
create a webhook
```
USAGE
@@ -852,14 +852,14 @@ FLAGS
--url=<value> Webhook URL
DESCRIPTION
Create a webhook on the current project.
create a webhook
```
_See code: [src/commands/webhook/create.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/webhook/create.ts)_
_See code: [src/commands/webhook/create.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/webhook/create.ts)_
## `eas webhook:delete [ID]`
Delete a webhook on the current project.
delete a webhook
```
USAGE
@@ -869,14 +869,14 @@ ARGUMENTS
ID ID of the webhook to delete
DESCRIPTION
Delete a webhook on the current project.
delete a webhook
```
_See code: [src/commands/webhook/delete.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/webhook/delete.ts)_
_See code: [src/commands/webhook/delete.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/webhook/delete.ts)_
## `eas webhook:list`
List webhooks on the current project.
list webhooks
```
USAGE
@@ -886,14 +886,14 @@ FLAGS
--event=(BUILD|SUBMIT) Event type that triggers the webhook
DESCRIPTION
List webhooks on the current project.
list webhooks
```
_See code: [src/commands/webhook/list.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/webhook/list.ts)_
_See code: [src/commands/webhook/list.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/webhook/list.ts)_
## `eas webhook:update`
Update a webhook on the current project.
update a webhook
```
USAGE
@@ -907,14 +907,14 @@ FLAGS
--url=<value> Webhook URL
DESCRIPTION
Update a webhook on the current project.
update a webhook
```
_See code: [src/commands/webhook/update.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/webhook/update.ts)_
_See code: [src/commands/webhook/update.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/webhook/update.ts)_
## `eas webhook:view ID`
View a webhook on the current project.
view a webhook
```
USAGE
@@ -924,8 +924,8 @@ ARGUMENTS
ID ID of the webhook to view
DESCRIPTION
View a webhook on the current project.
view a webhook
```
_See code: [src/commands/webhook/view.ts](https://github.com/expo/eas-cli/blob/v0.45.1/packages/eas-cli/src/commands/webhook/view.ts)_
_See code: [src/commands/webhook/view.ts](https://github.com/expo/eas-cli/blob/v0.48.2/packages/eas-cli/src/commands/webhook/view.ts)_
<!-- commandsstop -->
+563 -184
View File
File diff suppressed because it is too large. Load diff
+43 -33
View File
@@ -1,56 +1,60 @@
{
"name": "eas-cli",
"description": "EAS command line tool",
"version": "0.45.1",
"version": "0.48.2",
"author": "Expo <[email protected]>",
"bin": {
"eas": "./bin/run"
},
"bugs": "https://github.com/expo/eas-cli/issues",
"dependencies": {
"@expo/apple-utils": "0.0.0-alpha.27",
"@expo/config": "6.0.16",
"@expo/config-plugins": "4.0.16",
"@expo/eas-build-job": "0.2.64",
"@expo/eas-json": "0.45.1",
"@expo/apple-utils": "0.0.0-alpha.28",
"@expo/code-signing-certificates": "0.0.2",
"@expo/config": "6.0.19",
"@expo/config-plugins": "4.1.0",
"@expo/config-types": "44.0.0",
"@expo/eas-build-job": "0.2.66",
"@expo/eas-json": "0.48.0",
"@expo/json-file": "8.2.34",
"@expo/pkcs12": "0.0.6",
"@expo/pkcs12": "0.0.7",
"@expo/plist": "0.0.17",
"@expo/plugin-warn-if-update-available": "2.0.4",
"@expo/prebuild-config": "3.0.16",
"@expo/plugin-warn-if-update-available": "2.1.0",
"@expo/prebuild-config": "3.1.0",
"@expo/results": "1.0.0",
"@expo/rudder-sdk-node": "1.1.1",
"@expo/spawn-async": "1.5.0",
"@expo/spawn-async": "1.6.0",
"@expo/timeago.js": "1.0.0",
"@oclif/core": "1.1.2",
"@oclif/plugin-autocomplete": "1.1.1",
"@oclif/plugin-help": "5.1.10",
"@urql/core": "2.3.6",
"@oclif/core": "1.5.3",
"@oclif/plugin-autocomplete": "1.2.0",
"@oclif/plugin-help": "5.1.12",
"@urql/core": "2.4.3",
"@urql/exchange-retry": "0.3.2",
"chalk": "4.1.2",
"cli-table3": "0.6.1",
"dateformat": "4.6.3",
"dicer": "0.3.1",
"env-paths": "2.2.0",
"envinfo": "7.8.1",
"fast-deep-equal": "3.1.3",
"fast-glob": "3.2.11",
"figures": "3.2.0",
"form-data": "4.0.0",
"fs-extra": "10.0.0",
"fs-extra": "10.0.1",
"getenv": "1.0.0",
"got": "11.8.2",
"gradle-to-js": "2.0.0",
"graphql": "16.2.0",
"graphql": "16.3.0",
"graphql-tag": "2.12.6",
"https-proxy-agent": "5.0.0",
"ignore": "5.2.0",
"indent-string": "4.0.0",
"jks-js": "1.0.1",
"joi": "17.5.0",
"jks-js": "1.0.2",
"joi": "17.6.0",
"keychain": "1.3.0",
"log-symbols": "4.1.0",
"mime": "3.0.0",
"minimatch": "3.0.4",
"nanoid": "3.2.0",
"node-fetch": "2.6.1",
"minimatch": "3.0.5",
"nanoid": "3.3.1",
"node-fetch": "2.6.7",
"node-forge": "1.2.1",
"nullthrows": "1.1.1",
"ora": "5.1.0",
@@ -61,6 +65,7 @@
"semver": "7.3.5",
"slash": "3.0.0",
"strip-ansi": "6.0.0",
"structured-headers": "0.4.1",
"tar": "6.1.11",
"terminal-link": "2.1.1",
"tslib": "2.3.1",
@@ -70,31 +75,33 @@
"wrap-ansi": "7.0.0"
},
"devDependencies": {
"@graphql-codegen/cli": "2.3.1",
"@graphql-codegen/cli": "2.6.2",
"@graphql-codegen/introspection": "2.1.1",
"@graphql-codegen/typescript": "2.4.2",
"@graphql-codegen/typescript-operations": "2.2.2",
"@graphql-codegen/typescript": "2.4.7",
"@graphql-codegen/typescript-operations": "2.3.4",
"@types/dateformat": "3.0.1",
"@types/dicer": "0.2.2",
"@types/envinfo": "7.8.1",
"@types/fs-extra": "9.0.13",
"@types/getenv": "^1.0.0",
"@types/mime": "2.0.3",
"@types/node-fetch": "^2.5.7",
"@types/node-forge": "1.0.0",
"@types/node-forge": "1.0.1",
"@types/prompts": "2.0.14",
"@types/semver": "7.3.9",
"@types/tar": "6.1.1",
"@types/tough-cookie": "4.0.1",
"@types/uuid": "8.3.4",
"@types/wrap-ansi": "3.0.0",
"axios": "0.24.0",
"axios": "0.26.1",
"eslint-plugin-graphql": "4.0.0",
"form-data": "4.0.0",
"memfs": "3.4.1",
"mockdate": "3.0.5",
"nock": "13.2.2",
"nock": "13.2.4",
"tempy": "0.7.0",
"ts-deepmerge": "1.1.0",
"typescript": "4.5.4"
"ts-deepmerge": "2.0.1",
"typescript": "4.6.2"
},
"engines": {
"node": ">=12.0.0"
@@ -121,7 +128,10 @@
],
"topics": {
"account": {
"description": "manage your account"
"description": "manage account"
},
"branch": {
"description": "manage update branches"
},
"build": {
"description": "build app binaries"
@@ -130,10 +140,10 @@
"description": "manage update channels"
},
"device": {
"description": "manage your Apple devices for internal distribution"
"description": "manage Apple devices for Internal Distribution"
},
"project": {
"description": "manage your project"
"description": "manage project"
},
"release": {
"description": "manage update releases"
-27
View File
@@ -1,27 +0,0 @@
import { JSONValue } from '@expo/json-file';
import { HTTPError, RequestError } from 'got/dist/source';
export default class ApiV2Error extends RequestError {
readonly name = 'ApiV2Error';
readonly expoApiV2ErrorCode: string;
readonly expoApiV2ErrorDetails?: JSONValue;
readonly expoApiV2ErrorServerStack?: string;
readonly expoApiV2ErrorMetadata?: object;
constructor(
originalError: HTTPError,
response: {
message: string;
code: string;
stack?: string;
details?: JSONValue;
metadata?: object;
}
) {
super(response.message, originalError, originalError.request);
this.expoApiV2ErrorCode = response.code;
this.expoApiV2ErrorDetails = response.details;
this.expoApiV2ErrorServerStack = response.stack;
this.expoApiV2ErrorMetadata = response.metadata;
}
}
+4 -6
View File
@@ -1,9 +1,7 @@
import assert from 'assert';
import { RequestError } from 'got/dist/source';
import nock from 'nock';
import ApiV2Error from '../ApiV2Error';
import { apiClient, getExpoApiBaseUrl } from '../api';
import { ApiV2Error, api, getExpoApiBaseUrl } from '../api';
describe('apiClient', () => {
it('converts Expo APIv2 error to ApiV2Error', async () => {
@@ -23,7 +21,7 @@ describe('apiClient', () => {
let error: Error | null = null;
try {
await apiClient.post('test');
await api.postAsync('test', { body: {} });
} catch (e: any) {
error = e;
}
@@ -43,11 +41,11 @@ describe('apiClient', () => {
let error: Error | null = null;
try {
await apiClient.post('test');
await api.postAsync('test', { body: {} });
} catch (e: any) {
error = e;
}
expect(error).toBeInstanceOf(RequestError);
expect(error).not.toBeNull();
expect(error).not.toBeInstanceOf(ApiV2Error);
});
});
+87 -35
View File
@@ -1,42 +1,94 @@
import got, { HTTPError, NormalizedOptions, RequestError } from 'got';
import { JSONValue } from '@expo/json-file';
import ApiV2Error from './ApiV2Error';
import fetch, { RequestError, RequestInit } from './fetch';
import { getAccessToken, getSessionSecret } from './user/sessionStorage';
export const apiClient = got.extend({
prefixUrl: getExpoApiBaseUrl() + '/v2/',
hooks: {
beforeRequest: [
(options: NormalizedOptions) => {
const token = getAccessToken();
if (token) {
options.headers.authorization = `Bearer ${token}`;
return;
}
const sessionSecret = getSessionSecret();
if (sessionSecret) {
options.headers['expo-session'] = sessionSecret;
}
},
],
beforeError: [
(error: RequestError): RequestError => {
if (error instanceof HTTPError) {
let result: { [key: string]: any };
try {
result = JSON.parse(error.response.body as string);
} catch (e2) {
return error;
}
if (result.errors?.length) {
return new ApiV2Error(error, result.errors[0]);
}
}
return error;
},
],
export class ApiV2Error extends Error {
readonly name = 'ApiV2Error';
readonly expoApiV2ErrorCode: string;
readonly expoApiV2ErrorDetails?: JSONValue;
readonly expoApiV2ErrorServerStack?: string;
readonly expoApiV2ErrorMetadata?: object;
constructor(response: {
message: string;
code: string;
stack?: string;
details?: JSONValue;
metadata?: object;
}) {
super(response.message);
this.expoApiV2ErrorCode = response.code;
this.expoApiV2ErrorDetails = response.details;
this.expoApiV2ErrorServerStack = response.stack;
this.expoApiV2ErrorMetadata = response.metadata;
}
}
interface RequestOptions {
body: JSONValue;
}
export const api = {
async putAsync(path: string, options: RequestOptions): Promise<any> {
return await requestAsync(path, { method: 'PUT', body: JSON.stringify(options.body) });
},
});
async postAsync(path: string, options: RequestOptions): Promise<any> {
return await requestAsync(path, { method: 'POST', body: JSON.stringify(options.body) });
},
async deleteAsync(path: string): Promise<any> {
return await requestAsync(path, { method: 'DELETE' });
},
async getAsync(path: string): Promise<any> {
return await requestAsync(path, { method: 'GET' });
},
};
async function requestAsync(path: string, options: RequestInit): Promise<any> {
try {
const response = await fetch(`${getExpoApiBaseUrl()}/v2/${path}`, {
...options,
headers: {
'Content-Type': 'application/json',
...getAuthHeaders(),
},
});
return await response.json();
} catch (err) {
await handleApiErrorAsync(err);
}
}
async function handleApiErrorAsync(err: any): Promise<void> {
if (err instanceof RequestError) {
let result: { [key: string]: any };
try {
result = (await err.response.json()) as { [key: string]: any };
} catch {
throw new Error(`Malformed api response: ${await err.response.text()}`);
}
if (result.errors?.length) {
throw new ApiV2Error(result.errors[0]);
}
} else {
throw err;
}
}
function getAuthHeaders(): Record<string, string> {
const token = getAccessToken();
if (token) {
return { authorization: `Bearer ${token}` };
}
const sessionSecret = getSessionSecret();
if (sessionSecret) {
return { 'expo-session': sessionSecret };
}
return {};
}
export function getExpoApiBaseUrl(): string {
if (process.env.EXPO_STAGING) {
@@ -7,9 +7,9 @@ import fs from 'fs-extra';
import path from 'path';
import Log from '../../log';
import { isExpoUpdatesInstalled } from '../../project/projectUtils';
import { resolveWorkflowAsync } from '../../project/workflow';
import { isExpoUpdatesInstalled } from '../utils/updates';
import { syncUpdatesConfigurationAsync } from './UpdatesModule';
import { syncUpdatesConfigurationAsync } from '../../update/android/UpdatesModule';
import { BumpStrategy, bumpVersionAsync, bumpVersionInAppJsonAsync } from './version';
export async function syncProjectConfigurationAsync({
+2 -1
View File
@@ -287,7 +287,8 @@ export async function waitForBuildEndAsync(
const errored = builds.filter(build => build?.status === BuildStatus.Errored).length;
const finished = builds.filter(build => build?.status === BuildStatus.Finished).length;
const canceled = builds.filter(build => build?.status === BuildStatus.Canceled).length;
const unknown = builds.length - newBuilds - inQueue - inProgress - errored - finished;
const unknown =
builds.length - newBuilds - inQueue - inProgress - errored - finished - canceled;
spinner.text = [
newBuilds && `Builds created: ${newBuilds}`,
inQueue && `Builds in queue: ${inQueue}`,
@@ -3,9 +3,9 @@ import { Platform, Workflow } from '@expo/eas-build-job';
import { BuildProfile, IosVersionAutoIncrement } from '@expo/eas-json';
import type { XCBuildConfiguration } from 'xcode';
import { isExpoUpdatesInstalled } from '../../project/projectUtils';
import { resolveWorkflowAsync } from '../../project/workflow';
import { isExpoUpdatesInstalled } from '../utils/updates';
import { syncUpdatesConfigurationAsync } from './UpdatesModule';
import { syncUpdatesConfigurationAsync } from '../../update/ios/UpdatesModule';
import { BumpStrategy, bumpVersionAsync, bumpVersionInAppJsonAsync } from './version';
export async function syncProjectConfigurationAsync({
+1 -1
View File
@@ -6,7 +6,7 @@ import semver from 'semver';
import { ora } from '../ora';
const PLUGIN_PACKAGE_NAME = 'eas-cli-local-build-plugin';
const PLUGIN_PACKAGE_VERSION = '0.0.62';
const PLUGIN_PACKAGE_VERSION = '0.0.67';
export interface LocalBuildOptions {
enable: boolean;
+9 -22
View File
@@ -5,34 +5,21 @@ import fs from 'fs-extra';
import resolveFrom from 'resolve-from';
import Log from '../log';
import { getUsername } from '../project/projectUtils';
import { ensureLoggedInAsync } from '../user/actions';
import { easCliVersion } from '../utils/easCli';
import { getVcsClient } from '../vcs';
import { getUsername, isExpoUpdatesInstalled } from '../project/projectUtils';
import {
readChannelSafelyAsync as readAndroidChannelSafelyAsync,
readReleaseChannelSafelyAsync as readAndroidReleaseChannelSafelyAsync,
} from './android/UpdatesModule';
import { maybeResolveVersionsAsync as maybeResolveAndroidVersionsAsync } from './android/version';
import { BuildContext } from './context';
} from '../update/android/UpdatesModule';
import {
readChannelSafelyAsync as readIosChannelSafelyAsync,
readReleaseChannelSafelyAsync as readIosReleaseChannelSafelyAsync,
} from './ios/UpdatesModule';
} from '../update/ios/UpdatesModule';
import { ensureLoggedInAsync } from '../user/actions';
import { easCliVersion } from '../utils/easCli';
import { getVcsClient } from '../vcs';
import { maybeResolveVersionsAsync as maybeResolveAndroidVersionsAsync } from './android/version';
import { BuildContext } from './context';
import { maybeResolveVersionsAsync as maybeResolveIosVersionsAsync } from './ios/version';
import { isExpoUpdatesInstalled } from './utils/updates';
// TODO(JJ): Replace this with the getRuntimeVersionNullable function in @expo/config-plugins
function getRuntimeVersionNullable(
...[config, platform]: Parameters<typeof Updates.getRuntimeVersion>
): string | null {
try {
return Updates.getRuntimeVersion(config, platform);
} catch (e) {
Log.debug(e);
return null;
}
}
export async function collectMetadataAsync<T extends Platform>(
ctx: BuildContext<T>
@@ -49,7 +36,7 @@ export async function collectMetadataAsync<T extends Platform>(
workflow: ctx.workflow,
credentialsSource: ctx.buildProfile.credentialsSource,
sdkVersion: ctx.exp.sdkVersion,
runtimeVersion: getRuntimeVersionNullable(ctx.exp, ctx.platform) ?? undefined,
runtimeVersion: Updates.getRuntimeVersionNullable(ctx.exp, ctx.platform) ?? undefined,
reactNativeVersion: await getReactNativeVersionAsync(ctx),
...channelOrReleaseChannel,
distribution,
@@ -1,14 +0,0 @@
import { ExpoConfig, getPackageJson } from '@expo/config';
export function isExpoUpdatesInstalled(projectDir: string): boolean {
const packageJson = getPackageJson(projectDir);
return !!(packageJson.dependencies && 'expo-updates' in packageJson.dependencies);
}
export function ensureValidVersions(exp: ExpoConfig): void {
if (!exp.runtimeVersion && !exp.sdkVersion) {
throw new Error(
"Couldn't find either 'runtimeVersion' or 'sdkVersion' to configure 'expo-updates'. Please specify at least one of these properties under the 'expo' key in 'app.json'"
);
}
}
+11 -7
View File
@@ -4,20 +4,24 @@ import { getExpoApiBaseUrl, getExpoWebsiteBaseUrl } from '../../api';
import { AppPlatform, BuildFragment } from '../../graphql/generated';
export function getProjectDashboardUrl(accountName: string, projectName: string): string {
return `${getExpoWebsiteBaseUrl()}/accounts/${accountName}/projects/${projectName}`;
return new URL(
`/accounts/${accountName}/projects/${projectName}`,
getExpoWebsiteBaseUrl()
).toString();
}
export function getBuildLogsUrl(build: BuildFragment): string {
const { project } = build;
if (project.__typename === 'App') {
return `${getExpoWebsiteBaseUrl()}/accounts/${project.ownerAccount.name}/builds/${build.id}`;
} else {
return `${getExpoWebsiteBaseUrl()}/builds/${build.id}`;
}
const url =
project.__typename !== 'App'
? `/builds/${build.id}`
: `/accounts/${project.ownerAccount.name}/projects/${project.slug}/builds/${build.id}`;
return new URL(url, getExpoWebsiteBaseUrl()).toString();
}
export function getArtifactUrl(artifactId: string): string {
return `${getExpoWebsiteBaseUrl()}/artifacts/${artifactId}`;
return new URL(`/artifacts/${artifactId}`, getExpoWebsiteBaseUrl()).toString();
}
export function getInternalDistributionInstallUrl(build: BuildFragment): string {
+1 -1
View File
@@ -3,7 +3,7 @@ import Log from '../log';
import UserSettings from '../user/UserSettings';
export default class AnalyticsView extends EasCommand {
static description = 'view or change analytics settings';
static description = 'display or change analytics settings';
static args = [{ name: 'STATUS', options: ['on', 'off'] }];
@@ -52,7 +52,7 @@ export async function createUpdateBranchOnAppAsync({
}
export default class BranchCreate extends EasCommand {
static description = 'Create a branch on the current project.';
static description = 'create a branch';
static args = [
{
@@ -77,7 +77,7 @@ async function deleteBranchOnAppAsync({
}
export default class BranchDelete extends EasCommand {
static description = 'Delete a branch on the current project';
static description = 'delete a branch';
static args = [
{
+1 -1
View File
@@ -55,7 +55,7 @@ export async function listBranchesAsync({
}
export default class BranchList extends EasCommand {
static description = 'List all branches on this project.';
static description = 'list all branches';
static flags = {
json: Flags.boolean({
@@ -52,7 +52,7 @@ async function renameUpdateBranchOnAppAsync({
}
export default class BranchRename extends EasCommand {
static description = 'Rename a branch.';
static description = 'rename a branch';
static flags = {
from: Flags.string({
+1 -1
View File
@@ -14,7 +14,7 @@ import formatFields from '../../utils/formatFields';
import { enableJsonOutput, printJsonOnlyOutput } from '../../utils/json';
export default class BranchView extends EasCommand {
static description = 'View a branch.';
static description = 'view a branch';
static args = [
{
@@ -110,7 +110,7 @@ async function ensureBuildExistsAsync(buildId: string): Promise<void> {
}
export default class BuildCancel extends EasCommand {
static description = 'Cancel a build.';
static description = 'cancel a build';
static args = [{ name: 'BUILD_ID' }];
@@ -3,21 +3,20 @@ import { Platform, Workflow } from '@expo/eas-build-job';
import { Flags } from '@oclif/core';
import chalk from 'chalk';
import { syncUpdatesConfigurationAsync as syncAndroidUpdatesConfigurationAsync } from '../../build/android/UpdatesModule';
import { cleanUpOldEasBuildGradleScriptAsync } from '../../build/android/syncProjectConfiguration';
import { ensureProjectConfiguredAsync } from '../../build/configure';
import { syncUpdatesConfigurationAsync as syncIosUpdatesConfigurationAsync } from '../../build/ios/UpdatesModule';
import { isExpoUpdatesInstalled } from '../../build/utils/updates';
import EasCommand from '../../commandUtils/EasCommand';
import Log, { learnMore } from '../../log';
import { RequestedPlatform } from '../../platform';
import { findProjectRootAsync } from '../../project/projectUtils';
import { findProjectRootAsync, isExpoUpdatesInstalled } from '../../project/projectUtils';
import { resolveWorkflowAsync } from '../../project/workflow';
import { promptAsync } from '../../prompts';
import { syncUpdatesConfigurationAsync as syncAndroidUpdatesConfigurationAsync } from '../../update/android/UpdatesModule';
import { syncUpdatesConfigurationAsync as syncIosUpdatesConfigurationAsync } from '../../update/ios/UpdatesModule';
import { getVcsClient } from '../../vcs';
export default class BuildConfigure extends EasCommand {
static description = 'Configure the project to support EAS Build.';
static description = 'configure the project to support EAS Build';
static flags = {
platform: Flags.enum({
+9 -2
View File
@@ -33,7 +33,7 @@ interface RawBuildFlags {
}
export default class Build extends EasCommand {
static description = 'Start a build';
static description = 'start a build';
static flags = {
platform: Flags.enum({
@@ -50,7 +50,7 @@ export default class Build extends EasCommand {
}),
'skip-project-configuration': Flags.boolean({
default: false,
description: 'Skip project configuration',
hidden: true,
}),
profile: Flags.string({
description:
@@ -138,6 +138,13 @@ export default class Build extends EasCommand {
);
Log.newLine();
}
if (flags['skip-project-configuration']) {
Log.warnDeprecatedFlag(
'skip-project-configuration',
'Automatic configuration of native code is no longer optional.'
);
Log.newLine();
}
const profile = flags['profile'];
return {
@@ -26,7 +26,7 @@ const STAGE_DESCRIPTION = `Stage of the build you want to inspect.
export default class BuildInspect extends EasCommand {
static description =
'Inspect the state of the project at specific build stages. Useful for troubleshooting.';
'inspect the state of the project at specific build stages, useful for troubleshooting';
static flags = {
platform: Flags.enum({
@@ -9,10 +9,10 @@ import {
CreateUpdateChannelOnAppMutation,
CreateUpdateChannelOnAppMutationVariables,
} from '../../graphql/generated';
import { BranchQuery } from '../../graphql/queries/BranchQuery';
import Log from '../../log';
import {
findProjectRootAsync,
getBranchByNameAsync,
getProjectFullNameAsync,
getProjectIdAsync,
} from '../../project/projectUtils';
@@ -60,7 +60,7 @@ export async function createUpdateChannelOnAppAsync({
}
export default class ChannelCreate extends EasCommand {
static description = 'Create a channel on the current project.';
static description = 'create a channel';
static args = [
{
@@ -106,14 +106,15 @@ export default class ChannelCreate extends EasCommand {
let branchId: string;
let branchMessage: string;
try {
const existingBranch = await getBranchByNameAsync({
appId: projectId,
name: channelName,
});
const existingBranch = await BranchQuery.getBranchByNameAsync({
appId: projectId,
name: channelName,
});
if (existingBranch) {
branchId = existingBranch.id;
branchMessage = `We found a branch with the same name`;
} catch (e) {
} else {
const newBranch = await createUpdateBranchOnAppAsync({
appId: projectId,
name: channelName,
@@ -22,7 +22,7 @@ import { enableJsonOutput, printJsonOnlyOutput } from '../../utils/json';
export default class ChannelDelete extends EasCommand {
static hidden = true;
static description = 'Delete a channel on the current project';
static description = 'Delete a channel';
static args = [
{
@@ -33,7 +33,7 @@ export default class ChannelDelete extends EasCommand {
];
static flags = {
json: Flags.boolean({
description: `Delete a channel on the current project`,
description: 'print output as a JSON object',
default: false,
}),
'non-interactive': Flags.boolean({
+42 -38
View File
@@ -13,12 +13,9 @@ import {
UpdateChannelBranchMappingMutation,
UpdateChannelBranchMappingMutationVariables,
} from '../../graphql/generated';
import { BranchQuery } from '../../graphql/queries/BranchQuery';
import Log from '../../log';
import {
findProjectRootAsync,
getBranchByNameAsync,
getProjectIdAsync,
} from '../../project/projectUtils';
import { findProjectRootAsync, getProjectIdAsync } from '../../project/projectUtils';
import { promptAsync } from '../../prompts';
import { enableJsonOutput, printJsonOnlyOutput } from '../../utils/json';
@@ -96,7 +93,7 @@ export async function updateChannelBranchMappingAsync({
}
export default class ChannelEdit extends EasCommand {
static description = 'Point a channel at a new branch.';
static description = 'point a channel at a new branch';
static args = [
{
@@ -111,17 +108,14 @@ export default class ChannelEdit extends EasCommand {
description: 'Name of the branch to point to',
}),
json: Flags.boolean({
description: 'print output as a JSON object with the channel ID, name and branch mapping.',
description: 'Print output as a JSON object with the channel ID, name and branch mapping',
default: false,
}),
};
async runAsync(): Promise<void> {
let {
args: { name: channelName },
flags: { branch: branchName, json: jsonFlag },
} = await this.parse(ChannelEdit);
if (jsonFlag) {
const { args, flags } = await this.parse(ChannelEdit);
if (flags.json) {
enableJsonOutput();
}
@@ -129,18 +123,7 @@ export default class ChannelEdit extends EasCommand {
const { exp } = getConfig(projectDir, { skipSDKVersionRequirement: true });
const projectId = await getProjectIdAsync(exp);
if (!channelName) {
const validationMessage = 'A channel name is required to edit a specific channel.';
if (jsonFlag) {
throw new Error(validationMessage);
}
({ name: channelName } = await promptAsync({
type: 'text',
name: 'name',
message: 'Please enter the name of the channel to edit:',
validate: value => (value ? true : validationMessage),
}));
}
const channelName = args.name ?? (await promptForChannelAsync());
const existingChannel = await getChannelByNameForAppAsync({ appId: projectId, channelName });
if (existingChannel.updateBranches.length > 1) {
@@ -149,20 +132,19 @@ export default class ChannelEdit extends EasCommand {
);
}
if (!branchName) {
const validationMessage = 'branch name may not be empty.';
if (jsonFlag) {
throw new Error(validationMessage);
}
({ name: branchName } = await promptAsync({
type: 'text',
name: 'name',
message: chalk`What branch should it change to?`,
validate: value => (value ? true : validationMessage),
}));
}
const branchName = flags.branch ?? (await promptForBranchAsync());
const branch = await getBranchByNameAsync({ appId: projectId, name: branchName! });
const branch = await BranchQuery.getBranchByNameAsync({
appId: projectId,
name: branchName,
});
if (!branch) {
throw new Error(
`Could not find a branch named "${branchName}". Please check what branches exist on this project with ${chalk.bold(
'eas branch:list'
)}.`
);
}
const channel = await updateChannelBranchMappingAsync({
channelId: existingChannel.id,
// todo: move branch mapping logic to utility
@@ -172,7 +154,7 @@ export default class ChannelEdit extends EasCommand {
}),
});
if (jsonFlag) {
if (flags.json) {
printJsonOnlyOutput(channel);
} else {
Log.withTick(
@@ -185,3 +167,25 @@ export default class ChannelEdit extends EasCommand {
}
}
}
async function promptForChannelAsync(): Promise<string> {
Log.addNewLineIfNone();
const { name } = await promptAsync({
type: 'text',
name: 'name',
message: 'Please enter the name of the channel to edit:',
validate: value => (value ? true : 'The channel name may not be empty.'),
});
return name;
}
async function promptForBranchAsync(): Promise<string> {
Log.addNewLineIfNone();
const { name } = await promptAsync({
type: 'text',
name: 'name',
message: `To which branch should the channel link?`,
validate: value => (value ? true : 'The branch name may not be empty.'),
});
return name;
}
@@ -67,7 +67,7 @@ async function getAllUpdateChannelForAppAsync({
}
export default class ChannelList extends EasCommand {
static description = 'List all channels on the current project.';
static description = 'list all channels';
static flags = {
json: Flags.boolean({
@@ -4,17 +4,18 @@ import chalk from 'chalk';
import EasCommand from '../../commandUtils/EasCommand';
import { GetChannelByNameForAppQuery, UpdateBranch } from '../../graphql/generated';
import { BranchQuery } from '../../graphql/queries/BranchQuery';
import { ChannelQuery } from '../../graphql/queries/ChannelQuery';
import Log from '../../log';
import {
findProjectRootAsync,
getBranchByNameAsync,
getProjectFullNameAsync,
getProjectIdAsync,
} from '../../project/projectUtils';
import { promptAsync, selectAsync } from '../../prompts';
import { enableJsonOutput, printJsonOnlyOutput } from '../../utils/json';
import { updateChannelBranchMappingAsync } from './edit';
import { BranchMapping, getBranchMapping, getUpdateChannelByNameForAppAsync } from './view';
import { BranchMapping, getBranchMapping } from './view';
async function promptForRolloutPercentAsync({
promptMessage,
@@ -39,28 +40,20 @@ async function promptForRolloutPercentAsync({
return rolloutPercent;
}
function getRolloutInfo(getUpdateChannelByNameForAppResult: GetChannelByNameForAppQuery): {
function getRolloutInfo(
channel: NonNullable<GetChannelByNameForAppQuery['app']['byId']['updateChannelByName']>
): {
newBranch: Pick<UpdateBranch, 'name' | 'id'>;
oldBranch: Pick<UpdateBranch, 'name' | 'id'>;
currentPercent: number;
} {
const { branchMapping } = getBranchMapping(
getUpdateChannelByNameForAppResult.app?.byId.updateChannelByName?.branchMapping
);
const { branchMapping } = getBranchMapping(channel.branchMapping);
const [newBranchId, oldBranchId] = branchMapping.data.map(d => d.branchId);
const newBranch =
getUpdateChannelByNameForAppResult.app?.byId.updateChannelByName?.updateBranches.filter(
branch => branch.id === newBranchId
)[0];
const oldBranch =
getUpdateChannelByNameForAppResult.app?.byId.updateChannelByName?.updateBranches.filter(
branch => branch.id === oldBranchId
)[0];
const newBranch = channel.updateBranches.filter(branch => branch.id === newBranchId)[0];
const oldBranch = channel.updateBranches.filter(branch => branch.id === oldBranchId)[0];
if (!newBranch || !oldBranch) {
throw new Error(
`Branch mapping rollout is missing a branch for channel "${getUpdateChannelByNameForAppResult.app?.byId.updateChannelByName?.name}".`
);
throw new Error(`Branch mapping rollout is missing a branch for channel "${channel.name}".`);
}
const currentPercent = 100 * branchMapping.data[0].branchMappingLogic.operand;
@@ -75,16 +68,16 @@ async function startRolloutAsync({
projectId,
fullName,
currentBranchMapping,
getUpdateChannelByNameForAppResult,
channel,
}: {
channelName?: string;
branchName?: string;
branchName: string;
percent?: number;
jsonFlag: boolean;
projectId: string;
fullName: string;
currentBranchMapping: BranchMapping;
getUpdateChannelByNameForAppResult: GetChannelByNameForAppQuery;
channel: NonNullable<GetChannelByNameForAppQuery['app']['byId']['updateChannelByName']>;
}): Promise<{
newChannelInfo: {
id: string;
@@ -93,19 +86,18 @@ async function startRolloutAsync({
};
logMessage: string;
}> {
if (!branchName) {
const validationMessage = 'A branch must be specified.';
if (jsonFlag) {
throw new Error(validationMessage);
}
({ name: branchName } = await promptAsync({
type: 'text',
name: 'name',
message: `Select a branch to rollout onto ${channelName}`,
validate: value => (value ? true : validationMessage),
}));
const branch = await BranchQuery.getBranchByNameAsync({
appId: projectId,
name: branchName,
});
if (!branch) {
throw new Error(
`Could not find a branch named "${branchName}". Please check what branches exist on this project with ${chalk.bold(
'eas branch:list'
)}.`
);
}
const branch = await getBranchByNameAsync({ appId: projectId, name: branchName! });
const oldBranchId = currentBranchMapping.data[0].branchId;
if (branch.id === oldBranchId) {
throw new Error(
@@ -138,14 +130,11 @@ async function startRolloutAsync({
],
};
const newChannelInfo = await updateChannelBranchMappingAsync({
channelId: getUpdateChannelByNameForAppResult.app?.byId.updateChannelByName?.id!,
channelId: channel.id,
branchMapping: JSON.stringify(newBranchMapping),
});
const oldBranch =
getUpdateChannelByNameForAppResult.app?.byId.updateChannelByName?.updateBranches.filter(
branch => branch.id === oldBranchId
)[0];
const oldBranch = channel.updateBranches.filter(branch => branch.id === oldBranchId)[0];
if (!oldBranch) {
throw new Error(
`Branch mapping is missing its only branch for channel "${channelName}" on app "${fullName}"`
@@ -168,13 +157,13 @@ async function editRolloutAsync({
percent,
jsonFlag,
currentBranchMapping,
getUpdateChannelByNameForAppResult,
channel,
}: {
channelName?: string;
percent?: number;
jsonFlag: boolean;
currentBranchMapping: BranchMapping;
getUpdateChannelByNameForAppResult: GetChannelByNameForAppQuery;
channel: NonNullable<GetChannelByNameForAppQuery['app']['byId']['updateChannelByName']>;
}): Promise<{
newChannelInfo: {
id: string;
@@ -183,9 +172,7 @@ async function editRolloutAsync({
};
logMessage: string;
}> {
const { newBranch, oldBranch, currentPercent } = getRolloutInfo(
getUpdateChannelByNameForAppResult
);
const { newBranch, oldBranch, currentPercent } = getRolloutInfo(channel);
if (percent == null) {
if (jsonFlag) {
@@ -205,7 +192,7 @@ async function editRolloutAsync({
newBranchMapping.data[0].branchMappingLogic.operand = percent / 100;
const newChannelInfo = await updateChannelBranchMappingAsync({
channelId: getUpdateChannelByNameForAppResult.app?.byId.updateChannelByName?.id!,
channelId: channel.id,
branchMapping: JSON.stringify(newBranchMapping),
});
@@ -225,13 +212,13 @@ async function endRolloutAsync({
branchName,
jsonFlag,
projectId,
getUpdateChannelByNameForAppResult,
channel,
}: {
channelName?: string;
branchName?: string;
jsonFlag: boolean;
projectId: string;
getUpdateChannelByNameForAppResult: GetChannelByNameForAppQuery;
channel: NonNullable<GetChannelByNameForAppQuery['app']['byId']['updateChannelByName']>;
}): Promise<{
newChannelInfo: {
id: string;
@@ -241,13 +228,22 @@ async function endRolloutAsync({
logMessage: string;
}> {
// end rollout
const { newBranch, oldBranch, currentPercent } = getRolloutInfo(
getUpdateChannelByNameForAppResult
);
const { newBranch, oldBranch, currentPercent } = getRolloutInfo(channel);
let endOnNewBranch;
if (branchName) {
const branch = await getBranchByNameAsync({ appId: projectId, name: branchName! });
const branch = await BranchQuery.getBranchByNameAsync({
appId: projectId,
name: branchName,
});
if (!branch) {
throw new Error(
`Could not find a branch named "${branchName}". Please check what branches exist on this project with ${chalk.bold(
'eas branch:list'
)}.`
);
}
switch (branch.id) {
case newBranch.id:
endOnNewBranch = true;
@@ -295,7 +291,7 @@ async function endRolloutAsync({
};
const newChannelInfo = await updateChannelBranchMappingAsync({
channelId: getUpdateChannelByNameForAppResult.app?.byId.updateChannelByName?.id!,
channelId: channel.id,
branchMapping: JSON.stringify(newBranchMapping),
});
const logMessage = `️Rollout on channel ${chalk.bold(
@@ -352,12 +348,20 @@ export default class ChannelRollout extends EasCommand {
const fullName = await getProjectFullNameAsync(exp);
const projectId = await getProjectIdAsync(exp);
const getUpdateChannelByNameForAppResult = await getUpdateChannelByNameForAppAsync({
const channel = await ChannelQuery.getUpdateChannelByNameForAppAsync({
appId: projectId,
channelName: channelName!,
});
if (!channel) {
throw new Error(
`Could not find a channel named "${channelName}". Please check what channels exist on this project with ${chalk.bold(
'eas channel:list'
)}.`
);
}
const { branchMapping: currentBranchMapping, isRollout } = getBranchMapping(
getUpdateChannelByNameForAppResult.app?.byId.updateChannelByName?.branchMapping
channel.branchMapping
);
if (currentBranchMapping.data.length === 0) {
@@ -391,13 +395,13 @@ export default class ChannelRollout extends EasCommand {
if (!isRollout) {
rolloutMutationResult = await startRolloutAsync({
channelName,
branchName,
branchName: branchName ?? (await promptForBranchNameAsync(channelName)),
percent,
jsonFlag,
projectId,
fullName,
currentBranchMapping,
getUpdateChannelByNameForAppResult,
channel,
});
} else if (endFlag) {
rolloutMutationResult = await endRolloutAsync({
@@ -405,7 +409,7 @@ export default class ChannelRollout extends EasCommand {
branchName,
jsonFlag,
projectId,
getUpdateChannelByNameForAppResult,
channel,
});
} else {
rolloutMutationResult = await editRolloutAsync({
@@ -413,7 +417,7 @@ export default class ChannelRollout extends EasCommand {
percent,
jsonFlag,
currentBranchMapping,
getUpdateChannelByNameForAppResult,
channel,
});
}
if (!rolloutMutationResult) {
@@ -427,3 +431,13 @@ export default class ChannelRollout extends EasCommand {
}
}
}
async function promptForBranchNameAsync(channelName: string): Promise<string> {
const { name } = await promptAsync({
type: 'text',
name: 'name',
message: `Select a branch to rollout onto ${channelName}`,
validate: value => (value ? true : 'A branch must be specified.'),
});
return name;
}
+3 -59
View File
@@ -3,14 +3,9 @@ import { Flags } from '@oclif/core';
import assert from 'assert';
import chalk from 'chalk';
import Table from 'cli-table3';
import gql from 'graphql-tag';
import EasCommand from '../../commandUtils/EasCommand';
import { graphqlClient, withErrorHandlingAsync } from '../../graphql/client';
import {
GetChannelByNameForAppQuery,
GetChannelByNameForAppQueryVariables,
} from '../../graphql/generated';
import { ChannelQuery } from '../../graphql/queries/ChannelQuery';
import Log from '../../log';
import { findProjectRootAsync, getProjectIdAsync } from '../../project/projectUtils';
import { promptAsync } from '../../prompts';
@@ -91,56 +86,6 @@ export function getBranchMapping(branchMappingString?: string): {
return { branchMapping, isRollout, rolloutPercent };
}
export async function getUpdateChannelByNameForAppAsync({
appId,
channelName,
}: GetChannelByNameForAppQueryVariables): Promise<GetChannelByNameForAppQuery> {
return await withErrorHandlingAsync(
graphqlClient
.query<GetChannelByNameForAppQuery, GetChannelByNameForAppQueryVariables>(
gql`
query GetChannelByNameForApp($appId: String!, $channelName: String!) {
app {
byId(appId: $appId) {
id
updateChannelByName(name: $channelName) {
id
name
createdAt
branchMapping
updateBranches(offset: 0, limit: 1000) {
id
name
updates(offset: 0, limit: 10) {
id
group
message
runtimeVersion
createdAt
platform
actor {
id
... on User {
username
}
... on Robot {
firstName
}
}
}
}
}
}
}
}
`,
{ appId, channelName },
{ additionalTypenames: ['UpdateChannel', 'UpdateBranch', 'Update'] }
)
.toPromise()
);
}
export function logChannelDetails(channel: {
branchMapping: string;
updateBranches: {
@@ -193,7 +138,7 @@ export function logChannelDetails(channel: {
}
export default class ChannelView extends EasCommand {
static description = 'View a channel on the current project.';
static description = 'view a channel';
static args = [
{
@@ -236,11 +181,10 @@ export default class ChannelView extends EasCommand {
}));
}
const getUpdateChannelByNameForAppresult = await getUpdateChannelByNameForAppAsync({
const channel = await ChannelQuery.getUpdateChannelByNameForAppAsync({
appId: projectId,
channelName,
});
const channel = getUpdateChannelByNameForAppresult.app?.byId.updateChannelByName;
if (!channel) {
throw new Error(`Could not find a channel with name: ${channelName}`);
}
+9 -3
View File
@@ -2,16 +2,19 @@ import { getProjectConfigDescription } from '@expo/config';
import { Platform } from '@expo/eas-build-job';
import { EasJsonReader } from '@expo/eas-json';
import { Flags } from '@oclif/core';
import chalk from 'chalk';
import EasCommand from '../commandUtils/EasCommand';
import { toAppPlatform } from '../graphql/types/AppPlatform';
import Log from '../log';
import { appPlatformEmojis } from '../platform';
import { getExpoConfig } from '../project/expoConfig';
import { findProjectRootAsync } from '../project/projectUtils';
import { selectAsync } from '../prompts';
import { handleDeprecatedEasJsonAsync } from './build';
export default class Config extends EasCommand {
static description = 'show the eas.json config';
static description = 'display project configuration (app.json + eas.json)';
static flags = {
platform: Flags.enum({ char: 'p', options: ['android', 'ios'] }),
@@ -58,12 +61,15 @@ export default class Config extends EasCommand {
const profile = await reader.getBuildProfileAsync(platform, profileName);
const config = getExpoConfig(projectDir, { env: profile.env, isPublicConfig: true });
Log.log(getProjectConfigDescription(projectDir));
Log.addNewLineIfNone();
Log.log(chalk.bold(getProjectConfigDescription(projectDir)));
Log.newLine();
Log.log(JSON.stringify(config, null, 2));
Log.newLine();
Log.newLine();
Log.log(`Build profile "${profileName}" from eas.json for platform ${platform}`);
const appPlatform = toAppPlatform(platform);
const platformEmoji = appPlatformEmojis[appPlatform];
Log.log(`${platformEmoji} ${chalk.bold(`Build profile "${profileName}"`)}`);
Log.newLine();
Log.log(JSON.stringify(profile, null, 2));
}
+1 -1
View File
@@ -2,7 +2,7 @@ import EasCommand from '../commandUtils/EasCommand';
import { SelectPlatform } from '../credentials/manager/SelectPlatform';
export default class Credentials extends EasCommand {
static description = 'manage your credentials';
static description = 'manage credentials';
async runAsync(): Promise<void> {
await new SelectPlatform().runAsync();
+1 -1
View File
@@ -8,7 +8,7 @@ import { resolveWorkflowAsync } from '../project/workflow';
import { easCliVersion } from '../utils/easCli';
export default class Diagnostics extends EasCommand {
static description = 'log environment info to the console';
static description = 'display environment info';
protected requiresAuthentication = false;
@@ -20,7 +20,7 @@ import { getActorDisplayName } from '../../user/User';
import { ensureLoggedInAsync } from '../../user/actions';
export default class EnvironmentSecretCreate extends EasCommand {
static description = 'Create an environment secret on the current project or owner account.';
static description = 'create an environment secret on the current project or owner account';
static flags = {
scope: Flags.enum({
@@ -1,6 +1,5 @@
import { getConfig } from '@expo/config';
import { Flags } from '@oclif/core';
import chalk from 'chalk';
import EasCommand from '../../commandUtils/EasCommand';
import { EnvironmentSecretMutation } from '../../graphql/mutations/EnvironmentSecretMutation';
@@ -18,8 +17,7 @@ import {
import { promptAsync, toggleConfirmAsync } from '../../prompts';
export default class EnvironmentSecretDelete extends EasCommand {
static description = `Delete an environment secret by ID.
Unsure where to find the secret's ID? Run ${chalk.bold('eas secret:list')}`;
static description = 'delete an environment secret by ID';
static flags = {
id: Flags.string({
+1 -1
View File
@@ -13,7 +13,7 @@ import {
} from '../../project/projectUtils';
export default class EnvironmentSecretList extends EasCommand {
static description = 'Lists environment secrets available for your current app';
static description = 'list environment secrets available for your current app';
async runAsync(): Promise<void> {
const projectDir = await findProjectRootAsync();
+2 -3
View File
@@ -5,7 +5,7 @@ import chalk from 'chalk';
import EasCommand from '../commandUtils/EasCommand';
import { SubmissionFragment } from '../graphql/generated';
import { toAppPlatform } from '../graphql/types/AppPlatform';
import Log, { link } from '../log';
import Log from '../log';
import {
RequestedPlatform,
appPlatformDisplayNames,
@@ -41,8 +41,7 @@ interface CommandFlags {
}
export default class Submit extends EasCommand {
static description = `Submit build archive to App Store Connect
See how to configure submits with eas.json: ${link('https://docs.expo.dev/submit/eas-json/')}`;
static description = 'submit app binary to App Store and/or Play Store';
static aliases = ['build:submit'];
static flags = {
+203 -56
View File
@@ -1,32 +1,180 @@
import { ExpoConfig, getConfig, modifyConfigAsync } from '@expo/config';
import { Platform, Workflow } from '@expo/eas-build-job';
import { Flags } from '@oclif/core';
import assert from 'assert';
import chalk from 'chalk';
import { getEASUpdateURL } from '../../api';
import EasCommand from '../../commandUtils/EasCommand';
import { AppPlatform } from '../../graphql/generated';
import Log, { learnMore } from '../../log';
import { findProjectRootAsync, getProjectIdAsync } from '../../project/projectUtils';
import { RequestedPlatform, appPlatformDisplayNames } from '../../platform';
import {
findProjectRootAsync,
getProjectIdAsync,
installExpoUpdatesAsync,
isExpoUpdatesInstalledOrAvailable,
} from '../../project/projectUtils';
import { resolveWorkflowAsync } from '../../project/workflow';
import { syncUpdatesConfigurationAsync as syncAndroidUpdatesConfigurationAsync } from '../../update/android/UpdatesModule';
import { syncUpdatesConfigurationAsync as syncIosUpdatesConfigurationAsync } from '../../update/ios/UpdatesModule';
const DEFAULT_MANAGED_RUNTIME_VERSION = { policy: 'sdkVersion' } as const;
const DEFAULT_BARE_RUNTIME_VERSION = '1.0.0';
const DEFAULT_BARE_RUNTIME_VERSION = '1.0.0' as const;
async function configureProjectForEASUpdateAsync(
projectDir: string,
exp: ExpoConfig,
isBare: boolean
): Promise<void> {
export default class UpdateConfigure extends EasCommand {
static description = 'configure the project to support EAS Update';
static flags = {
platform: Flags.enum({
description: 'Platform to configure',
char: 'p',
options: ['android', 'ios', 'all'],
default: 'all',
}),
};
async runAsync(): Promise<void> {
Log.log(
'💡 The following process will configure your project to run EAS Update. These changes only apply to your local project files and you can safely revert them at any time.'
);
const { flags } = await this.parse(UpdateConfigure);
const platform = flags.platform as RequestedPlatform;
const projectDir = await findProjectRootAsync();
const { exp } = getConfig(projectDir, {
skipSDKVersionRequirement: true,
});
if (!isExpoUpdatesInstalledOrAvailable(projectDir, exp.sdkVersion)) {
await installExpoUpdatesAsync(projectDir);
}
const [androidWorkflow, iosWorkflow] = await Promise.all([
resolveWorkflowAsync(projectDir, Platform.ANDROID),
resolveWorkflowAsync(projectDir, Platform.IOS),
]);
const updatedExp = await configureAppJSONForEASUpdateAsync({
projectDir,
exp,
platform,
workflows: {
android: androidWorkflow,
ios: iosWorkflow,
},
});
Log.withTick(`Configured ${chalk.bold('app.json')} for EAS Update`);
// configure native files for EAS Update
if (
[RequestedPlatform.Android, RequestedPlatform.All].includes(platform) &&
androidWorkflow === Workflow.GENERIC
) {
await syncAndroidUpdatesConfigurationAsync(projectDir, updatedExp);
Log.withTick(`Configured ${chalk.bold('AndroidManifest.xml')} for EAS Update`);
}
if (
[RequestedPlatform.Ios, RequestedPlatform.All].includes(platform) &&
iosWorkflow === Workflow.GENERIC
) {
await syncIosUpdatesConfigurationAsync(projectDir, updatedExp);
Log.withTick(`Configured ${chalk.bold('Expo.plist')} for EAS Update`);
}
Log.addNewLineIfNone();
Log.log(`🎉 Your app is configured to run EAS Update!`);
}
}
async function configureAppJSONForEASUpdateAsync({
projectDir,
exp,
platform,
workflows,
}: {
projectDir: string;
exp: ExpoConfig;
platform: RequestedPlatform;
workflows: {
[key in RequestedPlatform.Android | RequestedPlatform.Ios]: Workflow;
};
}): Promise<ExpoConfig> {
const projectId = await getProjectIdAsync(exp);
const easUpdateURL = getEASUpdateURL(projectId);
const preexistingRuntimeVersion = exp.runtimeVersion;
const defaultRuntimeVersion = isBare
? DEFAULT_BARE_RUNTIME_VERSION
: DEFAULT_MANAGED_RUNTIME_VERSION;
const result = await modifyConfigAsync(projectDir, {
runtimeVersion: preexistingRuntimeVersion ?? defaultRuntimeVersion,
updates: { ...exp.updates, url: easUpdateURL },
});
const updates = { ...exp.updates, url: easUpdateURL };
const androidDefaultRuntimeVersion =
workflows['android'] === Workflow.GENERIC
? DEFAULT_BARE_RUNTIME_VERSION
: DEFAULT_MANAGED_RUNTIME_VERSION;
const iosDefaultRuntimeVersion =
workflows['ios'] === Workflow.GENERIC
? DEFAULT_BARE_RUNTIME_VERSION
: DEFAULT_MANAGED_RUNTIME_VERSION;
const newAndroidRuntimeVersion =
exp.android?.runtimeVersion ?? exp.runtimeVersion ?? androidDefaultRuntimeVersion;
const newIosRuntimeVersion =
exp.ios?.runtimeVersion ?? exp.runtimeVersion ?? iosDefaultRuntimeVersion;
let newConfig: Partial<ExpoConfig>;
switch (platform) {
case RequestedPlatform.All: {
if (isRuntimeEqual(newAndroidRuntimeVersion, newIosRuntimeVersion)) {
newConfig = {
runtimeVersion: newAndroidRuntimeVersion,
android: {
...exp.android,
runtimeVersion: undefined,
},
ios: { ...exp.ios, runtimeVersion: undefined },
updates,
};
} else {
newConfig = {
runtimeVersion: undefined, // top level runtime is redundant if it is specified in both android and ios
android: {
...exp.android,
runtimeVersion: newAndroidRuntimeVersion,
},
ios: {
...exp.ios,
runtimeVersion: newIosRuntimeVersion,
},
updates,
};
}
break;
}
case RequestedPlatform.Android: {
newConfig = {
android: {
...exp.android,
runtimeVersion: newAndroidRuntimeVersion,
},
updates,
};
break;
}
case RequestedPlatform.Ios: {
newConfig = {
ios: {
...exp.ios,
runtimeVersion: newIosRuntimeVersion,
},
updates,
};
break;
}
default: {
throw new Error(`Unsupported platform: ${platform}`);
}
}
const result = await modifyConfigAsync(projectDir, newConfig);
const prexistingAndroidRuntimeVersion = exp.android?.runtimeVersion ?? exp.runtimeVersion;
const prexistingIosRuntimeVersion = exp.ios?.runtimeVersion ?? exp.runtimeVersion;
switch (result.type) {
case 'success':
if (exp.updates?.url) {
@@ -38,12 +186,27 @@ async function configureProjectForEASUpdateAsync(
} else {
Log.withTick(`Set updates.url value, to "${easUpdateURL}" in app.json`);
}
if (!preexistingRuntimeVersion) {
if (
!prexistingAndroidRuntimeVersion &&
[RequestedPlatform.Android, RequestedPlatform.All].includes(platform)
) {
Log.withTick(
`Set runtimeVersion to "${JSON.stringify(defaultRuntimeVersion)}" in app.json`
`Set ${appPlatformDisplayNames[AppPlatform.Android]} runtimeVersion to "${JSON.stringify(
newConfig.android?.runtimeVersion ?? newConfig.runtimeVersion
)}" in app.json`
);
}
if (
!prexistingIosRuntimeVersion &&
[RequestedPlatform.Ios, RequestedPlatform.All].includes(platform)
) {
Log.withTick(
`Set ${appPlatformDisplayNames[AppPlatform.Ios]} runtimeVersion to "${JSON.stringify(
newConfig.ios?.runtimeVersion ?? newConfig.runtimeVersion
)}" in app.json`
);
}
break;
case 'warn': {
Log.addNewLineIfNone();
@@ -57,11 +220,15 @@ async function configureProjectForEASUpdateAsync(
'https://expo.fyi/eas-update-config.md'
)}\n`
);
Log.log(
chalk.bold(
`{\n "updates": {\n "url": "${easUpdateURL}"\n },\n "runtimeVersion": {\n "policy": "sdkVersion"\n }\n}`
)
);
Log.log(chalk.bold(JSON.stringify(newConfig, null, 2)));
Log.addNewLineIfNone();
if (workflows['android'] === Workflow.GENERIC || workflows['ios'] === Workflow.GENERIC) {
Log.warn(
`You will also have to manually edit the projects ${chalk.bold(
'Expo.plist/AndroidManifest.xml'
)}. ${learnMore('https://expo.fyi/eas-update-config.md#native-configuration')}`
);
}
Log.addNewLineIfNone();
throw new Error(result.message);
}
@@ -70,40 +237,20 @@ async function configureProjectForEASUpdateAsync(
default:
throw new Error('Unexpected result type from modifyConfigAsync');
}
assert(result.config, 'A successful result should have a config');
return result.config.expo;
}
export default class UpdateConfigure extends EasCommand {
static description = 'Configure the project to support EAS Update.';
async runAsync(): Promise<void> {
Log.log(
'💡 The following process will configure your project to run EAS Update. These changes only apply to your local project files and you can safely revert them at any time.'
);
const projectDir = await findProjectRootAsync();
const { exp } = getConfig(projectDir, {
skipSDKVersionRequirement: true,
});
const hasAndroidNativeProject =
(await resolveWorkflowAsync(projectDir, Platform.ANDROID)) === Workflow.GENERIC;
const hasIosNativeProject =
(await resolveWorkflowAsync(projectDir, Platform.IOS)) === Workflow.GENERIC;
const isBare = hasAndroidNativeProject || hasIosNativeProject;
await configureProjectForEASUpdateAsync(projectDir, exp, isBare);
Log.addNewLineIfNone();
if (isBare) {
Log.log(
`🧐 It seems you are on the bare workflow! Please also update your native files. You can do this by either running ${chalk.bold(
'eas build:configure'
)} or manually editing Expo.plist/AndroidManifest.xml. ${learnMore(
'https://expo.fyi/eas-update-config.md#native-configuration'
)}`
);
} else {
Log.log(`🎉 Your app is configured to run EAS Update!`);
}
function isRuntimeEqual(
runtimeVersionA: string | { policy: 'sdkVersion' | 'nativeVersion' },
runtimeVersionB: string | { policy: 'sdkVersion' | 'nativeVersion' }
): boolean {
if (typeof runtimeVersionA === 'string' && typeof runtimeVersionB === 'string') {
return runtimeVersionA === runtimeVersionB;
} else if (typeof runtimeVersionA === 'object' && typeof runtimeVersionB === 'object') {
return runtimeVersionA.policy === runtimeVersionB.policy;
} else {
return false;
}
}
@@ -36,7 +36,7 @@ async function deleteUpdateGroupAsync({
}
export default class UpdateDelete extends EasCommand {
static description = 'Delete all the updates in an update Group.';
static description = 'delete all the updates in an update group';
static args = [
{
@@ -68,8 +68,8 @@ export default class UpdateDelete extends EasCommand {
`${chalk.yellow(`This will delete all of the updates in group "${group}".`)} ${chalk.red(
'This is a permanent operation.'
)}\n\n` +
`If you want to revert to a previous publish, you should use 'branch:publish --republish' targeted at the last working update group instead.\n\n` +
`An update group should only be deleted in an emergency like an accidental publish of a secret. In this case user 'branch:publish --republish' to revert to the last working update group first and then proceed with the deletion. Deleting an update group when it is the latest publish can lead to inconsistent cacheing behavior by clients.\n\n` +
`If you want to revert to a previous publish, you should use 'update --republish' targeted at the last working update group instead.\n\n` +
`An update group should only be deleted in an emergency like an accidental publish of a secret. In this case user 'update --republish' to revert to the last working update group first and then proceed with the deletion. Deleting an update group when it is the latest publish can lead to inconsistent cacheing behavior by clients.\n\n` +
`Would you like to abort?`,
});
+118 -25
View File
@@ -1,21 +1,25 @@
import { ExpoConfig, getConfig } from '@expo/config';
import { Updates } from '@expo/config-plugins';
import { Platform, Workflow } from '@expo/eas-build-job';
import { Flags } from '@oclif/core';
import { Errors, Flags } from '@oclif/core';
import assert from 'assert';
import chalk from 'chalk';
import dateFormat from 'dateformat';
import gql from 'graphql-tag';
import nullthrows from 'nullthrows';
import { getEASUpdateURL } from '../../api';
import EasCommand from '../../commandUtils/EasCommand';
import fetch from '../../fetch';
import { graphqlClient, withErrorHandlingAsync } from '../../graphql/client';
import {
GetUpdateGroupAsyncQuery,
PublishUpdateGroupInput,
Robot,
RootQueryUpdatesByGroupArgs,
Update,
UpdateInfoGroup,
UpdatePublishMutation,
User,
ViewBranchUpdatesQuery,
} from '../../graphql/generated';
@@ -23,7 +27,12 @@ import { PublishMutation } from '../../graphql/mutations/PublishMutation';
import { UpdateQuery } from '../../graphql/queries/UpdateQuery';
import Log from '../../log';
import { ora } from '../../ora';
import { findProjectRootAsync, getProjectIdAsync } from '../../project/projectUtils';
import {
findProjectRootAsync,
getProjectIdAsync,
installExpoUpdatesAsync,
isExpoUpdatesInstalledOrAvailable,
} from '../../project/projectUtils';
import {
PublishPlatform,
buildBundlesAsync,
@@ -32,8 +41,14 @@ import {
uploadAssetsAsync,
} from '../../project/publish';
import { resolveWorkflowAsync } from '../../project/workflow';
import { promptAsync, selectAsync } from '../../prompts';
import { confirmAsync, promptAsync, selectAsync } from '../../prompts';
import { formatUpdate } from '../../update/utils';
import {
checkManifestBodyAgainstUpdateInfoGroup,
getCodeSigningInfoAsync,
getManifestBodyAsync,
signManifestBody,
} from '../../utils/code-signing';
import uniqBy from '../../utils/expodash/uniqBy';
import formatFields from '../../utils/formatFields';
import { enableJsonOutput, printJsonOnlyOutput } from '../../utils/json';
@@ -132,7 +147,7 @@ async function ensureBranchExistsAsync({
}
export default class UpdatePublish extends EasCommand {
static description = 'Publish an update group.';
static description = 'publish an update group';
static flags = {
branch: Flags.string({
@@ -175,6 +190,10 @@ export default class UpdatePublish extends EasCommand {
'Use the current git branch and commit message for the EAS branch and update message',
default: false,
}),
'private-key-path': Flags.string({
description: `File containing the PEM-encoded private key corresponding to the certificate in expo-updates' configuration. Defaults to a file named "private-key.pem" in the certificate's directory.`,
required: false,
}),
};
async runAsync(): Promise<void> {
@@ -189,11 +208,13 @@ export default class UpdatePublish extends EasCommand {
'input-dir': inputDir,
'skip-bundler': skipBundler,
platform,
'private-key-path': privateKeyPath,
},
} = await this.parse(UpdatePublish);
if (jsonFlag) {
enableJsonOutput();
}
const platformFlag = platform as PlatformFlag;
// If a group was specified, that means we are republishing it.
republish = group ? true : republish;
@@ -204,6 +225,24 @@ export default class UpdatePublish extends EasCommand {
isPublicConfig: true,
});
const codeSigningInfo = await getCodeSigningInfoAsync(exp, privateKeyPath);
if (!isExpoUpdatesInstalledOrAvailable(projectDir, exp.sdkVersion)) {
const install = await confirmAsync({
message: `You are creating an update which requires ${chalk.bold(
'expo-updates'
)} to be installed in your app.\n Do you want EAS CLI to install it for you?`,
instructions: 'The command will abort unless you agree.',
});
if (install) {
await installExpoUpdatesAsync(projectDir);
} else {
Errors.error(`Install ${chalk.bold('expo-updates')} manually and come back later.`, {
exit: 1,
});
}
}
const runtimeVersions = await getRuntimeVersionObjectAsync(exp, platformFlag, projectDir);
const projectId = await getProjectIdAsync(exp);
await checkEASUpdateURLIsSetAsync(exp);
@@ -392,30 +431,76 @@ export default class UpdatePublish extends EasCommand {
}
// Sort the updates into different groups based on their platform specific runtime versions
const updateGroups = Object.entries(runtimeToPlatformMapping).map(([runtime, platforms]) => {
const localUpdateInfoGroup = Object.fromEntries(
platforms.map(platform => [
platform,
unsortedUpdateInfoGroups[platform as keyof UpdateInfoGroup],
])
);
if (republish && !oldRuntimeVersion) {
throw new Error(
'Can not find the runtime version of the update group that is being republished.'
const updateGroups: PublishUpdateGroupInput[] = Object.entries(runtimeToPlatformMapping).map(
([runtime, platforms]) => {
const localUpdateInfoGroup = Object.fromEntries(
platforms.map(platform => [
platform,
unsortedUpdateInfoGroups[platform as keyof UpdateInfoGroup],
])
);
if (republish && !oldRuntimeVersion) {
throw new Error(
'Cannot find the runtime version of the update group that is being republished.'
);
}
return {
branchId,
updateInfoGroup: localUpdateInfoGroup,
runtimeVersion: republish ? oldRuntimeVersion : runtime,
message,
awaitingCodeSigningInfo: !!codeSigningInfo,
};
}
return {
branchId,
updateInfoGroup: localUpdateInfoGroup,
runtimeVersion: republish ? oldRuntimeVersion : runtime,
message,
};
});
let newUpdates;
);
let newUpdates: UpdatePublishMutation['updateBranch']['publishUpdateGroups'];
const publishSpinner = ora('Publishing...').start();
try {
newUpdates = await PublishMutation.publishUpdateGroupAsync(updateGroups);
if (codeSigningInfo) {
Log.log('🔒 Signing updates');
const updatesTemp = [...newUpdates];
const updateGroupsAndTheirUpdates = updateGroups.map(updateGroup => {
const newUpdates = updatesTemp.splice(0, Object.keys(updateGroup.updateInfoGroup).length);
return {
updateGroup,
newUpdates,
};
});
await Promise.all(
updateGroupsAndTheirUpdates.map(async ({ updateGroup, newUpdates }) => {
await Promise.all(
newUpdates.map(async newUpdate => {
const response = await fetch(newUpdate.manifestPermalink, {
method: 'GET',
headers: { accept: 'multipart/mixed' },
});
const manifestBody = nullthrows(await getManifestBodyAsync(response));
checkManifestBodyAgainstUpdateInfoGroup(
manifestBody,
nullthrows(
updateGroup.updateInfoGroup[newUpdate.platform as keyof UpdateInfoGroup]
)
);
const manifestSignature = signManifestBody(manifestBody, codeSigningInfo);
await PublishMutation.setCodeSigningInfoAsync(newUpdate.id, {
alg: codeSigningInfo.codeSigningMetadata.alg,
keyid: codeSigningInfo.codeSigningMetadata.keyid,
sig: manifestSignature,
});
})
);
})
);
}
publishSpinner.succeed('Published!');
} catch (e) {
publishSpinner.fail('Failed to published updates');
@@ -468,13 +553,21 @@ async function getRuntimeVersionObjectAsync(
if (isPolicy) {
const isManaged = (await resolveWorkflowAsync(projectDir, platform)) === Workflow.MANAGED;
if (!isManaged) {
throw new Error('Runtime version policies are only supported in the managed workflow.');
throw new Error(
'Runtime version policies are only supported in the managed workflow. In the bare workflow, runtime version needs to be set manually.'
);
}
}
}
return Object.fromEntries(
platforms.map(platform => [platform, Updates.getRuntimeVersion(exp, platform)])
platforms.map(platform => [
platform,
nullthrows(
Updates.getRuntimeVersion(exp, platform),
`Unable to determine runtime version for ${platform}`
),
])
);
}
+1 -1
View File
@@ -23,7 +23,7 @@ type UpdateGroupDescription = FormatUpdateParameter & {
};
export default class BranchView extends EasCommand {
static description = 'View the recent updates for a branch';
static description = 'view the recent updates for a branch';
static flags = {
branch: Flags.string({
+1 -1
View File
@@ -51,7 +51,7 @@ export async function viewUpdateAsync({
return data;
}
export default class UpdateView extends EasCommand {
static description = 'Update group details.';
static description = 'update group details';
static args = [
{
@@ -9,7 +9,7 @@ import { findProjectRootAsync, getProjectIdAsync } from '../../project/projectUt
import { prepareInputParamsAsync } from '../../webhooks/input';
export default class WebhookCreate extends EasCommand {
static description = 'Create a webhook on the current project.';
static description = 'create a webhook';
static flags = {
event: Flags.enum({
@@ -14,7 +14,7 @@ import { promptAsync, toggleConfirmAsync } from '../../prompts';
import { formatWebhook } from '../../webhooks/formatWebhook';
export default class WebhookDelete extends EasCommand {
static description = 'Delete a webhook on the current project.';
static description = 'delete a webhook';
static args = [
{
@@ -15,7 +15,7 @@ import {
import { formatWebhook } from '../../webhooks/formatWebhook';
export default class WebhookList extends EasCommand {
static description = 'List webhooks on the current project.';
static description = 'list webhooks';
static flags = {
event: Flags.enum({
@@ -9,7 +9,7 @@ import pick from '../../utils/expodash/pick';
import { prepareInputParamsAsync } from '../../webhooks/input';
export default class WebhookUpdate extends EasCommand {
static description = 'Update a webhook on the current project.';
static description = 'update a webhook';
static flags = {
id: Flags.string({
@@ -5,7 +5,7 @@ import { ora } from '../../ora';
import { formatWebhook } from '../../webhooks/formatWebhook';
export default class WebhookView extends EasCommand {
static description = 'View a webhook on the current project.';
static description = 'view a webhook';
static args = [
{
@@ -2,14 +2,11 @@ import spawnAsync from '@expo/spawn-async';
import chalk from 'chalk';
import crypto from 'crypto';
import fs from 'fs-extra';
// (dsokal) We actually want to use node-fetch but the change is in progress.
// See https://github.com/expo/eas-cli/issues/32 for context.
// eslint-disable-next-line no-restricted-imports
import fetch from 'node-fetch';
import path from 'path';
import { v4 as uuidv4 } from 'uuid';
import { Analytics, BuildEvent } from '../../../analytics/events';
import fetch from '../../../fetch';
import { AndroidKeystoreType } from '../../../graphql/generated';
import { KeystoreGenerationUrlMutation } from '../../../graphql/mutations/KeystoreGenerationUrlMutation';
import Log from '../../../log';
@@ -149,7 +146,7 @@ async function createKeystoreInCloudAsync(
body: JSON.stringify(keystoreParams),
headers: { 'Content-Type': 'application/json' },
});
const result: KeystoreServiceResult = await response.json();
const result = (await response.json()) as KeystoreServiceResult;
spinner.succeed();
return {
type: AndroidKeystoreType.Jks,
+2 -2
View File
@@ -106,7 +106,7 @@ export class CredentialsContext {
);
Log.log(
chalk.green(
'This is optional, but without Apple account access you will need to provide all the values manually and we can only run minimal validation on them.'
'This is optional, but without Apple account access you will need to provide all the missing values manually and we can only run minimal validation on them.'
)
);
const confirm = await confirmAsync({
@@ -117,7 +117,7 @@ export class CredentialsContext {
} else {
Log.log(
chalk.green(
'No problem! 👌 If you select an action that requires those credentials we will ask you again about it.'
'No problem! 👌 If any of the next steps will require Apple account access we will ask you again about it.'
)
);
}
@@ -11,7 +11,7 @@ export class SelectAndRemoveAscApiKey {
async runAsync(ctx: CredentialsContext): Promise<void> {
const selected = await selectAscApiKeysFromAccountAsync(ctx, this.account);
if (selected) {
await new RemoveAscApiKey(this.account, selected).runAsync(ctx);
await new RemoveAscApiKey(selected).runAsync(ctx);
Log.succeed('Removed App Store Connect API Key');
Log.newLine();
}
@@ -19,7 +19,7 @@ export class SelectAndRemoveAscApiKey {
}
export class RemoveAscApiKey {
constructor(private account: Account, private ascApiKey: AppStoreConnectApiKeyFragment) {}
constructor(private ascApiKey: AppStoreConnectApiKeyFragment) {}
public async runAsync(ctx: CredentialsContext): Promise<void> {
if (ctx.nonInteractive) {
@@ -11,7 +11,7 @@ export class SelectAndRemovePushKey {
async runAsync(ctx: CredentialsContext): Promise<void> {
const selected = await selectPushKeyAsync(ctx, this.account);
if (selected) {
await new RemovePushKey(this.account, selected).runAsync(ctx);
await new RemovePushKey(selected).runAsync(ctx);
Log.succeed('Removed push key');
Log.newLine();
}
@@ -19,7 +19,7 @@ export class SelectAndRemovePushKey {
}
export class RemovePushKey {
constructor(private account: Account, private pushKey: ApplePushKeyFragment) {}
constructor(private pushKey: ApplePushKeyFragment) {}
public async runAsync(ctx: CredentialsContext): Promise<void> {
if (ctx.nonInteractive) {
@@ -47,7 +47,7 @@ export class SetUpDistributionCertificate {
}
private async runNonInteractiveAsync(
ctx: CredentialsContext,
_ctx: CredentialsContext,
currentCertificate: AppleDistributionCertificateFragment | null
): Promise<AppleDistributionCertificateFragment> {
// TODO: implement validation
@@ -1,5 +1,5 @@
import { IosAppBuildCredentialsFragment, IosDistributionType } from '../../../graphql/generated';
import Log from '../../../log';
import Log, { learnMore } from '../../../log';
import { promptAsync } from '../../../prompts';
import { CredentialsContext } from '../../context';
import { AppLookupParams } from '../api/GraphqlClient';
@@ -51,6 +51,11 @@ export class SetUpInternalProvisioningProfile {
} else if (enterpriseBuildCredentialsExist) {
return await this.setupUniversalProvisioningProfileAsync(ctx);
} else {
Log.addNewLineIfNone();
Log.log(
'You need to log in to your Apple Developer account to generate credentials for internal distribution builds, or provide credentials via credentials.json'
);
Log.log(learnMore('https://docs.expo.dev/app-signing/local-credentials/'));
const { team } = await ctx.appStore.ensureAuthenticatedAsync();
if (team.inHouse) {
return await this.askForDistributionTypeAndSetupAsync(
@@ -1,21 +1,10 @@
import {
AppleDistributionCertificateFragment,
AppleProvisioningProfileFragment,
} from '../../../../graphql/generated';
import { testProvisioningProfileFragment } from '../../../__tests__/fixtures-ios';
import { CredentialsContext } from '../../../context';
import { AppLookupParams } from '../../api/GraphqlClient';
import { AppleProvisioningProfileMutationResult } from '../../api/graphql/mutations/AppleProvisioningProfileMutation';
export class ConfigureProvisioningProfile {
constructor(
private app: AppLookupParams,
private distributionCertificate: AppleDistributionCertificateFragment,
private originalProvisioningProfile: AppleProvisioningProfileFragment
) {}
public async runAsync(
ctx: CredentialsContext
_ctx: CredentialsContext
): Promise<AppleProvisioningProfileMutationResult | null> {
return testProvisioningProfileFragment;
}
@@ -1,16 +1,9 @@
import { AppleDistributionCertificateFragment } from '../../../../graphql/generated';
import { testProvisioningProfileFragment } from '../../../__tests__/fixtures-ios';
import { CredentialsContext } from '../../../context';
import { AppLookupParams } from '../../api/GraphqlClient';
import { AppleProvisioningProfileMutationResult } from '../../api/graphql/mutations/AppleProvisioningProfileMutation';
export class CreateProvisioningProfile {
constructor(
private app: AppLookupParams,
private distributionCertificate: AppleDistributionCertificateFragment
) {}
async runAsync(ctx: CredentialsContext): Promise<AppleProvisioningProfileMutationResult> {
async runAsync(_ctx: CredentialsContext): Promise<AppleProvisioningProfileMutationResult> {
return testProvisioningProfileFragment;
}
}
@@ -1,13 +1,7 @@
import {
AppleDistributionCertificateFragment,
IosDistributionType,
} from '../../../../graphql/generated';
import { AppleDistributionCertificateFragment } from '../../../../graphql/generated';
import { testDistCertFragmentOneDependency } from '../../../__tests__/fixtures-ios';
import { CredentialsContext } from '../../../context';
import { AppLookupParams } from '../../api/GraphqlClient';
export class SetUpDistributionCertificate {
constructor(private app: AppLookupParams, private distributionType: IosDistributionType) {}
public async runAsync(_ctx: CredentialsContext): Promise<AppleDistributionCertificateFragment> {
return testDistCertFragmentOneDependency;
}
@@ -1,9 +1,7 @@
import { asMock } from '../../../../__tests__/utils';
import { findApplicationTarget } from '../../../../project/ios/target';
import { confirmAsync } from '../../../../prompts';
import { createCtxMock } from '../../../__tests__/fixtures-context';
import { testAscApiKeyFragment, testTargets } from '../../../__tests__/fixtures-ios';
import { getAppLookupParamsFromContext } from '../BuildCredentialsUtils';
import { testAscApiKeyFragment } from '../../../__tests__/fixtures-ios';
import { RemoveAscApiKey } from '../RemoveAscApiKey';
jest.mock('../../../../prompts');
@@ -12,22 +10,14 @@ asMock(confirmAsync).mockImplementation(() => true);
describe(RemoveAscApiKey, () => {
it('removes an Asc API Key', async () => {
const ctx = createCtxMock({ nonInteractive: false });
const appLookupParams = getAppLookupParamsFromContext(ctx, findApplicationTarget(testTargets));
const removeAscApiKeyAction = new RemoveAscApiKey(
appLookupParams.account,
testAscApiKeyFragment
);
const removeAscApiKeyAction = new RemoveAscApiKey(testAscApiKeyFragment);
await removeAscApiKeyAction.runAsync(ctx);
expect(ctx.ios.deleteAscApiKeyAsync).toHaveBeenCalledTimes(1);
expect(ctx.appStore.revokeAscApiKeyAsync).toHaveBeenCalledTimes(1);
});
it('errors in Non-Interactive Mode', async () => {
const ctx = createCtxMock({ nonInteractive: true });
const appLookupParams = getAppLookupParamsFromContext(ctx, findApplicationTarget(testTargets));
const removeAscApiKeyAction = new RemoveAscApiKey(
appLookupParams.account,
testAscApiKeyFragment
);
const removeAscApiKeyAction = new RemoveAscApiKey(testAscApiKeyFragment);
await expect(removeAscApiKeyAction.runAsync(ctx)).rejects.toThrowError();
});
});
@@ -1,9 +1,7 @@
import { asMock } from '../../../../__tests__/utils';
import { findApplicationTarget } from '../../../../project/ios/target';
import { confirmAsync } from '../../../../prompts';
import { createCtxMock } from '../../../__tests__/fixtures-context';
import { testPushKey, testTargets } from '../../../__tests__/fixtures-ios';
import { getAppLookupParamsFromContext } from '../BuildCredentialsUtils';
import { testPushKey } from '../../../__tests__/fixtures-ios';
import { RemovePushKey } from '../RemovePushKey';
jest.mock('../../../../prompts');
@@ -12,8 +10,7 @@ asMock(confirmAsync).mockImplementation(() => true);
describe(RemovePushKey, () => {
it('deletes the push key on Expo and Apple servers in Interactive Mode', async () => {
const ctx = createCtxMock({ nonInteractive: false });
const appLookupParams = getAppLookupParamsFromContext(ctx, findApplicationTarget(testTargets));
const removePushKeyAction = new RemovePushKey(appLookupParams.account, testPushKey);
const removePushKeyAction = new RemovePushKey(testPushKey);
await removePushKeyAction.runAsync(ctx);
// expect push key to be deleted on expo servers
@@ -23,8 +20,7 @@ describe(RemovePushKey, () => {
});
it('errors in Non-Interactive Mode', async () => {
const ctx = createCtxMock({ nonInteractive: true });
const appLookupParams = getAppLookupParamsFromContext(ctx, findApplicationTarget(testTargets));
const removePushKeyAction = new RemovePushKey(appLookupParams.account, testPushKey);
const removePushKeyAction = new RemovePushKey(testPushKey);
await expect(removePushKeyAction.runAsync(ctx)).rejects.toThrowError();
});
});
@@ -86,16 +86,14 @@ export default class AppStoreApi {
public async useExistingProvisioningProfileAsync(
bundleIdentifier: string,
provisioningProfile: ProvisioningProfile,
distCert: DistributionCertificate,
profileClass?: ProfileClass
distCert: DistributionCertificate
): Promise<ProvisioningProfile> {
const ctx = await this.ensureAuthenticatedAsync();
return await useExistingProvisioningProfileAsync(
ctx,
bundleIdentifier,
provisioningProfile,
distCert,
profileClass
distCert
);
}
@@ -10,7 +10,7 @@ function mockCapabilities(Apple: any): void {
},
]);
Apple.MerchantId.createAsync = jest.fn((ctx, { identifier }) => ({
Apple.MerchantId.createAsync = jest.fn((_ctx, { identifier }) => ({
id: 'XXX-merch-2',
attributes: {
identifier,
@@ -25,7 +25,7 @@ function mockCapabilities(Apple: any): void {
},
},
]);
Apple.AppGroup.createAsync = jest.fn((ctx, { identifier }) => ({
Apple.AppGroup.createAsync = jest.fn((_ctx, { identifier }) => ({
id: 'XXX-group-2',
attributes: {
identifier,
@@ -41,7 +41,7 @@ function mockCapabilities(Apple: any): void {
},
]);
Apple.CloudContainer.createAsync = jest.fn((ctx, { identifier }) => ({
Apple.CloudContainer.createAsync = jest.fn((_ctx, { identifier }) => ({
id: 'XXX-icloud-2',
attributes: {
identifier,
@@ -150,7 +150,7 @@ describe(syncCapabilityIdentifiersForEntitlementsAsync, () => {
const Apple = require('@expo/apple-utils');
mockCapabilities(Apple);
Apple.MerchantId.createAsync = jest.fn(
(ctx: any, { identifier }: { identifier: string }): any => {
(_ctx: any, { identifier }: { identifier: string }): any => {
// e2e test with: merchant.expodemo
throw new Error(
`There is a problem with the request entity - A Merchant ID with Identifier '${identifier}' is not available. Please enter a different string.`
@@ -77,8 +77,7 @@ export async function useExistingProvisioningProfileAsync(
authCtx: AuthCtx,
bundleIdentifier: string,
provisioningProfile: ProvisioningProfile,
distCert: DistributionCertificate,
profileClass: ProfileClass = ProfileClass.General
distCert: DistributionCertificate
): Promise<ProvisioningProfile> {
if (!provisioningProfile.provisioningProfileId) {
throw new Error('Provisioning profile: cannot use existing profile, insufficient id');
+29
View File
@@ -0,0 +1,29 @@
import { Agent } from 'https';
import createHttpsProxyAgent from 'https-proxy-agent';
import fetch, { RequestInfo, RequestInit, Response } from 'node-fetch';
export * from 'node-fetch';
export class RequestError extends Error {
constructor(message: string, public readonly response: Response) {
super(message);
}
}
function createHttpAgent(): Agent | null {
const httpProxyUrl = process.env.http_proxy;
if (!httpProxyUrl) {
return null;
}
return createHttpsProxyAgent(httpProxyUrl);
}
export const httpProxyAgent: Agent | null = createHttpAgent();
export default async function (url: RequestInfo, init?: RequestInit): Promise<Response> {
const response = await fetch(url, init);
if (response.status >= 400) {
throw new RequestError(`Request failed: ${response.status} (${response.statusText})`, response);
}
return response;
}
+18 -27
View File
@@ -12,23 +12,13 @@ import {
} from '@urql/core';
import { retryExchange } from '@urql/exchange-retry';
import { DocumentNode } from 'graphql';
// node-fetch is used here because @urql/core uses the fetch API under the hood
// don't use node-fetch elsewhere
// eslint-disable-next-line
import fetch from 'node-fetch';
import { getExpoApiBaseUrl } from '../api';
import { httpProxyAgent } from '../fetch';
import Log from '../log';
import { getAccessToken, getSessionSecret } from '../user/sessionStorage';
type AccessTokenHeaders = {
authorization: string;
};
type SessionHeaders = {
'expo-session': string;
};
export const graphqlClient = createUrqlClient({
url: getExpoApiBaseUrl() + '/graphql',
exchanges: [
@@ -36,31 +26,32 @@ export const graphqlClient = createUrqlClient({
cacheExchange,
retryExchange({
maxDelayMs: 4000,
retryIf: err =>
!!(err && (err.networkError || err.graphQLErrors.some(e => e?.extensions?.isTransient))),
retryIf: (err, operation) => {
return !!(
err &&
!operation.context.noRetry &&
(err.networkError || err.graphQLErrors.some(e => e?.extensions?.isTransient))
);
},
}),
fetchExchange,
],
// @ts-expect-error Type 'typeof fetch' is not assignable to type '(input: RequestInfo, init?: RequestInit | undefined) => Promise<Response>'.
fetch,
fetchOptions: (): { headers?: AccessTokenHeaders | SessionHeaders } => {
fetchOptions: (): RequestInit => {
const headers: Record<string, string> = {};
const token = getAccessToken();
if (token) {
return {
headers: {
authorization: `Bearer ${token}`,
},
};
headers.authorization = `Bearer ${token}`;
}
const sessionSecret = getSessionSecret();
if (sessionSecret) {
return {
headers: {
'expo-session': sessionSecret,
},
};
if (!token && sessionSecret) {
headers['expo-session'] = sessionSecret;
}
return {};
return {
...(httpProxyAgent ? { agent: httpProxyAgent } : {}),
headers,
};
},
}) as StricterClient;
@@ -84,7 +75,7 @@ export async function withErrorHandlingAsync<T>(promise: Promise<OperationResult
throw error;
}
// Check for malfolmed response. This only checks the root query existence,
// Check for malformed response. This only checks the root query existence,
// It doesn't affect returning responses with empty resultset.
if (!data) {
throw new Error('Returned query result data is null!');
+181 -136
View File
@@ -29,7 +29,7 @@ export type Scalars = {
export type AcceptUserInvitationResult = {
__typename?: 'AcceptUserInvitationResult';
success?: Maybe<Scalars['Boolean']>;
success: Scalars['Boolean'];
};
/** A method of authentication for an Actor */
@@ -261,28 +261,28 @@ export type AccountMutation = {
/** Cancel scheduled subscription change */
cancelScheduledSubscriptionChange: Account;
/** Cancels the active subscription */
cancelSubscription?: Maybe<Account>;
cancelSubscription: Account;
/** Upgrades or downgrades the active subscription to the newPlanIdentifier, which must be one of the EAS plans (i.e., Production or Enterprise). */
changePlan: Account;
/** Add specified account Permissions for Actor. Actor must already have at least one permission on the account. */
grantActorPermissions?: Maybe<Account>;
grantActorPermissions: Account;
/** Rename this account and the primary user's username if this account is a personal account */
rename: Account;
/** Requests a refund for the specified charge. Returns true if auto-refund was possible, otherwise requests a manual refund from support and returns false. */
requestRefund?: Maybe<Scalars['Boolean']>;
requestRefund: Scalars['Boolean'];
/** Revoke specified Permissions for Actor. Actor must already have at least one permission on the account. */
revokeActorPermissions?: Maybe<Account>;
revokeActorPermissions: Account;
/**
* Update setting to purchase new build packs when the current one is consumed
* @deprecated Build packs are no longer supported
*/
setBuildAutoRenew?: Maybe<Account>;
/** Set payment details */
setPaymentSource?: Maybe<Account>;
setPaymentSource: Account;
/** Require authorization to send push notifications for experiences owned by this account */
setPushSecurityEnabled?: Maybe<Account>;
setPushSecurityEnabled: Account;
/** Add a subscription */
subscribeToProduct?: Maybe<Account>;
subscribeToProduct: Account;
};
@@ -484,15 +484,15 @@ export type AndroidAppBuildCredentialsInput = {
export type AndroidAppBuildCredentialsMutation = {
__typename?: 'AndroidAppBuildCredentialsMutation';
/** Create a set of build credentials for an Android app */
createAndroidAppBuildCredentials?: Maybe<AndroidAppBuildCredentials>;
createAndroidAppBuildCredentials: AndroidAppBuildCredentials;
/** delete a set of build credentials for an Android app */
deleteAndroidAppBuildCredentials?: Maybe<DeleteAndroidAppBuildCredentialsResult>;
deleteAndroidAppBuildCredentials: DeleteAndroidAppBuildCredentialsResult;
/** Set the build credentials to be the default for the Android app */
setDefault?: Maybe<AndroidAppBuildCredentials>;
setDefault: AndroidAppBuildCredentials;
/** Set the keystore to be used for an Android app */
setKeystore?: Maybe<AndroidAppBuildCredentials>;
setKeystore: AndroidAppBuildCredentials;
/** Set the name of a set of build credentials to be used for an Android app */
setName?: Maybe<AndroidAppBuildCredentials>;
setName: AndroidAppBuildCredentials;
};
@@ -550,11 +550,11 @@ export type AndroidAppCredentialsInput = {
export type AndroidAppCredentialsMutation = {
__typename?: 'AndroidAppCredentialsMutation';
/** Create a set of credentials for an Android app */
createAndroidAppCredentials?: Maybe<AndroidAppCredentials>;
createAndroidAppCredentials: AndroidAppCredentials;
/** Set the FCM push key to be used in an Android app */
setFcm?: Maybe<AndroidAppCredentials>;
setFcm: AndroidAppCredentials;
/** Set the Google Service Account Key to be used for submitting an Android app */
setGoogleServiceAccountKeyForSubmissions?: Maybe<AndroidAppCredentials>;
setGoogleServiceAccountKeyForSubmissions: AndroidAppCredentials;
};
@@ -804,8 +804,6 @@ export type App = Project & {
pushSecurityEnabled: Scalars['Boolean'];
/** Classic update release channel names (to be removed) */
releaseChannels: Array<Scalars['String']>;
/** @deprecated No longer supported */
releases: Array<Maybe<AppRelease>>;
/** @deprecated Legacy access tokens are deprecated */
requiresAccessTokenForPushSecurity: Scalars['Boolean'];
/** SDK version of the latest classic update publish, 0.0.0 otherwise */
@@ -825,6 +823,8 @@ export type App = Project & {
updateChannels: Array<UpdateChannel>;
/** Time of last classic update publish */
updated: Scalars['DateTime'];
/** EAS updates owned by an app */
updates: Array<Update>;
/** @deprecated Use ownerAccount.name instead */
username: Scalars['String'];
/** @deprecated No longer supported */
@@ -917,14 +917,6 @@ export type AppLikedByArgs = {
};
/** Represents an Exponent App (or Experience in legacy terms) */
export type AppReleasesArgs = {
limit?: InputMaybe<Scalars['Int']>;
offset?: InputMaybe<Scalars['Int']>;
platform: AppPlatform;
};
/** Represents an Exponent App (or Experience in legacy terms) */
export type AppSubmissionsArgs = {
filter: SubmissionFilter;
@@ -959,6 +951,13 @@ export type AppUpdateChannelsArgs = {
};
/** Represents an Exponent App (or Experience in legacy terms) */
export type AppUpdatesArgs = {
limit: Scalars['Int'];
offset: Scalars['Int'];
};
/** Represents an Exponent App (or Experience in legacy terms) */
export type AppWebhooksArgs = {
filter?: InputMaybe<WebhookFilter>;
@@ -991,7 +990,7 @@ export type AppMutation = {
/** @deprecated No longer supported */
grantAccess?: Maybe<App>;
/** Require api token to send push notifs for experience */
setPushSecurityEnabled?: Maybe<App>;
setPushSecurityEnabled: App;
};
@@ -1151,7 +1150,7 @@ export type AppleAppIdentifierInput = {
export type AppleAppIdentifierMutation = {
__typename?: 'AppleAppIdentifierMutation';
/** Create an Identifier for an iOS App */
createAppleAppIdentifier?: Maybe<AppleAppIdentifier>;
createAppleAppIdentifier: AppleAppIdentifier;
};
@@ -1454,7 +1453,7 @@ export type AssetMutation = {
* Returns an array of specifications for upload. Each URL is valid for an hour.
* The content type of the asset you wish to upload must be specified.
*/
getSignedAssetUploadSpecifications?: Maybe<GetSignedAssetUploadSpecificationsResult>;
getSignedAssetUploadSpecifications: GetSignedAssetUploadSpecificationsResult;
};
@@ -1508,7 +1507,10 @@ export type Build = ActivityTimelineProjectActivity & BuildOrBuildJob & {
logFiles: Array<Scalars['String']>;
metrics?: Maybe<BuildMetrics>;
platform: AppPlatform;
priority: BuildPriority;
project: Project;
/** Queue position is 1-indexed */
queuePosition?: Maybe<Scalars['Int']>;
reactNativeVersion?: Maybe<Scalars['String']>;
releaseChannel?: Maybe<Scalars['String']>;
runtimeVersion?: Maybe<Scalars['String']>;
@@ -1598,9 +1600,9 @@ export enum BuildJobLogsFormat {
export type BuildJobMutation = {
__typename?: 'BuildJobMutation';
cancel?: Maybe<BuildJob>;
cancel: BuildJob;
del?: Maybe<BuildJob>;
restart?: Maybe<BuildJob>;
restart: BuildJob;
};
export type BuildJobQuery = {
@@ -1717,6 +1719,11 @@ export type BuildOrBuildJob = {
id: Scalars['ID'];
};
export enum BuildPriority {
High = 'HIGH',
Normal = 'NORMAL'
}
/** Publicly visible data for a Build. */
export type BuildPublicData = {
__typename?: 'BuildPublicData';
@@ -1864,9 +1871,9 @@ export type CreateAccessTokenInput = {
export type CreateAccessTokenResponse = {
__typename?: 'CreateAccessTokenResponse';
/** AccessToken created */
accessToken?: Maybe<AccessToken>;
accessToken: AccessToken;
/** Full token string to be used for authentication */
token?: Maybe<Scalars['String']>;
token: Scalars['String'];
};
export type CreateAndroidSubmissionInput = {
@@ -2016,7 +2023,7 @@ export type EditUpdateBranchInput = {
export type EmailSubscriptionMutation = {
__typename?: 'EmailSubscriptionMutation';
addUser?: Maybe<AddUserPayload>;
addUser: AddUserPayload;
};
@@ -2098,7 +2105,7 @@ export enum Feature {
export type GetSignedAssetUploadSpecificationsResult = {
__typename?: 'GetSignedAssetUploadSpecificationsResult';
specifications: Array<Maybe<Scalars['String']>>;
specifications: Array<Scalars['String']>;
};
export type GoogleServiceAccountKey = {
@@ -2177,8 +2184,16 @@ export type InvoiceLineItem = {
description: Scalars['String'];
id: Scalars['ID'];
period: InvoicePeriod;
plan: InvoiceLineItemPlan;
proration: Scalars['Boolean'];
quantity: Scalars['Int'];
title: Scalars['String'];
};
export type InvoiceLineItemPlan = {
__typename?: 'InvoiceLineItemPlan';
id: Scalars['ID'];
name: Scalars['String'];
};
export type InvoicePeriod = {
@@ -2439,13 +2454,13 @@ export type MeMutation = {
/** Certify an initiated second factor authentication method for the current user */
certifySecondFactorDevice: SecondFactorBooleanResult;
/** Create a new Account and grant this User the owner Role */
createAccount?: Maybe<Account>;
createAccount: Account;
/** Delete an Account created via createAccount */
deleteAccount: DeleteAccountResult;
/** Delete a second factor device */
deleteSecondFactorDevice: SecondFactorBooleanResult;
/** Delete a Snack that the current user owns */
deleteSnack?: Maybe<Snack>;
deleteSnack: Snack;
/** Disable all second factor authentication for the current user */
disableSecondFactorAuthentication: SecondFactorBooleanResult;
/** Initiate setup of two-factor authentication for the current user */
@@ -2463,11 +2478,11 @@ export type MeMutation = {
/** Transfer project to a different Account */
transferApp: App;
/** Unpublish an App that the current user owns */
unpublishApp?: Maybe<App>;
unpublishApp: App;
/** Update an App that the current user owns */
updateApp?: Maybe<App>;
updateApp: App;
/** Update the current user's data */
updateProfile?: Maybe<User>;
updateProfile: User;
};
@@ -2509,7 +2524,7 @@ export type MeMutationDisableSecondFactorAuthenticationArgs = {
export type MeMutationInitiateSecondFactorAuthenticationArgs = {
deviceConfigurations: Array<InputMaybe<SecondFactorDeviceConfiguration>>;
deviceConfigurations: Array<SecondFactorDeviceConfiguration>;
recaptchaResponseToken?: InputMaybe<Scalars['String']>;
};
@@ -2680,6 +2695,7 @@ export type PublicArtifacts = {
};
export type PublishUpdateGroupInput = {
awaitingCodeSigningInfo?: InputMaybe<Scalars['Boolean']>;
branchId: Scalars['String'];
message?: InputMaybe<Scalars['String']>;
runtimeVersion: Scalars['String'];
@@ -2768,7 +2784,7 @@ export type RootMutation = {
/** Mutations that create, read, update, and delete AccessTokens for Actors */
accessToken: AccessTokenMutation;
/** Mutations that modify an Account */
account?: Maybe<AccountMutation>;
account: AccountMutation;
/** Mutations that modify the build credentials for an Android app */
androidAppBuildCredentials: AndroidAppBuildCredentialsMutation;
/** Mutations that modify the credentials for an Android app */
@@ -2797,9 +2813,9 @@ export type RootMutation = {
appleTeam: AppleTeamMutation;
asset: AssetMutation;
/** Mutations that modify an EAS Build */
build?: Maybe<BuildMutation>;
build: BuildMutation;
/** Mutations that modify an BuildJob */
buildJob?: Maybe<BuildJobMutation>;
buildJob: BuildJobMutation;
/** Mutations that modify an EmailSubscription */
emailSubscription: EmailSubscriptionMutation;
/** Mutations that create and delete EnvironmentSecrets */
@@ -2812,7 +2828,7 @@ export type RootMutation = {
iosAppCredentials: IosAppCredentialsMutation;
keystoreGenerationUrl: KeystoreGenerationUrlMutation;
/** Mutations that modify the currently authenticated User */
me?: Maybe<MeMutation>;
me: MeMutation;
/** Mutations that create, update, and delete Robots */
robot: RobotMutation;
/** Mutations that modify an EAS Submit submission */
@@ -2964,8 +2980,8 @@ export type SecondFactorDeviceConfigurationResult = {
export type SecondFactorInitiationResult = {
__typename?: 'SecondFactorInitiationResult';
configurationResults: Array<Maybe<SecondFactorDeviceConfigurationResult>>;
plaintextBackupCodes: Array<Maybe<Scalars['String']>>;
configurationResults: Array<SecondFactorDeviceConfigurationResult>;
plaintextBackupCodes: Array<Scalars['String']>;
};
export enum SecondFactorMethod {
@@ -2977,7 +2993,7 @@ export enum SecondFactorMethod {
export type SecondFactorRegenerateBackupCodesResult = {
__typename?: 'SecondFactorRegenerateBackupCodesResult';
plaintextBackupCodes: Array<Maybe<Scalars['String']>>;
plaintextBackupCodes: Array<Scalars['String']>;
};
export type Snack = Project & {
@@ -2986,6 +3002,8 @@ export type Snack = Project & {
description: Scalars['String'];
/** Full name of the Snack, e.g. "@john/mysnack", "@snack/245631" */
fullName: Scalars['String'];
/** Has the Snack been run without errors */
hasBeenRunSuccessfully?: Maybe<Scalars['Boolean']>;
hashId: Scalars['String'];
/** @deprecated No longer supported */
iconUrl?: Maybe<Scalars['String']>;
@@ -2994,6 +3012,8 @@ export type Snack = Project & {
isDraft: Scalars['Boolean'];
/** Name of the Snack, e.g. "My Snack" */
name: Scalars['String'];
/** Preview image of the running snack */
previewImage?: Maybe<Scalars['String']>;
published: Scalars['Boolean'];
/** Slug name, e.g. "mysnack", "245631" */
slug: Scalars['String'];
@@ -3042,6 +3062,7 @@ export type Submission = ActivityTimelineProjectActivity & {
actor?: Maybe<Actor>;
androidConfig?: Maybe<AndroidSubmissionConfig>;
app: App;
cancelingActor?: Maybe<Actor>;
createdAt: Scalars['DateTime'];
error?: Maybe<SubmissionError>;
id: Scalars['ID'];
@@ -3086,6 +3107,8 @@ export type SubmissionFilter = {
export type SubmissionMutation = {
__typename?: 'SubmissionMutation';
/** Cancel an EAS Submit submission */
cancelSubmission: Submission;
/** Create an Android EAS Submit submission */
createAndroidSubmission: CreateSubmissionResult;
/** Create an iOS EAS Submit submission */
@@ -3098,6 +3121,11 @@ export type SubmissionMutation = {
};
export type SubmissionMutationCancelSubmissionArgs = {
submissionId?: InputMaybe<Scalars['ID']>;
};
export type SubmissionMutationCreateAndroidSubmissionArgs = {
input: CreateAndroidSubmissionInput;
};
@@ -3152,6 +3180,7 @@ export type Update = ActivityTimelineProjectActivity & {
__typename?: 'Update';
activityTimestamp: Scalars['DateTime'];
actor?: Maybe<Actor>;
awaitingCodeSigningInfo: Scalars['Boolean'];
branch: UpdateBranch;
branchId: Scalars['ID'];
codeSigningInfo?: Maybe<CodeSigningInfo>;
@@ -3186,7 +3215,7 @@ export type UpdateBranchUpdatesArgs = {
export type UpdateBranchMutation = {
__typename?: 'UpdateBranchMutation';
/** Create an EAS branch for an app */
createUpdateBranchForApp?: Maybe<UpdateBranch>;
createUpdateBranchForApp: UpdateBranch;
/** Delete an EAS branch and all of its updates as long as the branch is not being used by any channels */
deleteUpdateBranch: DeleteUpdateBranchResult;
/**
@@ -3244,7 +3273,7 @@ export type UpdateChannelMutation = {
* In order to work with GraphQL formatting, the branchMapping should be a
* stringified JSON supplied to the mutation as a variable.
*/
createUpdateChannelForApp?: Maybe<UpdateChannel>;
createUpdateChannelForApp: UpdateChannel;
/** delete an EAS channel that doesn't point to any branches */
deleteUpdateChannel: DeleteUpdateChannelResult;
/**
@@ -3253,7 +3282,7 @@ export type UpdateChannelMutation = {
* In order to work with GraphQL formatting, the branchMapping should be a
* stringified JSON supplied to the mutation as a variable.
*/
editUpdateChannel?: Maybe<UpdateChannel>;
editUpdateChannel: UpdateChannel;
};
@@ -3656,7 +3685,7 @@ export type CreateUpdateBranchForAppMutationVariables = Exact<{
}>;
export type CreateUpdateBranchForAppMutation = { __typename?: 'RootMutation', updateBranch: { __typename?: 'UpdateBranchMutation', createUpdateBranchForApp?: { __typename?: 'UpdateBranch', id: string, name: string } | null | undefined } };
export type CreateUpdateBranchForAppMutation = { __typename?: 'RootMutation', updateBranch: { __typename?: 'UpdateBranchMutation', createUpdateBranchForApp: { __typename?: 'UpdateBranch', id: string, name: string } } };
export type GetBranchInfoQueryVariables = Exact<{
appId: Scalars['String'];
@@ -3664,7 +3693,7 @@ export type GetBranchInfoQueryVariables = Exact<{
}>;
export type GetBranchInfoQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateBranchByName?: { __typename?: 'UpdateBranch', id: string, name: string } | null | undefined } } };
export type GetBranchInfoQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateBranchByName?: { __typename?: 'UpdateBranch', id: string, name: string } | null } } };
export type DeleteUpdateBranchMutationVariables = Exact<{
branchId: Scalars['ID'];
@@ -3679,7 +3708,7 @@ export type BranchesByAppQueryVariables = Exact<{
}>;
export type BranchesByAppQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateBranches: Array<{ __typename?: 'UpdateBranch', id: string, name: string, updates: Array<{ __typename?: 'Update', id: string, createdAt: any, message?: string | null | undefined, runtimeVersion: string, group: string, platform: string, actor?: { __typename: 'Robot', firstName?: string | null | undefined, id: string } | { __typename: 'User', username: string, id: string } | null | undefined }> }> } } };
export type BranchesByAppQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateBranches: Array<{ __typename?: 'UpdateBranch', id: string, name: string, updates: Array<{ __typename?: 'Update', id: string, createdAt: any, message?: string | null, runtimeVersion: string, group: string, platform: string, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'User', username: string, id: string } | null }> }> } } };
export type EditUpdateBranchMutationVariables = Exact<{
input: EditUpdateBranchInput;
@@ -3693,7 +3722,7 @@ export type CancelBuildMutationVariables = Exact<{
}>;
export type CancelBuildMutation = { __typename?: 'RootMutation', build?: { __typename?: 'BuildMutation', cancel: { __typename?: 'Build', id: string, status: BuildStatus } } | null | undefined };
export type CancelBuildMutation = { __typename?: 'RootMutation', build: { __typename?: 'BuildMutation', cancel: { __typename?: 'Build', id: string, status: BuildStatus } } };
export type CreateUpdateChannelOnAppMutationVariables = Exact<{
appId: Scalars['ID'];
@@ -3702,7 +3731,7 @@ export type CreateUpdateChannelOnAppMutationVariables = Exact<{
}>;
export type CreateUpdateChannelOnAppMutation = { __typename?: 'RootMutation', updateChannel: { __typename?: 'UpdateChannelMutation', createUpdateChannelForApp?: { __typename?: 'UpdateChannel', id: string, name: string, branchMapping: string } | null | undefined } };
export type CreateUpdateChannelOnAppMutation = { __typename?: 'RootMutation', updateChannel: { __typename?: 'UpdateChannelMutation', createUpdateChannelForApp: { __typename?: 'UpdateChannel', id: string, name: string, branchMapping: string } } };
export type GetChannelInfoQueryVariables = Exact<{
appId: Scalars['String'];
@@ -3710,7 +3739,7 @@ export type GetChannelInfoQueryVariables = Exact<{
}>;
export type GetChannelInfoQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateChannelByName?: { __typename?: 'UpdateChannel', id: string, name: string } | null | undefined } } };
export type GetChannelInfoQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateChannelByName?: { __typename?: 'UpdateChannel', id: string, name: string } | null } } };
export type DeleteUpdateChannelMutationVariables = Exact<{
channelId: Scalars['ID'];
@@ -3725,7 +3754,7 @@ export type GetChannelByNameToEditQueryVariables = Exact<{
}>;
export type GetChannelByNameToEditQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateChannelByName?: { __typename?: 'UpdateChannel', id: string, name: string, updateBranches: Array<{ __typename?: 'UpdateBranch', id: string, name: string }> } | null | undefined } } };
export type GetChannelByNameToEditQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateChannelByName?: { __typename?: 'UpdateChannel', id: string, name: string, updateBranches: Array<{ __typename?: 'UpdateBranch', id: string, name: string }> } | null } } };
export type UpdateChannelBranchMappingMutationVariables = Exact<{
channelId: Scalars['ID'];
@@ -3733,7 +3762,7 @@ export type UpdateChannelBranchMappingMutationVariables = Exact<{
}>;
export type UpdateChannelBranchMappingMutation = { __typename?: 'RootMutation', updateChannel: { __typename?: 'UpdateChannelMutation', editUpdateChannel?: { __typename?: 'UpdateChannel', id: string, name: string, branchMapping: string } | null | undefined } };
export type UpdateChannelBranchMappingMutation = { __typename?: 'RootMutation', updateChannel: { __typename?: 'UpdateChannelMutation', editUpdateChannel: { __typename?: 'UpdateChannel', id: string, name: string, branchMapping: string } } };
export type GetAllChannelsForAppQueryVariables = Exact<{
appId: Scalars['String'];
@@ -3742,15 +3771,7 @@ export type GetAllChannelsForAppQueryVariables = Exact<{
}>;
export type GetAllChannelsForAppQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateChannels: Array<{ __typename?: 'UpdateChannel', id: string, name: string, branchMapping: string, updateBranches: Array<{ __typename?: 'UpdateBranch', id: string, name: string, updates: Array<{ __typename?: 'Update', id: string, group: string, message?: string | null | undefined, runtimeVersion: string, createdAt: any, platform: string, actor?: { __typename?: 'Robot', firstName?: string | null | undefined, id: string } | { __typename?: 'User', username: string, id: string } | null | undefined }> }> }> } } };
export type GetChannelByNameForAppQueryVariables = Exact<{
appId: Scalars['String'];
channelName: Scalars['String'];
}>;
export type GetChannelByNameForAppQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateChannelByName?: { __typename?: 'UpdateChannel', id: string, name: string, createdAt: any, branchMapping: string, updateBranches: Array<{ __typename?: 'UpdateBranch', id: string, name: string, updates: Array<{ __typename?: 'Update', id: string, group: string, message?: string | null | undefined, runtimeVersion: string, createdAt: any, platform: string, actor?: { __typename?: 'Robot', firstName?: string | null | undefined, id: string } | { __typename?: 'User', username: string, id: string } | null | undefined }> }> } | null | undefined } } };
export type GetAllChannelsForAppQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateChannels: Array<{ __typename?: 'UpdateChannel', id: string, name: string, branchMapping: string, updateBranches: Array<{ __typename?: 'UpdateBranch', id: string, name: string, updates: Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, runtimeVersion: string, createdAt: any, platform: string, actor?: { __typename?: 'Robot', firstName?: string | null, id: string } | { __typename?: 'User', username: string, id: string } | null }> }> }> } } };
export type AppInfoQueryVariables = Exact<{
appId: Scalars['String'];
@@ -3771,14 +3792,14 @@ export type GetUpdateGroupAsyncQueryVariables = Exact<{
}>;
export type GetUpdateGroupAsyncQuery = { __typename?: 'RootQuery', updatesByGroup: Array<{ __typename?: 'Update', id: string, group: string, runtimeVersion: string, manifestFragment: string, platform: string, message?: string | null | undefined }> };
export type GetUpdateGroupAsyncQuery = { __typename?: 'RootQuery', updatesByGroup: Array<{ __typename?: 'Update', id: string, group: string, runtimeVersion: string, manifestFragment: string, platform: string, message?: string | null }> };
export type UpdatesByGroupQueryVariables = Exact<{
groupId: Scalars['ID'];
}>;
export type UpdatesByGroupQuery = { __typename?: 'RootQuery', updatesByGroup: Array<{ __typename?: 'Update', id: string, group: string, runtimeVersion: string, platform: string, message?: string | null | undefined, createdAt: any, actor?: { __typename?: 'Robot', firstName?: string | null | undefined, id: string } | { __typename?: 'User', username: string, id: string } | null | undefined }> };
export type UpdatesByGroupQuery = { __typename?: 'RootQuery', updatesByGroup: Array<{ __typename?: 'Update', id: string, group: string, runtimeVersion: string, platform: string, message?: string | null, createdAt: any, actor?: { __typename?: 'Robot', firstName?: string | null, id: string } | { __typename?: 'User', username: string, id: string } | null }> };
export type CreateAndroidAppBuildCredentialsMutationVariables = Exact<{
androidAppBuildCredentialsInput: AndroidAppBuildCredentialsInput;
@@ -3786,7 +3807,7 @@ export type CreateAndroidAppBuildCredentialsMutationVariables = Exact<{
}>;
export type CreateAndroidAppBuildCredentialsMutation = { __typename?: 'RootMutation', androidAppBuildCredentials: { __typename?: 'AndroidAppBuildCredentialsMutation', createAndroidAppBuildCredentials?: { __typename?: 'AndroidAppBuildCredentials', id: string, isDefault: boolean, isLegacy: boolean, name: string, androidKeystore?: { __typename?: 'AndroidKeystore', id: string, type: AndroidKeystoreType, keystore: string, keystorePassword: string, keyAlias: string, keyPassword?: string | null | undefined, md5CertificateFingerprint?: string | null | undefined, sha1CertificateFingerprint?: string | null | undefined, sha256CertificateFingerprint?: string | null | undefined, createdAt: any, updatedAt: any } | null | undefined } | null | undefined } };
export type CreateAndroidAppBuildCredentialsMutation = { __typename?: 'RootMutation', androidAppBuildCredentials: { __typename?: 'AndroidAppBuildCredentialsMutation', createAndroidAppBuildCredentials: { __typename?: 'AndroidAppBuildCredentials', id: string, isDefault: boolean, isLegacy: boolean, name: string, androidKeystore?: { __typename?: 'AndroidKeystore', id: string, type: AndroidKeystoreType, keystore: string, keystorePassword: string, keyAlias: string, keyPassword?: string | null, md5CertificateFingerprint?: string | null, sha1CertificateFingerprint?: string | null, sha256CertificateFingerprint?: string | null, createdAt: any, updatedAt: any } | null } } };
export type SetKeystoreMutationVariables = Exact<{
androidAppBuildCredentialsId: Scalars['ID'];
@@ -3794,7 +3815,7 @@ export type SetKeystoreMutationVariables = Exact<{
}>;
export type SetKeystoreMutation = { __typename?: 'RootMutation', androidAppBuildCredentials: { __typename?: 'AndroidAppBuildCredentialsMutation', setKeystore?: { __typename?: 'AndroidAppBuildCredentials', id: string, isDefault: boolean, isLegacy: boolean, name: string, androidKeystore?: { __typename?: 'AndroidKeystore', id: string, type: AndroidKeystoreType, keystore: string, keystorePassword: string, keyAlias: string, keyPassword?: string | null | undefined, md5CertificateFingerprint?: string | null | undefined, sha1CertificateFingerprint?: string | null | undefined, sha256CertificateFingerprint?: string | null | undefined, createdAt: any, updatedAt: any } | null | undefined } | null | undefined } };
export type SetKeystoreMutation = { __typename?: 'RootMutation', androidAppBuildCredentials: { __typename?: 'AndroidAppBuildCredentialsMutation', setKeystore: { __typename?: 'AndroidAppBuildCredentials', id: string, isDefault: boolean, isLegacy: boolean, name: string, androidKeystore?: { __typename?: 'AndroidKeystore', id: string, type: AndroidKeystoreType, keystore: string, keystorePassword: string, keyAlias: string, keyPassword?: string | null, md5CertificateFingerprint?: string | null, sha1CertificateFingerprint?: string | null, sha256CertificateFingerprint?: string | null, createdAt: any, updatedAt: any } | null } } };
export type CreateAndroidAppCredentialsMutationVariables = Exact<{
androidAppCredentialsInput: AndroidAppCredentialsInput;
@@ -3803,7 +3824,7 @@ export type CreateAndroidAppCredentialsMutationVariables = Exact<{
}>;
export type CreateAndroidAppCredentialsMutation = { __typename?: 'RootMutation', androidAppCredentials: { __typename?: 'AndroidAppCredentialsMutation', createAndroidAppCredentials?: { __typename?: 'AndroidAppCredentials', id: string, applicationIdentifier?: string | null | undefined, isLegacy: boolean, app: { __typename?: 'App', id: string, fullName: string, slug: string }, androidFcm?: { __typename?: 'AndroidFcm', id: string, credential: any, version: AndroidFcmVersion, createdAt: any, updatedAt: any, snippet: { __typename?: 'FcmSnippetLegacy', firstFourCharacters: string, lastFourCharacters: string } | { __typename?: 'FcmSnippetV1', projectId: string, keyId: string, serviceAccountEmail: string, clientId?: string | null | undefined } } | null | undefined, googleServiceAccountKeyForSubmissions?: { __typename?: 'GoogleServiceAccountKey', id: string, projectIdentifier: string, privateKeyIdentifier: string, clientEmail: string, clientIdentifier: string, createdAt: any, updatedAt: any } | null | undefined, androidAppBuildCredentialsList: Array<{ __typename?: 'AndroidAppBuildCredentials', id: string, isDefault: boolean, isLegacy: boolean, name: string, androidKeystore?: { __typename?: 'AndroidKeystore', id: string, type: AndroidKeystoreType, keystore: string, keystorePassword: string, keyAlias: string, keyPassword?: string | null | undefined, md5CertificateFingerprint?: string | null | undefined, sha1CertificateFingerprint?: string | null | undefined, sha256CertificateFingerprint?: string | null | undefined, createdAt: any, updatedAt: any } | null | undefined }> } | null | undefined } };
export type CreateAndroidAppCredentialsMutation = { __typename?: 'RootMutation', androidAppCredentials: { __typename?: 'AndroidAppCredentialsMutation', createAndroidAppCredentials: { __typename?: 'AndroidAppCredentials', id: string, applicationIdentifier?: string | null, isLegacy: boolean, app: { __typename?: 'App', id: string, fullName: string, slug: string }, androidFcm?: { __typename?: 'AndroidFcm', id: string, credential: any, version: AndroidFcmVersion, createdAt: any, updatedAt: any, snippet: { __typename?: 'FcmSnippetLegacy', firstFourCharacters: string, lastFourCharacters: string } | { __typename?: 'FcmSnippetV1', projectId: string, keyId: string, serviceAccountEmail: string, clientId?: string | null } } | null, googleServiceAccountKeyForSubmissions?: { __typename?: 'GoogleServiceAccountKey', id: string, projectIdentifier: string, privateKeyIdentifier: string, clientEmail: string, clientIdentifier: string, createdAt: any, updatedAt: any } | null, androidAppBuildCredentialsList: Array<{ __typename?: 'AndroidAppBuildCredentials', id: string, isDefault: boolean, isLegacy: boolean, name: string, androidKeystore?: { __typename?: 'AndroidKeystore', id: string, type: AndroidKeystoreType, keystore: string, keystorePassword: string, keyAlias: string, keyPassword?: string | null, md5CertificateFingerprint?: string | null, sha1CertificateFingerprint?: string | null, sha256CertificateFingerprint?: string | null, createdAt: any, updatedAt: any } | null }> } } };
export type SetFcmMutationVariables = Exact<{
androidAppCredentialsId: Scalars['ID'];
@@ -3811,7 +3832,7 @@ export type SetFcmMutationVariables = Exact<{
}>;
export type SetFcmMutation = { __typename?: 'RootMutation', androidAppCredentials: { __typename?: 'AndroidAppCredentialsMutation', setFcm?: { __typename?: 'AndroidAppCredentials', id: string, applicationIdentifier?: string | null | undefined, isLegacy: boolean, app: { __typename?: 'App', id: string, fullName: string, slug: string }, androidFcm?: { __typename?: 'AndroidFcm', id: string, credential: any, version: AndroidFcmVersion, createdAt: any, updatedAt: any, snippet: { __typename?: 'FcmSnippetLegacy', firstFourCharacters: string, lastFourCharacters: string } | { __typename?: 'FcmSnippetV1', projectId: string, keyId: string, serviceAccountEmail: string, clientId?: string | null | undefined } } | null | undefined, googleServiceAccountKeyForSubmissions?: { __typename?: 'GoogleServiceAccountKey', id: string, projectIdentifier: string, privateKeyIdentifier: string, clientEmail: string, clientIdentifier: string, createdAt: any, updatedAt: any } | null | undefined, androidAppBuildCredentialsList: Array<{ __typename?: 'AndroidAppBuildCredentials', id: string, isDefault: boolean, isLegacy: boolean, name: string, androidKeystore?: { __typename?: 'AndroidKeystore', id: string, type: AndroidKeystoreType, keystore: string, keystorePassword: string, keyAlias: string, keyPassword?: string | null | undefined, md5CertificateFingerprint?: string | null | undefined, sha1CertificateFingerprint?: string | null | undefined, sha256CertificateFingerprint?: string | null | undefined, createdAt: any, updatedAt: any } | null | undefined }> } | null | undefined } };
export type SetFcmMutation = { __typename?: 'RootMutation', androidAppCredentials: { __typename?: 'AndroidAppCredentialsMutation', setFcm: { __typename?: 'AndroidAppCredentials', id: string, applicationIdentifier?: string | null, isLegacy: boolean, app: { __typename?: 'App', id: string, fullName: string, slug: string }, androidFcm?: { __typename?: 'AndroidFcm', id: string, credential: any, version: AndroidFcmVersion, createdAt: any, updatedAt: any, snippet: { __typename?: 'FcmSnippetLegacy', firstFourCharacters: string, lastFourCharacters: string } | { __typename?: 'FcmSnippetV1', projectId: string, keyId: string, serviceAccountEmail: string, clientId?: string | null } } | null, googleServiceAccountKeyForSubmissions?: { __typename?: 'GoogleServiceAccountKey', id: string, projectIdentifier: string, privateKeyIdentifier: string, clientEmail: string, clientIdentifier: string, createdAt: any, updatedAt: any } | null, androidAppBuildCredentialsList: Array<{ __typename?: 'AndroidAppBuildCredentials', id: string, isDefault: boolean, isLegacy: boolean, name: string, androidKeystore?: { __typename?: 'AndroidKeystore', id: string, type: AndroidKeystoreType, keystore: string, keystorePassword: string, keyAlias: string, keyPassword?: string | null, md5CertificateFingerprint?: string | null, sha1CertificateFingerprint?: string | null, sha256CertificateFingerprint?: string | null, createdAt: any, updatedAt: any } | null }> } } };
export type SetGoogleServiceAccountKeyForSubmissionsMutationVariables = Exact<{
androidAppCredentialsId: Scalars['ID'];
@@ -3819,7 +3840,7 @@ export type SetGoogleServiceAccountKeyForSubmissionsMutationVariables = Exact<{
}>;
export type SetGoogleServiceAccountKeyForSubmissionsMutation = { __typename?: 'RootMutation', androidAppCredentials: { __typename?: 'AndroidAppCredentialsMutation', setGoogleServiceAccountKeyForSubmissions?: { __typename?: 'AndroidAppCredentials', id: string, applicationIdentifier?: string | null | undefined, isLegacy: boolean, app: { __typename?: 'App', id: string, fullName: string, slug: string }, androidFcm?: { __typename?: 'AndroidFcm', id: string, credential: any, version: AndroidFcmVersion, createdAt: any, updatedAt: any, snippet: { __typename?: 'FcmSnippetLegacy', firstFourCharacters: string, lastFourCharacters: string } | { __typename?: 'FcmSnippetV1', projectId: string, keyId: string, serviceAccountEmail: string, clientId?: string | null | undefined } } | null | undefined, googleServiceAccountKeyForSubmissions?: { __typename?: 'GoogleServiceAccountKey', id: string, projectIdentifier: string, privateKeyIdentifier: string, clientEmail: string, clientIdentifier: string, createdAt: any, updatedAt: any } | null | undefined, androidAppBuildCredentialsList: Array<{ __typename?: 'AndroidAppBuildCredentials', id: string, isDefault: boolean, isLegacy: boolean, name: string, androidKeystore?: { __typename?: 'AndroidKeystore', id: string, type: AndroidKeystoreType, keystore: string, keystorePassword: string, keyAlias: string, keyPassword?: string | null | undefined, md5CertificateFingerprint?: string | null | undefined, sha1CertificateFingerprint?: string | null | undefined, sha256CertificateFingerprint?: string | null | undefined, createdAt: any, updatedAt: any } | null | undefined }> } | null | undefined } };
export type SetGoogleServiceAccountKeyForSubmissionsMutation = { __typename?: 'RootMutation', androidAppCredentials: { __typename?: 'AndroidAppCredentialsMutation', setGoogleServiceAccountKeyForSubmissions: { __typename?: 'AndroidAppCredentials', id: string, applicationIdentifier?: string | null, isLegacy: boolean, app: { __typename?: 'App', id: string, fullName: string, slug: string }, androidFcm?: { __typename?: 'AndroidFcm', id: string, credential: any, version: AndroidFcmVersion, createdAt: any, updatedAt: any, snippet: { __typename?: 'FcmSnippetLegacy', firstFourCharacters: string, lastFourCharacters: string } | { __typename?: 'FcmSnippetV1', projectId: string, keyId: string, serviceAccountEmail: string, clientId?: string | null } } | null, googleServiceAccountKeyForSubmissions?: { __typename?: 'GoogleServiceAccountKey', id: string, projectIdentifier: string, privateKeyIdentifier: string, clientEmail: string, clientIdentifier: string, createdAt: any, updatedAt: any } | null, androidAppBuildCredentialsList: Array<{ __typename?: 'AndroidAppBuildCredentials', id: string, isDefault: boolean, isLegacy: boolean, name: string, androidKeystore?: { __typename?: 'AndroidKeystore', id: string, type: AndroidKeystoreType, keystore: string, keystorePassword: string, keyAlias: string, keyPassword?: string | null, md5CertificateFingerprint?: string | null, sha1CertificateFingerprint?: string | null, sha256CertificateFingerprint?: string | null, createdAt: any, updatedAt: any } | null }> } } };
export type CreateAndroidFcmMutationVariables = Exact<{
androidFcmInput: AndroidFcmInput;
@@ -3827,7 +3848,7 @@ export type CreateAndroidFcmMutationVariables = Exact<{
}>;
export type CreateAndroidFcmMutation = { __typename?: 'RootMutation', androidFcm: { __typename?: 'AndroidFcmMutation', createAndroidFcm: { __typename?: 'AndroidFcm', id: string, credential: any, version: AndroidFcmVersion, createdAt: any, updatedAt: any, snippet: { __typename?: 'FcmSnippetLegacy', firstFourCharacters: string, lastFourCharacters: string } | { __typename?: 'FcmSnippetV1', projectId: string, keyId: string, serviceAccountEmail: string, clientId?: string | null | undefined } } } };
export type CreateAndroidFcmMutation = { __typename?: 'RootMutation', androidFcm: { __typename?: 'AndroidFcmMutation', createAndroidFcm: { __typename?: 'AndroidFcm', id: string, credential: any, version: AndroidFcmVersion, createdAt: any, updatedAt: any, snippet: { __typename?: 'FcmSnippetLegacy', firstFourCharacters: string, lastFourCharacters: string } | { __typename?: 'FcmSnippetV1', projectId: string, keyId: string, serviceAccountEmail: string, clientId?: string | null } } } };
export type DeleteAndroidFcmMutationVariables = Exact<{
androidFcmId: Scalars['ID'];
@@ -3842,7 +3863,7 @@ export type CreateAndroidKeystoreMutationVariables = Exact<{
}>;
export type CreateAndroidKeystoreMutation = { __typename?: 'RootMutation', androidKeystore: { __typename?: 'AndroidKeystoreMutation', createAndroidKeystore?: { __typename?: 'AndroidKeystore', id: string, type: AndroidKeystoreType, keystore: string, keystorePassword: string, keyAlias: string, keyPassword?: string | null | undefined, md5CertificateFingerprint?: string | null | undefined, sha1CertificateFingerprint?: string | null | undefined, sha256CertificateFingerprint?: string | null | undefined, createdAt: any, updatedAt: any } | null | undefined } };
export type CreateAndroidKeystoreMutation = { __typename?: 'RootMutation', androidKeystore: { __typename?: 'AndroidKeystoreMutation', createAndroidKeystore?: { __typename?: 'AndroidKeystore', id: string, type: AndroidKeystoreType, keystore: string, keystorePassword: string, keyAlias: string, keyPassword?: string | null, md5CertificateFingerprint?: string | null, sha1CertificateFingerprint?: string | null, sha256CertificateFingerprint?: string | null, createdAt: any, updatedAt: any } | null } };
export type DeleteAndroidKeystoreMutationVariables = Exact<{
androidKeystoreId: Scalars['ID'];
@@ -3873,7 +3894,7 @@ export type CommonAndroidAppCredentialsWithBuildCredentialsByApplicationIdentifi
}>;
export type CommonAndroidAppCredentialsWithBuildCredentialsByApplicationIdentifierQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byFullName: { __typename?: 'App', id: string, androidAppCredentials: Array<{ __typename?: 'AndroidAppCredentials', id: string, applicationIdentifier?: string | null | undefined, isLegacy: boolean, app: { __typename?: 'App', id: string, fullName: string, slug: string }, androidFcm?: { __typename?: 'AndroidFcm', id: string, credential: any, version: AndroidFcmVersion, createdAt: any, updatedAt: any, snippet: { __typename?: 'FcmSnippetLegacy', firstFourCharacters: string, lastFourCharacters: string } | { __typename?: 'FcmSnippetV1', projectId: string, keyId: string, serviceAccountEmail: string, clientId?: string | null | undefined } } | null | undefined, googleServiceAccountKeyForSubmissions?: { __typename?: 'GoogleServiceAccountKey', id: string, projectIdentifier: string, privateKeyIdentifier: string, clientEmail: string, clientIdentifier: string, createdAt: any, updatedAt: any } | null | undefined, androidAppBuildCredentialsList: Array<{ __typename?: 'AndroidAppBuildCredentials', id: string, isDefault: boolean, isLegacy: boolean, name: string, androidKeystore?: { __typename?: 'AndroidKeystore', id: string, type: AndroidKeystoreType, keystore: string, keystorePassword: string, keyAlias: string, keyPassword?: string | null | undefined, md5CertificateFingerprint?: string | null | undefined, sha1CertificateFingerprint?: string | null | undefined, sha256CertificateFingerprint?: string | null | undefined, createdAt: any, updatedAt: any } | null | undefined }> }> } } };
export type CommonAndroidAppCredentialsWithBuildCredentialsByApplicationIdentifierQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byFullName: { __typename?: 'App', id: string, androidAppCredentials: Array<{ __typename?: 'AndroidAppCredentials', id: string, applicationIdentifier?: string | null, isLegacy: boolean, app: { __typename?: 'App', id: string, fullName: string, slug: string }, androidFcm?: { __typename?: 'AndroidFcm', id: string, credential: any, version: AndroidFcmVersion, createdAt: any, updatedAt: any, snippet: { __typename?: 'FcmSnippetLegacy', firstFourCharacters: string, lastFourCharacters: string } | { __typename?: 'FcmSnippetV1', projectId: string, keyId: string, serviceAccountEmail: string, clientId?: string | null } } | null, googleServiceAccountKeyForSubmissions?: { __typename?: 'GoogleServiceAccountKey', id: string, projectIdentifier: string, privateKeyIdentifier: string, clientEmail: string, clientIdentifier: string, createdAt: any, updatedAt: any } | null, androidAppBuildCredentialsList: Array<{ __typename?: 'AndroidAppBuildCredentials', id: string, isDefault: boolean, isLegacy: boolean, name: string, androidKeystore?: { __typename?: 'AndroidKeystore', id: string, type: AndroidKeystoreType, keystore: string, keystorePassword: string, keyAlias: string, keyPassword?: string | null, md5CertificateFingerprint?: string | null, sha1CertificateFingerprint?: string | null, sha256CertificateFingerprint?: string | null, createdAt: any, updatedAt: any } | null }> }> } } };
export type GoogleServiceAccountKeyByAccountQueryVariables = Exact<{
accountName: Scalars['String'];
@@ -3888,7 +3909,7 @@ export type CreateAppStoreConnectApiKeyMutationVariables = Exact<{
}>;
export type CreateAppStoreConnectApiKeyMutation = { __typename?: 'RootMutation', appStoreConnectApiKey: { __typename?: 'AppStoreConnectApiKeyMutation', createAppStoreConnectApiKey: { __typename?: 'AppStoreConnectApiKey', id: string, issuerIdentifier: string, keyIdentifier: string, name?: string | null | undefined, roles?: Array<AppStoreConnectUserRole> | null | undefined, createdAt: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined } } };
export type CreateAppStoreConnectApiKeyMutation = { __typename?: 'RootMutation', appStoreConnectApiKey: { __typename?: 'AppStoreConnectApiKeyMutation', createAppStoreConnectApiKey: { __typename?: 'AppStoreConnectApiKey', id: string, issuerIdentifier: string, keyIdentifier: string, name?: string | null, roles?: Array<AppStoreConnectUserRole> | null, createdAt: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null } } };
export type DeleteAppStoreConnectApiKeyMutationVariables = Exact<{
appStoreConnectApiKeyId: Scalars['ID'];
@@ -3903,7 +3924,7 @@ export type CreateAppleAppIdentifierMutationVariables = Exact<{
}>;
export type CreateAppleAppIdentifierMutation = { __typename?: 'RootMutation', appleAppIdentifier: { __typename?: 'AppleAppIdentifierMutation', createAppleAppIdentifier?: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } | null | undefined } };
export type CreateAppleAppIdentifierMutation = { __typename?: 'RootMutation', appleAppIdentifier: { __typename?: 'AppleAppIdentifierMutation', createAppleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } } };
export type CreateAppleDeviceMutationVariables = Exact<{
appleDeviceInput: AppleDeviceInput;
@@ -3911,7 +3932,7 @@ export type CreateAppleDeviceMutationVariables = Exact<{
}>;
export type CreateAppleDeviceMutation = { __typename?: 'RootMutation', appleDevice: { __typename?: 'AppleDeviceMutation', createAppleDevice: { __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null | undefined, model?: string | null | undefined, deviceClass?: AppleDeviceClass | null | undefined } } };
export type CreateAppleDeviceMutation = { __typename?: 'RootMutation', appleDevice: { __typename?: 'AppleDeviceMutation', createAppleDevice: { __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null, model?: string | null, deviceClass?: AppleDeviceClass | null } } };
export type DeleteAppleDeviceMutationVariables = Exact<{
deviceId: Scalars['ID'];
@@ -3934,7 +3955,7 @@ export type CreateAppleDistributionCertificateMutationVariables = Exact<{
}>;
export type CreateAppleDistributionCertificateMutation = { __typename?: 'RootMutation', appleDistributionCertificate: { __typename?: 'AppleDistributionCertificateMutation', createAppleDistributionCertificate?: { __typename?: 'AppleDistributionCertificate', id: string, certificateP12?: string | null | undefined, certificatePassword?: string | null | undefined, serialNumber: string, developerPortalIdentifier?: string | null | undefined, validityNotBefore: any, validityNotAfter: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosAppCredentials: { __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, developerPortalIdentifier?: string | null | undefined } | null | undefined }> } | null | undefined } };
export type CreateAppleDistributionCertificateMutation = { __typename?: 'RootMutation', appleDistributionCertificate: { __typename?: 'AppleDistributionCertificateMutation', createAppleDistributionCertificate?: { __typename?: 'AppleDistributionCertificate', id: string, certificateP12?: string | null, certificatePassword?: string | null, serialNumber: string, developerPortalIdentifier?: string | null, validityNotBefore: any, validityNotAfter: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosAppCredentials: { __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, developerPortalIdentifier?: string | null } | null }> } | null } };
export type DeleteAppleDistributionCertificateMutationVariables = Exact<{
appleDistributionCertificateId: Scalars['ID'];
@@ -3950,7 +3971,7 @@ export type CreateAppleProvisioningProfileMutationVariables = Exact<{
}>;
export type CreateAppleProvisioningProfileMutation = { __typename?: 'RootMutation', appleProvisioningProfile: { __typename?: 'AppleProvisioningProfileMutation', createAppleProvisioningProfile: { __typename?: 'AppleProvisioningProfile', id: string, expiration: any, developerPortalIdentifier?: string | null | undefined, provisioningProfile?: string | null | undefined, updatedAt: any, status: string, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null | undefined, model?: string | null | undefined, deviceClass?: AppleDeviceClass | null | undefined }> } } };
export type CreateAppleProvisioningProfileMutation = { __typename?: 'RootMutation', appleProvisioningProfile: { __typename?: 'AppleProvisioningProfileMutation', createAppleProvisioningProfile: { __typename?: 'AppleProvisioningProfile', id: string, expiration: any, developerPortalIdentifier?: string | null, provisioningProfile?: string | null, updatedAt: any, status: string, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null, model?: string | null, deviceClass?: AppleDeviceClass | null }> } } };
export type UpdateAppleProvisioningProfileMutationVariables = Exact<{
appleProvisioningProfileId: Scalars['ID'];
@@ -3958,7 +3979,7 @@ export type UpdateAppleProvisioningProfileMutationVariables = Exact<{
}>;
export type UpdateAppleProvisioningProfileMutation = { __typename?: 'RootMutation', appleProvisioningProfile: { __typename?: 'AppleProvisioningProfileMutation', updateAppleProvisioningProfile: { __typename?: 'AppleProvisioningProfile', id: string, expiration: any, developerPortalIdentifier?: string | null | undefined, provisioningProfile?: string | null | undefined, updatedAt: any, status: string, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null | undefined, model?: string | null | undefined, deviceClass?: AppleDeviceClass | null | undefined }> } } };
export type UpdateAppleProvisioningProfileMutation = { __typename?: 'RootMutation', appleProvisioningProfile: { __typename?: 'AppleProvisioningProfileMutation', updateAppleProvisioningProfile: { __typename?: 'AppleProvisioningProfile', id: string, expiration: any, developerPortalIdentifier?: string | null, provisioningProfile?: string | null, updatedAt: any, status: string, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null, model?: string | null, deviceClass?: AppleDeviceClass | null }> } } };
export type DeleteAppleProvisioningProfilesMutationVariables = Exact<{
appleProvisioningProfileIds: Array<Scalars['ID']> | Scalars['ID'];
@@ -3973,7 +3994,7 @@ export type CreateApplePushKeyMutationVariables = Exact<{
}>;
export type CreateApplePushKeyMutation = { __typename?: 'RootMutation', applePushKey: { __typename?: 'ApplePushKeyMutation', createApplePushKey: { __typename?: 'ApplePushKey', id: string, keyIdentifier: string, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, iosAppCredentialsList: Array<{ __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }> } } };
export type CreateApplePushKeyMutation = { __typename?: 'RootMutation', applePushKey: { __typename?: 'ApplePushKeyMutation', createApplePushKey: { __typename?: 'ApplePushKey', id: string, keyIdentifier: string, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, iosAppCredentialsList: Array<{ __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }> } } };
export type DeleteApplePushKeyMutationVariables = Exact<{
applePushKeyId: Scalars['ID'];
@@ -3988,7 +4009,7 @@ export type CreateAppleTeamMutationVariables = Exact<{
}>;
export type CreateAppleTeamMutation = { __typename?: 'RootMutation', appleTeam: { __typename?: 'AppleTeamMutation', createAppleTeam: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined, account: { __typename?: 'Account', id: string, name: string } } } };
export type CreateAppleTeamMutation = { __typename?: 'RootMutation', appleTeam: { __typename?: 'AppleTeamMutation', createAppleTeam: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null, account: { __typename?: 'Account', id: string, name: string } } } };
export type CreateIosAppBuildCredentialsMutationVariables = Exact<{
iosAppBuildCredentialsInput: IosAppBuildCredentialsInput;
@@ -3996,7 +4017,7 @@ export type CreateIosAppBuildCredentialsMutationVariables = Exact<{
}>;
export type CreateIosAppBuildCredentialsMutation = { __typename?: 'RootMutation', iosAppBuildCredentials: { __typename?: 'IosAppBuildCredentialsMutation', createIosAppBuildCredentials: { __typename?: 'IosAppBuildCredentials', id: string, iosDistributionType: IosDistributionType, distributionCertificate?: { __typename?: 'AppleDistributionCertificate', id: string, certificateP12?: string | null | undefined, certificatePassword?: string | null | undefined, serialNumber: string, developerPortalIdentifier?: string | null | undefined, validityNotBefore: any, validityNotAfter: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosAppCredentials: { __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, developerPortalIdentifier?: string | null | undefined } | null | undefined }> } | null | undefined, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, expiration: any, developerPortalIdentifier?: string | null | undefined, provisioningProfile?: string | null | undefined, updatedAt: any, status: string, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null | undefined, model?: string | null | undefined, deviceClass?: AppleDeviceClass | null | undefined }> } | null | undefined } } };
export type CreateIosAppBuildCredentialsMutation = { __typename?: 'RootMutation', iosAppBuildCredentials: { __typename?: 'IosAppBuildCredentialsMutation', createIosAppBuildCredentials: { __typename?: 'IosAppBuildCredentials', id: string, iosDistributionType: IosDistributionType, distributionCertificate?: { __typename?: 'AppleDistributionCertificate', id: string, certificateP12?: string | null, certificatePassword?: string | null, serialNumber: string, developerPortalIdentifier?: string | null, validityNotBefore: any, validityNotAfter: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosAppCredentials: { __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, developerPortalIdentifier?: string | null } | null }> } | null, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, expiration: any, developerPortalIdentifier?: string | null, provisioningProfile?: string | null, updatedAt: any, status: string, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null, model?: string | null, deviceClass?: AppleDeviceClass | null }> } | null } } };
export type SetDistributionCertificateMutationVariables = Exact<{
iosAppBuildCredentialsId: Scalars['ID'];
@@ -4004,7 +4025,7 @@ export type SetDistributionCertificateMutationVariables = Exact<{
}>;
export type SetDistributionCertificateMutation = { __typename?: 'RootMutation', iosAppBuildCredentials: { __typename?: 'IosAppBuildCredentialsMutation', setDistributionCertificate: { __typename?: 'IosAppBuildCredentials', id: string, iosDistributionType: IosDistributionType, distributionCertificate?: { __typename?: 'AppleDistributionCertificate', id: string, certificateP12?: string | null | undefined, certificatePassword?: string | null | undefined, serialNumber: string, developerPortalIdentifier?: string | null | undefined, validityNotBefore: any, validityNotAfter: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosAppCredentials: { __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, developerPortalIdentifier?: string | null | undefined } | null | undefined }> } | null | undefined, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, expiration: any, developerPortalIdentifier?: string | null | undefined, provisioningProfile?: string | null | undefined, updatedAt: any, status: string, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null | undefined, model?: string | null | undefined, deviceClass?: AppleDeviceClass | null | undefined }> } | null | undefined } } };
export type SetDistributionCertificateMutation = { __typename?: 'RootMutation', iosAppBuildCredentials: { __typename?: 'IosAppBuildCredentialsMutation', setDistributionCertificate: { __typename?: 'IosAppBuildCredentials', id: string, iosDistributionType: IosDistributionType, distributionCertificate?: { __typename?: 'AppleDistributionCertificate', id: string, certificateP12?: string | null, certificatePassword?: string | null, serialNumber: string, developerPortalIdentifier?: string | null, validityNotBefore: any, validityNotAfter: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosAppCredentials: { __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, developerPortalIdentifier?: string | null } | null }> } | null, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, expiration: any, developerPortalIdentifier?: string | null, provisioningProfile?: string | null, updatedAt: any, status: string, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null, model?: string | null, deviceClass?: AppleDeviceClass | null }> } | null } } };
export type SetProvisioningProfileMutationVariables = Exact<{
iosAppBuildCredentialsId: Scalars['ID'];
@@ -4012,7 +4033,7 @@ export type SetProvisioningProfileMutationVariables = Exact<{
}>;
export type SetProvisioningProfileMutation = { __typename?: 'RootMutation', iosAppBuildCredentials: { __typename?: 'IosAppBuildCredentialsMutation', setProvisioningProfile: { __typename?: 'IosAppBuildCredentials', id: string, iosDistributionType: IosDistributionType, distributionCertificate?: { __typename?: 'AppleDistributionCertificate', id: string, certificateP12?: string | null | undefined, certificatePassword?: string | null | undefined, serialNumber: string, developerPortalIdentifier?: string | null | undefined, validityNotBefore: any, validityNotAfter: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosAppCredentials: { __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, developerPortalIdentifier?: string | null | undefined } | null | undefined }> } | null | undefined, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, expiration: any, developerPortalIdentifier?: string | null | undefined, provisioningProfile?: string | null | undefined, updatedAt: any, status: string, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null | undefined, model?: string | null | undefined, deviceClass?: AppleDeviceClass | null | undefined }> } | null | undefined } } };
export type SetProvisioningProfileMutation = { __typename?: 'RootMutation', iosAppBuildCredentials: { __typename?: 'IosAppBuildCredentialsMutation', setProvisioningProfile: { __typename?: 'IosAppBuildCredentials', id: string, iosDistributionType: IosDistributionType, distributionCertificate?: { __typename?: 'AppleDistributionCertificate', id: string, certificateP12?: string | null, certificatePassword?: string | null, serialNumber: string, developerPortalIdentifier?: string | null, validityNotBefore: any, validityNotAfter: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosAppCredentials: { __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, developerPortalIdentifier?: string | null } | null }> } | null, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, expiration: any, developerPortalIdentifier?: string | null, provisioningProfile?: string | null, updatedAt: any, status: string, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null, model?: string | null, deviceClass?: AppleDeviceClass | null }> } | null } } };
export type CreateIosAppCredentialsMutationVariables = Exact<{
iosAppCredentialsInput: IosAppCredentialsInput;
@@ -4021,7 +4042,7 @@ export type CreateIosAppCredentialsMutationVariables = Exact<{
}>;
export type CreateIosAppCredentialsMutation = { __typename?: 'RootMutation', iosAppCredentials: { __typename?: 'IosAppCredentialsMutation', createIosAppCredentials: { __typename?: 'IosAppCredentials', id: string, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosDistributionType: IosDistributionType, distributionCertificate?: { __typename?: 'AppleDistributionCertificate', id: string, certificateP12?: string | null | undefined, certificatePassword?: string | null | undefined, serialNumber: string, developerPortalIdentifier?: string | null | undefined, validityNotBefore: any, validityNotAfter: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosAppCredentials: { __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, developerPortalIdentifier?: string | null | undefined } | null | undefined }> } | null | undefined, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, expiration: any, developerPortalIdentifier?: string | null | undefined, provisioningProfile?: string | null | undefined, updatedAt: any, status: string, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null | undefined, model?: string | null | undefined, deviceClass?: AppleDeviceClass | null | undefined }> } | null | undefined }>, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string }, pushKey?: { __typename?: 'ApplePushKey', id: string, keyIdentifier: string, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, iosAppCredentialsList: Array<{ __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }> } | null | undefined, appStoreConnectApiKeyForSubmissions?: { __typename?: 'AppStoreConnectApiKey', id: string, issuerIdentifier: string, keyIdentifier: string, name?: string | null | undefined, roles?: Array<AppStoreConnectUserRole> | null | undefined, createdAt: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined } | null | undefined } } };
export type CreateIosAppCredentialsMutation = { __typename?: 'RootMutation', iosAppCredentials: { __typename?: 'IosAppCredentialsMutation', createIosAppCredentials: { __typename?: 'IosAppCredentials', id: string, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosDistributionType: IosDistributionType, distributionCertificate?: { __typename?: 'AppleDistributionCertificate', id: string, certificateP12?: string | null, certificatePassword?: string | null, serialNumber: string, developerPortalIdentifier?: string | null, validityNotBefore: any, validityNotAfter: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosAppCredentials: { __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, developerPortalIdentifier?: string | null } | null }> } | null, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, expiration: any, developerPortalIdentifier?: string | null, provisioningProfile?: string | null, updatedAt: any, status: string, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null, model?: string | null, deviceClass?: AppleDeviceClass | null }> } | null }>, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string }, pushKey?: { __typename?: 'ApplePushKey', id: string, keyIdentifier: string, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, iosAppCredentialsList: Array<{ __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }> } | null, appStoreConnectApiKeyForSubmissions?: { __typename?: 'AppStoreConnectApiKey', id: string, issuerIdentifier: string, keyIdentifier: string, name?: string | null, roles?: Array<AppStoreConnectUserRole> | null, createdAt: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null } | null } } };
export type SetPushKeyMutationVariables = Exact<{
iosAppCredentialsId: Scalars['ID'];
@@ -4029,7 +4050,7 @@ export type SetPushKeyMutationVariables = Exact<{
}>;
export type SetPushKeyMutation = { __typename?: 'RootMutation', iosAppCredentials: { __typename?: 'IosAppCredentialsMutation', setPushKey: { __typename?: 'IosAppCredentials', id: string, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosDistributionType: IosDistributionType, distributionCertificate?: { __typename?: 'AppleDistributionCertificate', id: string, certificateP12?: string | null | undefined, certificatePassword?: string | null | undefined, serialNumber: string, developerPortalIdentifier?: string | null | undefined, validityNotBefore: any, validityNotAfter: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosAppCredentials: { __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, developerPortalIdentifier?: string | null | undefined } | null | undefined }> } | null | undefined, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, expiration: any, developerPortalIdentifier?: string | null | undefined, provisioningProfile?: string | null | undefined, updatedAt: any, status: string, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null | undefined, model?: string | null | undefined, deviceClass?: AppleDeviceClass | null | undefined }> } | null | undefined }>, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string }, pushKey?: { __typename?: 'ApplePushKey', id: string, keyIdentifier: string, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, iosAppCredentialsList: Array<{ __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }> } | null | undefined, appStoreConnectApiKeyForSubmissions?: { __typename?: 'AppStoreConnectApiKey', id: string, issuerIdentifier: string, keyIdentifier: string, name?: string | null | undefined, roles?: Array<AppStoreConnectUserRole> | null | undefined, createdAt: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined } | null | undefined } } };
export type SetPushKeyMutation = { __typename?: 'RootMutation', iosAppCredentials: { __typename?: 'IosAppCredentialsMutation', setPushKey: { __typename?: 'IosAppCredentials', id: string, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosDistributionType: IosDistributionType, distributionCertificate?: { __typename?: 'AppleDistributionCertificate', id: string, certificateP12?: string | null, certificatePassword?: string | null, serialNumber: string, developerPortalIdentifier?: string | null, validityNotBefore: any, validityNotAfter: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosAppCredentials: { __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, developerPortalIdentifier?: string | null } | null }> } | null, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, expiration: any, developerPortalIdentifier?: string | null, provisioningProfile?: string | null, updatedAt: any, status: string, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null, model?: string | null, deviceClass?: AppleDeviceClass | null }> } | null }>, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string }, pushKey?: { __typename?: 'ApplePushKey', id: string, keyIdentifier: string, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, iosAppCredentialsList: Array<{ __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }> } | null, appStoreConnectApiKeyForSubmissions?: { __typename?: 'AppStoreConnectApiKey', id: string, issuerIdentifier: string, keyIdentifier: string, name?: string | null, roles?: Array<AppStoreConnectUserRole> | null, createdAt: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null } | null } } };
export type SetAppStoreConnectApiKeyForSubmissionsMutationVariables = Exact<{
iosAppCredentialsId: Scalars['ID'];
@@ -4037,7 +4058,7 @@ export type SetAppStoreConnectApiKeyForSubmissionsMutationVariables = Exact<{
}>;
export type SetAppStoreConnectApiKeyForSubmissionsMutation = { __typename?: 'RootMutation', iosAppCredentials: { __typename?: 'IosAppCredentialsMutation', setAppStoreConnectApiKeyForSubmissions: { __typename?: 'IosAppCredentials', id: string, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosDistributionType: IosDistributionType, distributionCertificate?: { __typename?: 'AppleDistributionCertificate', id: string, certificateP12?: string | null | undefined, certificatePassword?: string | null | undefined, serialNumber: string, developerPortalIdentifier?: string | null | undefined, validityNotBefore: any, validityNotAfter: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosAppCredentials: { __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, developerPortalIdentifier?: string | null | undefined } | null | undefined }> } | null | undefined, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, expiration: any, developerPortalIdentifier?: string | null | undefined, provisioningProfile?: string | null | undefined, updatedAt: any, status: string, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null | undefined, model?: string | null | undefined, deviceClass?: AppleDeviceClass | null | undefined }> } | null | undefined }>, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string }, pushKey?: { __typename?: 'ApplePushKey', id: string, keyIdentifier: string, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, iosAppCredentialsList: Array<{ __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }> } | null | undefined, appStoreConnectApiKeyForSubmissions?: { __typename?: 'AppStoreConnectApiKey', id: string, issuerIdentifier: string, keyIdentifier: string, name?: string | null | undefined, roles?: Array<AppStoreConnectUserRole> | null | undefined, createdAt: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined } | null | undefined } } };
export type SetAppStoreConnectApiKeyForSubmissionsMutation = { __typename?: 'RootMutation', iosAppCredentials: { __typename?: 'IosAppCredentialsMutation', setAppStoreConnectApiKeyForSubmissions: { __typename?: 'IosAppCredentials', id: string, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosDistributionType: IosDistributionType, distributionCertificate?: { __typename?: 'AppleDistributionCertificate', id: string, certificateP12?: string | null, certificatePassword?: string | null, serialNumber: string, developerPortalIdentifier?: string | null, validityNotBefore: any, validityNotAfter: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosAppCredentials: { __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, developerPortalIdentifier?: string | null } | null }> } | null, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, expiration: any, developerPortalIdentifier?: string | null, provisioningProfile?: string | null, updatedAt: any, status: string, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null, model?: string | null, deviceClass?: AppleDeviceClass | null }> } | null }>, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string }, pushKey?: { __typename?: 'ApplePushKey', id: string, keyIdentifier: string, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, iosAppCredentialsList: Array<{ __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }> } | null, appStoreConnectApiKeyForSubmissions?: { __typename?: 'AppStoreConnectApiKey', id: string, issuerIdentifier: string, keyIdentifier: string, name?: string | null, roles?: Array<AppStoreConnectUserRole> | null, createdAt: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null } | null } } };
export type AppByFullNameQueryVariables = Exact<{
fullName: Scalars['String'];
@@ -4051,7 +4072,7 @@ export type AppStoreConnectApiKeyByAccountQueryVariables = Exact<{
}>;
export type AppStoreConnectApiKeyByAccountQuery = { __typename?: 'RootQuery', account: { __typename?: 'AccountQuery', byName: { __typename?: 'Account', id: string, appStoreConnectApiKeys: Array<{ __typename?: 'AppStoreConnectApiKey', id: string, issuerIdentifier: string, keyIdentifier: string, name?: string | null | undefined, roles?: Array<AppStoreConnectUserRole> | null | undefined, createdAt: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined }> } } };
export type AppStoreConnectApiKeyByAccountQuery = { __typename?: 'RootQuery', account: { __typename?: 'AccountQuery', byName: { __typename?: 'Account', id: string, appStoreConnectApiKeys: Array<{ __typename?: 'AppStoreConnectApiKey', id: string, issuerIdentifier: string, keyIdentifier: string, name?: string | null, roles?: Array<AppStoreConnectUserRole> | null, createdAt: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null }> } } };
export type AppleAppIdentifierByBundleIdQueryVariables = Exact<{
accountName: Scalars['String'];
@@ -4067,7 +4088,7 @@ export type AppleDevicesByAppleTeamQueryVariables = Exact<{
}>;
export type AppleDevicesByAppleTeamQuery = { __typename?: 'RootQuery', appleTeam: { __typename?: 'AppleTeamQuery', byAppleTeamIdentifier?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null | undefined, model?: string | null | undefined, deviceClass?: AppleDeviceClass | null | undefined, appleTeam: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } }> } | null | undefined } };
export type AppleDevicesByAppleTeamQuery = { __typename?: 'RootQuery', appleTeam: { __typename?: 'AppleTeamQuery', byAppleTeamIdentifier?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null, model?: string | null, deviceClass?: AppleDeviceClass | null, appleTeam: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } }> } | null } };
export type AppleDevicesByTeamIdentifierQueryVariables = Exact<{
accountName: Scalars['String'];
@@ -4075,7 +4096,7 @@ export type AppleDevicesByTeamIdentifierQueryVariables = Exact<{
}>;
export type AppleDevicesByTeamIdentifierQuery = { __typename?: 'RootQuery', account: { __typename?: 'AccountQuery', byName: { __typename?: 'Account', id: string, appleTeams: Array<{ __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null | undefined, deviceClass?: AppleDeviceClass | null | undefined, enabled?: boolean | null | undefined }> }> } } };
export type AppleDevicesByTeamIdentifierQuery = { __typename?: 'RootQuery', account: { __typename?: 'AccountQuery', byName: { __typename?: 'Account', id: string, appleTeams: Array<{ __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null, deviceClass?: AppleDeviceClass | null, enabled?: boolean | null }> }> } } };
export type AppleDevicesByIdentifierQueryVariables = Exact<{
accountName: Scalars['String'];
@@ -4083,7 +4104,7 @@ export type AppleDevicesByIdentifierQueryVariables = Exact<{
}>;
export type AppleDevicesByIdentifierQuery = { __typename?: 'RootQuery', account: { __typename?: 'AccountQuery', byName: { __typename?: 'Account', id: string, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null | undefined, deviceClass?: AppleDeviceClass | null | undefined, enabled?: boolean | null | undefined, appleTeam: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } }> } } };
export type AppleDevicesByIdentifierQuery = { __typename?: 'RootQuery', account: { __typename?: 'AccountQuery', byName: { __typename?: 'Account', id: string, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null, deviceClass?: AppleDeviceClass | null, enabled?: boolean | null, appleTeam: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } }> } } };
export type AppleDistributionCertificateByAppQueryVariables = Exact<{
projectFullName: Scalars['String'];
@@ -4092,14 +4113,14 @@ export type AppleDistributionCertificateByAppQueryVariables = Exact<{
}>;
export type AppleDistributionCertificateByAppQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byFullName: { __typename?: 'App', id: string, iosAppCredentials: Array<{ __typename?: 'IosAppCredentials', id: string, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, distributionCertificate?: { __typename?: 'AppleDistributionCertificate', id: string, certificateP12?: string | null | undefined, certificatePassword?: string | null | undefined, serialNumber: string, developerPortalIdentifier?: string | null | undefined, validityNotBefore: any, validityNotAfter: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosAppCredentials: { __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, developerPortalIdentifier?: string | null | undefined } | null | undefined }> } | null | undefined }> }> } } };
export type AppleDistributionCertificateByAppQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byFullName: { __typename?: 'App', id: string, iosAppCredentials: Array<{ __typename?: 'IosAppCredentials', id: string, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, distributionCertificate?: { __typename?: 'AppleDistributionCertificate', id: string, certificateP12?: string | null, certificatePassword?: string | null, serialNumber: string, developerPortalIdentifier?: string | null, validityNotBefore: any, validityNotAfter: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosAppCredentials: { __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, developerPortalIdentifier?: string | null } | null }> } | null }> }> } } };
export type AppleDistributionCertificateByAccountQueryVariables = Exact<{
accountName: Scalars['String'];
}>;
export type AppleDistributionCertificateByAccountQuery = { __typename?: 'RootQuery', account: { __typename?: 'AccountQuery', byName: { __typename?: 'Account', id: string, appleDistributionCertificates: Array<{ __typename?: 'AppleDistributionCertificate', id: string, certificateP12?: string | null | undefined, certificatePassword?: string | null | undefined, serialNumber: string, developerPortalIdentifier?: string | null | undefined, validityNotBefore: any, validityNotAfter: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosAppCredentials: { __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, developerPortalIdentifier?: string | null | undefined } | null | undefined }> }> } } };
export type AppleDistributionCertificateByAccountQuery = { __typename?: 'RootQuery', account: { __typename?: 'AccountQuery', byName: { __typename?: 'Account', id: string, appleDistributionCertificates: Array<{ __typename?: 'AppleDistributionCertificate', id: string, certificateP12?: string | null, certificatePassword?: string | null, serialNumber: string, developerPortalIdentifier?: string | null, validityNotBefore: any, validityNotAfter: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosAppCredentials: { __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, developerPortalIdentifier?: string | null } | null }> }> } } };
export type AppleProvisioningProfilesByAppQueryVariables = Exact<{
projectFullName: Scalars['String'];
@@ -4108,21 +4129,21 @@ export type AppleProvisioningProfilesByAppQueryVariables = Exact<{
}>;
export type AppleProvisioningProfilesByAppQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byFullName: { __typename?: 'App', id: string, iosAppCredentials: Array<{ __typename?: 'IosAppCredentials', id: string, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, expiration: any, developerPortalIdentifier?: string | null | undefined, provisioningProfile?: string | null | undefined, updatedAt: any, status: string, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null | undefined, model?: string | null | undefined, deviceClass?: AppleDeviceClass | null | undefined }>, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } } | null | undefined }> }> } } };
export type AppleProvisioningProfilesByAppQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byFullName: { __typename?: 'App', id: string, iosAppCredentials: Array<{ __typename?: 'IosAppCredentials', id: string, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, expiration: any, developerPortalIdentifier?: string | null, provisioningProfile?: string | null, updatedAt: any, status: string, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null, model?: string | null, deviceClass?: AppleDeviceClass | null }>, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } } | null }> }> } } };
export type ApplePushKeyByAccountQueryVariables = Exact<{
accountName: Scalars['String'];
}>;
export type ApplePushKeyByAccountQuery = { __typename?: 'RootQuery', account: { __typename?: 'AccountQuery', byName: { __typename?: 'Account', id: string, applePushKeys: Array<{ __typename?: 'ApplePushKey', id: string, keyIdentifier: string, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, iosAppCredentialsList: Array<{ __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }> }> } } };
export type ApplePushKeyByAccountQuery = { __typename?: 'RootQuery', account: { __typename?: 'AccountQuery', byName: { __typename?: 'Account', id: string, applePushKeys: Array<{ __typename?: 'ApplePushKey', id: string, keyIdentifier: string, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, iosAppCredentialsList: Array<{ __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }> }> } } };
export type AppleTeamsByAccountNameQueryVariables = Exact<{
accountName: Scalars['String'];
}>;
export type AppleTeamsByAccountNameQuery = { __typename?: 'RootQuery', account: { __typename?: 'AccountQuery', byName: { __typename?: 'Account', id: string, appleTeams: Array<{ __typename?: 'AppleTeam', id: string, appleTeamName?: string | null | undefined, appleTeamIdentifier: string }> } } };
export type AppleTeamsByAccountNameQuery = { __typename?: 'RootQuery', account: { __typename?: 'AccountQuery', byName: { __typename?: 'Account', id: string, appleTeams: Array<{ __typename?: 'AppleTeam', id: string, appleTeamName?: string | null, appleTeamIdentifier: string }> } } };
export type AppleTeamByIdentifierQueryVariables = Exact<{
accountId: Scalars['ID'];
@@ -4130,7 +4151,7 @@ export type AppleTeamByIdentifierQueryVariables = Exact<{
}>;
export type AppleTeamByIdentifierQuery = { __typename?: 'RootQuery', appleTeam: { __typename?: 'AppleTeamQuery', byAppleTeamIdentifier?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined } };
export type AppleTeamByIdentifierQuery = { __typename?: 'RootQuery', appleTeam: { __typename?: 'AppleTeamQuery', byAppleTeamIdentifier?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null } };
export type IosAppBuildCredentialsByAppleAppIdentiferAndDistributionQueryVariables = Exact<{
projectFullName: Scalars['String'];
@@ -4139,7 +4160,7 @@ export type IosAppBuildCredentialsByAppleAppIdentiferAndDistributionQueryVariabl
}>;
export type IosAppBuildCredentialsByAppleAppIdentiferAndDistributionQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byFullName: { __typename?: 'App', id: string, iosAppCredentials: Array<{ __typename?: 'IosAppCredentials', id: string, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosDistributionType: IosDistributionType, distributionCertificate?: { __typename?: 'AppleDistributionCertificate', id: string, certificateP12?: string | null | undefined, certificatePassword?: string | null | undefined, serialNumber: string, developerPortalIdentifier?: string | null | undefined, validityNotBefore: any, validityNotAfter: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosAppCredentials: { __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, developerPortalIdentifier?: string | null | undefined } | null | undefined }> } | null | undefined, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, expiration: any, developerPortalIdentifier?: string | null | undefined, provisioningProfile?: string | null | undefined, updatedAt: any, status: string, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null | undefined, model?: string | null | undefined, deviceClass?: AppleDeviceClass | null | undefined }> } | null | undefined }> }> } } };
export type IosAppBuildCredentialsByAppleAppIdentiferAndDistributionQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byFullName: { __typename?: 'App', id: string, iosAppCredentials: Array<{ __typename?: 'IosAppCredentials', id: string, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosDistributionType: IosDistributionType, distributionCertificate?: { __typename?: 'AppleDistributionCertificate', id: string, certificateP12?: string | null, certificatePassword?: string | null, serialNumber: string, developerPortalIdentifier?: string | null, validityNotBefore: any, validityNotAfter: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosAppCredentials: { __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, developerPortalIdentifier?: string | null } | null }> } | null, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, expiration: any, developerPortalIdentifier?: string | null, provisioningProfile?: string | null, updatedAt: any, status: string, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null, model?: string | null, deviceClass?: AppleDeviceClass | null }> } | null }> }> } } };
export type IosAppCredentialsWithBuildCredentialsByAppIdentifierIdQueryVariables = Exact<{
projectFullName: Scalars['String'];
@@ -4148,7 +4169,7 @@ export type IosAppCredentialsWithBuildCredentialsByAppIdentifierIdQueryVariables
}>;
export type IosAppCredentialsWithBuildCredentialsByAppIdentifierIdQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byFullName: { __typename?: 'App', id: string, iosAppCredentials: Array<{ __typename?: 'IosAppCredentials', id: string, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosDistributionType: IosDistributionType, distributionCertificate?: { __typename?: 'AppleDistributionCertificate', id: string, certificateP12?: string | null | undefined, certificatePassword?: string | null | undefined, serialNumber: string, developerPortalIdentifier?: string | null | undefined, validityNotBefore: any, validityNotAfter: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosAppCredentials: { __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, developerPortalIdentifier?: string | null | undefined } | null | undefined }> } | null | undefined, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, expiration: any, developerPortalIdentifier?: string | null | undefined, provisioningProfile?: string | null | undefined, updatedAt: any, status: string, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null | undefined, model?: string | null | undefined, deviceClass?: AppleDeviceClass | null | undefined }> } | null | undefined }>, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string }, pushKey?: { __typename?: 'ApplePushKey', id: string, keyIdentifier: string, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, iosAppCredentialsList: Array<{ __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }> } | null | undefined, appStoreConnectApiKeyForSubmissions?: { __typename?: 'AppStoreConnectApiKey', id: string, issuerIdentifier: string, keyIdentifier: string, name?: string | null | undefined, roles?: Array<AppStoreConnectUserRole> | null | undefined, createdAt: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined } | null | undefined }> } } };
export type IosAppCredentialsWithBuildCredentialsByAppIdentifierIdQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byFullName: { __typename?: 'App', id: string, iosAppCredentials: Array<{ __typename?: 'IosAppCredentials', id: string, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosDistributionType: IosDistributionType, distributionCertificate?: { __typename?: 'AppleDistributionCertificate', id: string, certificateP12?: string | null, certificatePassword?: string | null, serialNumber: string, developerPortalIdentifier?: string | null, validityNotBefore: any, validityNotAfter: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosAppCredentials: { __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, developerPortalIdentifier?: string | null } | null }> } | null, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, expiration: any, developerPortalIdentifier?: string | null, provisioningProfile?: string | null, updatedAt: any, status: string, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null, model?: string | null, deviceClass?: AppleDeviceClass | null }> } | null }>, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string }, pushKey?: { __typename?: 'ApplePushKey', id: string, keyIdentifier: string, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, iosAppCredentialsList: Array<{ __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }> } | null, appStoreConnectApiKeyForSubmissions?: { __typename?: 'AppStoreConnectApiKey', id: string, issuerIdentifier: string, keyIdentifier: string, name?: string | null, roles?: Array<AppStoreConnectUserRole> | null, createdAt: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null } | null }> } } };
export type CommonIosAppCredentialsWithBuildCredentialsByAppIdentifierIdQueryVariables = Exact<{
projectFullName: Scalars['String'];
@@ -4156,14 +4177,14 @@ export type CommonIosAppCredentialsWithBuildCredentialsByAppIdentifierIdQueryVar
}>;
export type CommonIosAppCredentialsWithBuildCredentialsByAppIdentifierIdQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byFullName: { __typename?: 'App', id: string, iosAppCredentials: Array<{ __typename?: 'IosAppCredentials', id: string, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosDistributionType: IosDistributionType, distributionCertificate?: { __typename?: 'AppleDistributionCertificate', id: string, certificateP12?: string | null | undefined, certificatePassword?: string | null | undefined, serialNumber: string, developerPortalIdentifier?: string | null | undefined, validityNotBefore: any, validityNotAfter: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosAppCredentials: { __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, developerPortalIdentifier?: string | null | undefined } | null | undefined }> } | null | undefined, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, expiration: any, developerPortalIdentifier?: string | null | undefined, provisioningProfile?: string | null | undefined, updatedAt: any, status: string, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null | undefined, model?: string | null | undefined, deviceClass?: AppleDeviceClass | null | undefined }> } | null | undefined }>, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string }, pushKey?: { __typename?: 'ApplePushKey', id: string, keyIdentifier: string, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, iosAppCredentialsList: Array<{ __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }> } | null | undefined, appStoreConnectApiKeyForSubmissions?: { __typename?: 'AppStoreConnectApiKey', id: string, issuerIdentifier: string, keyIdentifier: string, name?: string | null | undefined, roles?: Array<AppStoreConnectUserRole> | null | undefined, createdAt: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined } | null | undefined }> } } };
export type CommonIosAppCredentialsWithBuildCredentialsByAppIdentifierIdQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byFullName: { __typename?: 'App', id: string, iosAppCredentials: Array<{ __typename?: 'IosAppCredentials', id: string, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosDistributionType: IosDistributionType, distributionCertificate?: { __typename?: 'AppleDistributionCertificate', id: string, certificateP12?: string | null, certificatePassword?: string | null, serialNumber: string, developerPortalIdentifier?: string | null, validityNotBefore: any, validityNotAfter: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosAppCredentials: { __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, developerPortalIdentifier?: string | null } | null }> } | null, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, expiration: any, developerPortalIdentifier?: string | null, provisioningProfile?: string | null, updatedAt: any, status: string, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null, model?: string | null, deviceClass?: AppleDeviceClass | null }> } | null }>, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string }, pushKey?: { __typename?: 'ApplePushKey', id: string, keyIdentifier: string, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, iosAppCredentialsList: Array<{ __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }> } | null, appStoreConnectApiKeyForSubmissions?: { __typename?: 'AppStoreConnectApiKey', id: string, issuerIdentifier: string, keyIdentifier: string, name?: string | null, roles?: Array<AppStoreConnectUserRole> | null, createdAt: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null } | null }> } } };
export type CreateAppMutationVariables = Exact<{
appInput: AppInput;
}>;
export type CreateAppMutation = { __typename?: 'RootMutation', app?: { __typename?: 'AppMutation', createApp: { __typename?: 'App', id: string } } | null | undefined };
export type CreateAppMutation = { __typename?: 'RootMutation', app?: { __typename?: 'AppMutation', createApp: { __typename?: 'App', id: string } } | null };
export type CreateAndroidBuildMutationVariables = Exact<{
appId: Scalars['ID'];
@@ -4172,7 +4193,7 @@ export type CreateAndroidBuildMutationVariables = Exact<{
}>;
export type CreateAndroidBuildMutation = { __typename?: 'RootMutation', build?: { __typename?: 'BuildMutation', createAndroidBuild: { __typename?: 'CreateBuildResult', build: { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null | undefined, releaseChannel?: string | null | undefined, distribution?: DistributionType | null | undefined, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null | undefined, buildProfile?: string | null | undefined, sdkVersion?: string | null | undefined, appVersion?: string | null | undefined, appBuildVersion?: string | null | undefined, runtimeVersion?: string | null | undefined, gitCommitHash?: string | null | undefined, createdAt?: any | null | undefined, updatedAt?: any | null | undefined, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null | undefined } | null | undefined, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null | undefined, xcodeBuildLogsUrl?: string | null | undefined } | null | undefined, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null | undefined, project: { __typename: 'App', id: string, name: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string } }, deprecationInfo?: { __typename?: 'EASBuildDeprecationInfo', type: EasBuildDeprecationInfoType, message: string } | null | undefined } } | null | undefined };
export type CreateAndroidBuildMutation = { __typename?: 'RootMutation', build: { __typename?: 'BuildMutation', createAndroidBuild: { __typename?: 'CreateBuildResult', build: { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, releaseChannel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, createdAt?: any | null, updatedAt?: any | null, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string } }, deprecationInfo?: { __typename?: 'EASBuildDeprecationInfo', type: EasBuildDeprecationInfoType, message: string } | null } } };
export type CreateIosBuildMutationVariables = Exact<{
appId: Scalars['ID'];
@@ -4181,7 +4202,7 @@ export type CreateIosBuildMutationVariables = Exact<{
}>;
export type CreateIosBuildMutation = { __typename?: 'RootMutation', build?: { __typename?: 'BuildMutation', createIosBuild: { __typename?: 'CreateBuildResult', build: { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null | undefined, releaseChannel?: string | null | undefined, distribution?: DistributionType | null | undefined, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null | undefined, buildProfile?: string | null | undefined, sdkVersion?: string | null | undefined, appVersion?: string | null | undefined, appBuildVersion?: string | null | undefined, runtimeVersion?: string | null | undefined, gitCommitHash?: string | null | undefined, createdAt?: any | null | undefined, updatedAt?: any | null | undefined, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null | undefined } | null | undefined, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null | undefined, xcodeBuildLogsUrl?: string | null | undefined } | null | undefined, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null | undefined, project: { __typename: 'App', id: string, name: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string } }, deprecationInfo?: { __typename?: 'EASBuildDeprecationInfo', type: EasBuildDeprecationInfoType, message: string } | null | undefined } } | null | undefined };
export type CreateIosBuildMutation = { __typename?: 'RootMutation', build: { __typename?: 'BuildMutation', createIosBuild: { __typename?: 'CreateBuildResult', build: { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, releaseChannel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, createdAt?: any | null, updatedAt?: any | null, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string } }, deprecationInfo?: { __typename?: 'EASBuildDeprecationInfo', type: EasBuildDeprecationInfoType, message: string } | null } } };
export type CreateEnvironmentSecretForAccountMutationVariables = Exact<{
input: CreateEnvironmentSecretInput;
@@ -4216,14 +4237,22 @@ export type GetSignedUploadMutationVariables = Exact<{
}>;
export type GetSignedUploadMutation = { __typename?: 'RootMutation', asset: { __typename?: 'AssetMutation', getSignedAssetUploadSpecifications?: { __typename?: 'GetSignedAssetUploadSpecificationsResult', specifications: Array<string | null | undefined> } | null | undefined } };
export type GetSignedUploadMutation = { __typename?: 'RootMutation', asset: { __typename?: 'AssetMutation', getSignedAssetUploadSpecifications: { __typename?: 'GetSignedAssetUploadSpecificationsResult', specifications: Array<string> } } };
export type UpdatePublishMutationVariables = Exact<{
publishUpdateGroupsInput: Array<PublishUpdateGroupInput> | PublishUpdateGroupInput;
}>;
export type UpdatePublishMutation = { __typename?: 'RootMutation', updateBranch: { __typename?: 'UpdateBranchMutation', publishUpdateGroups: Array<{ __typename?: 'Update', id: string, group: string, runtimeVersion: string, platform: string }> } };
export type UpdatePublishMutation = { __typename?: 'RootMutation', updateBranch: { __typename?: 'UpdateBranchMutation', publishUpdateGroups: Array<{ __typename?: 'Update', id: string, group: string, runtimeVersion: string, platform: string, manifestPermalink: string }> } };
export type SetCodeSigningInfoMutationVariables = Exact<{
updateId: Scalars['ID'];
codeSigningInfo: CodeSigningInfoInput;
}>;
export type SetCodeSigningInfoMutation = { __typename?: 'RootMutation', update: { __typename?: 'UpdateMutation', setCodeSigningInfo: { __typename?: 'Update', id: string, group: string, awaitingCodeSigningInfo: boolean, codeSigningInfo?: { __typename?: 'CodeSigningInfo', keyid: string, alg: string, sig: string } | null } } };
export type CreateAndroidSubmissionMutationVariables = Exact<{
appId: Scalars['ID'];
@@ -4232,7 +4261,7 @@ export type CreateAndroidSubmissionMutationVariables = Exact<{
}>;
export type CreateAndroidSubmissionMutation = { __typename?: 'RootMutation', submission: { __typename?: 'SubmissionMutation', createAndroidSubmission: { __typename?: 'CreateSubmissionResult', submission: { __typename?: 'Submission', id: string, status: SubmissionStatus, platform: AppPlatform, logsUrl?: string | null | undefined, app: { __typename?: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } }, androidConfig?: { __typename?: 'AndroidSubmissionConfig', applicationIdentifier?: string | null | undefined, track: SubmissionAndroidTrack, releaseStatus?: SubmissionAndroidReleaseStatus | null | undefined } | null | undefined, iosConfig?: { __typename?: 'IosSubmissionConfig', ascAppIdentifier: string, appleIdUsername?: string | null | undefined } | null | undefined, error?: { __typename?: 'SubmissionError', errorCode?: string | null | undefined, message?: string | null | undefined } | null | undefined } } } };
export type CreateAndroidSubmissionMutation = { __typename?: 'RootMutation', submission: { __typename?: 'SubmissionMutation', createAndroidSubmission: { __typename?: 'CreateSubmissionResult', submission: { __typename?: 'Submission', id: string, status: SubmissionStatus, platform: AppPlatform, logsUrl?: string | null, app: { __typename?: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } }, androidConfig?: { __typename?: 'AndroidSubmissionConfig', applicationIdentifier?: string | null, track: SubmissionAndroidTrack, releaseStatus?: SubmissionAndroidReleaseStatus | null } | null, iosConfig?: { __typename?: 'IosSubmissionConfig', ascAppIdentifier: string, appleIdUsername?: string | null } | null, error?: { __typename?: 'SubmissionError', errorCode?: string | null, message?: string | null } | null } } } };
export type CreateIosSubmissionMutationVariables = Exact<{
appId: Scalars['ID'];
@@ -4241,7 +4270,7 @@ export type CreateIosSubmissionMutationVariables = Exact<{
}>;
export type CreateIosSubmissionMutation = { __typename?: 'RootMutation', submission: { __typename?: 'SubmissionMutation', createIosSubmission: { __typename?: 'CreateSubmissionResult', submission: { __typename?: 'Submission', id: string, status: SubmissionStatus, platform: AppPlatform, logsUrl?: string | null | undefined, app: { __typename?: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } }, androidConfig?: { __typename?: 'AndroidSubmissionConfig', applicationIdentifier?: string | null | undefined, track: SubmissionAndroidTrack, releaseStatus?: SubmissionAndroidReleaseStatus | null | undefined } | null | undefined, iosConfig?: { __typename?: 'IosSubmissionConfig', ascAppIdentifier: string, appleIdUsername?: string | null | undefined } | null | undefined, error?: { __typename?: 'SubmissionError', errorCode?: string | null | undefined, message?: string | null | undefined } | null | undefined } } } };
export type CreateIosSubmissionMutation = { __typename?: 'RootMutation', submission: { __typename?: 'SubmissionMutation', createIosSubmission: { __typename?: 'CreateSubmissionResult', submission: { __typename?: 'Submission', id: string, status: SubmissionStatus, platform: AppPlatform, logsUrl?: string | null, app: { __typename?: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } }, androidConfig?: { __typename?: 'AndroidSubmissionConfig', applicationIdentifier?: string | null, track: SubmissionAndroidTrack, releaseStatus?: SubmissionAndroidReleaseStatus | null } | null, iosConfig?: { __typename?: 'IosSubmissionConfig', ascAppIdentifier: string, appleIdUsername?: string | null } | null, error?: { __typename?: 'SubmissionError', errorCode?: string | null, message?: string | null } | null } } } };
export type CreateUploadSessionMutationVariables = Exact<{
type: UploadSessionType;
@@ -4273,12 +4302,20 @@ export type DeleteWebhookMutationVariables = Exact<{
export type DeleteWebhookMutation = { __typename?: 'RootMutation', webhook: { __typename?: 'WebhookMutation', deleteWebhook: { __typename?: 'DeleteWebhookResult', id: string } } };
export type ViewBranchQueryVariables = Exact<{
appId: Scalars['String'];
name: Scalars['String'];
}>;
export type ViewBranchQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateBranchByName?: { __typename?: 'UpdateBranch', id: string, name: string } | null } } };
export type BuildsByIdQueryVariables = Exact<{
buildId: Scalars['ID'];
}>;
export type BuildsByIdQuery = { __typename?: 'RootQuery', builds: { __typename?: 'BuildQuery', byId: { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null | undefined, releaseChannel?: string | null | undefined, distribution?: DistributionType | null | undefined, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null | undefined, buildProfile?: string | null | undefined, sdkVersion?: string | null | undefined, appVersion?: string | null | undefined, appBuildVersion?: string | null | undefined, runtimeVersion?: string | null | undefined, gitCommitHash?: string | null | undefined, createdAt?: any | null | undefined, updatedAt?: any | null | undefined, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null | undefined } | null | undefined, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null | undefined, xcodeBuildLogsUrl?: string | null | undefined } | null | undefined, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null | undefined, project: { __typename: 'App', id: string, name: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string } } } };
export type BuildsByIdQuery = { __typename?: 'RootQuery', builds: { __typename?: 'BuildQuery', byId: { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, releaseChannel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, createdAt?: any | null, updatedAt?: any | null, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string } } } };
export type GetAllBuildsForAppQueryVariables = Exact<{
appId: Scalars['String'];
@@ -4288,7 +4325,15 @@ export type GetAllBuildsForAppQueryVariables = Exact<{
}>;
export type GetAllBuildsForAppQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, builds: Array<{ __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null | undefined, releaseChannel?: string | null | undefined, distribution?: DistributionType | null | undefined, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null | undefined, buildProfile?: string | null | undefined, sdkVersion?: string | null | undefined, appVersion?: string | null | undefined, appBuildVersion?: string | null | undefined, runtimeVersion?: string | null | undefined, gitCommitHash?: string | null | undefined, createdAt?: any | null | undefined, updatedAt?: any | null | undefined, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null | undefined } | null | undefined, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null | undefined, xcodeBuildLogsUrl?: string | null | undefined } | null | undefined, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null | undefined, project: { __typename: 'App', id: string, name: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string } }> } } };
export type GetAllBuildsForAppQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, builds: Array<{ __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, releaseChannel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, createdAt?: any | null, updatedAt?: any | null, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string } }> } } };
export type GetChannelByNameForAppQueryVariables = Exact<{
appId: Scalars['String'];
channelName: Scalars['String'];
}>;
export type GetChannelByNameForAppQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateChannelByName?: { __typename?: 'UpdateChannel', id: string, name: string, createdAt: any, branchMapping: string, updateBranches: Array<{ __typename?: 'UpdateBranch', id: string, name: string, updates: Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, runtimeVersion: string, createdAt: any, platform: string, actor?: { __typename?: 'Robot', firstName?: string | null, id: string } | { __typename?: 'User', username: string, id: string } | null }> }> } | null } } };
export type EnvironmentSecretsByAccountNameQueryVariables = Exact<{
accountName: Scalars['String'];
@@ -4324,7 +4369,7 @@ export type SubmissionsByIdQueryVariables = Exact<{
}>;
export type SubmissionsByIdQuery = { __typename?: 'RootQuery', submissions: { __typename?: 'SubmissionQuery', byId: { __typename?: 'Submission', id: string, status: SubmissionStatus, platform: AppPlatform, logsUrl?: string | null | undefined, app: { __typename?: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } }, androidConfig?: { __typename?: 'AndroidSubmissionConfig', applicationIdentifier?: string | null | undefined, track: SubmissionAndroidTrack, releaseStatus?: SubmissionAndroidReleaseStatus | null | undefined } | null | undefined, iosConfig?: { __typename?: 'IosSubmissionConfig', ascAppIdentifier: string, appleIdUsername?: string | null | undefined } | null | undefined, error?: { __typename?: 'SubmissionError', errorCode?: string | null | undefined, message?: string | null | undefined } | null | undefined } } };
export type SubmissionsByIdQuery = { __typename?: 'RootQuery', submissions: { __typename?: 'SubmissionQuery', byId: { __typename?: 'Submission', id: string, status: SubmissionStatus, platform: AppPlatform, logsUrl?: string | null, app: { __typename?: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } }, androidConfig?: { __typename?: 'AndroidSubmissionConfig', applicationIdentifier?: string | null, track: SubmissionAndroidTrack, releaseStatus?: SubmissionAndroidReleaseStatus | null } | null, iosConfig?: { __typename?: 'IosSubmissionConfig', ascAppIdentifier: string, appleIdUsername?: string | null } | null, error?: { __typename?: 'SubmissionError', errorCode?: string | null, message?: string | null } | null } } };
export type GetAllSubmissionsForAppQueryVariables = Exact<{
appId: Scalars['String'];
@@ -4335,7 +4380,7 @@ export type GetAllSubmissionsForAppQueryVariables = Exact<{
}>;
export type GetAllSubmissionsForAppQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, submissions: Array<{ __typename?: 'Submission', id: string, status: SubmissionStatus, platform: AppPlatform, logsUrl?: string | null | undefined, app: { __typename?: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } }, androidConfig?: { __typename?: 'AndroidSubmissionConfig', applicationIdentifier?: string | null | undefined, track: SubmissionAndroidTrack, releaseStatus?: SubmissionAndroidReleaseStatus | null | undefined } | null | undefined, iosConfig?: { __typename?: 'IosSubmissionConfig', ascAppIdentifier: string, appleIdUsername?: string | null | undefined } | null | undefined, error?: { __typename?: 'SubmissionError', errorCode?: string | null | undefined, message?: string | null | undefined } | null | undefined }> } } };
export type GetAllSubmissionsForAppQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, submissions: Array<{ __typename?: 'Submission', id: string, status: SubmissionStatus, platform: AppPlatform, logsUrl?: string | null, app: { __typename?: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } }, androidConfig?: { __typename?: 'AndroidSubmissionConfig', applicationIdentifier?: string | null, track: SubmissionAndroidTrack, releaseStatus?: SubmissionAndroidReleaseStatus | null } | null, iosConfig?: { __typename?: 'IosSubmissionConfig', ascAppIdentifier: string, appleIdUsername?: string | null } | null, error?: { __typename?: 'SubmissionError', errorCode?: string | null, message?: string | null } | null }> } } };
export type ViewAllUpdatesQueryVariables = Exact<{
appId: Scalars['String'];
@@ -4343,7 +4388,7 @@ export type ViewAllUpdatesQueryVariables = Exact<{
}>;
export type ViewAllUpdatesQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateBranches: Array<{ __typename?: 'UpdateBranch', id: string, name: string, updates: Array<{ __typename?: 'Update', id: string, group: string, message?: string | null | undefined, createdAt: any, runtimeVersion: string, platform: string, actor?: { __typename?: 'Robot', firstName?: string | null | undefined, id: string } | { __typename?: 'User', username: string, id: string } | null | undefined }> }> } } };
export type ViewAllUpdatesQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateBranches: Array<{ __typename?: 'UpdateBranch', id: string, name: string, updates: Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, actor?: { __typename?: 'Robot', firstName?: string | null, id: string } | { __typename?: 'User', username: string, id: string } | null }> }> } } };
export type ViewBranchUpdatesQueryVariables = Exact<{
appId: Scalars['String'];
@@ -4352,12 +4397,12 @@ export type ViewBranchUpdatesQueryVariables = Exact<{
}>;
export type ViewBranchUpdatesQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateBranchByName?: { __typename?: 'UpdateBranch', id: string, name: string, updates: Array<{ __typename?: 'Update', id: string, group: string, message?: string | null | undefined, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, actor?: { __typename?: 'Robot', firstName?: string | null | undefined, id: string } | { __typename?: 'User', username: string, id: string } | null | undefined }> } | null | undefined } } };
export type ViewBranchUpdatesQuery = { __typename?: 'RootQuery', app: { __typename?: 'AppQuery', byId: { __typename?: 'App', id: string, updateBranchByName?: { __typename?: 'UpdateBranch', id: string, name: string, updates: Array<{ __typename?: 'Update', id: string, group: string, message?: string | null, createdAt: any, runtimeVersion: string, platform: string, manifestFragment: string, actor?: { __typename?: 'Robot', firstName?: string | null, id: string } | { __typename?: 'User', username: string, id: string } | null }> } | null } } };
export type CurrentUserQueryVariables = Exact<{ [key: string]: never; }>;
export type CurrentUserQuery = { __typename?: 'RootQuery', meActor?: { __typename: 'Robot', firstName?: string | null | undefined, id: string, isExpoAdmin: boolean, accounts: Array<{ __typename?: 'Account', id: string, name: string }> } | { __typename: 'User', username: string, id: string, isExpoAdmin: boolean, accounts: Array<{ __typename?: 'Account', id: string, name: string }> } | null | undefined };
export type CurrentUserQuery = { __typename?: 'RootQuery', meActor?: { __typename: 'Robot', firstName?: string | null, id: string, isExpoAdmin: boolean, accounts: Array<{ __typename?: 'Account', id: string, name: string }> } | { __typename: 'User', username: string, id: string, isExpoAdmin: boolean, accounts: Array<{ __typename?: 'Account', id: string, name: string }> } | null };
export type WebhooksByAppIdQueryVariables = Exact<{
appId: Scalars['String'];
@@ -4376,46 +4421,46 @@ export type WebhookByIdQuery = { __typename?: 'RootQuery', webhook: { __typename
export type AppFragment = { __typename?: 'App', id: string, fullName: string, slug: string };
export type BuildFragment = { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null | undefined, releaseChannel?: string | null | undefined, distribution?: DistributionType | null | undefined, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null | undefined, buildProfile?: string | null | undefined, sdkVersion?: string | null | undefined, appVersion?: string | null | undefined, appBuildVersion?: string | null | undefined, runtimeVersion?: string | null | undefined, gitCommitHash?: string | null | undefined, createdAt?: any | null | undefined, updatedAt?: any | null | undefined, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null | undefined } | null | undefined, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null | undefined, xcodeBuildLogsUrl?: string | null | undefined } | null | undefined, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null | undefined, project: { __typename: 'App', id: string, name: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string } };
export type BuildFragment = { __typename?: 'Build', id: string, status: BuildStatus, platform: AppPlatform, channel?: string | null, releaseChannel?: string | null, distribution?: DistributionType | null, iosEnterpriseProvisioning?: BuildIosEnterpriseProvisioning | null, buildProfile?: string | null, sdkVersion?: string | null, appVersion?: string | null, appBuildVersion?: string | null, runtimeVersion?: string | null, gitCommitHash?: string | null, createdAt?: any | null, updatedAt?: any | null, error?: { __typename?: 'BuildError', errorCode: string, message: string, docsUrl?: string | null } | null, artifacts?: { __typename?: 'BuildArtifacts', buildUrl?: string | null, xcodeBuildLogsUrl?: string | null } | null, initiatingActor?: { __typename: 'Robot', id: string, displayName: string } | { __typename: 'User', id: string, displayName: string } | null, project: { __typename: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } } | { __typename: 'Snack', id: string, name: string, slug: string } };
export type EnvironmentSecretFragment = { __typename?: 'EnvironmentSecret', id: string, name: string, createdAt: any };
export type SubmissionFragment = { __typename?: 'Submission', id: string, status: SubmissionStatus, platform: AppPlatform, logsUrl?: string | null | undefined, app: { __typename?: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } }, androidConfig?: { __typename?: 'AndroidSubmissionConfig', applicationIdentifier?: string | null | undefined, track: SubmissionAndroidTrack, releaseStatus?: SubmissionAndroidReleaseStatus | null | undefined } | null | undefined, iosConfig?: { __typename?: 'IosSubmissionConfig', ascAppIdentifier: string, appleIdUsername?: string | null | undefined } | null | undefined, error?: { __typename?: 'SubmissionError', errorCode?: string | null | undefined, message?: string | null | undefined } | null | undefined };
export type SubmissionFragment = { __typename?: 'Submission', id: string, status: SubmissionStatus, platform: AppPlatform, logsUrl?: string | null, app: { __typename?: 'App', id: string, name: string, slug: string, ownerAccount: { __typename?: 'Account', id: string, name: string } }, androidConfig?: { __typename?: 'AndroidSubmissionConfig', applicationIdentifier?: string | null, track: SubmissionAndroidTrack, releaseStatus?: SubmissionAndroidReleaseStatus | null } | null, iosConfig?: { __typename?: 'IosSubmissionConfig', ascAppIdentifier: string, appleIdUsername?: string | null } | null, error?: { __typename?: 'SubmissionError', errorCode?: string | null, message?: string | null } | null };
export type UpdateBranchFragment = { __typename?: 'UpdateBranch', id: string, name: string, updates: Array<{ __typename?: 'Update', id: string, createdAt: any, message?: string | null | undefined, runtimeVersion: string, group: string, platform: string, actor?: { __typename: 'Robot', firstName?: string | null | undefined, id: string } | { __typename: 'User', username: string, id: string } | null | undefined }> };
export type UpdateBranchFragment = { __typename?: 'UpdateBranch', id: string, name: string, updates: Array<{ __typename?: 'Update', id: string, createdAt: any, message?: string | null, runtimeVersion: string, group: string, platform: string, actor?: { __typename: 'Robot', firstName?: string | null, id: string } | { __typename: 'User', username: string, id: string } | null }> };
export type WebhookFragment = { __typename?: 'Webhook', id: string, event: WebhookType, url: string, createdAt: any, updatedAt: any };
export type AndroidAppBuildCredentialsFragment = { __typename?: 'AndroidAppBuildCredentials', id: string, isDefault: boolean, isLegacy: boolean, name: string, androidKeystore?: { __typename?: 'AndroidKeystore', id: string, type: AndroidKeystoreType, keystore: string, keystorePassword: string, keyAlias: string, keyPassword?: string | null | undefined, md5CertificateFingerprint?: string | null | undefined, sha1CertificateFingerprint?: string | null | undefined, sha256CertificateFingerprint?: string | null | undefined, createdAt: any, updatedAt: any } | null | undefined };
export type AndroidAppBuildCredentialsFragment = { __typename?: 'AndroidAppBuildCredentials', id: string, isDefault: boolean, isLegacy: boolean, name: string, androidKeystore?: { __typename?: 'AndroidKeystore', id: string, type: AndroidKeystoreType, keystore: string, keystorePassword: string, keyAlias: string, keyPassword?: string | null, md5CertificateFingerprint?: string | null, sha1CertificateFingerprint?: string | null, sha256CertificateFingerprint?: string | null, createdAt: any, updatedAt: any } | null };
export type CommonAndroidAppCredentialsFragment = { __typename?: 'AndroidAppCredentials', id: string, applicationIdentifier?: string | null | undefined, isLegacy: boolean, app: { __typename?: 'App', id: string, fullName: string, slug: string }, androidFcm?: { __typename?: 'AndroidFcm', id: string, credential: any, version: AndroidFcmVersion, createdAt: any, updatedAt: any, snippet: { __typename?: 'FcmSnippetLegacy', firstFourCharacters: string, lastFourCharacters: string } | { __typename?: 'FcmSnippetV1', projectId: string, keyId: string, serviceAccountEmail: string, clientId?: string | null | undefined } } | null | undefined, googleServiceAccountKeyForSubmissions?: { __typename?: 'GoogleServiceAccountKey', id: string, projectIdentifier: string, privateKeyIdentifier: string, clientEmail: string, clientIdentifier: string, createdAt: any, updatedAt: any } | null | undefined, androidAppBuildCredentialsList: Array<{ __typename?: 'AndroidAppBuildCredentials', id: string, isDefault: boolean, isLegacy: boolean, name: string, androidKeystore?: { __typename?: 'AndroidKeystore', id: string, type: AndroidKeystoreType, keystore: string, keystorePassword: string, keyAlias: string, keyPassword?: string | null | undefined, md5CertificateFingerprint?: string | null | undefined, sha1CertificateFingerprint?: string | null | undefined, sha256CertificateFingerprint?: string | null | undefined, createdAt: any, updatedAt: any } | null | undefined }> };
export type CommonAndroidAppCredentialsFragment = { __typename?: 'AndroidAppCredentials', id: string, applicationIdentifier?: string | null, isLegacy: boolean, app: { __typename?: 'App', id: string, fullName: string, slug: string }, androidFcm?: { __typename?: 'AndroidFcm', id: string, credential: any, version: AndroidFcmVersion, createdAt: any, updatedAt: any, snippet: { __typename?: 'FcmSnippetLegacy', firstFourCharacters: string, lastFourCharacters: string } | { __typename?: 'FcmSnippetV1', projectId: string, keyId: string, serviceAccountEmail: string, clientId?: string | null } } | null, googleServiceAccountKeyForSubmissions?: { __typename?: 'GoogleServiceAccountKey', id: string, projectIdentifier: string, privateKeyIdentifier: string, clientEmail: string, clientIdentifier: string, createdAt: any, updatedAt: any } | null, androidAppBuildCredentialsList: Array<{ __typename?: 'AndroidAppBuildCredentials', id: string, isDefault: boolean, isLegacy: boolean, name: string, androidKeystore?: { __typename?: 'AndroidKeystore', id: string, type: AndroidKeystoreType, keystore: string, keystorePassword: string, keyAlias: string, keyPassword?: string | null, md5CertificateFingerprint?: string | null, sha1CertificateFingerprint?: string | null, sha256CertificateFingerprint?: string | null, createdAt: any, updatedAt: any } | null }> };
export type AndroidFcmFragment = { __typename?: 'AndroidFcm', id: string, credential: any, version: AndroidFcmVersion, createdAt: any, updatedAt: any, snippet: { __typename?: 'FcmSnippetLegacy', firstFourCharacters: string, lastFourCharacters: string } | { __typename?: 'FcmSnippetV1', projectId: string, keyId: string, serviceAccountEmail: string, clientId?: string | null | undefined } };
export type AndroidFcmFragment = { __typename?: 'AndroidFcm', id: string, credential: any, version: AndroidFcmVersion, createdAt: any, updatedAt: any, snippet: { __typename?: 'FcmSnippetLegacy', firstFourCharacters: string, lastFourCharacters: string } | { __typename?: 'FcmSnippetV1', projectId: string, keyId: string, serviceAccountEmail: string, clientId?: string | null } };
export type AndroidKeystoreFragment = { __typename?: 'AndroidKeystore', id: string, type: AndroidKeystoreType, keystore: string, keystorePassword: string, keyAlias: string, keyPassword?: string | null | undefined, md5CertificateFingerprint?: string | null | undefined, sha1CertificateFingerprint?: string | null | undefined, sha256CertificateFingerprint?: string | null | undefined, createdAt: any, updatedAt: any };
export type AndroidKeystoreFragment = { __typename?: 'AndroidKeystore', id: string, type: AndroidKeystoreType, keystore: string, keystorePassword: string, keyAlias: string, keyPassword?: string | null, md5CertificateFingerprint?: string | null, sha1CertificateFingerprint?: string | null, sha256CertificateFingerprint?: string | null, createdAt: any, updatedAt: any };
export type AppStoreConnectApiKeyFragment = { __typename?: 'AppStoreConnectApiKey', id: string, issuerIdentifier: string, keyIdentifier: string, name?: string | null | undefined, roles?: Array<AppStoreConnectUserRole> | null | undefined, createdAt: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined };
export type AppStoreConnectApiKeyFragment = { __typename?: 'AppStoreConnectApiKey', id: string, issuerIdentifier: string, keyIdentifier: string, name?: string | null, roles?: Array<AppStoreConnectUserRole> | null, createdAt: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null };
export type AppleAppIdentifierFragment = { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string };
export type AppleDeviceFragment = { __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null | undefined, model?: string | null | undefined, deviceClass?: AppleDeviceClass | null | undefined };
export type AppleDeviceFragment = { __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null, model?: string | null, deviceClass?: AppleDeviceClass | null };
export type AppleDeviceRegistrationRequestFragment = { __typename?: 'AppleDeviceRegistrationRequest', id: string };
export type AppleDistributionCertificateFragment = { __typename?: 'AppleDistributionCertificate', id: string, certificateP12?: string | null | undefined, certificatePassword?: string | null | undefined, serialNumber: string, developerPortalIdentifier?: string | null | undefined, validityNotBefore: any, validityNotAfter: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosAppCredentials: { __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, developerPortalIdentifier?: string | null | undefined } | null | undefined }> };
export type AppleDistributionCertificateFragment = { __typename?: 'AppleDistributionCertificate', id: string, certificateP12?: string | null, certificatePassword?: string | null, serialNumber: string, developerPortalIdentifier?: string | null, validityNotBefore: any, validityNotAfter: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosAppCredentials: { __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, developerPortalIdentifier?: string | null } | null }> };
export type AppleProvisioningProfileFragment = { __typename?: 'AppleProvisioningProfile', id: string, expiration: any, developerPortalIdentifier?: string | null | undefined, provisioningProfile?: string | null | undefined, updatedAt: any, status: string, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null | undefined, model?: string | null | undefined, deviceClass?: AppleDeviceClass | null | undefined }> };
export type AppleProvisioningProfileFragment = { __typename?: 'AppleProvisioningProfile', id: string, expiration: any, developerPortalIdentifier?: string | null, provisioningProfile?: string | null, updatedAt: any, status: string, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null, model?: string | null, deviceClass?: AppleDeviceClass | null }> };
export type AppleProvisioningProfileIdentifiersFragment = { __typename?: 'AppleProvisioningProfile', id: string, developerPortalIdentifier?: string | null | undefined };
export type AppleProvisioningProfileIdentifiersFragment = { __typename?: 'AppleProvisioningProfile', id: string, developerPortalIdentifier?: string | null };
export type ApplePushKeyFragment = { __typename?: 'ApplePushKey', id: string, keyIdentifier: string, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, iosAppCredentialsList: Array<{ __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }> };
export type ApplePushKeyFragment = { __typename?: 'ApplePushKey', id: string, keyIdentifier: string, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, iosAppCredentialsList: Array<{ __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }> };
export type AppleTeamFragment = { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined };
export type AppleTeamFragment = { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null };
export type GoogleServiceAccountKeyFragment = { __typename?: 'GoogleServiceAccountKey', id: string, projectIdentifier: string, privateKeyIdentifier: string, clientEmail: string, clientIdentifier: string, createdAt: any, updatedAt: any };
export type IosAppBuildCredentialsFragment = { __typename?: 'IosAppBuildCredentials', id: string, iosDistributionType: IosDistributionType, distributionCertificate?: { __typename?: 'AppleDistributionCertificate', id: string, certificateP12?: string | null | undefined, certificatePassword?: string | null | undefined, serialNumber: string, developerPortalIdentifier?: string | null | undefined, validityNotBefore: any, validityNotAfter: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosAppCredentials: { __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, developerPortalIdentifier?: string | null | undefined } | null | undefined }> } | null | undefined, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, expiration: any, developerPortalIdentifier?: string | null | undefined, provisioningProfile?: string | null | undefined, updatedAt: any, status: string, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null | undefined, model?: string | null | undefined, deviceClass?: AppleDeviceClass | null | undefined }> } | null | undefined };
export type IosAppBuildCredentialsFragment = { __typename?: 'IosAppBuildCredentials', id: string, iosDistributionType: IosDistributionType, distributionCertificate?: { __typename?: 'AppleDistributionCertificate', id: string, certificateP12?: string | null, certificatePassword?: string | null, serialNumber: string, developerPortalIdentifier?: string | null, validityNotBefore: any, validityNotAfter: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosAppCredentials: { __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, developerPortalIdentifier?: string | null } | null }> } | null, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, expiration: any, developerPortalIdentifier?: string | null, provisioningProfile?: string | null, updatedAt: any, status: string, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null, model?: string | null, deviceClass?: AppleDeviceClass | null }> } | null };
export type CommonIosAppCredentialsWithoutBuildCredentialsFragment = { __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string }, pushKey?: { __typename?: 'ApplePushKey', id: string, keyIdentifier: string, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, iosAppCredentialsList: Array<{ __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }> } | null | undefined, appStoreConnectApiKeyForSubmissions?: { __typename?: 'AppStoreConnectApiKey', id: string, issuerIdentifier: string, keyIdentifier: string, name?: string | null | undefined, roles?: Array<AppStoreConnectUserRole> | null | undefined, createdAt: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined } | null | undefined };
export type CommonIosAppCredentialsWithoutBuildCredentialsFragment = { __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string }, pushKey?: { __typename?: 'ApplePushKey', id: string, keyIdentifier: string, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, iosAppCredentialsList: Array<{ __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }> } | null, appStoreConnectApiKeyForSubmissions?: { __typename?: 'AppStoreConnectApiKey', id: string, issuerIdentifier: string, keyIdentifier: string, name?: string | null, roles?: Array<AppStoreConnectUserRole> | null, createdAt: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null } | null };
export type CommonIosAppCredentialsFragment = { __typename?: 'IosAppCredentials', id: string, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosDistributionType: IosDistributionType, distributionCertificate?: { __typename?: 'AppleDistributionCertificate', id: string, certificateP12?: string | null | undefined, certificatePassword?: string | null | undefined, serialNumber: string, developerPortalIdentifier?: string | null | undefined, validityNotBefore: any, validityNotAfter: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosAppCredentials: { __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, developerPortalIdentifier?: string | null | undefined } | null | undefined }> } | null | undefined, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, expiration: any, developerPortalIdentifier?: string | null | undefined, provisioningProfile?: string | null | undefined, updatedAt: any, status: string, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null | undefined, model?: string | null | undefined, deviceClass?: AppleDeviceClass | null | undefined }> } | null | undefined }>, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string }, pushKey?: { __typename?: 'ApplePushKey', id: string, keyIdentifier: string, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined, iosAppCredentialsList: Array<{ __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }> } | null | undefined, appStoreConnectApiKeyForSubmissions?: { __typename?: 'AppStoreConnectApiKey', id: string, issuerIdentifier: string, keyIdentifier: string, name?: string | null | undefined, roles?: Array<AppStoreConnectUserRole> | null | undefined, createdAt: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null | undefined } | null | undefined } | null | undefined };
export type CommonIosAppCredentialsFragment = { __typename?: 'IosAppCredentials', id: string, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosDistributionType: IosDistributionType, distributionCertificate?: { __typename?: 'AppleDistributionCertificate', id: string, certificateP12?: string | null, certificatePassword?: string | null, serialNumber: string, developerPortalIdentifier?: string | null, validityNotBefore: any, validityNotAfter: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, iosAppBuildCredentialsList: Array<{ __typename?: 'IosAppBuildCredentials', id: string, iosAppCredentials: { __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, developerPortalIdentifier?: string | null } | null }> } | null, provisioningProfile?: { __typename?: 'AppleProvisioningProfile', id: string, expiration: any, developerPortalIdentifier?: string | null, provisioningProfile?: string | null, updatedAt: any, status: string, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, appleDevices: Array<{ __typename?: 'AppleDevice', id: string, identifier: string, name?: string | null, model?: string | null, deviceClass?: AppleDeviceClass | null }> } | null }>, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string }, pushKey?: { __typename?: 'ApplePushKey', id: string, keyIdentifier: string, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null, iosAppCredentialsList: Array<{ __typename?: 'IosAppCredentials', id: string, app: { __typename?: 'App', id: string, fullName: string, slug: string }, appleAppIdentifier: { __typename?: 'AppleAppIdentifier', id: string, bundleIdentifier: string } }> } | null, appStoreConnectApiKeyForSubmissions?: { __typename?: 'AppStoreConnectApiKey', id: string, issuerIdentifier: string, keyIdentifier: string, name?: string | null, roles?: Array<AppStoreConnectUserRole> | null, createdAt: any, updatedAt: any, appleTeam?: { __typename?: 'AppleTeam', id: string, appleTeamIdentifier: string, appleTeamName?: string | null } | null } | null };
@@ -51,7 +51,8 @@ export const BuildMutation = {
}
${print(BuildFragmentNode)}
`,
input
input,
{ noRetry: true }
)
.toPromise()
);
@@ -86,7 +87,8 @@ export const BuildMutation = {
}
${print(BuildFragmentNode)}
`,
input
input,
{ noRetry: true }
)
.toPromise()
);
@@ -1,7 +1,12 @@
import gql from 'graphql-tag';
import { graphqlClient, withErrorHandlingAsync } from '../client';
import { PublishUpdateGroupInput, UpdatePublishMutation } from '../generated';
import {
CodeSigningInfoInput,
PublishUpdateGroupInput,
SetCodeSigningInfoMutation,
UpdatePublishMutation,
} from '../generated';
export const PublishMutation = {
async getUploadURLsAsync(contentTypes: string[]): Promise<{ specifications: string[] }> {
@@ -43,6 +48,7 @@ export const PublishMutation = {
group
runtimeVersion
platform
manifestPermalink
}
}
}
@@ -53,4 +59,37 @@ export const PublishMutation = {
);
return data.updateBranch.publishUpdateGroups;
},
async setCodeSigningInfoAsync(
updateId: string,
codeSigningInfo: CodeSigningInfoInput
): Promise<SetCodeSigningInfoMutation['update']['setCodeSigningInfo']> {
const data = await withErrorHandlingAsync(
graphqlClient
.mutation<SetCodeSigningInfoMutation>(
gql`
mutation SetCodeSigningInfoMutation(
$updateId: ID!
$codeSigningInfo: CodeSigningInfoInput!
) {
update {
setCodeSigningInfo(updateId: $updateId, codeSigningInfo: $codeSigningInfo) {
id
group
awaitingCodeSigningInfo
codeSigningInfo {
keyid
alg
sig
}
}
}
}
`,
{ updateId, codeSigningInfo }
)
.toPromise()
);
return data.update.setCodeSigningInfo;
},
};
@@ -0,0 +1,44 @@
import gql from 'graphql-tag';
import { graphqlClient, withErrorHandlingAsync } from '../client';
import { ViewBranchQuery, ViewBranchQueryVariables } from '../generated';
export const BranchQuery = {
async getBranchByNameAsync({
appId,
name,
}: {
appId: string;
name: string;
}): Promise<ViewBranchQuery['app']['byId']['updateBranchByName']> {
const {
app: {
byId: { updateBranchByName: branch },
},
} = await withErrorHandlingAsync<ViewBranchQuery>(
graphqlClient
.query<ViewBranchQuery, ViewBranchQueryVariables>(
gql`
query ViewBranch($appId: String!, $name: String!) {
app {
byId(appId: $appId) {
id
updateBranchByName(name: $name) {
id
name
}
}
}
}
`,
{
appId,
name,
},
{ additionalTypenames: ['UpdateBranch'] }
)
.toPromise()
);
return branch;
},
};
@@ -0,0 +1,63 @@
import gql from 'graphql-tag';
import { graphqlClient, withErrorHandlingAsync } from '../client';
import { GetChannelByNameForAppQuery, GetChannelByNameForAppQueryVariables } from '../generated';
export const ChannelQuery = {
async getUpdateChannelByNameForAppAsync({
appId,
channelName,
}: GetChannelByNameForAppQueryVariables): Promise<
GetChannelByNameForAppQuery['app']['byId']['updateChannelByName']
> {
const {
app: {
byId: { updateChannelByName },
},
} = await withErrorHandlingAsync(
graphqlClient
.query<GetChannelByNameForAppQuery, GetChannelByNameForAppQueryVariables>(
gql`
query GetChannelByNameForApp($appId: String!, $channelName: String!) {
app {
byId(appId: $appId) {
id
updateChannelByName(name: $channelName) {
id
name
createdAt
branchMapping
updateBranches(offset: 0, limit: 1000) {
id
name
updates(offset: 0, limit: 10) {
id
group
message
runtimeVersion
createdAt
platform
actor {
id
... on User {
username
}
... on Robot {
firstName
}
}
}
}
}
}
}
}
`,
{ appId, channelName },
{ additionalTypenames: ['UpdateChannel', 'UpdateBranch', 'Update'] }
)
.toPromise()
);
return updateChannelByName;
},
};
@@ -23,6 +23,7 @@ export const BuildFragmentNode = gql`
__typename
id
name
slug
... on App {
ownerAccount {
id
+1 -1
View File
@@ -13,7 +13,7 @@ export const appPlatformEmojis = {
[AppPlatform.Android]: '🤖',
};
// for `eas build` and `eas submit`
// for `eas build`, `eas submit`, and `eas update`
export enum RequestedPlatform {
Android = 'android',
Ios = 'ios',
+40 -60
View File
@@ -1,16 +1,17 @@
import { AppJSONConfig, ExpoConfig, getConfigFilePaths, modifyConfigAsync } from '@expo/config';
import { ExpoConfig, getConfigFilePaths, getPackageJson, modifyConfigAsync } from '@expo/config';
import { Env } from '@expo/eas-build-job';
import chalk from 'chalk';
import gql from 'graphql-tag';
import path from 'path';
import pkgDir from 'pkg-dir';
import semver from 'semver';
import { graphqlClient, withErrorHandlingAsync } from '../graphql/client';
import { AppPrivacy, UpdateBranch } from '../graphql/generated';
import { AppPrivacy } from '../graphql/generated';
import Log from '../log';
import { confirmAsync } from '../prompts';
import { Actor } from '../user/User';
import { ensureLoggedInAsync } from '../user/actions';
import { expoCommandAsync } from '../utils/expoCli';
import { getVcsClient } from '../vcs';
import {
ensureProjectExistsAsync,
findProjectIdByAccountNameAndSlugNullableAsync,
@@ -67,6 +68,15 @@ export async function findProjectRootAsync({
return process.cwd();
}
} else {
let vcsRoot;
try {
vcsRoot = path.normalize(await getVcsClient().getRootPathAsync());
} catch {}
if (vcsRoot && vcsRoot.startsWith(projectRootDir) && vcsRoot !== projectRootDir) {
throw new Error(
`package.json is outside of the current git repository (project root: ${projectRootDir}, git root: ${vcsRoot}.`
);
}
return projectRootDir;
}
}
@@ -112,16 +122,7 @@ export async function setProjectIdAsync(
}
Log.withTick(`Linked app.json to project with ID ${chalk.bold(projectId)}`);
/**
* result.config will always be an AppJSONConfig if result.type === 'success'
* PR to fix this typing: https://github.com/expo/expo-cli/pull/3482/files
*
* Code is written to safely handle the case where config type is not
* AppJSONConfig (namely there will be no expo key and the result will be undefined).
* TODO-JJ delete AppJSONConfig casting once typing is updated in the published @expo/config and
* remove undefined alternative from return type
*/
return (result.config as AppJSONConfig)?.expo;
return result.config?.expo;
}
export async function getProjectIdAsync(
@@ -193,52 +194,6 @@ export function getProjectConfigDescription(projectDir: string): string {
return 'app.config.js/app.json';
}
export async function getBranchByNameAsync({
appId,
name,
}: {
appId: string;
name: string;
}): Promise<UpdateBranch> {
const data = await withErrorHandlingAsync(
graphqlClient
.query<
{
app: {
byId: {
updateBranchByName: UpdateBranch;
};
};
},
{
appId: string;
name: string;
}
>(
gql`
query ViewBranch($appId: String!, $name: String!) {
app {
byId(appId: $appId) {
id
updateBranchByName(name: $name) {
id
name
}
}
}
}
`,
{
appId,
name,
},
{ additionalTypenames: ['UpdateBranch'] }
)
.toPromise()
);
return data.app.byId.updateBranchByName;
}
// return project id of existing/newly created project, or null if user declines
export async function promptToCreateProjectIfNotExistsAsync(
exp: ExpoConfig
@@ -265,3 +220,28 @@ export async function promptToCreateProjectIfNotExistsAsync(
privacy,
});
}
export function isExpoUpdatesInstalled(projectDir: string): boolean {
const packageJson = getPackageJson(projectDir);
return !!(packageJson.dependencies && 'expo-updates' in packageJson.dependencies);
}
export function isExpoUpdatesInstalledOrAvailable(
projectDir: string,
sdkVersion?: string
): boolean {
// before sdk 44, expo-updates was included in with the expo module
if (sdkVersion && semver.lt(sdkVersion, '44.0.0')) {
return true;
}
return isExpoUpdatesInstalled(projectDir);
}
export async function installExpoUpdatesAsync(projectDir: string): Promise<void> {
Log.newLine();
Log.log(`Running ${chalk.bold('expo install expo-updates')}`);
Log.newLine();
await expoCommandAsync(projectDir, ['install', 'expo-updates']);
Log.newLine();
}
+1 -1
View File
@@ -277,7 +277,7 @@ export async function uploadAssetsAsync(assetsForUpdateInfoGroup: CollectedAsset
await Promise.all(
missingAssets.map((missingAsset, i) => {
const presignedPost: PresignedPost = JSON.parse(specifications[i]);
return uploadWithPresignedPostAsync(fs.createReadStream(missingAsset.path), presignedPost);
return uploadWithPresignedPostAsync(missingAsset.path, presignedPost);
})
);
+4 -3
View File
@@ -344,7 +344,7 @@ async function handlePromptSourceAsync(source: ArchivePromptSource): Promise<Arc
const sourceType = sourceTypeRaw as ArchiveSourceType;
switch (sourceType) {
case ArchiveSourceType.url: {
const url = await askForArchiveUrlAsync();
const url = await askForArchiveUrlAsync(source.platform);
return getArchiveAsync({
...source,
sourceType: ArchiveSourceType.url,
@@ -378,8 +378,9 @@ async function handlePromptSourceAsync(source: ArchivePromptSource): Promise<Arc
}
}
async function askForArchiveUrlAsync(): Promise<string> {
const defaultArchiveUrl = 'https://url.to/your/archive.aab';
async function askForArchiveUrlAsync(platform: Platform): Promise<string> {
const isIos = platform === Platform.IOS;
const defaultArchiveUrl = `https://url.to/your/archive.${isIos ? 'ipa' : 'aab'}`;
const { url } = await promptAsync({
name: 'url',
message: 'URL:',
+3 -3
View File
@@ -1,6 +1,6 @@
import chalk from 'chalk';
import got from 'got';
import fetch from '../../fetch';
import { SubmissionFragment, SubmissionStatus } from '../../graphql/generated';
import Log from '../../log';
import { printSubmissionError } from './errors';
@@ -25,8 +25,8 @@ async function downloadAndPrintSubmissionLogsAsync(submission: SubmissionFragmen
if (!submission.logsUrl) {
return;
}
const { body: data } = await got.get(submission.logsUrl);
const logs = parseLogs(data);
const response = await fetch(submission.logsUrl);
const logs = parseLogs(await response.text());
Log.addNewLineIfNone();
const prefix = chalk.blueBright('[logs] ');
for (const { level, msg } of logs) {
@@ -1,21 +1,23 @@
import { ExpoConfig } from '@expo/config';
import { AndroidConfig, AndroidManifest } from '@expo/config-plugins';
import { RequestedPlatform } from '../../platform';
import { getProjectAccountName } from '../../project/projectUtils';
import { ensureLoggedInAsync } from '../../user/actions';
import { ensureValidVersions } from '../utils/updates';
import { ensureValidVersions } from '../utils';
export async function syncUpdatesConfigurationAsync(
projectDir: string,
exp: ExpoConfig
): Promise<void> {
ensureValidVersions(exp);
ensureValidVersions(exp, RequestedPlatform.Android);
const accountName = getProjectAccountName(exp, await ensureLoggedInAsync());
const androidManifestPath = await AndroidConfig.Paths.getAndroidManifestAsync(projectDir);
const androidManifest = await getAndroidManifestAsync(projectDir);
const updatedAndroidManifest = AndroidConfig.Updates.setUpdatesConfig(
projectDir,
exp,
androidManifest,
accountName
@@ -1,20 +1,26 @@
import { ExpoConfig } from '@expo/config';
import { IOSConfig } from '@expo/config-plugins';
import { RequestedPlatform } from '../../platform';
import { getProjectAccountName } from '../../project/projectUtils';
import { ensureLoggedInAsync } from '../../user/actions';
import { readPlistAsync, writePlistAsync } from '../../utils/plist';
import { getVcsClient } from '../../vcs';
import { ensureValidVersions } from '../utils/updates';
import { ensureValidVersions } from '../utils';
export async function syncUpdatesConfigurationAsync(
projectDir: string,
exp: ExpoConfig
): Promise<void> {
ensureValidVersions(exp);
ensureValidVersions(exp, RequestedPlatform.Ios);
const accountName = getProjectAccountName(exp, await ensureLoggedInAsync());
const expoPlist = await readExpoPlistAsync(projectDir);
const updatedExpoPlist = IOSConfig.Updates.setUpdatesConfig(exp, expoPlist, accountName);
const updatedExpoPlist = IOSConfig.Updates.setUpdatesConfig(
projectDir,
exp,
expoPlist,
accountName
);
await writeExpoPlistAsync(projectDir, updatedExpoPlist);
}
@@ -43,10 +49,8 @@ export async function readReleaseChannelSafelyAsync(projectDir: string): Promise
export async function readChannelSafelyAsync(projectDir: string): Promise<string | null> {
try {
// TODO-JJ remove any once IOSConfig.ExpoPlist is updated to include `EXUpdatesRequestHeaders : Record<string,string>`
const expoPlist: any = await readExpoPlistAsync(projectDir);
//TODO-JJ 'EXUpdatesRequestHeaders' IosConfig.Updates.Config.UPDATES_CONFIGURATION_REQUEST_HEADERS_KEY once https://github.com/expo/expo-cli/pull/3571 is published
const updatesRequestHeaders = expoPlist['EXUpdatesRequestHeaders'] ?? {};
const expoPlist = await readExpoPlistAsync(projectDir);
const updatesRequestHeaders = expoPlist['EXUpdatesRequestHeaders'];
return updatesRequestHeaders['expo-channel-name'] ?? null;
} catch (err) {
return null;
+33
View File
@@ -1,6 +1,10 @@
import { ExpoConfig } from '@expo/config';
import { format } from '@expo/timeago.js';
import chalk from 'chalk';
import { Maybe, Robot, Update, User } from '../graphql/generated';
import { learnMore } from '../log';
import { RequestedPlatform } from '../platform';
import { getActorDisplayName } from '../user/User';
import groupBy from '../utils/expodash/groupBy';
@@ -41,3 +45,32 @@ export function formatUpdate(update: FormatUpdateParameter): string {
update.actor as any
)})`;
}
export function ensureValidVersions(exp: ExpoConfig, platform: RequestedPlatform): void {
const error = new Error(
`Couldn't find either ${chalk.bold('runtimeVersion')} or ${chalk.bold(
'sdkVersion'
)} to configure ${chalk.bold(
'expo-updates'
)}. Please specify at least one of these properties under the ${chalk.bold(
'expo'
)} key in ${chalk.bold('app.json')}. ${learnMore(
'https://docs.expo.dev/eas-update/runtime-versions/'
)}`
);
if (
[RequestedPlatform.Android, RequestedPlatform.All].includes(platform) &&
!(exp.android?.runtimeVersion || exp.runtimeVersion) &&
!exp.sdkVersion
) {
throw error;
}
if (
[RequestedPlatform.Ios, RequestedPlatform.All].includes(platform) &&
!(exp.ios?.runtimeVersion || exp.runtimeVersion) &&
!exp.sdkVersion
) {
throw error;
}
}
+29 -23
View File
@@ -1,17 +1,11 @@
import assert from 'assert';
import FormData from 'form-data';
import fs from 'fs-extra';
import got, { Progress } from 'got';
import { Readable } from 'stream';
import fetch from './fetch';
import { UploadSessionType } from './graphql/generated';
import { PresignedPost, UploadSessionMutation } from './graphql/mutations/UploadSessionMutation';
type ProgressHandler = (props: {
progress?: Progress;
isComplete?: boolean;
error?: Error;
}) => void;
import { ProgressHandler } from './utils/progress';
export async function uploadAsync(
type: UploadSessionType,
@@ -19,42 +13,54 @@ export async function uploadAsync(
handleProgressEvent: ProgressHandler
): Promise<{ url: string; bucketKey: string }> {
const presignedPost = await UploadSessionMutation.createUploadSessionAsync(type);
const url = await uploadWithPresignedPostAsync(
fs.createReadStream(path),
presignedPost,
handleProgressEvent
);
const url = await uploadWithPresignedPostAsync(path, presignedPost, handleProgressEvent);
assert(presignedPost.fields.key, 'key is not specified in in presigned post');
return { url, bucketKey: presignedPost.fields.key };
}
export async function uploadWithPresignedPostAsync(
stream: Readable | Buffer,
file: string,
presignedPost: PresignedPost,
handleProgressEvent?: ProgressHandler
): Promise<string> {
const fileStat = await fs.stat(file);
const fileSize = fileStat.size;
const form = new FormData();
for (const [fieldKey, fieldValue] of Object.entries(presignedPost.fields)) {
form.append(fieldKey, fieldValue);
}
form.append('file', stream);
form.append('file', fs.createReadStream(file), { knownLength: fileSize });
const formHeaders = form.getHeaders();
let uploadPromise = got.post(presignedPost.url, { body: form, headers: { ...formHeaders } });
const uploadPromise = fetch(presignedPost.url, {
method: 'POST',
body: form,
headers: {
...formHeaders,
},
});
let currentSize = 0;
if (handleProgressEvent) {
uploadPromise = uploadPromise.on('uploadProgress', progress =>
handleProgressEvent({ progress })
);
form.addListener('data', (chunk: Buffer) => {
currentSize += Buffer.byteLength(chunk);
handleProgressEvent({
progress: {
total: fileSize,
percent: currentSize / fileSize,
transferred: currentSize,
},
});
});
try {
const response = await uploadPromise;
handleProgressEvent({ isComplete: true });
return String(response.headers.location);
return String(response.headers.get('location'));
} catch (error: any) {
handleProgressEvent({ isComplete: true, error });
throw error;
}
} else {
const response = await uploadPromise;
return String(response.headers.get('location'));
}
const response = await uploadPromise;
return String(response.headers.location);
}
+3 -5
View File
@@ -1,7 +1,7 @@
import gql from 'graphql-tag';
import * as Analytics from '../analytics/rudderstackClient';
import { apiClient } from '../api';
import { api } from '../api';
import { graphqlClient } from '../graphql/client';
import { CurrentUserQuery } from '../graphql/generated';
import { UserQuery } from '../graphql/queries/UserQuery';
@@ -54,10 +54,8 @@ export async function loginAsync({
password: string;
otp?: string;
}): Promise<void> {
const body = await apiClient
.post('auth/loginAsync', { json: { username, password, otp } })
.json();
const { sessionSecret } = (body as any).data;
const body = await api.postAsync('auth/loginAsync', { body: { username, password, otp } });
const { sessionSecret } = body.data;
const result = await graphqlClient
.query(
gql`
@@ -13,13 +13,10 @@ import {
jest.mock('fs');
jest.mock('../../api', () => ({
apiClient: {
post: jest.fn(() => {
return {
json: () => Promise.resolve({ data: { sessionSecret: 'SESSION_SECRET' } }),
};
}),
api: {
postAsync: jest.fn(async () => ({ data: { sessionSecret: 'SESSION_SECRET' } })),
},
ApiV2Error: jest.requireActual('../../api').ApiV2Error,
}));
jest.mock('../../graphql/client', () => ({
graphqlClient: {
@@ -1,12 +1,15 @@
import ApiV2Error from '../../ApiV2Error';
import { asMock } from '../../__tests__/utils';
import { ApiV2Error } from '../../api';
import { promptAsync } from '../../prompts';
import { Actor, loginAsync } from '../User';
import { ensureActorHasUsername, showLoginPromptAsync } from '../actions';
import { UserSecondFactorDeviceMethod, retryUsernamePasswordAuthWithOTPAsync } from '../otp';
jest.mock('../../prompts');
jest.mock('../../api');
jest.mock('../../api', () => ({
ApiV2Error: jest.requireActual('../../api').ApiV2Error,
}));
jest.mock('../otp');
jest.mock('../User', () => ({
loginAsync: jest.fn(),
@@ -57,7 +60,7 @@ describe(showLoginPromptAsync, () => {
});
asMock(loginAsync)
.mockImplementationOnce(async () => {
throw new ApiV2Error({ code: 'testcode', request: {} } as any, {
throw new ApiV2Error({
message: 'An OTP is required',
code: 'ONE_TIME_PASSWORD_REQUIRED',
metadata: {
@@ -1,5 +1,5 @@
import { asMock } from '../../__tests__/utils';
import { apiClient } from '../../api';
import { api } from '../../api';
import Log from '../../log';
import { promptAsync, selectAsync } from '../../prompts';
import { loginAsync } from '../User';
@@ -186,9 +186,7 @@ describe(retryUsernamePasswordAuthWithOTPAsync, () => {
throw new Error("shouldn't happen");
});
asMock(apiClient.post).mockReturnValueOnce({
json: () => Promise.resolve({ data: { sessionSecret: 'SESSION_SECRET' } }),
});
asMock(api.postAsync).mockReturnValueOnce(Promise.resolve({ sessionSecret: 'SESSION_SECRET' }));
await retryUsernamePasswordAuthWithOTPAsync('blah', 'blah', {
secondFactorDevices: [
@@ -209,10 +207,10 @@ describe(retryUsernamePasswordAuthWithOTPAsync, () => {
});
expect(asMock(promptAsync).mock.calls.length).toBe(2); // first OTP, second OTP
expect(asMock(apiClient.post).mock.calls[0]).toEqual([
expect(asMock(api.postAsync).mock.calls[0]).toEqual([
'auth/send-sms-otp',
{
json: {
body: {
username: 'blah',
password: 'blah',
secondFactorDeviceID: 'p2',
+1 -1
View File
@@ -2,7 +2,7 @@ import { Errors } from '@oclif/core';
import chalk from 'chalk';
import nullthrows from 'nullthrows';
import ApiV2Error from '../ApiV2Error';
import { ApiV2Error } from '../api';
import Log, { learnMore } from '../log';
import { promptAsync } from '../prompts';
import { Actor, getUserAsync, loginAsync } from './User';
+8 -10
View File
@@ -1,7 +1,7 @@
import assert from 'assert';
import chalk from 'chalk';
import { apiClient } from '../api';
import { api } from '../api';
import Log from '../log';
import { promptAsync, selectAsync } from '../prompts';
import { loginAsync } from './User';
@@ -92,15 +92,13 @@ async function promptForBackupOTPAsync(
const device = smsNonPrimarySecondFactorDevices[selectedValue];
await apiClient
.post('auth/send-sms-otp', {
json: {
username,
password,
secondFactorDeviceID: device.id,
},
})
.json();
await api.postAsync('auth/send-sms-otp', {
body: {
username,
password,
secondFactorDeviceID: device.id,
},
});
return await promptForOTPAsync('cancel');
}
@@ -0,0 +1,349 @@
import FormData from 'form-data';
import path from 'path';
import { Headers, Response } from '../../fetch';
import { PartialManifest } from '../../graphql/generated';
import {
checkManifestBodyAgainstUpdateInfoGroup,
getCodeSigningInfoAsync,
getKeyAndCertificateFromPathsAsync,
getManifestBodyAsync,
parseMultipartMixedResponseAsync,
} from '../code-signing';
function generateMultipartBody(stringifiedManifest: string): FormData {
const form = new FormData();
// This generates a 26 + 24 character boundary similar to those used by Firefox and form-data.
let boundary = '-----ExpoManifestBoundary-';
for (let i = 0; i < 24; i++) {
boundary += Math.floor(Math.random() * 16).toString(16);
}
form.setBoundary(boundary);
form.append('manifest', stringifiedManifest, {
contentType: 'application/json',
});
form.append('extensions', JSON.stringify({}), {
contentType: 'application/json',
});
return form;
}
describe(getCodeSigningInfoAsync, () => {
it('throws when codeSigningMetadata is not specified for EAS', async () => {
await expect(
getCodeSigningInfoAsync(
{
name: 'wat',
slug: 'test',
updates: {
codeSigningCertificate: 'wat',
} as any,
},
'test'
)
).rejects.toThrow(
'Must specify codeSigningMetadata under the "updates" field of your app config file to use EAS code signing'
);
});
});
describe(getKeyAndCertificateFromPathsAsync, () => {
it('throws an informative error when file at either path does not exist', async () => {
const codeSigningCertificatePath = path.join(
__dirname,
'./fixtures/certificate-path-not-exist.pem'
);
const privateKeyPath = path.join(__dirname, './fixtures/test-private-key.pem');
await expect(
getKeyAndCertificateFromPathsAsync({
codeSigningCertificatePath,
privateKeyPath,
})
).rejects.toThrow(
`Code signing certificate cannot be read from path: ${codeSigningCertificatePath}`
);
const codeSigningCertificatePath2 = path.join(__dirname, './fixtures/test-certificate.pem');
const privateKeyPath2 = path.join(__dirname, './fixtures/private-key-path-not-exist.pem');
await expect(
getKeyAndCertificateFromPathsAsync({
codeSigningCertificatePath: codeSigningCertificatePath2,
privateKeyPath: privateKeyPath2,
})
).rejects.toThrow(`Code signing private key cannot be read from path: ${privateKeyPath2}`);
});
it('loads certificate and private key', async () => {
const result = await getKeyAndCertificateFromPathsAsync({
codeSigningCertificatePath: path.join(__dirname, './fixtures/test-certificate.pem'),
privateKeyPath: path.join(__dirname, './fixtures/test-private-key.pem'),
});
expect(result.certificate).not.toBe(null);
expect(result.privateKey).not.toBe(null);
});
it('validates certificate and private key', async () => {
await expect(
getKeyAndCertificateFromPathsAsync({
codeSigningCertificatePath: path.join(__dirname, './fixtures/invalid-certificate.pem'),
privateKeyPath: path.join(__dirname, './fixtures/invalid-private-key.pem'),
})
).rejects.toThrow('Certificate validity expired');
});
});
describe(parseMultipartMixedResponseAsync, () => {
it('parses multipart response', async () => {
const form = generateMultipartBody(JSON.stringify({ hello: 'world' }));
const parts = await parseMultipartMixedResponseAsync({
arrayBuffer: async () => form.getBuffer(),
headers: new Headers({
'content-type': `multipart/mixed; boundary=${form.getBoundary()}`,
}),
} as any as Response);
expect(parts).toHaveLength(2);
});
});
describe(getManifestBodyAsync, () => {
it('gets multipart manifest body', async () => {
const stringifiedManifest = JSON.stringify({ hello: 'world' });
const form = generateMultipartBody(stringifiedManifest);
const body = await getManifestBodyAsync({
arrayBuffer: async () => form.getBuffer(),
headers: new Headers({
'content-type': `multipart/mixed; boundary=${form.getBoundary()}`,
}),
} as any as Response);
expect(body).toEqual(stringifiedManifest);
});
});
describe(checkManifestBodyAgainstUpdateInfoGroup, () => {
it('returns void when valid', () => {
const manifestResponseBodyJSON = JSON.stringify({
extra: {
expoClient: {
test: 'wat',
},
},
launchAsset: {
hash: '1',
contentType: 'test/hex',
key: '1',
},
assets: [
{
hash: '2',
contentType: 'test/hex',
key: '2',
},
],
});
const partialManifest: PartialManifest = {
extra: {
expoClient: {
test: 'wat',
},
},
launchAsset: {
fileSHA256: '1',
contentType: 'test/hex',
bundleKey: '1',
storageKey: 'wat',
},
assets: [
{
fileSHA256: '2',
contentType: 'test/hex',
bundleKey: '2',
storageKey: 'wat',
},
],
};
expect(() =>
checkManifestBodyAgainstUpdateInfoGroup(manifestResponseBodyJSON, partialManifest)
).not.toThrow();
});
it('throws when extra.expoClient is tampered with', () => {
const manifestResponseBodyJSON = JSON.stringify({
extra: {
expoClient: {
test: 'wat',
},
},
launchAsset: {
fileSHA256: '1',
contentType: 'test/hex',
bundleKey: '1',
storageKey: 'wat',
},
});
const partialManifest: PartialManifest = {
extra: {
expoClient: {
test: 'wat',
maliciousExtraKey: {
nestedDeeply: {
hello: 'world',
},
},
},
},
launchAsset: {
fileSHA256: '1',
contentType: 'test/hex',
bundleKey: '1',
storageKey: 'wat',
},
assets: [],
};
expect(() =>
checkManifestBodyAgainstUpdateInfoGroup(manifestResponseBodyJSON, partialManifest)
).toThrow(
`Code signing manifest integrity error: The manifest being signed contains an extra.expoClient field that does not match the initially uploaded manifest's extra.expoClient field`
);
});
it('throws when assets differ in length', () => {
const manifestResponseBodyJSON = JSON.stringify({
extra: {
expoClient: {
test: 'wat',
},
},
launchAsset: {
hash: '1',
contentType: 'test/hex',
key: '1',
},
assets: [
{
hash: '2',
contentType: 'test/hex',
key: '2',
},
],
});
const partialManifest: PartialManifest = {
extra: {
expoClient: {
test: 'wat',
},
},
launchAsset: {
fileSHA256: '1',
contentType: 'test/hex',
bundleKey: '1',
storageKey: 'wat',
},
assets: [],
};
expect(() =>
checkManifestBodyAgainstUpdateInfoGroup(manifestResponseBodyJSON, partialManifest)
).toThrow(
'Code signing manifest integrity error: The manifest being signed has an assets array of differing length from the initially uploaded manifest'
);
});
it('throws when an asset is not present', () => {
const manifestResponseBodyJSON = JSON.stringify({
extra: {
expoClient: {
test: 'wat',
},
},
launchAsset: {
hash: '1',
contentType: 'test/hex',
key: '1',
},
assets: [
{
hash: '2',
contentType: 'test/hex',
key: '2',
},
],
});
const partialManifest: PartialManifest = {
extra: {
expoClient: {
test: 'wat',
},
},
launchAsset: {
fileSHA256: '1',
contentType: 'test/hex',
bundleKey: '1',
storageKey: 'wat',
},
assets: [
{
fileSHA256: '3',
contentType: 'test/hex',
bundleKey: '3',
storageKey: 'wat',
},
],
};
expect(() =>
checkManifestBodyAgainstUpdateInfoGroup(manifestResponseBodyJSON, partialManifest)
).toThrow(
'Code signing manifest integrity error: The manifest being signed has is missing an asset specified in the initially uploaded manifest: 3'
);
});
it('throws when an asset has been tampered with', () => {
const manifestResponseBodyJSON = JSON.stringify({
extra: {
expoClient: {
test: 'wat',
},
},
launchAsset: {
hash: '1',
contentType: 'test/hex',
key: '1',
},
assets: [
{
hash: '2',
contentType: 'test/hex',
key: '2',
},
],
});
const partialManifest: PartialManifest = {
extra: {
expoClient: {
test: 'wat',
},
},
launchAsset: {
fileSHA256: '1',
contentType: 'test/hex',
bundleKey: '1',
storageKey: 'wat',
},
assets: [
{
fileSHA256: '2',
contentType: 'test/malicious',
bundleKey: '2',
storageKey: 'wat',
},
],
};
expect(() =>
checkManifestBodyAgainstUpdateInfoGroup(manifestResponseBodyJSON, partialManifest)
).toThrow(
'Code signing manifest integrity error: Manifest asset tamper detected for asset: 2; field: contentType'
);
});
});
@@ -0,0 +1,18 @@
-----BEGIN CERTIFICATE-----
MIICzTCCAbWgAwIBAgIJbOc3N87bRTW9MA0GCSqGSIb3DQEBCwUAMBAxDjAMBgNV
BAMTBWhlbGxvMB4XDTIyMDIwNDAxNDkzNFoXDTIyMDIwNDAxNDkzNFowEDEOMAwG
A1UEAxMFaGVsbG8wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDpQHor
Eh7eb1L8HJuKciyL/qoLAvzrHEvn0bafL6rywLu+sBqnI0jBLi76rjYOlO7Ruy8X
/tbZ6rMjoAIjW5zjk6SAZMYTVAcoJk6oKg1hgRVA6ZMQ3uvTBvw9JAvnJy2nsjXQ
NamW/ELFtlMAj9XOnTU7BGohunUcIQTfyii5IZZwaG/VsyJXBVOGUcJoG+cf6aS9
E+7ID/BNH4qYIE7IK+jZu5Etmx38BmzXJko1S0jRWGvaSZKM48S1ENsP3NgbI99V
Tu7eQyjonK5gpeYZaaRHYOT+iPNU3lGYqyLZ680IaBzZCzCjUNCG0e86b/H70yUd
Z7qH11ygtjjRMDATAgMBAAGjKjAoMA4GA1UdDwEB/wQEAwIHgDAWBgNVHSUBAf8E
DDAKBggrBgEFBQcDAzANBgkqhkiG9w0BAQsFAAOCAQEAKk5tUXJM9ofr7UWeElm0
G30mMWG6heQm/Id0oSy5JY3w4+fbWxqYqUzEiUEwJnTFkfFw3l5AJUwNXKs57XqZ
MFdxNTrFVE7N8hE3RzW93J3cS/cDF4gkmhDJFT5svDwsuQUnfrTMsC1SpNx2HJzK
AcpDOgKHfDf/5H1eV9THMK3uqCpg0144iVxWazBFENZ+GGWUjAhyEFM8VIazk/6S
8vc2DvWHI0hN0gNGIddY1rEjbZ6Vdi5yXTtja5A2mE7adHNvrc+aAUX8o94n59Af
STflvOlXarKkGGiZnyrkVovH71QOfoQBES8W1fGmRdJu2sjhkf/68XZTXFp+z/8a
Ww==
-----END CERTIFICATE-----
@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEA6UB6KxIe3m9S/BybinIsi/6qCwL86xxL59G2ny+q8sC7vrAa
pyNIwS4u+q42DpTu0bsvF/7W2eqzI6ACI1uc45OkgGTGE1QHKCZOqCoNYYEVQOmT
EN7r0wb8PSQL5yctp7I10DWplvxCxbZTAI/Vzp01OwRqIbp1HCEE38oouSGWcGhv
1bMiVwVThlHCaBvnH+mkvRPuyA/wTR+KmCBOyCvo2buRLZsd/AZs1yZKNUtI0Vhr
2kmSjOPEtRDbD9zYGyPfVU7u3kMo6JyuYKXmGWmkR2Dk/ojzVN5RmKsi2evNCGgc
2Qswo1DQhtHvOm/x+9MlHWe6h9dcoLY40TAwEwIDAQABAoIBAQCJ5n7T3AC4DSUI
vHkQ3vOLSOKLZBbXgYE26vuHHY15u4zD7iWzzt6Cp6VKu5hmApM3F+19yEKJz4Jd
e4oIEW+t9Gn7JpkccD9S82LpdQM4NDK2j+FMxh6yQpz6IMeQv870KB48nJ1JEJcB
gQuNd3w2jScdXzzH+A6otLTHAiQVXq7uLcLZ3fqBYev4yh4wOQUETjr+HxPMPEFZ
hN42ZnGIRnV4AdrKPR4RSVXGJAhP1zaEg/jNjCWvljFkM9Db8fQcmjTBUEj3jil3
1Mtw5kfWrXHBHjnOMxjb5OZF1nQAjayMlNJ6RAkq6YTqegjkRTpDaBt5dYmwngdN
JjIXG7ihAoGBAP/MGklGE0wnDtRgqed/lDLb93Kr6ra3FKY8wAVyNANfIjrLbcJu
5fkTQzADn6qtF63euODFzJTAXPsBuu21Wr0kH5TwI2ARxTxMbesnOv5M3IH95Ft/
Jx/8vgMHDw9wEyUgXGT0IP3rHZXA0MHU5He4OMTjIuGekq3rHiWZIs2bAoGBAOlv
zOiFwtNZuvh9L7e+LwB2nVMxYH6suX+LKJ3ZtkZsfJ6KC/tol0BhB5aHNvpQnL+y
y4m/ohbDL1DyKVkyXwIDQEY/xFN7IyzU219GCgAX/w0glqRzrnl7DZgq2cma6bwR
2L5w+C68W6qXtW/0dNMm+n2bFUt29Bo2fUSyoQrpAoGASRXi6M6p0tdSCGI6CVfN
Wx64O75dCKmUr86puqSfsdrrp8rZ6HTRJnJXfw95/kUIf/gj8KzzQAkaR+l9pE9t
xp7cmyxlnxxUs17PBSInW+NQGaAWMAJLhnsrOyg4KFwITFJLs9iA2KvlvxThUJBo
WsB7D94p6Dbrh9+mtG1loUMCgYEAyR2wbZhojQyewF2ikeyBtCV9T+KXnyuSuacb
/DtJBg2LpE+NGTI4NZgjIHYoUKrJEYOqRmha7r+E8XlhVF7IagSBCMUBkWbinEpb
Ig9GqGQEMrwj7VVZOYJh6PrqHf6gZ478rL7JpAJV+3ivMeBsEktfvn2xcA3xKvBN
JrW7d5kCgYAP+PJAfksrkv3yXYG9Ks0a/A6Qfdyi5wXhRg8W+tO2BZnrZM1RSKOe
TQ0lSpAA7SLCSJwSEqxt22sY4mzM7PjWi824BF/eNJ4lB+DCRFIuSsv4dxTa9HdG
theL0jT06zzlIuUsA0npbadnkOGi1p7u5LtGbA6RI4Kc6L7sBow71w==
-----END RSA PRIVATE KEY-----
@@ -0,0 +1,17 @@
-----BEGIN CERTIFICATE-----
MIICyzCCAbOgAwIBAgIJWVXVdVgS9u+DMA0GCSqGSIb3DQEBCwUAMA8xDTALBgNV
BAMTBFRlc3QwHhcNMjIwMjA0MDEzODU2WhcNMjMwMjA0MDEzODU2WjAPMQ0wCwYD
VQQDEwRUZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAp1ILmaSl
1pUVFgt/nLtzoaGuBW4OPRFN5uU2rYPow3uy4NfULKiir4AWxGETcm4gFIOG3RIb
DJys6TAJJLnFEFnzpV+qaNeqaMqnXm4OBspx/WS2rSSGIwr7raKy4yrpPYJB1A2D
5fZ6oFoWROyjbHJvPddu0PqbbEWSM3PzdZYOKfF13ofzFOPlsTnlo12QWgksxrcT
wgeX7cjHsXaUc+I8U9DRR+9SgKhejWdFNPGcMkEc5BIXwtkTau+8+DwQzXz775Wl
hf0eJwfnNQeleblbLQIp8i+RmfIjPSt8W/iTSN64iBROpOvnOeJ9gKX922QDZoqW
z9o4RTNCPfyYBQIDAQABoyowKDAOBgNVHQ8BAf8EBAMCB4AwFgYDVR0lAQH/BAww
CgYIKwYBBQUHAwMwDQYJKoZIhvcNAQELBQADggEBAHTyG2f/CReXVrS3zZjpgnje
Vn2/XYevnaHNWYIxjlUVGaASE/k6qWkM832f0gaZwJYXsll2YxJa5Jcdqa1yq8QA
Ay5YBq8Vv6K6iGTeZ5wTQc3xNys7zcS95eNq7yhDDjbLDbSDdZ8T/1hZqiha2DG5
itLGfBH+HywW2G9njLgIzNcmKx3d76y3jlVXqug1/AVFK9in+r/0t0TYlk+opqZb
H7cjJSefHusnq2vvvR6gbkZzyzSYP5FMlj/RjRCSJ+VHNwCn3fS+KDlJgVOk0Cxc
7n52UGazeFwH3mem89DN+Bhw/uyU0IcIaDLykb6PsTPy2tjHsLpK5kpvfrp2m0o=
-----END CERTIFICATE-----
@@ -0,0 +1,27 @@
-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAp1ILmaSl1pUVFgt/nLtzoaGuBW4OPRFN5uU2rYPow3uy4NfU
LKiir4AWxGETcm4gFIOG3RIbDJys6TAJJLnFEFnzpV+qaNeqaMqnXm4OBspx/WS2
rSSGIwr7raKy4yrpPYJB1A2D5fZ6oFoWROyjbHJvPddu0PqbbEWSM3PzdZYOKfF1
3ofzFOPlsTnlo12QWgksxrcTwgeX7cjHsXaUc+I8U9DRR+9SgKhejWdFNPGcMkEc
5BIXwtkTau+8+DwQzXz775Wlhf0eJwfnNQeleblbLQIp8i+RmfIjPSt8W/iTSN64
iBROpOvnOeJ9gKX922QDZoqWz9o4RTNCPfyYBQIDAQABAoIBAEKMXVTEqbkJHpPg
Cud5nuoAdkhul3cudL+LFw44UtG9V04aSadhgyMuXN/KhIOUzWmbTn6K/vsrLZKp
qllTEdAJFuEFha+hZ4O6ZosmVqnYxzGzZvzCdB9n9OYAugmkPZRbRHdk0LscJ3Wz
nvvW6sDtWtVL5CV2J28O1LFmQsTXPtEE5aQ5KX3Ix0OW1HBdEMOXRDFFDXhf7AKz
nlvl3WRsXLyHYBfKs0pQHy8Gi+zl2OgKZDc9elMdU0Mx0jTJUUDtPSgNAsmdKO26
qmkhbGd/kM1+6h+zngY3m48yD9elDxR3WUIYE2x5tT9fv3T6/xn1QfMz/gtToplx
qY1DegECgYEA3bGUq91QMIH5rxrr2BBQpniXOTtOPAdvRcRh0/EsYhHcuL+uJEtG
W9o9MqrREhXMMeD9Y8RorL+qefJjGq+GRwnPHlDjr6NkGTZfDKUn4IFH1xMbspET
Nen5BsY5inUrQ/LSg1+HiVsSDyIJzGVcGMTOh9qC53M/zIGdiEwHgUECgYEAwTZ3
AVieag5ETYahGdverxCRKlJ0MFJq3VKEdt6EcZHfeY1gmi17vGZ39q6djmfTT9Il
QVP4/mxU2/mg/UgRC+rwiAZs3qlhOrtkrGd9qPOIeZ8PJkoNlvhM2WC2rGjTfXsb
2IKtDEVXetwGgm3SXqpjycI5Xj6/9VlHAmCc4cUCgYAv9dT2AWDxvYyopyhSi+UG
vpvok73vGqSl8UBAu7IgXUDk7wLbczV7dZE7vtyQDwsn10a6KKmEhcp5q0hpY4On
JqYaJuG7A5wKIEsbzzb7SLyj+MxLKzt+tGldX9De9U4w2v1T0nzd6EfV4kVAZMUx
zpHnrgwXykUJFxlffSM6gQKBgQCMxKXHsU0Zb/OLmD7fnDWNzsA02YYVfralMW2Z
PV25cNIkuUBclC7GgNF+RJI+Ip7uVOkXw5pxo3PgIOuOHWduC2nbcPL49ucD52vd
wDjpUyVnlt9uwh1MlPNInRH6YxVTItKS2AJEInEt7ghAFstidTnm0T8Czy0EEFuP
+9vREQKBgQDIQxJ5oPIOEibJqn34z6qm5EmUyme/evvHxtQTaVuQi5CrzD5+qw1C
jOTHmlJQQsb8b1g9wk7n+JbqWYhkRiAE6dwqvp/zDz1VfR90WbAPYQ8ZiXZ07D2P
8P6ZXR3ZyDchuT6oUBXz5WtHUWOzXRJgPbXnFhrkIU8PkZYiPs/4Bw==
-----END RSA PRIVATE KEY-----
+234
View File
@@ -0,0 +1,234 @@
import {
convertCertificatePEMToCertificate,
convertPrivateKeyPEMToPrivateKey,
signStringRSASHA256AndVerify,
validateSelfSignedCertificate,
} from '@expo/code-signing-certificates';
import { ExpoConfig } from '@expo/config';
import Dicer from 'dicer';
import isDeepEqual from 'fast-deep-equal';
import { promises as fs } from 'fs';
import { pki as PKI } from 'node-forge';
import nullthrows from 'nullthrows';
import path from 'path';
import { Stream } from 'stream';
import { parseItem } from 'structured-headers';
import { Response } from '../fetch';
import { PartialManifest, PartialManifestAsset } from '../graphql/generated';
type CodeSigningInfo = {
privateKey: PKI.rsa.PrivateKey;
certificate: PKI.Certificate;
codeSigningMetadata: { alg: string; keyid: string };
};
export async function getCodeSigningInfoAsync(
config: ExpoConfig,
privateKeyPath: string | undefined
): Promise<CodeSigningInfo | undefined> {
const codeSigningCertificatePath = config.updates?.codeSigningCertificate;
if (!codeSigningCertificatePath) {
return undefined;
}
if (!privateKeyPath) {
privateKeyPath = path.join(path.dirname(codeSigningCertificatePath), 'private-key.pem');
}
const codeSigningMetadata = config.updates?.codeSigningMetadata;
if (!codeSigningMetadata) {
throw new Error(
'Must specify codeSigningMetadata under the "updates" field of your app config file to use EAS code signing'
);
}
const { alg, keyid } = codeSigningMetadata;
if (!alg || !keyid) {
throw new Error(
'Must specify keyid and alg in the codeSigningMetadata field under the "updates" field of your app config file to use EAS code signing'
);
}
return codeSigningCertificatePath && privateKeyPath
? {
...(await getKeyAndCertificateFromPathsAsync({
codeSigningCertificatePath,
privateKeyPath,
})),
codeSigningMetadata: {
alg,
keyid,
},
}
: undefined;
}
async function readFileAsync(path: string, errorMessage: string): Promise<string> {
try {
return await fs.readFile(path, 'utf8');
} catch {
throw new Error(errorMessage);
}
}
export async function getKeyAndCertificateFromPathsAsync({
codeSigningCertificatePath,
privateKeyPath,
}: {
codeSigningCertificatePath: string;
privateKeyPath: string;
}): Promise<{ privateKey: PKI.rsa.PrivateKey; certificate: PKI.Certificate }> {
const [codeSigningCertificatePEM, privateKeyPEM] = await Promise.all([
readFileAsync(
codeSigningCertificatePath,
`Code signing certificate cannot be read from path: ${codeSigningCertificatePath}`
),
readFileAsync(
privateKeyPath,
`Code signing private key cannot be read from path: ${privateKeyPath}`
),
]);
const privateKey = convertPrivateKeyPEMToPrivateKey(privateKeyPEM);
const certificate = convertCertificatePEMToCertificate(codeSigningCertificatePEM);
validateSelfSignedCertificate(certificate, {
publicKey: certificate.publicKey as PKI.rsa.PublicKey,
privateKey,
});
return {
privateKey,
certificate,
};
}
export type MultipartPart = { headers: Map<string, string>; body: string };
export async function parseMultipartMixedResponseAsync(res: Response): Promise<MultipartPart[]> {
const contentType = res.headers.get('content-type');
if (!contentType) {
throw new Error('The multipart manifest response is missing the content-type header');
}
const boundaryRegex = /^multipart\/.+?; boundary=(?:"([^"]+)"|([^\s;]+))/i;
const matches = boundaryRegex.exec(contentType);
if (!matches) {
throw new Error('The content-type header in the HTTP response is not a multipart media type');
}
const boundary = matches[1] ?? matches[2];
const bodyBuffer = await res.arrayBuffer();
const bufferStream = new Stream.PassThrough();
bufferStream.end(bodyBuffer);
return await new Promise((resolve, reject) => {
const parts: MultipartPart[] = [];
bufferStream.pipe(
new Dicer({ boundary })
.on('part', p => {
const part: MultipartPart = {
body: '',
headers: new Map(),
};
p.on('header', headers => {
for (const h in headers) {
part.headers.set(h, (headers as { [key: string]: string[] })[h][0]);
}
});
p.on('data', data => {
part.body += data.toString();
});
p.on('end', () => {
parts.push(part);
});
})
.on('finish', () => {
resolve(parts);
})
.on('error', error => {
reject(error);
})
);
});
}
function isManifestMultipartPart(multipartPart: MultipartPart): boolean {
const [, parameters] = parseItem(nullthrows(multipartPart.headers.get('content-disposition')));
const partName = parameters.get('name');
return partName === 'manifest';
}
export async function getManifestBodyAsync(res: Response): Promise<string | null> {
const multipartParts = await parseMultipartMixedResponseAsync(res);
const manifestPart = multipartParts.find(isManifestMultipartPart);
return manifestPart?.body ?? null;
}
export function signManifestBody(body: string, codeSigningInfo: CodeSigningInfo): string {
return signStringRSASHA256AndVerify(
codeSigningInfo.privateKey,
codeSigningInfo.certificate,
body
);
}
function assertAssetParity(
manifestResponseBodyAssetJSON: { [key: string]: any },
partialManifestAsset: PartialManifestAsset
): void {
const baseErrorMessage = `Code signing manifest integrity error: Manifest asset tamper detected for asset: ${partialManifestAsset.bundleKey}; field: `;
if (manifestResponseBodyAssetJSON.hash !== partialManifestAsset.fileSHA256) {
throw new Error(baseErrorMessage + 'hash');
}
if (manifestResponseBodyAssetJSON.contentType !== partialManifestAsset.contentType) {
throw new Error(baseErrorMessage + 'contentType');
}
if (manifestResponseBodyAssetJSON.key !== partialManifestAsset.bundleKey) {
throw new Error(baseErrorMessage + 'key');
}
}
export function checkManifestBodyAgainstUpdateInfoGroup(
manifestResponseBody: string,
partialManifest: PartialManifest
): void {
const manifestResponseBodyJSON = JSON.parse(manifestResponseBody);
// Assert expoClient config is equal. We do not want to sign the manifest if the
// server has compromised the integrity of the manifest.
// JSON stringify and unstringify to remove any undefined values and bring it as close
// to the server sanitized value as possible
const isExtraEqual = isDeepEqual(
JSON.parse(JSON.stringify(partialManifest.extra?.expoClient)),
manifestResponseBodyJSON.extra?.expoClient
);
if (!isExtraEqual) {
throw new Error(
`Code signing manifest integrity error: The manifest being signed contains an extra.expoClient field that does not match the initially uploaded manifest's extra.expoClient field`
);
}
assertAssetParity(manifestResponseBodyJSON.launchAsset, partialManifest.launchAsset);
if (manifestResponseBodyJSON.assets.length !== partialManifest.assets.length) {
throw new Error(
'Code signing manifest integrity error: The manifest being signed has an assets array of differing length from the initially uploaded manifest'
);
}
for (const partialManifestAsset of partialManifest.assets) {
const partialManifestAssetBundleKey = nullthrows(partialManifestAsset).bundleKey;
const correspondingManifestResponseBodyAssetJSON = manifestResponseBodyJSON.assets.find(
(manifestResponseBodyAssetJSON: { [key: string]: any }) =>
manifestResponseBodyAssetJSON.key === partialManifestAssetBundleKey
);
if (!correspondingManifestResponseBodyAssetJSON) {
throw new Error(
`Code signing manifest integrity error: The manifest being signed has is missing an asset specified in the initially uploaded manifest: ${partialManifestAssetBundleKey}`
);
}
assertAssetParity(correspondingManifestResponseBodyAssetJSON, nullthrows(partialManifestAsset));
}
}
+7 -2
View File
@@ -1,10 +1,15 @@
import chalk from 'chalk';
import { Progress } from 'got';
import { Ora, ora } from '../ora';
import { endTimer, formatMilliseconds, startTimer } from './timer';
type ProgressHandler = (props: {
export type Progress = {
total: number;
percent: number;
transferred: number;
};
export type ProgressHandler = (props: {
progress?: Progress;
isComplete?: boolean;
error?: Error;
+2
View File
@@ -5,6 +5,8 @@
"module": "commonjs",
"esModuleInterop": true,
"noImplicitReturns": true,
"noUnusedParameters":true,
"noUnusedLocals":true,
"strict": true,
"target": "ES2019",
"outDir": "build",
+5 -5
View File
@@ -1,16 +1,16 @@
{
"name": "@expo/eas-json",
"description": "A library for interacting with eas.json",
"version": "0.45.1",
"version": "0.48.0",
"author": "Expo <[email protected]>",
"bugs": "https://github.com/expo/eas-cli/issues",
"dependencies": {
"@expo/eas-build-job": "0.2.64",
"@expo/eas-build-job": "0.2.66",
"@expo/json-file": "8.2.34",
"chalk": "4.1.2",
"env-string": "1.0.1",
"fs-extra": "10.0.0",
"joi": "17.5.0",
"fs-extra": "10.0.1",
"joi": "17.6.0",
"log-symbols": "4.1.0",
"semver": "7.3.5",
"tslib": "2.3.1"
@@ -18,7 +18,7 @@
"devDependencies": {
"@types/fs-extra": "9.0.13",
"memfs": "3.4.1",
"typescript": "4.5.4"
"typescript": "4.6.2"
},
"engines": {
"node": ">=12.0.0"
Generated
+1504 -2501
View File
File diff suppressed because it is too large. Load diff