realitydb 1.7.0 → 1.8.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.
Files changed (2) hide show
  1. package/dist/index.js +140 -14
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -22938,11 +22938,13 @@ function generateEnum(ctx, values, weights) {
22938
22938
  if (!weights || weights.length === 0) {
22939
22939
  result = ctx.seed.pick(values);
22940
22940
  } else {
22941
+ const sum = weights.reduce((a, b) => a + b, 0);
22942
+ const normalized = sum > 0 && Math.abs(sum - 1) > 1e-3 ? weights.map((w) => w / sum) : weights;
22941
22943
  const roll = ctx.seed.next();
22942
22944
  let cumulative = 0;
22943
22945
  result = values[values.length - 1];
22944
22946
  for (let i = 0; i < values.length; i++) {
22945
- cumulative += weights[i];
22947
+ cumulative += normalized[i];
22946
22948
  if (roll < cumulative) {
22947
22949
  result = values[i];
22948
22950
  break;
@@ -23185,6 +23187,10 @@ function generateDataset(plan) {
23185
23187
  }
23186
23188
  }
23187
23189
  }
23190
+ if (tablePlan.temporalConstraints && tablePlan.temporalConstraints.length > 0) {
23191
+ applyTemporalFixup(row, tablePlan.temporalConstraints, seed);
23192
+ }
23193
+ applyLifecycleRules(row, tablePlan.columns);
23188
23194
  rows.push(row);
23189
23195
  }
23190
23196
  const generatedTable = {
@@ -23206,6 +23212,49 @@ function generateDataset(plan) {
23206
23212
  totalRows
23207
23213
  };
23208
23214
  }
23215
+ function applyTemporalFixup(row, constraints, seed) {
23216
+ for (const constraint of constraints) {
23217
+ if (constraint.mode !== "dependent" || !constraint.afterColumn)
23218
+ continue;
23219
+ const baseValue = row[constraint.afterColumn];
23220
+ const depValue = row[constraint.columnName];
23221
+ if (baseValue == null || depValue == null)
23222
+ continue;
23223
+ if (typeof baseValue !== "string" && !(baseValue instanceof Date))
23224
+ continue;
23225
+ const baseDate = new Date(baseValue);
23226
+ if (isNaN(baseDate.getTime()))
23227
+ continue;
23228
+ const depDate = new Date(depValue);
23229
+ const withinDays = constraint.withinDays ?? 90;
23230
+ if (isNaN(depDate.getTime()) || depDate <= baseDate) {
23231
+ const offsetMs = (1 + Math.floor(seed.next() * withinDays)) * 864e5;
23232
+ const newDate = new Date(baseDate.getTime() + offsetMs);
23233
+ row[constraint.columnName] = newDate.toISOString();
23234
+ }
23235
+ }
23236
+ }
23237
+ function applyLifecycleRules(row, columns) {
23238
+ for (const colPlan of columns) {
23239
+ if (colPlan.strategy.kind !== "enum")
23240
+ continue;
23241
+ const lifecycleRules = colPlan.strategy.options?.["lifecycleRules"];
23242
+ if (!lifecycleRules || !Array.isArray(lifecycleRules))
23243
+ continue;
23244
+ const currentValue = row[colPlan.columnName];
23245
+ if (typeof currentValue !== "string")
23246
+ continue;
23247
+ for (const rule of lifecycleRules) {
23248
+ if (rule.value === currentValue && Array.isArray(rule.nullFields)) {
23249
+ for (const field of rule.nullFields) {
23250
+ if (field in row) {
23251
+ row[field] = null;
23252
+ }
23253
+ }
23254
+ }
23255
+ }
23256
+ }
23257
+ }
23209
23258
 
23210
23259
  // ../../packages/generators/dist/exporters/json.js
23211
23260
  var import_promises = require("fs/promises");
@@ -29554,6 +29603,19 @@ function validateTemplateJSON(json) {
29554
29603
  if (c.options !== void 0 && (typeof c.options !== "object" || Array.isArray(c.options))) {
29555
29604
  errors.push(`Table "${tableName}".columns."${colName}": "options" must be an object`);
29556
29605
  }
29606
+ if (c.foreignKey !== void 0) {
29607
+ if (typeof c.foreignKey !== "object" || Array.isArray(c.foreignKey) || c.foreignKey === null) {
29608
+ errors.push(`Table "${tableName}".columns."${colName}": "foreignKey" must be an object`);
29609
+ } else {
29610
+ const fk = c.foreignKey;
29611
+ if (typeof fk.table !== "string" || !fk.table) {
29612
+ errors.push(`Table "${tableName}".columns."${colName}": "foreignKey.table" must be a non-empty string`);
29613
+ }
29614
+ if (typeof fk.column !== "string" || !fk.column) {
29615
+ errors.push(`Table "${tableName}".columns."${colName}": "foreignKey.column" must be a non-empty string`);
29616
+ }
29617
+ }
29618
+ }
29557
29619
  }
29558
29620
  }
