realitydb 0.2.0 → 0.4.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 +1092 -13
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -5708,6 +5708,474 @@ var educationTemplate = {
5708
5708
  ])
5709
5709
  };
5710
5710
 
5711
+ // ../../packages/templates/dist/domains/fintech.js
5712
+ var fintechTemplate = {
5713
+ name: "fintech",
5714
+ version: "1.0",
5715
+ description: "Financial services with accounts, transactions, fraud alerts, and settlements",
5716
+ targetTables: ["accounts", "transactions", "fraud_alerts", "settlements", "chargebacks"],
5717
+ tableConfigs: /* @__PURE__ */ new Map([
5718
+ ["accounts", {
5719
+ tableName: "accounts",
5720
+ matchPattern: ["accounts", "*account*"],
5721
+ columnOverrides: [
5722
+ {
5723
+ columnName: "account_type",
5724
+ strategy: {
5725
+ kind: "enum",
5726
+ options: {
5727
+ values: ["checking", "savings", "investment", "credit", "business"],
5728
+ weights: [0.35, 0.25, 0.15, 0.15, 0.1]
5729
+ }
5730
+ }
5731
+ },
5732
+ {
5733
+ columnName: "balance_cents",
5734
+ strategy: { kind: "money", options: { min: 0, max: 5e6 } }
5735
+ },
5736
+ {
5737
+ columnName: "currency",
5738
+ strategy: {
5739
+ kind: "enum",
5740
+ options: {
5741
+ values: ["USD", "EUR", "GBP", "CAD", "JPY"],
5742
+ weights: [0.55, 0.2, 0.1, 0.08, 0.07]
5743
+ }
5744
+ }
5745
+ },
5746
+ {
5747
+ columnName: "status",
5748
+ strategy: {
5749
+ kind: "enum",
5750
+ options: {
5751
+ values: ["active", "frozen", "closed", "pending_review"],
5752
+ weights: [0.82, 0.05, 0.08, 0.05]
5753
+ }
5754
+ }
5755
+ },
5756
+ {
5757
+ columnName: "owner_name",
5758
+ strategy: { kind: "full_name" }
5759
+ },
5760
+ {
5761
+ columnName: "email",
5762
+ strategy: { kind: "email" }
5763
+ },
5764
+ {
5765
+ columnName: "account_number",
5766
+ strategy: { kind: "text", options: { mode: "short" } }
5767
+ },
5768
+ {
5769
+ columnName: "opened_at",
5770
+ strategy: { kind: "timestamp", options: { mode: "past" } }
5771
+ }
5772
+ ]
5773
+ }],
5774
+ ["transactions", {
5775
+ tableName: "transactions",
5776
+ matchPattern: ["transactions", "*transaction*", "*transfer*"],
5777
+ columnOverrides: [
5778
+ {
5779
+ columnName: "transaction_type",
5780
+ strategy: {
5781
+ kind: "enum",
5782
+ options: {
5783
+ values: ["deposit", "withdrawal", "transfer", "payment", "refund", "fee"],
5784
+ weights: [0.25, 0.2, 0.2, 0.2, 0.1, 0.05]
5785
+ }
5786
+ }
5787
+ },
5788
+ {
5789
+ columnName: "amount_cents",
5790
+ strategy: { kind: "money", options: { min: 100, max: 5e5 } }
5791
+ },
5792
+ {
5793
+ columnName: "currency",
5794
+ strategy: {
5795
+ kind: "enum",
5796
+ options: {
5797
+ values: ["USD", "EUR", "GBP", "CAD", "JPY"],
5798
+ weights: [0.55, 0.2, 0.1, 0.08, 0.07]
5799
+ }
5800
+ }
5801
+ },
5802
+ {
5803
+ columnName: "status",
5804
+ strategy: {
5805
+ kind: "enum",
5806
+ options: {
5807
+ values: ["completed", "pending", "failed", "reversed", "held"],
5808
+ weights: [0.78, 0.08, 0.05, 0.04, 0.05]
5809
+ }
5810
+ }
5811
+ },
5812
+ {
5813
+ columnName: "description",
5814
+ strategy: { kind: "text", options: { mode: "short" } }
5815
+ },
5816
+ {
5817
+ columnName: "created_at",
5818
+ strategy: { kind: "timestamp", options: { mode: "past" } }
5819
+ }
5820
+ ]
5821
+ }],
5822
+ ["fraud_alerts", {
5823
+ tableName: "fraud_alerts",
5824
+ matchPattern: ["fraud_alerts", "*fraud*", "*alert*"],
5825
+ columnOverrides: [
5826
+ {
5827
+ columnName: "alert_type",
5828
+ strategy: {
5829
+ kind: "enum",
5830
+ options: {
5831
+ values: ["unusual_amount", "velocity_check", "geo_mismatch", "duplicate_transaction", "account_takeover"],
5832
+ weights: [0.3, 0.25, 0.2, 0.15, 0.1]
5833
+ }
5834
+ }
5835
+ },
5836
+ {
5837
+ columnName: "severity",
5838
+ strategy: {
5839
+ kind: "enum",
5840
+ options: {
5841
+ values: ["low", "medium", "high", "critical"],
5842
+ weights: [0.2, 0.4, 0.3, 0.1]
5843
+ }
5844
+ }
5845
+ },
5846
+ {
5847
+ columnName: "status",
5848
+ strategy: {
5849
+ kind: "enum",
5850
+ options: {
5851
+ values: ["open", "investigating", "resolved_fraud", "resolved_legitimate", "escalated"],
5852
+ weights: [0.25, 0.2, 0.3, 0.15, 0.1]
5853
+ }
5854
+ }
5855
+ },
5856
+ {
5857
+ columnName: "description",
5858
+ strategy: { kind: "text", options: { mode: "short" } }
5859
+ },
5860
+ {
5861
+ columnName: "created_at",
5862
+ strategy: { kind: "timestamp", options: { mode: "past" } }
5863
+ }
5864
+ ]
5865
+ }],
5866
+ ["settlements", {
5867
+ tableName: "settlements",
5868
+ matchPattern: ["settlements", "*settlement*"],
5869
+ columnOverrides: [
5870
+ {
5871
+ columnName: "settlement_type",
5872
+ strategy: {
5873
+ kind: "enum",
5874
+ options: {
5875
+ values: ["standard", "expedited", "batch", "real_time"],
5876
+ weights: [0.5, 0.2, 0.2, 0.1]
5877
+ }
5878
+ }
5879
+ },
5880
+ {
5881
+ columnName: "amount_cents",
5882
+ strategy: { kind: "money", options: { min: 100, max: 5e5 } }
5883
+ },
5884
+ {
5885
+ columnName: "status",
5886
+ strategy: {
5887
+ kind: "enum",
5888
+ options: {
5889
+ values: ["pending", "processing", "completed", "failed"],
5890
+ weights: [0.15, 0.1, 0.7, 0.05]
5891
+ }
5892
+ }
5893
+ },
5894
+ {
5895
+ columnName: "created_at",
5896
+ strategy: { kind: "timestamp", options: { mode: "past" } }
5897
+ }
5898
+ ]
5899
+ }],
5900
+ ["chargebacks", {
5901
+ tableName: "chargebacks",
5902
+ matchPattern: ["chargebacks", "*chargeback*", "*dispute*"],
5903
+ columnOverrides: [
5904
+ {
5905
+ columnName: "reason",
5906
+ strategy: {
5907
+ kind: "enum",
5908
+ options: {
5909
+ values: ["unauthorized", "product_not_received", "product_defective", "duplicate_charge", "subscription_canceled", "other"],
5910
+ weights: [0.25, 0.2, 0.15, 0.15, 0.15, 0.1]
5911
+ }
5912
+ }
5913
+ },
5914
+ {
5915
+ columnName: "amount_cents",
5916
+ strategy: { kind: "money", options: { min: 500, max: 2e5 } }
5917
+ },
5918
+ {
5919
+ columnName: "status",
5920
+ strategy: {
5921
+ kind: "enum",
5922
+ options: {
5923
+ values: ["open", "under_review", "won", "lost", "expired"],
5924
+ weights: [0.2, 0.25, 0.3, 0.15, 0.1]
5925
+ }
5926
+ }
5927
+ },
5928
+ {
5929
+ columnName: "filed_at",
5930
+ strategy: { kind: "timestamp", options: { mode: "past" } }
5931
+ }
5932
+ ]
5933
+ }]
5934
+ ])
5935
+ };
5936
+
5937
+ // ../../packages/templates/dist/domains/healthcare.js
5938
+ var healthcareTemplate = {
5939
+ name: "healthcare",
5940
+ version: "1.0",
5941
+ description: "Healthcare system with patients, providers, encounters, diagnoses, and billing",
5942
+ targetTables: ["patients", "providers", "encounters", "diagnoses", "billing"],
5943
+ tableConfigs: /* @__PURE__ */ new Map([
5944
+ ["patients", {
5945
+ tableName: "patients",
5946
+ matchPattern: ["patients", "*patient*"],
5947
+ columnOverrides: [
5948
+ {
5949
+ columnName: "first_name",
5950
+ strategy: { kind: "first_name" }
5951
+ },
5952
+ {
5953
+ columnName: "last_name",
5954
+ strategy: { kind: "last_name" }
5955
+ },
5956
+ {
5957
+ columnName: "email",
5958
+ strategy: { kind: "email" }
5959
+ },
5960
+ {
5961
+ columnName: "phone",
5962
+ strategy: { kind: "phone" }
5963
+ },
5964
+ {
5965
+ columnName: "gender",
5966
+ strategy: {
5967
+ kind: "enum",
5968
+ options: {
5969
+ values: ["Male", "Female", "Non-binary", "Other", "Prefer not to say"],
5970
+ weights: [0.48, 0.48, 0.02, 0.01, 0.01]
5971
+ }
5972
+ }
5973
+ },
5974
+ {
5975
+ columnName: "insurance_provider",
5976
+ strategy: {
5977
+ kind: "enum",
5978
+ options: {
5979
+ values: ["Blue Cross", "Aetna", "UnitedHealth", "Cigna", "Humana", "Medicare", "Medicaid", "Self-Pay"],
5980
+ weights: [0.18, 0.15, 0.15, 0.12, 0.1, 0.12, 0.1, 0.08]
5981
+ }
5982
+ }
5983
+ },
5984
+ {
5985
+ columnName: "mrn",
5986
+ strategy: { kind: "text", options: { mode: "short" } }
5987
+ },
5988
+ {
5989
+ columnName: "date_of_birth",
5990
+ strategy: { kind: "timestamp", options: { mode: "past" } }
5991
+ },
5992
+ {
5993
+ columnName: "registered_at",
5994
+ strategy: { kind: "timestamp", options: { mode: "past" } }
5995
+ }
5996
+ ]
5997
+ }],
5998
+ ["providers", {
5999
+ tableName: "providers",
6000
+ matchPattern: ["providers", "doctors", "physicians", "*provider*"],
6001
+ columnOverrides: [
6002
+ {
6003
+ columnName: "first_name",
6004
+ strategy: { kind: "first_name" }
6005
+ },
6006
+ {
6007
+ columnName: "last_name",
6008
+ strategy: { kind: "last_name" }
6009
+ },
6010
+ {
6011
+ columnName: "email",
6012
+ strategy: { kind: "email" }
6013
+ },
6014
+ {
6015
+ columnName: "specialty",
6016
+ strategy: {
6017
+ kind: "enum",
6018
+ options: {
6019
+ values: ["Family Medicine", "Internal Medicine", "Pediatrics", "Cardiology", "Orthopedics", "Dermatology", "Neurology", "Psychiatry", "Emergency Medicine", "Radiology"],
6020
+ weights: [0.18, 0.15, 0.12, 0.1, 0.1, 0.08, 0.08, 0.07, 0.07, 0.05]
6021
+ }
6022
+ }
6023
+ },
6024
+ {
6025
+ columnName: "department",
6026
+ strategy: {
6027
+ kind: "enum",
6028
+ options: {
6029
+ values: ["Primary Care", "Surgery", "Emergency", "Specialty", "Diagnostics"],
6030
+ weights: [0.3, 0.2, 0.15, 0.25, 0.1]
6031
+ }
6032
+ }
6033
+ },
6034
+ {
6035
+ columnName: "npi",
6036
+ strategy: { kind: "text", options: { mode: "short" } }
6037
+ },
6038
+ {
6039
+ columnName: "active",
6040
+ strategy: { kind: "boolean", options: { trueWeight: 0.92 } }
6041
+ }
6042
+ ]
6043
+ }],
6044
+ ["encounters", {
6045
+ tableName: "encounters",
6046
+ matchPattern: ["encounters", "visits", "appointments", "*encounter*", "*visit*"],
6047
+ columnOverrides: [
6048
+ {
6049
+ columnName: "encounter_type",
6050
+ strategy: {
6051
+ kind: "enum",
6052
+ options: {
6053
+ values: ["office_visit", "emergency", "telehealth", "procedure", "follow_up", "annual_checkup"],
6054
+ weights: [0.35, 0.08, 0.15, 0.12, 0.18, 0.12]
6055
+ }
6056
+ }
6057
+ },
6058
+ {
6059
+ columnName: "status",
6060
+ strategy: {
6061
+ kind: "enum",
6062
+ options: {
6063
+ values: ["completed", "scheduled", "in_progress", "canceled", "no_show"],
6064
+ weights: [0.55, 0.15, 0.1, 0.1, 0.1]
6065
+ }
6066
+ }
6067
+ },
6068
+ {
6069
+ columnName: "chief_complaint",
6070
+ strategy: {
6071
+ kind: "enum",
6072
+ options: {
6073
+ values: ["Headache", "Back pain", "Cough", "Chest pain", "Fatigue", "Fever", "Joint pain", "Shortness of breath", "Abdominal pain", "Skin rash", "Dizziness", "Annual checkup"],
6074
+ weights: [0.1, 0.12, 0.1, 0.06, 0.08, 0.08, 0.09, 0.06, 0.08, 0.07, 0.06, 0.1]
6075
+ }
6076
+ }
6077
+ },
6078
+ {
6079
+ columnName: "scheduled_at",
6080
+ strategy: { kind: "timestamp", options: { mode: "past" } }
6081
+ }
6082
+ ]
6083
+ }],
6084
+ ["diagnoses", {
6085
+ tableName: "diagnoses",
6086
+ matchPattern: ["diagnoses", "*diagnosis*", "*diagnos*"],
6087
+ columnOverrides: [
6088
+ {
6089
+ columnName: "icd_code",
6090
+ strategy: {
6091
+ kind: "enum",
6092
+ options: {
6093
+ values: ["J06.9", "M54.5", "I10", "E11.9", "J20.9", "R51.9", "M25.50", "Z00.00", "K21.0", "L30.9", "F41.1", "E78.5"],
6094
+ weights: [0.1, 0.1, 0.12, 0.1, 0.08, 0.08, 0.08, 0.08, 0.07, 0.06, 0.07, 0.06]
6095
+ }
6096
+ }
6097
+ },
6098
+ {
6099
+ columnName: "description",
6100
+ strategy: {
6101
+ kind: "enum",
6102
+ options: {
6103
+ values: ["Acute upper respiratory infection", "Low back pain", "Essential hypertension", "Type 2 diabetes", "Acute bronchitis", "Headache", "Joint pain", "General adult medical exam", "Gastroesophageal reflux", "Dermatitis", "Generalized anxiety disorder", "Hyperlipidemia"],
6104
+ weights: [0.1, 0.1, 0.12, 0.1, 0.08, 0.08, 0.08, 0.08, 0.07, 0.06, 0.07, 0.06]
6105
+ }
6106
+ }
6107
+ },
6108
+ {
6109
+ columnName: "diagnosis_type",
6110
+ strategy: {
6111
+ kind: "enum",
6112
+ options: {
6113
+ values: ["primary", "secondary", "admitting", "working"],
6114
+ weights: [0.6, 0.25, 0.08, 0.07]
6115
+ }
6116
+ }
6117
+ },
6118
+ {
6119
+ columnName: "diagnosed_at",
6120
+ strategy: { kind: "timestamp", options: { mode: "past" } }
6121
+ }
6122
+ ]
6123
+ }],
6124
+ ["billing", {
6125
+ tableName: "billing",
6126
+ matchPattern: ["billing", "claims", "charges", "*bill*", "*claim*"],
6127
+ columnOverrides: [
6128
+ {
6129
+ columnName: "cpt_code",
6130
+ strategy: {
6131
+ kind: "enum",
6132
+ options: {
6133
+ values: ["99213", "99214", "99215", "99203", "99204", "99281", "99282", "99283", "99395", "99396"],
6134
+ weights: [0.25, 0.2, 0.1, 0.1, 0.08, 0.05, 0.05, 0.05, 0.06, 0.06]
6135
+ }
6136
+ }
6137
+ },
6138
+ {
6139
+ columnName: "description",
6140
+ strategy: {
6141
+ kind: "enum",
6142
+ options: {
6143
+ values: ["Office visit - established, low", "Office visit - established, moderate", "Office visit - established, high", "Office visit - new, low", "Office visit - new, moderate", "ED visit - low", "ED visit - moderate", "ED visit - high", "Preventive visit 18-39", "Preventive visit 40-64"],
6144
+ weights: [0.25, 0.2, 0.1, 0.1, 0.08, 0.05, 0.05, 0.05, 0.06, 0.06]
6145
+ }
6146
+ }
6147
+ },
6148
+ {
6149
+ columnName: "amount_cents",
6150
+ strategy: { kind: "money", options: { min: 5e3, max: 15e4 } }
6151
+ },
6152
+ {
6153
+ columnName: "insurance_covered_cents",
6154
+ strategy: { kind: "money", options: { min: 0, max: 12e4 } }
6155
+ },
6156
+ {
6157
+ columnName: "patient_responsibility_cents",
6158
+ strategy: { kind: "money", options: { min: 0, max: 5e4 } }
6159
+ },
6160
+ {
6161
+ columnName: "status",
6162
+ strategy: {
6163
+ kind: "enum",
6164
+ options: {
6165
+ values: ["paid", "pending", "denied", "appealed", "partially_paid"],
6166
+ weights: [0.5, 0.2, 0.1, 0.05, 0.15]
6167
+ }
6168
+ }
6169
+ },
6170
+ {
6171
+ columnName: "billed_at",
6172
+ strategy: { kind: "timestamp", options: { mode: "past" } }
6173
+ }
6174
+ ]
6175
+ }]
6176
+ ])
6177
+ };
6178
+
5711
6179
  // ../../packages/templates/dist/registry.js
