@hot-updater/android-helper 1.2.0-rc.4 → 1.2.0-rc.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -54,6 +54,16 @@ declare const findPlayInternalRelease: ({ versionCode, packageName, serviceAccou
54
54
  serviceAccount: Credentials["play-service-account"];
55
55
  fetch?: typeof globalThis.fetch;
56
56
  }) => Promise<boolean>;
57
+ /**
58
+ * Whether Google Play releases any version of `packageName` on any track,
59
+ * which means Play has the app's upload key. It reads the tracks in an edit
60
+ * it then deletes, changing nothing.
61
+ */
62
+ declare const hasPlayReleases: ({ packageName, serviceAccount: { json }, fetch }: {
63
+ packageName: string;
64
+ serviceAccount: Credentials["play-service-account"];
65
+ fetch?: typeof globalThis.fetch;
66
+ }) => Promise<boolean>;
57
67
  /**
58
68
  * Throws when the `.aab` is signed with the Android debug keystore, which
59
69
  * Google Play refuses: a release build type left on `signingConfigs.debug`,
@@ -146,28 +156,22 @@ declare const readBuiltVersionCode: ({ artifactPath, androidProjectPath }: {
146
156
  //#region src/google/types.d.ts
147
157
  /** What stopped Hot Updater from issuing the Play service account key. */
148
158
  type PlayServiceAccountErrorCode =
149
- /** No OAuth client to sign in with, or Google refused it. */
150
- "sign-in-not-configured" |
151
- /** The browser sign-in was cancelled, refused, or timed out. */
152
- "sign-in-cancelled" |
153
- /** The account unticked a scope the setup needs on Google's consent screen. */
154
- "scope-not-granted" |
155
- /** The developer account ID names no Play Console account. */
156
- "developer-not-found" |
157
- /** The Google Account is no admin of the Play Console developer account. */
158
- "not-play-admin" |
159
- /** Google Play has no app with the package name in the developer account. */
160
- "app-not-found" |
159
+ /** The gcloud CLI, which signs in to Google, is not installed. */
160
+ "gcloud-not-installed" |
161
+ /** `gcloud auth login` ended with no active Google Account. */
162
+ "gcloud-not-signed-in" |
161
163
  /** The Google Account may not create a Google Cloud project. */
162
164
  "project-create-denied" |
163
165
  /** The Google Account has no Google Cloud project quota left. */
164
166
  "project-quota" |
165
167
  /** The Google Account may not enable APIs or create service accounts in the project. */
166
168
  "project-access-denied" |
167
- /** Google is still enabling an API, or it is disabled in the OAuth client's project. */
169
+ /** Google is still enabling an API, or it is disabled in another project. */
168
170
  "api-not-enabled" |
169
171
  /** An organization policy (`iam.disableServiceAccountKeyCreation`) forbids keys. */
170
- "key-creation-disabled";
172
+ "key-creation-disabled" |
173
+ /** The key never reached the app: the Play Console invite, or the app's first upload, is missing. */
174
+ "play-access-pending";
171
175
  /** A named failure of `issuePlayServiceAccount`, with what to do in its message. */
172
176
  declare class PlayServiceAccountError extends Error {
173
177
  readonly code: PlayServiceAccountErrorCode;
@@ -175,57 +179,42 @@ declare class PlayServiceAccountError extends Error {
175
179
  cause?: unknown;
176
180
  });
177
181
  }
178
- /**
179
- * A Google OAuth client of type "Desktop app". Google treats an installed
180
- * app's client secret as public, so it ships with the client ID.
181
- */
182
- interface GoogleOAuthClient {
183
- readonly clientId: string;
184
- readonly clientSecret?: string;
185
- }
186
- /** The environment variables that replace Hot Updater's Google OAuth client. */
187
- declare const GOOGLE_OAUTH_CLIENT_ENV_NAMES: {
188
- readonly clientId: "HOT_UPDATER_GOOGLE_OAUTH_CLIENT_ID";
189
- readonly clientSecret: "HOT_UPDATER_GOOGLE_OAUTH_CLIENT_SECRET";
190
- };
191
182
  /** The service account Hot Updater creates, `hot-updater-play@<project>.iam.gserviceaccount.com`. */
192
183
  declare const PLAY_SERVICE_ACCOUNT_ID = "hot-updater-play";
193
- /** Where a Play Console admin finds the developer account ID. */
194
- declare const PLAY_CONSOLE_URL = "https://play.google.com/console";
195
184
  //#endregion
196
185
  //#region src/playServiceAccount.d.ts
