@reporting-bi/cli 0.0.16 → 0.0.17
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 +166 -108
- 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.17"
|
|
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
|
|
@@ -34937,8 +34987,8 @@ async function checkForUpdate() {
|
|
|
34937
34987
|
saveUpdateCheck({ lastCheck: now });
|
|
34938
34988
|
const latest = await fetchLatestVersion();
|
|
34939
34989
|
if (!latest) return;
|
|
34940
|
-
if (!isNewer(latest, "0.0.
|
|
34941
|
-
console.log(`\x1B[33mUpdating ${PACKAGE_NAME} ${"0.0.
|
|
34990
|
+
if (!isNewer(latest, "0.0.17")) return;
|
|
34991
|
+
console.log(`\x1B[33mUpdating ${PACKAGE_NAME} ${"0.0.17"} \u2192 ${latest}...\x1B[0m`);
|
|
34942
34992
|
(0, import_node_child_process2.execSync)(npmInstallCmd(latest), { stdio: "inherit" });
|
|
34943
34993
|
console.log(`\x1B[32mUpdated to ${latest}.\x1B[0m`);
|
|
34944
34994
|
} catch {
|
|
@@ -34950,11 +35000,11 @@ async function forceUpdate() {
|
|
|
34950
35000
|
console.error("Could not fetch latest version from npm.");
|
|
34951
35001
|
process.exit(1);
|
|
34952
35002
|
}
|
|
34953
|
-
if (!isNewer(latest, "0.0.
|
|
34954
|
-
console.log(`Already up to date (${"0.0.
|
|
35003
|
+
if (!isNewer(latest, "0.0.17")) {
|
|
35004
|
+
console.log(`Already up to date (${"0.0.17"}).`);
|
|
34955
35005
|
return;
|
|
34956
35006
|
}
|
|
34957
|
-
console.log(`Updating ${PACKAGE_NAME} ${"0.0.
|
|
35007
|
+
console.log(`Updating ${PACKAGE_NAME} ${"0.0.17"} \u2192 ${latest}...`);
|
|
34958
35008
|
(0, import_node_child_process2.execSync)(npmInstallCmd(latest), { stdio: "inherit" });
|
|
34959
35009
|
console.log(`\x1B[32mUpdated to ${latest}.\x1B[0m`);
|
|
34960
35010
|
saveUpdateCheck({ lastCheck: Date.now() });
|
|
@@ -34983,6 +35033,10 @@ ETL:
|
|
|
34983
35033
|
etl content <id> Get thread SQL content (plain text)
|
|
34984
35034
|
etl exec <id> [--sql "..."|--file f] Execute thread (optionally with custom SQL)
|
|
34985
35035
|
etl search <query> Search threads
|
|
35036
|
+
etl pull [--dir <path>] [--no-context] Pull all ETL threads, parameters, metadata & schema to local files
|
|
35037
|
+
etl push [files...] [--dir <path>] [--force] Push modified/new .sql files back to server
|
|
35038
|
+
etl status [--dir <path>] Show local changes (modified, new, deleted)
|
|
35039
|
+
etl context [--dir <path>] Pull context only (schema & modules)
|
|
34986
35040
|
|
|
34987
35041
|
Jobs:
|
|
34988
35042
|
jobs list List available jobs
|
|
@@ -35052,6 +35106,10 @@ Examples:
|
|
|
35052
35106
|
rpbi etl list
|
|
35053
35107
|
rpbi etl exec 42
|
|
35054
35108
|
rpbi etl content 42
|
|
35109
|
+
rpbi etl pull
|
|
35110
|
+
rpbi etl push
|
|
35111
|
+
rpbi etl push IA/folder/script.sql
|
|
35112
|
+
rpbi etl status
|
|
35055
35113
|
|
|
35056
35114
|
rpbi jobs list
|
|
35057
35115
|
rpbi jobs start "My Job"
|
|
@@ -35084,7 +35142,7 @@ Examples:
|
|
|
35084
35142
|
(async () => {
|
|
35085
35143
|
const [command, ...args] = process.argv.slice(2);
|
|
35086
35144
|
if (command === "--version" || command === "-v") {
|
|
35087
|
-
console.log("0.0.
|
|
35145
|
+
console.log("0.0.17");
|
|
35088
35146
|
return;
|
|
35089
35147
|
}
|
|
35090
35148
|
await checkForUpdate();
|