chrome-webstore-upload 3.1.3 → 3.2.0

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.
Files changed (3) hide show
  1. package/index.d.ts +20 -4
  2. package/index.js +15 -3
  3. package/package.json +2 -5
package/index.d.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import { type ReadStream } from 'node:fs';
2
- import { type JsonObject } from 'type-fest';
3
2
  export declare const refreshTokenURI = "https://www.googleapis.com/oauth2/v4/token";
4
3
  export type APIClientOptions = {
5
4
  extensionId: string;
@@ -7,16 +6,33 @@ export type APIClientOptions = {
7
6
  refreshToken: string;
8
7
  clientSecret: string | undefined;
9
8
  };
9
+ export type ItemResource = {
10
+ kind: 'chromewebstore#item';
11
+ id: string;
12
+ publicKey: string;
13
+ uploadState: 'FAILURE' | 'IN_PROGRESS' | 'NOT_FOUND' | 'SUCCESS';
14
+ itemError: Array<{
15
+ error_code: string;
16
+ error_detail: string;
17
+ }>;
18
+ };
19
+ export type PublishResponse = {
20
+ kind: 'chromewebstore#item';
21
+ item_id: string;
22
+ status: Array<'OK' | 'NOT_AUTHORIZED' | 'INVALID_DEVELOPER' | 'DEVELOPER_NO_OWNERSHIP' | 'DEVELOPER_SUSPENDED' | 'ITEM_NOT_FOUND' | 'ITEM_PENDING_REVIEW' | 'ITEM_TAKEN_DOWN' | 'PUBLISHER_SUSPENDED'>;
23
+ statusDetail: string[];
24
+ };
10
25
  declare class APIClient {
11
26
  extensionId: string;
12
27
  clientId: string;
13
28
  refreshToken: string;
14
29
  clientSecret: string | undefined;
15
30
  constructor(options: APIClientOptions);
16
- uploadExisting(readStream: ReadStream | ReadableStream, token?: Promise<string>): Promise<JsonObject>;
17
- publish(target?: string, token?: Promise<string>, deployPercentage?: number | undefined): Promise<JsonObject>;
18
- get(projection?: string, token?: Promise<string>): Promise<JsonObject>;
31
+ uploadExisting(readStream: ReadStream | ReadableStream, token?: string | Promise<string>, maxAwaitInProgressResponseSeconds?: number): Promise<ItemResource>;
32
+ publish(target?: string, token?: string | Promise<string>, deployPercentage?: number | undefined): Promise<PublishResponse>;
33
+ get(projection?: string, token?: string | Promise<string>): Promise<ItemResource>;
19
34
  fetchToken(): Promise<string>;
35
+ _waitUploadSuccess(response: ItemResource, maxAwaitInProgressResponseSeconds: number): Promise<ItemResource>;
20
36
  _headers(token: string): {
21
37
  Authorization: string;
22
38
  'x-goog-api-version': string;
package/index.js CHANGED
@@ -14,6 +14,7 @@ const publishURI = ({ extensionId, target = 'default', deployPercentage }) => {
14
14
  };
15
15
  const getURI = (id, projection) => `${rootURI}/chromewebstore/v1.1/items/${id}?projection=${projection}`;
16
16
  const requiredFields = ['extensionId', 'clientId', 'refreshToken'];
17
+ const retryIntervalSeconds = 2;
17
18
  function throwIfNotOk(request, response) {
18
19
  if (!request.ok) {
19
20
  const error = new Error(request.statusText ?? 'Unknown error');
@@ -43,7 +44,7 @@ class APIClient {
43
44
  this.refreshToken = options.refreshToken;
44
45
  this.clientSecret = options.clientSecret;
45
46
  }
46
- async uploadExisting(readStream, token = this.fetchToken()) {
47
+ async uploadExisting(readStream, token = this.fetchToken(), maxAwaitInProgressResponseSeconds = 0) {
47
48
  if (!readStream) {
48
49
  throw new Error('Read stream missing');
49
50
  }
@@ -58,7 +59,7 @@ class APIClient {
58
59
  });
59
60
  const response = await request.json();
60
61
  throwIfNotOk(request, response);
61
- return response;
62
+ return this._waitUploadSuccess(response, maxAwaitInProgressResponseSeconds);
62
63
  }
63
64
  async publish(target = 'default', token = this.fetchToken(), deployPercentage = undefined) {
64
65
  const { extensionId } = this;
@@ -100,7 +101,18 @@ class APIClient {
100
101
  });
101
102
  const response = await request.json();
102
103
  throwIfNotOk(request, response);
103
- return response['access_token'];
104
+ return response.access_token;
105
+ }
106
+ async _waitUploadSuccess(response, maxAwaitInProgressResponseSeconds) {
107
+ if (response.uploadState !== 'IN_PROGRESS' || maxAwaitInProgressResponseSeconds < retryIntervalSeconds) {
108
+ return response;
109
+ }
110
+ // Wait before checking again
111
+ await new Promise(resolve => {
112
+ setTimeout(resolve, retryIntervalSeconds * 1000);
113
+ });
114
+ // Retry fetching the item resource
115
+ return this._waitUploadSuccess(await this.get('DRAFT'), maxAwaitInProgressResponseSeconds - retryIntervalSeconds);
104
116
  }
105
117
  _headers(token) {
106
118
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "chrome-webstore-upload",
3
- "version": "3.1.3",
3
+ "version": "3.2.0",
4
4
  "description": "Upload Chrome Extensions to the Chrome Web Store",
5
5
  "keywords": [
6
6
  "chrome",
@@ -61,9 +61,6 @@
61
61
  ],
62
62
  "space": 4
63
63
  },
64
- "dependencies": {
65
- "type-fest": "^4.26.1"
66
- },
67
64
  "devDependencies": {
68
65
  "@sindresorhus/tsconfig": "^5.0.0",
69
66
  "dot-json": "^1.3.0",
@@ -71,7 +68,7 @@
71
68
  "node-fetch": "^2.7.0",
72
69
  "typescript": "^5.3.3",
73
70
  "utc-version": "^2.0.2",
74
- "vitest": "^1.6.0",
71
+ "vitest": "^3.2.4",
75
72
  "xo": "^0.58.0"
76
73
  },
77
74
  "engines": {