197
- /**
198
- * Hot Updater's Google OAuth client, a "Desktop app" client the sign-in
199
- * opens Google's consent screen for. Empty in a build that has none, where
200
- * `HOT_UPDATER_GOOGLE_OAUTH_CLIENT_ID` and `_SECRET` name one.
201
- */
202
- declare const HOT_UPDATER_GOOGLE_OAUTH_CLIENT: GoogleOAuthClient;
203
186
  /** A Google Cloud project the signed-in account can use. */
204
187
  interface GoogleCloudProject {
205
188
  readonly projectId: string;
206
189
  readonly displayName?: string;
190
+ /** Whether the Google Play Android Developer API is enabled in it. */
191
+ readonly playApiEnabled: boolean;
207
192
  }
208
193
  interface IssuePlayServiceAccountRequest {
209
- /** The app's package name in Google Play, which the service account may release. */
210
- readonly packageName: string;
211
- /** The OAuth client to sign in with; Hot Updater's unless set. */
212
- readonly oauthClient?: GoogleOAuthClient;
213
- /** Sees the sign-in URL, to print it and open it in a browser. */
214
- readonly onSignInUrl: (url: string) => Promise<void> | void;
215
- /** Asks for the Play Console developer account ID, after the sign-in. */
216
- readonly askDeveloperId: () => Promise<string>;
217
194
  /**
218
- * Sees the account's projects when there are any, and returns the one to
219
- * create the service account in, or undefined to create a project.
195
+ * Asks for the app's package name in Google Play, which the service
196
+ * account may release: after the sign-in's own tool is found, before
197
+ * anything else.
198
+ */
199
+ readonly askPackageName: () => Promise<string>;
200
+ /**
201
+ * Sees Play Console's page that invites the service account `email`, to
202
+ * print it and open it in a browser; the issuer then waits for the invite.
203
+ */
204
+ readonly onInvite: (url: string, email: string) => Promise<void> | void;
205
+ /**
206
+ * Sees the account's projects when no one of them is the obvious home of
207
+ * the service account, the only one with the Google Play Developer API,
208
+ * and returns the project ID to create it in, or null for a new project.
209
+ * Never called for an account without projects: a new one is created.
220
210
  */
221
- readonly chooseProject: (projects: readonly GoogleCloudProject[]) => Promise<string | undefined>;
211
+ readonly chooseProject: (projects: readonly GoogleCloudProject[]) => Promise<string | null>;
222
212
  /** Reports each step, such as "Creating the service account". */
223
213
  readonly onStep?: (message: string) => void;
224
214
  }
225
215
  /**
226
- * A Play service account's JSON key, just created, with the access token
227
- * of the sign-in it was created in. `revoke` deletes the key while the
228
- * sign-in lasts, and `dispose` ends the sign-in.
216
+ * A Play service account's JSON key, just created, which already reaches
217
+ * the app in Google Play. `revoke` deletes the key with gcloud's sign-in.
229
218
  */