29559
29621
  return { valid: errors.length === 0, errors };
@@ -29594,15 +29656,31 @@ function convertToDomainTemplate(json) {
29594
29656
  const columnOverrides = [];
29595
29657
  for (const [colName, colJson] of Object.entries(tableJson.columns)) {
29596
29658
  const col = colJson;
29597
- columnOverrides.push({
29598
- columnName: colName,
29599
- matchPattern: col.match,
29600
- strategy: {
29601
- kind: col.strategy,
29602
- options: col.options
29603
- },
29604
- description: col.description
29605
- });
29659
+ if (col.foreignKey) {
29660
+ columnOverrides.push({
29661
+ columnName: colName,
29662
+ matchPattern: col.match,
29663
+ strategy: {
29664
+ kind: "foreign_key",
29665
+ options: {
29666
+ ...col.options,
29667
+ referencedTable: col.foreignKey.table,
29668
+ referencedColumn: col.foreignKey.column
29669
+ }
29670
+ },
29671
+ description: col.description
29672
+ });
29673
+ } else {
29674
+ columnOverrides.push({
29675
+ columnName: colName,
29676
+ matchPattern: col.match,
29677
+ strategy: {
29678
+ kind: col.strategy,
29679
+ options: col.options
29680
+ },
29681
+ description: col.description
29682
+ });
29683
+ }
29606
29684
  }
29607
29685
  tableConfigs.set(tableName, {
29608
29686
  tableName,
@@ -29616,7 +29694,9 @@ function convertToDomainTemplate(json) {
29616
29694
  version: json.version,
29617
29695
  description: json.description,
29618
29696
  targetTables,
29619
- tableConfigs
29697
+ tableConfigs,
29698
+ simulation: json.simulation,
29699
+ generationConfig: json.generationConfig
29620
29700
  };
29621
29701
  }
29622
29702
 
@@ -29973,7 +30053,7 @@ var fintechLifecycle = {
29973
30053
 
29974
30054
  // ../../packages/core/dist/planning/buildPlan.js
29975
30055
  function buildGenerationPlan(schema, config, timelineConfig) {
29976
- const defaultRowCount = config.seed.defaultRecords;
30056
+ let defaultRowCount = config.seed.defaultRecords;
29977
30057
  const batchSize = config.seed.batchSize;
29978
30058
  const environment = config.seed.environment ?? "dev";
29979
30059
  const randomSeed = config.seed.randomSeed ?? 42;
@@ -30090,18 +30170,41 @@ function buildGenerationPlan(schema, config, timelineConfig) {
30090
30170
  selectionMode: "uniform"
30091
30171
  };
30092
30172
  columnPlan.foreignKeyRef = ref;
30173
+ } else if (strategy.kind === "foreign_key" && strategy.options?.["referencedTable"] && strategy.options?.["referencedColumn"]) {
30174
+ columnPlan.strategy = { kind: "foreign_key" };
30175
+ columnPlan.foreignKeyRef = {
30176
+ referencedTable: strategy.options["referencedTable"],
30177
+ referencedColumn: strategy.options["referencedColumn"],
30178
+ selectionMode: "uniform"
30179
+ };
30093
30180
  }
30094
30181
  return columnPlan;
30095
30182
  });
30183
+ const templateTemporalConstraints = [];
30184
+ for (const colPlan of columns) {
30185
+ const opts = colPlan.strategy.options;
30186
+ if (opts?.["dependsOn"] && typeof opts["dependsOn"] === "string") {
30187
+ templateTemporalConstraints.push({
30188
+ columnName: colPlan.columnName,
30189
+ afterColumn: opts["dependsOn"],
30190
+ mode: "dependent",
30191
+ withinDays: 90
30192
+ });
30193
+ }
30194
+ }
30096
30195
  const rowCount = tableConfig?.rowCountMultiplier ? Math.round(defaultRowCount * tableConfig.rowCountMultiplier) : defaultRowCount;
30097
30196
  const enabled = template ? tableConfig !== null : true;
30098
- return {
30197
+ const tablePlan = {
30099
30198
  tableName: table.name,
30100
30199
  rowCount,
30101
30200
  dependencies: uniqueDeps,
30102
30201
  columns,
30103
30202
  enabled
30104
30203
  };
30204
+ if (templateTemporalConstraints.length > 0) {
30205
+ tablePlan.temporalConstraints = templateTemporalConstraints;
30206
+ }
30207
+ return tablePlan;
30105
30208
  });
