@contentful/app-scripts 1.10.2 → 1.12.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/README.md CHANGED
@@ -106,14 +106,15 @@ When passing the `--ci` argument the command will fail when the required variabl
106
106
 
107
107
  **Options:**
108
108
 
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. |
109
+ | Argument | Description | Default value |
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` | `false` |
116
+ | `--comment` | (optional) A comment which will be associated with the created `AppBundle`. Can be used to differentiate bundles. | |
117
+ | `--host` | (optional) Contentful CMA-endpoint to use | `api.contentful.com` |
117
118
 
118
119
  **Note:** You can also pass all arguments in interactive mode to skip being asked for it.
119
120
 
@@ -148,12 +149,13 @@ When passing the `--ci` argument adding all variables as arguments is required.
148
149
 
149
150
  **Options:**
150
151
 
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) |
152
+ | Argument | Description | Default value |
153
+ | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | --- |
154
+ | `--bundle-id` | The ID of the AppBundle you want to activate | |
155
+ | `--organization-id` | The ID of your organisation | |
156
+ | `--definition-id` | The ID of the app to which to add the bundle | |
157
+ | `--token` | A personal [access token](https://www.contentful.com/developers/docs/references/content-management-api/#/reference/personal-access-tokens) | |
158
+ | `--host` | (optional) Contentful CMA-endpoint to use | `api.contentful.com` |
157
159
 
158
160
  **Note:** You can also pass all arguments in interactive mode to skip being asked for it.
159
161
 
@@ -208,13 +210,13 @@ When passing the `--ci` argument adding all variables as arguments is required
208
210
 
209
211
  **Options:**
210
212
 
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 |
213
+ | Argument | Description | Default value |
214
+ | ------------------- | -------------------------------------------- | -------------------- |
215
+ | `--bundle-id` | The ID of the AppBundle you want to activate | |
216
+ | `--organization-id` | The ID of your organisation | |
217
+ | `--definition-id` | The ID of the app to which to add the bundle | |
218
+ | `--keep` | (optional) The amount of bundles to keep | `50` |
219
+ | `--host` | (optional) Contentful CMA-endpoint to use | `api.contentful.com` |
218
220
 
219
221
  **Note:** You can also pass all arguments in interactive mode to skip being asked for it.
220
222
 
@@ -4,25 +4,33 @@ const inquirer = require('inquirer');
4
4
  const { getAppInfo } = require('../get-app-info');
5
5
 
6
6
  async function buildBundleActivateSettings(options) {
7
- let { bundleId, host } = options;
7
+ const { bundleId, host } = options;
8
+ const prompts = [];
9
+
8
10
  if (!bundleId) {
9
- const prompts = await inquirer.prompt([
10
- {
11
- name: 'bundleId',
12
- message: `The id of the bundle you want to activate (required):`,
13
- validate: (input) => input.length > 0,
14
- },
15
- ]);
16
- bundleId = prompts.bundleId;
11
+ prompts.push({
12
+ name: 'bundleId',
13
+ message: `The id of the bundle you want to activate (required):`,
14
+ validate: (input) => input.length > 0,
15
+ });
16
+ }
17
+ if (!host) {
18
+ prompts.push({
19
+ name: 'host',
20
+ message: `Contentful CMA endpoint URL:`,
21
+ default: 'api.contentful.com',
22
+ });
17
23
  }
18
24
 
25
+ const appActivateSettings = await inquirer.prompt(prompts);
19
26
  const appInfo = await getAppInfo(options);
20
27
 
21
28
  // Add app-config & dialog automatically
22
29
  return {
23
- ...appInfo,
24
30
  bundleId,
25
31
  host,
32
+ ...appActivateSettings,
33
+ ...appInfo,
26
34
  };
27
35
  }
28
36
 
@@ -1,12 +1,35 @@
1
- const { DEFAULT_BUNDLES_TO_KEEP } = require('../../utils/constants');
1
+ const inquirer = require('inquirer');
2
+ const { DEFAULT_BUNDLES_TO_KEEP, CONTENTFUL_API_HOST } = require('../../utils/constants');
2
3
  const { getAppInfo } = require('../get-app-info');
3
4
 
4
5
  async function buildCleanUpSettings(options) {
6
+ const { keep, host } = options;
7
+ const prompts = [];
8
+
9
+ if (!keep) {
10
+ prompts.push({
11
+ type: 'number',
12
+ name: 'keep',
13
+ message: `The amount of newest bundles to keep:`,
14
+ default: DEFAULT_BUNDLES_TO_KEEP,
15
+ });
16
+ }
17
+ if (!host) {
18
+ prompts.push({
19
+ name: 'host',
20
+ message: `Contentful CMA endpoint URL:`,
21
+ default: CONTENTFUL_API_HOST,
22
+ });
23
+ }
24
+
25
+ const appCleanUpSettings = await inquirer.prompt(prompts);
5
26
  const appInfo = await getAppInfo(options);
27
+
6
28
  return {
29
+ keep: +keep,
30
+ host,
31
+ ...appCleanUpSettings,
7
32
  ...appInfo,
8
- keep: options.keep !== undefined ? +options.keep : DEFAULT_BUNDLES_TO_KEEP,
9
- host: options.host,
10
33
  };
11
34
  }
12
35
 
@@ -14,7 +14,7 @@ const bundlesFixture = [
14
14
  { sys: { id: 'test-8' } },
15
15
  ];
16
16
 
17
- describe.only('cleanUpBundles', () => {
17
+ describe('cleanUpBundles', () => {
18
18
  let subject, clientMock, deleteMock, createClientArgs;
19
19
  let mockedBundles = bundlesFixture;
20
20
 
@@ -92,7 +92,7 @@ describe.only('cleanUpBundles', () => {
92
92
  mockedBundles.unshift({ sys: { id: 'slow' } });
93
93
  mockedBundles = mockedBundles.reverse();
94
94
  clientMock.appBundle.delete = stub().callsFake(
95
- ({ appBundleId }) => new Promise((r) => setTimeout(r, appBundleId === 'slow' ? 200 : 100))
95
+ ({ appBundleId }) => new Promise((r) => setTimeout(r, appBundleId === 'slow' ? 200 : 100)),
96
96
  );
97
97
  subject({ ...mockedSettings, keep: 0 });
98
98
  await clock.tickAsync(50);
@@ -2,12 +2,15 @@
2
2
 
3
3
  const inquirer = require('inquirer');
4
4
  const { getAppInfo } = require('../get-app-info');
5
- const { getActionsManifest } = require('../utils');
5
+ const { getEntityFromManifest } = require('../utils');
6
+ const { CONTENTFUL_API_HOST } = require('../../utils/constants');
6
7
 
7
8
  async function buildAppUploadSettings(options) {
8
- const actionsManifest = getActionsManifest();
9
+ const actionsManifest = getEntityFromManifest('actions');
10
+ const deliveryFnManifest = getEntityFromManifest('deliveryFunctions');
9
11
  const prompts = [];
10
12
  const { bundleDir, comment, skipActivation, host } = options;
13
+
11
14
  if (!bundleDir) {
12
15
  prompts.push({
13
16
  name: 'bundleDirectory',
@@ -22,17 +25,33 @@ async function buildAppUploadSettings(options) {
22
25
  default: '',
23
26
  });
24
27
  }
28
+ if (skipActivation === undefined) {
29
+ prompts.push({
30
+ type: 'confirm',
31
+ name: 'activateBundle',
32
+ message: `Do you want to activate the bundle after upload?`,
33
+ default: true,
34
+ });
35
+ }
36
+ if (!host) {
37
+ prompts.push({
38
+ name: 'host',
39
+ message: `Contentful CMA endpoint URL:`,
40
+ default: CONTENTFUL_API_HOST,
41
+ });
42
+ }
25
43
 
26
- const appUploadSettings = await inquirer.prompt(prompts);
44
+ const { activateBundle, ...appUploadSettings } = await inquirer.prompt(prompts);
27
45
 
28
46
  const appInfo = await getAppInfo(options);
29
47
  // Add app-config & dialog automatically
30
48
  return {
31
49
  bundleDirectory: bundleDir,
32
- skipActivation: !!skipActivation,
50
+ skipActivation: skipActivation === undefined ? !activateBundle : skipActivation,
33
51
  comment,
34
52
  host,
35
53
  actions: actionsManifest,
54
+ deliveryFunctions: deliveryFnManifest,
36
55
  ...appUploadSettings,
37
56
  ...appInfo,
38
57
  };
@@ -6,7 +6,7 @@ const { createClient } = require('contentful-management');
6
6
  const { createAppUpload } = require('./create-app-upload');
7
7
 
8
8
  async function createAppBundleFromUpload(settings, appUploadId) {
9
- const { accessToken, host, userAgentApplication, comment, actions } = settings;
9
+ const { accessToken, host, userAgentApplication, comment, actions, deliveryFunctions } = settings;
10
10
  const clientSpinner = ora('Verifying your upload...').start();
11
11
  const client = createClient({
12
12
  accessToken,
@@ -24,6 +24,7 @@ async function createAppBundleFromUpload(settings, appUploadId) {
24
24
  appUploadId,
25
25
  comment: comment && comment.length > 0 ? comment : undefined,
26
26
  actions,
27
+ deliveryFunctions,
27
28
  });
28
29
  } catch (err) {
29
30
  showCreationError('app upload', err.message);
@@ -38,8 +39,8 @@ async function createAppBundleFromSettings(settings) {
38
39
  appUpload = await createAppUpload(settings);
39
40
  console.log(`
