@forzalabs/remora 1.5.0 → 1.6.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.
package/CHANGELOG.md CHANGED
@@ -6,6 +6,14 @@ The format is based on Keep a Changelog, and this project adheres to Semantic Ve
6
6
 
7
7
  ## Unreleased
8
8
 
9
+ ## V 1.6.0 - 2026-07-21
10
+
11
+ ### Added
12
+ - Added an optional `decimals` property on producer dimensions to control how many decimal places generated `number` values get for synthetic-data generation (`synth`). `decimals: 0` forces whole integers (so values load into an `integer` column), and a positive value rounds to that many decimals — so generated numbers load without decimal-into-integer failures. Metadata only; no effect on normal producer reads
13
+
14
+ ### Fixed
15
+ - Fixed synthetic-data generation (`synth`) emitting `YYYYMMDD` integer dates into rate/proportion/percentage columns. A field name such as `..._year_to_date_percentage` contains the substring `_date` (inside `to_date`) and was matched by the date generator, overflowing e.g. a `numeric(10,4)` column. Rate/adherence metric topics (`percentage`, `proportion`, `days_covered`, `pdc`, `probability`) are now matched ahead of the date topic, so these columns get a proportion/percentage value instead of a date
16
+
9
17
  ## V 1.5.0 - 2026-07-15
10
18
 
11
19
  ### Added
package/index.js CHANGED
@@ -13394,7 +13394,7 @@ var CONSTANTS, Constants_default;
13394
13394
  var init_Constants = __esm({
13395
13395
  "../../packages/constants/src/Constants.ts"() {
13396
13396
  CONSTANTS = {
13397
- cliVersion: "1.5.0",
13397
+ cliVersion: "1.6.0",
13398
13398
  backendVersion: 1,
13399
13399
  backendPort: 5088,
13400
13400
  workerVersion: 2,
@@ -44859,13 +44859,14 @@ var init_MockDataFactory = __esm({
44859
44859
  { keys: ["plan_name"], gen: () => `${r6.helpers.arrayElement(PAYERS)} ${r6.helpers.arrayElement(PLAN_SUFFIXES)}` }
44860
44860
  ];
44861
44861
  HEALTHCARE_NUMBER_TOPICS = [
44862
+ { keys: ["percentage", "percent"], gen: () => r6.number.float({ min: 0, max: 100, fractionDigits: 2 }) },
44863
+ { keys: ["proportion_of_days", "days_covered", "proportion", "pdc", "probability"], gen: () => r6.number.float({ min: 0, max: 1, fractionDigits: 4 }) },
44862
44864
  { keys: ["year_month"], gen: () => Number(`${r6.number.int({ min: 2019, max: 2024 })}${String(r6.number.int({ min: 1, max: 12 })).padStart(2, "0")}`) },
44863
44865
  { keys: ["birth_date", "_date"], gen: () => Number((0, import_dayjs3.default)(r6.date.between({ from: DATE_FROM, to: DATE_TO })).format("YYYYMMDD")) },
44864
44866
  { keys: ["numerator", "denominator", "_count"], gen: () => r6.number.int({ min: 0, max: 500 }) },
44865
44867
  { keys: ["systolic"], gen: () => r6.number.int({ min: 95, max: 180 }) },
44866
44868
  { keys: ["diastolic"], gen: () => r6.number.int({ min: 55, max: 110 }) },
44867
- { keys: ["hba1c"], gen: () => r6.number.float({ min: 5, max: 13, fractionDigits: 1 }) },
44868
- { keys: ["probability", "proportion", "pdc"], gen: () => r6.number.float({ min: 0, max: 1, fractionDigits: 3 }) }
44869
+ { keys: ["hba1c"], gen: () => r6.number.float({ min: 5, max: 13, fractionDigits: 1 }) }
44869
44870
  ];
44870
44871
  STRING_TOPICS = [
44871
44872
  ...HEALTHCARE_STRING_TOPICS,
@@ -44945,11 +44946,19 @@ var init_MockDataFactory = __esm({
44945
44946
  return topic ? topic.gen() : r6.lorem.words({ min: 1, max: 3 });
44946
44947
  };
44947
44948
  this._number = (spec) => {
44949
+ const value = this._rawNumber(spec);
44950
+ return spec.decimals === void 0 ? value : this._round(value, spec.decimals);
44951
+ };
44952
+ this._rawNumber = (spec) => {
44948
44953
  if (spec.min !== void 0 || spec.max !== void 0)
44949
44954
  return r6.number.int({ min: Math.round(spec.min ?? 0), max: Math.round(spec.max ?? 1e3) });
44950
44955
  const topic = this._match(NUMBER_TOPICS, spec.name);
44951
44956
  return topic ? topic.gen() : r6.number.int({ min: 0, max: 1e3 });
44952
44957
  };
44958
+ this._round = (value, decimals) => {
44959
+ const factor = Math.pow(10, decimals);
44960
+ return Math.round(value * factor) / factor;
44961
+ };
44953
44962
  this._datetime = (spec) => {
44954
44963
  const date2 = r6.date.between({ from: DATE_FROM, to: DATE_TO });
44955
44964
  return spec.format ? (0, import_dayjs3.default)(date2).format(spec.format) : date2.toISOString();
@@ -45095,6 +45104,7 @@ var init_SyntheticInputEngine = __esm({
45095
45104
  name,
45096
45105
  type: dim.type ?? "string",
45097
45106
  format: dim.format,
45107
+ decimals: dim.decimals,
45098
45108
  isPk: dim.pk === true,
45099
45109
  isKey: !isValue && (dim.pk === true || this._isKeyName(name)),
45100
45110
  enumValues,
@@ -48,6 +48,11 @@
48
48
  "type": "string",
49
49
  "description": "Optional source format used when parsing/casting the value, e.g. a date format like 'YYYYMMDD' or 'DD-MM-YYYY'."
50
50
  },
51
+ "decimals": {
52
+ "type": "integer",
53
+ "minimum": 0,
54
+ "description": "How many decimal places generated number values should have. Used only by synthetic-data generation ('synth'): 0 forces whole integers (so values load into an integer column); a positive value rounds to that many decimals. Omit to keep the generator's own value."
55
+ },
51
56
  "alias": {
52
57
  "type": "string",
53
58
  "description": "The SQL column or field key that corresponds to this dimension. If left empty, the column name is assumed to be the same as the dimension name."
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@forzalabs/remora",
3
- "version": "1.5.0",
3
+ "version": "1.6.0",
4
4
  "description": "A powerful CLI tool for seamless data translation.",
5
5
  "main": "index.js",
6
6
  "private": false,
@@ -13393,7 +13393,7 @@ var CONSTANTS, Constants_default;
13393
13393
  var init_Constants = __esm({
13394
13394
  "../../packages/constants/src/Constants.ts"() {
13395
13395
  CONSTANTS = {
13396
- cliVersion: "1.5.0",
13396
+ cliVersion: "1.6.0",
13397
13397
  backendVersion: 1,
13398
13398
  backendPort: 5088,
13399
13399
  workerVersion: 2,
@@ -44566,13 +44566,14 @@ var init_MockDataFactory = __esm({
44566
44566
  { keys: ["plan_name"], gen: () => `${r6.helpers.arrayElement(PAYERS)} ${r6.helpers.arrayElement(PLAN_SUFFIXES)}` }
44567
44567
  ];
44568
44568
  HEALTHCARE_NUMBER_TOPICS = [
44569
+ { keys: ["percentage", "percent"], gen: () => r6.number.float({ min: 0, max: 100, fractionDigits: 2 }) },
44570
+ { keys: ["proportion_of_days", "days_covered", "proportion", "pdc", "probability"], gen: () => r6.number.float({ min: 0, max: 1, fractionDigits: 4 }) },
44569
44571
  { keys: ["year_month"], gen: () => Number(`${r6.number.int({ min: 2019, max: 2024 })}${String(r6.number.int({ min: 1, max: 12 })).padStart(2, "0")}`) },
44570
44572
  { keys: ["birth_date", "_date"], gen: () => Number((0, import_dayjs3.default)(r6.date.between({ from: DATE_FROM, to: DATE_TO })).format("YYYYMMDD")) },
44571
44573
  { keys: ["numerator", "denominator", "_count"], gen: () => r6.number.int({ min: 0, max: 500 }) },
44572
44574
  { keys: ["systolic"], gen: () => r6.number.int({ min: 95, max: 180 }) },
44573
44575
  { keys: ["diastolic"], gen: () => r6.number.int({ min: 55, max: 110 }) },
44574
- { keys: ["hba1c"], gen: () => r6.number.float({ min: 5, max: 13, fractionDigits: 1 }) },
44575
- { keys: ["probability", "proportion", "pdc"], gen: () => r6.number.float({ min: 0, max: 1, fractionDigits: 3 }) }
44576
+ { keys: ["hba1c"], gen: () => r6.number.float({ min: 5, max: 13, fractionDigits: 1 }) }
44576
44577
  ];
44577
44578
  STRING_TOPICS = [
44578
44579
  ...HEALTHCARE_STRING_TOPICS,
@@ -44652,11 +44653,19 @@ var init_MockDataFactory = __esm({
44652
44653
  return topic ? topic.gen() : r6.lorem.words({ min: 1, max: 3 });
44653
44654
  };
44654
44655
  this._number = (spec) => {
44656
+ const value = this._rawNumber(spec);
44657
+ return spec.decimals === void 0 ? value : this._round(value, spec.decimals);
44658
+ };
44659
+ this._rawNumber = (spec) => {
44655
44660
  if (spec.min !== void 0 || spec.max !== void 0)
44656
44661
  return r6.number.int({ min: Math.round(spec.min ?? 0), max: Math.round(spec.max ?? 1e3) });
44657
44662
  const topic = this._match(NUMBER_TOPICS, spec.name);
44658
44663
  return topic ? topic.gen() : r6.number.int({ min: 0, max: 1e3 });
44659
44664
  };
44665
+ this._round = (value, decimals) => {
44666
+ const factor = Math.pow(10, decimals);
44667
+ return Math.round(value * factor) / factor;
44668
+ };
44660
44669
  this._datetime = (spec) => {
44661
44670
  const date2 = r6.date.between({ from: DATE_FROM, to: DATE_TO });
44662
44671
  return spec.format ? (0, import_dayjs3.default)(date2).format(spec.format) : date2.toISOString();
@@ -44802,6 +44811,7 @@ var init_SyntheticInputEngine = __esm({
44802
44811
  name,
44803
44812
  type: dim.type ?? "string",
44804
44813
  format: dim.format,
44814
+ decimals: dim.decimals,
44805
44815
  isPk: dim.pk === true,
44806
44816
  isKey: !isValue && (dim.pk === true || this._isKeyName(name)),
44807
44817
  enumValues,