230
219
  interface IssuedPlayServiceAccount {
231
220
  /** The JSON key file, as Google Cloud downloads it. */
@@ -233,27 +222,25 @@ interface IssuedPlayServiceAccount {
233
222
  /** The service account's email, the Play Console user it releases as. */
234
223
  readonly email: string;
235
224
  readonly projectId: string;
236
- readonly developerId: string;
237
225
  /** The key's ID, as Google Cloud lists it under the service account's keys. */
238
226
  readonly keyId: string;
239
- /** Deletes the key with the same sign-in; whether Google Cloud did. */
227
+ /** Deletes the key with gcloud's sign-in; whether Google Cloud did. */
240
228
  revoke(): Promise<boolean>;
241
- /** Ends the sign-in: Google revokes its access token. */
229
+ /** Releases what the issue held; gcloud keeps its own sign-in. */
242
230
  dispose(): Promise<void>;
243
231
  }
244
232
  /**
245
- * Signs in with Google and issues a service account key that releases the
246
- * app to Google Play: the developer signs in on Google's own consent
247
- * screen, in a browser, and the caller never sees the password. Nothing of
248
- * the sign-in outlives `dispose`.
233
+ * Issues a service account key that releases the app to Google Play, with
234
+ * the gcloud CLI's Google sign-in: the caller never sees the password, and
235
+ * the developer invites the service account in Play Console once.
249
236
  */
250
237
  type IssuePlayServiceAccount = (request: IssuePlayServiceAccountRequest) => Promise<IssuedPlayServiceAccount>;
251
238
  /**
252
- * Hot Updater's issuer, the one place that picks how it is done: Google's
253
- * OAuth for installed apps, then the Cloud Resource Manager, Service Usage,
254
- * IAM, and Play Developer APIs. Another implementation of
255
- * `IssuePlayServiceAccount` replaces it here without touching its callers.
239
+ * Hot Updater's issuer, the one place that picks how it is done: gcloud's
240
+ * sign-in, then the Cloud Resource Manager, Service Usage, IAM, and Play
241
+ * Developer APIs. Another implementation of `IssuePlayServiceAccount`
242
+ * replaces it here without touching its callers.
256
243
  */
257
244
  declare const issuePlayServiceAccount: IssuePlayServiceAccount;
258
245
  //#endregion
259
- export { type EnrichedNativeBuildAndroidScheme, GOOGLE_OAUTH_CLIENT_ENV_NAMES, type GoogleCloudProject, type GoogleOAuthClient, HOT_UPDATER_GOOGLE_OAUTH_CLIENT, type IssuePlayServiceAccount, type IssuePlayServiceAccountRequest, type IssuedPlayServiceAccount, PLAY_CONSOLE_URL, PLAY_SERVICE_ACCOUNT_ID, PlayServiceAccountError, type PlayServiceAccountErrorCode, PlayVersionCodeUsedError, type UploadToPlayResult, assertPlaySigned, buildAndroid, enrichNativeBuildAndroidScheme, extractBuiltInBundle, findPlayInternalRelease, issuePlayServiceAccount, readBuiltApp, readBuiltPackageName, readBuiltVersionCode, resolvePlayUploadServiceAccount, uploadToPlay };
246
+ export { type EnrichedNativeBuildAndroidScheme, type GoogleCloudProject, type IssuePlayServiceAccount, type IssuePlayServiceAccountRequest, type IssuedPlayServiceAccount, PLAY_SERVICE_ACCOUNT_ID, PlayServiceAccountError, type PlayServiceAccountErrorCode, PlayVersionCodeUsedError, type UploadToPlayResult, assertPlaySigned, buildAndroid, enrichNativeBuildAndroidScheme, extractBuiltInBundle, findPlayInternalRelease, hasPlayReleases, issuePlayServiceAccount, readBuiltApp, readBuiltPackageName, readBuiltVersionCode, resolvePlayUploadServiceAccount, uploadToPlay };
package/dist/index.d.mts CHANGED
@@ -55,6 +55,16 @@ declare const findPlayInternalRelease: ({ versionCode, packageName, serviceAccou
55
55
  serviceAccount: Credentials["play-service-account"];
56
56
  fetch?: typeof globalThis.fetch;
57
57
  }) => Promise<boolean>;
58
+ /**
59
+ * Whether Google Play releases any version of `packageName` on any track,
60
+ * which means Play has the app's upload key. It reads the tracks in an edit
61
+ * it then deletes, changing nothing.
62
+ */
63
+ declare const hasPlayReleases: ({ packageName, serviceAccount: { json }, fetch }: {
64
+ packageName: string;
65
+ serviceAccount: Credentials["play-service-account"];
66
+ fetch?: typeof globalThis.fetch;
67
+ }) => Promise<boolean>;
58
68
  /**
59
69
  * Throws when the `.aab` is signed with the Android debug keystore, which
60
70
  * Google Play refuses: a release build type left on `signingConfigs.debug`,
@@ -147,28 +157,22 @@ declare const readBuiltVersionCode: ({ artifactPath, androidProjectPath }: {
147
157
  //#region src/google/types.d.ts
148
158
  /** What stopped Hot Updater from issuing the Play service account key. */
149
159
  type PlayServiceAccountErrorCode =
150
- /** No OAuth client to sign in with, or Google refused it. */
151
- "sign-in-not-configured" |
152
- /** The browser sign-in was cancelled, refused, or timed out. */
153
- "sign-in-cancelled" |
154
- /** The account unticked a scope the setup needs on Google's consent screen. */
155
- "scope-not-granted" |
156
- /** The developer account ID names no Play Console account. */
157
- "developer-not-found" |
158
- /** The Google Account is no admin of the Play Console developer account. */
159
- "not-play-admin" |
160
- /** Google Play has no app with the package name in the developer account. */
161
- "app-not-found" |
160
+ /** The gcloud CLI, which signs in to Google, is not installed. */
161
+ "gcloud-not-installed" |
162
+ /** `gcloud auth login` ended with no active Google Account. */
163
+ "gcloud-not-signed-in" |
162
164
  /** The Google Account may not create a Google Cloud project. */
163
165
  "project-create-denied" |
164
166
  /** The Google Account has no Google Cloud project quota left. */
165
167
  "project-quota" |
166
168
  /** The Google Account may not enable APIs or create service accounts in the project. */
167
169
  "project-access-denied" |
168
- /** Google is still enabling an API, or it is disabled in the OAuth client's project. */
170
+ /** Google is still enabling an API, or it is disabled in another project. */
169
171
  "api-not-enabled" |
170
172
  /** An organization policy (`iam.disableServiceAccountKeyCreation`) forbids keys. */
171
- "key-creation-disabled";
173
+ "key-creation-disabled" |
174
+ /** The key never reached the app: the Play Console invite, or the app's first upload, is missing. */
175
+ "play-access-pending";
172
176
  /** A named failure of `issuePlayServiceAccount`, with what to do in its message. */
173
177
  declare class PlayServiceAccountError extends Error {
174
178
  readonly code: PlayServiceAccountErrorCode;
@@ -176,57 +180,42 @@ declare class PlayServiceAccountError extends Error {
176
180
  cause?: unknown;
177
181
  });
178
182
  }
