@sanity/export 2.33.4-performance-opts.16 → 3.0.0-canary.186

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/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "@sanity/export",
3
- "version": "2.33.4-performance-opts.16+6acb5be7ec",
3
+ "version": "3.0.0-canary.186+7aff92534",
4
4
  "description": "Export Sanity documents and assets",
5
- "main": "lib/export.js",
5
+ "main": "./src/export.js",
6
+ "files": [
7
+ "src"
8
+ ],
6
9
  "engines": {
7
- "node": ">=12.0.0"
10
+ "node": ">=14.0.0"
8
11
  },
9
12
  "author": "Sanity.io <hello@sanity.io>",
10
13
  "license": "MIT",
11
14
  "scripts": {
12
- "build": "babel src --copy-files --out-dir lib",
13
- "clean": "rimraf lib dest",
14
- "prebuild": "npm run clean",
15
15
  "test": "jest"
16
16
  },
17
17
  "keywords": [
@@ -26,15 +26,14 @@
26
26
  "dependencies": {
27
27
  "archiver": "^5.0.0",
28
28
  "debug": "^3.2.7",
29
- "fs-extra": "^7.0.0",
30
29
  "get-it": "^5.2.1",
31
- "lodash": "^4.17.15",
30
+ "lodash": "^4.17.21",
32
31
  "mississippi": "^4.0.0",
33
32
  "p-queue": "^2.3.0",
33
+ "rimraf": "^3.0.2",
34
34
  "split2": "^3.2.2"
35
35
  },
36
36
  "devDependencies": {
37
- "rimraf": "^2.7.1",
38
37
  "string-to-stream": "^1.1.0"
39
38
  },
40
39
  "publishConfig": {
@@ -49,5 +48,5 @@
49
48
  "url": "https://github.com/sanity-io/sanity/issues"
50
49
  },
51
50
  "homepage": "https://www.sanity.io/",
52
- "gitHead": "6acb5be7ec060806773c41c9b015f318e2fbfbd9"
51
+ "gitHead": "7aff92534da0e74236f647102792b896001346aa"
53
52
  }
@@ -1,13 +1,14 @@
1
1
  const path = require('path')
2
2
  const crypto = require('crypto')
3
3
  const {parse: parseUrl, format: formatUrl} = require('url')
4
- const fse = require('fs-extra')
4
+ const {mkdirSync, createWriteStream} = require('fs')
5
5
  const miss = require('mississippi')
6
6
  const PQueue = require('p-queue')
7
7
  const {omit, noop} = require('lodash')
8
8
  const pkg = require('../package.json')
9
9
  const requestStream = require('./requestStream')
10
10
  const debug = require('./debug')
11
+ const rimraf = require('./util/rimraf')
11
12
 
12
13
  const EXCLUDE_PROPS = ['_id', '_type', 'assetId', 'extension', 'mimeType', 'path', 'url']
13
14
  const ACTION_REMOVE = 'remove'
@@ -112,8 +113,8 @@ class AssetHandler {
112
113
  }
113
114
 
114
115
  /* eslint-disable no-sync */
115
- fse.ensureDirSync(path.join(this.tmpDir, 'files'))
116
- fse.ensureDirSync(path.join(this.tmpDir, 'images'))
116
+ mkdirSync(path.join(this.tmpDir, 'files'), {recursive: true})
117
+ mkdirSync(path.join(this.tmpDir, 'images'), {recursive: true})
117
118
  /* eslint-enable no-sync */
118
119
  this.assetDirsCreated = true
119
120
  }
