realitydb 1.4.2 → 1.4.4

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 +107 -95
  2. package/package.json +3 -1
package/dist/index.js CHANGED
@@ -10478,27 +10478,27 @@ var saasLifecycle = {
10478
10478
  {
10479
10479
  name: "trial",
10480
10480
  weight: 0.12,
10481
- columnValues: {}
10481
+ columnValues: { status: "active" }
10482
10482
  },
10483
10483
  {
10484
10484
  name: "active",
10485
10485
  weight: 0.65,
10486
- columnValues: {}
10486
+ columnValues: { status: "active" }
10487
10487
  },
10488
10488
  {
10489
10489
  name: "churned",
10490
10490
  weight: 0.1,
10491
- columnValues: {}
10491
+ columnValues: { status: "inactive" }
10492
10492
  },
10493
10493
  {
10494
10494
  name: "past_due",
10495
10495
  weight: 0.08,
10496
- columnValues: {}
10496
+ columnValues: { status: "active" }
10497
10497
  },
10498
10498
  {
10499
10499
  name: "paused",
10500
10500
  weight: 0.05,
10501
- columnValues: {}
10501
+ columnValues: { status: "inactive" }
10502
10502
  }
10503
10503
  ],
10504
10504
  transitions: [
@@ -10510,7 +10510,7 @@ var saasLifecycle = {
10510
10510
  {
10511
10511
  table: "subscriptions",
10512
10512
  action: "create",
10513
- values: { status: "active", plan: "Professional" }
10513
+ values: { status: "active" }
10514
10514
  },
10515
10515
  {
10516
10516
  table: "payments",
@@ -10613,20 +10613,6 @@ var saasLifecycle = {
10613
10613
  }
10614
10614
  ],
10615
10615
  correlations: [
10616
- {
10617
- description: "Enterprise plan users have 2x more payments (longer tenure)",
10618
- condition: {
10619
- table: "subscriptions",
10620
- column: "plan",
10621
- operator: "eq",
10622
- value: "Enterprise"
10623
- },
10624
- effect: {
10625
- table: "payments",
10626
- column: "amount_cents",
10627
- multiplier: 2
10628
- }
10629
- },
10630
10616
  {
10631
10617
  description: "Churned users always have a failed payment before cancel",
10632
10618
  condition: {
@@ -11731,53 +11717,13 @@ async function seedDatabase(config, options) {
11731
11717
  throw new Error(`Generation plan validation failed:
11732
11718
  ${validation.errors.join("\n")}`);
11733
11719
  }
11734
- let dataset;
11735
11720
  const lifecycleUsed = !!options?.lifecycle;
11721
+ let dataset = timelineConfig ? generateTimelineDataset(plan, timelineConfig) : generateDataset(plan);
11736
11722
  if (options?.lifecycle && options?.template) {
11737
11723
  const lifecycle = resolveLifecycle(options.template);
11738
11724
  if (lifecycle) {
11739
- const random = createSeededRandom(plan.reproducibility.randomSeed);
11740
- const entityCount = effectiveConfig.seed.defaultRecords;
11741
- const simResult = simulateLifecycles(lifecycle, entityCount, random);
11742
- const correlatedResult = applyCorrelations(simResult, lifecycle.correlations, random);
11743
- const schemaColumnLookup = /* @__PURE__ */ new Map();
11744
- for (const table of schema.tables) {
11745
- schemaColumnLookup.set(table.name, new Set(table.columns.map((c) => c.name)));
11746
- }
11747
- const tables = /* @__PURE__ */ new Map();
11748
- let totalRows = 0;
11749
- for (const [tableName, rows] of correlatedResult.tables) {
11750
- const validColumns = schemaColumnLookup.get(tableName);
11751
- const filteredRows = validColumns ? rows.map((row) => {
11752
- const filtered = {};
11753
- for (const [col, val] of Object.entries(row)) {
11754
- if (validColumns.has(col)) {
11755
- filtered[col] = val;
11756
- } else {
11757
- console.warn(`[lifecycle] Skipping column '${col}' on table '${tableName}' \u2014 column does not exist`);
11758
- }
11759
- }
11760
- return filtered;
11761
- }) : rows;
11762
- tables.set(tableName, {
11763
- tableName,
11764
- columns: filteredRows.length > 0 ? Object.keys(filteredRows[0]) : [],
11765
- rows: filteredRows,
11766
- rowCount: filteredRows.length
11767
- });
11768
- totalRows += filteredRows.length;
11769
- }
11770
- dataset = {
11771
- tables,
11772
- generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
11773
- seed: plan.reproducibility.randomSeed,
11774
- totalRows
11775
- };
11776
- } else {
11777
- dataset = timelineConfig ? generateTimelineDataset(plan, timelineConfig) : generateDataset(plan);
11725
+ dataset = applyLifecycleOverlay(dataset, lifecycle, plan, schema);
11778
11726
  }
11779
- } else {
11780
- dataset = timelineConfig ? generateTimelineDataset(plan, timelineConfig) : generateDataset(plan);
11781
11727
  }
11782
11728
  let scenariosApplied;
11783
11729
  let scenarioReportData;
@@ -11819,6 +11765,66 @@ ${validation.errors.join("\n")}`);
11819
11765
  await closeConnection(pool);
11820
11766
  }
11821
11767
  }
11768
+ function applyLifecycleOverlay(dataset, lifecycle, plan, schema) {
11769
+ const random = createSeededRandom(plan.reproducibility.randomSeed);
11770
+ const rootTable = dataset.tables.get(lifecycle.rootTable);
11771
+ const entityCount = rootTable?.rowCount ?? plan.tables[0]?.rowCount ?? 0;
11772
+ const simResult = simulateLifecycles(lifecycle, entityCount, random);
11773
+ const correlatedResult = applyCorrelations(simResult, lifecycle.correlations, random);
11774
+ const schemaColumnLookup = /* @__PURE__ */ new Map();
11775
+ for (const table of schema.tables) {
11776
+ schemaColumnLookup.set(table.name, new Set(table.columns.map((c) => c.name)));
11777
+ }
11778
+ const warnedColumns = /* @__PURE__ */ new Set();
11779
+ if (rootTable) {
11780
+ const lifecycleRootRows = correlatedResult.tables.get(lifecycle.rootTable);
11781
+ if (lifecycleRootRows) {
11782
+ const validColumns = schemaColumnLookup.get(lifecycle.rootTable);
11783
+ const count = Math.min(rootTable.rows.length, lifecycleRootRows.length);
11784
+ for (let i = 0; i < count; i++) {
11785
+ for (const [col, val] of Object.entries(lifecycleRootRows[i])) {
11786
+ if (col === "id")
11787
+ continue;
11788
+ if (validColumns && !validColumns.has(col)) {
11789
+ const key = `${lifecycle.rootTable}.${col}`;
11790
+ if (!warnedColumns.has(key)) {
11791
+ console.warn(`[lifecycle] Skipping column '${col}' on table '${lifecycle.rootTable}' \u2014 does not exist in schema`);
11792
+ warnedColumns.add(key);
11793
+ }
11794
+ continue;
11795
+ }
11796
+ rootTable.rows[i][col] = val;
11797
+ }
11798
+ }
11799
+ }
11800
+ }
11801
+ for (const [tableName, lifecycleRows] of correlatedResult.tables) {
11802
+ if (tableName === lifecycle.rootTable)
11803
+ continue;
11804
+ const existingTable = dataset.tables.get(tableName);
11805
+ if (!existingTable || lifecycleRows.length === 0)
11806
+ continue;
11807
+ const validColumns = schemaColumnLookup.get(tableName);
11808
+ const entityIdCol = `${lifecycle.entityName}_id`;
11809
+ const count = Math.min(lifecycleRows.length, existingTable.rows.length);
11810
+ for (let i = 0; i < count; i++) {
11811
+ for (const [col, val] of Object.entries(lifecycleRows[i])) {
11812
+ if (col === "id" || col === entityIdCol)
11813
+ continue;
11814
+ if (validColumns && !validColumns.has(col)) {
11815
+ const key = `${tableName}.${col}`;
11816
+ if (!warnedColumns.has(key)) {
11817
+ console.warn(`[lifecycle] Skipping column '${col}' on table '${tableName}' \u2014 does not exist in schema`);
11818
+ warnedColumns.add(key);
11819
+ }
11820
+ continue;
11821
+ }
11822
+ existingTable.rows[i][col] = val;
11823
+ }
11824
+ }
11825
+ }
11826
+ return dataset;
11827
+ }
11822
11828
  function computeTotalMonths(tc) {
11823
11829
  const start = new Date(tc.startDate);
11824
11830
  const end = new Date(tc.endDate);
@@ -12763,7 +12769,7 @@ var VERSION2 = "0.10.0";
12763
12769
  async function scanCommand(options) {
12764
12770
  const start = performance.now();
12765
12771
  try {
12766
- const config = await loadConfig();
12772
+ const config = await loadConfig(options.configPath);
12767
12773
  const result = await scanDatabase(config);
12768
12774
  const { schema } = result;
12769
12775
  const masked = maskConnectionString(config.database.connectionString);
@@ -12883,7 +12889,7 @@ var VERSION3 = "1.3.1";
12883
12889
  async function seedCommand(options) {
12884
12890
  const start = performance.now();
12885
12891
  try {
12886
- const config = await loadConfig();
12892
+ const config = await loadConfig(options.configPath);
12887
12893
  const records = options.records ? parseInt(options.records, 10) : void 0;
12888
12894
  const seed = options.seed ? parseInt(options.seed, 10) : void 0;
12889
12895
  const rawTemplateName = options.template ?? config.template;
@@ -13093,7 +13099,7 @@ async function resetCommand(options) {
13093
13099
  process.exit(0);
13094
13100
  }
13095
13101
  try {
13096
- const config = await loadConfig();
13102
+ const config = await loadConfig(options.configPath);
13097
13103
  const masked = maskConnectionString(config.database.connectionString);
13098
13104
  if (!options.ci) {
13099
13105
  console.log("");
@@ -13158,7 +13164,7 @@ var VERSION5 = "1.3.1";
13158
13164
  async function exportCommand(options) {
13159
13165
  const start = performance.now();
13160
13166
  try {
13161
- const config = await loadConfig();
13167
+ const config = await loadConfig(options.configPath);
13162
13168
  const format = options.format ?? config.export?.defaultFormat ?? "json";
13163
13169
  const outputDir = options.output ?? config.export?.outputDir ?? "./.realitydb";
13164
13170
  const records = options.records ? parseInt(options.records, 10) : void 0;
@@ -13518,7 +13524,7 @@ var import_node_path13 = require("path");
13518
13524
  var import_promises10 = require("fs/promises");
13519
13525
  async function packExportCommand(options) {
13520
13526
  try {
13521
- const config = await loadConfig();
13527
+ const config = await loadConfig(options.configPath);
13522
13528
  const records = options.records ? parseInt(options.records, 10) : void 0;
13523
13529
  const seed = options.seed ? parseInt(options.seed, 10) : void 0;
13524
13530
  const rawTemplateName = options.template ?? config.template;
@@ -13620,7 +13626,7 @@ async function packImportCommand(filePath, options) {
13620
13626
  console.error("Usage: realitydb pack import <file> --confirm");
13621
13627
  process.exit(1);
13622
13628
  }
13623
- const config = await loadConfig();
13629
+ const config = await loadConfig(options.configPath);
13624
13630
  const masked = maskConnectionString(config.database.connectionString);
13625
13631
  const pack = await loadRealityPack(filePath);
13626
13632
  console.log("");
@@ -13689,7 +13695,7 @@ async function captureCommand(options) {
13689
13695
  console.error("Usage: realitydb capture --name <name>");
13690
13696
  process.exit(1);
13691
13697
  }
13692
- const config = await loadConfig();
13698
+ const config = await loadConfig(options.configPath);
13693
13699
  const masked = maskConnectionString(config.database.connectionString);
13694
13700
  const tables = options.tables ? options.tables.split(",").map((t) => t.trim()).filter((t) => t.length > 0) : void 0;
13695
13701
  if (!options.ci) {
@@ -13935,7 +13941,7 @@ async function loadCommand(filePath, options) {
13935
13941
  }
13936
13942
  return;
13937
13943
  }
13938
- const config = await loadConfig();
13944
+ const config = await loadConfig(options.configPath);
13939
13945
  const masked = maskConnectionString(config.database.connectionString);
13940
13946
  if (!options.ci) {
13941
13947
  console.log("");
@@ -14254,7 +14260,7 @@ var VERSION12 = "1.3.1";
14254
14260
  async function analyzeCommand(options) {
14255
14261
  const start = performance.now();
14256
14262
  try {
14257
- const config = await loadConfig();
14263
+ const config = await loadConfig(options.configPath);
14258
14264
  const sampleSize = options.sampleSize ? parseInt(options.sampleSize, 10) : 1e3;
14259
14265
  const masked = maskConnectionString(config.database.connectionString);
14260
14266
  if (!options.ci) {
@@ -14348,7 +14354,7 @@ var VERSION13 = "1.3.1";
14348
14354
  async function maskCommand(options) {
14349
14355
  const start = performance.now();
14350
14356
  try {
14351
- const config = await loadConfig();
14357
+ const config = await loadConfig(options.configPath);
14352
14358
  const mode = options.mode ?? "gdpr";
14353
14359
  const seed = options.seed ? parseInt(options.seed, 10) : void 0;
14354
14360
  const dryRun = options.dryRun ?? false;
@@ -14557,7 +14563,7 @@ async function classroomListCommand(options) {
14557
14563
  async function classroomStartCommand(courseName, options) {
14558
14564
  const start = performance.now();
14559
14565
  try {
14560
- const config = await loadConfig();
14566
+ const config = await loadConfig(options.configPath);
14561
14567
  const masked = maskConnectionString(config.database.connectionString);
14562
14568
  if (!options.ci) {
14563
14569
  console.log("");
@@ -15010,33 +15016,33 @@ async function simulateWebhooksCommand(options) {
15010
15016
  }
15011
15017
 
15012
15018
  // src/cli.ts
15013
- var VERSION16 = "1.3.1";
15019
+ var VERSION16 = "1.4.4";
15014
15020
  function run(argv) {
15015
15021
  const program2 = new Command();
15016
15022
  program2.name("realitydb").description("RealityDB \u2014 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);
15017
15023
  program2.command("scan").description("Scan database schema").action(async () => {
15018
15024
  const opts = program2.opts();
15019
- await scanCommand({ ci: opts.ci });
15025
+ await scanCommand({ ci: opts.ci, configPath: opts.config });
15020
15026
  });
15021
15027
  program2.command("analyze").description("Analyze database schema and suggest column strategies").option("--output <file>", "Generate a template JSON file from analysis").option("--sample-size <count>", "Number of rows to sample per table", "1000").action(async (cmdOpts) => {
15022
15028
  const opts = program2.opts();
15023
- await analyzeCommand({ ...cmdOpts, ci: opts.ci });
15029
+ await analyzeCommand({ ...cmdOpts, ci: opts.ci, configPath: opts.config });
15024
15030
  });
15025
15031
  program2.command("seed").description("Seed database with generated data").option("--records <count>", "Number of records per table").option("--template <name|path>", "Template name or path to custom .json file").option("--seed <number>", "Random seed for reproducibility").option("--timeline <duration>", 'Timeline duration (e.g., "12-months", "1-year")').option("--scenario <names>", "Scenarios to apply (comma-separated)").option("--scenario-intensity <level>", "Scenario intensity (low|medium|high)", "medium").option("--scenario-schedule <schedule>", 'Timeline-scheduled scenarios (e.g., "fraud-spike:month-6,churn-spike:month-9")').option("--lifecycle", "Enable lifecycle simulation for causally-connected data").action(async (cmdOpts) => {
15026
15032
  const opts = program2.opts();
15027
- await seedCommand({ ...cmdOpts, ci: opts.ci });
15033
+ await seedCommand({ ...cmdOpts, ci: opts.ci, configPath: opts.config });
15028
15034
  });
15029
15035
  program2.command("reset").description("Reset seeded data").option("--confirm", "Confirm destructive operation").action(async (cmdOpts) => {
15030
15036
  const opts = program2.opts();
15031
- await resetCommand({ ...cmdOpts, ci: opts.ci });
15037
+ await resetCommand({ ...cmdOpts, ci: opts.ci, configPath: opts.config });
15032
15038
  });
15033
15039
  program2.command("export").description("Export generated data").option("--format <format>", "Output format (json|csv|sql)", "json").option("--output <dir>", "Output directory", "./.realitydb").option("--records <count>", "Number of records per table").option("--seed <number>", "Random seed for reproducibility").option("--template <name>", "Template to use").option("--timeline <duration>", 'Timeline duration (e.g., "12-months", "1-year")').option("--scenario <names>", "Scenarios to apply (comma-separated)").option("--scenario-intensity <level>", "Scenario intensity (low|medium|high)", "medium").option("--scenario-schedule <schedule>", 'Timeline-scheduled scenarios (e.g., "fraud-spike:month-6,churn-spike:month-9")').action(async (cmdOpts) => {
15034
15040
  const opts = program2.opts();
15035
- await exportCommand({ ...cmdOpts, ci: opts.ci });
15041
+ await exportCommand({ ...cmdOpts, ci: opts.ci, configPath: opts.config });
15036
15042
  });
15037
15043
  program2.command("generate").description("Generate large-scale datasets for data science (no database required)").option("--records <count>", "Number of records to generate", "1000").option("--schema <file>", "Schema definition file (.sql or .json)").option("--format <format>", "Output format (json|csv|parquet)", "json").option("--output <dir>", "Output directory", "./.realitydb/generated").option("--seed <number>", "Random seed for reproducibility").option("--table <name>", "Generate only a specific table").option("--correlations", "Enable cross-column correlations from schema").action(async (cmdOpts) => {
15038
15044
  const opts = program2.opts();
15039
- await generateCommand({ ...cmdOpts, ci: opts.ci });
15045
+ await generateCommand({ ...cmdOpts, ci: opts.ci, configPath: opts.config });
15040
15046
  });
15041
15047
  const templates = program2.command("templates").description("Template management");
15042
15048
  templates.command("list", { isDefault: true }).description("List available domain templates").action(templatesCommand);
@@ -15052,61 +15058,67 @@ function run(argv) {
15052
15058
  });
15053
15059
  program2.command("mask").description("Detect and mask PII in your database").option("--mode <mode>", "Compliance mode (hipaa|gdpr|strict)", "gdpr").option("--seed <number>", "Random seed for deterministic masking").option("--dry-run", "Preview PII detection without modifying data").option("--output <dir>", "Export masked data to files instead of writing to DB").option("--output-format <format>", "Output format (json|csv|sql)", "json").option("--audit-log <file>", "Write audit log to file").option("--confirm", "Confirm writing masked data back to database").action(async (cmdOpts) => {
15054
15060
  const opts = program2.opts();
15055
- await maskCommand({ ...cmdOpts, ci: opts.ci });
15061
+ await maskCommand({ ...cmdOpts, ci: opts.ci, configPath: opts.config });
15056
15062
  });
15057
15063
  const classroom = program2.command("classroom").description("Education and classroom mode");
15058
15064
  classroom.command("list", { isDefault: true }).description("List available courses").action(async () => {
15059
15065
  const opts = program2.opts();
15060
- await classroomListCommand({ ci: opts.ci });
15066
+ await classroomListCommand({ ci: opts.ci, configPath: opts.config });
15061
15067
  });
15062
15068
  classroom.command("start <course>").description("Load a course into your database").action(async (course) => {
15063
15069
  const opts = program2.opts();
15064
- await classroomStartCommand(course, { ci: opts.ci });
15070
+ await classroomStartCommand(course, { ci: opts.ci, configPath: opts.config });
15065
15071
  });
15066
15072
  classroom.command("status [course]").description("Show progress for all courses or a specific course").action(async (course) => {
15067
15073
  const opts = program2.opts();
15068
- await classroomStatusCommand(course, { ci: opts.ci });
15074
+ await classroomStatusCommand(course, { ci: opts.ci, configPath: opts.config });
15069
15075
  });
15070
15076
  classroom.command("complete <course> <exercise>").description("Mark an exercise as completed").action(async (course, exercise) => {
15071
15077
  const opts = program2.opts();
15072
- await classroomCompleteCommand(course, exercise, { ci: opts.ci });
15078
+ await classroomCompleteCommand(course, exercise, { ci: opts.ci, configPath: opts.config });
15073
15079
  });
15074
15080
  classroom.command("reset <course>").description("Reset progress for a course").action(async (course) => {
15075
15081
  const opts = program2.opts();
15076
- await classroomResetCommand(course, { ci: opts.ci });
15082
+ await classroomResetCommand(course, { ci: opts.ci, configPath: opts.config });
15077
15083
  });
15078
15084
  classroom.command("create <name>").description("Scaffold a custom course JSON file").action(async (name) => {
15079
15085
  const opts = program2.opts();
15080
- await classroomCreateCommand(name, { ci: opts.ci });
15086
+ await classroomCreateCommand(name, { ci: opts.ci, configPath: opts.config });
15081
15087
  });
15082
15088
  const simulate = program2.command("simulate").description("System behavior simulation");
15083
15089
  simulate.command("run", { isDefault: true }).description("Run a simulation with a profile").option("--profile <name>", "Simulation profile (saas-startup|ecommerce-peak|api-service)", "saas-startup").option("--duration <duration>", "Override profile duration (e.g., 1-hour, 1-day, 1-week)").option("--events <count>", "Number of events to generate", "1000").option("--seed <number>", "Random seed for reproducibility").option("--output <file>", "Output file path").option("--format <format>", "Output format (json|ndjson)", "json").action(async (cmdOpts) => {
15084
15090
  const opts = program2.opts();
15085
- await simulateRunCommand({ ...cmdOpts, ci: opts.ci });
15091
+ await simulateRunCommand({ ...cmdOpts, ci: opts.ci, configPath: opts.config });
15086
15092
  });
15087
15093
  simulate.command("profiles").description("List available simulation profiles").action(async () => {
15088
15094
  const opts = program2.opts();
15089
- await simulateProfilesCommand({ ci: opts.ci });
15095
+ await simulateProfilesCommand({ ci: opts.ci, configPath: opts.config });
15090
15096
  });
15091
15097
  simulate.command("webhooks").description("Generate webhook events from a specific source").option("--source <source>", "Webhook source (stripe|github)", "stripe").option("--events <count>", "Number of events to generate", "100").option("--seed <number>", "Random seed for reproducibility").option("--output <file>", "Output file path").option("--format <format>", "Output format (json|ndjson)", "json").action(async (cmdOpts) => {
15092
15098
  const opts = program2.opts();
15093
- await simulateWebhooksCommand({ ...cmdOpts, ci: opts.ci });
15099
+ await simulateWebhooksCommand({ ...cmdOpts, ci: opts.ci, configPath: opts.config });
15094
15100
  });
15095
15101
  program2.command("capture").description("Capture live database state into a Reality Pack").requiredOption("--name <name>", "Name for the captured pack").option("--description <desc>", "Pack description").option("--tables <tables>", "Comma-separated list of tables to capture").option("--output <dir>", "Output directory", ".").action(async (cmdOpts) => {
15096
15102
  const opts = program2.opts();
15097
- await captureCommand({ ...cmdOpts, ci: opts.ci });
15103
+ await captureCommand({ ...cmdOpts, ci: opts.ci, configPath: opts.config });
15098
15104
  });
15099
15105
  program2.command("share <file>").description("Share a Reality Pack file").option("--gist", "Upload to GitHub Gist").option("--description <desc>", "Gist description").action(async (filePath, cmdOpts) => {
15100
15106
  const opts = program2.opts();
15101
- await shareCommand(filePath, { ...cmdOpts, ci: opts.ci });
15107
+ await shareCommand(filePath, { ...cmdOpts, ci: opts.ci, configPath: opts.config });
15102
15108
  });
15103
15109
  program2.command("load <file>").description("Load a Reality Pack into the database (file path or URL)").option("--confirm", "Confirm import operation").option("--show-ddl", "Show schema DDL without importing").action(async (filePath, cmdOpts) => {
15104
15110
  const opts = program2.opts();
15105
- await loadCommand(filePath, { ...cmdOpts, ci: opts.ci });
15111
+ await loadCommand(filePath, { ...cmdOpts, ci: opts.ci, configPath: opts.config });
15106
15112
  });
15107
15113
  const pack = program2.command("pack").description("Reality Pack operations");
15108
- pack.command("export").description("Export environment as Reality Pack").option("--name <name>", "Pack name").option("--description <desc>", "Pack description").option("--output <dir>", "Output directory", ".").option("--records <count>", "Number of records per table").option("--seed <number>", "Random seed for reproducibility").option("--template <name>", "Template to use").option("--timeline <duration>", 'Timeline duration (e.g., "12-months", "1-year")').option("--scenario <names>", "Scenarios to apply (comma-separated)").option("--scenario-intensity <level>", "Scenario intensity (low|medium|high)", "medium").option("--scenario-schedule <schedule>", 'Timeline-scheduled scenarios (e.g., "fraud-spike:month-6,churn-spike:month-9")').action(packExportCommand);
15109
- pack.command("import <file>").description("Import Reality Pack into database").option("--confirm", "Confirm import operation").action(packImportCommand);
15114
+ pack.command("export").description("Export environment as Reality Pack").option("--name <name>", "Pack name").option("--description <desc>", "Pack description").option("--output <dir>", "Output directory", ".").option("--records <count>", "Number of records per table").option("--seed <number>", "Random seed for reproducibility").option("--template <name>", "Template to use").option("--timeline <duration>", 'Timeline duration (e.g., "12-months", "1-year")').option("--scenario <names>", "Scenarios to apply (comma-separated)").option("--scenario-intensity <level>", "Scenario intensity (low|medium|high)", "medium").option("--scenario-schedule <schedule>", 'Timeline-scheduled scenarios (e.g., "fraud-spike:month-6,churn-spike:month-9")').action(async (cmdOpts) => {
15115
+ const opts = program2.opts();
15116
+ await packExportCommand({ ...cmdOpts, configPath: opts.config });
15117
+ });
15118
+ pack.command("import <file>").description("Import Reality Pack into database").option("--confirm", "Confirm import operation").action(async (filePath, cmdOpts) => {
15119
+ const opts = program2.opts();
15120
+ await packImportCommand(filePath, { ...cmdOpts, configPath: opts.config });
15121
+ });
15110
15122
  const packs = program2.command("packs").description("Browse available Reality Packs");
15111
15123
  packs.command("list", { isDefault: true }).description("List available demo packs").action(() => {
15112
15124
  const opts = program2.opts();
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "realitydb",
3
- "version": "1.4.2",
3
+
4
+ "version": "1.4.4",
4
5
  "description": "Developer Reality Platform - realistic database environments from your schema",
5
6
  "license": "MIT",
6
7
  "keywords": [
@@ -59,3 +60,4 @@
59
60
  "pg": "^8.20.0"
60
61
  }
61
62
  }
63
+