Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 53 additions & 79 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { access } from 'fs'

import bfj from 'bfj'
import Promise from 'bluebird'
import Table from 'cli-table3'
Expand All @@ -10,18 +9,10 @@ import startCase from 'lodash.startcase'
import mkdirp from 'mkdirp'
import { differenceInSeconds } from 'date-fns/differenceInSeconds'
import { formatDistance } from 'date-fns/formatDistance'

import {
setupLogging,
displayErrorLog,
wrapTask,
writeErrorLogFile
} from 'contentful-batch-libs'

import { setupLogging, displayErrorLog, wrapTask, writeErrorLogFile } from 'contentful-batch-libs'
import downloadAssets from './tasks/download-assets'
import getSpaceData from './tasks/get-space-data'
import initClient from './tasks/init-client'

import parseOptions from './parseOptions'

const accessP = Promise.promisify(access)
Expand All @@ -43,9 +34,9 @@ function createListrOptions (options) {
}
}

export default function runContentfulExport (params) {
export default async function runContentfulExport (params) {
const log = []
const options = parseOptions(params)
const options = await parseOptions(params)

const listrOptions = createListrOptions(options)

Expand Down Expand Up @@ -97,9 +88,7 @@ export default function runContentfulExport (params) {
{
title: 'Download assets',
task: wrapTask(downloadAssets(options)),
skip: (ctx) =>
!options.downloadAssets ||
!Object.prototype.hasOwnProperty.call(ctx.data, 'assets')
skip: (ctx) => !options.downloadAssets || !Object.prototype.hasOwnProperty.call(ctx.data, 'assets')
},
{
title: 'Write export log file',
Expand Down Expand Up @@ -141,78 +130,63 @@ export default function runContentfulExport (params) {
listrOptions
)

return tasks
.run({
data: {}
})
.then((ctx) => {
const resultTypes = Object.keys(ctx.data)
if (resultTypes.length) {
const resultTable = new Table(tableOptions)
let ctx
try {
ctx = await tasks.run({ data: {} })
const resultTypes = Object.keys(ctx.data)
if (resultTypes.length) {
const resultTable = new Table(tableOptions)

resultTable.push([{ colSpan: 2, content: 'Exported entities' }])
resultTable.push([{ colSpan: 2, content: 'Exported entities' }])

resultTypes.forEach((type) => {
resultTable.push([startCase(type), ctx.data[type].length])
})
resultTypes.forEach((type) => {
resultTable.push([startCase(type), ctx.data[type].length])
})

console.log(resultTable.toString())
} else {
console.log('No data was exported')
}
console.log(resultTable.toString())
} else {
console.log('No data was exported')
}

if ('assetDownloads' in ctx) {
const downloadsTable = new Table(tableOptions)
downloadsTable.push([
{ colSpan: 2, content: 'Asset file download results' }
])
downloadsTable.push(['Successful', ctx.assetDownloads.successCount])
downloadsTable.push(['Warnings ', ctx.assetDownloads.warningCount])
downloadsTable.push(['Errors ', ctx.assetDownloads.errorCount])
console.log(downloadsTable.toString())
}
if ('assetDownloads' in ctx) {
const downloadsTable = new Table(tableOptions)
downloadsTable.push([{ colSpan: 2, content: 'Asset file download results' }])
downloadsTable.push(['Successful', ctx.assetDownloads.successCount])
downloadsTable.push(['Warnings ', ctx.assetDownloads.warningCount])
downloadsTable.push(['Errors ', ctx.assetDownloads.errorCount])
console.log(downloadsTable.toString())
}

const endTime = new Date()
const durationHuman = formatDistance(endTime, options.startTime)
const durationSeconds = differenceInSeconds(endTime, options.startTime)
const endTime = new Date()
const durationHuman = formatDistance(endTime, options.startTime)
const durationSeconds = differenceInSeconds(endTime, options.startTime)

console.log(`The export took ${durationHuman} (${durationSeconds}s)`)
if (options.saveFile) {
console.log(
`\nStored space data to json file at: ${options.logFilePath}`
)
}
return ctx.data
})
.catch((err) => {
log.push({
ts: new Date().toJSON(),
level: 'error',
error: err
})
console.log(`The export took ${durationHuman} (${durationSeconds}s)`)
if (options.saveFile) {
console.log(`\nStored space data to json file at: ${options.logFilePath}`)
}
} catch (err) {
log.push({
ts: new Date().toJSON(),
level: 'error',
error: err
})
.then((data) => {
// @todo this should live in batch libs
const errorLog = log.filter(
(logMessage) =>
logMessage.level !== 'info' && logMessage.level !== 'warning'
)
const displayLog = log.filter(
(logMessage) => logMessage.level !== 'info'
)
displayErrorLog(displayLog)

if (errorLog.length) {
return writeErrorLogFile(options.errorLogFile, errorLog).then(() => {
const multiError = new Error('Errors occured')
multiError.name = 'ContentfulMultiError'
Object.assign(multiError, { errors: errorLog })
throw multiError
})
}
}

console.log('The export was successful.')
const errorLog = log.filter((logMessage) => logMessage.level !== 'info' && logMessage.level !== 'warning')
const displayLog = log.filter((logMessage) => logMessage.level !== 'info')
displayErrorLog(displayLog)

return data
if (errorLog.length) {
return writeErrorLogFile(options.errorLogFile, errorLog).then(() => {
const multiError = new Error('Errors occured')
multiError.name = 'ContentfulMultiError'
Object.assign(multiError, { errors: errorLog })
throw multiError
})
}

console.log('The export was successful.')

return ctx.data
}
25 changes: 16 additions & 9 deletions lib/parseOptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,10 @@ import { addSequenceHeader, agentFromProxy, proxyStringToObject } from 'contentf
import { format } from 'date-fns/format'
import { resolve } from 'path'
import qs from 'querystring'

import { version } from '../package.json'
import { getHeadersConfig } from './utils/headers'

export default function parseOptions (params) {
export default async function parseOptions (params) {
const defaultOptions = {
environmentId: 'master',
exportDir: process.cwd(),
Expand All @@ -25,10 +24,11 @@ export default function parseOptions (params) {
rawProxy: false
}

const configFile = params.config
// eslint-disable-next-line @typescript-eslint/no-require-imports
? require(resolve(process.cwd(), params.config))
: {}
let configFile = {}
if (params.config) {
const externalConfigFile = await import(resolve(process.cwd(), params.config))
configFile = externalConfigFile.default
}

const options = {
...defaultOptions,
Expand All @@ -47,12 +47,17 @@ export default function parseOptions (params) {
}

options.startTime = new Date()
options.contentFile = options.contentFile || `contentful-export-${options.spaceId}-${options.environmentId}-${format(options.startTime, "yyyy-MM-dd'T'HH-mm-ss")}.json`
options.contentFile =
options.contentFile ||
`contentful-export-${options.spaceId}-${options.environmentId}-${format(options.startTime, "yyyy-MM-dd'T'HH-mm-ss")}.json`

options.logFilePath = resolve(options.exportDir, options.contentFile)

if (!options.errorLogFile) {
options.errorLogFile = resolve(options.exportDir, `contentful-export-error-log-${options.spaceId}-${options.environmentId}-${format(options.startTime, "yyyy-MM-dd'T'HH-mm-ss")}.json`)
options.errorLogFile = resolve(
options.exportDir,
`contentful-export-error-log-${options.spaceId}-${options.environmentId}-${format(options.startTime, "yyyy-MM-dd'T'HH-mm-ss")}.json`
)
} else {
options.errorLogFile = resolve(process.cwd(), options.errorLogFile)
}
Expand All @@ -65,7 +70,9 @@ export default function parseOptions (params) {
const proxySimpleExp = /.+:\d+/
const proxyAuthExp = /.+:.+@.+:\d+/
if (!(proxySimpleExp.test(options.proxy) || proxyAuthExp.test(options.proxy))) {
throw new Error('Please provide the proxy config in the following format:\nhost:port or user:password@host:port')
throw new Error(
'Please provide the proxy config in the following format:\nhost:port or user:password@host:port'
)
}
options.proxy = proxyStringToObject(options.proxy)
}
Expand Down
6 changes: 3 additions & 3 deletions lib/tasks/download-assets.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ async function downloadAsset ({ url, directory, httpClient }) {
try {
// download asset
const assetRequest = await httpClient.get(url, {
responseType: "stream",
transformResponse: [(data) => data],
responseType: 'stream',
transformResponse: [(data) => data]
})

// Wait for stream to be consumed before returning local file
Expand Down Expand Up @@ -92,7 +92,7 @@ export default function downloadAssets (options) {

return startingPromise
.then(downloadAsset)
.then((_downLoadedFile) => {
.then(() => {
task.output = `${figures.tick} downloaded ${entityName} (${url})`
successCount++
})
Expand Down
Loading