@@ -195,7 +196,7 @@ class AssetHandler {
195
196
 
196
197
  const detailsString = `Details:\n - ${details.filter(Boolean).join('\n - ')}`
197
198
 
198
- await fse.unlink(tmpPath)
199
+ await rimraf(tmpPath)
199
200
  this.queue.clear()
200
201
 
201
202
  const error = new Error(
@@ -306,7 +307,7 @@ function writeHashedStream(filePath, stream) {
306
307
  })
307
308
 
308
309
  return new Promise((resolve, reject) =>
309
- miss.pipe(stream, hasher, fse.createWriteStream(filePath), (err) => {
310
+ miss.pipe(stream, hasher, createWriteStream(filePath), (err) => {
310
311
  if (err) {
311
312
  reject(err)
312
313
  return
package/src/export.js CHANGED
@@ -1,10 +1,11 @@
1
1
  const os = require('os')
2
2
  const path = require('path')
3
3
  const zlib = require('zlib')
4
- const fse = require('fs-extra')
4
+ const fs = require('fs')
5
5
  const miss = require('mississippi')
6
6
  const split = require('split2')
7
7
  const archiver = require('archiver')
8
+ const rimraf = require('./util/rimraf')
8
9
  const debug = require('./debug')
9
10
  const AssetHandler = require('./AssetHandler')
10
11
  const stringifyStream = require('./stringifyStream')
@@ -35,7 +36,7 @@ function exportDataset(opts) {
35
36
  const prefix = `${opts.dataset}-export-${slugDate}`
36
37
  const tmpDir = path.join(os.tmpdir(), prefix)
37
38
  const cleanup = () =>
38
- fse.remove(tmpDir).catch((err) => {
39
+ rimraf(tmpDir).catch((err) => {
39
40
  debug(`Error while cleaning up temporary files: ${err.message}`)
40
41
  })
41
42
 
@@ -54,7 +55,7 @@ function exportDataset(opts) {
54
55
  outputStream = options.outputPath
55
56
  } else {
56
57
  outputStream =
57
- options.outputPath === '-' ? process.stdout : fse.createWriteStream(options.outputPath)
58
+ options.outputPath === '-' ? process.stdout : fs.createWriteStream(options.outputPath)
58
59
  }
59
60
 
60
61
  let assetStreamHandler = assetHandler.noop
@@ -0,0 +1,4 @@
1
+ const {promisify} = require('util')
2
+ const rimrafCb = require('rimraf')
3
+
4
+ module.exports = promisify(rimrafCb)
package/jest.config.js DELETED
@@ -1,6 +0,0 @@
1
- const createConfig = require('../../../createJestConfig')
2
-
3
- module.exports = createConfig({
4
- displayName: require('./package.json').name,
5
- testEnvironment: 'node',
6
- })
@@ -1,407 +0,0 @@
1
- "use strict";
2
-
3
- var _excluded = ["asset"];
4
-
5
- function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
6
-
7
- function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
8
-
9
- function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
10
-
11
- function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
12
-
13
- function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"]; if (_i == null) return; var _arr = []; var _n = true; var _d = false; var _s, _e; try { for (_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
14
-
15
- function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
16
-
17
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
18
-
19
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
20
-
21
- function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
22
-
23
- function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
24
-
25
- function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
26
-
27
- function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
28
-
29
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
30
-
31
- var path = require('path');
32
-
33
- var crypto = require('crypto');
34
-
35
- var _require = require('url'),
36
- parseUrl = _require.parse,
37
- formatUrl = _require.format;
38
-
39
- var fse = require('fs-extra');
40
-
41
- var miss = require('mississippi');
42
-
43
- var PQueue = require('p-queue');
44
-
45
- var _require2 = require('lodash'),
46
- omit = _require2.omit,
47
- noop = _require2.noop;
48
-
49
- var pkg = require('../package.json');
50
-
51
- var requestStream = require('./requestStream');
52
-
53
- var debug = require('./debug');
54
-
55
- var EXCLUDE_PROPS = ['_id', '_type', 'assetId', 'extension', 'mimeType', 'path', 'url'];
56
- var ACTION_REMOVE = 'remove';
57
- var ACTION_REWRITE = 'rewrite';
58
- var ASSET_DOWNLOAD_CONCURRENCY = 8;
59
-
60
- class AssetHandler {
61
- constructor(options) {
62
- var _this = this;
63
-
64
- _defineProperty(this, "rewriteAssets", miss.through.obj( /*#__PURE__*/function () {
65
- var _ref = _asyncToGenerator(function* (doc, enc, callback) {
66
- if (['sanity.imageAsset', 'sanity.fileAsset'].includes(doc._type)) {
67
- var type = doc._type === 'sanity.imageAsset' ? 'image' : 'file';
68
- var filePath = "".concat(type, "s/").concat(generateFilename(doc._id));
69
-
70
- _this.assetsSeen.set(doc._id, type);
71
-
72
- _this.queueAssetDownload(doc, filePath, type);
73
-
74
- callback();
75
- return;
76
- }
77
-
78
- callback(null, _this.findAndModify(doc, ACTION_REWRITE));
79
- });
80
-
81
- return function (_x, _x2, _x3) {
82
- return _ref.apply(this, arguments);
83
- };
84
- }()));
85
-
86
- _defineProperty(this, "stripAssets", miss.through.obj( /*#__PURE__*/function () {
87
- var _ref2 = _asyncToGenerator(function* (doc, enc, callback) {
88
- if (['sanity.imageAsset', 'sanity.fileAsset'].includes(doc._type)) {
89
- callback();
90
- return;
91
- }
92
-
93
- callback(null, _this.findAndModify(doc, ACTION_REMOVE));
94
- });
95
-
96
- return function (_x4, _x5, _x6) {
97
- return _ref2.apply(this, arguments);
98
- };
99
- }()));
100
-
101
- _defineProperty(this, "skipAssets", miss.through.obj((doc, enc, callback) => {
102
- var isAsset = ['sanity.imageAsset', 'sanity.fileAsset'].includes(doc._type);
103
-
104
- if (isAsset) {
105
- callback();
106
- return;
107
- }
108
-
109
- callback(null, doc);
110
- }));
111
-
112
- _defineProperty(this, "noop", miss.through.obj((doc, enc, callback) => callback(null, doc)));
113
-
114
- _defineProperty(this, "findAndModify", (item, action) => {
115
- if (Array.isArray(item)) {
116
- var children = item.map(child => this.findAndModify(child, action));
117
- return children.filter(Boolean);
118
- }
119
-
120
- if (!item || typeof item !== 'object') {
121
- return item;
122
- }
123
-
124
- var isAsset = isAssetField(item);
125
-
126
- if (isAsset && action === ACTION_REMOVE) {
127
- return undefined;
128
- }
129
-
130
- if (isAsset && action === ACTION_REWRITE) {
131
- var asset = item.asset,
132
- other = _objectWithoutProperties(item, _excluded);
133
-
134
- var assetId = asset._ref;
135
- var assetType = getAssetType(item);
136
- var filePath = "".concat(assetType, "s/").concat(generateFilename(assetId));
137
- return _objectSpread({
138
- _sanityAsset: "".concat(assetType, "@file://./").concat(filePath)
139
- }, this.findAndModify(other, action));
140
- }
141
-
142
- var newItem = {};
143
- var keys = Object.keys(item);
144
-
145
- for (var i = 0; i < keys.length; i++) {
146
- var key = keys[i];
147
- var value = item[key];
148
- newItem[key] = this.findAndModify(value, action);
149
-
150
- if (typeof newItem[key] === 'undefined') {
151
- delete newItem[key];
152
- }
153
- }
154
-
155
- return newItem;
156
- });
157
-
158
- var concurrency = options.concurrency || ASSET_DOWNLOAD_CONCURRENCY;
159
- debug('Using asset download concurrency of %d', concurrency);
160
- this.client = options.client;
161
- this.tmpDir = options.tmpDir;
162
- this.assetDirsCreated = false;
163
- this.downloading = [];
164
- this.assetsSeen = new Map();
165
- this.assetMap = {};
166
- this.filesWritten = 0;
167
- this.queueSize = 0;
168
- this.queue = options.queue || new PQueue({
169
- concurrency
170
- });
171
- this.rejectedError = null;
172
-
173
- this.reject = err => {
174
- this.rejectedError = err;
175
- };
176
- }
177
-
178
- clear() {
179
- this.assetsSeen.clear();
180
- this.queue.clear();
181
- this.queueSize = 0;
182
- }
183
-
184
- finish() {
185
- return new Promise((resolve, reject) => {
186
- if (this.rejectedError) {
187
- reject(this.rejectedError);
188
- return;
189
- }
190
-
191
- this.reject = reject;
192
- this.queue.onIdle().then(() => resolve(this.assetMap));
193
- });
194
- } // Called when we want to download all assets to local filesystem and rewrite documents to hold
195
- // placeholder asset references (_sanityAsset: 'image@file:///local/path')
196
-
197
-
198
- queueAssetDownload(assetDoc, dstPath, type) {
199
- if (!assetDoc.url) {
200
- debug('Asset document "%s" does not have a URL property, skipping', assetDoc._id);
201
- return;
202
- }
203
-
204
- debug('Adding download task for %s (destination: %s)', assetDoc._id, dstPath);
205
- this.queueSize++;
206
- this.downloading.push(assetDoc.url);
207
- this.queue.add(() => this.downloadAsset(assetDoc, dstPath));
208
- }
209
-
210
- maybeCreateAssetDirs() {
211
- if (this.assetDirsCreated) {
212
- return;
213
- }
214
- /* eslint-disable no-sync */
215
-
216
-
217
- fse.ensureDirSync(path.join(this.tmpDir, 'files'));
218
- fse.ensureDirSync(path.join(this.tmpDir, 'images'));
219
- /* eslint-enable no-sync */
220
-
221
- this.assetDirsCreated = true;
222
- }
223
-
224
- getAssetRequestOptions(assetDoc) {
225
- var token = this.client.config().token;
226
- var headers = {
227
- 'User-Agent': "".concat(pkg.name, "@").concat(pkg.version)
228
- };
229
- var isImage = assetDoc._type === 'sanity.imageAsset';
230
- var url = parseUrl(assetDoc.url, true);
231
-
232
- if (isImage && ['cdn.sanity.io', 'cdn.sanity.work'].includes(url.hostname) && token) {
233
- headers.Authorization = "Bearer ".concat(token);
234
- url.query = _objectSpread(_objectSpread({}, url.query || {}), {}, {
235
- dlRaw: 'true'
236
- });
237
- }
238
-
239
- return {
240
- url: formatUrl(url),
241
- headers
242
- };
243
- }
244
-
245
- downloadAsset(assetDoc, dstPath) {
246
- var _arguments = arguments,
247
- _this2 = this;
248
-
249
- return _asyncToGenerator(function* () {
250
- var attemptNum = _arguments.length > 2 && _arguments[2] !== undefined ? _arguments[2] : 0;
251
- var url = assetDoc.url;
252
-
253
- var options = _this2.getAssetRequestOptions(assetDoc);
254
-
255
- var stream;
256
-
257
- try {
258
- stream = yield requestStream(options);
259
- } catch (err) {
260
- _this2.reject(err);
261
-
262
- return false;
263
- }
264
-
265
- if (stream.statusCode !== 200) {
266
- _this2.queue.clear();
267
-
268
- var err = yield tryGetErrorFromStream(stream);
269
- var errMsg = "Referenced asset URL \"".concat(url, "\" returned HTTP ").concat(stream.statusCode);
270
-
271
- if (err) {
272
- errMsg = "".concat(errMsg, ":\n\n").concat(err);
273
- }
274
-
275
- _this2.reject(new Error(errMsg));
276
-
277
- return false;
278
- }
279
-
280
- _this2.maybeCreateAssetDirs();
281
-
282
- debug('Asset stream ready, writing to filesystem at %s', dstPath);
283
- var tmpPath = path.join(_this2.tmpDir, dstPath);
284
-
285
- var _yield$writeHashedStr = yield writeHashedStream(tmpPath, stream),
286
- sha1 = _yield$writeHashedStr.sha1,
287
- md5 = _yield$writeHashedStr.md5,
288
- size = _yield$writeHashedStr.size; // Verify it against our downloaded stream to make sure we have the same copy
289
-
290
-
291
- var contentLength = stream.headers['content-length'];
292
- var remoteSha1 = stream.headers['x-sanity-sha1'];
293
- var remoteMd5 = stream.headers['x-sanity-md5'];
294
- var hasHash = Boolean(remoteSha1 || remoteMd5);
295
- var method = sha1 ? 'sha1' : 'md5'; // Asset validity is primarily determined by the sha1 hash. However, the sha1 hash is computed
296
- // before certain processes (i.e. svg sanitization) which can result in a different hash.
297
- // When the sha1 hashes don't match, fallback to using the md5 hash.
298
-
299
- var sha1Differs = remoteSha1 && sha1 !== remoteSha1;
300
- var md5Differs = remoteMd5 && md5 !== remoteMd5;
301
- var differs = sha1Differs && md5Differs;
302
-
303
- if (differs && attemptNum < 3) {
304
- debug('%s does not match downloaded asset, retrying (#%d) [%s]', method, attemptNum + 1, url);
305
- return _this2.downloadAsset(assetDoc, dstPath, attemptNum + 1);
306
- } else if (differs) {
307
- var details = [hasHash && (method === 'md5' ? "md5 should be ".concat(remoteMd5, ", got ").concat(md5) : "sha1 should be ".concat(remoteSha1, ", got ").concat(sha1)), contentLength && parseInt(contentLength, 10) !== size && "Asset should be ".concat(contentLength, " bytes, got ").concat(size), "Did not succeed after ".concat(attemptNum, " attempts.")];
308
- var detailsString = "Details:\n - ".concat(details.filter(Boolean).join('\n - '));
309
- yield fse.unlink(tmpPath);
310
-
311
- _this2.queue.clear();
312
-
313
- var error = new Error("Failed to download asset at ".concat(assetDoc.url, ", giving up. ").concat(detailsString));
314
-
315
- _this2.reject(error);
316
-
317
- return false;
318
- }
319
-
320
- var isImage = assetDoc._type === 'sanity.imageAsset';
321
- var type = isImage ? 'image' : 'file';
322
- var id = "".concat(type, "-").concat(sha1);
323
- var metaProps = omit(assetDoc, EXCLUDE_PROPS);
324
-
325
- if (Object.keys(metaProps).length > 0) {
326
- _this2.assetMap[id] = metaProps;
327
- }
328
-
329
- _this2.downloading.splice(_this2.downloading.findIndex(datUrl => datUrl === url), 1);
330
-
331
- _this2.filesWritten++;
332
- return true;
333
- })();
334
- }
335
-
336
- }
337
-
338
- function isAssetField(item) {
339
- return item.asset && item.asset._ref && isSanityAsset(item.asset._ref);
340
- }
341
-
342
- function getAssetType(item) {
343
- if (!item.asset || typeof item.asset._ref !== 'string') {
344
- return null;
345
- }
346
-
347
- var _ref3 = item.asset._ref.match(/^(image|file)-/) || [],
348
- _ref4 = _slicedToArray(_ref3, 2),
349
- type = _ref4[1];
350
-
351
- return type || null;
352
- }
353
-
354
- function isSanityAsset(assetId) {
355
- return /^image-[a-f0-9]{40}-\d+x\d+-[a-z]+$/.test(assetId) || /^file-[a-f0-9]{40}-[a-z0-9]+$/.test(assetId);
356
- }
357
-
358
- function generateFilename(assetId) {
359
- var _ref5 = assetId.match(/^(image|file)-(.*?)(-[a-z]+)?$/) || [],
360
- _ref6 = _slicedToArray(_ref5, 4),
361
- asset = _ref6[2],
362
- ext = _ref6[3];
363
-
364
- var extension = (ext || 'bin').replace(/^-/, '');
365
- return asset ? "".concat(asset, ".").concat(extension) : "".concat(assetId, ".bin");
366
- }
367
-
368
- function writeHashedStream(filePath, stream) {
369
- var size = 0;
370
- var md5 = crypto.createHash('md5');
371
- var sha1 = crypto.createHash('sha1');
372
- var hasher = miss.through((chunk, enc, cb) => {
373
- size += chunk.length;
374
- md5.update(chunk);
375
- sha1.update(chunk);
376
- cb(null, chunk);
377
- });
378
- return new Promise((resolve, reject) => miss.pipe(stream, hasher, fse.createWriteStream(filePath), err => {
379
- if (err) {
380
- reject(err);
381
- return;
382
- }
383
-
384
- resolve({
385
- size,
386
- sha1: sha1.digest('hex'),
387
- md5: md5.digest('hex')
388
- });
389
- }));
390
- }
391
-
392
- function tryGetErrorFromStream(stream) {
393
- return new Promise((resolve, reject) => {
394
- miss.pipe(stream, miss.concat(parse), err => err ? reject(err) : noop);
395
-
396
- function parse(body) {
397
- try {
398
- var parsed = JSON.parse(body.toString('utf8'));
399
- resolve(parsed.message || parsed.error || null);
400
- } catch (err) {
401
- resolve(body.toString('utf8').slice(0, 16000));
402
- }
403
- }
404
- });
405
- }
406
-
407
- module.exports = AssetHandler;
package/lib/debug.js DELETED
@@ -1,3 +0,0 @@
1
- "use strict";
2
-
3
- module.exports = require('debug')('sanity:export');
package/lib/export.js DELETED
@@ -1,249 +0,0 @@
1
- "use strict";
2
-
3
- function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
4
-
5
- function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
6
-
7
- var os = require('os');
8
-
9
- var path = require('path');
10
-
11
- var zlib = require('zlib');
12
-
13
- var fse = require('fs-extra');
14
-
15
- var miss = require('mississippi');
16
-
17
- var split = require('split2');
18
-
19
- var archiver = require('archiver');
20
-
21
- var debug = require('./debug');
22
-
23
- var AssetHandler = require('./AssetHandler');
24
-
25
- var stringifyStream = require('./stringifyStream');
26
-
27
- var validateOptions = require('./validateOptions');
28
-
29
- var rejectOnApiError = require('./rejectOnApiError');
30
-
31
- var getDocumentsStream = require('./getDocumentsStream');
32
-
33
- var filterSystemDocuments = require('./filterSystemDocuments');
34
-
35
- var filterDocumentTypes = require('./filterDocumentTypes');
36
-
37
- var filterDrafts = require('./filterDrafts');
38
-
39
- var logFirstChunk = require('./logFirstChunk');
40
-
41
- var tryParseJson = require('./tryParseJson');
42
-
43
- var noop = () => null;
44
-
45
- function exportDataset(opts) {
46
- var options = validateOptions(opts);
47
- var onProgress = options.onProgress || noop;
48
- var archive = archiver('tar', {
49
- gzip: true,
50
- gzipOptions: {
51
- level: options.compress ? zlib.Z_DEFAULT_COMPRESSION : zlib.Z_NO_COMPRESSION
52
- }
53
- });
54
- var slugDate = new Date().toISOString().replace(/[^a-z0-9]/gi, '-').toLowerCase();
55
- var prefix = "".concat(opts.dataset, "-export-").concat(slugDate);
56
- var tmpDir = path.join(os.tmpdir(), prefix);
57
-
58
- var cleanup = () => fse.remove(tmpDir).catch(err => {
59
- debug("Error while cleaning up temporary files: ".concat(err.message));
60
- });
61
-
62
- var assetHandler = new AssetHandler({
63
- client: options.client,
64
- tmpDir,
65
- prefix,
66
- concurrency: options.assetConcurrency
67
- });
68
- debug('Outputting assets (temporarily) to %s', tmpDir);
69
- debug('Outputting to %s', options.outputPath === '-' ? 'stdout' : options.outputPath);
70
- var outputStream;
71
-
72
- if (isWritableStream(options.outputPath)) {
73
- outputStream = options.outputPath;
74
- } else {
75
- outputStream = options.outputPath === '-' ? process.stdout : fse.createWriteStream(options.outputPath);
76
- }
77
-
78
- var assetStreamHandler = assetHandler.noop;
79
-
80
- if (!options.raw) {
81
- assetStreamHandler = options.assets ? assetHandler.rewriteAssets : assetHandler.stripAssets;
82
- }
83
-
84
- return new Promise( /*#__PURE__*/function () {
85
- var _ref = _asyncToGenerator(function* (resolve, reject) {
86
- miss.finished(archive, /*#__PURE__*/function () {
87
- var _ref2 = _asyncToGenerator(function* (archiveErr) {
88
- if (archiveErr) {
89
- debug('Archiving errored! %s', archiveErr.stack);
90
- yield cleanup();
91
- reject(archiveErr);
92
- return;
93
- }
94
-
95
- debug('Archive finished!');
96
- });
97
-
98
- return function (_x3) {
99
- return _ref2.apply(this, arguments);
100
- };
101
- }());
102
- debug('Getting dataset export stream');
103
- onProgress({
104
- step: 'Exporting documents...'
105
- });
106
- var documentCount = 0;
107
- var lastReported = Date.now();
108
-
109
- var reportDocumentCount = (chunk, enc, cb) => {
110
- ++documentCount;
111
- var now = Date.now();
112
-
113
- if (now - lastReported > 50) {
114
- onProgress({
115
- step: 'Exporting documents...',
116
- current: documentCount,
117
- total: '?',
118
- update: true
119
- });
120
- lastReported = now;
121
- }
122
-
123
- cb(null, chunk);
124
- };
125
-
126
- var inputStream = yield getDocumentsStream(options.client, options.dataset);
127
- debug('Got HTTP %d', inputStream.statusCode);
128
- debug('Response headers: %o', inputStream.headers);
129
- var jsonStream = miss.pipeline(inputStream, logFirstChunk(), split(tryParseJson), rejectOnApiError(), filterSystemDocuments(), assetStreamHandler, filterDocumentTypes(options.types), options.drafts ? miss.through.obj() : filterDrafts(), stringifyStream(), miss.through(reportDocumentCount));
130
- miss.finished(jsonStream, /*#__PURE__*/function () {
131
- var _ref3 = _asyncToGenerator(function* (err) {
132
- if (err) {
133
- return;
134
- }
135
-
136
- onProgress({
137
- step: 'Exporting documents...',
138
- current: documentCount,
139
- total: documentCount,
140
- update: true
141
- });
142
-
143
- if (!options.raw && options.assets) {
144
- onProgress({
145
- step: 'Downloading assets...'
146
- });
147
- }
148
-
149
- var prevCompleted = 0;
150
- var progressInterval = setInterval(() => {
151
- var completed = assetHandler.queueSize - assetHandler.queue.size - assetHandler.queue.pending;
152
-
153
- if (prevCompleted === completed) {
154
- return;
155
- }
156
-
157
- prevCompleted = completed;
158
- onProgress({
159
- step: 'Downloading assets...',
160
- current: completed,
161
- total: assetHandler.queueSize,
162
- update: true
163
- });
164
- }, 500);
165
- debug('Waiting for asset handler to complete downloads');
166
-
167
- try {
168
- var assetMap = yield assetHandler.finish(); // Make sure we mark the progress as done (eg 100/100 instead of 99/100)
169
-
170
- onProgress({
171
- step: 'Downloading assets...',
172
- current: assetHandler.queueSize,
173
- total: assetHandler.queueSize,
174
- update: true
175
- });
176
- archive.append(JSON.stringify(assetMap), {
177
- name: 'assets.json',
178
- prefix
179
- });
180
- clearInterval(progressInterval);
181
- } catch (assetErr) {
182
- clearInterval(progressInterval);
183
- yield cleanup();
184
- reject(assetErr);
185
- return;
186
- } // Add all downloaded assets to archive
187
-
188
-
189
- archive.directory(path.join(tmpDir, 'files'), "".concat(prefix, "/files"), {
190
- store: true
191
- });
192
- archive.directory(path.join(tmpDir, 'images'), "".concat(prefix, "/images"), {
193
- store: true
194
- });
195
- debug('Finalizing archive, flushing streams');
196
- onProgress({
197
- step: 'Adding assets to archive...'
198
- });
199
- archive.finalize();
200
- });
201
-
202
- return function (_x4) {
203
- return _ref3.apply(this, arguments);
204
- };
205
- }());
206
- archive.on('warning', err => {
207
- debug('Archive warning: %s', err.message);
208
- });
209
- archive.append(jsonStream, {
210
- name: 'data.ndjson',
211
- prefix
212
- });
213
- miss.pipe(archive, outputStream, onComplete);
214
-
215
- function onComplete(_x5) {
216
- return _onComplete.apply(this, arguments);
217
- }
218
-
219
- function _onComplete() {
220
- _onComplete = _asyncToGenerator(function* (err) {
221
- onProgress({
222
- step: 'Clearing temporary files...'
223
- });
224
- yield cleanup();
225
-
226
- if (!err) {
227
- resolve();
228
- return;
229
- }
230
-
231
- debug('Error during streaming: %s', err.stack);
232
- assetHandler.clear();
233
- reject(err);
234
- });
235
- return _onComplete.apply(this, arguments);
236
- }
237
- });
238
-
239
- return function (_x, _x2) {
240
- return _ref.apply(this, arguments);
241
- };
242
- }());
243
- }
244
-
245
- function isWritableStream(val) {
246
- return val !== null && typeof val === 'object' && typeof val.pipe === 'function' && typeof val._write === 'function' && typeof val._writableState === 'object';
247
- }
248
-
249
- module.exports = exportDataset;
@@ -1,14 +0,0 @@
1
- "use strict";
2
-
3
- var miss = require('mississippi');
4
-
5
- module.exports = allowedTypes => allowedTypes ? miss.through.obj((doc, enc, callback) => {
6
- var type = doc && doc._type;
7
-
8
- if (allowedTypes.includes(type)) {
9
- callback(null, doc);
10
- return;
11
- }
12
-
13
- callback();
14
- }) : miss.through.obj();
@@ -1,13 +0,0 @@
1
- "use strict";
2
-
3
- var miss = require('mississippi');
4
-
5
- var isDraft = doc => doc && doc._id && doc._id.indexOf('drafts.') === 0;
6
-
7
- module.exports = () => miss.through.obj((doc, enc, callback) => {
8
- if (isDraft(doc)) {
9
- return callback();
10
- }
11
-
12
- return callback(null, doc);
13
- });
@@ -1,16 +0,0 @@
1
- "use strict";
2
-
3
- var miss = require('mississippi');
4
-
5
- var debug = require('./debug');
6
-
7
- var isSystemDocument = doc => doc && doc._id && doc._id.indexOf('_.') === 0;
8
-
9
- module.exports = () => miss.through.obj((doc, enc, callback) => {
10
- if (isSystemDocument(doc)) {
11
- debug('%s is a system document, skipping', doc && doc._id);
12
- return callback();
13
- }
14
-
15
- return callback(null, doc);
16
- });
@@ -1,29 +0,0 @@
1
- "use strict";
2
-
3
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
4
-
5
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
6
-
7
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
8
-
9
- var pkg = require('../package.json');
10
-
11
- var requestStream = require('./requestStream');
12
-
13
- module.exports = (client, dataset) => {
14
- // Sanity client doesn't handle streams natively since we want to support node/browser
15
- // with same API. We're just using it here to get hold of URLs and tokens.
16
- var url = client.getUrl("/data/export/".concat(dataset));
17
- var token = client.config().token;
18
-
19
- var headers = _objectSpread({
20
- 'User-Agent': "".concat(pkg.name, "@").concat(pkg.version)
21
- }, token ? {
22
- Authorization: "Bearer ".concat(token)
23
- } : {});
24
-
25
- return requestStream({
26
- url,
27
- headers
28
- });
29
- };
@@ -1,18 +0,0 @@
1
- "use strict";
2
-
3
- var miss = require('mississippi');
4
-
5
- var debug = require('./debug');
6
-
7
- module.exports = () => {
8
- var firstChunk = true;
9
- return miss.through((chunk, enc, callback) => {
10
- if (firstChunk) {
11
- var string = chunk.toString('utf8').split('\n')[0];
12
- debug('First chunk received: %s', string.slice(0, 300));
13
- firstChunk = false;
14
- }
15
-
16
- callback(null, chunk);
17
- });
18
- };
@@ -1,17 +0,0 @@
1
- "use strict";
2
-
3
- var miss = require('mississippi');
4
-
5
- module.exports = () => miss.through.obj((doc, enc, callback) => {
6
- if (doc.error && doc.statusCode) {
7
- callback(new Error([doc.statusCode, doc.error].join(': ')));
8
- return;
9
- }
10
-
11
- if (!doc._id && doc.error) {
12
- callback(new Error(doc.error.description || doc.error.message || JSON.stringify(doc)));
13
- return;
14
- }
15
-
16
- callback(null, doc);
17
- });
@@ -1,84 +0,0 @@
1
- "use strict";
2
-
3
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
4
-
5
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
6
-
7
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
8
-
9
- function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
10
-
11
- function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
12
-
13
- var getIt = require('get-it');
14
-
15
- var _require = require('get-it/middleware'),
16
- keepAlive = _require.keepAlive,
17
- promise = _require.promise;
18
-
19
- var debug = require('./debug');
20
-
21
- var request = getIt([keepAlive(), promise({
22
- onlyBody: true
23
- })]);
24
- var socketsWithTimeout = new WeakSet();
25
- var CONNECTION_TIMEOUT = 15 * 1000; // 15 seconds
26
-
27
- var READ_TIMEOUT = 3 * 60 * 1000; // 3 minutes
28
-
29
- var MAX_RETRIES = 5;
30
-
31
- function delay(ms) {
32
- return new Promise(resolve => setTimeout(resolve, ms));
33
- }
34
- /* eslint-disable no-await-in-loop, max-depth */
35
-
36
-
37
- module.exports = /*#__PURE__*/function () {
38
- var _ref = _asyncToGenerator(function* (options) {
39
- var error;
40
-
41
- for (var i = 0; i < MAX_RETRIES; i++) {
42
- try {
43
- var _ret = yield* function* () {
44
- var response = yield request(_objectSpread(_objectSpread({}, options), {}, {
45
- stream: true,
46
- maxRedirects: 0,
47
- timeout: {
48
- connect: CONNECTION_TIMEOUT,
49
- socket: READ_TIMEOUT
50
- }
51
- }));
52
-
53
- if (response.connection && typeof response.connection.setTimeout === 'function' && !socketsWithTimeout.has(response.connection)) {
54
- socketsWithTimeout.add(response.connection);
55
- response.connection.setTimeout(READ_TIMEOUT, () => {
56
- response.destroy(new Error("Read timeout: No data received on socket for ".concat(READ_TIMEOUT, " ms")));
57
- });
58
- }
59
-
60
- return {
61
- v: response
62
- };
63
- }();
64
-
65
- if (typeof _ret === "object") return _ret.v;
66
- } catch (err) {
67
- error = err;
68
-
69
- if (err.response && err.response.statusCode && err.response.statusCode < 500) {
70
- break;
71
- }
72
-
73
- debug('Error, retrying after 1500ms: %s', err.message);
74
- yield delay(1500);
75
- }
76
- }
77
-
78
- throw error;
79
- });
80
-
81
- return function (_x) {
82
- return _ref.apply(this, arguments);
83
- };
84
- }();
@@ -1,5 +0,0 @@
1
- "use strict";
2
-
3
- var miss = require('mississippi');
4
-
5
- module.exports = () => miss.through.obj((doc, enc, callback) => callback(null, "".concat(JSON.stringify(doc), "\n")));
@@ -1,25 +0,0 @@
1
- "use strict";
2
-
3
- module.exports = line => {
4
- try {
5
- return JSON.parse(line);
6
- } catch (err) {
7
- // Catch half-done lines with an error at the end
8
- var errorPosition = line.lastIndexOf('{"error":');
9
-
10
- if (errorPosition === -1) {
11
- err.message = "".concat(err.message, " (").concat(line, ")");
12
- throw err;
13
- }
14
-
15
- var errorJson = line.slice(errorPosition);
16
- var errorLine = JSON.parse(errorJson);
17
- var error = errorLine && errorLine.error;
18
-
19
- if (error && error.description) {
20
- throw new Error("Error streaming dataset: ".concat(error.description, "\n\n").concat(errorJson, "\n"));
21
- }
22
-
23
- throw err;
24
- }
25
- };
@@ -1,58 +0,0 @@
1
- "use strict";
2
-
3
- var defaults = require('lodash/defaults');
4
-
5
- var clientMethods = ['getUrl', 'config'];
6
- var booleanFlags = ['assets', 'raw', 'compress', 'drafts'];
7
- var exportDefaults = {
8
- compress: true,
9
- drafts: true,
10
- assets: true,
11
- raw: false
12
- };
13
-
14
- function validateOptions(opts) {
15
- var options = defaults({}, opts, exportDefaults);
16
-
17
- if (typeof options.dataset !== 'string' || options.dataset.length < 1) {
18
- throw new Error("options.dataset must be a valid dataset name");
19
- }
20
-
21
- if (options.onProgress && typeof options.onProgress !== 'function') {
22
- throw new Error("options.onProgress must be a function");
23
- }
24
-
25
- if (!options.client) {
26
- throw new Error('`options.client` must be set to an instance of @sanity/client');
27
- }
28
-
29
- var missing = clientMethods.find(key => typeof options.client[key] !== 'function');
30
-
31
- if (missing) {
32
- throw new Error("`options.client` is not a valid @sanity/client instance - no \"".concat(missing, "\" method found"));
33
- }
34
-
35
- var clientConfig = options.client.config();
36
-
37
- if (!clientConfig.token) {
38
- throw new Error('Client is not instantiated with a `token`');
39
- }
40
-
41
- booleanFlags.forEach(flag => {
42
- if (typeof options[flag] !== 'boolean') {
43
- throw new Error("Flag ".concat(flag, " must be a boolean (true/false)"));
44
- }
45
- });
46
-
47
- if (!options.outputPath) {
48
- throw new Error('outputPath must be specified (- for stdout)');
49
- }
50
-
51
- if (options.assetConcurrency && (options.assetConcurrency < 1 || options.assetConcurrency > 24)) {
52
- throw new Error('`assetConcurrency` must be between 1 and 24');
53
- }
54
-
55
- return options;
56
- }
57
-
58
- module.exports = validateOptions;