@sanity/export 3.43.0 → 3.45.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 +23 -0
- package/package.json +1 -1
- package/src/export.js +2 -6
- package/src/filterDocumentTypes.js +1 -1
- package/src/{filterSystemDocuments.js → filterDocuments.js} +21 -6
- package/src/getDocumentCursorStream.js +8 -2
- package/src/getDocumentsStream.js +8 -2
- package/src/validateOptions.js +4 -0
- package/src/filterDrafts.js +0 -12
package/README.md
CHANGED
|
@@ -18,6 +18,7 @@ exportDataset({
|
|
|
18
18
|
client: someInstantiatedSanityClientInstance,
|
|
19
19
|
|
|
20
20
|
// Name of dataset to export
|
|
21
|
+
// Cannot be combined with `mediaLibraryId`.
|
|
21
22
|
dataset: 'myDataset',
|
|
22
23
|
|
|
23
24
|
// Path to write tar.gz-archive file to, or `-` for stdout
|
|
@@ -47,6 +48,28 @@ exportDataset({
|
|
|
47
48
|
// Cursor mode might help when dealing with large datasets, but might yield inconsistent results if the dataset is mutated during export.
|
|
48
49
|
// Default: 'stream'
|
|
49
50
|
mode: 'stream',
|
|
51
|
+
|
|
52
|
+
// Export data from a media library, instead of a dataset.
|
|
53
|
+
// Cannot be combined with `dataset`.
|
|
54
|
+
mediaLibraryId: 'myMediaLibrary',
|
|
55
|
+
|
|
56
|
+
// Whether to include the `assets.json` assets map. This file is not necessary when creating a
|
|
57
|
+
// media library archive.
|
|
58
|
+
// Caution: customising this option may result in an archive being produced that is impossible to import.
|
|
59
|
+
// Optional, default: `true`
|
|
60
|
+
assetsMap: true,
|
|
61
|
+
|
|
62
|
+
// A custom filter function for controlling which documents are exported.
|
|
63
|
+
// Optional, default: `() => true`
|
|
64
|
+
filterDocument: document => (document.title ?? '').includes('capybara'),
|
|
65
|
+
|
|
66
|
+
// A custom transformation function for controlling how each document is exported.
|
|
67
|
+
// Caution: customising this option may result in an archive being produced that is impossible to import.
|
|
68
|
+
// Optional, default: `document => document`
|
|
69
|
+
transformDocument: document => ({
|
|
70
|
+
...document,
|
|
71
|
+
title: document.title ?? 'capybara',
|
|
72
|
+
}),
|
|
50
73
|
})
|
|
51
74
|
```
|
|
52
75
|
|
package/package.json
CHANGED
package/src/export.js
CHANGED
|
@@ -9,9 +9,7 @@ const JsonStreamStringify = require('json-stream-stringify')
|
|
|
9
9
|
const AssetHandler = require('./AssetHandler')
|
|
10
10
|
const debug = require('./debug')
|
|
11
11
|
const pipeAsync = require('./util/pipeAsync')
|
|
12
|
-
const
|
|
13
|
-
const filterDrafts = require('./filterDrafts')
|
|
14
|
-
const filterSystemDocuments = require('./filterSystemDocuments')
|
|
12
|
+
const filterDocuments = require('./filterDocuments')
|
|
15
13
|
const getDocumentsStream = require('./getDocumentsStream')
|
|
16
14
|
const getDocumentCursorStream = require('./getDocumentCursorStream')
|
|
17
15
|
const logFirstChunk = require('./logFirstChunk')
|
|
@@ -156,10 +154,8 @@ async function exportDataset(opts) {
|
|
|
156
154
|
logFirstChunk(),
|
|
157
155
|
split(tryParseJson),
|
|
158
156
|
rejectOnApiError(),
|
|
159
|
-
|
|
157
|
+
filterDocuments(options.drafts),
|
|
160
158
|
assetStreamHandler,
|
|
161
|
-
filterDocumentTypes(options.types),
|
|
162
|
-
options.drafts ? miss.through.obj() : filterDrafts(),
|
|
163
159
|
miss.through.obj((doc, _enc, callback) => {
|
|
164
160
|
if (options.filterDocument(doc)) {
|
|
165
161
|
return callback(null, doc)
|
|
@@ -1,19 +1,34 @@
|
|
|
1
1
|
const miss = require('mississippi')
|
|
2
2
|
const debug = require('./debug')
|
|
3
3
|
|
|
4
|
+
const isDraftOrVersion = (doc) => doc && doc._id && (
|
|
5
|
+
doc._id.indexOf('drafts.') === 0 ||
|
|
6
|
+
doc._id.indexOf('versions.') === 0
|
|
7
|
+
)
|
|
8
|
+
|
|
4
9
|
const isSystemDocument = (doc) => doc && doc._id && doc._id.indexOf('_.') === 0
|
|
10
|
+
const isRelease = (doc) => doc && doc._id && doc._id.indexOf('_.releases.') === 0
|
|
5
11
|
const isCursor = (doc) => doc && !doc._id && doc.nextCursor !== undefined
|
|
6
12
|
|
|
7
|
-
module.exports = () =>
|
|
13
|
+
module.exports = (drafts) =>
|
|
8
14
|
miss.through.obj((doc, enc, callback) => {
|
|
9
|
-
if (isSystemDocument(doc)) {
|
|
10
|
-
debug('%s is a system document, skipping', doc && doc._id)
|
|
11
|
-
return callback()
|
|
12
|
-
}
|
|
13
15
|
if (isCursor(doc)) {
|
|
14
16
|
debug('%o is a cursor, skipping', doc)
|
|
15
17
|
return callback()
|
|
16
18
|
}
|
|
17
19
|
|
|
20
|
+
if (!drafts && isDraftOrVersion(doc)) {
|
|
21
|
+
debug('%s is a draft or version, skipping', doc && doc._id)
|
|
22
|
+
return callback()
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (isSystemDocument(doc)) {
|
|
26
|
+
if (!drafts && isRelease(doc)) {
|
|
27
|
+
return callback(null, doc)
|
|
28
|
+
}
|
|
29
|
+
debug('%s is a system document, skipping', doc && doc._id)
|
|
30
|
+
return callback()
|
|
31
|
+
}
|
|
32
|
+
|
|
18
33
|
return callback(null, doc)
|
|
19
|
-
})
|
|
34
|
+
})
|
|
@@ -72,7 +72,13 @@ function startStream(options, nextCursor) {
|
|
|
72
72
|
: `/media-libraries/${options.mediaLibraryId}/export`,
|
|
73
73
|
)
|
|
74
74
|
|
|
75
|
-
const url =
|
|
75
|
+
const url = new URL(baseUrl)
|
|
76
|
+
url.searchParams.set('nextCursor', nextCursor)
|
|
77
|
+
|
|
78
|
+
// Type filtering is only supported for datasets.
|
|
79
|
+
if (options.types && options.types.length > 0 && options.dataset) {
|
|
80
|
+
url.searchParams.set('types', options.types.join())
|
|
81
|
+
}
|
|
76
82
|
const token = options.client.config().token
|
|
77
83
|
const headers = {
|
|
78
84
|
'User-Agent': `${pkg.name}@${pkg.version}`,
|
|
@@ -81,7 +87,7 @@ function startStream(options, nextCursor) {
|
|
|
81
87
|
|
|
82
88
|
debug('Starting stream with cursor "%s"', nextCursor)
|
|
83
89
|
|
|
84
|
-
return requestStream({url, headers, maxRetries: options.maxRetries}).then((res) => {
|
|
90
|
+
return requestStream({url: url.toString(), headers, maxRetries: options.maxRetries}).then((res) => {
|
|
85
91
|
debug('Got stream with HTTP %d', res.statusCode)
|
|
86
92
|
|
|
87
93
|
return res
|
|
@@ -4,11 +4,17 @@ const requestStream = require('./requestStream')
|
|
|
4
4
|
module.exports = (options) => {
|
|
5
5
|
// Sanity client doesn't handle streams natively since we want to support node/browser
|
|
6
6
|
// with same API. We're just using it here to get hold of URLs and tokens.
|
|
7
|
-
const
|
|
7
|
+
const baseUrl = options.client.getUrl(
|
|
8
8
|
options.dataset
|
|
9
9
|
? `/data/export/${options.dataset}`
|
|
10
10
|
: `/media-libraries/${options.mediaLibraryId}/export`,
|
|
11
11
|
)
|
|
12
|
+
|
|
13
|
+
// Type filtering is only supported for datasets.
|
|
14
|
+
const url = new URL(baseUrl)
|
|
15
|
+
if (options.types && options.types.length > 0 && options.dataset) {
|
|
16
|
+
url.searchParams.set('types', options.types.join())
|
|
17
|
+
}
|
|
12
18
|
|
|
13
19
|
const token = options.client.config().token
|
|
14
20
|
const headers = {
|
|
@@ -17,7 +23,7 @@ module.exports = (options) => {
|
|
|
17
23
|
}
|
|
18
24
|
|
|
19
25
|
return requestStream({
|
|
20
|
-
url,
|
|
26
|
+
url: url.toString(),
|
|
21
27
|
headers,
|
|
22
28
|
maxRetries: options.maxRetries,
|
|
23
29
|
readTimeout: options.readTimeout,
|
package/src/validateOptions.js
CHANGED
|
@@ -43,6 +43,10 @@ function validateOptions(opts) {
|
|
|
43
43
|
)
|
|
44
44
|
}
|
|
45
45
|
|
|
46
|
+
if (options.types && !options.dataset) {
|
|
47
|
+
throw new Error('`options.types` is only supported when exporting from a dataset')
|
|
48
|
+
}
|
|
49
|
+
|
|
46
50
|
if (
|
|
47
51
|
typeof options.mode !== 'string' ||
|
|
48
52
|
(options.mode !== MODE_STREAM && options.mode !== MODE_CURSOR)
|
package/src/filterDrafts.js
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
const miss = require('mississippi')
|
|
2
|
-
|
|
3
|
-
const isDraft = (doc) => doc && doc._id && doc._id.indexOf('drafts.') === 0
|
|
4
|
-
|
|
5
|
-
module.exports = () =>
|
|
6
|
-
miss.through.obj((doc, enc, callback) => {
|
|
7
|
-
if (isDraft(doc)) {
|
|
8
|
-
return callback()
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
return callback(null, doc)
|
|
12
|
-
})
|