realitydb 1.4.4 → 1.5.1
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 +406 -142
- 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) {
|
|
@@ -3642,7 +3569,16 @@ function inferColumnStrategy(column, tableForeignKeys, tableName) {
|
|
|
3642
3569
|
return { kind: "company_name" };
|
|
3643
3570
|
}
|
|
3644
3571
|
if (name.includes("amount") || name.includes("price") || name.includes("cost") || name.includes("total")) {
|
|
3645
|
-
|
|
3572
|
+
let min = 100;
|
|
3573
|
+
let max = 1e5;
|
|
3574
|
+
if (column.numericPrecision !== null && column.numericScale !== null) {
|
|
3575
|
+
const columnMax = Math.pow(10, column.numericPrecision - column.numericScale) - Math.pow(10, -column.numericScale);
|
|
3576
|
+
if (max > columnMax)
|
|
3577
|
+
max = columnMax;
|
|
3578
|
+
if (min > max)
|
|
3579
|
+
min = 0;
|
|
3580
|
+
}
|
|
3581
|
+
return { kind: "money", options: { min, max } };
|
|
3646
3582
|
}
|
|
3647
3583
|
if (name.includes("status")) {
|
|
3648
3584
|
return {
|
|
@@ -3685,7 +3621,11 @@ function inferColumnStrategy(column, tableForeignKeys, tableName) {
|
|
|
3685
3621
|
return { kind: "integer", options: { min: 0, max: 1e4 } };
|
|
3686
3622
|
}
|
|
3687
3623
|
if (dataType === "numeric" || dataType === "decimal" || dataType === "float4" || dataType === "float8" || dataType === "float") {
|
|
3688
|
-
|
|
3624
|
+
let max = 1e4;
|
|
3625
|
+
if (column.numericPrecision !== null && column.numericScale !== null) {
|
|
3626
|
+
max = Math.pow(10, column.numericPrecision - column.numericScale) - Math.pow(10, -column.numericScale);
|
|
3627
|
+
}
|
|
3628
|
+
return { kind: "float", options: { min: 0, max } };
|
|
3689
3629
|
}
|
|
3690
3630
|
if (dataType === "bool" || dataType === "boolean") {
|
|
3691
3631
|
return { kind: "boolean", options: { trueWeight: 0.5 } };
|
|
@@ -4390,32 +4330,32 @@ function generateDataset(plan) {
|
|
|
4390
4330
|
}
|
|
4391
4331
|
|
|
4392
4332
|
// ../../packages/generators/dist/exporters/json.js
|
|
4393
|
-
var
|
|
4394
|
-
var
|
|
4333
|
+
var import_promises = require("fs/promises");
|
|
4334
|
+
var import_node_path = require("path");
|
|
4395
4335
|
async function exportToJson(dataset, outputDir) {
|
|
4396
|
-
await (0,
|
|
4336
|
+
await (0, import_promises.mkdir)(outputDir, { recursive: true });
|
|
4397
4337
|
const files = [];
|
|
4398
4338
|
for (const [tableName, table] of dataset.tables) {
|
|
4399
|
-
const filePath = (0,
|
|
4339
|
+
const filePath = (0, import_node_path.join)(outputDir, `${tableName}.json`);
|
|
4400
4340
|
const content = JSON.stringify(table.rows, null, 2);
|
|
4401
|
-
await (0,
|
|
4341
|
+
await (0, import_promises.writeFile)(filePath, content, "utf-8");
|
|
4402
4342
|
files.push(filePath);
|
|
4403
4343
|
}
|
|
4404
4344
|
return files;
|
|
4405
4345
|
}
|
|
4406
4346
|
|
|
4407
4347
|
// ../../packages/generators/dist/exporters/csv.js
|
|
4408
|
-
var
|
|
4409
|
-
var
|
|
4348
|
+
var import_promises2 = require("fs/promises");
|
|
4349
|
+
var import_node_path2 = require("path");
|
|
4410
4350
|
async function exportToCsv(dataset, outputDir) {
|
|
4411
|
-
await (0,
|
|
4351
|
+
await (0, import_promises2.mkdir)(outputDir, { recursive: true });
|
|
4412
4352
|
const files = [];
|
|
4413
4353
|
for (const [tableName, table] of dataset.tables) {
|
|
4414
|
-
const filePath = (0,
|
|
4354
|
+
const filePath = (0, import_node_path2.join)(outputDir, `${tableName}.csv`);
|
|
4415
4355
|
const header = table.columns.map(escapeCsvField).join(",");
|
|
4416
4356
|
const rows = table.rows.map((row) => table.columns.map((col) => escapeCsvField(String(row[col] ?? ""))).join(","));
|
|
4417
4357
|
const content = [header, ...rows].join("\n");
|
|
4418
|
-
await (0,
|
|
4358
|
+
await (0, import_promises2.writeFile)(filePath, content, "utf-8");
|
|
4419
4359
|
files.push(filePath);
|
|
4420
4360
|
}
|
|
4421
4361
|
return files;
|
|
@@ -4428,10 +4368,10 @@ function escapeCsvField(value) {
|
|
|
4428
4368
|
}
|
|
4429
4369
|
|
|
4430
4370
|
// ../../packages/generators/dist/exporters/sql.js
|
|
4431
|
-
var
|
|
4432
|
-
var
|
|
4371
|
+
var import_promises3 = require("fs/promises");
|
|
4372
|
+
var import_node_path3 = require("path");
|
|
4433
4373
|
async function exportToSql(dataset, outputDir, tableOrder) {
|
|
4434
|
-
await (0,
|
|
4374
|
+
await (0, import_promises3.mkdir)(outputDir, { recursive: true });
|
|
4435
4375
|
const lines = [];
|
|
4436
4376
|
lines.push("-- Generated by DataBox");
|
|
4437
4377
|
lines.push(`-- Seed: ${dataset.seed}`);
|
|
@@ -4448,8 +4388,8 @@ async function exportToSql(dataset, outputDir, tableOrder) {
|
|
|
4448
4388
|
}
|
|
4449
4389
|
lines.push("");
|
|
4450
4390
|
}
|
|
4451
|
-
const filePath = (0,
|
|
4452
|
-
await (0,
|
|
4391
|
+
const filePath = (0, import_node_path3.join)(outputDir, "seed.sql");
|
|
4392
|
+
await (0, import_promises3.writeFile)(filePath, lines.join("\n"), "utf-8");
|
|
4453
4393
|
return [filePath];
|
|
4454
4394
|
}
|
|
4455
4395
|
function escapeSqlValue(value) {
|
|
@@ -5731,7 +5671,7 @@ function countRows2(dataset) {
|
|
|
5731
5671
|
|
|
5732
5672
|
// ../../packages/generators/dist/scenarios/loadScenario.js
|
|
5733
5673
|
var import_node_fs = require("fs");
|
|
5734
|
-
var
|
|
5674
|
+
var import_node_path4 = require("path");
|
|
5735
5675
|
function scaffoldCustomScenario(name) {
|
|
5736
5676
|
return {
|
|
5737
5677
|
name,
|
|
@@ -5802,8 +5742,8 @@ function extractTablesFromModifications(modifications) {
|
|
|
5802
5742
|
}
|
|
5803
5743
|
|
|
5804
5744
|
// ../../packages/generators/dist/packExporter.js
|
|
5805
|
-
var
|
|
5806
|
-
var
|
|
5745
|
+
var import_promises4 = require("fs/promises");
|
|
5746
|
+
var import_node_path5 = require("path");
|
|
5807
5747
|
function exportRealityPack(dataset, plan, schema, options) {
|
|
5808
5748
|
const name = options?.name ?? plan.config.templateName ?? "realitydb-pack";
|
|
5809
5749
|
const packSchema = {
|
|
@@ -5851,14 +5791,14 @@ function exportRealityPack(dataset, plan, schema, options) {
|
|
|
5851
5791
|
}
|
|
5852
5792
|
async function saveRealityPack(pack, outputPath) {
|
|
5853
5793
|
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,
|
|
5794
|
+
await (0, import_promises4.mkdir)((0, import_node_path5.dirname)(filePath), { recursive: true });
|
|
5795
|
+
await (0, import_promises4.writeFile)(filePath, JSON.stringify(pack, null, 2), "utf-8");
|
|
5856
5796
|
return filePath;
|
|
5857
5797
|
}
|
|
5858
5798
|
async function loadRealityPack(filePath) {
|
|
5859
5799
|
let raw;
|
|
5860
5800
|
try {
|
|
5861
|
-
raw = await (0,
|
|
5801
|
+
raw = await (0, import_promises4.readFile)(filePath, "utf-8");
|
|
5862
5802
|
} catch (err) {
|
|
5863
5803
|
const message = err instanceof Error ? err.message : String(err);
|
|
5864
5804
|
throw new Error(`Failed to read Reality Pack file: ${message}`);
|
|
@@ -6414,7 +6354,7 @@ function isIntLike(value) {
|
|
|
6414
6354
|
}
|
|
6415
6355
|
|
|
6416
6356
|
// ../../packages/generators/dist/writers/parquet.js
|
|
6417
|
-
var
|
|
6357
|
+
var import_promises5 = require("fs/promises");
|
|
6418
6358
|
async function appendParquetBatch(rows, filePath) {
|
|
6419
6359
|
const { appendFile: appendFile3 } = await import("fs/promises");
|
|
6420
6360
|
const lines = rows.map((row) => JSON.stringify(row)).join("\n") + "\n";
|
|
@@ -6422,14 +6362,14 @@ async function appendParquetBatch(rows, filePath) {
|
|
|
6422
6362
|
}
|
|
6423
6363
|
|
|
6424
6364
|
// ../../packages/generators/dist/writers/csv.js
|
|
6425
|
-
var
|
|
6365
|
+
var import_promises6 = require("fs/promises");
|
|
6426
6366
|
async function writeCsvHeader(columns, filePath) {
|
|
6427
6367
|
const header = columns.map(escapeCsvField2).join(",") + "\n";
|
|
6428
|
-
await (0,
|
|
6368
|
+
await (0, import_promises6.writeFile)(filePath, header, "utf-8");
|
|
6429
6369
|
}
|
|
6430
6370
|
async function appendCsvBatch(rows, columns, filePath) {
|
|
6431
6371
|
const lines = rows.map((row) => columns.map((col) => escapeCsvField2(String(row[col] ?? ""))).join(",")).join("\n") + "\n";
|
|
6432
|
-
await (0,
|
|
6372
|
+
await (0, import_promises6.appendFile)(filePath, lines, "utf-8");
|
|
6433
6373
|
}
|
|
6434
6374
|
function escapeCsvField2(value) {
|
|
6435
6375
|
if (value.includes(",") || value.includes('"') || value.includes("\n") || value.includes("\r")) {
|
|
@@ -6439,13 +6379,13 @@ function escapeCsvField2(value) {
|
|
|
6439
6379
|
}
|
|
6440
6380
|
|
|
6441
6381
|
// ../../packages/generators/dist/writers/json.js
|
|
6442
|
-
var
|
|
6382
|
+
var import_promises7 = require("fs/promises");
|
|
6443
6383
|
async function writeJsonHeader(filePath) {
|
|
6444
|
-
await (0,
|
|
6384
|
+
await (0, import_promises7.writeFile)(filePath, "", "utf-8");
|
|
6445
6385
|
}
|
|
6446
6386
|
async function appendJsonBatch(rows, filePath) {
|
|
6447
6387
|
const lines = rows.map((row) => JSON.stringify(row)).join("\n") + "\n";
|
|
6448
|
-
await (0,
|
|
6388
|
+
await (0, import_promises7.appendFile)(filePath, lines, "utf-8");
|
|
6449
6389
|
}
|
|
6450
6390
|
|
|
6451
6391
|
// ../../packages/generators/dist/analyze/columnDetector.js
|
|
@@ -6574,7 +6514,11 @@ function detectColumn(column, tableForeignKeys, tableName) {
|
|
|
6574
6514
|
return { ...base, detectedKind: "integer", strategy: { kind: "integer", options: { min: 0, max: 1e4 } }, confidence: "medium", reason: "Integer data type (refine range with sample data)" };
|
|
6575
6515
|
}
|
|
6576
6516
|
if (["numeric", "decimal", "float4", "float8", "float", "real", "double precision"].includes(dataType)) {
|
|
6577
|
-
|
|
6517
|
+
let max = 1e4;
|
|
6518
|
+
if (column.numericPrecision !== null && column.numericScale !== null) {
|
|
6519
|
+
max = Math.pow(10, column.numericPrecision - column.numericScale) - Math.pow(10, -column.numericScale);
|
|
6520
|
+
}
|
|
6521
|
+
return { ...base, detectedKind: "float", strategy: { kind: "float", options: { min: 0, max } }, confidence: "medium", reason: "Float data type (refine range with sample data)" };
|
|
6578
6522
|
}
|
|
6579
6523
|
if ((dataType === "varchar" || dataType === "text" || dataType === "char") && column.maxLength !== null && column.maxLength <= 10) {
|
|
6580
6524
|
return { ...base, detectedKind: "text", strategy: { kind: "text", options: { mode: "short" } }, confidence: "low", reason: "Short text column" };
|
|
@@ -7309,13 +7253,13 @@ var CourseRegistry = class {
|
|
|
7309
7253
|
|
|
7310
7254
|
// ../../packages/generators/dist/classroom/progressTracker.js
|
|
7311
7255
|
var import_node_fs2 = require("fs");
|
|
7312
|
-
var
|
|
7256
|
+
var import_node_path6 = require("path");
|
|
7313
7257
|
var import_node_os = require("os");
|
|
7314
7258
|
function getProgressDir() {
|
|
7315
|
-
return (0,
|
|
7259
|
+
return (0, import_node_path6.join)((0, import_node_os.homedir)(), ".realitydb");
|
|
7316
7260
|
}
|
|
7317
7261
|
function getProgressPath() {
|
|
7318
|
-
return (0,
|
|
7262
|
+
return (0, import_node_path6.join)(getProgressDir(), "progress.json");
|
|
7319
7263
|
}
|
|
7320
7264
|
function loadProgress() {
|
|
7321
7265
|
const filePath = getProgressPath();
|
|
@@ -10304,7 +10248,7 @@ var VALID_STRATEGY_KINDS = [
|
|
|
10304
10248
|
|
|
10305
10249
|
// ../../packages/templates/dist/loadTemplate.js
|
|
10306
10250
|
var import_node_fs3 = require("fs");
|
|
10307
|
-
var
|
|
10251
|
+
var import_node_path7 = require("path");
|
|
10308
10252
|
|
|
10309
10253
|
// ../../packages/templates/dist/validateTemplate.js
|
|
10310
10254
|
function validateTemplateJSON(json) {
|
|
@@ -10388,7 +10332,7 @@ function assertValidTemplate(json) {
|
|
|
10388
10332
|
|
|
10389
10333
|
// ../../packages/templates/dist/loadTemplate.js
|
|
10390
10334
|
function loadTemplateFromJSON(filePath) {
|
|
10391
|
-
const resolvedPath = (0,
|
|
10335
|
+
const resolvedPath = (0, import_node_path7.resolve)(filePath);
|
|
10392
10336
|
let raw;
|
|
10393
10337
|
try {
|
|
10394
10338
|
raw = (0, import_node_fs3.readFileSync)(resolvedPath, "utf-8");
|
|
@@ -10441,11 +10385,11 @@ function convertToDomainTemplate(json) {
|
|
|
10441
10385
|
|
|
10442
10386
|
// ../../packages/templates/dist/userTemplates.js
|
|
10443
10387
|
var import_node_os2 = require("os");
|
|
10444
|
-
var
|
|
10388
|
+
var import_node_path8 = require("path");
|
|
10445
10389
|
var import_node_fs4 = require("fs");
|
|
10446
10390
|
var USER_TEMPLATE_DIR_NAME = ".realitydb/templates";
|
|
10447
10391
|
function getUserTemplateDir() {
|
|
10448
|
-
return (0,
|
|
10392
|
+
return (0, import_node_path8.join)((0, import_node_os2.homedir)(), USER_TEMPLATE_DIR_NAME);
|
|
10449
10393
|
}
|
|
10450
10394
|
function listUserTemplates() {
|
|
10451
10395
|
const dir = getUserTemplateDir();
|
|
@@ -10456,14 +10400,14 @@ function listUserTemplates() {
|
|
|
10456
10400
|
const files = (0, import_node_fs4.readdirSync)(dir);
|
|
10457
10401
|
return files.filter((f) => f.endsWith(".json")).map((f) => ({
|
|
10458
10402
|
name: f.replace(/\.json$/, ""),
|
|
10459
|
-
filePath: (0,
|
|
10403
|
+
filePath: (0, import_node_path8.join)(dir, f)
|
|
10460
10404
|
}));
|
|
10461
10405
|
} catch {
|
|
10462
10406
|
return [];
|
|
10463
10407
|
}
|
|
10464
10408
|
}
|
|
10465
10409
|
function resolveUserTemplate(name) {
|
|
10466
|
-
const filePath = (0,
|
|
10410
|
+
const filePath = (0, import_node_path8.join)(getUserTemplateDir(), `${name}.json`);
|
|
10467
10411
|
if ((0, import_node_fs4.existsSync)(filePath)) {
|
|
10468
10412
|
return filePath;
|
|
10469
10413
|
}
|
|
@@ -11204,6 +11148,8 @@ function normalizeSchema(raw) {
|
|
|
11204
11148
|
hasDefault: col.column_default !== null,
|
|
11205
11149
|
defaultValue: col.column_default,
|
|
11206
11150
|
maxLength: col.character_maximum_length,
|
|
11151
|
+
numericPrecision: col.numeric_precision ?? null,
|
|
11152
|
+
numericScale: col.numeric_scale ?? null,
|
|
11207
11153
|
isPrimaryKey: pk !== null && pk.column_name === col.column_name,
|
|
11208
11154
|
isUnique: pk !== null && pk.column_name === col.column_name || uniqueColumns.has(`${rawTable.table_name}.${col.column_name}`),
|
|
11209
11155
|
ordinalPosition: col.ordinal_position
|
|
@@ -11298,7 +11244,7 @@ async function getTables(pool, schemaName = "public") {
|
|
|
11298
11244
|
async function getColumns(pool, schemaName = "public") {
|
|
11299
11245
|
const result = await pool.query(`SELECT table_name, column_name, data_type, udt_name,
|
|
11300
11246
|
is_nullable, column_default, character_maximum_length,
|
|
11301
|
-
ordinal_position
|
|
11247
|
+
numeric_precision, numeric_scale, ordinal_position
|
|
11302
11248
|
FROM information_schema.columns
|
|
11303
11249
|
WHERE table_schema = $1
|
|
11304
11250
|
ORDER BY table_name, ordinal_position`, [schemaName]);
|
|
@@ -11550,7 +11496,7 @@ function parseColumnDef(def, tableName, ordinal) {
|
|
|
11550
11496
|
const name = colMatch[1];
|
|
11551
11497
|
const rawType = colMatch[2].trim();
|
|
11552
11498
|
const constraints = colMatch[3] ?? "";
|
|
11553
|
-
const { dataType, udtName, maxLength } = normalizeDataType(rawType);
|
|
11499
|
+
const { dataType, udtName, maxLength, numericPrecision, numericScale } = normalizeDataType(rawType);
|
|
11554
11500
|
const isNullable = !/NOT\s+NULL/i.test(constraints);
|
|
11555
11501
|
const isPrimaryKey = /PRIMARY\s+KEY/i.test(constraints);
|
|
11556
11502
|
const isUnique = /UNIQUE/i.test(constraints) || isPrimaryKey;
|
|
@@ -11577,6 +11523,8 @@ function parseColumnDef(def, tableName, ordinal) {
|
|
|
11577
11523
|
hasDefault,
|
|
11578
11524
|
defaultValue,
|
|
11579
11525
|
maxLength,
|
|
11526
|
+
numericPrecision,
|
|
11527
|
+
numericScale,
|
|
11580
11528
|
isPrimaryKey,
|
|
11581
11529
|
isUnique,
|
|
11582
11530
|
ordinalPosition: ordinal
|
|
@@ -11588,6 +11536,9 @@ function normalizeDataType(raw) {
|
|
|
11588
11536
|
const lower = raw.toLowerCase().trim();
|
|
11589
11537
|
const lengthMatch = lower.match(/(?:varchar|character varying|char|character)\s*\((\d+)\)/);
|
|
11590
11538
|
const maxLength = lengthMatch ? parseInt(lengthMatch[1], 10) : null;
|
|
11539
|
+
const numericMatch = lower.match(/(?:numeric|decimal)\s*\((\d+)\s*,\s*(\d+)\)/);
|
|
11540
|
+
const numericPrecision = numericMatch ? parseInt(numericMatch[1], 10) : null;
|
|
11541
|
+
const numericScale = numericMatch ? parseInt(numericMatch[2], 10) : null;
|
|
11591
11542
|
const typeMap = {
|
|
11592
11543
|
serial: { dataType: "integer", udtName: "int4" },
|
|
11593
11544
|
bigserial: { dataType: "bigint", udtName: "int8" },
|
|
@@ -11615,15 +11566,15 @@ function normalizeDataType(raw) {
|
|
|
11615
11566
|
const baseLower = lower.replace(/\s*\([^)]*\)/, "").trim();
|
|
11616
11567
|
const mapped = typeMap[baseLower];
|
|
11617
11568
|
if (mapped) {
|
|
11618
|
-
return { ...mapped, maxLength };
|
|
11569
|
+
return { ...mapped, maxLength, numericPrecision, numericScale };
|
|
11619
11570
|
}
|
|
11620
11571
|
if (baseLower.startsWith("varchar") || baseLower.startsWith("character varying")) {
|
|
11621
|
-
return { dataType: "character varying", udtName: "varchar", maxLength };
|
|
11572
|
+
return { dataType: "character varying", udtName: "varchar", maxLength, numericPrecision, numericScale };
|
|
11622
11573
|
}
|
|
11623
11574
|
if (baseLower.startsWith("char") || baseLower.startsWith("character")) {
|
|
11624
|
-
return { dataType: "character", udtName: "bpchar", maxLength };
|
|
11575
|
+
return { dataType: "character", udtName: "bpchar", maxLength, numericPrecision, numericScale };
|
|
11625
11576
|
}
|
|
11626
|
-
return { dataType: lower, udtName: lower, maxLength };
|
|
11577
|
+
return { dataType: lower, udtName: lower, maxLength, numericPrecision, numericScale };
|
|
11627
11578
|
}
|
|
11628
11579
|
function splitTableBody(body) {
|
|
11629
11580
|
const parts = [];
|
|
@@ -12200,7 +12151,7 @@ async function captureDatabase(config, options) {
|
|
|
12200
12151
|
}
|
|
12201
12152
|
|
|
12202
12153
|
// ../../packages/core/dist/sharePipeline.js
|
|
12203
|
-
var
|
|
12154
|
+
var import_promises8 = require("fs/promises");
|
|
12204
12155
|
|
|
12205
12156
|
// ../../packages/core/dist/sharing/gistUpload.js
|
|
12206
12157
|
var import_node_https = __toESM(require("https"), 1);
|
|
@@ -12288,11 +12239,11 @@ function formatSize(bytes) {
|
|
|
12288
12239
|
}
|
|
12289
12240
|
async function shareRealityPack(filePath, options) {
|
|
12290
12241
|
const pack = await loadRealityPack(filePath);
|
|
12291
|
-
const fileStat = await (0,
|
|
12242
|
+
const fileStat = await (0, import_promises8.stat)(filePath);
|
|
12292
12243
|
const size = formatSize(fileStat.size);
|
|
12293
12244
|
const method = options?.method ?? "file";
|
|
12294
12245
|
if (method === "gist") {
|
|
12295
|
-
const content = await (0,
|
|
12246
|
+
const content = await (0, import_promises8.readFile)(filePath, "utf-8");
|
|
12296
12247
|
const compressed = await compressPack(content);
|
|
12297
12248
|
const compressedSize = formatSize(compressed.length);
|
|
12298
12249
|
const filename = `${pack.metadata.name}.realitydb-pack.json`;
|
|
@@ -12764,6 +12715,316 @@ function maskConnectionString(connectionString) {
|
|
|
12764
12715
|
}
|
|
12765
12716
|
}
|
|
12766
12717
|
|
|
12718
|
+
// src/commands/init.ts
|
|
12719
|
+
var CONFIG_FILE = "realitydb.config.json";
|
|
12720
|
+
var DEFAULT_CONNECTION = "postgres://postgres:postgres@localhost:5432/myapp_dev";
|
|
12721
|
+
function ask(rl, prompt) {
|
|
12722
|
+
return new Promise((resolve12) => {
|
|
12723
|
+
rl.question(prompt, (answer) => {
|
|
12724
|
+
resolve12(answer);
|
|
12725
|
+
});
|
|
12726
|
+
});
|
|
12727
|
+
}
|
|
12728
|
+
async function initCommand() {
|
|
12729
|
+
const rl = (0, import_node_readline.createInterface)({ input: import_node_process.stdin, output: import_node_process.stdout });
|
|
12730
|
+
rl.on("close", () => {
|
|
12731
|
+
if (!wizardComplete) {
|
|
12732
|
+
console.log("");
|
|
12733
|
+
console.log("");
|
|
12734
|
+
console.log("Init cancelled.");
|
|
12735
|
+
console.log("");
|
|
12736
|
+
process.exit(0);
|
|
12737
|
+
}
|
|
12738
|
+
});
|
|
12739
|
+
let wizardComplete = false;
|
|
12740
|
+
try {
|
|
12741
|
+
console.log("");
|
|
12742
|
+
console.log("Welcome to RealityDB");
|
|
12743
|
+
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");
|
|
12744
|
+
console.log("");
|
|
12745
|
+
console.log("Let's connect to your database and fill it with realistic data.");
|
|
12746
|
+
console.log("");
|
|
12747
|
+
if ((0, import_node_fs7.existsSync)(CONFIG_FILE)) {
|
|
12748
|
+
const overwrite = await ask(rl, `${CONFIG_FILE} already exists. Overwrite? (y/N) `);
|
|
12749
|
+
if (overwrite.toLowerCase() !== "y") {
|
|
12750
|
+
wizardComplete = true;
|
|
12751
|
+
console.log("");
|
|
12752
|
+
console.log("Init cancelled. Existing config preserved.");
|
|
12753
|
+
console.log("");
|
|
12754
|
+
return;
|
|
12755
|
+
}
|
|
12756
|
+
console.log("");
|
|
12757
|
+
}
|
|
12758
|
+
let connectionString;
|
|
12759
|
+
let scanResult;
|
|
12760
|
+
let masked;
|
|
12761
|
+
while (true) {
|
|
12762
|
+
console.log("Step 1: Database Connection");
|
|
12763
|
+
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");
|
|
12764
|
+
connectionString = await promptWithDefault(
|
|
12765
|
+
rl,
|
|
12766
|
+
"PostgreSQL connection string",
|
|
12767
|
+
DEFAULT_CONNECTION
|
|
12768
|
+
);
|
|
12769
|
+
console.log("");
|
|
12770
|
+
console.log("Step 2: Connecting & Scanning");
|
|
12771
|
+
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");
|
|
12772
|
+
masked = maskConnectionString(connectionString);
|
|
12773
|
+
console.log(` Connecting to ${masked}...`);
|
|
12774
|
+
const scanConfig = {
|
|
12775
|
+
database: { client: "postgres", connectionString },
|
|
12776
|
+
seed: { defaultRecords: 50, batchSize: 1e3, environment: "dev" }
|
|
12777
|
+
};
|
|
12778
|
+
try {
|
|
12779
|
+
scanResult = await scanDatabase(scanConfig);
|
|
12780
|
+
break;
|
|
12781
|
+
} catch (err) {
|
|
12782
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
12783
|
+
console.error("");
|
|
12784
|
+
console.error(` Connection failed: ${msg}`);
|
|
12785
|
+
console.error("");
|
|
12786
|
+
console.error("Hints:");
|
|
12787
|
+
console.error(" - Is PostgreSQL running? (docker ps, pg_isready)");
|
|
12788
|
+
console.error(" - Check host, port, username, password, and database name");
|
|
12789
|
+
console.error(" - Ensure the database exists (createdb myapp_dev)");
|
|
12790
|
+
console.error("");
|
|
12791
|
+
const retry = await ask(rl, "Try a different connection string? (Y/n) ");
|
|
12792
|
+
if (retry.toLowerCase() === "n") {
|
|
12793
|
+
wizardComplete = true;
|
|
12794
|
+
process.exit(1);
|
|
12795
|
+
}
|
|
12796
|
+
console.log("");
|
|
12797
|
+
}
|
|
12798
|
+
}
|
|
12799
|
+
const { schema } = scanResult;
|
|
12800
|
+
console.log(" Connected successfully.");
|
|
12801
|
+
console.log("");
|
|
12802
|
+
if (schema.tables.length === 0) {
|
|
12803
|
+
wizardComplete = true;
|
|
12804
|
+
console.log(" No tables found in the public schema.");
|
|
12805
|
+
console.log("");
|
|
12806
|
+
console.log(" Run your migrations first, then try again:");
|
|
12807
|
+
console.log(" npx prisma migrate dev");
|
|
12808
|
+
console.log(" npx knex migrate:latest");
|
|
12809
|
+
console.log(" rails db:migrate");
|
|
12810
|
+
console.log("");
|
|
12811
|
+
process.exit(1);
|
|
12812
|
+
}
|
|
12813
|
+
console.log("Step 3: Schema");
|
|
12814
|
+
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");
|
|
12815
|
+
console.log(` Found ${schema.tables.length} tables, ${schema.foreignKeys.length} foreign keys`);
|
|
12816
|
+
console.log("");
|
|
12817
|
+
console.log(" Tables:");
|
|
12818
|
+
for (const table of schema.tables) {
|
|
12819
|
+
const colCount = table.columns.length;
|
|
12820
|
+
const pkLabel = table.primaryKey ? ` PK: ${table.primaryKey.columnName}` : "";
|
|
12821
|
+
console.log(` ${table.name} (${colCount} cols${pkLabel})`);
|
|
12822
|
+
}
|
|
12823
|
+
console.log("");
|
|
12824
|
+
console.log("Step 4: Template Selection");
|
|
12825
|
+
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");
|
|
12826
|
+
const registry = getDefaultRegistry();
|
|
12827
|
+
const allTemplates = registry.list();
|
|
12828
|
+
const detected = detectTemplate(schema.tables.map((t) => t.name), allTemplates);
|
|
12829
|
+
let templateName;
|
|
12830
|
+
if (detected) {
|
|
12831
|
+
console.log(` Auto-detected domain: ${detected.name}`);
|
|
12832
|
+
console.log(` ${detected.description}`);
|
|
12833
|
+
console.log("");
|
|
12834
|
+
const useDetected = await ask(rl, ` Use "${detected.name}" template? (Y/n) `);
|
|
12835
|
+
if (useDetected.toLowerCase() !== "n") {
|
|
12836
|
+
templateName = detected.name;
|
|
12837
|
+
}
|
|
12838
|
+
}
|
|
12839
|
+
if (!templateName) {
|
|
12840
|
+
console.log("");
|
|
12841
|
+
console.log(" Available templates:");
|
|
12842
|
+
for (let i = 0; i < allTemplates.length; i++) {
|
|
12843
|
+
console.log(` ${i + 1}. ${allTemplates[i].name} \u2014 ${allTemplates[i].description}`);
|
|
12844
|
+
}
|
|
12845
|
+
console.log(` ${allTemplates.length + 1}. none \u2014 use schema-only generation`);
|
|
12846
|
+
console.log("");
|
|
12847
|
+
const choice = await ask(rl, ` Choose template (1-${allTemplates.length + 1}): `);
|
|
12848
|
+
const choiceNum = parseInt(choice, 10);
|
|
12849
|
+
if (choiceNum >= 1 && choiceNum <= allTemplates.length) {
|
|
12850
|
+
templateName = allTemplates[choiceNum - 1].name;
|
|
12851
|
+
}
|
|
12852
|
+
}
|
|
12853
|
+
console.log("");
|
|
12854
|
+
console.log("Step 5: Configuration");
|
|
12855
|
+
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");
|
|
12856
|
+
const recordsStr = await promptWithDefault(rl, "Records per table", "50");
|
|
12857
|
+
const records = parseInt(recordsStr, 10) || 50;
|
|
12858
|
+
console.log("");
|
|
12859
|
+
console.log("Step 6: Writing Config");
|
|
12860
|
+
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");
|
|
12861
|
+
const config = {
|
|
12862
|
+
database: {
|
|
12863
|
+
client: "postgres",
|
|
12864
|
+
connectionString
|
|
12865
|
+
},
|
|
12866
|
+
seed: {
|
|
12867
|
+
defaultRecords: records,
|
|
12868
|
+
batchSize: 1e3,
|
|
12869
|
+
environment: "dev",
|
|
12870
|
+
randomSeed: 42
|
|
12871
|
+
},
|
|
12872
|
+
...templateName ? { template: templateName } : {}
|
|
12873
|
+
};
|
|
12874
|
+
(0, import_node_fs7.writeFileSync)(CONFIG_FILE, JSON.stringify(config, null, 2) + "\n");
|
|
12875
|
+
console.log(` Created ${CONFIG_FILE}`);
|
|
12876
|
+
console.log("");
|
|
12877
|
+
const runSeed = await ask(rl, "Run initial seed now? (Y/n) ");
|
|
12878
|
+
if (runSeed.toLowerCase() !== "n") {
|
|
12879
|
+
console.log("");
|
|
12880
|
+
console.log("Seeding...");
|
|
12881
|
+
try {
|
|
12882
|
+
const result = await seedDatabase(config, {
|
|
12883
|
+
records,
|
|
12884
|
+
seed: 42,
|
|
12885
|
+
template: templateName
|
|
12886
|
+
});
|
|
12887
|
+
console.log("");
|
|
12888
|
+
for (const tableResult of result.insertResult.tables) {
|
|
12889
|
+
console.log(
|
|
12890
|
+
` ${tableResult.tableName}: ${tableResult.rowsInserted} rows`
|
|
12891
|
+
);
|
|
12892
|
+
}
|
|
12893
|
+
const totalTime = (result.durationMs / 1e3).toFixed(1);
|
|
12894
|
+
console.log("");
|
|
12895
|
+
console.log(` Seed complete. ${result.totalRows} rows in ${totalTime}s`);
|
|
12896
|
+
} catch (err) {
|
|
12897
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
12898
|
+
console.error("");
|
|
12899
|
+
console.error(` Seed failed: ${msg}`);
|
|
12900
|
+
console.error(" You can retry later with: realitydb seed");
|
|
12901
|
+
}
|
|
12902
|
+
}
|
|
12903
|
+
wizardComplete = true;
|
|
12904
|
+
console.log("");
|
|
12905
|
+
console.log("RealityDB initialized!");
|
|
12906
|
+
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");
|
|
12907
|
+
console.log(` Config: ./${CONFIG_FILE}`);
|
|
12908
|
+
console.log(` Database: ${masked}`);
|
|
12909
|
+
if (templateName) {
|
|
12910
|
+
console.log(` Template: ${templateName}`);
|
|
12911
|
+
}
|
|
12912
|
+
console.log(` Records: ${records} per table`);
|
|
12913
|
+
console.log("");
|
|
12914
|
+
console.log("Next steps:");
|
|
12915
|
+
console.log(" realitydb scan Inspect your schema");
|
|
12916
|
+
console.log(" realitydb seed Generate data");
|
|
12917
|
+
console.log(" realitydb export Export without writing to DB");
|
|
12918
|
+
console.log(" realitydb analyze Generate a custom template");
|
|
12919
|
+
console.log(" realitydb --help See all commands");
|
|
12920
|
+
console.log("");
|
|
12921
|
+
} finally {
|
|
12922
|
+
rl.close();
|
|
12923
|
+
}
|
|
12924
|
+
}
|
|
12925
|
+
async function promptWithDefault(rl, label, defaultValue) {
|
|
12926
|
+
console.log(` ${label}`);
|
|
12927
|
+
console.log(` Default: ${defaultValue}`);
|
|
12928
|
+
const answer = await ask(rl, " > ");
|
|
12929
|
+
return answer.trim() || defaultValue;
|
|
12930
|
+
}
|
|
12931
|
+
function detectTemplate(tableNames, templates) {
|
|
12932
|
+
const lower = new Set(tableNames.map((t) => t.toLowerCase()));
|
|
12933
|
+
let bestMatch = null;
|
|
12934
|
+
let bestScore = 0;
|
|
12935
|
+
for (const template of templates) {
|
|
12936
|
+
let matches = 0;
|
|
12937
|
+
for (const target of template.targetTables) {
|
|
12938
|
+
if (lower.has(target.toLowerCase())) {
|
|
12939
|
+
matches++;
|
|
12940
|
+
}
|
|
12941
|
+
}
|
|
12942
|
+
if (matches >= 2 && matches > bestScore) {
|
|
12943
|
+
bestScore = matches;
|
|
12944
|
+
bestMatch = template;
|
|
12945
|
+
}
|
|
12946
|
+
}
|
|
12947
|
+
return bestMatch;
|
|
12948
|
+
}
|
|
12949
|
+
|
|
12950
|
+
// ../../packages/config/dist/loadConfig.js
|
|
12951
|
+
var import_promises9 = require("fs/promises");
|
|
12952
|
+
var import_node_path9 = require("path");
|
|
12953
|
+
|
|
12954
|
+
// ../../packages/config/dist/defaults.js
|
|
12955
|
+
var DEFAULT_CONFIG = {
|
|
12956
|
+
seed: {
|
|
12957
|
+
defaultRecords: 5e3,
|
|
12958
|
+
batchSize: 1e3,
|
|
12959
|
+
environment: "dev"
|
|
12960
|
+
},
|
|
12961
|
+
export: {
|
|
12962
|
+
defaultFormat: "json",
|
|
12963
|
+
outputDir: "./.databox"
|
|
12964
|
+
}
|
|
12965
|
+
};
|
|
12966
|
+
|
|
12967
|
+
// ../../packages/config/dist/loadConfig.js
|
|
12968
|
+
var CONFIG_FILES = ["realitydb.config.json", "seedforge.config.json", "databox.config.json"];
|
|
12969
|
+
async function findConfigFile(basePath) {
|
|
12970
|
+
for (const name of CONFIG_FILES) {
|
|
12971
|
+
const fullPath = (0, import_node_path9.resolve)(basePath, name);
|
|
12972
|
+
try {
|
|
12973
|
+
await (0, import_promises9.access)(fullPath);
|
|
12974
|
+
return fullPath;
|
|
12975
|
+
} catch {
|
|
12976
|
+
continue;
|
|
12977
|
+
}
|
|
12978
|
+
}
|
|
12979
|
+
return null;
|
|
12980
|
+
}
|
|
12981
|
+
async function loadConfig(filePath) {
|
|
12982
|
+
let resolvedPath;
|
|
12983
|
+
if (filePath) {
|
|
12984
|
+
resolvedPath = (0, import_node_path9.resolve)(filePath);
|
|
12985
|
+
} else {
|
|
12986
|
+
const found = await findConfigFile(".");
|
|
12987
|
+
if (!found) {
|
|
12988
|
+
throw new Error(`[realitydb] Config file not found.
|
|
12989
|
+
Create a realitydb.config.json or specify a path with --config.`);
|
|
12990
|
+
}
|
|
12991
|
+
resolvedPath = found;
|
|
12992
|
+
}
|
|
12993
|
+
let raw;
|
|
12994
|
+
try {
|
|
12995
|
+
raw = await (0, import_promises9.readFile)(resolvedPath, "utf-8");
|
|
12996
|
+
} catch {
|
|
12997
|
+
throw new Error(`[realitydb] Config file not found: ${resolvedPath}
|
|
12998
|
+
Create a realitydb.config.json or specify a path with --config.`);
|
|
12999
|
+
}
|
|
13000
|
+
let parsed;
|
|
13001
|
+
try {
|
|
13002
|
+
parsed = JSON.parse(raw);
|
|
13003
|
+
} catch {
|
|
13004
|
+
throw new Error(`[realitydb] Invalid JSON in config file: ${resolvedPath}`);
|
|
13005
|
+
}
|
|
13006
|
+
const config = parsed;
|
|
13007
|
+
const database = config["database"];
|
|
13008
|
+
if (!database || typeof database["connectionString"] !== "string") {
|
|
13009
|
+
throw new Error("[realitydb] Config validation failed: database.connectionString is required.");
|
|
13010
|
+
}
|
|
13011
|
+
return {
|
|
13012
|
+
database: {
|
|
13013
|
+
client: "postgres",
|
|
13014
|
+
connectionString: database["connectionString"]
|
|
13015
|
+
},
|
|
13016
|
+
seed: {
|
|
13017
|
+
...DEFAULT_CONFIG.seed,
|
|
13018
|
+
...config["seed"] ?? {}
|
|
13019
|
+
},
|
|
13020
|
+
template: config["template"],
|
|
13021
|
+
export: {
|
|
13022
|
+
...DEFAULT_CONFIG.export,
|
|
13023
|
+
...config["export"] ?? {}
|
|
13024
|
+
}
|
|
13025
|
+
};
|
|
13026
|
+
}
|
|
13027
|
+
|
|
12767
13028
|
// src/commands/scan.ts
|
|
12768
13029
|
var VERSION2 = "0.10.0";
|
|
12769
13030
|
async function scanCommand(options) {
|
|
@@ -13317,7 +13578,7 @@ async function exportCommand(options) {
|
|
|
13317
13578
|
}
|
|
13318
13579
|
|
|
13319
13580
|
// src/commands/templates.ts
|
|
13320
|
-
var
|
|
13581
|
+
var import_node_fs8 = require("fs");
|
|
13321
13582
|
var VERSION6 = "0.10.0";
|
|
13322
13583
|
function templatesCommand() {
|
|
13323
13584
|
const registry = getDefaultRegistry();
|
|
@@ -13344,7 +13605,7 @@ function templatesCommand() {
|
|
|
13344
13605
|
}
|
|
13345
13606
|
function templatesInitCommand() {
|
|
13346
13607
|
const fileName = "realitydb.template.json";
|
|
13347
|
-
if ((0,
|
|
13608
|
+
if ((0, import_node_fs8.existsSync)(fileName)) {
|
|
13348
13609
|
console.error(`[realitydb] ${fileName} already exists in this directory.`);
|
|
13349
13610
|
process.exit(1);
|
|
13350
13611
|
}
|
|
@@ -13378,7 +13639,7 @@ function templatesInitCommand() {
|
|
|
13378
13639
|
}
|
|
13379
13640
|
}
|
|
13380
13641
|
};
|
|
13381
|
-
(0,
|
|
13642
|
+
(0, import_node_fs8.writeFileSync)(fileName, JSON.stringify(scaffold, null, 2) + "\n");
|
|
13382
13643
|
console.log("");
|
|
13383
13644
|
console.log(`Created ${fileName}`);
|
|
13384
13645
|
console.log("Edit this file to define your custom template.");
|
|
@@ -13389,7 +13650,7 @@ function templatesInitCommand() {
|
|
|
13389
13650
|
}
|
|
13390
13651
|
function templatesValidateCommand(filePath, options) {
|
|
13391
13652
|
const start = performance.now();
|
|
13392
|
-
if (!(0,
|
|
13653
|
+
if (!(0, import_node_fs8.existsSync)(filePath)) {
|
|
13393
13654
|
if (options.ci) {
|
|
13394
13655
|
console.log(formatCIOutput({
|
|
13395
13656
|
success: false,
|
|
@@ -13406,7 +13667,7 @@ function templatesValidateCommand(filePath, options) {
|
|
|
13406
13667
|
}
|
|
13407
13668
|
let json;
|
|
13408
13669
|
try {
|
|
13409
|
-
const raw = (0,
|
|
13670
|
+
const raw = (0, import_node_fs8.readFileSync)(filePath, "utf-8");
|
|
13410
13671
|
json = JSON.parse(raw);
|
|
13411
13672
|
} catch {
|
|
13412
13673
|
if (options.ci) {
|
|
@@ -13469,7 +13730,7 @@ function templatesValidateCommand(filePath, options) {
|
|
|
13469
13730
|
}
|
|
13470
13731
|
|
|
13471
13732
|
// src/commands/scenarios.ts
|
|
13472
|
-
var
|
|
13733
|
+
var import_node_fs9 = require("fs");
|
|
13473
13734
|
var import_node_path12 = require("path");
|
|
13474
13735
|
function scenariosCommand() {
|
|
13475
13736
|
const registry = getDefaultScenarioRegistry();
|
|
@@ -13494,12 +13755,12 @@ function scenariosCreateCommand(name) {
|
|
|
13494
13755
|
const sanitized = name.trim().toLowerCase().replace(/[^a-z0-9-]/g, "-");
|
|
13495
13756
|
const fileName = `${sanitized}.scenario.json`;
|
|
13496
13757
|
const filePath = (0, import_node_path12.resolve)(fileName);
|
|
13497
|
-
if ((0,
|
|
13758
|
+
if ((0, import_node_fs9.existsSync)(filePath)) {
|
|
13498
13759
|
console.error(`[realitydb] File already exists: ${fileName}`);
|
|
13499
13760
|
process.exit(1);
|
|
13500
13761
|
}
|
|
13501
13762
|
const scaffold = scaffoldCustomScenario(sanitized);
|
|
13502
|
-
(0,
|
|
13763
|
+
(0, import_node_fs9.writeFileSync)(filePath, JSON.stringify(scaffold, null, 2) + "\n", "utf-8");
|
|
13503
13764
|
console.log("");
|
|
13504
13765
|
console.log(`Created custom scenario: ${fileName}`);
|
|
13505
13766
|
console.log("");
|
|
@@ -14254,7 +14515,7 @@ function getDefaultSchema() {
|
|
|
14254
14515
|
}
|
|
14255
14516
|
|
|
14256
14517
|
// src/commands/analyze.ts
|
|
14257
|
-
var
|
|
14518
|
+
var import_node_fs10 = require("fs");
|
|
14258
14519
|
var import_node_path16 = require("path");
|
|
14259
14520
|
var VERSION12 = "1.3.1";
|
|
14260
14521
|
async function analyzeCommand(options) {
|
|
@@ -14296,14 +14557,14 @@ async function analyzeCommand(options) {
|
|
|
14296
14557
|
}));
|
|
14297
14558
|
if (result.templateJson && options.output) {
|
|
14298
14559
|
const filePath = (0, import_node_path16.resolve)(options.output);
|
|
14299
|
-
(0,
|
|
14560
|
+
(0, import_node_fs10.writeFileSync)(filePath, result.templateJson + "\n", "utf-8");
|
|
14300
14561
|
}
|
|
14301
14562
|
return;
|
|
14302
14563
|
}
|
|
14303
14564
|
console.log(formatAnalysisReport(result.report));
|
|
14304
14565
|
if (result.templateJson && options.output) {
|
|
14305
14566
|
const filePath = (0, import_node_path16.resolve)(options.output);
|
|
14306
|
-
(0,
|
|
14567
|
+
(0, import_node_fs10.writeFileSync)(filePath, result.templateJson + "\n", "utf-8");
|
|
14307
14568
|
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
14569
|
console.log(`Template generated: ${filePath}`);
|
|
14309
14570
|
console.log("");
|
|
@@ -14348,7 +14609,7 @@ async function analyzeCommand(options) {
|
|
|
14348
14609
|
}
|
|
14349
14610
|
|
|
14350
14611
|
// src/commands/mask.ts
|
|
14351
|
-
var
|
|
14612
|
+
var import_node_fs11 = require("fs");
|
|
14352
14613
|
var import_node_path17 = require("path");
|
|
14353
14614
|
var VERSION13 = "1.3.1";
|
|
14354
14615
|
async function maskCommand(options) {
|
|
@@ -14426,7 +14687,7 @@ async function maskCommand(options) {
|
|
|
14426
14687
|
const durationMs = Math.round(performance.now() - start);
|
|
14427
14688
|
if (options.auditLog) {
|
|
14428
14689
|
const auditPath = (0, import_node_path17.resolve)(options.auditLog);
|
|
14429
|
-
(0,
|
|
14690
|
+
(0, import_node_fs11.writeFileSync)(auditPath, serializeAuditLog(result.auditLog) + "\n", "utf-8");
|
|
14430
14691
|
}
|
|
14431
14692
|
if (options.ci) {
|
|
14432
14693
|
console.log(formatCIOutput({
|
|
@@ -14501,7 +14762,7 @@ async function maskCommand(options) {
|
|
|
14501
14762
|
}
|
|
14502
14763
|
|
|
14503
14764
|
// src/commands/classroom.ts
|
|
14504
|
-
var
|
|
14765
|
+
var import_node_fs12 = require("fs");
|
|
14505
14766
|
var import_node_path18 = require("path");
|
|
14506
14767
|
var VERSION14 = "1.3.1";
|
|
14507
14768
|
async function classroomListCommand(options) {
|
|
@@ -14766,7 +15027,7 @@ async function classroomCreateCommand(name, options) {
|
|
|
14766
15027
|
const content = classroomCreate(name);
|
|
14767
15028
|
const filename = `${name}.course.json`;
|
|
14768
15029
|
const filePath = (0, import_node_path18.resolve)(filename);
|
|
14769
|
-
(0,
|
|
15030
|
+
(0, import_node_fs12.writeFileSync)(filePath, content + "\n", "utf-8");
|
|
14770
15031
|
const durationMs = Math.round(performance.now() - start);
|
|
14771
15032
|
if (options.ci) {
|
|
14772
15033
|
console.log(formatCIOutput({
|
|
@@ -15016,10 +15277,13 @@ async function simulateWebhooksCommand(options) {
|
|
|
15016
15277
|
}
|
|
15017
15278
|
|
|
15018
15279
|
// src/cli.ts
|
|
15019
|
-
var VERSION16 = "1.
|
|
15280
|
+
var VERSION16 = "1.5.1";
|
|
15020
15281
|
function run(argv) {
|
|
15021
15282
|
const program2 = new Command();
|
|
15022
15283
|
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);
|
|
15284
|
+
program2.command("init").description("Interactive setup wizard \u2014 connect, scan, and seed in one step").action(async () => {
|
|
15285
|
+
await initCommand();
|
|
15286
|
+
});
|
|
15023
15287
|
program2.command("scan").description("Scan database schema").action(async () => {
|
|
15024
15288
|
const opts = program2.opts();
|
|
15025
15289
|
await scanCommand({ ci: opts.ci, configPath: opts.config });
|
package/package.json
CHANGED