5712
6180
  var TemplateRegistry = class {
5713
6181
  templates = /* @__PURE__ */ new Map();
@@ -5763,6 +6231,8 @@ function getDefaultRegistry() {
5763
6231
  registry.register(saasTemplate);
5764
6232
  registry.register(ecommerceTemplate);
5765
6233
  registry.register(educationTemplate);
6234
+ registry.register(fintechTemplate);
6235
+ registry.register(healthcareTemplate);
5766
6236
  return registry;
5767
6237
  }
5768
6238
 
@@ -6150,6 +6620,13 @@ async function truncateTables(pool, tableNames, cascade) {
6150
6620
  };
6151
6621
  }
6152
6622
 
6623
+ // ../../packages/db/dist/readTable.js
6624
+ async function readTableRows(pool, tableName, columns) {
6625
+ const quotedColumns = columns.map((c) => `"${c}"`).join(", ");
6626
+ const result = await pool.query(`SELECT ${quotedColumns} FROM "${tableName}"`);
6627
+ return result.rows;
6628
+ }
6629
+
6153
6630
  // ../../packages/schema/dist/normalizer.js
6154
6631
  function normalizeSchema(raw) {
6155
6632
  const primaryKeyMap = /* @__PURE__ */ new Map();
@@ -6334,10 +6811,89 @@ async function introspectDatabase(pool, schemaName = "public") {
6334
6811
  for (const warning of validation.warnings) {
6335
6812
  console.warn(`[databox] Schema warning: ${warning}`);
6336
6813
  }
6337
- for (const error of validation.errors) {
6338
- console.error(`[databox] Schema error: ${error}`);
6814
+ for (const error of validation.errors) {
6815
+ console.error(`[databox] Schema error: ${error}`);
6816
+ }
6817
+ return schema;
6818
+ }
6819
+
6820
+ // ../../packages/schema/dist/generateDDL.js
6821
+ function generateCreateTableDDL(schema) {
6822
+ const orderedNames = orderByDependency(schema.tables, schema.foreignKeys);
6823
+ const tableMap = /* @__PURE__ */ new Map();
6824
+ for (const table of schema.tables) {
6825
+ tableMap.set(table.name, table);
6826
+ }
6827
+ const fksBySource = /* @__PURE__ */ new Map();
6828
+ for (const fk of schema.foreignKeys) {
6829
+ const existing = fksBySource.get(fk.sourceTable) ?? [];
6830
+ existing.push(fk);
6831
+ fksBySource.set(fk.sourceTable, existing);
6832
+ }
6833
+ const statements = [];
6834
+ for (const tableName of orderedNames) {
6835
+ const table = tableMap.get(tableName);
6836
+ if (!table)
6837
+ continue;
6838
+ const columnDefs = table.columns.sort((a, b) => a.ordinalPosition - b.ordinalPosition).map((col) => formatColumnDef(col));
6839
+ if (table.primaryKey) {
6840
+ columnDefs.push(` PRIMARY KEY ("${table.primaryKey.columnName}")`);
6841
+ }
6842
+ const tableFks = fksBySource.get(tableName) ?? [];
6843
+ for (const fk of tableFks) {
6844
+ columnDefs.push(` FOREIGN KEY ("${fk.sourceColumn}") REFERENCES "${fk.targetTable}" ("${fk.targetColumn}")`);
6845
+ }
6846
+ statements.push(`CREATE TABLE "${tableName}" (
6847
+ ${columnDefs.join(",\n")}
6848
+ );`);
6849
+ }
6850
+ return statements.join("\n\n") + "\n";
6851
+ }
6852
+ function formatColumnDef(col) {
6853
+ let typeName = col.dataType.toUpperCase();
6854
+ if (col.maxLength && (typeName === "CHARACTER VARYING" || typeName === "VARCHAR")) {
6855
+ typeName = `VARCHAR(${col.maxLength})`;
6856
+ }
6857
+ let def = ` "${col.name}" ${typeName}`;
6858
+ if (!col.isNullable) {
6859
+ def += " NOT NULL";
6860
+ }
6861
+ if (col.hasDefault && col.defaultValue !== null) {
6862
+ def += ` DEFAULT ${col.defaultValue}`;
6863
+ }
6864
+ return def;
6865
+ }
6866
+ function orderByDependency(tables, foreignKeys) {
6867
+ const tableNames = new Set(tables.map((t) => t.name));
6868
+ const deps = /* @__PURE__ */ new Map();
6869
+ for (const name of tableNames) {
6870
+ deps.set(name, /* @__PURE__ */ new Set());
6339
6871
  }
6340
- return schema;
6872
+ for (const fk of foreignKeys) {
6873
+ if (fk.sourceTable !== fk.targetTable && tableNames.has(fk.targetTable)) {
6874
+ deps.get(fk.sourceTable).add(fk.targetTable);
6875
+ }
6876
+ }
6877
+ const result = [];
6878
+ const visited = /* @__PURE__ */ new Set();
6879
+ const visiting = /* @__PURE__ */ new Set();
6880
+ function visit(name) {
6881
+ if (visited.has(name))
6882
+ return;
6883
+ if (visiting.has(name))
6884
+ return;
6885
+ visiting.add(name);
6886
+ for (const dep of deps.get(name) ?? []) {
6887
+ visit(dep);
6888
+ }
6889
+ visiting.delete(name);
6890
+ visited.add(name);
6891
+ result.push(name);
6892
+ }
6893
+ for (const name of tableNames) {
6894
+ visit(name);
6895
+ }
6896
+ return result;
6341
6897
  }
6342
6898
 
6343
6899
  // ../../packages/core/dist/scanPipeline.js
@@ -6628,6 +7184,198 @@ function packDatasetToGenerated(pack) {
6628
7184
  };
6629
7185
  }
6630
7186
 
7187
+ // ../../packages/core/dist/capturePipeline.js
7188
+ function maskConnection(connectionString) {
7189
+ try {
7190
+ const url = new URL(connectionString);
7191
+ if (url.password) {
7192
+ url.password = "****";
7193
+ }
7194
+ return url.toString();
7195
+ } catch {
7196
+ return connectionString.replace(/:([^@/]+)@/, ":****@");
7197
+ }
7198
+ }
7199
+ async function captureDatabase(config, options) {
7200
+ const start = performance.now();
7201
+ const pool = createPostgresClient(config.database.connectionString);
7202
+ try {
7203
+ await testConnection(pool);
7204
+ const schema = await introspectDatabase(pool);
7205
+ const graph = buildDependencyGraph(schema.foreignKeys);
7206
+ const sorted = topologicalSort(graph);
7207
+ const graphOrder = sorted.order;
7208
+ const allTableNames = schema.tables.map((t) => t.name);
7209
+ const tableOrder = [
7210
+ ...graphOrder,
7211
+ ...allTableNames.filter((t) => !graphOrder.includes(t))
7212
+ ];
7213
+ let tablesToCapture;
7214
+ if (options.tables && options.tables.length > 0) {
7215
+ let addDeps2 = function(tableName) {
7216
+ if (allDeps.has(tableName))
7217
+ return;
7218
+ allDeps.add(tableName);
7219
+ for (const fk of schema.foreignKeys) {
7220
+ if (fk.sourceTable === tableName && fk.sourceTable !== fk.targetTable) {
7221
+ addDeps2(fk.targetTable);
7222
+ }
7223
+ }
7224
+ };
7225
+ var addDeps = addDeps2;
7226
+ const requested = new Set(options.tables);
7227
+ const allDeps = /* @__PURE__ */ new Set();
7228
+ for (const t of requested) {
7229
+ addDeps2(t);
7230
+ }
7231
+ tablesToCapture = tableOrder.filter((t) => allDeps.has(t));
7232
+ } else {
7233
+ tablesToCapture = tableOrder;
7234
+ }
7235
+ const capturedTableSet = new Set(tablesToCapture);
7236
+ const filteredTables = schema.tables.filter((t) => capturedTableSet.has(t.name));
7237
+ const filteredFKs = schema.foreignKeys.filter((fk) => capturedTableSet.has(fk.sourceTable) && capturedTableSet.has(fk.targetTable));
7238
+ const filteredSchema = {
7239
+ ...schema,
7240
+ tables: filteredTables,
7241
+ foreignKeys: filteredFKs,
7242
+ tableCount: filteredTables.length,
7243
+ foreignKeyCount: filteredFKs.length
7244
+ };
7245
+ const ddl = generateCreateTableDDL(filteredSchema);
7246
+ const packDataset = { tables: {} };
7247
+ const tableDetails = [];
7248
+ let totalRows = 0;
7249
+ for (const tableName of tablesToCapture) {
7250
+ const tableSchema = filteredTables.find((t) => t.name === tableName);
7251
+ if (!tableSchema)
7252
+ continue;
7253
+ const columns = tableSchema.columns.map((c) => c.name);
7254
+ const rows = await readTableRows(pool, tableName, columns);
7255
+ const rowCount = rows.length;
7256
+ packDataset.tables[tableName] = {
7257
+ columns,
7258
+ rows,
7259
+ rowCount
7260
+ };
7261
+ tableDetails.push({ name: tableName, rowCount });
7262
+ totalRows += rowCount;
7263
+ }
7264
+ const packSchema = {
7265
+ tables: filteredTables.map((t) => ({
7266
+ name: t.name,
7267
+ columns: t.columns.map((c) => ({
7268
+ name: c.name,
7269
+ dataType: c.dataType,
7270
+ nullable: c.isNullable,
7271
+ maxLength: c.maxLength
7272
+ })),
7273
+ primaryKey: t.primaryKey?.columnName
7274
+ })),
7275
+ foreignKeys: filteredFKs.map((fk) => ({
7276
+ sourceTable: fk.sourceTable,
7277
+ sourceColumn: fk.sourceColumn,
7278
+ targetTable: fk.targetTable,
7279
+ targetColumn: fk.targetColumn
7280
+ }))
7281
+ };
7282
+ const plan = {
7283
+ version: "1.0",
7284
+ planId: `capture-${options.name}-${Date.now()}`,
7285
+ tables: [],
7286
+ tableOrder: tablesToCapture,
7287
+ config: {
7288
+ targetDatabase: "postgres",
7289
+ defaultRowCount: 0,
7290
+ batchSize: config.seed?.batchSize ?? 1e3,
7291
+ environment: "dev"
7292
+ },
7293
+ reproducibility: {
7294
+ randomSeed: 0,
7295
+ strategyVersion: "0.3.0"
7296
+ }
7297
+ };
7298
+ const masked = maskConnection(config.database.connectionString);
7299
+ const pack = {
7300
+ format: "databox-reality-pack",
7301
+ version: "1.0",
7302
+ metadata: {
7303
+ name: options.name,
7304
+ description: options.description,
7305
+ createdAt: (/* @__PURE__ */ new Date()).toISOString(),
7306
+ seed: 0,
7307
+ totalRows,
7308
+ tableCount: tablesToCapture.length,
7309
+ ddl,
7310
+ capturedFrom: masked
7311
+ },
7312
+ schema: packSchema,
7313
+ plan,
7314
+ dataset: packDataset
7315
+ };
7316
+ const outputDir = options.outputDir ?? ".";
7317
+ const filePath = await saveRealityPack(pack, outputDir);
7318
+ const durationMs = Math.round(performance.now() - start);
7319
+ return {
7320
+ pack,
7321
+ filePath,
7322
+ totalRows,
7323
+ tableCount: tablesToCapture.length,
7324
+ durationMs,
7325
+ tableDetails
7326
+ };
7327
+ } finally {
7328
+ await closeConnection(pool);
7329
+ }
7330
+ }
7331
+
7332
+ // ../../packages/core/dist/sharePipeline.js
7333
+ var import_promises6 = require("fs/promises");
7334
+ function formatSize(bytes) {
7335
+ if (bytes < 1024)
7336
+ return `${bytes} B`;
7337
+ const kb = Math.round(bytes / 1024);
7338
+ if (kb < 1024)
7339
+ return `${kb} KB`;
7340
+ const mb = (bytes / (1024 * 1024)).toFixed(1);
7341
+ return `${mb} MB`;
7342
+ }
7343
+ async function shareRealityPack(filePath, options) {
7344
+ const pack = await loadRealityPack(filePath);
7345
+ const fileStat = await (0, import_promises6.stat)(filePath);
7346
+ const size = formatSize(fileStat.size);
7347
+ const method = options?.method ?? "file";
7348
+ if (method === "gist") {
7349
+ const token = process.env.GITHUB_TOKEN;
7350
+ if (!token) {
7351
+ return {
7352
+ method: "file",
7353
+ location: filePath,
7354
+ packName: pack.metadata.name,
7355
+ size,
7356
+ tableCount: pack.metadata.tableCount,
7357
+ totalRows: pack.metadata.totalRows
7358
+ };
7359
+ }
7360
+ return {
7361
+ method: "file",
7362
+ location: filePath,
7363
+ packName: pack.metadata.name,
7364
+ size,
7365
+ tableCount: pack.metadata.tableCount,
7366
+ totalRows: pack.metadata.totalRows
7367
+ };
7368
+ }
7369
+ return {
7370
+ method: "file",
7371
+ location: filePath,
7372
+ packName: pack.metadata.name,
7373
+ size,
7374
+ tableCount: pack.metadata.tableCount,
7375
+ totalRows: pack.metadata.totalRows
7376
+ };
7377
+ }
7378
+
6631
7379
  // src/utils.ts
6632
7380
  function maskConnectionString(connectionString) {
6633
7381
  try {
@@ -6642,7 +7390,7 @@ function maskConnectionString(connectionString) {
6642
7390
  }
6643
7391
 
6644
7392
  // src/commands/scan.ts
6645
- var VERSION2 = "0.2.0";
7393
+ var VERSION2 = "0.4.0";
6646
7394
  async function scanCommand(options) {
6647
7395
  const start = performance.now();
6648
7396
  try {
@@ -6733,7 +7481,7 @@ async function scanCommand(options) {
6733
7481
  }
6734
7482
 
6735
7483
  // src/commands/seed.ts
6736
- var VERSION3 = "0.2.0";
7484
+ var VERSION3 = "0.4.0";
6737
7485
  async function seedCommand(options) {
6738
7486
  const start = performance.now();
6739
7487
  try {
@@ -6911,7 +7659,7 @@ async function seedCommand(options) {
6911
7659
  }
6912
7660
 
6913
7661
  // src/commands/reset.ts
6914
- var VERSION4 = "0.2.0";
7662
+ var VERSION4 = "0.4.0";
6915
7663
  async function resetCommand(options) {
6916
7664
  const start = performance.now();
6917
7665
  if (!options.ci && !options.confirm) {
@@ -6981,7 +7729,7 @@ async function resetCommand(options) {
6981
7729
  }
6982
7730
 
6983
7731
  // src/commands/export.ts
6984
- var VERSION5 = "0.2.0";
7732
+ var VERSION5 = "0.4.0";
6985
7733
  async function exportCommand(options) {
6986
7734
  const start = performance.now();
6987
7735
  try {
@@ -7174,7 +7922,7 @@ function scenariosCommand() {
7174
7922
  }
7175
7923
 
7176
7924
  // src/commands/pack.ts
7177
- var import_promises6 = require("fs/promises");
7925
+ var import_promises7 = require("fs/promises");
7178
7926
  async function packExportCommand(options) {
7179
7927
  try {
7180
7928
  const config = await loadConfig();
@@ -7251,7 +7999,7 @@ async function packExportCommand(options) {
7251
7999
  scenarios: options.scenario,
7252
8000
  scenarioIntensity
7253
8001
  });
7254
- const fileStat = await (0, import_promises6.stat)(result.filePath);
8002
+ const fileStat = await (0, import_promises7.stat)(result.filePath);
7255
8003
  const sizeKb = Math.round(fileStat.size / 1024);
7256
8004
  console.log("");
7257
8005
  console.log(`Tables: ${result.pack.metadata.tableCount}`);
@@ -7331,11 +8079,330 @@ async function packImportCommand(filePath, options) {
7331
8079
  }
7332
8080
  }
7333
8081
 
8082
+ // src/commands/capture.ts
8083
+ var import_promises8 = require("fs/promises");
8084
+ var VERSION6 = "0.4.0";
8085
+ async function captureCommand(options) {
8086
+ const start = performance.now();
8087
+ try {
8088
+ if (!options.name) {
8089
+ const msg = "Missing required --name flag.";
8090
+ if (options.ci) {
8091
+ console.log(formatCIOutput({
8092
+ success: false,
8093
+ command: "capture",
8094
+ version: VERSION6,
8095
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
8096
+ durationMs: 0,
8097
+ error: msg
8098
+ }));
8099
+ process.exit(1);
8100
+ }
8101
+ console.error(`[realitydb] ${msg}`);
8102
+ console.error("Usage: realitydb capture --name <name>");
8103
+ process.exit(1);
8104
+ }
8105
+ const config = await loadConfig();
8106
+ const masked = maskConnectionString(config.database.connectionString);
8107
+ const tables = options.tables ? options.tables.split(",").map((t) => t.trim()).filter((t) => t.length > 0) : void 0;
8108
+ if (!options.ci) {
8109
+ console.log("");
8110
+ console.log("RealityDB Capture");
8111
+ console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
8112
+ console.log(`Database: ${masked}`);
8113
+ console.log(`Name: ${options.name}`);
8114
+ if (tables) {
8115
+ console.log(`Tables: ${tables.join(", ")}`);
8116
+ }
8117
+ console.log("");
8118
+ console.log("Capturing...");
8119
+ }
8120
+ const result = await captureDatabase(config, {
8121
+ name: options.name,
8122
+ description: options.description,
8123
+ tables,
8124
+ outputDir: options.output
8125
+ });
8126
+ const durationMs = Math.round(performance.now() - start);
8127
+ if (options.ci) {
8128
+ console.log(formatCIOutput({
8129
+ success: true,
8130
+ command: "capture",
8131
+ version: VERSION6,
8132
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
8133
+ durationMs,
8134
+ data: {
8135
+ database: masked,
8136
+ name: options.name,
8137
+ filePath: result.filePath,
8138
+ tableCount: result.tableCount,
8139
+ totalRows: result.totalRows,
8140
+ tables: result.tableDetails.map((t) => ({
8141
+ name: t.name,
8142
+ rowCount: t.rowCount
8143
+ })),
8144
+ ddlIncluded: true
8145
+ }
8146
+ }));
8147
+ return;
8148
+ }
8149
+ for (const table of result.tableDetails) {
8150
+ console.log(` ${table.name}: ${table.rowCount} rows`);
8151
+ }
8152
+ const fileStat = await (0, import_promises8.stat)(result.filePath);
8153
+ const sizeKb = Math.round(fileStat.size / 1024);
8154
+ console.log("");
8155
+ console.log(`Captured: ${result.filePath} (${sizeKb} KB)`);
8156
+ console.log("Schema DDL included. Share this file to reproduce the environment.");
8157
+ console.log("");
8158
+ } catch (err) {
8159
+ const message = err instanceof Error ? err.message : String(err);
8160
+ if (options.ci) {
8161
+ console.log(formatCIOutput({
8162
+ success: false,
8163
+ command: "capture",
8164
+ version: VERSION6,
8165
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
8166
+ durationMs: Math.round(performance.now() - start),
8167
+ error: message
8168
+ }));
8169
+ process.exit(1);
8170
+ }
8171
+ if (message.includes("Config file not found")) {
8172
+ console.error(`[realitydb] ${message}`);
8173
+ } else if (message.includes("connection") || message.includes("ECONNREFUSED")) {
8174
+ console.error(`[realitydb] Capture failed: ${message}`);
8175
+ console.error("Hint: Check that your database is running (e.g. Docker)");
8176
+ } else {
8177
+ console.error(`[realitydb] Capture failed: ${message}`);
8178
+ }
8179
+ process.exit(1);
8180
+ }
8181
+ }
8182
+
8183
+ // src/commands/share.ts
8184
+ var VERSION7 = "0.4.0";
8185
+ async function shareCommand(filePath, options) {
8186
+ const start = performance.now();
8187
+ try {
8188
+ if (!filePath) {
8189
+ const msg = "Missing file path argument.";
8190
+ if (options.ci) {
8191
+ console.log(formatCIOutput({
8192
+ success: false,
8193
+ command: "share",
8194
+ version: VERSION7,
8195
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
8196
+ durationMs: 0,
8197
+ error: msg
8198
+ }));
8199
+ process.exit(1);
8200
+ }
8201
+ console.error(`[realitydb] ${msg}`);
8202
+ console.error("Usage: realitydb share <file>");
8203
+ process.exit(1);
8204
+ }
8205
+ const result = await shareRealityPack(filePath);
8206
+ const durationMs = Math.round(performance.now() - start);
8207
+ if (options.ci) {
8208
+ console.log(formatCIOutput({
8209
+ success: true,
8210
+ command: "share",
8211
+ version: VERSION7,
8212
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
8213
+ durationMs,
8214
+ data: {
8215
+ method: result.method,
8216
+ location: result.location,
8217
+ packName: result.packName,
8218
+ size: result.size,
8219
+ tableCount: result.tableCount,
8220
+ totalRows: result.totalRows
8221
+ }
8222
+ }));
8223
+ return;
8224
+ }
8225
+ console.log("");
8226
+ console.log("RealityDB Share");
8227
+ console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
8228
+ console.log(`Pack: ${result.packName} (${result.tableCount} tables, ${result.totalRows} rows, ${result.size})`);
8229
+ console.log("");
8230
+ console.log("Share this file:");
8231
+ console.log(` File: ${result.location}`);
8232
+ console.log(` Size: ${result.size}`);
8233
+ console.log("");
8234
+ console.log("The receiver can load it with:");
8235
+ console.log(` realitydb load ${result.location} --confirm`);
8236
+ console.log("");
8237
+ console.log("Tip: To create the schema first, the receiver can run:");
8238
+ console.log(` realitydb load ${result.location} --show-ddl`);
8239
+ console.log("");
8240
+ } catch (err) {
8241
+ const message = err instanceof Error ? err.message : String(err);
8242
+ if (options.ci) {
8243
+ console.log(formatCIOutput({
8244
+ success: false,
8245
+ command: "share",
8246
+ version: VERSION7,
8247
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
8248
+ durationMs: Math.round(performance.now() - start),
8249
+ error: message
8250
+ }));
8251
+ process.exit(1);
8252
+ }
8253
+ console.error(`[realitydb] Share failed: ${message}`);
8254
+ process.exit(1);
8255
+ }
8256
+ }
8257
+
8258
+ // src/commands/load.ts
8259
+ var VERSION8 = "0.4.0";
8260
+ async function loadCommand(filePath, options) {
8261
+ const start = performance.now();
8262
+ try {
8263
+ if (!filePath) {
8264
+ const msg = "Missing file path argument.";
8265
+ if (options.ci) {
8266
+ console.log(formatCIOutput({
8267
+ success: false,
8268
+ command: "load",
8269
+ version: VERSION8,
8270
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
8271
+ durationMs: 0,
8272
+ error: msg
8273
+ }));
8274
+ process.exit(1);
8275
+ }
8276
+ console.error(`[realitydb] ${msg}`);
8277
+ console.error("Usage: realitydb load <file> --confirm");
8278
+ process.exit(1);
8279
+ }
8280
+ const pack = await loadRealityPack(filePath);
8281
+ if (options.showDdl) {
8282
+ const ddl = pack.metadata.ddl;
8283
+ if (options.ci) {
8284
+ console.log(formatCIOutput({
8285
+ success: true,
8286
+ command: "load",
8287
+ version: VERSION8,
8288
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
8289
+ durationMs: Math.round(performance.now() - start),
8290
+ data: {
8291
+ packName: pack.metadata.name,
8292
+ ddlAvailable: !!ddl,
8293
+ ddl: ddl ?? null
8294
+ }
8295
+ }));
8296
+ return;
8297
+ }
8298
+ if (ddl) {
8299
+ console.log("");
8300
+ console.log("Schema DDL (run this SQL to create tables):");
8301
+ console.log("");
8302
+ console.log(ddl);
8303
+ } else {
8304
+ console.log("");
8305
+ console.log("No DDL available in this Reality Pack.");
8306
+ console.log("This pack was created with pack export (generated data), not capture.");
8307
+ console.log("");
8308
+ }
8309
+ return;
8310
+ }
8311
+ const config = await loadConfig();
8312
+ const masked = maskConnectionString(config.database.connectionString);
8313
+ if (!options.ci) {
8314
+ console.log("");
8315
+ console.log("RealityDB Load");
8316
+ console.log("\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550");
8317
+ console.log(`Database: ${masked}`);
8318
+ console.log(`Pack: ${pack.metadata.name} (v${pack.version})`);
8319
+ if (pack.metadata.templateName) {
8320
+ console.log(`Template: ${pack.metadata.templateName}`);
8321
+ }
8322
+ console.log(`Tables: ${pack.metadata.tableCount}`);
8323
+ console.log(`Total rows: ${pack.metadata.totalRows}`);
8324
+ const ddl = pack.metadata.ddl;
8325
+ if (ddl) {
8326
+ console.log("Schema DDL: included");
8327
+ }
8328
+ console.log("");
8329
+ }
8330
+ if (!options.ci && !options.confirm) {
8331
+ console.error("[realitydb] Load requires --confirm flag.");
8332
+ console.error("Hint: This will insert data into your database. Use --confirm to proceed.");
8333
+ console.error("");
8334
+ console.error("To view the schema DDL first:");
8335
+ console.error(` realitydb load ${filePath} --show-ddl`);
8336
+ process.exit(1);
8337
+ }
8338
+ if (!options.ci) {
8339
+ console.log("Loading...");
8340
+ }
8341
+ const result = await importPack(config, filePath);
8342
+ const durationMs = Math.round(performance.now() - start);
8343
+ if (options.ci) {
8344
+ console.log(formatCIOutput({
8345
+ success: true,
8346
+ command: "load",
8347
+ version: VERSION8,
8348
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
8349
+ durationMs,
8350
+ data: {
8351
+ database: masked,
8352
+ packName: pack.metadata.name,
8353
+ totalRows: result.totalRows,
8354
+ tables: result.insertResult.tables.map((t) => ({
8355
+ name: t.tableName,
8356
+ rowsInserted: t.rowsInserted,
8357
+ durationMs: t.durationMs
8358
+ }))
8359
+ }
8360
+ }));
8361
+ return;
8362
+ }
8363
+ for (const tableResult of result.insertResult.tables) {
8364
+ console.log(
8365
+ ` ${tableResult.tableName}: ${tableResult.rowsInserted} rows loaded`
8366
+ );
8367
+ }
8368
+ const totalTime = (result.durationMs / 1e3).toFixed(1);
8369
+ console.log("");
8370
+ console.log(`Load complete. ${result.totalRows} rows in ${totalTime}s`);
8371
+ console.log("");
8372
+ } catch (err) {
8373
+ const message = err instanceof Error ? err.message : String(err);
8374
+ if (options.ci) {
8375
+ console.log(formatCIOutput({
8376
+ success: false,
8377
+ command: "load",
8378
+ version: VERSION8,
8379
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
8380
+ durationMs: Math.round(performance.now() - start),
8381
+ error: message
8382
+ }));
8383
+ process.exit(1);
8384
+ }
8385
+ if (message.includes("Config file not found")) {
8386
+ console.error(`[realitydb] ${message}`);
8387
+ } else if (message.includes("Cannot import Reality Pack")) {
8388
+ console.error(`[realitydb] ${message}`);
8389
+ const ddlHint = "Tip: Use --show-ddl to get the schema creation SQL.";
8390
+ console.error(ddlHint);
8391
+ } else if (message.includes("connection") || message.includes("ECONNREFUSED")) {
8392
+ console.error(`[realitydb] Load failed: ${message}`);
8393
+ console.error("Hint: Check that your database is running (e.g. Docker)");
8394
+ } else {
8395
+ console.error(`[realitydb] Load failed: ${message}`);
8396
+ }
8397
+ process.exit(1);
8398
+ }
8399
+ }
8400
+
7334
8401
  // src/cli.ts
7335
- var VERSION6 = "0.2.0";
8402
+ var VERSION9 = "0.4.0";
7336
8403
  function run(argv) {
7337
8404
  const program2 = new Command();
7338
- program2.name("realitydb").description("RealityDB \u2014 Developer Reality Platform").version(VERSION6).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);
8405
+ program2.name("realitydb").description("RealityDB \u2014 Developer Reality Platform").version(VERSION9).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);
7339
8406
  program2.command("scan").description("Scan database schema").action(async () => {
7340
8407
  const opts = program2.opts();
7341
8408
  await scanCommand({ ci: opts.ci });
@@ -7354,16 +8421,28 @@ function run(argv) {
7354
8421
  });
7355
8422
  program2.command("templates").description("List available domain templates").action(templatesCommand);
7356
8423
  program2.command("scenarios").description("List available scenarios").action(scenariosCommand);
8424
+ 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) => {
8425
+ const opts = program2.opts();
8426
+ await captureCommand({ ...cmdOpts, ci: opts.ci });
8427
+ });
8428
+ program2.command("share <file>").description("Share a Reality Pack file").action(async (filePath) => {
8429
+ const opts = program2.opts();
8430
+ await shareCommand(filePath, { ci: opts.ci });
8431
+ });
8432
+ program2.command("load <file>").description("Load a Reality Pack into the database").option("--confirm", "Confirm import operation").option("--show-ddl", "Show schema DDL without importing").action(async (filePath, cmdOpts) => {
8433
+ const opts = program2.opts();
8434
+ await loadCommand(filePath, { ...cmdOpts, ci: opts.ci });
8435
+ });
7357
8436
  const pack = program2.command("pack").description("Reality Pack operations");
7358
8437
  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").action(packExportCommand);
7359
8438
  pack.command("import <file>").description("Import Reality Pack into database").option("--confirm", "Confirm import operation").action(packImportCommand);
7360
8439
  program2.action(() => {
7361
8440
  const opts = program2.opts();
7362
8441
  if (opts.ci) {
7363
- console.log(JSON.stringify({ name: "realitydb", version: VERSION6 }));
8442
+ console.log(JSON.stringify({ name: "realitydb", version: VERSION9 }));
7364
8443
  } else {
7365
8444
  console.log("");
7366
- console.log(`RealityDB v${VERSION6} \u2014 Developer Reality Platform`);
8445
+ console.log(`RealityDB v${VERSION9} \u2014 Developer Reality Platform`);
7367
8446
  console.log("Run `realitydb --help` for available commands.");
7368
8447
  console.log("");
7369
8448
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "realitydb",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "Developer Reality Platform - realistic database environments from your schema",
5
5
  "license": "MIT",
6
6
  "keywords": [