@pujansrt/data-genie
Version:
High performant ETL engine written in TypeScript
159 lines (158 loc) • 5.89 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.SelectFields = exports.RemoveFields = exports.SetCalculatedField = exports.SetField = exports.RenameField = exports.BasicFieldTransformer = void 0;
class BasicFieldTransformer {
constructor(...fieldNames) {
this.fieldNames = fieldNames;
}
stringToDouble() {
return (record) => {
this.fieldNames.forEach((fieldName) => {
if (typeof record[fieldName] === 'string') {
record[fieldName] = parseFloat(record[fieldName]);
}
});
return record;
};
}
nullToValue(defaultValue) {
return (record) => {
this.fieldNames.forEach((fieldName) => {
if (record[fieldName] === null || record[fieldName] === undefined) {
record[fieldName] = defaultValue;
}
});
return record;
};
}
stringToInt() {
return (record) => {
this.fieldNames.forEach((fieldName) => {
if (typeof record[fieldName] === 'string') {
record[fieldName] = parseInt(record[fieldName], 10);
}
});
return record;
};
}
dateParse(format) {
return (record) => {
this.fieldNames.forEach((fieldName) => {
if (typeof record[fieldName] === 'string') {
// Use a library like date-fns or moment.js for robust date parsing
const parsedDate = new Date(record[fieldName]); // Simplified; consider using a library for format handling
if (!isNaN(parsedDate.getTime())) {
record[fieldName] = parsedDate;
}
else {
console.warn(`Invalid date format for field "${fieldName}": ${record[fieldName]}`);
}
}
});
return record;
};
}
}
exports.BasicFieldTransformer = BasicFieldTransformer;
class RenameField {
constructor(oldName, newName) {
this.oldName = oldName;
this.newName = newName;
this.allowDuplicateFieldNames = false; // Default to not allowing duplicates/overwrites
}
setAllowDuplicateFieldNames(value) {
this.allowDuplicateFieldNames = value;
return this;
}
transform() {
return (record) => {
// Only proceed if the old field exists in the record
if (record.hasOwnProperty(this.oldName)) {
// Check if the new field name already exists
if (record.hasOwnProperty(this.newName)) {
// If duplicates are not allowed, log a warning
if (!this.allowDuplicateFieldNames) {
console.warn(`Warning: Field "${this.newName}" already exists. Renaming "${this.oldName}" to "${this.newName}" will overwrite existing data. Set 'allowDuplicateFieldNames(true)' to suppress this warning.`);
// NOTE: The logic here depends on your desired behavior.
// If you truly want to *prevent* the rename unless allowed, you'd 'return record;' here.
// For this example, we'll proceed with the overwrite even with a warning,
// as the subsequent setAllowDuplicateFieldNames(true) implies this intent.
}
}
// Perform the rename (overwrite if newName exists, or create if it doesn't)
record[this.newName] = record[this.oldName];
delete record[this.oldName]; // Delete the old field
}
return record;
};
}
}
exports.RenameField = RenameField;
class SetField {
constructor(fieldName, value) {
this.fieldName = fieldName;
this.value = value;
}
transform() {
return (record) => {
record[this.fieldName] = this.value;
return record;
};
}
}
exports.SetField = SetField;
// transformers/fieldTransformers.ts (continued)
class SetCalculatedField {
constructor(fieldName, expression) {
this.fieldName = fieldName;
this.expression = expression;
}
transform() {
return (record) => {
// WARNING: Using eval is dangerous. Consider a dedicated expression parser.
try {
const evaluatedValue = new Function('record', `with(record) { return ${this.expression} }`)(record);
record[this.fieldName] = evaluatedValue;
}
catch (e) {
console.error(`Error evaluating expression for field ${this.fieldName}: ${e}`, record);
// Handle error: e.g., set to null, skip record
}
return record;
};
}
}
exports.SetCalculatedField = SetCalculatedField;
// transformers/fieldTransformers.ts (continued)
class RemoveFields {
constructor(...fieldNames) {
this.fieldNames = fieldNames;
}
transform() {
return (record) => {
this.fieldNames.forEach((fieldName) => {
delete record[fieldName];
});
return record;
};
}
}
exports.RemoveFields = RemoveFields;
// transformers/fieldTransformers.ts (continued)
class SelectFields {
constructor(...fieldNames) {
this.fieldNames = fieldNames;
}
transform() {
return (record) => {
const newRecord = {};
this.fieldNames.forEach((fieldName) => {
if (record.hasOwnProperty(fieldName)) {
newRecord[fieldName] = record[fieldName];
}
});
return newRecord;
};
}
}
exports.SelectFields = SelectFields;