Created
May 11, 2018 12:05
-
-
Save Craga89/c2096bcb24ce18ada1dae31c8205f47b to your computer and use it in GitHub Desktop.
dataImporterFactory.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const get = require('lodash/get'); | |
const isNil = require('lodash/isNil'); | |
const omitBy = require('lodash/omitBy'); | |
const identity = require('lodash/identity'); | |
const { createImport } = require('../urls'); | |
const { listTableColumns } = require('./tableColumn'); | |
const NO_MORE_INFORMATION = 'No more information available.'; | |
const RESULT_TYPE_FAILED_INSERTING = 'FailedInserting'; | |
const RESULT_TYPE_FAILED_UPDATING = 'FailedUpdating'; | |
const RESULT_TYPE_SUCCESS_INSERTING = 'SuccessInserting'; | |
const RESULT_TYPE_SUCCESS_UPDATING = 'SuccessUpdating'; | |
const RESULT_TYPE_PRIMARY_KEY_VIOLATION = 'PrimaryKeyViolation'; | |
const RESULT_TYPE_FOREIGN_KEY_VIOLATION = 'ForeignKeyViolation'; | |
const RESULT_TYPE_COLUMN_MAPPING_FAILURE = 'ColumnMappingFailure'; | |
const RESULT_TYPE_COLUMNS_NOT_IN_TABLE = 'ColumnsNotInTable'; | |
const RESULT_TYPE_NO_REQUIRED_COLUMN_IN_TABLE = 'NoRequiredColumnInTable'; | |
const RESULT_TYPE_COLUMN_REQUIRED = 'ColumnRequired'; | |
const RESULT_TYPE_DUPLICATE_COLUMN_MAPPING = 'DuplicateColumnMapping'; | |
const RESULT_TYPE_NO_CHANGE_TO_EXISTING_CONTACT = 'NoChangeToExistingContact'; | |
const RESULT_TYPE_NOT_NULL_VIOLATION = 'NotNullViolation'; | |
const RESULT_TYPE_UNKNOWN = 'Unknown'; | |
const RESULT_TYPES_ERROR = new Set([ | |
RESULT_TYPE_FAILED_INSERTING, | |
RESULT_TYPE_FAILED_UPDATING, | |
RESULT_TYPE_PRIMARY_KEY_VIOLATION, | |
RESULT_TYPE_FOREIGN_KEY_VIOLATION, | |
RESULT_TYPE_COLUMN_MAPPING_FAILURE, | |
RESULT_TYPE_COLUMNS_NOT_IN_TABLE, | |
RESULT_TYPE_NO_REQUIRED_COLUMN_IN_TABLE, | |
RESULT_TYPE_COLUMN_REQUIRED, | |
RESULT_TYPE_DUPLICATE_COLUMN_MAPPING, | |
RESULT_TYPE_NOT_NULL_VIOLATION, | |
RESULT_TYPE_UNKNOWN | |
]); | |
const omitEmpties = (obj) => omitBy(obj, isNil); | |
const DATA_TYPES_MAP = { | |
'Text': 'string', | |
'Long Text': 'string', | |
'Email Address': 'string', | |
'Date': 'datetime', | |
'Date Time': 'datetime' | |
}; | |
exports.generateColumnMappings = (z, bundle) => | |
Object.keys(bundle.inputData).reduce((memo, key) => { | |
if (key.startsWith('columns.')) { | |
memo.push({ | |
ColumnId: parseInt(key.slice(8)), | |
Value: bundle.inputData[key] | |
}); | |
} | |
return memo; | |
}, []); | |
exports.getTableInputFieldsFactory = (noun) => (z, bundle) => { | |
const tableId = bundle.inputData.tableId; | |
z.console.log('Getting columns for table: ' + tableId); | |
if (tableId == null) { | |
return []; | |
} | |
return listTableColumns(z, bundle) | |
.then((columns) => columns.map((column) => ({ | |
key: 'rows.testing', | |
label: 'rows.testing', | |
required: !!column.isUnique, | |
type: 'string' | |
}))); | |
}; | |
exports.createFactory = (requestFields, dataRecordFields) => (z, bundle) => { | |
z.console.log(JSON.stringify(bundle, null, 4)); | |
const fields = requestFields({ | |
ClientTableId: bundle.inputData.tableId, | |
Type: bundle.inputData.type, | |
FormatDate: bundle.inputData.dateFormat, | |
Records: { | |
DataRecord: [ | |
dataRecordFields({ | |
ColumnMappings: { | |
ColumnMapping: exports.generateColumnMappings(z, bundle) | |
} | |
}, z, bundle) | |
] | |
} | |
}, z, bundle); | |
return z.request({ | |
method: 'POST', | |
url: createImport(), | |
body: omitEmpties(fields) | |
}) | |
// Check if the import failed by checking ImportTopLevel | |
.then(response => { | |
let resultType = get(response.json, ['ImportTopLevel', 0, 'ImportResultType']); | |
if (RESULT_TYPES_ERROR.has(resultType)) { | |
const failedImport = response.json.ImportDetails.find((i) => i.Result === resultType); | |
if (failedImport) { | |
throw new Error(`${resultType} Error (#${failedImport.Row}): ${failedImport.Response || NO_MORE_INFORMATION}`); | |
} | |
throw new Error(`${resultType} Error: ${NO_MORE_INFORMATION}.`); | |
} | |
return response; | |
}); | |
}; | |
exports.sampleFactory = (type) => ({ | |
tableId: 1, | |
columns: [{ | |
id: 1, | |
value: 'email@address.com' | |
}] | |
}); | |
exports.default = ({ | |
key, | |
noun, | |
pluralNoun = `${noun}s`, | |
tableNoun = 'Table', | |
tableList, | |
tableSearch, | |
inputFields = identity, | |
requestFields = identity, | |
dataRecordFields = identity | |
}) => ({ | |
key, | |
noun, | |
create: { | |
display: { | |
label: `Create/Update ${pluralNoun}`, | |
description: `Create or update one or multiple ${pluralNoun}.` | |
}, | |
operation: { | |
inputFields: inputFields([ | |
{ | |
key: 'type', | |
required: true, | |
label: 'Import type', | |
choices: [{ | |
label: 'Insert', | |
sample: `Creates a new ${noun} if a record with the same primary key does not exist, otherwise it will fail.`, | |
value: 'Insert' | |
}, { | |
label: 'Update', | |
sample: `Updates an existing ${noun} if a record with the same primary key exist, otherwise it will fail.`, | |
value: 'Update', | |
}, { | |
label: 'Upsert', | |
sample: `Updates an existing ${noun} if a record with the same primary key exist, otherwise it will create a new ${noun}`, | |
value: 'Upsert' | |
}] | |
}, | |
{ key: 'dateFormat', label: 'Date Format', type: 'string', required: false }, | |
{ | |
key: 'tableId', | |
type: 'number', | |
required: true, | |
label: tableNoun, | |
dynamic: tableList, | |
search: tableSearch, | |
altersDynamicFields: true | |
}, | |
{ | |
key: 'rows', | |
label: 'Rows', | |
altersDynamicFields: true, | |
children: [exports.getTableInputFieldsFactory(noun)] | |
} | |
]), | |
perform: exports.createFactory(requestFields, dataRecordFields), | |
sample: exports.sampleFactory(key) | |
} | |
}, | |
sample: exports.sampleFactory(key), | |
outputFields: [ | |
{ key: 'id', label: 'ID' }, | |
{ key: 'name', label: 'Name' } | |
] | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment