@forzalabs/remora 0.0.28 → 0.0.29
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.
package/Constants.js
CHANGED
|
@@ -68,9 +68,11 @@
|
|
|
68
68
|
"enum": [
|
|
69
69
|
"hash",
|
|
70
70
|
"mask",
|
|
71
|
-
"crypt"
|
|
71
|
+
"crypt",
|
|
72
|
+
"random",
|
|
73
|
+
"seeded-random"
|
|
72
74
|
],
|
|
73
|
-
"description": "Masking type to apply to this dimension"
|
|
75
|
+
"description": "Masking type to apply to this dimension. 'hash' replaces with a hashed value. 'mask' replaces characters with a mask character. 'crypt' encrypts the value. 'random' replaces with a random value. 'seeded-random' replaces with a random value generated from a seed."
|
|
74
76
|
}
|
|
75
77
|
},
|
|
76
78
|
"required": [
|
package/engines/CryptoEngine.js
CHANGED
|
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
const crypto_1 = __importDefault(require("crypto"));
|
|
7
7
|
const Algo_1 = __importDefault(require("../core/Algo"));
|
|
8
|
+
const RandomEngine_1 = __importDefault(require("./RandomEngine"));
|
|
8
9
|
class CryptoEngineClass {
|
|
9
10
|
constructor() {
|
|
10
11
|
this.hashQuery = (maskType, fieldReference, fieldName) => {
|
|
@@ -24,7 +25,7 @@ class CryptoEngineClass {
|
|
|
24
25
|
this.valueToHash = (value) => {
|
|
25
26
|
return crypto_1.default.createHash('sha256').update(JSON.stringify(value)).digest('hex');
|
|
26
27
|
};
|
|
27
|
-
this.hashValue = (maskType, value) => {
|
|
28
|
+
this.hashValue = (maskType, value, valueType) => {
|
|
28
29
|
if (!Algo_1.default.hasVal(value))
|
|
29
30
|
return value;
|
|
30
31
|
if (!Algo_1.default.hasVal(maskType))
|
|
@@ -32,6 +33,24 @@ class CryptoEngineClass {
|
|
|
32
33
|
switch (maskType) {
|
|
33
34
|
case 'hash':
|
|
34
35
|
return this.valueToHash(value);
|
|
36
|
+
case 'random': {
|
|
37
|
+
switch (valueType) {
|
|
38
|
+
case 'datetime': return RandomEngine_1.default.rngDate();
|
|
39
|
+
case 'number': return RandomEngine_1.default.rng();
|
|
40
|
+
case 'string': return this.valueToHash(value);
|
|
41
|
+
default:
|
|
42
|
+
throw new Error('Not implemented yet');
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
case 'seeded-random': {
|
|
46
|
+
switch (valueType) {
|
|
47
|
+
case 'datetime': return RandomEngine_1.default.sRngDate(value);
|
|
48
|
+
case 'number': return RandomEngine_1.default.sRng(value);
|
|
49
|
+
case 'string': return this.valueToHash(value);
|
|
50
|
+
default:
|
|
51
|
+
throw new Error('Not implemented yet');
|
|
52
|
+
}
|
|
53
|
+
}
|
|
35
54
|
case 'crypt':
|
|
36
55
|
throw new Error('Not implemented yet');
|
|
37
56
|
case 'mask':
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const seedrandom_1 = __importDefault(require("seedrandom"));
|
|
7
|
+
const Algo_1 = __importDefault(require("../core/Algo"));
|
|
8
|
+
class RandomEngineClass {
|
|
9
|
+
constructor() {
|
|
10
|
+
this.rng = (min, max) => {
|
|
11
|
+
const rng = Math.random;
|
|
12
|
+
if (Algo_1.default.hasVal(min) || Algo_1.default.hasVal(max))
|
|
13
|
+
return Math.floor(rng() * (max - min + 1)) + min;
|
|
14
|
+
else
|
|
15
|
+
return rng();
|
|
16
|
+
};
|
|
17
|
+
this.sRng = (seed, min, max) => {
|
|
18
|
+
const rng = (0, seedrandom_1.default)(String(seed));
|
|
19
|
+
if (Algo_1.default.hasVal(min) || Algo_1.default.hasVal(max))
|
|
20
|
+
return Math.floor(rng() * (max - min + 1)) + min;
|
|
21
|
+
else
|
|
22
|
+
return rng();
|
|
23
|
+
};
|
|
24
|
+
this.rngDate = (min, max) => {
|
|
25
|
+
const randomNumber = this.rng(min, max);
|
|
26
|
+
return new Date(randomNumber).toJSON();
|
|
27
|
+
};
|
|
28
|
+
this.sRngDate = (seed, min, max) => {
|
|
29
|
+
const randomNumber = this.sRng(seed, min, max);
|
|
30
|
+
return new Date(randomNumber).toJSON();
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const RandomEngine = new RandomEngineClass();
|
|
35
|
+
exports.default = RandomEngine;
|
|
@@ -33,15 +33,16 @@ class PostProcessorClass {
|
|
|
33
33
|
const groups = Algo_1.default.groupBy(items, groupingRule.groupingKey);
|
|
34
34
|
const projections = [];
|
|
35
35
|
groups.forEach(gItems => {
|
|
36
|
-
var _a;
|
|
36
|
+
var _a, _b, _c;
|
|
37
37
|
const projected = {};
|
|
38
38
|
const first = gItems[0];
|
|
39
39
|
for (const field of allFields) {
|
|
40
40
|
const { key, alias, grouping } = field.cField;
|
|
41
41
|
const fieldKey = alias !== null && alias !== void 0 ? alias : key;
|
|
42
42
|
const maskType = (_a = field.dimension) === null || _a === void 0 ? void 0 : _a.mask;
|
|
43
|
+
const fieldType = (_c = (_b = field.dimension) === null || _b === void 0 ? void 0 : _b.type) !== null && _c !== void 0 ? _c : 'string';
|
|
43
44
|
if (!field.cField.grouping) {
|
|
44
|
-
projected[fieldKey] = CryptoEngine_1.default.hashValue(maskType, first[fieldKey]);
|
|
45
|
+
projected[fieldKey] = CryptoEngine_1.default.hashValue(maskType, first[fieldKey], fieldType);
|
|
45
46
|
}
|
|
46
47
|
else {
|
|
47
48
|
const { subFields } = grouping;
|
|
@@ -64,7 +65,7 @@ class PostProcessorClass {
|
|
|
64
65
|
const fieldType = (_c = (_b = field.dimension) === null || _b === void 0 ? void 0 : _b.type) !== null && _c !== void 0 ? _c : 'string';
|
|
65
66
|
const fieldValue = this._getFieldValue(x, field);
|
|
66
67
|
if (Algo_1.default.hasVal(maskType))
|
|
67
|
-
projected[fieldKey] = CryptoEngine_1.default.hashValue(maskType, fieldValue);
|
|
68
|
+
projected[fieldKey] = CryptoEngine_1.default.hashValue(maskType, fieldValue, fieldType);
|
|
68
69
|
else
|
|
69
70
|
projected[fieldKey] = TypeCaster_1.default.cast(fieldValue, fieldType);
|
|
70
71
|
}
|
|
@@ -87,9 +88,10 @@ class PostProcessorClass {
|
|
|
87
88
|
const columns = FileCompiler_1.default.compileProducer(producer, source);
|
|
88
89
|
(0, Affirm_1.default)(columns, `Invalid columns from compilation for producer "${producer.name}"`);
|
|
89
90
|
const unpackDimension = (item, dimension) => {
|
|
90
|
-
var _a;
|
|
91
|
+
var _a, _b, _c;
|
|
91
92
|
const { nameInProducer, aliasInProducer } = dimension;
|
|
92
93
|
const maskType = (_a = dimension.dimension.mask) !== null && _a !== void 0 ? _a : undefined;
|
|
94
|
+
const fieldType = (_c = (_b = dimension.dimension) === null || _b === void 0 ? void 0 : _b.type) !== null && _c !== void 0 ? _c : 'string';
|
|
93
95
|
const keys = aliasInProducer.split('.');
|
|
94
96
|
let prevValue = item;
|
|
95
97
|
for (const key of keys) {
|
|
@@ -114,7 +116,7 @@ class PostProcessorClass {
|
|
|
114
116
|
prevValue = prevValue === null || prevValue === void 0 ? void 0 : prevValue[key];
|
|
115
117
|
}
|
|
116
118
|
}
|
|
117
|
-
prevValue = CryptoEngine_1.default.hashValue(maskType, prevValue);
|
|
119
|
+
prevValue = CryptoEngine_1.default.hashValue(maskType, prevValue, fieldType);
|
|
118
120
|
const res = { [nameInProducer]: prevValue };
|
|
119
121
|
return res;
|
|
120
122
|
};
|
|
@@ -104,7 +104,8 @@ class ExecutionPlannerClas {
|
|
|
104
104
|
plan.push({ type: 'read-file-lines', producer, lines: { from: (_a = options.offset) !== null && _a !== void 0 ? _a : 0, to: options.limit ? (options.offset + options.limit) : undefined } });
|
|
105
105
|
else
|
|
106
106
|
plan.push({ type: 'read-file-whole', producer });
|
|
107
|
-
|
|
107
|
+
const fileType = (_b = producer.settings.fileType) === null || _b === void 0 ? void 0 : _b.toUpperCase();
|
|
108
|
+
if (fileType === 'CSV' || fileType === 'TXT' || fileType === 'XLS' || fileType === 'XLSX')
|
|
108
109
|
plan.push({ type: 'csv-to-json', producer });
|
|
109
110
|
if (producer.dimensions.some(x => { var _a, _b; return ((_a = x.alias) === null || _a === void 0 ? void 0 : _a.includes('{')) || ((_b = x.alias) === null || _b === void 0 ? void 0 : _b.includes('[')); }))
|
|
110
111
|
plan.push({ type: 'nested-field-unpacking', producer });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forzalabs/remora",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.29",
|
|
4
4
|
"description": "A powerful CLI tool for seamless data translation.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"private": false,
|
|
@@ -54,6 +54,7 @@
|
|
|
54
54
|
"ora": "^5.4.1",
|
|
55
55
|
"react": "^18.2.0",
|
|
56
56
|
"react-dom": "^18.2.0",
|
|
57
|
+
"seedrandom": "^3.0.5",
|
|
57
58
|
"xlsx": "^0.18.5",
|
|
58
59
|
"zod": "^3.24.2"
|
|
59
60
|
},
|