@reporting-bi/cli 0.0.16 → 0.0.18
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 +174 -113
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -9803,9 +9803,9 @@ function saveCredentials(data) {
|
|
|
9803
9803
|
function findLocalConfig(startDir) {
|
|
9804
9804
|
let dir = path.resolve(startDir || process.cwd());
|
|
9805
9805
|
while (true) {
|
|
9806
|
-
const
|
|
9806
|
+
const configPath = path.join(dir, ".rpbi", "config.json");
|
|
9807
9807
|
try {
|
|
9808
|
-
const data = JSON.parse(fs.readFileSync(
|
|
9808
|
+
const data = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
9809
9809
|
if (data.domain) return { domain: data.domain, accounting: data.accounting };
|
|
9810
9810
|
} catch {
|
|
9811
9811
|
}
|
|
@@ -10197,7 +10197,7 @@ function status() {
|
|
|
10197
10197
|
const local = findLocalConfig();
|
|
10198
10198
|
const domains = Object.keys(creds.connections);
|
|
10199
10199
|
if (local) {
|
|
10200
|
-
console.log(`Local config (.rpbi/
|
|
10200
|
+
console.log(`Local config (.rpbi/config.json):`);
|
|
10201
10201
|
console.log(` domain: ${local.domain}`);
|
|
10202
10202
|
console.log(` accounting: ${local.accounting ?? "not set"}`);
|
|
10203
10203
|
console.log();
|
|
@@ -10379,41 +10379,124 @@ var fs3 = __toESM(require("node:fs"));
|
|
|
10379
10379
|
var path2 = __toESM(require("node:path"));
|
|
10380
10380
|
var crypto = __toESM(require("node:crypto"));
|
|
10381
10381
|
var RPBI_DIR = ".rpbi";
|
|
10382
|
-
var
|
|
10382
|
+
var CONFIG_FILE = "config.json";
|
|
10383
|
+
var INDEX_FILE = "index.json";
|
|
10383
10384
|
function computeHash(content2) {
|
|
10384
10385
|
return crypto.createHash("sha256").update(content2, "utf-8").digest("hex");
|
|
10385
10386
|
}
|
|
10386
|
-
function
|
|
10387
|
-
return path2.join(dir, RPBI_DIR,
|
|
10387
|
+
function getConfigPath(dir) {
|
|
10388
|
+
return path2.join(dir, RPBI_DIR, CONFIG_FILE);
|
|
10388
10389
|
}
|
|
10389
|
-
function
|
|
10390
|
-
|
|
10390
|
+
function getIndexPath(dir) {
|
|
10391
|
+
return path2.join(dir, RPBI_DIR, INDEX_FILE);
|
|
10392
|
+
}
|
|
10393
|
+
function readConfig(dir) {
|
|
10391
10394
|
try {
|
|
10392
|
-
const data = fs3.readFileSync(
|
|
10395
|
+
const data = fs3.readFileSync(getConfigPath(dir), "utf-8");
|
|
10393
10396
|
return JSON.parse(data);
|
|
10394
10397
|
} catch {
|
|
10395
10398
|
return null;
|
|
10396
10399
|
}
|
|
10397
10400
|
}
|
|
10398
|
-
function
|
|
10401
|
+
function writeConfig(dir, config2) {
|
|
10399
10402
|
const rpbiDir = path2.join(dir, RPBI_DIR);
|
|
10400
10403
|
fs3.mkdirSync(rpbiDir, { recursive: true });
|
|
10401
10404
|
fs3.writeFileSync(
|
|
10402
|
-
path2.join(rpbiDir,
|
|
10403
|
-
JSON.stringify(
|
|
10405
|
+
path2.join(rpbiDir, CONFIG_FILE),
|
|
10406
|
+
JSON.stringify(config2, null, 2)
|
|
10407
|
+
);
|
|
10408
|
+
}
|
|
10409
|
+
function readIndex(dir) {
|
|
10410
|
+
try {
|
|
10411
|
+
const data = fs3.readFileSync(getIndexPath(dir), "utf-8");
|
|
10412
|
+
return JSON.parse(data);
|
|
10413
|
+
} catch {
|
|
10414
|
+
return [];
|
|
10415
|
+
}
|
|
10416
|
+
}
|
|
10417
|
+
function writeIndex(dir, index) {
|
|
10418
|
+
const rpbiDir = path2.join(dir, RPBI_DIR);
|
|
10419
|
+
fs3.mkdirSync(rpbiDir, { recursive: true });
|
|
10420
|
+
fs3.writeFileSync(
|
|
10421
|
+
path2.join(rpbiDir, INDEX_FILE),
|
|
10422
|
+
JSON.stringify(index, null, 2)
|
|
10404
10423
|
);
|
|
10405
10424
|
}
|
|
10406
10425
|
function findEtlRoot(startDir) {
|
|
10407
10426
|
let dir = path2.resolve(startDir);
|
|
10408
10427
|
while (true) {
|
|
10409
|
-
if (fs3.existsSync(
|
|
10428
|
+
if (fs3.existsSync(getConfigPath(dir))) return dir;
|
|
10410
10429
|
const parent = path2.dirname(dir);
|
|
10411
10430
|
if (parent === dir) return null;
|
|
10412
10431
|
dir = parent;
|
|
10413
10432
|
}
|
|
10414
10433
|
}
|
|
10415
10434
|
|
|
10435
|
+
// src/yaml.ts
|
|
10436
|
+
function toYaml(data, indent = 0) {
|
|
10437
|
+
if (data === null || data === void 0) return "null";
|
|
10438
|
+
if (typeof data === "boolean") return data ? "true" : "false";
|
|
10439
|
+
if (typeof data === "number") return String(data);
|
|
10440
|
+
if (typeof data === "string") {
|
|
10441
|
+
if (data.includes("\n")) {
|
|
10442
|
+
const prefix = " ".repeat(indent);
|
|
10443
|
+
const lines = data.split("\n").map((l) => prefix + " " + l).join("\n");
|
|
10444
|
+
return "|\n" + lines;
|
|
10445
|
+
}
|
|
10446
|
+
if (data === "" || /[:{}\[\],&*?|>!'"%@`#]/.test(data) || /^\s|\s$/.test(data)) {
|
|
10447
|
+
return JSON.stringify(data);
|
|
10448
|
+
}
|
|
10449
|
+
return data;
|
|
10450
|
+
}
|
|
10451
|
+
if (Array.isArray(data)) {
|
|
10452
|
+
if (data.length === 0) return "[]";
|
|
10453
|
+
const prefix = " ".repeat(indent);
|
|
10454
|
+
return data.map((item) => {
|
|
10455
|
+
if (typeof item === "object" && item !== null && !Array.isArray(item)) {
|
|
10456
|
+
const entries = Object.entries(item);
|
|
10457
|
+
if (entries.length === 0) return `${prefix}- {}`;
|
|
10458
|
+
const [firstKey, firstVal] = entries[0];
|
|
10459
|
+
const firstLine = `${prefix}- ${firstKey}: ${toYaml(firstVal, indent + 2)}`;
|
|
10460
|
+
const rest = entries.slice(1).map(
|
|
10461
|
+
([k, v]) => `${prefix} ${k}: ${toYaml(v, indent + 2)}`
|
|
10462
|
+
);
|
|
10463
|
+
return [firstLine, ...rest].join("\n");
|
|
10464
|
+
}
|
|
10465
|
+
return `${prefix}- ${toYaml(item, indent + 2)}`;
|
|
10466
|
+
}).join("\n");
|
|
10467
|
+
}
|
|
10468
|
+
if (typeof data === "object") {
|
|
10469
|
+
const entries = Object.entries(data);
|
|
10470
|
+
if (entries.length === 0) return "{}";
|
|
10471
|
+
const prefix = " ".repeat(indent);
|
|
10472
|
+
return entries.map(
|
|
10473
|
+
([k, v]) => `${prefix}${k}: ${toYaml(v, indent)}`
|
|
10474
|
+
).join("\n");
|
|
10475
|
+
}
|
|
10476
|
+
return String(data);
|
|
10477
|
+
}
|
|
10478
|
+
|
|
10416
10479
|
// src/commands/etl-sync.ts
|
|
10480
|
+
var TYPE_DIR_NAMES = {
|
|
10481
|
+
"IA": "threads_import",
|
|
10482
|
+
"IM": "threads_import_manual",
|
|
10483
|
+
"O": "threads_export",
|
|
10484
|
+
"A": "agent_parameters",
|
|
10485
|
+
"AC": "agent_config",
|
|
10486
|
+
"EC": "excel_config",
|
|
10487
|
+
"D": "threads_delete",
|
|
10488
|
+
"L": "lists",
|
|
10489
|
+
"S": "scripts"
|
|
10490
|
+
};
|
|
10491
|
+
var DIR_NAME_TYPES = Object.fromEntries(
|
|
10492
|
+
Object.entries(TYPE_DIR_NAMES).map(([k, v]) => [v, k])
|
|
10493
|
+
);
|
|
10494
|
+
function typeToDirName(type) {
|
|
10495
|
+
return TYPE_DIR_NAMES[type] || "unknown";
|
|
10496
|
+
}
|
|
10497
|
+
function dirNameToType(dirName) {
|
|
10498
|
+
return DIR_NAME_TYPES[dirName] || null;
|
|
10499
|
+
}
|
|
10417
10500
|
var PARAMETER_TYPES = ["IA", "IM", "O", "D"];
|
|
10418
10501
|
var PARAMETER_EXCLUDE_FIELDS = ["accounting", "id_thread", "idz", "validate_flag", "date_created"];
|
|
10419
10502
|
var THREAD_EXCLUDE_FIELDS = ["command_txt", "command_preview", "accounting", "id_thread", "type", "idz", "validate_flag", "date_created"];
|
|
@@ -10466,15 +10549,15 @@ function getFilePath(description, extension = ".sql") {
|
|
|
10466
10549
|
}
|
|
10467
10550
|
function threadToRelPath(thread) {
|
|
10468
10551
|
const segments = getFilePath(thread.description || "");
|
|
10469
|
-
return [thread.type, ...segments].join("/");
|
|
10552
|
+
return [typeToDirName(thread.type), ...segments].join("/");
|
|
10470
10553
|
}
|
|
10471
10554
|
function threadToParamPath(thread) {
|
|
10472
10555
|
const segments = getFilePath(thread.description || "", ".yaml");
|
|
10473
|
-
return [".parameters", thread.type, ...segments].join("/");
|
|
10556
|
+
return [".rpbi", "parameters", typeToDirName(thread.type), ...segments].join("/");
|
|
10474
10557
|
}
|
|
10475
10558
|
function threadToMetaPath(thread) {
|
|
10476
10559
|
const segments = getFilePath(thread.description || "", ".yaml");
|
|
10477
|
-
return [".threads", thread.type, ...segments].join("/");
|
|
10560
|
+
return [".rpbi", "threads", typeToDirName(thread.type), ...segments].join("/");
|
|
10478
10561
|
}
|
|
10479
10562
|
function writeFileSync4(filePath, content2) {
|
|
10480
10563
|
fs4.mkdirSync(path3.dirname(filePath), { recursive: true });
|
|
@@ -10489,48 +10572,6 @@ function stripFields(obj, excludeFields) {
|
|
|
10489
10572
|
}
|
|
10490
10573
|
return result;
|
|
10491
10574
|
}
|
|
10492
|
-
function toYaml(data, indent = 0) {
|
|
10493
|
-
if (data === null || data === void 0) return "null";
|
|
10494
|
-
if (typeof data === "boolean") return data ? "true" : "false";
|
|
10495
|
-
if (typeof data === "number") return String(data);
|
|
10496
|
-
if (typeof data === "string") {
|
|
10497
|
-
if (data.includes("\n")) {
|
|
10498
|
-
const prefix = " ".repeat(indent);
|
|
10499
|
-
const lines = data.split("\n").map((l) => prefix + " " + l).join("\n");
|
|
10500
|
-
return "|\n" + lines;
|
|
10501
|
-
}
|
|
10502
|
-
if (data === "" || /[:{}\[\],&*?|>!'"%@`#]/.test(data) || /^\s|\s$/.test(data)) {
|
|
10503
|
-
return JSON.stringify(data);
|
|
10504
|
-
}
|
|
10505
|
-
return data;
|
|
10506
|
-
}
|
|
10507
|
-
if (Array.isArray(data)) {
|
|
10508
|
-
if (data.length === 0) return "[]";
|
|
10509
|
-
const prefix = " ".repeat(indent);
|
|
10510
|
-
return data.map((item) => {
|
|
10511
|
-
if (typeof item === "object" && item !== null && !Array.isArray(item)) {
|
|
10512
|
-
const entries = Object.entries(item);
|
|
10513
|
-
if (entries.length === 0) return `${prefix}- {}`;
|
|
10514
|
-
const [firstKey, firstVal] = entries[0];
|
|
10515
|
-
const firstLine = `${prefix}- ${firstKey}: ${toYaml(firstVal, indent + 2)}`;
|
|
10516
|
-
const rest = entries.slice(1).map(
|
|
10517
|
-
([k, v]) => `${prefix} ${k}: ${toYaml(v, indent + 2)}`
|
|
10518
|
-
);
|
|
10519
|
-
return [firstLine, ...rest].join("\n");
|
|
10520
|
-
}
|
|
10521
|
-
return `${prefix}- ${toYaml(item, indent + 2)}`;
|
|
10522
|
-
}).join("\n");
|
|
10523
|
-
}
|
|
10524
|
-
if (typeof data === "object") {
|
|
10525
|
-
const entries = Object.entries(data);
|
|
10526
|
-
if (entries.length === 0) return "{}";
|
|
10527
|
-
const prefix = " ".repeat(indent);
|
|
10528
|
-
return entries.map(
|
|
10529
|
-
([k, v]) => `${prefix}${k}: ${toYaml(v, indent)}`
|
|
10530
|
-
).join("\n");
|
|
10531
|
-
}
|
|
10532
|
-
return String(data);
|
|
10533
|
-
}
|
|
10534
10575
|
async function pull(flags) {
|
|
10535
10576
|
const dir = path3.resolve(flags.dir || ".");
|
|
10536
10577
|
const conn = getActiveConnection();
|
|
@@ -10546,12 +10587,7 @@ async function pull(flags) {
|
|
|
10546
10587
|
order: [["type", "asc"], ["description", "asc"]]
|
|
10547
10588
|
}) || [];
|
|
10548
10589
|
console.log(`Found ${threads.length} threads`);
|
|
10549
|
-
const
|
|
10550
|
-
domain: conn.domain,
|
|
10551
|
-
accounting: conn.tokens.accounting,
|
|
10552
|
-
pulledAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
10553
|
-
threads: {}
|
|
10554
|
-
};
|
|
10590
|
+
const index = [];
|
|
10555
10591
|
let pulled = 0;
|
|
10556
10592
|
for (const thread of threads) {
|
|
10557
10593
|
if (!thread.id_thread || !thread.type || !thread.description) continue;
|
|
@@ -10564,11 +10600,12 @@ async function pull(flags) {
|
|
|
10564
10600
|
{ parseResponse: false }
|
|
10565
10601
|
) || "";
|
|
10566
10602
|
writeFileSync4(absPath, content2);
|
|
10567
|
-
|
|
10603
|
+
index.push({
|
|
10604
|
+
path: relPath,
|
|
10568
10605
|
id_thread: thread.id_thread,
|
|
10569
10606
|
hash: computeHash(content2),
|
|
10570
10607
|
type: thread.type
|
|
10571
|
-
};
|
|
10608
|
+
});
|
|
10572
10609
|
pulled++;
|
|
10573
10610
|
if (pulled % 50 === 0) console.log(` ${pulled}/${threads.length} threads...`);
|
|
10574
10611
|
} catch (err) {
|
|
@@ -10608,24 +10645,30 @@ async function pull(flags) {
|
|
|
10608
10645
|
if (!flags["no-context"]) {
|
|
10609
10646
|
await pullContext(dir, etlService, defService);
|
|
10610
10647
|
}
|
|
10611
|
-
|
|
10648
|
+
writeConfig(dir, {
|
|
10649
|
+
domain: conn.domain,
|
|
10650
|
+
accounting: conn.tokens.accounting,
|
|
10651
|
+
pulledAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
10652
|
+
});
|
|
10653
|
+
writeIndex(dir, index);
|
|
10612
10654
|
console.log(`Done. Pulled ${pulled} threads to ${dir}`);
|
|
10613
10655
|
}
|
|
10614
10656
|
async function push(flags, files) {
|
|
10615
10657
|
const startDir = flags.dir || ".";
|
|
10616
10658
|
const root = findEtlRoot(startDir);
|
|
10617
10659
|
if (!root) {
|
|
10618
|
-
console.error('No .rpbi/
|
|
10660
|
+
console.error('No .rpbi/config.json found. Run "rpbi etl pull" first.');
|
|
10619
10661
|
process.exit(1);
|
|
10620
10662
|
}
|
|
10621
|
-
const
|
|
10663
|
+
const index = readIndex(root);
|
|
10664
|
+
const indexMap = new Map(index.map((e) => [e.path, e]));
|
|
10622
10665
|
const etlService = await createService("etl");
|
|
10623
10666
|
const force = flags.force === "true";
|
|
10624
10667
|
let filesToPush;
|
|
10625
10668
|
if (files.length > 0) {
|
|
10626
10669
|
filesToPush = files.map((f) => path3.relative(root, path3.resolve(f)));
|
|
10627
10670
|
} else {
|
|
10628
|
-
filesToPush = detectModifiedFiles(root,
|
|
10671
|
+
filesToPush = detectModifiedFiles(root, index);
|
|
10629
10672
|
}
|
|
10630
10673
|
if (filesToPush.length === 0) {
|
|
10631
10674
|
console.log("Nothing to push.");
|
|
@@ -10639,7 +10682,7 @@ async function push(flags, files) {
|
|
|
10639
10682
|
continue;
|
|
10640
10683
|
}
|
|
10641
10684
|
const localContent = fs4.readFileSync(absPath, "utf-8");
|
|
10642
|
-
const entry =
|
|
10685
|
+
const entry = indexMap.get(relPath);
|
|
10643
10686
|
if (entry) {
|
|
10644
10687
|
if (!force) {
|
|
10645
10688
|
try {
|
|
@@ -10657,11 +10700,16 @@ async function push(flags, files) {
|
|
|
10657
10700
|
}
|
|
10658
10701
|
}
|
|
10659
10702
|
await etlService.post(`threadContent/${entry.id_thread}`, localContent);
|
|
10660
|
-
|
|
10703
|
+
entry.hash = computeHash(localContent);
|
|
10661
10704
|
console.log(` Updated: ${relPath}`);
|
|
10662
10705
|
} else {
|
|
10663
10706
|
const parts = relPath.split("/");
|
|
10664
|
-
const
|
|
10707
|
+
const dirName = parts[0];
|
|
10708
|
+
const type = dirNameToType(dirName);
|
|
10709
|
+
if (!type) {
|
|
10710
|
+
console.error(` Unknown thread type directory: ${dirName}`);
|
|
10711
|
+
continue;
|
|
10712
|
+
}
|
|
10665
10713
|
const description = parts.slice(1).join("/").replace(/\.sql$/, "");
|
|
10666
10714
|
const newThread = await etlService.post("threads", {
|
|
10667
10715
|
type,
|
|
@@ -10670,22 +10718,23 @@ async function push(flags, files) {
|
|
|
10670
10718
|
});
|
|
10671
10719
|
if (newThread?.id_thread) {
|
|
10672
10720
|
await etlService.post(`threadContent/${newThread.id_thread}`, localContent);
|
|
10673
|
-
|
|
10721
|
+
index.push({
|
|
10722
|
+
path: relPath,
|
|
10674
10723
|
id_thread: newThread.id_thread,
|
|
10675
10724
|
hash: computeHash(localContent),
|
|
10676
10725
|
type
|
|
10677
|
-
};
|
|
10726
|
+
});
|
|
10678
10727
|
console.log(` Created: ${relPath} (thread #${newThread.id_thread})`);
|
|
10679
10728
|
} else {
|
|
10680
10729
|
console.error(` Failed to create thread for ${relPath}`);
|
|
10681
10730
|
}
|
|
10682
10731
|
}
|
|
10683
10732
|
}
|
|
10684
|
-
|
|
10733
|
+
writeIndex(path3.resolve(root), index);
|
|
10685
10734
|
console.log("Push complete.");
|
|
10686
10735
|
}
|
|
10687
10736
|
async function pullContext(dir, etlService, defService) {
|
|
10688
|
-
const contextDir = path3.join(dir, ".context");
|
|
10737
|
+
const contextDir = path3.join(dir, ".rpbi", "context");
|
|
10689
10738
|
console.log("Pulling context (schema & modules)...");
|
|
10690
10739
|
try {
|
|
10691
10740
|
const modules2 = await defService.get("accountingModules");
|
|
@@ -10722,39 +10771,40 @@ async function context(flags) {
|
|
|
10722
10771
|
await pullContext(dir, etlService, defService);
|
|
10723
10772
|
console.log("Context pull complete.");
|
|
10724
10773
|
}
|
|
10725
|
-
function detectModifiedFiles(root,
|
|
10774
|
+
function detectModifiedFiles(root, index) {
|
|
10726
10775
|
const modified = [];
|
|
10727
|
-
for (const
|
|
10728
|
-
const absPath = path3.join(root,
|
|
10776
|
+
for (const entry of index) {
|
|
10777
|
+
const absPath = path3.join(root, entry.path);
|
|
10729
10778
|
if (!fs4.existsSync(absPath)) {
|
|
10730
|
-
modified.push(
|
|
10779
|
+
modified.push(entry.path);
|
|
10731
10780
|
continue;
|
|
10732
10781
|
}
|
|
10733
10782
|
const content2 = fs4.readFileSync(absPath, "utf-8");
|
|
10734
10783
|
if (computeHash(content2) !== entry.hash) {
|
|
10735
|
-
modified.push(
|
|
10784
|
+
modified.push(entry.path);
|
|
10736
10785
|
}
|
|
10737
10786
|
}
|
|
10738
10787
|
return modified;
|
|
10739
10788
|
}
|
|
10740
|
-
function detectNewFiles(root,
|
|
10789
|
+
function detectNewFiles(root, index) {
|
|
10741
10790
|
const newFiles = [];
|
|
10791
|
+
const knownPaths = new Set(index.map((e) => e.path));
|
|
10742
10792
|
const entries = fs4.readdirSync(root, { withFileTypes: true });
|
|
10743
10793
|
for (const entry of entries) {
|
|
10744
10794
|
if (!entry.isDirectory() || entry.name.startsWith(".")) continue;
|
|
10745
|
-
walkDir(path3.join(root, entry.name), root,
|
|
10795
|
+
walkDir(path3.join(root, entry.name), root, knownPaths, newFiles);
|
|
10746
10796
|
}
|
|
10747
10797
|
return newFiles;
|
|
10748
10798
|
}
|
|
10749
|
-
function walkDir(dir, root,
|
|
10799
|
+
function walkDir(dir, root, knownPaths, result) {
|
|
10750
10800
|
const entries = fs4.readdirSync(dir, { withFileTypes: true });
|
|
10751
10801
|
for (const entry of entries) {
|
|
10752
10802
|
const full = path3.join(dir, entry.name);
|
|
10753
10803
|
if (entry.isDirectory()) {
|
|
10754
|
-
walkDir(full, root,
|
|
10804
|
+
walkDir(full, root, knownPaths, result);
|
|
10755
10805
|
} else if (entry.name.endsWith(".sql")) {
|
|
10756
10806
|
const rel = path3.relative(root, full);
|
|
10757
|
-
if (!
|
|
10807
|
+
if (!knownPaths.has(rel)) {
|
|
10758
10808
|
result.push(rel);
|
|
10759
10809
|
}
|
|
10760
10810
|
}
|
|
@@ -10764,16 +10814,17 @@ async function status2(flags) {
|
|
|
10764
10814
|
const startDir = flags.dir || ".";
|
|
10765
10815
|
const root = findEtlRoot(startDir);
|
|
10766
10816
|
if (!root) {
|
|
10767
|
-
console.error('No .rpbi/
|
|
10817
|
+
console.error('No .rpbi/config.json found. Run "rpbi etl pull" first.');
|
|
10768
10818
|
process.exit(1);
|
|
10769
10819
|
}
|
|
10770
|
-
const
|
|
10820
|
+
const config2 = readConfig(root);
|
|
10821
|
+
const index = readIndex(root);
|
|
10771
10822
|
console.log(`ETL workspace: ${root}`);
|
|
10772
|
-
console.log(`Domain: ${
|
|
10773
|
-
console.log(`Pulled at: ${
|
|
10823
|
+
console.log(`Domain: ${config2?.domain} | Accounting: ${config2?.accounting}`);
|
|
10824
|
+
console.log(`Pulled at: ${config2?.pulledAt}`);
|
|
10774
10825
|
console.log("");
|
|
10775
|
-
const modified = detectModifiedFiles(root,
|
|
10776
|
-
const newFiles = detectNewFiles(root,
|
|
10826
|
+
const modified = detectModifiedFiles(root, index);
|
|
10827
|
+
const newFiles = detectNewFiles(root, index);
|
|
10777
10828
|
const deleted = modified.filter((f) => !fs4.existsSync(path3.join(root, f)));
|
|
10778
10829
|
const changed = modified.filter((f) => fs4.existsSync(path3.join(root, f)));
|
|
10779
10830
|
if (changed.length === 0 && newFiles.length === 0 && deleted.length === 0) {
|
|
@@ -34395,7 +34446,7 @@ function text(data) {
|
|
|
34395
34446
|
async function mcp() {
|
|
34396
34447
|
const server = new McpServer({
|
|
34397
34448
|
name: "reporting-bi",
|
|
34398
|
-
version: "0.0.
|
|
34449
|
+
version: "0.0.18"
|
|
34399
34450
|
});
|
|
34400
34451
|
server.tool(
|
|
34401
34452
|
"status",
|
|
@@ -34845,17 +34896,16 @@ function init(args) {
|
|
|
34845
34896
|
console.error(`Not logged in to "${domain2}". Run "rpbi login ${domain2}" first.`);
|
|
34846
34897
|
process.exit(1);
|
|
34847
34898
|
}
|
|
34848
|
-
const existing =
|
|
34849
|
-
const
|
|
34899
|
+
const existing = readConfig(process.cwd());
|
|
34900
|
+
const config2 = {
|
|
34850
34901
|
domain: domain2,
|
|
34851
34902
|
accounting: flags.accounting ? parseInt(flags.accounting) : existing?.accounting ?? creds.connections[domain2].accounting ?? 0,
|
|
34852
|
-
...existing?.pulledAt && { pulledAt: existing.pulledAt }
|
|
34853
|
-
...existing?.threads && { threads: existing.threads }
|
|
34903
|
+
...existing?.pulledAt && { pulledAt: existing.pulledAt }
|
|
34854
34904
|
};
|
|
34855
|
-
|
|
34856
|
-
console.log(`Initialized .rpbi/
|
|
34857
|
-
console.log(` domain: ${
|
|
34858
|
-
console.log(` accounting: ${
|
|
34905
|
+
writeConfig(process.cwd(), config2);
|
|
34906
|
+
console.log(`Initialized .rpbi/config.json`);
|
|
34907
|
+
console.log(` domain: ${config2.domain}`);
|
|
34908
|
+
console.log(` accounting: ${config2.accounting || "not set"}`);
|
|
34859
34909
|
}
|
|
34860
34910
|
|
|
34861
34911
|
// src/autoupdate.ts
|
|
@@ -34870,11 +34920,14 @@ var CHECK_INTERVAL = 60 * 60 * 1e3;
|
|
|
34870
34920
|
var PACKAGE_NAME = "@reporting-bi/cli";
|
|
34871
34921
|
var INSTALL_PREFIX = detectPrefix();
|
|
34872
34922
|
function detectPrefix() {
|
|
34873
|
-
|
|
34874
|
-
|
|
34875
|
-
|
|
34876
|
-
|
|
34877
|
-
|
|
34923
|
+
try {
|
|
34924
|
+
const realPath = fs6.realpathSync(process.argv[1]);
|
|
34925
|
+
const libIndex = realPath.indexOf(path4.join("lib", "node_modules"));
|
|
34926
|
+
if (libIndex > 0) {
|
|
34927
|
+
const prefix = realPath.slice(0, libIndex - 1);
|
|
34928
|
+
if (prefix !== "/usr" && prefix !== "/usr/local") return prefix;
|
|
34929
|
+
}
|
|
34930
|
+
} catch {
|
|
34878
34931
|
}
|
|
34879
34932
|
return null;
|
|
34880
34933
|
}
|
|
@@ -34937,8 +34990,8 @@ async function checkForUpdate() {
|
|
|
34937
34990
|
saveUpdateCheck({ lastCheck: now });
|
|
34938
34991
|
const latest = await fetchLatestVersion();
|
|
34939
34992
|
if (!latest) return;
|
|
34940
|
-
if (!isNewer(latest, "0.0.
|
|
34941
|
-
console.log(`\x1B[33mUpdating ${PACKAGE_NAME} ${"0.0.
|
|
34993
|
+
if (!isNewer(latest, "0.0.18")) return;
|
|
34994
|
+
console.log(`\x1B[33mUpdating ${PACKAGE_NAME} ${"0.0.18"} \u2192 ${latest}...\x1B[0m`);
|
|
34942
34995
|
(0, import_node_child_process2.execSync)(npmInstallCmd(latest), { stdio: "inherit" });
|
|
34943
34996
|
console.log(`\x1B[32mUpdated to ${latest}.\x1B[0m`);
|
|
34944
34997
|
} catch {
|
|
@@ -34950,11 +35003,11 @@ async function forceUpdate() {
|
|
|
34950
35003
|
console.error("Could not fetch latest version from npm.");
|
|
34951
35004
|
process.exit(1);
|
|
34952
35005
|
}
|
|
34953
|
-
if (!isNewer(latest, "0.0.
|
|
34954
|
-
console.log(`Already up to date (${"0.0.
|
|
35006
|
+
if (!isNewer(latest, "0.0.18")) {
|
|
35007
|
+
console.log(`Already up to date (${"0.0.18"}).`);
|
|
34955
35008
|
return;
|
|
34956
35009
|
}
|
|
34957
|
-
console.log(`Updating ${PACKAGE_NAME} ${"0.0.
|
|
35010
|
+
console.log(`Updating ${PACKAGE_NAME} ${"0.0.18"} \u2192 ${latest}...`);
|
|
34958
35011
|
(0, import_node_child_process2.execSync)(npmInstallCmd(latest), { stdio: "inherit" });
|
|
34959
35012
|
console.log(`\x1B[32mUpdated to ${latest}.\x1B[0m`);
|
|
34960
35013
|
saveUpdateCheck({ lastCheck: Date.now() });
|
|
@@ -34983,6 +35036,10 @@ ETL:
|
|
|
34983
35036
|
etl content <id> Get thread SQL content (plain text)
|
|
34984
35037
|
etl exec <id> [--sql "..."|--file f] Execute thread (optionally with custom SQL)
|
|
34985
35038
|
etl search <query> Search threads
|
|
35039
|
+
etl pull [--dir <path>] [--no-context] Pull all ETL threads, parameters, metadata & schema to local files
|
|
35040
|
+
etl push [files...] [--dir <path>] [--force] Push modified/new .sql files back to server
|
|
35041
|
+
etl status [--dir <path>] Show local changes (modified, new, deleted)
|
|
35042
|
+
etl context [--dir <path>] Pull context only (schema & modules)
|
|
34986
35043
|
|
|
34987
35044
|
Jobs:
|
|
34988
35045
|
jobs list List available jobs
|
|
@@ -35052,6 +35109,10 @@ Examples:
|
|
|
35052
35109
|
rpbi etl list
|
|
35053
35110
|
rpbi etl exec 42
|
|
35054
35111
|
rpbi etl content 42
|
|
35112
|
+
rpbi etl pull
|
|
35113
|
+
rpbi etl push
|
|
35114
|
+
rpbi etl push IA/folder/script.sql
|
|
35115
|
+
rpbi etl status
|
|
35055
35116
|
|
|
35056
35117
|
rpbi jobs list
|
|
35057
35118
|
rpbi jobs start "My Job"
|
|
@@ -35084,7 +35145,7 @@ Examples:
|
|
|
35084
35145
|
(async () => {
|
|
35085
35146
|
const [command, ...args] = process.argv.slice(2);
|
|
35086
35147
|
if (command === "--version" || command === "-v") {
|
|
35087
|
-
console.log("0.0.
|
|
35148
|
+
console.log("0.0.18");
|
|
35088
35149
|
return;
|
|
35089
35150
|
}
|
|
35090
35151
|
await checkForUpdate();
|