@fragno-dev/cli 0.1.14 → 0.1.16
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/.turbo/turbo-build.log +7 -7
- package/CHANGELOG.md +23 -0
- package/dist/cli.d.ts +32 -8
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +400 -94
- package/dist/cli.js.map +1 -1
- package/package.json +6 -4
- package/src/cli.ts +90 -83
- package/src/commands/corpus.ts +523 -44
package/dist/cli.js
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { cli, define
|
|
2
|
+
import { cli, define } from "gunshi";
|
|
3
3
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
4
|
-
import { dirname, relative, resolve } from "node:path";
|
|
4
|
+
import { dirname, join, relative, resolve } from "node:path";
|
|
5
5
|
import { executeMigrations, generateMigrationsOrSchema } from "@fragno-dev/db/generation-engine";
|
|
6
6
|
import { FragnoDatabase, isFragnoDatabase } from "@fragno-dev/db";
|
|
7
7
|
import { fragnoDatabaseAdapterNameFakeSymbol, fragnoDatabaseAdapterVersionFakeSymbol } from "@fragno-dev/db/adapters";
|
|
8
8
|
import { instantiatedFragmentFakeSymbol } from "@fragno-dev/core/api/fragment-instantiation";
|
|
9
9
|
import { loadConfig } from "c12";
|
|
10
|
-
import { getSubject, getSubjects } from "@fragno-dev/corpus";
|
|
10
|
+
import { getAllSubjects, getSubject, getSubjectChildren, getSubjectParent, getSubjects } from "@fragno-dev/corpus";
|
|
11
|
+
import { marked } from "marked";
|
|
12
|
+
import { markedTerminal } from "marked-terminal";
|
|
13
|
+
import { stripVTControlCharacters } from "node:util";
|
|
14
|
+
import { readFileSync } from "node:fs";
|
|
15
|
+
import { fileURLToPath } from "node:url";
|
|
11
16
|
|
|
12
17
|
//#region src/utils/find-fragno-databases.ts
|
|
13
18
|
async function importFragmentFile(path) {
|
|
@@ -391,75 +396,360 @@ const searchCommand = define({
|
|
|
391
396
|
|
|
392
397
|
//#endregion
|
|
393
398
|
//#region src/commands/corpus.ts
|
|
399
|
+
marked.use(markedTerminal());
|
|
394
400
|
/**
|
|
395
|
-
*
|
|
401
|
+
* Build markdown content for multiple subjects
|
|
396
402
|
*/
|
|
397
|
-
function
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
403
|
+
function buildSubjectsMarkdown(subjects) {
|
|
404
|
+
let fullMarkdown = "";
|
|
405
|
+
for (const subject of subjects) {
|
|
406
|
+
fullMarkdown += `# ${subject.title}\n\n`;
|
|
407
|
+
if (subject.description) fullMarkdown += `${subject.description}\n\n`;
|
|
408
|
+
if (subject.imports) fullMarkdown += `### Imports\n\n\`\`\`typescript\n${subject.imports}\n\`\`\`\n\n`;
|
|
409
|
+
if (subject.prelude.length > 0) {
|
|
410
|
+
fullMarkdown += `### Prelude\n\n`;
|
|
411
|
+
for (const block of subject.prelude) fullMarkdown += `\`\`\`typescript\n${block.code}\n\`\`\`\n\n`;
|
|
412
|
+
}
|
|
413
|
+
for (const section of subject.sections) fullMarkdown += `## ${section.heading}\n\n${section.content}\n\n`;
|
|
414
|
+
}
|
|
415
|
+
return fullMarkdown;
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* Add line numbers to content
|
|
419
|
+
*/
|
|
420
|
+
function addLineNumbers(content, startFrom = 1) {
|
|
421
|
+
const lines = content.split("\n");
|
|
422
|
+
const maxDigits = String(startFrom + lines.length - 1).length;
|
|
423
|
+
return lines.map((line, index) => {
|
|
424
|
+
const lineNum = startFrom + index;
|
|
425
|
+
return `${String(lineNum).padStart(maxDigits, " ")}│ ${line}`;
|
|
426
|
+
}).join("\n");
|
|
427
|
+
}
|
|
428
|
+
/**
|
|
429
|
+
* Filter content by line range
|
|
430
|
+
*/
|
|
431
|
+
function filterByLineRange(content, startLine, endLine) {
|
|
432
|
+
const lines = content.split("\n");
|
|
433
|
+
const start = Math.max(0, startLine - 1);
|
|
434
|
+
const end = Math.min(lines.length, endLine);
|
|
435
|
+
return lines.slice(start, end).join("\n");
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Extract headings and code block information with line numbers
|
|
439
|
+
*/
|
|
440
|
+
function extractHeadingsAndBlocks(subjects) {
|
|
441
|
+
let output = "";
|
|
442
|
+
let currentLine = 1;
|
|
443
|
+
let lastOutputLine = 0;
|
|
444
|
+
const addGapIfNeeded = () => {
|
|
445
|
+
if (lastOutputLine > 0 && currentLine > lastOutputLine + 1) output += ` │\n`;
|
|
446
|
+
};
|
|
447
|
+
output += "Use --start N --end N flags to show specific line ranges\n\n";
|
|
448
|
+
for (const subject of subjects) {
|
|
449
|
+
addGapIfNeeded();
|
|
450
|
+
output += `${currentLine.toString().padStart(4, " ")}│ # ${subject.title}\n`;
|
|
451
|
+
lastOutputLine = currentLine;
|
|
452
|
+
currentLine += 1;
|
|
453
|
+
output += `${currentLine.toString().padStart(4, " ")}│\n`;
|
|
454
|
+
lastOutputLine = currentLine;
|
|
455
|
+
currentLine += 1;
|
|
456
|
+
if (subject.description) {
|
|
457
|
+
const descLines = subject.description.split("\n");
|
|
458
|
+
for (const line of descLines) {
|
|
459
|
+
output += `${currentLine.toString().padStart(4, " ")}│ ${line}\n`;
|
|
460
|
+
lastOutputLine = currentLine;
|
|
461
|
+
currentLine += 1;
|
|
462
|
+
}
|
|
463
|
+
output += `${currentLine.toString().padStart(4, " ")}│\n`;
|
|
464
|
+
lastOutputLine = currentLine;
|
|
465
|
+
currentLine += 1;
|
|
466
|
+
}
|
|
467
|
+
if (subject.imports) {
|
|
468
|
+
addGapIfNeeded();
|
|
469
|
+
output += `${currentLine.toString().padStart(4, " ")}│ ### Imports\n`;
|
|
470
|
+
lastOutputLine = currentLine;
|
|
471
|
+
currentLine += 1;
|
|
472
|
+
output += `${currentLine.toString().padStart(4, " ")}│\n`;
|
|
473
|
+
lastOutputLine = currentLine;
|
|
474
|
+
currentLine += 1;
|
|
475
|
+
output += `${currentLine.toString().padStart(4, " ")}│ \`\`\`typescript\n`;
|
|
476
|
+
lastOutputLine = currentLine;
|
|
477
|
+
currentLine += 1;
|
|
478
|
+
const importLines = subject.imports.split("\n");
|
|
479
|
+
for (const line of importLines) {
|
|
480
|
+
output += `${currentLine.toString().padStart(4, " ")}│ ${line}\n`;
|
|
481
|
+
lastOutputLine = currentLine;
|
|
482
|
+
currentLine += 1;
|
|
483
|
+
}
|
|
484
|
+
output += `${currentLine.toString().padStart(4, " ")}│ \`\`\`\n`;
|
|
485
|
+
lastOutputLine = currentLine;
|
|
486
|
+
currentLine += 1;
|
|
487
|
+
output += `${currentLine.toString().padStart(4, " ")}│\n`;
|
|
488
|
+
lastOutputLine = currentLine;
|
|
489
|
+
currentLine += 1;
|
|
490
|
+
}
|
|
491
|
+
if (subject.prelude.length > 0) {
|
|
492
|
+
addGapIfNeeded();
|
|
493
|
+
output += `${currentLine.toString().padStart(4, " ")}│ ### Prelude\n`;
|
|
494
|
+
lastOutputLine = currentLine;
|
|
495
|
+
currentLine += 1;
|
|
496
|
+
output += `${currentLine.toString().padStart(4, " ")}│\n`;
|
|
497
|
+
lastOutputLine = currentLine;
|
|
498
|
+
currentLine += 1;
|
|
499
|
+
for (const block of subject.prelude) {
|
|
500
|
+
const id = block.id || "(no-id)";
|
|
501
|
+
const blockStartLine = currentLine + 1;
|
|
502
|
+
const codeLines = block.code.split("\n").length;
|
|
503
|
+
const blockEndLine = currentLine + 1 + codeLines;
|
|
504
|
+
output += `${currentLine.toString().padStart(4, " ")}│ - id: \`${id}\`, L${blockStartLine}-${blockEndLine}\n`;
|
|
505
|
+
lastOutputLine = currentLine;
|
|
506
|
+
currentLine += codeLines + 3;
|
|
507
|
+
}
|
|
508
|
+
lastOutputLine = currentLine - 1;
|
|
509
|
+
}
|
|
510
|
+
const sectionToExamples = /* @__PURE__ */ new Map();
|
|
511
|
+
for (const example of subject.examples) for (const section of subject.sections) if (section.content.includes(example.code.substring(0, Math.min(50, example.code.length)))) {
|
|
512
|
+
if (!sectionToExamples.has(section.heading)) sectionToExamples.set(section.heading, []);
|
|
513
|
+
sectionToExamples.get(section.heading).push(example);
|
|
514
|
+
break;
|
|
515
|
+
}
|
|
516
|
+
for (const section of subject.sections) {
|
|
517
|
+
addGapIfNeeded();
|
|
518
|
+
output += `${currentLine.toString().padStart(4, " ")}│ ## ${section.heading}\n`;
|
|
519
|
+
lastOutputLine = currentLine;
|
|
520
|
+
currentLine += 1;
|
|
521
|
+
const examples = sectionToExamples.get(section.heading) || [];
|
|
522
|
+
if (examples.length > 0) {
|
|
523
|
+
const sectionStartLine = currentLine;
|
|
524
|
+
const lines = section.content.split("\n");
|
|
525
|
+
for (const example of examples) {
|
|
526
|
+
const id = example.id || "(no-id)";
|
|
527
|
+
let blockStartLine = sectionStartLine;
|
|
528
|
+
let blockEndLine = sectionStartLine;
|
|
529
|
+
let foundBlock = false;
|
|
530
|
+
for (let i = 0; i < lines.length; i++) if (lines[i].trim().startsWith("```") && true) {
|
|
531
|
+
const codeStart = i + 1;
|
|
532
|
+
let matches = true;
|
|
533
|
+
const exampleLines = example.code.split("\n");
|
|
534
|
+
for (let j = 0; j < Math.min(3, exampleLines.length); j++) if (lines[codeStart + j]?.trim() !== exampleLines[j]?.trim()) {
|
|
535
|
+
matches = false;
|
|
536
|
+
break;
|
|
537
|
+
}
|
|
538
|
+
if (matches) {
|
|
539
|
+
blockStartLine = sectionStartLine + i + 1;
|
|
540
|
+
blockEndLine = sectionStartLine + i + exampleLines.length;
|
|
541
|
+
foundBlock = true;
|
|
542
|
+
break;
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
if (foundBlock) output += `${currentLine.toString().padStart(4, " ")}│ - id: \`${id}\`, L${blockStartLine}-${blockEndLine}\n`;
|
|
546
|
+
else output += `${currentLine.toString().padStart(4, " ")}│ - id: \`${id}\`\n`;
|
|
547
|
+
lastOutputLine = currentLine;
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
const sectionLines = section.content.split("\n");
|
|
551
|
+
for (const _line of sectionLines) currentLine += 1;
|
|
552
|
+
currentLine += 1;
|
|
553
|
+
lastOutputLine = currentLine - 1;
|
|
554
|
+
}
|
|
404
555
|
}
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
556
|
+
return output;
|
|
557
|
+
}
|
|
558
|
+
/**
|
|
559
|
+
* Print subjects with the given options
|
|
560
|
+
*/
|
|
561
|
+
async function printSubjects(subjects, options) {
|
|
562
|
+
if (options.headingsOnly) {
|
|
563
|
+
const headingsOutput = extractHeadingsAndBlocks(subjects);
|
|
564
|
+
console.log(headingsOutput);
|
|
565
|
+
return;
|
|
410
566
|
}
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
567
|
+
const markdown = buildSubjectsMarkdown(subjects);
|
|
568
|
+
let output = await marked.parse(markdown);
|
|
569
|
+
const startLine = options.startLine ?? 1;
|
|
570
|
+
if (options.startLine !== void 0 || options.endLine !== void 0) {
|
|
571
|
+
const end = options.endLine ?? output.split("\n").length;
|
|
572
|
+
output = filterByLineRange(output, startLine, end);
|
|
416
573
|
}
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
574
|
+
if (options.showLineNumbers) output = addLineNumbers(output, startLine);
|
|
575
|
+
console.log(output);
|
|
576
|
+
}
|
|
577
|
+
/**
|
|
578
|
+
* Find and print code blocks by ID
|
|
579
|
+
*/
|
|
580
|
+
async function printCodeBlockById(id, topics, showLineNumbers) {
|
|
581
|
+
const subjects = topics.length > 0 ? getSubject(...topics) : getAllSubjects();
|
|
582
|
+
const matches = [];
|
|
583
|
+
for (const subject of subjects) {
|
|
584
|
+
const fullMarkdown = buildSubjectsMarkdown([subject]);
|
|
585
|
+
const renderedLines = (await marked.parse(fullMarkdown)).split("\n");
|
|
586
|
+
for (const block of subject.prelude) if (block.id === id) {
|
|
587
|
+
let startLine;
|
|
588
|
+
let endLine;
|
|
589
|
+
const codeLines = block.code.split("\n");
|
|
590
|
+
const firstCodeLine = codeLines[0].trim();
|
|
591
|
+
for (let i = 0; i < renderedLines.length; i++) if (stripVTControlCharacters(renderedLines[i]).trim() === firstCodeLine) {
|
|
592
|
+
startLine = i + 1;
|
|
593
|
+
endLine = i + codeLines.length;
|
|
594
|
+
break;
|
|
595
|
+
}
|
|
596
|
+
matches.push({
|
|
597
|
+
subjectId: subject.id,
|
|
598
|
+
subjectTitle: subject.title,
|
|
599
|
+
section: "Prelude",
|
|
600
|
+
code: block.code,
|
|
601
|
+
type: "prelude",
|
|
602
|
+
startLine,
|
|
603
|
+
endLine
|
|
604
|
+
});
|
|
605
|
+
}
|
|
606
|
+
for (const example of subject.examples) if (example.id === id) {
|
|
607
|
+
let sectionName = "Unknown Section";
|
|
608
|
+
let startLine;
|
|
609
|
+
let endLine;
|
|
610
|
+
for (const section of subject.sections) if (section.content.includes(example.code.substring(0, Math.min(50, example.code.length)))) {
|
|
611
|
+
sectionName = section.heading;
|
|
612
|
+
const codeLines = example.code.split("\n");
|
|
613
|
+
const firstCodeLine = codeLines[0].trim();
|
|
614
|
+
for (let i = 0; i < renderedLines.length; i++) if (stripVTControlCharacters(renderedLines[i]).trim() === firstCodeLine) {
|
|
615
|
+
startLine = i + 1;
|
|
616
|
+
endLine = i + codeLines.length;
|
|
617
|
+
break;
|
|
618
|
+
}
|
|
619
|
+
break;
|
|
620
|
+
}
|
|
621
|
+
matches.push({
|
|
622
|
+
subjectId: subject.id,
|
|
623
|
+
subjectTitle: subject.title,
|
|
624
|
+
section: sectionName,
|
|
625
|
+
code: example.code,
|
|
626
|
+
type: "example",
|
|
627
|
+
startLine,
|
|
628
|
+
endLine
|
|
629
|
+
});
|
|
426
630
|
}
|
|
427
|
-
|
|
631
|
+
}
|
|
632
|
+
if (matches.length === 0) {
|
|
633
|
+
console.error(`Error: No code block found with id "${id}"`);
|
|
634
|
+
if (topics.length > 0) console.error(`Searched in topics: ${topics.join(", ")}`);
|
|
635
|
+
else console.error("Searched in all available topics");
|
|
636
|
+
process.exit(1);
|
|
637
|
+
}
|
|
638
|
+
for (let i = 0; i < matches.length; i++) {
|
|
639
|
+
const match = matches[i];
|
|
640
|
+
if (matches.length > 1 && i > 0) console.log("\n---\n");
|
|
641
|
+
let matchMarkdown = `# ${match.subjectTitle}\n\n`;
|
|
642
|
+
matchMarkdown += `## ${match.section}\n\n`;
|
|
643
|
+
if (showLineNumbers && match.startLine && match.endLine) console.log(`Lines ${match.startLine}-${match.endLine} (use with --start/--end)\n`);
|
|
644
|
+
matchMarkdown += `\`\`\`typescript\n${match.code}\n\`\`\`\n`;
|
|
645
|
+
const rendered = await marked.parse(matchMarkdown);
|
|
646
|
+
console.log(rendered);
|
|
428
647
|
}
|
|
429
648
|
}
|
|
430
649
|
/**
|
|
431
650
|
* Print information about the corpus command
|
|
432
651
|
*/
|
|
433
652
|
function printCorpusHelp() {
|
|
434
|
-
console.log("Fragno Corpus - Code examples and documentation");
|
|
653
|
+
console.log("Fragno Corpus - Code examples and documentation (similar to LLMs.txt");
|
|
654
|
+
console.log("");
|
|
655
|
+
console.log("Usage: fragno-cli corpus [options] [topic...]");
|
|
435
656
|
console.log("");
|
|
436
|
-
console.log("
|
|
657
|
+
console.log("Options:");
|
|
658
|
+
console.log(" -n, --no-line-numbers Hide line numbers (shown by default)");
|
|
659
|
+
console.log(" -s, --start N Starting line number to display from");
|
|
660
|
+
console.log(" -e, --end N Ending line number to display to");
|
|
661
|
+
console.log(" --headings Show only headings and code block IDs");
|
|
662
|
+
console.log(" --id <id> Retrieve a specific code block by ID");
|
|
437
663
|
console.log("");
|
|
438
664
|
console.log("Examples:");
|
|
439
665
|
console.log(" fragno-cli corpus # List all available topics");
|
|
440
666
|
console.log(" fragno-cli corpus defining-routes # Show route definition examples");
|
|
667
|
+
console.log(" fragno-cli corpus --headings database-querying");
|
|
668
|
+
console.log(" # Show structure overview");
|
|
669
|
+
console.log(" fragno-cli corpus --start 10 --end 50 database-querying");
|
|
670
|
+
console.log(" # Show specific lines");
|
|
671
|
+
console.log(" fragno-cli corpus --id create-user # Get code block by ID");
|
|
441
672
|
console.log(" fragno-cli corpus database-adapters kysely-adapter");
|
|
442
673
|
console.log(" # Show multiple topics");
|
|
443
674
|
console.log("");
|
|
444
675
|
console.log("Available topics:");
|
|
445
676
|
const subjects = getSubjects();
|
|
446
|
-
|
|
677
|
+
const rootSubjects = [];
|
|
678
|
+
const subjectMap = new Map(subjects.map((s) => [s.id, s]));
|
|
679
|
+
for (const subject of subjects) if (!getSubjectParent(subject.id)) {
|
|
680
|
+
const children = getSubjectChildren(subject.id);
|
|
681
|
+
rootSubjects.push({
|
|
682
|
+
id: subject.id,
|
|
683
|
+
title: subject.title,
|
|
684
|
+
children: children.map((childId) => ({
|
|
685
|
+
id: childId,
|
|
686
|
+
title: subjectMap.get(childId)?.title || childId
|
|
687
|
+
}))
|
|
688
|
+
});
|
|
689
|
+
}
|
|
690
|
+
for (const root of rootSubjects) {
|
|
691
|
+
console.log(` ${root.id.padEnd(30)} ${root.title}`);
|
|
692
|
+
for (let i = 0; i < root.children.length; i++) {
|
|
693
|
+
const child = root.children[i];
|
|
694
|
+
const connector = i === root.children.length - 1 ? "└─" : "├─";
|
|
695
|
+
console.log(` ${connector} ${child.id.padEnd(26)} ${child.title}`);
|
|
696
|
+
}
|
|
697
|
+
}
|
|
447
698
|
}
|
|
448
699
|
const corpusCommand = define({
|
|
449
700
|
name: "corpus",
|
|
450
701
|
description: "View code examples and documentation for Fragno",
|
|
451
|
-
|
|
702
|
+
args: {
|
|
703
|
+
"no-line-numbers": {
|
|
704
|
+
type: "boolean",
|
|
705
|
+
short: "n",
|
|
706
|
+
description: "Hide line numbers (line numbers are shown by default)"
|
|
707
|
+
},
|
|
708
|
+
start: {
|
|
709
|
+
type: "number",
|
|
710
|
+
short: "s",
|
|
711
|
+
description: "Starting line number (1-based) to display from"
|
|
712
|
+
},
|
|
713
|
+
end: {
|
|
714
|
+
type: "number",
|
|
715
|
+
short: "e",
|
|
716
|
+
description: "Ending line number (1-based) to display to"
|
|
717
|
+
},
|
|
718
|
+
headings: {
|
|
719
|
+
type: "boolean",
|
|
720
|
+
description: "Show only section headings and code block IDs with line numbers"
|
|
721
|
+
},
|
|
722
|
+
id: {
|
|
723
|
+
type: "string",
|
|
724
|
+
description: "Retrieve a specific code block by ID"
|
|
725
|
+
}
|
|
726
|
+
},
|
|
727
|
+
run: async (ctx) => {
|
|
452
728
|
const topics = ctx.positionals;
|
|
729
|
+
const showLineNumbers = !(ctx.values["no-line-numbers"] ?? false);
|
|
730
|
+
const startLine = ctx.values.start;
|
|
731
|
+
const endLine = ctx.values.end;
|
|
732
|
+
const headingsOnly = ctx.values.headings ?? false;
|
|
733
|
+
const codeBlockId = ctx.values.id;
|
|
734
|
+
if (codeBlockId) {
|
|
735
|
+
await printCodeBlockById(codeBlockId, topics, showLineNumbers);
|
|
736
|
+
return;
|
|
737
|
+
}
|
|
453
738
|
if (topics.length === 0) {
|
|
454
739
|
printCorpusHelp();
|
|
455
740
|
return;
|
|
456
741
|
}
|
|
742
|
+
if (startLine !== void 0 && endLine !== void 0 && startLine > endLine) {
|
|
743
|
+
console.error("Error: --start must be less than or equal to --end");
|
|
744
|
+
process.exit(1);
|
|
745
|
+
}
|
|
457
746
|
try {
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
747
|
+
await printSubjects(getSubject(...topics), {
|
|
748
|
+
showLineNumbers,
|
|
749
|
+
startLine,
|
|
750
|
+
endLine,
|
|
751
|
+
headingsOnly
|
|
752
|
+
});
|
|
463
753
|
} catch (error) {
|
|
464
754
|
console.error("Error loading topics:", error instanceof Error ? error.message : error);
|
|
465
755
|
console.log("\nRun 'fragno-cli corpus' to see available topics.");
|
|
@@ -470,75 +760,91 @@ const corpusCommand = define({
|
|
|
470
760
|
|
|
471
761
|
//#endregion
|
|
472
762
|
//#region src/cli.ts
|
|
763
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
764
|
+
const version = JSON.parse(readFileSync(join(__dirname, "../package.json"), "utf-8")).version;
|
|
473
765
|
const dbSubCommands = /* @__PURE__ */ new Map();
|
|
474
766
|
dbSubCommands.set("generate", generateCommand);
|
|
475
767
|
dbSubCommands.set("migrate", migrateCommand);
|
|
476
768
|
dbSubCommands.set("info", infoCommand);
|
|
477
|
-
function printDbHelp() {
|
|
478
|
-
console.log("Database management commands for Fragno");
|
|
479
|
-
console.log("");
|
|
480
|
-
console.log("Usage: fragno-cli db <command> [options]");
|
|
481
|
-
console.log("");
|
|
482
|
-
console.log("Commands:");
|
|
483
|
-
console.log(" generate Generate schema files from FragnoDatabase definitions");
|
|
484
|
-
console.log(" migrate Run database migrations");
|
|
485
|
-
console.log(" info Display database information and migration status");
|
|
486
|
-
console.log("");
|
|
487
|
-
console.log("Run 'fragno-cli db <command> --help' for more information.");
|
|
488
|
-
}
|
|
489
769
|
const dbCommand = define({
|
|
490
770
|
name: "db",
|
|
491
|
-
description: "Database management commands"
|
|
492
|
-
run: printDbHelp
|
|
771
|
+
description: "Database management commands"
|
|
493
772
|
});
|
|
494
|
-
const rootSubCommands = /* @__PURE__ */ new Map();
|
|
495
|
-
rootSubCommands.set("db", dbCommand);
|
|
496
|
-
rootSubCommands.set("search", searchCommand);
|
|
497
|
-
rootSubCommands.set("corpus", corpusCommand);
|
|
498
773
|
const mainCommand = define({
|
|
499
774
|
name: "fragno-cli",
|
|
500
|
-
description: "
|
|
501
|
-
run: () => {
|
|
502
|
-
console.log("Fragno CLI - Tools for working with Fragno fragments");
|
|
503
|
-
console.log("");
|
|
504
|
-
console.log("Usage: fragno-cli <command> [options]");
|
|
505
|
-
console.log("");
|
|
506
|
-
console.log("Commands:");
|
|
507
|
-
console.log(" db Database management commands");
|
|
508
|
-
console.log(" search Search the Fragno documentation");
|
|
509
|
-
console.log(" corpus View code examples and documentation");
|
|
510
|
-
console.log("");
|
|
511
|
-
console.log("Run 'fragno-cli <command> --help' for more information.");
|
|
512
|
-
}
|
|
775
|
+
description: "Tools for working with Fragno fragments"
|
|
513
776
|
});
|
|
514
777
|
if (import.meta.main) try {
|
|
515
778
|
const args = process.argv.slice(2);
|
|
516
|
-
if (args[0] === "search") await cli(args.slice(1), searchCommand
|
|
517
|
-
|
|
518
|
-
|
|
779
|
+
if (args[0] === "search") await cli(args.slice(1), searchCommand, {
|
|
780
|
+
name: "fragno-cli search",
|
|
781
|
+
version
|
|
782
|
+
});
|
|
783
|
+
else if (args[0] === "corpus") await cli(args.slice(1), corpusCommand, {
|
|
784
|
+
name: "fragno-cli corpus",
|
|
785
|
+
version
|
|
786
|
+
});
|
|
787
|
+
else if (args[0] === "db") {
|
|
519
788
|
const subCommandName = args[1];
|
|
520
|
-
if (subCommandName === "--help" || subCommandName === "-h") {
|
|
521
|
-
|
|
522
|
-
process.exit(0);
|
|
523
|
-
}
|
|
524
|
-
const subCommand = dbSubCommands.get(subCommandName);
|
|
525
|
-
if (!subCommand) {
|
|
526
|
-
console.error(`Unknown command: ${subCommandName}`);
|
|
789
|
+
if (!subCommandName || subCommandName === "--help" || subCommandName === "-h") {
|
|
790
|
+
console.log("Database management commands");
|
|
527
791
|
console.log("");
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
792
|
+
console.log("USAGE:");
|
|
793
|
+
console.log(" fragno-cli db <COMMAND>");
|
|
794
|
+
console.log("");
|
|
795
|
+
console.log("COMMANDS:");
|
|
796
|
+
console.log(" generate Generate schema files from FragnoDatabase definitions");
|
|
797
|
+
console.log(" migrate Run database migrations");
|
|
798
|
+
console.log(" info Display database information and migration status");
|
|
799
|
+
console.log("");
|
|
800
|
+
console.log("For more info, run any command with the `--help` flag:");
|
|
801
|
+
console.log(" fragno-cli db generate --help");
|
|
802
|
+
console.log(" fragno-cli db migrate --help");
|
|
803
|
+
console.log(" fragno-cli db info --help");
|
|
804
|
+
console.log("");
|
|
805
|
+
console.log("OPTIONS:");
|
|
806
|
+
console.log(" -h, --help Display this help message");
|
|
807
|
+
console.log(" -v, --version Display this version");
|
|
808
|
+
} else if (subCommandName === "--version" || subCommandName === "-v") console.log(version);
|
|
809
|
+
else {
|
|
810
|
+
const subCommand = dbSubCommands.get(subCommandName);
|
|
811
|
+
if (!subCommand) {
|
|
812
|
+
console.error(`Unknown command: ${subCommandName}`);
|
|
813
|
+
console.log("");
|
|
814
|
+
console.log("Run 'fragno-cli db --help' for available commands.");
|
|
815
|
+
process.exit(1);
|
|
816
|
+
}
|
|
817
|
+
await cli(args.slice(2), subCommand, {
|
|
818
|
+
name: `fragno-cli db ${subCommandName}`,
|
|
819
|
+
version
|
|
820
|
+
});
|
|
537
821
|
}
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
822
|
+
} else if (!args.length || args[0] === "--help" || args[0] === "-h") {
|
|
823
|
+
console.log("Tools for working with Fragno");
|
|
824
|
+
console.log("");
|
|
825
|
+
console.log("USAGE:");
|
|
826
|
+
console.log(" fragno-cli <COMMAND>");
|
|
827
|
+
console.log("");
|
|
828
|
+
console.log("COMMANDS:");
|
|
829
|
+
console.log(" db Database management commands");
|
|
830
|
+
console.log(" search Search the Fragno documentation");
|
|
831
|
+
console.log(" corpus View code examples and documentation for Fragno");
|
|
832
|
+
console.log("");
|
|
833
|
+
console.log("For more info, run any command with the `--help` flag:");
|
|
834
|
+
console.log(" fragno-cli db --help");
|
|
835
|
+
console.log(" fragno-cli search --help");
|
|
836
|
+
console.log(" fragno-cli corpus --help");
|
|
837
|
+
console.log("");
|
|
838
|
+
console.log("OPTIONS:");
|
|
839
|
+
console.log(" -h, --help Display this help message");
|
|
840
|
+
console.log(" -v, --version Display this version");
|
|
841
|
+
} else if (args[0] === "--version" || args[0] === "-v") console.log(version);
|
|
842
|
+
else {
|
|
843
|
+
console.error(`Unknown command: ${args[0]}`);
|
|
844
|
+
console.log("");
|
|
845
|
+
console.log("Run 'fragno-cli --help' for available commands.");
|
|
846
|
+
process.exit(1);
|
|
847
|
+
}
|
|
542
848
|
} catch (error) {
|
|
543
849
|
console.error("Error:", error instanceof Error ? error.message : error);
|
|
544
850
|
process.exit(1);
|