179
- /**
180
- * A Google OAuth client of type "Desktop app". Google treats an installed
181
- * app's client secret as public, so it ships with the client ID.
182
- */
183
- interface GoogleOAuthClient {
184
- readonly clientId: string;
185
- readonly clientSecret?: string;
186
- }
187
- /** The environment variables that replace Hot Updater's Google OAuth client. */
188
- declare const GOOGLE_OAUTH_CLIENT_ENV_NAMES: {
189
- readonly clientId: "HOT_UPDATER_GOOGLE_OAUTH_CLIENT_ID";
190
- readonly clientSecret: "HOT_UPDATER_GOOGLE_OAUTH_CLIENT_SECRET";
191
- };
192
183
  /** The service account Hot Updater creates, `hot-updater-play@<project>.iam.gserviceaccount.com`. */
193
184
  declare const PLAY_SERVICE_ACCOUNT_ID = "hot-updater-play";
194
- /** Where a Play Console admin finds the developer account ID. */
195
- declare const PLAY_CONSOLE_URL = "https://play.google.com/console";
196
185
  //#endregion
197
186
  //#region src/playServiceAccount.d.ts
198
- /**
199
- * Hot Updater's Google OAuth client, a "Desktop app" client the sign-in
200
- * opens Google's consent screen for. Empty in a build that has none, where
201
- * `HOT_UPDATER_GOOGLE_OAUTH_CLIENT_ID` and `_SECRET` name one.
202
- */
203
- declare const HOT_UPDATER_GOOGLE_OAUTH_CLIENT: GoogleOAuthClient;
204
187
  /** A Google Cloud project the signed-in account can use. */
205
188
  interface GoogleCloudProject {
206
189
  readonly projectId: string;
207
190
  readonly displayName?: string;
191
+ /** Whether the Google Play Android Developer API is enabled in it. */
192
+ readonly playApiEnabled: boolean;
208
193
  }
209
194
  interface IssuePlayServiceAccountRequest {
210
- /** The app's package name in Google Play, which the service account may release. */
211
- readonly packageName: string;
212
- /** The OAuth client to sign in with; Hot Updater's unless set. */
213
- readonly oauthClient?: GoogleOAuthClient;
214
- /** Sees the sign-in URL, to print it and open it in a browser. */
215
- readonly onSignInUrl: (url: string) => Promise<void> | void;
216
- /** Asks for the Play Console developer account ID, after the sign-in. */
217
- readonly askDeveloperId: () => Promise<string>;
218
195
  /**
219
- * Sees the account's projects when there are any, and returns the one to
220
- * create the service account in, or undefined to create a project.
196
+ * Asks for the app's package name in Google Play, which the service
197
+ * account may release: after the sign-in's own tool is found, before
198
+ * anything else.
199
+ */
200
+ readonly askPackageName: () => Promise<string>;
201
+ /**
202
+ * Sees Play Console's page that invites the service account `email`, to
203
+ * print it and open it in a browser; the issuer then waits for the invite.
204
+ */
205
+ readonly onInvite: (url: string, email: string) => Promise<void> | void;
206
+ /**
207
+ * Sees the account's projects when no one of them is the obvious home of
208
+ * the service account, the only one with the Google Play Developer API,
209
+ * and returns the project ID to create it in, or null for a new project.
210
+ * Never called for an account without projects: a new one is created.
221
211
  */
222
- readonly chooseProject: (projects: readonly GoogleCloudProject[]) => Promise<string | undefined>;
212
+ readonly chooseProject: (projects: readonly GoogleCloudProject[]) => Promise<string | null>;
223
213
  /** Reports each step, such as "Creating the service account". */
224
214
  readonly onStep?: (message: string) => void;
225
215
  }
