@contentful/app-scripts 1.1.38 → 1.2.1
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/README.md +27 -29
- package/bin/app-scripts +11 -13
- package/lib/clean-up/build-clean-up-settings.js +5 -1
- package/lib/clean-up/clean-up-bundles.js +7 -1
- package/lib/get-app-info.js +3 -3
- package/lib/get-management-token.js +8 -11
- package/lib/get-management-token.test.js +69 -37
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -16,17 +16,18 @@ Globally:
|
|
|
16
16
|
npm i -g @contentful/app-scripts
|
|
17
17
|
```
|
|
18
18
|
|
|
19
|
-
|
|
20
19
|
## ⚙️ Usage
|
|
21
20
|
|
|
22
21
|
### 💻 CLI
|
|
23
22
|
|
|
24
23
|
When installed
|
|
24
|
+
|
|
25
25
|
```
|
|
26
26
|
$ contentful-app-scripts create-app-definition
|
|
27
27
|
```
|
|
28
28
|
|
|
29
29
|
Otherwise
|
|
30
|
+
|
|
30
31
|
```
|
|
31
32
|
$ npx @contentful/app-scripts create-app-definition
|
|
32
33
|
```
|
|
@@ -34,14 +35,12 @@ $ npx @contentful/app-scripts create-app-definition
|
|
|
34
35
|
### 👨💻 Programmatic
|
|
35
36
|
|
|
36
37
|
```javascript
|
|
37
|
-
const { createAppDefinition } = require('@contentful/app-scripts')
|
|
38
|
-
const { myCustomLogic } = require('./my-custom-logic')
|
|
39
|
-
|
|
40
|
-
(async function main() {
|
|
38
|
+
const { createAppDefinition } = require('@contentful/app-scripts');
|
|
39
|
+
const { myCustomLogic } = require('./my-custom-logic')(async function main() {
|
|
41
40
|
myCustomLogic();
|
|
42
41
|
|
|
43
|
-
await createAppDefinition.interactive()
|
|
44
|
-
})()
|
|
42
|
+
await createAppDefinition.interactive();
|
|
43
|
+
})();
|
|
45
44
|
```
|
|
46
45
|
|
|
47
46
|
## 📜 API
|
|
@@ -107,18 +106,17 @@ When passing the `--ci` argument the command will fail when the required variabl
|
|
|
107
106
|
|
|
108
107
|
**Options:**
|
|
109
108
|
|
|
110
|
-
| Argument
|
|
111
|
-
|
|
|
112
|
-
| `--bundle-dir`
|
|
113
|
-
| `--organization-id`
|
|
114
|
-
| `--definition-id`
|
|
115
|
-
| `--token`
|
|
116
|
-
| `--skip-activation`
|
|
117
|
-
| `--comment`
|
|
109
|
+
| Argument | Description |
|
|
110
|
+
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
111
|
+
| `--bundle-dir` | The directory of your build folder (e.g.: `./build`) |
|
|
112
|
+
| `--organization-id` | The ID of your organisation |
|
|
113
|
+
| `--definition-id` | The ID of the app to which to add the bundle |
|
|
114
|
+
| `--token` | A personal [access token](https://www.contentful.com/developers/docs/references/content-management-api/#/reference/personal-access-tokens) |
|
|
115
|
+
| `--skip-activation` | (optional) Boolean flag to skip the automatic activation of the `AppBundle` |
|
|
116
|
+
| `--comment` | (optional) A comment which will be associated with the created `AppBundle`. Can be used to differentiate bundles. |
|
|
118
117
|
|
|
119
118
|
**Note:** You can also pass all arguments in interactive mode to skip being asked for it.
|
|
120
119
|
|
|
121
|
-
|
|
122
120
|
### Activate an AppBundle
|
|
123
121
|
|
|
124
122
|
Allows you to activate an AppBundle for an AppDefinition.
|
|
@@ -150,12 +148,12 @@ When passing the `--ci` argument adding all variables as arguments is required
|
|
|
150
148
|
|
|
151
149
|
**Options:**
|
|
152
150
|
|
|
153
|
-
| Argument
|
|
154
|
-
|
|
|
155
|
-
| `--bundle-id`
|
|
156
|
-
| `--organization-id`
|
|
157
|
-
| `--definition-id`
|
|
158
|
-
| `--token`
|
|
151
|
+
| Argument | Description |
|
|
152
|
+
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
153
|
+
| `--bundle-id` | The ID of the AppBundle you want to activate |
|
|
154
|
+
| `--organization-id` | The ID of your organisation |
|
|
155
|
+
| `--definition-id` | The ID of the app to which to add the bundle |
|
|
156
|
+
| `--token` | A personal [access token](https://www.contentful.com/developers/docs/references/content-management-api/#/reference/personal-access-tokens) |
|
|
159
157
|
|
|
160
158
|
**Note:** You can also pass all arguments in interactive mode to skip being asked for it.
|
|
161
159
|
|
|
@@ -177,7 +175,6 @@ You can also execute this command without the argument if the environment variab
|
|
|
177
175
|
> $ CONTENTFUL_APP_DEF_ID=some-definition-id npx --no-install @contentful/app-scripts open-settings
|
|
178
176
|
> ```
|
|
179
177
|
|
|
180
|
-
|
|
181
178
|
### Clean up bundles
|
|
182
179
|
|
|
183
180
|
Allows you to clean the list of previous bundles. It fetches the list and deletes all bundles except the 50 newest ones.
|
|
@@ -211,11 +208,12 @@ When passing the `--ci` argument adding all variables as arguments is required
|
|
|
211
208
|
|
|
212
209
|
**Options:**
|
|
213
210
|
|
|
214
|
-
| Argument
|
|
215
|
-
|
|
|
216
|
-
| `--bundle-id`
|
|
217
|
-
| `--organization-id`
|
|
218
|
-
| `--definition-id`
|
|
219
|
-
| `--keep`
|
|
211
|
+
| Argument | Description |
|
|
212
|
+
| ------------------- | -------------------------------------------- |
|
|
213
|
+
| `--bundle-id` | The ID of the AppBundle you want to activate |
|
|
214
|
+
| `--organization-id` | The ID of your organisation |
|
|
215
|
+
| `--definition-id` | The ID of the app to which to add the bundle |
|
|
216
|
+
| `--keep` | Optional, the amount of bundles to keep |
|
|
217
|
+
| `--host` | Optional, the Contentful CMA-endpoint to use |
|
|
220
218
|
|
|
221
219
|
**Note:** You can also pass all arguments in interactive mode to skip being asked for it.
|
package/bin/app-scripts
CHANGED
|
@@ -3,25 +3,22 @@
|
|
|
3
3
|
const { program } = require('commander');
|
|
4
4
|
const { version } = require('../package.json');
|
|
5
5
|
|
|
6
|
-
const {createAppDefinition, upload, activate, cleanup, open} = require('../')
|
|
7
|
-
|
|
6
|
+
const { createAppDefinition, upload, activate, cleanup, open } = require('../');
|
|
8
7
|
|
|
9
8
|
async function runCommand(command, options) {
|
|
10
|
-
const {ci} = program.opts()
|
|
9
|
+
const { ci } = program.opts();
|
|
11
10
|
return ci ? await command.nonInteractive(options) : await command.interactive(options);
|
|
12
11
|
}
|
|
13
12
|
|
|
14
13
|
(async function main() {
|
|
15
|
-
program
|
|
16
|
-
.version(version)
|
|
17
|
-
.option('--ci', 'Execute in non-interactive mode', false)
|
|
14
|
+
program.version(version).option('--ci', 'Execute in non-interactive mode', false);
|
|
18
15
|
|
|
19
16
|
program
|
|
20
17
|
.command('create-app-definition')
|
|
21
18
|
.description('Create a new AppDefinition for an App')
|
|
22
19
|
.action(async (options) => {
|
|
23
20
|
await runCommand(createAppDefinition, options);
|
|
24
|
-
})
|
|
21
|
+
});
|
|
25
22
|
|
|
26
23
|
program
|
|
27
24
|
.command('upload')
|
|
@@ -34,7 +31,7 @@ async function runCommand(command, options) {
|
|
|
34
31
|
.option('--skip-activation', 'A Boolean flag to skip automatic activation')
|
|
35
32
|
.action(async (options) => {
|
|
36
33
|
await runCommand(upload, options);
|
|
37
|
-
})
|
|
34
|
+
});
|
|
38
35
|
|
|
39
36
|
program
|
|
40
37
|
.command('activate')
|
|
@@ -45,7 +42,7 @@ async function runCommand(command, options) {
|
|
|
45
42
|
.option('--token [accessToken]', 'Your content management access token')
|
|
46
43
|
.action(async (options) => {
|
|
47
44
|
await runCommand(activate, options);
|
|
48
|
-
})
|
|
45
|
+
});
|
|
49
46
|
|
|
50
47
|
program
|
|
51
48
|
.command('open-settings')
|
|
@@ -53,7 +50,7 @@ async function runCommand(command, options) {
|
|
|
53
50
|
.option('--definition-id [defId]', 'The id of your apps definition')
|
|
54
51
|
.action(async (options) => {
|
|
55
52
|
await runCommand(open, options);
|
|
56
|
-
})
|
|
53
|
+
});
|
|
57
54
|
|
|
58
55
|
program
|
|
59
56
|
.command('bundle-cleanup')
|
|
@@ -62,13 +59,14 @@ async function runCommand(command, options) {
|
|
|
62
59
|
.option('--definition-id [defId]', 'The id of your apps definition')
|
|
63
60
|
.option('--token [accessToken]', 'Your content management access token')
|
|
64
61
|
.option('--keep [keepAmount]', 'The amount of bundles that should remain')
|
|
62
|
+
.option('--host [host]', 'Contentful CMA-endpoint to use')
|
|
65
63
|
.action(async (options) => {
|
|
66
64
|
await runCommand(cleanup, options);
|
|
67
|
-
})
|
|
65
|
+
});
|
|
68
66
|
|
|
69
67
|
await program.parseAsync(process.argv);
|
|
70
|
-
})().catch(e => {
|
|
68
|
+
})().catch((e) => {
|
|
71
69
|
console.error(e);
|
|
72
70
|
// eslint-disable-next-line no-process-exit
|
|
73
71
|
process.exit(1);
|
|
74
|
-
})
|
|
72
|
+
});
|
|
@@ -3,7 +3,11 @@ const { getAppInfo } = require('../get-app-info');
|
|
|
3
3
|
|
|
4
4
|
async function buildCleanUpSettings(options) {
|
|
5
5
|
const appInfo = await getAppInfo(options);
|
|
6
|
-
return {
|
|
6
|
+
return {
|
|
7
|
+
...appInfo,
|
|
8
|
+
keep: options.keep !== undefined ? +options.keep : DEFAULT_BUNDLES_TO_KEEP,
|
|
9
|
+
host: options.host,
|
|
10
|
+
};
|
|
7
11
|
}
|
|
8
12
|
|
|
9
13
|
module.exports = {
|
|
@@ -30,7 +30,13 @@ const scheduleBundleDeletion = async (bundlesToDelete, client, settings) => {
|
|
|
30
30
|
|
|
31
31
|
async function cleanUpBundles(settings) {
|
|
32
32
|
let bundles, definition;
|
|
33
|
-
const client = createClient(
|
|
33
|
+
const client = createClient(
|
|
34
|
+
{
|
|
35
|
+
host: settings.host,
|
|
36
|
+
accessToken: settings.accessToken,
|
|
37
|
+
},
|
|
38
|
+
{ type: 'plain' }
|
|
39
|
+
);
|
|
34
40
|
const bundlesSpinner = ora(`Fetching all bundles...`).start();
|
|
35
41
|
try {
|
|
36
42
|
bundles = await client.appBundle.getMany({
|
package/lib/get-app-info.js
CHANGED
|
@@ -4,9 +4,9 @@ const { createClient } = require('contentful-management');
|
|
|
4
4
|
const { getManagementToken } = require('./get-management-token');
|
|
5
5
|
|
|
6
6
|
const getAppInfo = async (options) => {
|
|
7
|
-
const
|
|
8
|
-
|
|
9
|
-
const client = createClient({ accessToken });
|
|
7
|
+
const { host } = options;
|
|
8
|
+
const accessToken = options.token || (await getManagementToken(host));
|
|
9
|
+
const client = createClient({ accessToken, host });
|
|
10
10
|
|
|
11
11
|
const organization = options.organizationId
|
|
12
12
|
? await getOrganizationById(client, options.organizationId)
|
|
@@ -5,22 +5,19 @@ const open = require('open');
|
|
|
5
5
|
const inquirer = require('inquirer');
|
|
6
6
|
const { cacheEnvVars } = require('../utils/cache-credential');
|
|
7
7
|
const { createClient } = require('contentful-management');
|
|
8
|
-
const {
|
|
9
|
-
ACCESS_TOKEN_ENV_KEY
|
|
10
|
-
} = require('../utils/constants');
|
|
8
|
+
const { ACCESS_TOKEN_ENV_KEY } = require('../utils/constants');
|
|
11
9
|
|
|
12
|
-
const checkTokenValidity = async (accessToken) => {
|
|
10
|
+
const checkTokenValidity = async (accessToken, host) => {
|
|
13
11
|
try {
|
|
14
|
-
const client = createClient({ accessToken });
|
|
12
|
+
const client = createClient({ accessToken, host });
|
|
15
13
|
await client.getCurrentUser();
|
|
16
14
|
return true;
|
|
17
|
-
|
|
18
|
-
} catch(err) {
|
|
15
|
+
} catch (err) {
|
|
19
16
|
return false;
|
|
20
17
|
}
|
|
21
|
-
}
|
|
18
|
+
};
|
|
22
19
|
|
|
23
|
-
async function getManagementToken() {
|
|
20
|
+
async function getManagementToken(host) {
|
|
24
21
|
const redirectUrl = 'https://www.contentful.com/developers/cli-oauth-page/';
|
|
25
22
|
const CLIENT_ID = '9f86a1d54f3d6f85c159468f5919d6e5d27716b3ed68fd01bd534e3dea2df864';
|
|
26
23
|
const oauthUrl = `https://be.contentful.com/oauth/authorize?response_type=token&scope=content_management_manage&client_id=${CLIENT_ID}&&redirect_uri=${encodeURIComponent(
|
|
@@ -28,7 +25,7 @@ async function getManagementToken() {
|
|
|
28
25
|
)}`;
|
|
29
26
|
|
|
30
27
|
const cachedAccessToken = process.env[ACCESS_TOKEN_ENV_KEY];
|
|
31
|
-
const cachedTokenValid = await checkTokenValidity(cachedAccessToken);
|
|
28
|
+
const cachedTokenValid = await checkTokenValidity(cachedAccessToken, host);
|
|
32
29
|
|
|
33
30
|
if (cachedTokenValid) {
|
|
34
31
|
return cachedAccessToken;
|
|
@@ -57,7 +54,7 @@ async function getManagementToken() {
|
|
|
57
54
|
},
|
|
58
55
|
]);
|
|
59
56
|
|
|
60
|
-
await cacheEnvVars({[ACCESS_TOKEN_ENV_KEY]: mgmtToken});
|
|
57
|
+
await cacheEnvVars({ [ACCESS_TOKEN_ENV_KEY]: mgmtToken });
|
|
61
58
|
|
|
62
59
|
return mgmtToken;
|
|
63
60
|
}
|
|
@@ -1,50 +1,82 @@
|
|
|
1
1
|
const proxyquire = require('proxyquire');
|
|
2
|
-
const { stub } = require('sinon');
|
|
2
|
+
const { stub, spy } = require('sinon');
|
|
3
3
|
const assert = require('assert');
|
|
4
4
|
|
|
5
|
-
describe('getManagementToken', () => {
|
|
6
|
-
|
|
5
|
+
describe('getManagementToken-js', () => {
|
|
6
|
+
context('getManagementToken', () => {
|
|
7
|
+
let subject, promptMock, openMock;
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
beforeEach(() => {
|
|
10
|
+
stub(console, 'log');
|
|
11
|
+
});
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
afterEach(() => {
|
|
14
|
+
console.log.restore();
|
|
15
|
+
});
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
({ getManagementToken: subject } = proxyquire('./get-management-token', {
|
|
21
|
-
inquirer: { prompt: promptMock },
|
|
22
|
-
open: openMock,
|
|
23
|
-
'contentful-management': {
|
|
24
|
-
createClient() {
|
|
25
|
-
return {
|
|
26
|
-
async getOrganizations() {
|
|
27
|
-
throw new Error();
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
}));
|
|
33
|
-
});
|
|
17
|
+
beforeEach(() => {
|
|
18
|
+
promptMock = stub();
|
|
19
|
+
openMock = stub();
|
|
34
20
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
21
|
+
({ getManagementToken: subject } = proxyquire('./get-management-token', {
|
|
22
|
+
inquirer: { prompt: promptMock },
|
|
23
|
+
open: openMock,
|
|
24
|
+
'contentful-management': {
|
|
25
|
+
createClient() {
|
|
26
|
+
return {
|
|
27
|
+
async getOrganizations() {
|
|
28
|
+
throw new Error();
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
},
|
|
32
|
+
},
|
|
33
|
+
}));
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('throws when unable to open the browser', async () => {
|
|
37
|
+
openMock.throws(new Error());
|
|
38
|
+
await assert.rejects(() => subject());
|
|
39
|
+
});
|
|
39
40
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
it('throws when unable to get input', async () => {
|
|
42
|
+
promptMock.throws(new Error());
|
|
43
|
+
await assert.rejects(() => subject());
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('returns management token', async () => {
|
|
47
|
+
const mgmtToken = 'token';
|
|
48
|
+
promptMock.returns({ mgmtToken });
|
|
49
|
+
assert.strictEqual(await subject(), mgmtToken);
|
|
50
|
+
});
|
|
43
51
|
});
|
|
44
52
|
|
|
45
|
-
|
|
53
|
+
context('checkTokenValidity', () => {
|
|
54
|
+
let subject, createClientSpy, promptMock, openMock;
|
|
46
55
|
const mgmtToken = 'token';
|
|
47
|
-
|
|
48
|
-
|
|
56
|
+
const host = 'host';
|
|
57
|
+
const mockedSettings = {
|
|
58
|
+
host,
|
|
59
|
+
accessToken: mgmtToken,
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
beforeEach(() => {
|
|
63
|
+
promptMock = stub();
|
|
64
|
+
openMock = stub();
|
|
65
|
+
createClientSpy = spy();
|
|
66
|
+
|
|
67
|
+
({ getManagementToken: subject } = proxyquire('./get-management-token', {
|
|
68
|
+
inquirer: { prompt: promptMock },
|
|
69
|
+
open: openMock,
|
|
70
|
+
'contentful-management': {
|
|
71
|
+
createClient: createClientSpy,
|
|
72
|
+
},
|
|
73
|
+
}));
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
it('Call CMA with a host argument', async () => {
|
|
77
|
+
promptMock.returns({ mgmtToken });
|
|
78
|
+
assert.strictEqual(await subject(host), mgmtToken);
|
|
79
|
+
assert.strictEqual(createClientSpy.args[0][0].host, mockedSettings.host);
|
|
80
|
+
});
|
|
49
81
|
});
|
|
50
82
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentful/app-scripts",
|
|
3
|
-
"version": "1.1
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "A collection of scripts for building Contentful Apps",
|
|
5
5
|
"author": "Contentful GmbH",
|
|
6
6
|
"license": "MIT",
|
|
@@ -52,7 +52,7 @@
|
|
|
52
52
|
"bottleneck": "2.19.5",
|
|
53
53
|
"chalk": "4.1.2",
|
|
54
54
|
"commander": "9.4.1",
|
|
55
|
-
"contentful-management": "10.
|
|
55
|
+
"contentful-management": "10.21.0",
|
|
56
56
|
"dotenv": "16.0.3",
|
|
57
57
|
"ignore": "5.2.0",
|
|
58
58
|
"inquirer": "8.2.5",
|
|
@@ -60,5 +60,5 @@
|
|
|
60
60
|
"open": "8.4.0",
|
|
61
61
|
"ora": "5.4.1"
|
|
62
62
|
},
|
|
63
|
-
"gitHead": "
|
|
63
|
+
"gitHead": "4931037eadb494e1b4de4d07f07adf52f39701e8"
|
|
64
64
|
}
|