chrome-webstore-upload 0.5.0 → 1.0.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.
package/index.js CHANGED
@@ -1,17 +1,15 @@
1
- const got = require('got');
1
+ import got from 'got';
2
2
 
3
3
  const rootURI = 'https://www.googleapis.com';
4
4
  const refreshTokenURI = 'https://www.googleapis.com/oauth2/v4/token';
5
- const uploadExistingURI = id => `${rootURI}/upload/chromewebstore/v1.1/items/${id}`;
6
- const publishURI = (id, target) => (
7
- `${rootURI}/chromewebstore/v1.1/items/${id}/publish?publishTarget=${target}`
8
- );
5
+ const uploadExistingURI = id =>
6
+ `${rootURI}/upload/chromewebstore/v1.1/items/${id}`;
7
+ const publishURI = (id, target) =>
8
+ `${rootURI}/chromewebstore/v1.1/items/${id}/publish?publishTarget=${target}`;
9
+ const getURI = (id, projection) =>
10
+ `${rootURI}/chromewebstore/v1.1/items/${id}?projection=${projection}`;
9
11
 
10
- const requiredFields = [
11
- 'extensionId',
12
- 'clientId',
13
- 'refreshToken',
14
- ];
12
+ const requiredFields = ['extensionId', 'clientId', 'refreshToken'];
15
13
 
16
14
  class APIClient {
17
15
  constructor(options) {
@@ -35,18 +33,32 @@ class APIClient {
35
33
 
36
34
  const { extensionId } = this;
37
35
 
38
- return got.put(uploadExistingURI(extensionId), {
39
- headers: this._headers(await token),
40
- body: readStream,
41
- }).json();
36
+ return got
37
+ .put(uploadExistingURI(extensionId), {
38
+ headers: this._headers(await token),
39
+ body: readStream,
40
+ })
41
+ .json();
42
42
  }
43
43
 
44
44
  async publish(target = 'default', token = this.fetchToken()) {
45
45
  const { extensionId } = this;
46
46
 
47
- return got.post(publishURI(extensionId, target), {
48
- headers: this._headers(await token),
49
- }).json();
47
+ return got
48
+ .post(publishURI(extensionId, target), {
49
+ headers: this._headers(await token),
50
+ })
51
+ .json();
52
+ }
53
+
54
+ async get(projection = 'DRAFT', token = this.fetchToken()) {
55
+ const { extensionId } = this;
56
+
57
+ return got
58
+ .get(getURI(extensionId, projection), {
59
+ headers: this._headers(await token),
60
+ })
61
+ .json();
50
62
  }
51
63
 
52
64
  async fetchToken() {
@@ -74,6 +86,6 @@ class APIClient {
74
86
  }
75
87
  }
76
88
 
77
- module.exports = function (...args) {
89
+ export default function chromeWebstoreUpload(...args) {
78
90
  return new APIClient(...args);
79
- };
91
+ }
package/license ADDED
@@ -0,0 +1,10 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) Federico Brigante <me@fregante.com> (https://fregante.com)
4
+ Copyright (c) 2020 Andrew Levine
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
7
+
8
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
9
+
10
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/package.json CHANGED
@@ -1,16 +1,7 @@
1
1
  {
2
2
  "name": "chrome-webstore-upload",
3
- "version": "0.5.0",
4
- "license": "MIT",
5
- "description": "Programatically upload + publish changes to the Chrome Webstore",
6
- "repository": "fregante/chrome-webstore-upload",
7
- "funding": "https://github.com/sponsors/fregante",
8
- "engines": {
9
- "node": ">=12.20"
10
- },
11
- "scripts": {
12
- "test": "xo && ava"
13
- },
3
+ "version": "1.0.0",
4
+ "description": "Upload Chrome Extensions to the Chrome Web Store",
14
5
  "keywords": [
15
6
  "chrome",
16
7
  "publish",
@@ -21,10 +12,31 @@
21
12
  "update",
22
13
  "upload"
23
14
  ],
15
+ "repository": "fregante/chrome-webstore-upload",
16
+ "funding": "https://github.com/sponsors/fregante",
17
+ "license": "MIT",
18
+ "author": "Andrew Levine",
24
19
  "contributors": [
25
- "Andrew Levine",
26
20
  "Federico Brigante <me@fregante.com> (https://fregante.com)"
27
21
  ],
22
+ "type": "module",
23
+ "exports": "./index.js",
24
+ "files": [
25
+ "index.js"
26
+ ],
27
+ "scripts": {
28
+ "test": "xo && ava"
29
+ },
30
+ "xo": {
31
+ "rules": {
32
+ "camelcase": "off",
33
+ "object-curly-spacing": [
34
+ "error",
35
+ "always"
36
+ ]
37
+ },
38
+ "space": 4
39
+ },
28
40
  "dependencies": {
29
41
  "got": "^11.8.2"
30
42
  },
@@ -33,17 +45,7 @@
33
45
  "sinon": "^11.1.2",
34
46
  "xo": "^0.44.0"
35
47
  },
36
- "xo": {
37
- "space": 4,
38
- "rules": {
39
- "camelcase": "off",
40
- "func-names": "off",
41
- "object-curly-spacing": [
42
- "error",
43
- "always"
44
- ],
45
- "unicorn/filename-case": "off",
46
- "unicorn/prefer-module": "off"
47
- }
48
+ "engines": {
49
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
48
50
  }
49
51
  }
@@ -5,6 +5,7 @@
5
5
  If you're looking to upload/publish from the CLI, then use [chrome-webstore-upload-cli](https://github.com/fregante/chrome-webstore-upload-cli).
6
6
 
7
7
  ## Install
8
+
8
9
  ```
9
10
  npm install --save-dev chrome-webstore-upload
10
11
  ```
@@ -20,40 +21,57 @@ Note: If you created the APIs before version 0.5.0 (September 2021), you might h
20
21
  All methods return an ES2015-compliant promise.
21
22
 
22
23
  ### Create a new client
24
+
23
25
  ```javascript
24
- const webStore = require('chrome-webstore-upload')({
25
- extensionId: 'ecnglinljpjkbgmdpeiglonddahpbkeb',
26
- clientId: 'xxxxxxxxxx',
27
- refreshToken: 'xxxxxxxxxx'
26
+ import chromeWebstoreUpload from 'chrome-webstore-upload';
27
+
28
+ const store = chromeWebstoreUpload({
29
+ extensionId: 'ecnglinljpjkbgmdpeiglonddahpbkeb',
30
+ clientId: 'xxxxxxxxxx',
31
+ refreshToken: 'xxxxxxxxxx',
28
32
  });
29
33
  ```
30
34
 
31
35
  ### Upload to existing extension
36
+
32
37
  ```javascript
33
- const fs = require('fs');
38
+ import fs from 'fs';
34
39
 
35
40
  const myZipFile = fs.createReadStream('./mypackage.zip');
36
41
  const token = 'xxxx'; // optional. One will be fetched if not provided
37
- webStore.uploadExisting(myZipFile, token).then(res => {
38
- // Response is a Resource Representation
39
- // https://developer.chrome.com/webstore/webstore_api/items#resource
42
+ store.uploadExisting(myZipFile, token).then(res => {
43
+ // Response is a Resource Representation
44
+ // https://developer.chrome.com/webstore/webstore_api/items#resource
40
45
  });
41
46
  ```
42
47
 
43
48
  ### Publish extension
49
+
44
50
  ```javascript
45
51
  const target = 'default'; // optional. Can also be 'trustedTesters'
46
52
  const token = 'xxxx'; // optional. One will be fetched if not provided
47
- webStore.publish(target, token).then(res => {
48
- // Response is documented here:
49
- // https://developer.chrome.com/webstore/webstore_api/items/publish
53
+ store.publish(target, token).then(res => {
54
+ // Response is documented here:
55
+ // https://developer.chrome.com/webstore/webstore_api/items/publish
56
+ });
57
+ ```
58
+
59
+ ### Get a Chrome Web Store item
60
+
61
+ ```javascript
62
+ const projection = "DRAFT"; // optional. Can also be 'PUBLISHED' but only "DRAFT" is supported at this time.
63
+ const token = "xxxx"; // optional. One will be fetched if not provided
64
+ store.get(projection, token).then((res) => {
65
+ // Response is documented here:
66
+ // https://developer.chrome.com/docs/webstore/webstore_api/items/get
50
67
  });
51
68
  ```
52
69
 
53
70
  ### Fetch token
71
+
54
72
  ```javascript
55
- webStore.fetchToken().then(token => {
56
- // Token is a string
73
+ store.fetchToken().then(token => {
74
+ // Token is a string
57
75
  });
58
76
  ```
59
77
 
@@ -61,6 +79,9 @@ webStore.fetchToken().then(token => {
61
79
 
62
80
  - If you plan to upload _and_ publish at the same time, use the `fetchToken` method, and pass it to both `uploadExisting` and `publish` as the optional second parameter. This will avoid those methods making duplicate calls for new tokens.
63
81
 
64
- ## Prior Art
65
- - [grunt-webstore-upload](https://github.com/c301/grunt-webstore-upload)
66
- - [chrome-webstore-manager](https://github.com/pastak/chrome-webstore-manager)
82
+ ## Related
83
+
84
+ - [webext-storage-cache](https://github.com/fregante/webext-storage-cache) - Map-like promised cache storage with expiration. Chrome and Firefox
85
+ - [webext-dynamic-content-scripts](https://github.com/fregante/webext-dynamic-content-scripts) - Automatically registers your content_scripts on domains added via permission.request
86
+ - [Awesome-WebExtensions](https://github.com/fregante/Awesome-WebExtensions) - A curated list of awesome resources for WebExtensions development.
87
+ - [More…](https://github.com/fregante/webext-fun)
@@ -1,22 +0,0 @@
1
- name: CI
2
- on:
3
- - push
4
- - pull_request
5
- jobs:
6
- test:
7
- name: Node.js ${{ matrix.node-version }}
8
- runs-on: ubuntu-latest
9
- strategy:
10
- fail-fast: false
11
- matrix:
12
- node-version:
13
- - 16
14
- - 14
15
- - 12
16
- steps:
17
- - uses: actions/checkout@v2
18
- - uses: actions/setup-node@v2
19
- with:
20
- node-version: ${{ matrix.node-version }}
21
- - run: npm install
22
- - run: npm test
@@ -1,89 +0,0 @@
1
- # How to generate Google API keys
2
-
3
- [chrome-webstore-upload](https://github.com/fregante/chrome-webstore-upload) uses the Chrome Web Store API.
4
-
5
- Here's how to get its 2 access keys: `clientId`, `refreshToken`
6
-
7
- Version below v0.5.0 used `clientSecret`, but this is no longer used, as long as you create a "Chrome App" OAuth.
8
-
9
- *Note:* the names you enter here don't really matter. It's an app that only you will have access to. This will take approximately 10 minutes and Google likes to change these screens often. Sorry.
10
-
11
- 0. Visit https://console.developers.google.com/apis/credentials
12
- 0. Create a project:
13
-
14
- <img width="772" alt="Google APIs: Create project" src="https://user-images.githubusercontent.com/1402241/77865620-9a8a3680-722f-11ea-99cb-b09e5c0c11ec.png">
15
-
16
- 0. Enter `chrome-webstore-upload` and **Create**
17
- 0. Visit https://console.cloud.google.com/apis/credentials/consent
18
- 0. Select on **External** and **Create**
19
-
20
- > <img width="804" alt="OAuth Consent Screen" src="https://user-images.githubusercontent.com/1402241/133878019-f159f035-2b76-4686-a461-0e0005355da6.png">
21
-
22
- 0. Only enter the Application name (e.g. `chrome-webstore-upload`) and required email fields, and click **Save**
23
-
24
- > <img width="475" alt="Consent screen configuration" src="https://user-images.githubusercontent.com/1402241/77865809-82ff7d80-7230-11ea-8a96-e381d55524c5.png">
25
-
26
- 0. On the 3rd screen, add your own email address:
27
-
28
- > <img width="632" alt="Test users selection" src="https://user-images.githubusercontent.com/1402241/106213510-7c180300-6192-11eb-97b4-b4ae92424bf1.png">
29
-
30
- 0. Visit https://console.developers.google.com/apis/library/chromewebstore.googleapis.com
31
- 0. Click **Enable**
32
- 0. Visit https://console.developers.google.com/apis/credentials
33
- 0. Click **Create credentials** > **OAuth client ID**:
34
-
35
- > <img width="771" alt="Create credentials" src="https://user-images.githubusercontent.com/1402241/77865679-e89f3a00-722f-11ea-942d-5245091f22b8.png">
36
-
37
- 0. Select **Chrome app**, enter `Chrome Webstore Upload`, your extension’s ID, and click **Create**
38
-
39
- > <img width="547" alt="Create OAuth client ID" src="https://user-images.githubusercontent.com/1402241/106205904-de6a0700-6184-11eb-8591-984e69c5e82a.png">
40
-
41
- 0. Save your ✅ `clientId`; This is 1 of the 2 keys you will need
42
-
43
- > <img width="567" alt="OAuth client created" src="https://user-images.githubusercontent.com/1402241/133878131-9303a024-3f8e-4037-9816-cdf042a91d84.png">
44
-
45
- 0. Visit https://console.cloud.google.com/apis/credentials/consent
46
- 0. Click **PUBLISH APP** and confirm
47
-
48
- <img width="771" alt="Publish app" src="https://user-images.githubusercontent.com/27696701/114265946-2da2a280-9a26-11eb-9567-c4e00f572500.png">
49
-
50
- 0. Place your `clientId` in this URL and open it:
51
-
52
- `https://accounts.google.com/o/oauth2/auth?response_type=code&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fchromewebstore&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&access_type=offline&approval_prompt=force&client_id=YOUR_CLIENT_ID_HERE`
53
-
54
- 0. Follow its steps and warnings (this is your own personal app)
55
- 0. Wait on this page:
56
-
57
- <img width="521" alt="Last page of OAuth" src="https://user-images.githubusercontent.com/1402241/77866731-79781480-7234-11ea-8f81-c533846d89ea.png">
58
-
59
- 0. Run this in your browser console **on that last page**. It's a wizard to create your `refresh_token`:
60
-
61
- ```js
62
- (async () => {
63
- const response = await fetch('https://accounts.google.com/o/oauth2/token', {
64
- method: "POST",
65
- body: new URLSearchParams([
66
- ['client_id', prompt('Enter your clientId')],
67
- ['code', new URLSearchParams(location.search).get('approvalCode')],
68
- ['grant_type', 'authorization_code'],
69
- ['redirect_uri', 'urn:ietf:wg:oauth:2.0:oob']
70
- ]),
71
- headers: {
72
- 'Content-Type': 'application/x-www-form-urlencoded'
73
- }
74
- });
75
- const json = await response.json();
76
- console.log(json);
77
- if (!json.error) {
78
- if (typeof copy === 'function') {
79
- copy(json.refresh_token);
80
- alert('The refresh_token has been copied into your clipboard. You’re done!');
81
- } else {
82
- console.log('Copy your token:', json.refresh_token);
83
- alert('Copy your refresh_token from the console output. You’re done!');
84
- }
85
- }
86
- })();
87
- ```
88
-
89
- 9001. Done. Now you should have ✅ `clientId` and ✅ `refreshToken`. You can use these for all your extensions, but don't share them!
package/LICENSE.md DELETED
@@ -1,21 +0,0 @@
1
- The MIT License (MIT)
2
-
3
- Copyright (c) 2020 Andrew Levine
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.