40
41
  ${chalk.yellow('Done!')} Your files were successfully uploaded and a new AppUpload (${chalk.dim(
41
- appUpload.sys.id
42
- )}) has been created.`);
42
+ appUpload.sys.id,
43
+ )}) has been created.`);
43
44
  } catch (err) {
44
45
  showCreationError('app upload', err.message);
45
46
  }
@@ -54,7 +55,7 @@ async function createAppBundleFromSettings(settings) {
54
55
 
55
56
  console.log(`
56
57
  ${chalk.cyan('Success!')} Created a new app bundle for ${chalk.cyan(
57
- settings.definition.name
58
+ settings.definition.name,
58
59
  )} in ${chalk.bold(settings.organization.name)}.
59
60
 
60
61
  Bundle Id: ${chalk.yellow(appBundle.sys.id)}
@@ -2,7 +2,7 @@ const chalk = require('chalk');
2
2
  const ora = require('ora');
3
3
  const { getAppInfo } = require('../get-app-info');
4
4
  const { validateArguments } = require('../validate-arguments');
5
- const { getActionsManifest } = require('../utils');
5
+ const { getEntityFromManifest } = require('../utils');
6
6
 
7
7
  const requiredOptions = {
8
8
  definitionId: '--definition-id',
@@ -13,7 +13,8 @@ const requiredOptions = {
13
13
 
14
14
  async function getUploadSettingsArgs(options) {
15
15
  const validateSpinner = ora('Validating your input...').start();
16
- const actionsManifest = getActionsManifest();
16
+ const actionsManifest = getEntityFromManifest('actions');
17
+ const deliveryFnManifest = getEntityFromManifest('deliveryFunctions');
17
18
  const { bundleDir, comment, skipActivation, host, userAgentApplication } = options;
18
19
 
19
20
  try {
@@ -27,6 +28,7 @@ async function getUploadSettingsArgs(options) {
27
28
  host,
28
29
  userAgentApplication,
29
30
  actions: actionsManifest,
31
+ deliveryFunctions: deliveryFnManifest,
30
32
  };
31
33
  } catch (err) {
32
34
  console.log(`
package/lib/utils.js CHANGED
@@ -35,6 +35,14 @@ const showCreationError = (subject, message) => {
35
35
  `);
36
36
  };
37
37
 
38
+ const logProgress = (message) => {
39
+ console.log('');
40
+ console.log(` ----------------------------
41
+ ${message}
42
+ ----------------------------`);
43
+ console.log('');
44
+ };
45
+
38
46
  const throwError = (err, message) => {
39
47
  console.log(`
40
48
  ${chalk.red('Error:')} ${message}.
@@ -50,10 +58,8 @@ const selectFromList = async (list, message, cachedOptionEnvVar) => {
50
58
  const cachedElement = list.find((item) => item.value === cachedEnvVar);
51
59
 
52
60
  if (cachedElement) {
53
- console.log(`
54
- ${message}
55
- Using environment variable: ${cachedElement.name} (${chalk.blue(cachedElement.value)})
56
- `);
61
+ logProgress(`${message}
62
+ Using environment variable: ${cachedElement.name} (${chalk.blue(cachedElement.value)})`);
57
63
  return cachedElement;
58
64
  } else {
59
65
  const { elementId } = await inquirer.prompt([
@@ -73,7 +79,7 @@ const selectFromList = async (list, message, cachedOptionEnvVar) => {
73
79
  }
74
80
  };
75
81
 
76
- function getActionsManifest() {
82
+ function getEntityFromManifest(type) {
77
83
  const isManifestExists = fs.existsSync(DEFAULT_MANIFEST_PATH);
78
84
 
79
85
  if (!isManifestExists) {
@@ -83,29 +89,29 @@ function getActionsManifest() {
83
89
  try {
84
90
  const manifest = JSON.parse(fs.readFileSync(DEFAULT_MANIFEST_PATH, { encoding: 'utf8' }));
85
91
 
86
- if (!Array.isArray(manifest.actions) || manifest.actions.length === 0) {
92
+ if (!Array.isArray(manifest[type]) || manifest[type].length === 0) {
87
93
  return;
88
94
  }
89
95
 
90
- console.log('');
91
- console.log(` ----------------------------
92
- App actions manifest found in ${chalk.bold(DEFAULT_MANIFEST_PATH)}.
93
- ----------------------------`);
94
- console.log('');
96
+ logProgress(
97
+ `${type === 'actions' ? 'App Actions' : 'Delivery functions'} found in ${chalk.bold(
98
+ DEFAULT_MANIFEST_PATH,
99
+ )}.`,
100
+ );
95
101
 
96
- const actions = manifest.actions.map((action) => {
97
- const allowNetworks = Array.isArray(action.allowNetworks)
98
- ? action.allowNetworks.map(stripProtocol)
102
+ const items = manifest[type].map((item) => {
103
+ const allowNetworks = Array.isArray(item.allowNetworks)
104
+ ? item.allowNetworks.map(stripProtocol)
99
105
  : [];
100
106
 
101
107
  const hasInvalidNetwork = allowNetworks.find((netWork) => !isValidNetwork(netWork));
102
108
  if (hasInvalidNetwork) {
103
109
  console.log(
104
110
  `${chalk.red(
105
- 'Error:'
106
- )} Invalid IP address ${hasInvalidNetwork} found in the allowNetworks array for action "${
107
- action.name
108
- }".`
111
+ 'Error:',
112
+ )} Invalid IP address ${hasInvalidNetwork} found in the allowNetworks array for ${type} "${
113
+ item.name
114
+ }".`,
109
115
  );
110
116
  // eslint-disable-next-line no-process-exit
111
117
  process.exit(1);
@@ -113,20 +119,20 @@ function getActionsManifest() {
113
119
 
114
120
  // EntryFile is not used but we do want to strip it from action
115
121
  // eslint-disable-next-line no-unused-vars
116
- const { entryFile: _, ...actionWithoutEntryFile } = action;
122
+ const { entryFile: _, ...itemWithoutEntryFile } = item;
117
123
 
118
124
  return {
119
- ...actionWithoutEntryFile,
125
+ ...itemWithoutEntryFile,
120
126
  allowNetworks,
121
127
  };
122
128
  });
123
129
 
124
- return actions;
130
+ return items;
125
131
  } catch {
126
132
  console.log(
127
133
  `${chalk.red('Error:')} Invalid JSON in manifest file at ${chalk.bold(
128
- DEFAULT_MANIFEST_PATH
129
- )}.`
134
+ DEFAULT_MANIFEST_PATH,
135
+ )}.`,
130
136
  );
131
137
  // eslint-disable-next-line no-process-exit
132
138
  process.exit(1);
@@ -138,7 +144,7 @@ module.exports = {
138
144
  throwError,
139
145
  selectFromList,
140
146
  showCreationError,
141
- getActionsManifest,
147
+ getEntityFromManifest,
142
148
  isValidNetwork,
143
149
  stripProtocol,
144
150
  };
package/lib/utils.test.js CHANGED
@@ -68,9 +68,8 @@ describe('removeProtocolFromUrl', () => {
68
68
  });
69
69
  });
70
70
 
71
- describe('getActionsManifest', () => {
71
+ describe('get actions from manifest', () => {
72
72
  let fs, exitStub, consoleLog, chalk;
73
- let DEFAULT_MANIFEST_PATH = 'path/to/manifest';
74
73
 
75
74
  const actionMock = {
76
75
  name: 'name',
@@ -94,7 +93,7 @@ describe('getActionsManifest', () => {
94
93
  red: stub(),
95
94
  };
96
95
 
97
- let { getActionsManifest } = proxyquire('./utils', { fs, chalk });
96
+ let { getEntityFromManifest } = proxyquire('./utils', { fs, chalk });
98
97
 
99
98
  beforeEach(() => {
100
99
  exitStub = stub(process, 'exit');
@@ -108,7 +107,7 @@ describe('getActionsManifest', () => {
108
107
  it('should return undefined if manifest does not exist', () => {
109
108
  fs.existsSync.returns(false);
110
109
 
111
- const result = getActionsManifest(DEFAULT_MANIFEST_PATH);
110
+ const result = getEntityFromManifest('actions');
112
111
 
113
112
  assert.equal(result, undefined);
114
113
  });
@@ -117,7 +116,7 @@ describe('getActionsManifest', () => {
117
116
  fs.existsSync.returns(true);
118
117
  fs.readFileSync.returns(JSON.stringify({ actions: [] }));
119
118
 
120
- const result = getActionsManifest(DEFAULT_MANIFEST_PATH);
119
+ const result = getEntityFromManifest('actions');
121
120
  assert.equal(result, undefined);
122
121
  });
123
122
 
@@ -126,10 +125,10 @@ describe('getActionsManifest', () => {
126
125
  fs.readFileSync.returns(
127
126
  JSON.stringify({
128
127
  actions: [actionMock],
129
- })
128
+ }),
130
129
  );
131
130
 
132
- const result = getActionsManifest();
131
+ const result = getEntityFromManifest('actions');
133
132
 
134
133
  assert.deepEqual(result, [resultMock]);
135
134
  assert.ok(consoleLog.called);
@@ -146,10 +145,10 @@ describe('getActionsManifest', () => {
146
145
  fs.readFileSync.returns(
147
146
  JSON.stringify({
148
147
  actions: [mockAction],
149
- })
148
+ }),
150
149
  );
151
150
 
152
- const result = getActionsManifest();
151
+ const result = getEntityFromManifest('actions');
153
152
 
154
153
  assert.deepEqual(result, [{ ...resultMock, allowNetworks: ['some.domain.tld'] }]);
155
154
  assert.ok(consoleLog.called);
@@ -160,10 +159,10 @@ describe('getActionsManifest', () => {
160
159
  fs.readFileSync.returns(
161
160
  JSON.stringify({
162
161
  actions: [actionMock],
163
- })
162
+ }),
164
163
  );
165
164
 
166
- const result = getActionsManifest();
165
+ const result = getEntityFromManifest('actions');
167
166
 
168
167
  assert.notDeepEqual(result, [actionMock]);
169
168
  });
@@ -179,10 +178,10 @@ describe('getActionsManifest', () => {
179
178
  allowNetworks: ['412.1.1.1'],
180
179
  },
181
180
  ],
182
- })
181
+ }),
183
182
  );
184
183
 
185
- getActionsManifest();
184
+ getEntityFromManifest('actions');
186
185
 
187
186
  assert.ok(exitStub.calledOnceWith(1));
188
187
  });
@@ -191,7 +190,133 @@ describe('getActionsManifest', () => {
191
190
  fs.existsSync.returns(true);
192
191
  fs.readFileSync.throws();
193
192
 
194
- getActionsManifest();
193
+ getEntityFromManifest('actions');
194
+
195
+ assert.ok(exitStub.calledOnceWith(1));
196
+ });
197
+ });
198
+
199
+ describe('get delivery functions from manifest', () => {
200
+ let fs, exitStub, consoleLog, chalk;
201
+
202
+ const deliveryFnMock = {
203
+ id: 'test',
204
+ name: 'name',
205
+ description: 'descriptoin',
206
+ path: 'delivery-functions/mock.js',
207
+ entryFile: './delivery-functions/mock.ts',
208
+ allowNetworks: ['127.0.0.1', 'some.domain.tld'],
209
+ };
210
+ // eslint-disable-next-line no-unused-vars
211
+ const { entryFile: _, ...resultMock } = deliveryFnMock;
212
+
213
+ fs = {
214
+ existsSync: stub(),
215
+ readFileSync: stub(),
216
+ };
217
+ chalk = {
218
+ bold: stub(),
219
+ red: stub(),
220
+ };
221
+
222
+ let { getEntityFromManifest } = proxyquire('./utils', { fs, chalk });
223
+
224
+ beforeEach(() => {
225
+ exitStub = stub(process, 'exit');
226
+ consoleLog = stub(console, 'log');
227
+ });
228
+ afterEach(() => {
229
+ exitStub.restore();
230
+ consoleLog.restore();
231
+ });
232
+
233
+ it('should return undefined if manifest does not exist', () => {
234
+ fs.existsSync.returns(false);
235
+
236
+ const result = getEntityFromManifest('deliveryFunctions');
237
+
238
+ assert.equal(result, undefined);
239
+ });
240
+
241
+ it('should return undefined if manifest has no delivery functions', () => {
242
+ fs.existsSync.returns(true);
243
+ fs.readFileSync.returns(JSON.stringify({ deliveryFunctions: [] }));
244
+
245
+ const result = getEntityFromManifest('deliveryFunctions');
246
+ assert.equal(result, undefined);
247
+ });
248
+
249
+ it('should return an array of delivery functions if manifest is valid', () => {
250
+ fs.existsSync.returns(true);
251
+ fs.readFileSync.returns(
252
+ JSON.stringify({
253
+ deliveryFunctions: [deliveryFnMock],
254
+ }),
255
+ );
256
+
257
+ const result = getEntityFromManifest('deliveryFunctions');
258
+
259
+ assert.deepEqual(result, [resultMock]);
260
+ assert.ok(consoleLog.called);
261
+ });
262
+
263
+ it('should strip the protocol when a domain has a protocol in allowNetworks', () => {
264
+ const mockDeliveryFn = {
265
+ ...deliveryFnMock,
266
+ allowNetworks: ['http://some.domain.tld'],
267
+ };
268
+ // eslint-disable-next-line no-unused-vars
269
+ const { entryFile: _, ...resultMock } = mockDeliveryFn;
270
+ fs.existsSync.returns(true);
271
+ fs.readFileSync.returns(
272
+ JSON.stringify({
273
+ deliveryFunctions: [mockDeliveryFn],
274
+ }),
275
+ );
276
+
277
+ const result = getEntityFromManifest('deliveryFunctions');
278
+
279
+ assert.deepEqual(result, [{ ...resultMock, allowNetworks: ['some.domain.tld'] }]);
280
+ assert.ok(consoleLog.called);
281
+ });
282
+
283
+ it('should return an array of delivery functions without entryFile prop if manifest is valid', () => {
284
+ fs.existsSync.returns(true);
285
+ fs.readFileSync.returns(
286
+ JSON.stringify({
287
+ deliveryFunctions: [deliveryFnMock],
288
+ }),
289
+ );
290
+
291
+ const result = getEntityFromManifest('deliveryFunctions');
292
+
293
+ assert.notDeepEqual(result, [deliveryFnMock]);
294
+ });
295
+
296
+ it('should exit with error if invalid network is found in allowNetworks', () => {
297
+ fs.existsSync.returns(true);
298
+ fs.readFileSync.returns(
299
+ JSON.stringify({
300
+ deliveryFunctions: [
301
+ {
302
+ name: 'test resolver fn',
303
+ entryFile: 'entry1',
304
+ allowNetworks: ['412.1.1.1'],
305
+ },
306
+ ],
307
+ }),
308
+ );
309
+
310
+ getEntityFromManifest('deliveryFunctions');
311
+
312
+ assert.ok(exitStub.calledOnceWith(1));
313
+ });
314
+
315
+ it('should exit with error if manifest is invalid JSON', () => {
316
+ fs.existsSync.returns(true);
317
+ fs.readFileSync.throws();
318
+
319
+ getEntityFromManifest('deliveryFunctions');
195
320
 
196
321
  assert.ok(exitStub.calledOnceWith(1));
197
322
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@contentful/app-scripts",
3
- "version": "1.10.2",
3
+ "version": "1.12.0",
4
4
  "description": "A collection of scripts for building Contentful Apps",
5
5
  "author": "Contentful GmbH",
6
6
  "license": "MIT",
@@ -27,7 +27,7 @@
27
27
  "prettier": "prettier **/*.js --write --ignore-path .gitignore",
28
28
  "lint": "eslint ./lib",
29
29
  "lint:fix": "npm run lint -- --fix",
30
- "test": "mocha ./lib/**/*.test.js ./lib/*.test.js ./utils/**/*.test.js",
30
+ "test": "mocha \"./{,!(node_modules)/**/}*.test.js\" --exit",
31
31
  "test:watch": "npm t -- --watch",
32
32
  "pre-commit": "lint-staged"
33
33
  },
@@ -52,14 +52,14 @@
52
52
  "analytics-node": "^6.2.0",
53
53
  "bottleneck": "2.19.5",
54
54
  "chalk": "4.1.2",
55
- "commander": "10.0.1",
56
- "contentful-management": "10.35.4",
57
- "dotenv": "16.0.3",
55
+ "commander": "11.0.0",
56
+ "contentful-management": "10.40.0",
57
+ "dotenv": "16.3.1",
58
58
  "ignore": "5.2.4",
59
- "inquirer": "8.2.5",
59
+ "inquirer": "8.2.6",
60
60
  "lodash": "4.17.21",
61
61
  "open": "8.4.2",
62
62
  "ora": "5.4.1"
63
63
  },
64
- "gitHead": "decd25e2e3c38482d6e636777f37de44fd49ab1c"
64
+ "gitHead": "e6ee977c9fc8db111bcd36c8caa1550f4829afb6"
65
65
  }
@@ -7,12 +7,15 @@ const DEFAULT_BUNDLES_TO_KEEP = 50;
7
7
  const DEFAULT_BUNDLES_TO_FETCH = 1000;
8
8
  const MAX_CONCURRENT_DELETION_CALLS = 5;
9
9
 
10
+ const DEFAULT_CONTENTFUL_API_HOST = 'api.contentful.com';
11
+
10
12
  module.exports = {
11
13
  DOTENV_FILE,
12
- DEFAULT_BUNDLES_TO_KEEP,
13
14
  ACCESS_TOKEN_ENV_KEY,
14
15
  ORG_ID_ENV_KEY,
15
16
  APP_DEF_ENV_KEY,
16
- MAX_CONCURRENT_DELETION_CALLS,
17
+ DEFAULT_BUNDLES_TO_KEEP,
17
18
  DEFAULT_BUNDLES_TO_FETCH,
19
+ MAX_CONCURRENT_DELETION_CALLS,
20
+ CONTENTFUL_API_HOST: DEFAULT_CONTENTFUL_API_HOST,
18
21
  };