Skip to content

Instantly share code, notes, and snippets.

@Craga89
Created May 11, 2018 12:05
Show Gist options
  • Save Craga89/c2096bcb24ce18ada1dae31c8205f47b to your computer and use it in GitHub Desktop.
Save Craga89/c2096bcb24ce18ada1dae31c8205f47b to your computer and use it in GitHub Desktop.
dataImporterFactory.js
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