realitydb 1.4.4 → 1.5.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/dist/index.js +373 -133
- package/package.json +1 -3
package/dist/index.js
CHANGED
|
@@ -3476,83 +3476,10 @@ var {
|
|
|
3476
3476
|
Help
|
|
3477
3477
|
} = import_index.default;
|
|
3478
3478
|
|
|
3479
|
-
//
|
|
3480
|
-
var
|
|
3481
|
-
var
|
|
3482
|
-
|
|
3483
|
-
// ../../packages/config/dist/defaults.js
|
|
3484
|
-
var DEFAULT_CONFIG = {
|
|
3485
|
-
seed: {
|
|
3486
|
-
defaultRecords: 5e3,
|
|
3487
|
-
batchSize: 1e3,
|
|
3488
|
-
environment: "dev"
|
|
3489
|
-
},
|
|
3490
|
-
export: {
|
|
3491
|
-
defaultFormat: "json",
|
|
3492
|
-
outputDir: "./.databox"
|
|
3493
|
-
}
|
|
3494
|
-
};
|
|
3495
|
-
|
|
3496
|
-
// ../../packages/config/dist/loadConfig.js
|
|
3497
|
-
var CONFIG_FILES = ["realitydb.config.json", "seedforge.config.json", "databox.config.json"];
|
|
3498
|
-
async function findConfigFile(basePath) {
|
|
3499
|
-
for (const name of CONFIG_FILES) {
|
|
3500
|
-
const fullPath = (0, import_node_path.resolve)(basePath, name);
|
|
3501
|
-
try {
|
|
3502
|
-
await (0, import_promises.access)(fullPath);
|
|
3503
|
-
return fullPath;
|
|
3504
|
-
} catch {
|
|
3505
|
-
continue;
|
|
3506
|
-
}
|
|
3507
|
-
}
|
|
3508
|
-
return null;
|
|
3509
|
-
}
|
|
3510
|
-
async function loadConfig(filePath) {
|
|
3511
|
-
let resolvedPath;
|
|
3512
|
-
if (filePath) {
|
|
3513
|
-
resolvedPath = (0, import_node_path.resolve)(filePath);
|
|
3514
|
-
} else {
|
|
3515
|
-
const found = await findConfigFile(".");
|
|
3516
|
-
if (!found) {
|
|
3517
|
-
throw new Error(`[realitydb] Config file not found.
|
|
3518
|
-
Create a realitydb.config.json or specify a path with --config.`);
|
|
3519
|
-
}
|
|
3520
|
-
resolvedPath = found;
|
|
3521
|
-
}
|
|
3522
|
-
let raw;
|
|
3523
|
-
try {
|
|
3524
|
-
raw = await (0, import_promises.readFile)(resolvedPath, "utf-8");
|
|
3525
|
-
} catch {
|
|
3526
|
-
throw new Error(`[realitydb] Config file not found: ${resolvedPath}
|
|
3527
|
-
Create a realitydb.config.json or specify a path with --config.`);
|
|
3528
|
-
}
|
|
3529
|
-
let parsed;
|
|
3530
|
-
try {
|
|
3531
|
-
parsed = JSON.parse(raw);
|
|
3532
|
-
} catch {
|
|
3533
|
-
throw new Error(`[realitydb] Invalid JSON in config file: ${resolvedPath}`);
|
|
3534
|
-
}
|
|
3535
|
-
const config = parsed;
|
|
3536
|
-
const database = config["database"];
|
|
3537
|
-
if (!database || typeof database["connectionString"] !== "string") {
|
|
3538
|
-
throw new Error("[realitydb] Config validation failed: database.connectionString is required.");
|
|
3539
|
-
}
|
|
3540
|
-
return {
|
|
3541
|
-
database: {
|
|
3542
|
-
client: "postgres",
|
|
3543
|
-
connectionString: database["connectionString"]
|
|
3544
|
-
},
|
|
3545
|
-
seed: {
|
|
3546
|
-
...DEFAULT_CONFIG.seed,
|
|
3547
|
-
...config["seed"] ?? {}
|
|
3548
|
-
},
|
|
3549
|
-
template: config["template"],
|
|
3550
|
-
export: {
|
|
3551
|
-
...DEFAULT_CONFIG.export,
|
|
3552
|
-
...config["export"] ?? {}
|
|
3553
|
-
}
|
|
3554
|
-
};
|
|
3555
|
-
}
|
|
3479
|
+
// src/commands/init.ts
|
|
3480
|
+
var import_node_readline = require("readline");
|
|
3481
|
+
var import_node_process = require("process");
|
|
3482
|
+
var import_node_fs7 = require("fs");
|
|
3556
3483
|
|
|
3557
3484
|
// ../../packages/core/dist/planning/dependencyGraph.js
|
|
3558
3485
|
function buildDependencyGraph(foreignKeys) {
|
|
@@ -4390,32 +4317,32 @@ function generateDataset(plan) {
|
|
|
4390
4317
|
}
|
|
4391
4318
|
|
|
4392
4319
|
// ../../packages/generators/dist/exporters/json.js
|
|
4393
|
-
var
|
|
4394
|
-
var
|
|
4320
|
+
var import_promises = require("fs/promises");
|
|
4321
|
+
var import_node_path = require("path");
|
|
4395
4322
|
async function exportToJson(dataset, outputDir) {
|
|
4396
|
-
await (0,
|
|
4323
|
+
await (0, import_promises.mkdir)(outputDir, { recursive: true });
|
|
4397
4324
|
const files = [];
|
|
4398
4325
|
for (const [tableName, table] of dataset.tables) {
|
|
4399
|
-
const filePath = (0,
|
|
4326
|
+
const filePath = (0, import_node_path.join)(outputDir, `${tableName}.json`);
|
|
4400
4327
|
const content = JSON.stringify(table.rows, null, 2);
|
|
4401
|
-
await (0,
|
|
4328
|
+
await (0, import_promises.writeFile)(filePath, content, "utf-8");
|
|
4402
4329
|
files.push(filePath);
|
|
4403
4330
|
}
|
|
4404
4331
|
return files;
|
|
4405
4332
|
}
|
|
4406
4333
|
|
|
4407
4334
|
// ../../packages/generators/dist/exporters/csv.js
|
|
4408
|
-
var
|
|
4409
|
-
var
|
|
4335
|
+
var import_promises2 = require("fs/promises");
|
|
4336
|
+
var import_node_path2 = require("path");
|
|
4410
4337
|
async function exportToCsv(dataset, outputDir) {
|
|
4411
|
-
await (0,
|
|
4338
|
+
await (0, import_promises2.mkdir)(outputDir, { recursive: true });
|
|
4412
4339
|
const files = [];
|
|
4413
4340
|
for (const [tableName, table] of dataset.tables) {
|
|
4414
|
-
const filePath = (0,
|
|
4341
|
+
const filePath = (0, import_node_path2.join)(outputDir, `${tableName}.csv`);
|
|
4415
4342
|
const header = table.columns.map(escapeCsvField).join(",");
|
|
4416
4343
|
const rows = table.rows.map((row) => table.columns.map((col) => escapeCsvField(String(row[col] ?? ""))).join(","));
|
|
4417
4344
|
const content = [header, ...rows].join("\n");
|
|
4418
|
-
await (0,
|
|
4345
|
+
await (0, import_promises2.writeFile)(filePath, content, "utf-8");
|
|
4419
4346
|
files.push(filePath);
|
|
4420
4347
|
}
|
|
4421
4348
|
return files;
|
|
@@ -4428,10 +4355,10 @@ function escapeCsvField(value) {
|
|
|
4428
4355
|
}
|
|
4429
4356
|
|
|
4430
4357
|
// ../../packages/generators/dist/exporters/sql.js
|
|
4431
|
-
var
|
|
4432
|
-
var
|
|
4358
|
+
var import_promises3 = require("fs/promises");
|
|
4359
|
+
var import_node_path3 = require("path");
|
|
4433
4360
|
async function exportToSql(dataset, outputDir, tableOrder) {
|
|
4434
|
-
await (0,
|
|
4361
|
+
await (0, import_promises3.mkdir)(outputDir, { recursive: true });
|
|
4435
4362
|
const lines = [];
|
|
4436
4363
|
lines.push("-- Generated by DataBox");
|
|
4437
4364
|
lines.push(`-- Seed: ${dataset.seed}`);
|
|
@@ -4448,8 +4375,8 @@ async function exportToSql(dataset, outputDir, tableOrder) {
|
|
|
4448
4375
|
}
|
|
4449
4376
|
lines.push("");
|
|
4450
4377
|
}
|
|
4451
|
-
const filePath = (0,
|
|
4452
|
-
await (0,
|
|
4378
|
+
const filePath = (0, import_node_path3.join)(outputDir, "seed.sql");
|
|
4379
|
+
await (0, import_promises3.writeFile)(filePath, lines.join("\n"), "utf-8");
|
|
4453
4380
|
return [filePath];
|
|
4454
4381
|
}
|
|
4455
4382
|
function escapeSqlValue(value) {
|
|
@@ -5731,7 +5658,7 @@ function countRows2(dataset) {
|
|
|
5731
5658
|
|
|
5732
5659
|
// ../../packages/generators/dist/scenarios/loadScenario.js
|
|
5733
5660
|
var import_node_fs = require("fs");
|
|
5734
|
-
var
|
|
5661
|
+
var import_node_path4 = require("path");
|
|
5735
5662
|
function scaffoldCustomScenario(name) {
|
|
5736
5663
|
return {
|
|
5737
5664
|
name,
|
|
@@ -5802,8 +5729,8 @@ function extractTablesFromModifications(modifications) {
|
|
|
5802
5729
|
}
|
|
5803
5730
|
|
|
5804
5731
|
// ../../packages/generators/dist/packExporter.js
|
|
5805
|
-
var
|
|
5806
|
-
var
|
|
5732
|
+
var import_promises4 = require("fs/promises");
|
|
5733
|
+
var import_node_path5 = require("path");
|
|
5807
5734
|
function exportRealityPack(dataset, plan, schema, options) {
|
|
5808
5735
|
const name = options?.name ?? plan.config.templateName ?? "realitydb-pack";
|
|
5809
5736
|
const packSchema = {
|
|
@@ -5851,14 +5778,14 @@ function exportRealityPack(dataset, plan, schema, options) {
|
|
|
5851
5778
|
}
|
|
5852
5779
|
async function saveRealityPack(pack, outputPath) {
|
|
5853
5780
|
const filePath = outputPath.endsWith(".realitydb-pack.json") || outputPath.endsWith(".databox-pack.json") ? outputPath : `${outputPath}/${pack.metadata.name}.realitydb-pack.json`;
|
|
5854
|
-
await (0,
|
|
5855
|
-
await (0,
|
|
5781
|
+
await (0, import_promises4.mkdir)((0, import_node_path5.dirname)(filePath), { recursive: true });
|
|
5782
|
+
await (0, import_promises4.writeFile)(filePath, JSON.stringify(pack, null, 2), "utf-8");
|
|
5856
5783
|
return filePath;
|
|
5857
5784
|
}
|
|
5858
5785
|
async function loadRealityPack(filePath) {
|
|
5859
5786
|
let raw;
|
|
5860
5787
|
try {
|
|
5861
|
-
raw = await (0,
|
|
5788
|
+
raw = await (0, import_promises4.readFile)(filePath, "utf-8");
|
|
5862
5789
|
} catch (err) {
|
|
5863
5790
|
const message = err instanceof Error ? err.message : String(err);
|
|
5864
5791
|
throw new Error(`Failed to read Reality Pack file: ${message}`);
|
|
@@ -6414,7 +6341,7 @@ function isIntLike(value) {
|
|
|
6414
6341
|
}
|
|
6415
6342
|
|
|
6416
6343
|
// ../../packages/generators/dist/writers/parquet.js
|
|
6417
|
-
var
|
|
6344
|
+
var import_promises5 = require("fs/promises");
|
|
6418
6345
|
async function appendParquetBatch(rows, filePath) {
|
|
6419
6346
|
const { appendFile: appendFile3 } = await import("fs/promises");
|
|
6420
6347
|
const lines = rows.map((row) => JSON.stringify(row)).join("\n") + "\n";
|
|
@@ -6422,14 +6349,14 @@ async function appendParquetBatch(rows, filePath) {
|
|
|
6422
6349
|
}
|
|
6423
6350
|
|
|
6424
6351
|
// ../../packages/generators/dist/writers/csv.js
|
|
6425
|
-
var
|
|
6352
|
+
var import_promises6 = require("fs/promises");
|
|
6426
6353
|
async function writeCsvHeader(columns, filePath) {
|
|
6427
6354
|
const header = columns.map(escapeCsvField2).join(",") + "\n";
|
|
6428
|
-
await (0,
|
|
6355
|
+
await (0, import_promises6.writeFile)(filePath, header, "utf-8");
|
|
6429
6356
|
}
|
|
6430
6357
|
async function appendCsvBatch(rows, columns, filePath) {
|
|
6431
6358
|
const lines = rows.map((row) => columns.map((col) => escapeCsvField2(String(row[col] ?? ""))).join(",")).join("\n") + "\n";
|
|
6432
|
-
await (0,
|
|
6359
|
+
await (0, import_promises6.appendFile)(filePath, lines, "utf-8");
|
|
6433
6360
|
}
|
|
6434
6361
|
function escapeCsvField2(value) {
|
|
6435
6362
|
if (value.includes(",") || value.includes('"') || value.includes("\n") || value.includes("\r")) {
|
|
@@ -6439,13 +6366,13 @@ function escapeCsvField2(value) {
|
|
|
6439
6366
|
}
|
|
6440
6367
|
|
|
6441
6368
|
// ../../packages/generators/dist/writers/json.js
|
|
6442
|
-
var
|
|
6369
|
+
var import_promises7 = require("fs/promises");
|
|
6443
6370
|
async function writeJsonHeader(filePath) {
|
|
6444
|
-
await (0,
|
|
6371
|
+
await (0, import_promises7.writeFile)(filePath, "", "utf-8");
|
|
6445
6372
|
}
|
|
6446
6373
|
async function appendJsonBatch(rows, filePath) {
|
|
6447
6374
|
const lines = rows.map((row) => JSON.stringify(row)).join("\n") + "\n";
|
|
6448
|
-
await (0,
|
|
6375
|
+
await (0, import_promises7.appendFile)(filePath, lines, "utf-8");
|
|
6449
6376
|
}
|
|
6450
6377
|
|
|
6451
6378
|
// ../../packages/generators/dist/analyze/columnDetector.js
|
|
@@ -7309,13 +7236,13 @@ var CourseRegistry = class {
|
|
|
7309
7236
|
|
|
7310
7237
|
// ../../packages/generators/dist/classroom/progressTracker.js
|
|
7311
7238
|
var import_node_fs2 = require("fs");
|
|
7312
|
-
var
|
|
7239
|
+
var import_node_path6 = require("path");
|
|
7313
7240
|
var import_node_os = require("os");
|
|
7314
7241
|
function getProgressDir() {
|
|
7315
|
-
return (0,
|
|
7242
|
+
return (0, import_node_path6.join)((0, import_node_os.homedir)(), ".realitydb");
|
|
7316
7243
|
}
|
|
7317
7244
|
function getProgressPath() {
|
|
7318
|
-
return (0,
|
|
7245
|
+
return (0, import_node_path6.join)(getProgressDir(), "progress.json");
|
|
7319
7246
|
}
|
|
7320
7247
|
function loadProgress() {
|
|
7321
7248
|
const filePath = getProgressPath();
|
|
@@ -10304,7 +10231,7 @@ var VALID_STRATEGY_KINDS = [
|
|
|
10304
10231
|
|
|
10305
10232
|
// ../../packages/templates/dist/loadTemplate.js
|
|
10306
10233
|
var import_node_fs3 = require("fs");
|
|
10307
|
-
var
|
|
10234
|
+
var import_node_path7 = require("path");
|
|
10308
10235
|
|
|
10309
10236
|
// ../../packages/templates/dist/validateTemplate.js
|
|
10310
10237
|
function validateTemplateJSON(json) {
|
|
@@ -10388,7 +10315,7 @@ function assertValidTemplate(json) {
|
|
|
10388
10315
|
|
|
10389
10316
|
// ../../packages/templates/dist/loadTemplate.js
|
|
10390
10317
|
function loadTemplateFromJSON(filePath) {
|
|
10391
|
-
const resolvedPath = (0,
|
|
10318
|
+
const resolvedPath = (0, import_node_path7.resolve)(filePath);
|
|
10392
10319
|
let raw;
|
|
10393
10320
|
try {
|
|
10394
10321
|
raw = (0, import_node_fs3.readFileSync)(resolvedPath, "utf-8");
|
|
@@ -10441,11 +10368,11 @@ function convertToDomainTemplate(json) {
|
|
|
10441
10368
|
|
|
10442
10369
|
// ../../packages/templates/dist/userTemplates.js
|
|
10443
10370
|
var import_node_os2 = require("os");
|
|
10444
|
-
var
|
|
10371
|
+
var import_node_path8 = require("path");
|
|
10445
10372
|
var import_node_fs4 = require("fs");
|
|
10446
10373
|
var USER_TEMPLATE_DIR_NAME = ".realitydb/templates";
|
|
10447
10374
|
function getUserTemplateDir() {
|
|
10448
|
-
return (0,
|
|
10375
|
+
return (0, import_node_path8.join)((0, import_node_os2.homedir)(), USER_TEMPLATE_DIR_NAME);
|
|
10449
10376
|
}
|
|
10450
10377
|
function listUserTemplates() {
|
|
10451
10378
|
const dir = getUserTemplateDir();
|
|
@@ -10456,14 +10383,14 @@ function listUserTemplates() {
|
|
|
10456
10383
|
const files = (0, import_node_fs4.readdirSync)(dir);
|
|
10457
10384
|
return files.filter((f) => f.endsWith(".json")).map((f) => ({
|
|
10458
10385
|
name: f.replace(/\.json$/, ""),
|
|
10459
|
-
filePath: (0,
|
|
10386
|
+
filePath: (0, import_node_path8.join)(dir, f)
|
|
10460
10387
|
}));
|
|
10461
10388
|
} catch {
|
|
10462
10389
|
return [];
|
|
10463
10390
|
}
|
|
10464
10391
|
}
|
|
10465
10392
|
function resolveUserTemplate(name) {
|
|
10466
|
-
const filePath = (0,
|
|
10393
|
+
const filePath = (0, import_node_path8.join)(getUserTemplateDir(), `${name}.json`);
|
|
10467
10394
|
if ((0, import_node_fs4.existsSync)(filePath)) {
|
|
10468
10395
|
return filePath;
|
|
10469
10396
|
}
|
|
@@ -12200,7 +12127,7 @@ async function captureDatabase(config, options) {
|
|
|
12200
12127
|
}
|
|
12201
12128
|
|
|
12202
12129
|
// ../../packages/core/dist/sharePipeline.js
|
|
12203
|
-
var
|
|
12130
|
+
var import_promises8 = require("fs/promises");
|
|
12204
12131
|
|
|
12205
12132
|
// ../../packages/core/dist/sharing/gistUpload.js
|
|
12206
12133
|
var import_node_https = __toESM(require("https"), 1);
|
|
@@ -12288,11 +12215,11 @@ function formatSize(bytes) {
|
|
|
12288
12215
|
}
|
|
12289
12216
|
async function shareRealityPack(filePath, options) {
|
|
12290
12217
|
const pack = await loadRealityPack(filePath);
|
|
12291
|
-
const fileStat = await (0,
|
|
12218
|
+
const fileStat = await (0, import_promises8.stat)(filePath);
|
|
12292
12219
|
const size = formatSize(fileStat.size);
|
|
12293
12220
|
const method = options?.method ?? "file";
|
|
12294
12221
|
if (method === "gist") {
|
|
12295
|
-
const content = await (0,
|
|
12222
|
+
const content = await (0, import_promises8.readFile)(filePath, "utf-8");
|
|
12296
12223
|
const compressed = await compressPack(content);
|
|
12297
12224
|
const compressedSize = formatSize(compressed.length);
|
|
12298
12225
|
const filename = `${pack.metadata.name}.realitydb-pack.json`;
|
|
@@ -12764,6 +12691,316 @@ function maskConnectionString(connectionString) {
|
|
|
12764
12691
|
}
|
|
12765
12692
|
}
|
|
12766
12693
|
|
|
12694
|
+
// src/commands/init.ts
|
|
12695
|
+
var CONFIG_FILE = "realitydb.config.json";
|
|
12696
|
+
var DEFAULT_CONNECTION = "postgres://postgres:postgres@localhost:5432/myapp_dev";
|
|
12697
|
+
function ask(rl, prompt) {
|
|
12698
|
+
return new Promise((resolve12) => {
|
|
12699
|
+
rl.question(prompt, (answer) => {
|
|
12700
|
+
resolve12(answer);
|
|
12701
|
+
});
|
|
12702
|
+
});
|
|
12703
|
+
}
|
|
12704
|
+
async function initCommand() {
|
|
12705
|
+
const rl = (0, import_node_readline.createInterface)({ input: import_node_process.stdin, output: import_node_process.stdout });
|
|
12706
|
+
rl.on("close", () => {
|
|
12707
|
+
if (!wizardComplete) {
|
|
12708
|
+
console.log("");
|
|
12709
|
+
console.log("");
|
|
12710
|
+
console.log("Init cancelled.");
|
|
12711
|
+
console.log("");
|
|
12712
|
+
process.exit(0);
|
|
12713
|
+
}
|
|
12714
|
+
});
|
|
12715
|
+
let wizardComplete = false;
|
|
12716
|
+
try {
|
|
12717
|
+
console.log("");
|
|
12718
|
+
console.log("Welcome to RealityDB");
|
|
12719
|
+
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");
|
|
12720
|
+
console.log("");
|
|
12721
|
+
console.log("Let's connect to your database and fill it with realistic data.");
|
|
12722
|
+
console.log("");
|
|
12723
|
+
if ((0, import_node_fs7.existsSync)(CONFIG_FILE)) {
|
|
12724
|
+
const overwrite = await ask(rl, `${CONFIG_FILE} already exists. Overwrite? (y/N) `);
|
|
12725
|
+
if (overwrite.toLowerCase() !== "y") {
|
|
12726
|
+
wizardComplete = true;
|
|
12727
|
+
console.log("");
|
|
12728
|
+
console.log("Init cancelled. Existing config preserved.");
|
|
12729
|
+
console.log("");
|
|
12730
|
+
return;
|
|
12731
|
+
}
|
|
12732
|
+
console.log("");
|
|
12733
|
+
}
|
|
12734
|
+
let connectionString;
|
|
12735
|
+
let scanResult;
|
|
12736
|
+
let masked;
|
|
12737
|
+
while (true) {
|
|
12738
|
+
console.log("Step 1: Database Connection");
|
|
12739
|
+
console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
12740
|
+
connectionString = await promptWithDefault(
|
|
12741
|
+
rl,
|
|
12742
|
+
"PostgreSQL connection string",
|
|
12743
|
+
DEFAULT_CONNECTION
|
|
12744
|
+
);
|
|
12745
|
+
console.log("");
|
|
12746
|
+
console.log("Step 2: Connecting & Scanning");
|
|
12747
|
+
console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
12748
|
+
masked = maskConnectionString(connectionString);
|
|
12749
|
+
console.log(` Connecting to ${masked}...`);
|
|
12750
|
+
const scanConfig = {
|
|
12751
|
+
database: { client: "postgres", connectionString },
|
|
12752
|
+
seed: { defaultRecords: 50, batchSize: 1e3, environment: "dev" }
|
|
12753
|
+
};
|
|
12754
|
+
try {
|
|
12755
|
+
scanResult = await scanDatabase(scanConfig);
|
|
12756
|
+
break;
|
|
12757
|
+
} catch (err) {
|
|
12758
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
12759
|
+
console.error("");
|
|
12760
|
+
console.error(` Connection failed: ${msg}`);
|
|
12761
|
+
console.error("");
|
|
12762
|
+
console.error("Hints:");
|
|
12763
|
+
console.error(" - Is PostgreSQL running? (docker ps, pg_isready)");
|
|
12764
|
+
console.error(" - Check host, port, username, password, and database name");
|
|
12765
|
+
console.error(" - Ensure the database exists (createdb myapp_dev)");
|
|
12766
|
+
console.error("");
|
|
12767
|
+
const retry = await ask(rl, "Try a different connection string? (Y/n) ");
|
|
12768
|
+
if (retry.toLowerCase() === "n") {
|
|
12769
|
+
wizardComplete = true;
|
|
12770
|
+
process.exit(1);
|
|
12771
|
+
}
|
|
12772
|
+
console.log("");
|
|
12773
|
+
}
|
|
12774
|
+
}
|
|
12775
|
+
const { schema } = scanResult;
|
|
12776
|
+
console.log(" Connected successfully.");
|
|
12777
|
+
console.log("");
|
|
12778
|
+
if (schema.tables.length === 0) {
|
|
12779
|
+
wizardComplete = true;
|
|
12780
|
+
console.log(" No tables found in the public schema.");
|
|
12781
|
+
console.log("");
|
|
12782
|
+
console.log(" Run your migrations first, then try again:");
|
|
12783
|
+
console.log(" npx prisma migrate dev");
|
|
12784
|
+
console.log(" npx knex migrate:latest");
|
|
12785
|
+
console.log(" rails db:migrate");
|
|
12786
|
+
console.log("");
|
|
12787
|
+
process.exit(1);
|
|
12788
|
+
}
|
|
12789
|
+
console.log("Step 3: Schema");
|
|
12790
|
+
console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
12791
|
+
console.log(` Found ${schema.tables.length} tables, ${schema.foreignKeys.length} foreign keys`);
|
|
12792
|
+
console.log("");
|
|
12793
|
+
console.log(" Tables:");
|
|
12794
|
+
for (const table of schema.tables) {
|
|
12795
|
+
const colCount = table.columns.length;
|
|
12796
|
+
const pkLabel = table.primaryKey ? ` PK: ${table.primaryKey.columnName}` : "";
|
|
12797
|
+
console.log(` ${table.name} (${colCount} cols${pkLabel})`);
|
|
12798
|
+
}
|
|
12799
|
+
console.log("");
|
|
12800
|
+
console.log("Step 4: Template Selection");
|
|
12801
|
+
console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
12802
|
+
const registry = getDefaultRegistry();
|
|
12803
|
+
const allTemplates = registry.list();
|
|
12804
|
+
const detected = detectTemplate(schema.tables.map((t) => t.name), allTemplates);
|
|
12805
|
+
let templateName;
|
|
12806
|
+
if (detected) {
|
|
12807
|
+
console.log(` Auto-detected domain: ${detected.name}`);
|
|
12808
|
+
console.log(` ${detected.description}`);
|
|
12809
|
+
console.log("");
|
|
12810
|
+
const useDetected = await ask(rl, ` Use "${detected.name}" template? (Y/n) `);
|
|
12811
|
+
if (useDetected.toLowerCase() !== "n") {
|
|
12812
|
+
templateName = detected.name;
|
|
12813
|
+
}
|
|
12814
|
+
}
|
|
12815
|
+
if (!templateName) {
|
|
12816
|
+
console.log("");
|
|
12817
|
+
console.log(" Available templates:");
|
|
12818
|
+
for (let i = 0; i < allTemplates.length; i++) {
|
|
12819
|
+
console.log(` ${i + 1}. ${allTemplates[i].name} \u2014 ${allTemplates[i].description}`);
|
|
12820
|
+
}
|
|
12821
|
+
console.log(` ${allTemplates.length + 1}. none \u2014 use schema-only generation`);
|
|
12822
|
+
console.log("");
|
|
12823
|
+
const choice = await ask(rl, ` Choose template (1-${allTemplates.length + 1}): `);
|
|
12824
|
+
const choiceNum = parseInt(choice, 10);
|
|
12825
|
+
if (choiceNum >= 1 && choiceNum <= allTemplates.length) {
|
|
12826
|
+
templateName = allTemplates[choiceNum - 1].name;
|
|
12827
|
+
}
|
|
12828
|
+
}
|
|
12829
|
+
console.log("");
|
|
12830
|
+
console.log("Step 5: Configuration");
|
|
12831
|
+
console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
12832
|
+
const recordsStr = await promptWithDefault(rl, "Records per table", "50");
|
|
12833
|
+
const records = parseInt(recordsStr, 10) || 50;
|
|
12834
|
+
console.log("");
|
|
12835
|
+
console.log("Step 6: Writing Config");
|
|
12836
|
+
console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
12837
|
+
const config = {
|
|
12838
|
+
database: {
|
|
12839
|
+
client: "postgres",
|
|
12840
|
+
connectionString
|
|
12841
|
+
},
|
|
12842
|
+
seed: {
|
|
12843
|
+
defaultRecords: records,
|
|
12844
|
+
batchSize: 1e3,
|
|
12845
|
+
environment: "dev",
|
|
12846
|
+
randomSeed: 42
|
|
12847
|
+
},
|
|
12848
|
+
...templateName ? { template: templateName } : {}
|
|
12849
|
+
};
|
|
12850
|
+
(0, import_node_fs7.writeFileSync)(CONFIG_FILE, JSON.stringify(config, null, 2) + "\n");
|
|
12851
|
+
console.log(` Created ${CONFIG_FILE}`);
|
|
12852
|
+
console.log("");
|
|
12853
|
+
const runSeed = await ask(rl, "Run initial seed now? (Y/n) ");
|
|
12854
|
+
if (runSeed.toLowerCase() !== "n") {
|
|
12855
|
+
console.log("");
|
|
12856
|
+
console.log("Seeding...");
|
|
12857
|
+
try {
|
|
12858
|
+
const result = await seedDatabase(config, {
|
|
12859
|
+
records,
|
|
12860
|
+
seed: 42,
|
|
12861
|
+
template: templateName
|
|
12862
|
+
});
|
|
12863
|
+
console.log("");
|
|
12864
|
+
for (const tableResult of result.insertResult.tables) {
|
|
12865
|
+
console.log(
|
|
12866
|
+
` ${tableResult.tableName}: ${tableResult.rowsInserted} rows`
|
|
12867
|
+
);
|
|
12868
|
+
}
|
|
12869
|
+
const totalTime = (result.durationMs / 1e3).toFixed(1);
|
|
12870
|
+
console.log("");
|
|
12871
|
+
console.log(` Seed complete. ${result.totalRows} rows in ${totalTime}s`);
|
|
12872
|
+
} catch (err) {
|
|
12873
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
12874
|
+
console.error("");
|
|
12875
|
+
console.error(` Seed failed: ${msg}`);
|
|
12876
|
+
console.error(" You can retry later with: realitydb seed");
|
|
12877
|
+
}
|
|
12878
|
+
}
|
|
12879
|
+
wizardComplete = true;
|
|
12880
|
+
console.log("");
|
|
12881
|
+
console.log("RealityDB initialized!");
|
|
12882
|
+
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");
|
|
12883
|
+
console.log(` Config: ./${CONFIG_FILE}`);
|
|
12884
|
+
console.log(` Database: ${masked}`);
|
|
12885
|
+
if (templateName) {
|
|
12886
|
+
console.log(` Template: ${templateName}`);
|
|
12887
|
+
}
|
|
12888
|
+
console.log(` Records: ${records} per table`);
|
|
12889
|
+
console.log("");
|
|
12890
|
+
console.log("Next steps:");
|
|
12891
|
+
console.log(" realitydb scan Inspect your schema");
|
|
12892
|
+
console.log(" realitydb seed Generate data");
|
|
12893
|
+
console.log(" realitydb export Export without writing to DB");
|
|
12894
|
+
console.log(" realitydb analyze Generate a custom template");
|
|
12895
|
+
console.log(" realitydb --help See all commands");
|
|
12896
|
+
console.log("");
|
|
12897
|
+
} finally {
|
|
12898
|
+
rl.close();
|
|
12899
|
+
}
|
|
12900
|
+
}
|
|
12901
|
+
async function promptWithDefault(rl, label, defaultValue) {
|
|
12902
|
+
console.log(` ${label}`);
|
|
12903
|
+
console.log(` Default: ${defaultValue}`);
|
|
12904
|
+
const answer = await ask(rl, " > ");
|
|
12905
|
+
return answer.trim() || defaultValue;
|
|
12906
|
+
}
|
|
12907
|
+
function detectTemplate(tableNames, templates) {
|
|
12908
|
+
const lower = new Set(tableNames.map((t) => t.toLowerCase()));
|
|
12909
|
+
let bestMatch = null;
|
|
12910
|
+
let bestScore = 0;
|
|
12911
|
+
for (const template of templates) {
|
|
12912
|
+
let matches = 0;
|
|
12913
|
+
for (const target of template.targetTables) {
|
|
12914
|
+
if (lower.has(target.toLowerCase())) {
|
|
12915
|
+
matches++;
|
|
12916
|
+
}
|
|
12917
|
+
}
|
|
12918
|
+
if (matches >= 2 && matches > bestScore) {
|
|
12919
|
+
bestScore = matches;
|
|
12920
|
+
bestMatch = template;
|
|
12921
|
+
}
|
|
12922
|
+
}
|
|
12923
|
+
return bestMatch;
|
|
12924
|
+
}
|
|
12925
|
+
|
|
12926
|
+
// ../../packages/config/dist/loadConfig.js
|
|
12927
|
+
var import_promises9 = require("fs/promises");
|
|
12928
|
+
var import_node_path9 = require("path");
|
|
12929
|
+
|
|
12930
|
+
// ../../packages/config/dist/defaults.js
|
|
12931
|
+
var DEFAULT_CONFIG = {
|
|
12932
|
+
seed: {
|
|
12933
|
+
defaultRecords: 5e3,
|
|
12934
|
+
batchSize: 1e3,
|
|
12935
|
+
environment: "dev"
|
|
12936
|
+
},
|
|
12937
|
+
export: {
|
|
12938
|
+
defaultFormat: "json",
|
|
12939
|
+
outputDir: "./.databox"
|
|
12940
|
+
}
|
|
12941
|
+
};
|
|
12942
|
+
|
|
12943
|
+
// ../../packages/config/dist/loadConfig.js
|
|
12944
|
+
var CONFIG_FILES = ["realitydb.config.json", "seedforge.config.json", "databox.config.json"];
|
|
12945
|
+
async function findConfigFile(basePath) {
|
|
12946
|
+
for (const name of CONFIG_FILES) {
|
|
12947
|
+
const fullPath = (0, import_node_path9.resolve)(basePath, name);
|
|
12948
|
+
try {
|
|
12949
|
+
await (0, import_promises9.access)(fullPath);
|
|
12950
|
+
return fullPath;
|
|
12951
|
+
} catch {
|
|
12952
|
+
continue;
|
|
12953
|
+
}
|
|
12954
|
+
}
|
|
12955
|
+
return null;
|
|
12956
|
+
}
|
|
12957
|
+
async function loadConfig(filePath) {
|
|
12958
|
+
let resolvedPath;
|
|
12959
|
+
if (filePath) {
|
|
12960
|
+
resolvedPath = (0, import_node_path9.resolve)(filePath);
|
|
12961
|
+
} else {
|
|
12962
|
+
const found = await findConfigFile(".");
|
|
12963
|
+
if (!found) {
|
|
12964
|
+
throw new Error(`[realitydb] Config file not found.
|
|
12965
|
+
Create a realitydb.config.json or specify a path with --config.`);
|
|
12966
|
+
}
|
|
12967
|
+
resolvedPath = found;
|
|
12968
|
+
}
|
|
12969
|
+
let raw;
|
|
12970
|
+
try {
|
|
12971
|
+
raw = await (0, import_promises9.readFile)(resolvedPath, "utf-8");
|
|
12972
|
+
} catch {
|
|
12973
|
+
throw new Error(`[realitydb] Config file not found: ${resolvedPath}
|
|
12974
|
+
Create a realitydb.config.json or specify a path with --config.`);
|
|
12975
|
+
}
|
|
12976
|
+
let parsed;
|
|
12977
|
+
try {
|
|
12978
|
+
parsed = JSON.parse(raw);
|
|
12979
|
+
} catch {
|
|
12980
|
+
throw new Error(`[realitydb] Invalid JSON in config file: ${resolvedPath}`);
|
|
12981
|
+
}
|
|
12982
|
+
const config = parsed;
|
|
12983
|
+
const database = config["database"];
|
|
12984
|
+
if (!database || typeof database["connectionString"] !== "string") {
|
|
12985
|
+
throw new Error("[realitydb] Config validation failed: database.connectionString is required.");
|
|
12986
|
+
}
|
|
12987
|
+
return {
|
|
12988
|
+
database: {
|
|
12989
|
+
client: "postgres",
|
|
12990
|
+
connectionString: database["connectionString"]
|
|
12991
|
+
},
|
|
12992
|
+
seed: {
|
|
12993
|
+
...DEFAULT_CONFIG.seed,
|
|
12994
|
+
...config["seed"] ?? {}
|
|
12995
|
+
},
|
|
12996
|
+
template: config["template"],
|
|
12997
|
+
export: {
|
|
12998
|
+
...DEFAULT_CONFIG.export,
|
|
12999
|
+
...config["export"] ?? {}
|
|
13000
|
+
}
|
|
13001
|
+
};
|
|
13002
|
+
}
|
|
13003
|
+
|
|
12767
13004
|
// src/commands/scan.ts
|
|
12768
13005
|
var VERSION2 = "0.10.0";
|
|
12769
13006
|
async function scanCommand(options) {
|
|
@@ -13317,7 +13554,7 @@ async function exportCommand(options) {
|
|
|
13317
13554
|
}
|
|
13318
13555
|
|
|
13319
13556
|
// src/commands/templates.ts
|
|
13320
|
-
var
|
|
13557
|
+
var import_node_fs8 = require("fs");
|
|
13321
13558
|
var VERSION6 = "0.10.0";
|
|
13322
13559
|
function templatesCommand() {
|
|
13323
13560
|
const registry = getDefaultRegistry();
|
|
@@ -13344,7 +13581,7 @@ function templatesCommand() {
|
|
|
13344
13581
|
}
|
|
13345
13582
|
function templatesInitCommand() {
|
|
13346
13583
|
const fileName = "realitydb.template.json";
|
|
13347
|
-
if ((0,
|
|
13584
|
+
if ((0, import_node_fs8.existsSync)(fileName)) {
|
|
13348
13585
|
console.error(`[realitydb] ${fileName} already exists in this directory.`);
|
|
13349
13586
|
process.exit(1);
|
|
13350
13587
|
}
|
|
@@ -13378,7 +13615,7 @@ function templatesInitCommand() {
|
|
|
13378
13615
|
}
|
|
13379
13616
|
}
|
|
13380
13617
|
};
|
|
13381
|
-
(0,
|
|
13618
|
+
(0, import_node_fs8.writeFileSync)(fileName, JSON.stringify(scaffold, null, 2) + "\n");
|
|
13382
13619
|
console.log("");
|
|
13383
13620
|
console.log(`Created ${fileName}`);
|
|
13384
13621
|
console.log("Edit this file to define your custom template.");
|
|
@@ -13389,7 +13626,7 @@ function templatesInitCommand() {
|
|
|
13389
13626
|
}
|
|
13390
13627
|
function templatesValidateCommand(filePath, options) {
|
|
13391
13628
|
const start = performance.now();
|
|
13392
|
-
if (!(0,
|
|
13629
|
+
if (!(0, import_node_fs8.existsSync)(filePath)) {
|
|
13393
13630
|
if (options.ci) {
|
|
13394
13631
|
console.log(formatCIOutput({
|
|
13395
13632
|
success: false,
|
|
@@ -13406,7 +13643,7 @@ function templatesValidateCommand(filePath, options) {
|
|
|
13406
13643
|
}
|
|
13407
13644
|
let json;
|
|
13408
13645
|
try {
|
|
13409
|
-
const raw = (0,
|
|
13646
|
+
const raw = (0, import_node_fs8.readFileSync)(filePath, "utf-8");
|
|
13410
13647
|
json = JSON.parse(raw);
|
|
13411
13648
|
} catch {
|
|
13412
13649
|
if (options.ci) {
|
|
@@ -13469,7 +13706,7 @@ function templatesValidateCommand(filePath, options) {
|
|
|
13469
13706
|
}
|
|
13470
13707
|
|
|
13471
13708
|
// src/commands/scenarios.ts
|
|
13472
|
-
var
|
|
13709
|
+
var import_node_fs9 = require("fs");
|
|
13473
13710
|
var import_node_path12 = require("path");
|
|
13474
13711
|
function scenariosCommand() {
|
|
13475
13712
|
const registry = getDefaultScenarioRegistry();
|
|
@@ -13494,12 +13731,12 @@ function scenariosCreateCommand(name) {
|
|
|
13494
13731
|
const sanitized = name.trim().toLowerCase().replace(/[^a-z0-9-]/g, "-");
|
|
13495
13732
|
const fileName = `${sanitized}.scenario.json`;
|
|
13496
13733
|
const filePath = (0, import_node_path12.resolve)(fileName);
|
|
13497
|
-
if ((0,
|
|
13734
|
+
if ((0, import_node_fs9.existsSync)(filePath)) {
|
|
13498
13735
|
console.error(`[realitydb] File already exists: ${fileName}`);
|
|
13499
13736
|
process.exit(1);
|
|
13500
13737
|
}
|
|
13501
13738
|
const scaffold = scaffoldCustomScenario(sanitized);
|
|
13502
|
-
(0,
|
|
13739
|
+
(0, import_node_fs9.writeFileSync)(filePath, JSON.stringify(scaffold, null, 2) + "\n", "utf-8");
|
|
13503
13740
|
console.log("");
|
|
13504
13741
|
console.log(`Created custom scenario: ${fileName}`);
|
|
13505
13742
|
console.log("");
|
|
@@ -14254,7 +14491,7 @@ function getDefaultSchema() {
|
|
|
14254
14491
|
}
|
|
14255
14492
|
|
|
14256
14493
|
// src/commands/analyze.ts
|
|
14257
|
-
var
|
|
14494
|
+
var import_node_fs10 = require("fs");
|
|
14258
14495
|
var import_node_path16 = require("path");
|
|
14259
14496
|
var VERSION12 = "1.3.1";
|
|
14260
14497
|
async function analyzeCommand(options) {
|
|
@@ -14296,14 +14533,14 @@ async function analyzeCommand(options) {
|
|
|
14296
14533
|
}));
|
|
14297
14534
|
if (result.templateJson && options.output) {
|
|
14298
14535
|
const filePath = (0, import_node_path16.resolve)(options.output);
|
|
14299
|
-
(0,
|
|
14536
|
+
(0, import_node_fs10.writeFileSync)(filePath, result.templateJson + "\n", "utf-8");
|
|
14300
14537
|
}
|
|
14301
14538
|
return;
|
|
14302
14539
|
}
|
|
14303
14540
|
console.log(formatAnalysisReport(result.report));
|
|
14304
14541
|
if (result.templateJson && options.output) {
|
|
14305
14542
|
const filePath = (0, import_node_path16.resolve)(options.output);
|
|
14306
|
-
(0,
|
|
14543
|
+
(0, import_node_fs10.writeFileSync)(filePath, result.templateJson + "\n", "utf-8");
|
|
14307
14544
|
console.log("\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
14308
14545
|
console.log(`Template generated: ${filePath}`);
|
|
14309
14546
|
console.log("");
|
|
@@ -14348,7 +14585,7 @@ async function analyzeCommand(options) {
|
|
|
14348
14585
|
}
|
|
14349
14586
|
|
|
14350
14587
|
// src/commands/mask.ts
|
|
14351
|
-
var
|
|
14588
|
+
var import_node_fs11 = require("fs");
|
|
14352
14589
|
var import_node_path17 = require("path");
|
|
14353
14590
|
var VERSION13 = "1.3.1";
|
|
14354
14591
|
async function maskCommand(options) {
|
|
@@ -14426,7 +14663,7 @@ async function maskCommand(options) {
|
|
|
14426
14663
|
const durationMs = Math.round(performance.now() - start);
|
|
14427
14664
|
if (options.auditLog) {
|
|
14428
14665
|
const auditPath = (0, import_node_path17.resolve)(options.auditLog);
|
|
14429
|
-
(0,
|
|
14666
|
+
(0, import_node_fs11.writeFileSync)(auditPath, serializeAuditLog(result.auditLog) + "\n", "utf-8");
|
|
14430
14667
|
}
|
|
14431
14668
|
if (options.ci) {
|
|
14432
14669
|
console.log(formatCIOutput({
|
|
@@ -14501,7 +14738,7 @@ async function maskCommand(options) {
|
|
|
14501
14738
|
}
|
|
14502
14739
|
|
|
14503
14740
|
// src/commands/classroom.ts
|
|
14504
|
-
var
|
|
14741
|
+
var import_node_fs12 = require("fs");
|
|
14505
14742
|
var import_node_path18 = require("path");
|
|
14506
14743
|
var VERSION14 = "1.3.1";
|
|
14507
14744
|
async function classroomListCommand(options) {
|
|
@@ -14766,7 +15003,7 @@ async function classroomCreateCommand(name, options) {
|
|
|
14766
15003
|
const content = classroomCreate(name);
|
|
14767
15004
|
const filename = `${name}.course.json`;
|
|
14768
15005
|
const filePath = (0, import_node_path18.resolve)(filename);
|
|
14769
|
-
(0,
|
|
15006
|
+
(0, import_node_fs12.writeFileSync)(filePath, content + "\n", "utf-8");
|
|
14770
15007
|
const durationMs = Math.round(performance.now() - start);
|
|
14771
15008
|
if (options.ci) {
|
|
14772
15009
|
console.log(formatCIOutput({
|
|
@@ -15016,10 +15253,13 @@ async function simulateWebhooksCommand(options) {
|
|
|
15016
15253
|
}
|
|
15017
15254
|
|
|
15018
15255
|
// src/cli.ts
|
|
15019
|
-
var VERSION16 = "1.
|
|
15256
|
+
var VERSION16 = "1.5.0";
|
|
15020
15257
|
function run(argv) {
|
|
15021
15258
|
const program2 = new Command();
|
|
15022
15259
|
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);
|
|
15260
|
+
program2.command("init").description("Interactive setup wizard \u2014 connect, scan, and seed in one step").action(async () => {
|
|
15261
|
+
await initCommand();
|
|
15262
|
+
});
|
|
15023
15263
|
program2.command("scan").description("Scan database schema").action(async () => {
|
|
15024
15264
|
const opts = program2.opts();
|
|
15025
15265
|
await scanCommand({ ci: opts.ci, configPath: opts.config });
|
package/package.json
CHANGED