@contrail/transform-data 1.1.4 → 1.2.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.
|
@@ -98,6 +98,7 @@ class MapFileUtil {
|
|
|
98
98
|
processor: step['processor'],
|
|
99
99
|
rekeyDelete: step['rekeyDelete'],
|
|
100
100
|
rekeyKeepMissingValues: step['rekeyKeepMissingValues'],
|
|
101
|
+
rekeyNestedDelimiter: step['rekeyNestedDelimiter'],
|
|
101
102
|
};
|
|
102
103
|
for (const mapping of [
|
|
103
104
|
'conditionalTransformDefinitions',
|
|
@@ -17,7 +17,7 @@ class TransformProcessor {
|
|
|
17
17
|
morph_transformer_1.MorphTransformer.transformData(rows, transformTask.functionTransformers, transformTask.dependencies);
|
|
18
18
|
break;
|
|
19
19
|
case 'REKEY':
|
|
20
|
-
rekey_1.RekeyTransformer.transformData(rows, transformTask.rekeyTransformers, transformTask.rekeyDelete, transformTask.rekeyKeepMissingValues);
|
|
20
|
+
rekey_1.RekeyTransformer.transformData(rows, transformTask.rekeyTransformers, transformTask.rekeyDelete, transformTask.rekeyKeepMissingValues, transformTask.rekeyNestedDelimiter);
|
|
21
21
|
break;
|
|
22
22
|
case 'REMOVE':
|
|
23
23
|
remove_1.RemoveTransformer.transformData(rows, transformTask.removeKeys);
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
export declare class RekeyTransformer {
|
|
2
|
-
static transformData(csvJSON: any[], federatedMappings: Record<string, string>, deleteOldKey?: boolean, rekeyKeepMissingValues?: boolean): void;
|
|
3
|
-
static transformObject(row: any, federatedMappings: Record<string, string>, deleteOldKey?: boolean, rekeyKeepMissingValues?: boolean): void;
|
|
2
|
+
static transformData(csvJSON: any[], federatedMappings: Record<string, string>, deleteOldKey?: boolean, rekeyKeepMissingValues?: boolean, nestedDelimiter?: string | undefined): void;
|
|
3
|
+
static transformObject(row: any, federatedMappings: Record<string, string>, deleteOldKey?: boolean, rekeyKeepMissingValues?: boolean, nestedDelimiter?: string | undefined): void;
|
|
4
|
+
private static parseKeyParts;
|
|
5
|
+
private static setValueAtPath;
|
|
6
|
+
private static getValueAtPath;
|
|
4
7
|
}
|
|
@@ -2,25 +2,83 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.RekeyTransformer = void 0;
|
|
4
4
|
class RekeyTransformer {
|
|
5
|
-
static transformData(csvJSON, federatedMappings, deleteOldKey = false, rekeyKeepMissingValues = false) {
|
|
5
|
+
static transformData(csvJSON, federatedMappings, deleteOldKey = false, rekeyKeepMissingValues = false, nestedDelimiter = undefined) {
|
|
6
6
|
for (const row of csvJSON) {
|
|
7
|
-
RekeyTransformer.transformObject(row, federatedMappings, deleteOldKey, rekeyKeepMissingValues);
|
|
7
|
+
RekeyTransformer.transformObject(row, federatedMappings, deleteOldKey, rekeyKeepMissingValues, nestedDelimiter);
|
|
8
8
|
}
|
|
9
9
|
}
|
|
10
|
-
static transformObject(row, federatedMappings, deleteOldKey = false, rekeyKeepMissingValues = false) {
|
|
11
|
-
const keys = Object.keys(row);
|
|
10
|
+
static transformObject(row, federatedMappings, deleteOldKey = false, rekeyKeepMissingValues = false, nestedDelimiter = undefined) {
|
|
12
11
|
for (const [newKey, oldKey] of Object.entries(federatedMappings)) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
const newKeyParts = RekeyTransformer.parseKeyParts(newKey, nestedDelimiter);
|
|
13
|
+
const oldKeyParts = RekeyTransformer.parseKeyParts(oldKey, nestedDelimiter);
|
|
14
|
+
const { value: oldValue, isExistingPath: doesOldKeyExist } = RekeyTransformer.getValueAtPath({
|
|
15
|
+
obj: row,
|
|
16
|
+
pathParts: oldKeyParts,
|
|
17
|
+
nestedDelimiter,
|
|
18
|
+
});
|
|
19
|
+
if (doesOldKeyExist) {
|
|
20
|
+
RekeyTransformer.setValueAtPath({ obj: row, pathParts: newKeyParts, value: oldValue });
|
|
21
|
+
}
|
|
22
|
+
else if (rekeyKeepMissingValues) {
|
|
23
|
+
RekeyTransformer.setValueAtPath({ obj: row, pathParts: newKeyParts, value: undefined });
|
|
17
24
|
}
|
|
18
25
|
}
|
|
19
26
|
if (deleteOldKey) {
|
|
20
27
|
for (const oldKey of Object.values(federatedMappings)) {
|
|
21
|
-
|
|
28
|
+
if (nestedDelimiter && oldKey.includes(nestedDelimiter)) {
|
|
29
|
+
const oldKeyParts = RekeyTransformer.parseKeyParts(oldKey, nestedDelimiter);
|
|
30
|
+
let current = row;
|
|
31
|
+
for (let i = 0; i < oldKeyParts.length - 1; i++) {
|
|
32
|
+
if (current == null || typeof current !== 'object' || !(oldKeyParts[i] in current)) {
|
|
33
|
+
current = null;
|
|
34
|
+
break;
|
|
35
|
+
}
|
|
36
|
+
current = current[oldKeyParts[i]];
|
|
37
|
+
}
|
|
38
|
+
if (current && oldKeyParts[oldKeyParts.length - 1] in current) {
|
|
39
|
+
delete current[oldKeyParts[oldKeyParts.length - 1]];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
delete row[oldKey];
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
static parseKeyParts(key, nestedDelimiter) {
|
|
49
|
+
if (!nestedDelimiter || !key.includes(nestedDelimiter)) {
|
|
50
|
+
return [key];
|
|
51
|
+
}
|
|
52
|
+
const parts = key.split(nestedDelimiter);
|
|
53
|
+
return parts;
|
|
54
|
+
}
|
|
55
|
+
static setValueAtPath({ obj, pathParts, value, }) {
|
|
56
|
+
let current = obj;
|
|
57
|
+
for (let i = 0; i < pathParts.length - 1; i++) {
|
|
58
|
+
const key = pathParts[i];
|
|
59
|
+
if (current[key] == null || typeof current[key] !== 'object') {
|
|
60
|
+
current[key] = {};
|
|
61
|
+
}
|
|
62
|
+
current = current[key];
|
|
63
|
+
}
|
|
64
|
+
const finalKey = pathParts[pathParts.length - 1];
|
|
65
|
+
if (!Object.prototype.hasOwnProperty.call(current, finalKey)) {
|
|
66
|
+
current[finalKey] = value;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
static getValueAtPath({ obj, pathParts, nestedDelimiter, }) {
|
|
70
|
+
if (!nestedDelimiter || pathParts.length === 1) {
|
|
71
|
+
const propertyKey = pathParts[0];
|
|
72
|
+
return { value: obj[propertyKey], isExistingPath: obj.hasOwnProperty(propertyKey) };
|
|
73
|
+
}
|
|
74
|
+
let current = obj;
|
|
75
|
+
for (const key of pathParts) {
|
|
76
|
+
if (current == null || typeof current !== 'object' || !Object.prototype.hasOwnProperty.call(current, key)) {
|
|
77
|
+
return { value: undefined, isExistingPath: false };
|
|
22
78
|
}
|
|
79
|
+
current = current[key];
|
|
23
80
|
}
|
|
81
|
+
return { value: current, isExistingPath: true };
|
|
24
82
|
}
|
|
25
83
|
}
|
|
26
84
|
exports.RekeyTransformer = RekeyTransformer;
|