contentful-export 7.20.0 → 7.21.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/dist/index.js CHANGED
@@ -170,7 +170,9 @@ function runContentfulExport(params) {
170
170
  return (0, _contentfulBatchLibs.writeErrorLogFile)(options.errorLogFile, errorLog).then(() => {
171
171
  const multiError = new Error('Errors occured');
172
172
  multiError.name = 'ContentfulMultiError';
173
- multiError.errors = errorLog;
173
+ Object.assign(multiError, {
174
+ errors: errorLog
175
+ });
174
176
  throw multiError;
175
177
  });
176
178
  }
@@ -8,7 +8,7 @@ var _contentfulBatchLibs = require("contentful-batch-libs");
8
8
  var _format = require("date-fns/format");
9
9
  var _path = require("path");
10
10
  var _querystring = _interopRequireDefault(require("querystring"));
11
- var _package = require("../package");
11
+ var _package = require("../package.json");
12
12
  var _headers = require("./utils/headers");
13
13
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
14
14
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
@@ -48,11 +48,6 @@ function parseOptions(params) {
48
48
  if (!options.managementToken) {
49
49
  throw new Error('The `managementToken` option is required.');
50
50
  }
51
- const proxySimpleExp = /.+:\d+/;
52
- const proxyAuthExp = /.+:.+@.+:\d+/;
53
- if (options.proxy && !(proxySimpleExp.test(options.proxy) || proxyAuthExp.test(options.proxy))) {
54
- throw new Error('Please provide the proxy config in the following format:\nhost:port or user:password@host:port');
55
- }
56
51
  options.startTime = new Date();
57
52
  options.contentFile = options.contentFile || `contentful-export-${options.spaceId}-${options.environmentId}-${(0, _format.format)(options.startTime, "yyyy-MM-dd'T'HH-mm-ss")}.json`;
58
53
  options.logFilePath = (0, _path.resolve)(options.exportDir, options.contentFile);
@@ -64,12 +59,19 @@ function parseOptions(params) {
64
59
 
65
60
  // Further processing
66
61
  options.accessToken = options.managementToken;
67
- if (typeof options.proxy === 'string') {
68
- options.proxy = (0, _contentfulBatchLibs.proxyStringToObject)(options.proxy);
69
- }
70
- if (!options.rawProxy && options.proxy) {
71
- options.httpsAgent = (0, _contentfulBatchLibs.agentFromProxy)(options.proxy);
72
- delete options.proxy;
62
+ if (options.proxy) {
63
+ if (typeof options.proxy === 'string') {
64
+ const proxySimpleExp = /.+:\d+/;
65
+ const proxyAuthExp = /.+:.+@.+:\d+/;
66
+ if (!(proxySimpleExp.test(options.proxy) || proxyAuthExp.test(options.proxy))) {
67
+ throw new Error('Please provide the proxy config in the following format:\nhost:port or user:password@host:port');
68
+ }
69
+ options.proxy = (0, _contentfulBatchLibs.proxyStringToObject)(options.proxy);
70
+ }
71
+ if (!options.rawProxy) {
72
+ options.httpsAgent = (0, _contentfulBatchLibs.agentFromProxy)(options.proxy);
73
+ delete options.proxy;
74
+ }
73
75
  }
74
76
  if (options.queryEntries && options.queryEntries.length > 0) {
75
77
  const querystr = options.queryEntries.join('&');
@@ -8,16 +8,24 @@ var _bluebird = _interopRequireDefault(require("bluebird"));
8
8
  var _contentfulBatchLibs = require("contentful-batch-libs");
9
9
  var _figures = _interopRequireDefault(require("figures"));
10
10
  var _fs = require("fs");
11
- var _nodeFetch = _interopRequireDefault(require("node-fetch"));
12
11
  var _path = _interopRequireDefault(require("path"));
13
12
  var _stream = require("stream");
14
13
  var _util = require("util");
15
14
  var _embargoedAssets = require("../utils/embargoedAssets");
15
+ var _axios = _interopRequireDefault(require("axios"));
16
16
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
17
17
  const streamPipeline = (0, _util.promisify)(_stream.pipeline);
18
+
19
+ /**
20
+ * @param {Object} options - The options for downloading the asset.
21
+ * @param {string} options.url - The URL of the asset to download.
22
+ * @param {string} options.directory - The directory where the asset should be saved.
23
+ * @param {import('axios').AxiosInstance} options.httpClient - The HTTP client to use for downloading the asset.
24
+ */
18
25
  async function downloadAsset({
19
26
  url,
20
- directory
27
+ directory,
28
+ httpClient
21
29
  }) {
22
30
  // handle urls without protocol
23
31
  if (url.startsWith('//')) {
@@ -33,22 +41,35 @@ async function downloadAsset({
33
41
  recursive: true
34
42
  });
35
43
  const file = (0, _fs.createWriteStream)(localFile);
44
+ try {
45
+ // download asset
46
+ const assetRequest = await httpClient.get(url, {
47
+ responseType: 'blob'
48
+ });
36
49
 
37
- // download asset
38
- const assetRequest = await (0, _nodeFetch.default)(url);
39
- if (!assetRequest.ok) {
40
- throw new Error(`error response status: ${assetRequest.status}`);
50
+ // Wait for stream to be consumed before returning local file
51
+ await streamPipeline(assetRequest.data, file);
52
+ return localFile;
53
+ } catch (e) {
54
+ /**
55
+ * @type {import('axios').AxiosError}
56
+ */
57
+ const axiosError = e;
58
+ throw new Error(`error response status: ${axiosError.response.status}`);
41
59
  }
42
-
43
- // Wait for stream to be consumed before returning local file
44
- await streamPipeline(assetRequest.body, file);
45
- return localFile;
46
60
  }
47
61
  function downloadAssets(options) {
48
62
  return (ctx, task) => {
49
63
  let successCount = 0;
50
64
  let warningCount = 0;
51
65
  let errorCount = 0;
66
+ const httpClient = _axios.default.create({
67
+ headers: options.headers,
68
+ timeout: options.timeout,
69
+ httpAgent: options.httpAgent,
70
+ httpsAgent: options.httpsAgent,
71
+ proxy: options.proxy
72
+ });
52
73
  return _bluebird.default.map(ctx.data.assets, asset => {
53
74
  if (!asset.fields.file) {
54
75
  task.output = `${_figures.default.warning} asset ${(0, _contentfulBatchLibs.getEntityName)(asset)} has no file(s)`;
@@ -65,7 +86,8 @@ function downloadAssets(options) {
65
86
  }
66
87
  let startingPromise = _bluebird.default.resolve({
67
88
  url,
68
- directory: options.exportDir
89
+ directory: options.exportDir,
90
+ httpClient
69
91
  });
70
92
  if ((0, _embargoedAssets.isEmbargoedAsset)(url)) {
71
93
  const {
@@ -75,9 +97,10 @@ function downloadAssets(options) {
75
97
  environmentId
76
98
  } = options;
77
99
  const expiresAtMs = (0, _embargoedAssets.calculateExpiryTimestamp)();
78
- startingPromise = (0, _embargoedAssets.signUrl)(host, accessToken, spaceId, environmentId, url, expiresAtMs).then(signedUrl => ({
100
+ startingPromise = (0, _embargoedAssets.signUrl)(host, accessToken, spaceId, environmentId, url, expiresAtMs, httpClient).then(signedUrl => ({
79
101
  url: signedUrl,
80
- directory: options.exportDir
102
+ directory: options.exportDir,
103
+ httpClient
81
104
  }));
82
105
  }
83
106
  return startingPromise.then(downloadAsset).then(downLoadedFile => {
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
  var _yargs = _interopRequireDefault(require("yargs"));
8
- var _package = _interopRequireDefault(require("../package"));
8
+ var _package = _interopRequireDefault(require("../package.json"));
9
9
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
10
10
  var _default = exports.default = _yargs.default.version(_package.default.version || 'Version only available on installed package').usage('Usage: $0 [options]').option('space-id', {
11
11
  describe: 'ID of Space with source data',
@@ -8,14 +8,22 @@ exports.isEmbargoedAsset = isEmbargoedAsset;
8
8
  exports.shouldCreateNewCacheItem = void 0;
9
9
  exports.signUrl = signUrl;
10
10
  var _jsonwebtoken = _interopRequireDefault(require("jsonwebtoken"));
11
- var _nodeFetch = _interopRequireDefault(require("node-fetch"));
12
11
  function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
12
  const SIX_HOURS_IN_MS = 6 * 60 * 60 * 1000;
14
13
  const assetKeyCache = new Map();
15
- function createAssetKey(host, accessToken, spaceId, environmentId, expiresAtMs) {
16
- return (0, _nodeFetch.default)(`https://${host}/spaces/${spaceId}/environments/${environmentId}/asset_keys`, {
14
+
15
+ /**
16
+ * @param {string} host - The Contentful API host.
17
+ * @param {string} accessToken - The access token for the Contentful API.
18
+ * @param {string} spaceId - The ID of the Contentful space.
19
+ * @param {string} environmentId - The ID of the Contentful environment.
20
+ * @param {number} expiresAtMs - The expiration time in milliseconds.
21
+ * @param {import('axios').AxiosInstance} httpClient - The HTTP client to use for requests.
22
+ */
23
+ function createAssetKey(host, accessToken, spaceId, environmentId, expiresAtMs, httpClient) {
24
+ return httpClient(`https://${host}/spaces/${spaceId}/environments/${environmentId}/asset_keys`, {
17
25
  method: 'POST',
18
- body: JSON.stringify({
26
+ data: JSON.stringify({
19
27
  expiresAt: Math.floor(expiresAtMs / 1000) // in seconds
20
28
  }),
21
29
  headers: {
@@ -26,7 +34,7 @@ function createAssetKey(host, accessToken, spaceId, environmentId, expiresAtMs)
26
34
  }
27
35
  const shouldCreateNewCacheItem = (cacheItem, currentExpiresAtMs) => !cacheItem || currentExpiresAtMs - cacheItem.expiresAtMs > SIX_HOURS_IN_MS;
28
36
  exports.shouldCreateNewCacheItem = shouldCreateNewCacheItem;
29
- async function createCachedAssetKey(host, accessToken, spaceId, environmentId, minExpiresAtMs) {
37
+ async function createCachedAssetKey(host, accessToken, spaceId, environmentId, minExpiresAtMs, httpClient) {
30
38
  const cacheKey = `${host}:${spaceId}:${environmentId}`;
31
39
  let cacheItem = assetKeyCache.get(cacheKey);
32
40
  if (shouldCreateNewCacheItem(cacheItem, minExpiresAtMs)) {
@@ -35,12 +43,10 @@ async function createCachedAssetKey(host, accessToken, spaceId, environmentId, m
35
43
  throw new Error(`Cannot fetch an asset key so far in the future: ${minExpiresAtMs} > ${expiresAtMs}`);
36
44
  }
37
45
  try {
38
- const assetKeyPromise = createAssetKey(host, accessToken, spaceId, environmentId, expiresAtMs);
39
- const resolvedAssetKeyPromise = await assetKeyPromise;
40
- const result = await resolvedAssetKeyPromise.json();
46
+ const assetKeyResponse = await createAssetKey(host, accessToken, spaceId, environmentId, expiresAtMs, httpClient);
41
47
  cacheItem = {
42
48
  expiresAtMs,
43
- result
49
+ result: assetKeyResponse.data
44
50
  };
45
51
  assetKeyCache.set(cacheKey, cacheItem);
46
52
  } catch (err) {
@@ -79,12 +85,22 @@ function isEmbargoedAsset(url) {
79
85
  function calculateExpiryTimestamp() {
80
86
  return Date.now() + SIX_HOURS_IN_MS;
81
87
  }
82
- function signUrl(host, accessToken, spaceId, environmentId, url, expiresAtMs) {
88
+
89
+ /**
90
+ * @param {string} host - The Contentful API host.
91
+ * @param {string} accessToken - The access token for the Contentful API.
92
+ * @param {string} spaceId - The ID of the Contentful space.
93
+ * @param {string} environmentId - The ID of the Contentful environment.
94
+ * @param {string} url - The URL to be signed.
95
+ * @param {number} expiresAtMs - The expiration time in milliseconds.
96
+ * @param {import('axios').AxiosInstance} httpClient - The HTTP client to use for requests.
97
+ */
98
+ function signUrl(host, accessToken, spaceId, environmentId, url, expiresAtMs, httpClient) {
83
99
  // handle urls without protocol
84
100
  if (url.startsWith('//')) {
85
101
  url = 'https:' + url;
86
102
  }
87
- return createCachedAssetKey(host, accessToken, spaceId, environmentId, expiresAtMs).then(({
103
+ return createCachedAssetKey(host, accessToken, spaceId, environmentId, expiresAtMs, httpClient).then(({
88
104
  policy,
89
105
  secret
90
106
  }) => generateSignedUrl(policy, secret, url, expiresAtMs));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "contentful-export",
3
- "version": "7.20.0",
3
+ "version": "7.21.0",
4
4
  "description": "this tool allows you to export a space to a JSON dump",
5
5
  "main": "dist/index.js",
6
6
  "types": "types.d.ts",
@@ -11,8 +11,9 @@
11
11
  "contentful-export": "./bin/contentful-export"
12
12
  },
13
13
  "scripts": {
14
- "build": "npm run clean && babel lib --out-dir dist",
14
+ "build": "npm run clean && npm run check && babel lib --out-dir dist",
15
15
  "build:watch": "babel lib --out-dir dist --watch",
16
+ "check": "tsc",
16
17
  "clean": "rimraf dist && rimraf coverage",
17
18
  "lint": "eslint lib bin/* types.d.ts",
18
19
  "lint:fix": "npm run lint -- --fix",
@@ -44,6 +45,7 @@
44
45
  "url": "https://github.com/contentful/contentful-export/issues"
45
46
  },
46
47
  "dependencies": {
48
+ "axios": "^1.7.8",
47
49
  "bfj": "^8.0.0",
48
50
  "bluebird": "^3.3.3",
49
51
  "cli-table3": "^0.6.0",
@@ -58,7 +60,6 @@
58
60
  "listr-verbose-renderer": "^0.6.0",
59
61
  "lodash.startcase": "^4.4.0",
60
62
  "mkdirp": "^2.0.0",
61
- "node-fetch": "^2.6.7",
62
63
  "yargs": "^17.1.1"
63
64
  },
64
65
  "devDependencies": {
@@ -136,5 +137,8 @@
136
137
  "coveragePathIgnorePatterns": [
137
138
  "usageParams.js"
138
139
  ]
140
+ },
141
+ "overrides": {
142
+ "cross-spawn": "^7.0.6"
139
143
  }
140
144
  }