226
216
  /**
227
- * A Play service account's JSON key, just created, with the access token
228
- * of the sign-in it was created in. `revoke` deletes the key while the
229
- * sign-in lasts, and `dispose` ends the sign-in.
217
+ * A Play service account's JSON key, just created, which already reaches
218
+ * the app in Google Play. `revoke` deletes the key with gcloud's sign-in.
230
219
  */
231
220
  interface IssuedPlayServiceAccount {
232
221
  /** The JSON key file, as Google Cloud downloads it. */
@@ -234,27 +223,25 @@ interface IssuedPlayServiceAccount {
234
223
  /** The service account's email, the Play Console user it releases as. */
235
224
  readonly email: string;
236
225
  readonly projectId: string;
237
- readonly developerId: string;
238
226
  /** The key's ID, as Google Cloud lists it under the service account's keys. */
239
227
  readonly keyId: string;
240
- /** Deletes the key with the same sign-in; whether Google Cloud did. */
228
+ /** Deletes the key with gcloud's sign-in; whether Google Cloud did. */
241
229
  revoke(): Promise<boolean>;
242
- /** Ends the sign-in: Google revokes its access token. */
230
+ /** Releases what the issue held; gcloud keeps its own sign-in. */
243
231
  dispose(): Promise<void>;
244
232
  }
245
233
  /**
246
- * Signs in with Google and issues a service account key that releases the
247
- * app to Google Play: the developer signs in on Google's own consent
248
- * screen, in a browser, and the caller never sees the password. Nothing of
249
- * the sign-in outlives `dispose`.
234
+ * Issues a service account key that releases the app to Google Play, with
235
+ * the gcloud CLI's Google sign-in: the caller never sees the password, and
236
+ * the developer invites the service account in Play Console once.
250
237
  */
251
238
  type IssuePlayServiceAccount = (request: IssuePlayServiceAccountRequest) => Promise<IssuedPlayServiceAccount>;
252
239
  /**
253
- * Hot Updater's issuer, the one place that picks how it is done: Google's
254
- * OAuth for installed apps, then the Cloud Resource Manager, Service Usage,
255
- * IAM, and Play Developer APIs. Another implementation of
256
- * `IssuePlayServiceAccount` replaces it here without touching its callers.
240
+ * Hot Updater's issuer, the one place that picks how it is done: gcloud's
241
+ * sign-in, then the Cloud Resource Manager, Service Usage, IAM, and Play
242
+ * Developer APIs. Another implementation of `IssuePlayServiceAccount`
243
+ * replaces it here without touching its callers.
257
244
  */
258
245
  declare const issuePlayServiceAccount: IssuePlayServiceAccount;
259
246
  //#endregion
260
- export { type EnrichedNativeBuildAndroidScheme, GOOGLE_OAUTH_CLIENT_ENV_NAMES, type GoogleCloudProject, type GoogleOAuthClient, HOT_UPDATER_GOOGLE_OAUTH_CLIENT, type IssuePlayServiceAccount, type IssuePlayServiceAccountRequest, type IssuedPlayServiceAccount, PLAY_CONSOLE_URL, PLAY_SERVICE_ACCOUNT_ID, PlayServiceAccountError, type PlayServiceAccountErrorCode, PlayVersionCodeUsedError, type UploadToPlayResult, assertPlaySigned, buildAndroid, enrichNativeBuildAndroidScheme, extractBuiltInBundle, findPlayInternalRelease, issuePlayServiceAccount, readBuiltApp, readBuiltPackageName, readBuiltVersionCode, resolvePlayUploadServiceAccount, uploadToPlay };
247
+ export { type EnrichedNativeBuildAndroidScheme, type GoogleCloudProject, type IssuePlayServiceAccount, type IssuePlayServiceAccountRequest, type IssuedPlayServiceAccount, PLAY_SERVICE_ACCOUNT_ID, PlayServiceAccountError, type PlayServiceAccountErrorCode, PlayVersionCodeUsedError, type UploadToPlayResult, assertPlaySigned, buildAndroid, enrichNativeBuildAndroidScheme, extractBuiltInBundle, findPlayInternalRelease, hasPlayReleases, issuePlayServiceAccount, readBuiltApp, readBuiltPackageName, readBuiltVersionCode, resolvePlayUploadServiceAccount, uploadToPlay };