30106
30209
  if (template) {
30107
30210
  const enabledSet = new Set(tables.filter((t) => t.enabled).map((t) => t.tableName));
@@ -30452,6 +30555,17 @@ async function batchInsertDataset(client, dataset, tableOrder, batchSize, dialec
30452
30555
  const start = performance.now();
30453
30556
  const results = [];
30454
30557
  let totalRows = 0;
30558
+ const targetTables = tableOrder.filter((name) => dataset.tables.has(name));
30559
+ for (let i = targetTables.length - 1; i >= 0; i--) {
30560
+ const tableName = quoteIdent(dialect, targetTables[i]);
30561
+ if (dialect === "mysql") {
30562
+ await client.query("SET FOREIGN_KEY_CHECKS = 0");
30563
+ await client.query(`TRUNCATE TABLE ${tableName}`);
30564
+ await client.query("SET FOREIGN_KEY_CHECKS = 1");
30565
+ } else {
30566
+ await client.query(`TRUNCATE TABLE ${tableName} CASCADE`);
30567
+ }
30568
+ }
30455
30569
  for (const tableName of tableOrder) {
30456
30570
  const table = dataset.tables.get(tableName);
30457
30571
  if (!table)
@@ -31136,6 +31250,18 @@ async function seedDatabase(config, options) {
31136
31250
  if (options?.template !== void 0) {
31137
31251
  effectiveConfig.template = options.template;
31138
31252
  }
31253
+ if (options?.records === void 0 && effectiveConfig.template) {
31254
+ const isFilePath = effectiveConfig.template.includes("/") || effectiveConfig.template.includes("\\") || effectiveConfig.template.endsWith(".json");
31255
+ if (isFilePath) {
31256
+ try {
31257
+ const tmpl = loadTemplateFromJSON(effectiveConfig.template);
31258
+ if (tmpl.generationConfig?.seed?.defaultRecords) {
31259
+ effectiveConfig.seed.defaultRecords = tmpl.generationConfig.seed.defaultRecords;
31260
+ }
31261
+ } catch {
31262
+ }
31263
+ }
31264
+ }
31139
31265
  const timelineConfig = options?.timeline ? parseTimelineString(options.timeline) : void 0;
31140
31266
  if (timelineConfig) {
31141
31267
  timelineConfig.growthModel.finalCount = effectiveConfig.seed.defaultRecords;
@@ -35154,7 +35280,7 @@ async function simulateWebhooksCommand(options) {
35154
35280
  }
35155
35281
 
35156
35282
  // src/cli.ts
35157
- var VERSION16 = "1.7.0";
35283
+ var VERSION16 = "1.8.0";
35158
35284
  function run(argv) {
35159
35285
  const program2 = new Command();
35160
35286
  program2.name("realitydb").description("RealityDB \xC3\u0192\xC6\u2019\xC3\u2020\xE2\u20AC\u2122\xC3\u0192\xE2\u20AC\u0161\xC3\u201A\xC2\xA2\xC3\u0192\xC6\u2019\xC3\u201A\xC2\xA2\xC3\u0192\xC2\xA2\xC3\xA2\xE2\u20AC\u0161\xC2\xAC\xC3\u2026\xC2\xA1\xC3\u0192\xE2\u20AC\u0161\xC3\u201A\xC2\xAC\xC3\u0192\xC6\u2019\xC3\u201A\xC2\xA2\xC3\u0192\xC2\xA2\xC3\xA2\xE2\u201A\xAC\xC5\xA1\xC3\u201A\xC2\xAC\xC3\u0192\xE2\u20AC\u0161\xC3\u201A\xC2\x9D Developer Reality Platform").version(VERSION16).option("--config <path>", "Path to config file").option("--ci", "CI mode: JSON output, no prompts, proper exit codes", false).option("--verbose", "Enable verbose output", false);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "realitydb",
3
- "version": "1.7.0",
3
+ "version": "1.8.0",
4
4
  "description": "Developer Reality Platform - realistic database environments from your schema",
5
5
  "license": "MIT",
6
6
  "keywords": [