@sanity/export 3.38.0 → 3.38.2
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 +1 -1
- package/src/constants.js +6 -0
- package/src/export.js +35 -6
- package/src/rejectOnApiError.js +17 -9
package/package.json
CHANGED
package/src/constants.js
CHANGED
package/src/export.js
CHANGED
|
@@ -17,6 +17,7 @@ const stringifyStream = require('./stringifyStream')
|
|
|
17
17
|
const tryParseJson = require('./tryParseJson')
|
|
18
18
|
const rimraf = require('./util/rimraf')
|
|
19
19
|
const validateOptions = require('./validateOptions')
|
|
20
|
+
const {DOCUMENT_STREAM_DEBUG_INTERVAL} = require('./constants')
|
|
20
21
|
|
|
21
22
|
const noop = () => null
|
|
22
23
|
|
|
@@ -39,6 +40,9 @@ async function exportDataset(opts) {
|
|
|
39
40
|
|
|
40
41
|
const prefix = `${opts.dataset}-export-${slugDate}`
|
|
41
42
|
const tmpDir = path.join(os.tmpdir(), prefix)
|
|
43
|
+
fs.mkdirSync(tmpDir, {recursive: true})
|
|
44
|
+
const dataPath = path.join(tmpDir, 'data.ndjson')
|
|
45
|
+
|
|
42
46
|
const cleanup = () =>
|
|
43
47
|
rimraf(tmpDir).catch((err) => {
|
|
44
48
|
debug(`Error while cleaning up temporary files: ${err.message}`)
|
|
@@ -90,11 +94,14 @@ async function exportDataset(opts) {
|
|
|
90
94
|
onProgress({step: 'Exporting documents...'})
|
|
91
95
|
|
|
92
96
|
let documentCount = 0
|
|
97
|
+
let lastDocumentID = null
|
|
93
98
|
let lastReported = Date.now()
|
|
94
|
-
const reportDocumentCount = (
|
|
99
|
+
const reportDocumentCount = (doc, enc, cb) => {
|
|
95
100
|
++documentCount
|
|
96
101
|
|
|
97
102
|
const now = Date.now()
|
|
103
|
+
// We report to the `onProgress` handler every 50 ms.
|
|
104
|
+
// It's up to the caller to not do too much expensive work.
|
|
98
105
|
if (now - lastReported > 50) {
|
|
99
106
|
onProgress({
|
|
100
107
|
step: 'Exporting documents...',
|
|
@@ -106,13 +113,30 @@ async function exportDataset(opts) {
|
|
|
106
113
|
lastReported = now
|
|
107
114
|
}
|
|
108
115
|
|
|
109
|
-
|
|
116
|
+
lastDocumentID = doc._id
|
|
117
|
+
|
|
118
|
+
cb(null, doc)
|
|
110
119
|
}
|
|
111
120
|
|
|
112
121
|
const inputStream = await getDocumentsStream(options)
|
|
113
122
|
debug('Got HTTP %d', inputStream.statusCode)
|
|
114
123
|
debug('Response headers: %o', inputStream.headers)
|
|
115
124
|
|
|
125
|
+
let debugTimer = null
|
|
126
|
+
function scheduleDebugTimer() {
|
|
127
|
+
debugTimer = setTimeout(() => {
|
|
128
|
+
debug('Still streaming documents', {
|
|
129
|
+
documentCount,
|
|
130
|
+
lastDocumentID,
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
// Schedule another tick:
|
|
134
|
+
scheduleDebugTimer()
|
|
135
|
+
}, DOCUMENT_STREAM_DEBUG_INTERVAL)
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
scheduleDebugTimer()
|
|
139
|
+
|
|
116
140
|
const jsonStream = miss.pipeline(
|
|
117
141
|
inputStream,
|
|
118
142
|
logFirstChunk(),
|
|
@@ -122,13 +146,15 @@ async function exportDataset(opts) {
|
|
|
122
146
|
assetStreamHandler,
|
|
123
147
|
filterDocumentTypes(options.types),
|
|
124
148
|
options.drafts ? miss.through.obj() : filterDrafts(),
|
|
149
|
+
miss.through.obj(reportDocumentCount),
|
|
125
150
|
stringifyStream(),
|
|
126
|
-
miss.through(reportDocumentCount),
|
|
127
151
|
)
|
|
128
152
|
|
|
129
|
-
miss.
|
|
153
|
+
miss.pipe(jsonStream, fs.createWriteStream(dataPath), async (err) => {
|
|
154
|
+
if (debugTimer !== null) clearTimeout(debugTimer)
|
|
155
|
+
|
|
130
156
|
if (err) {
|
|
131
|
-
debug(
|
|
157
|
+
debug(`Export stream error @ ${lastDocumentID}/${documentCount}: `, err)
|
|
132
158
|
reject(err)
|
|
133
159
|
return
|
|
134
160
|
}
|
|
@@ -141,6 +167,9 @@ async function exportDataset(opts) {
|
|
|
141
167
|
update: true,
|
|
142
168
|
})
|
|
143
169
|
|
|
170
|
+
debug('Adding data.ndjson to archive')
|
|
171
|
+
archive.file(dataPath, {name: 'data.ndjson', prefix})
|
|
172
|
+
|
|
144
173
|
if (!options.raw && options.assets) {
|
|
145
174
|
onProgress({step: 'Downloading assets...'})
|
|
146
175
|
}
|
|
@@ -197,7 +226,6 @@ async function exportDataset(opts) {
|
|
|
197
226
|
debug('Archive warning: %s', err.message)
|
|
198
227
|
})
|
|
199
228
|
|
|
200
|
-
archive.append(jsonStream, {name: 'data.ndjson', prefix})
|
|
201
229
|
miss.pipe(archive, outputStream, onComplete)
|
|
202
230
|
|
|
203
231
|
async function onComplete(err) {
|
|
@@ -205,6 +233,7 @@ async function exportDataset(opts) {
|
|
|
205
233
|
await cleanup()
|
|
206
234
|
|
|
207
235
|
if (!err) {
|
|
236
|
+
debug('Export completed')
|
|
208
237
|
resolve({
|
|
209
238
|
outputPath: options.outputPath,
|
|
210
239
|
documentCount,
|
package/src/rejectOnApiError.js
CHANGED
|
@@ -2,18 +2,26 @@ const miss = require('mississippi')
|
|
|
2
2
|
|
|
3
3
|
module.exports = () =>
|
|
4
4
|
miss.through.obj((doc, enc, callback) => {
|
|
5
|
-
if
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
['Export', `HTTP ${doc.statusCode}`, doc.error, doc.message]
|
|
9
|
-
.filter((part) => typeof part === 'string')
|
|
10
|
-
.join(': '),
|
|
11
|
-
),
|
|
12
|
-
)
|
|
5
|
+
// check if the document passed contains a document attribtue first, and return early.
|
|
6
|
+
if (doc._id) {
|
|
7
|
+
callback(null, doc)
|
|
13
8
|
return
|
|
14
9
|
}
|
|
15
10
|
|
|
16
|
-
if (
|
|
11
|
+
if (doc.error) {
|
|
12
|
+
// if we got a statusCode we can decorate the error with it
|
|
13
|
+
if (doc.statusCode) {
|
|
14
|
+
callback(
|
|
15
|
+
new Error(
|
|
16
|
+
['Export', `HTTP ${doc.statusCode}`, doc.error, doc.message]
|
|
17
|
+
.filter((part) => typeof part === 'string')
|
|
18
|
+
.join(': '),
|
|
19
|
+
),
|
|
20
|
+
)
|
|
21
|
+
return
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// no statusCode, just serialize and return the error
|
|
17
25
|
callback(new Error(doc.error.description || doc.error.message || JSON.stringify(doc)))
|
|
18
26
|
return
|
|
19
27
|
}
|