openzca 0.1.37 → 0.1.38
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/cli.js +268 -280
- package/package.json +1 -2
package/dist/cli.js
CHANGED
|
@@ -15,10 +15,8 @@ import {
|
|
|
15
15
|
Gender,
|
|
16
16
|
Reactions,
|
|
17
17
|
ReviewPendingMemberRequestStatus,
|
|
18
|
-
TextStyle,
|
|
19
18
|
ThreadType
|
|
20
19
|
} from "zca-js";
|
|
21
|
-
import { marked } from "marked";
|
|
22
20
|
|
|
23
21
|
// src/lib/store.ts
|
|
24
22
|
import fs from "fs/promises";
|
|
@@ -580,6 +578,273 @@ async function assertFilesExist(files) {
|
|
|
580
578
|
}
|
|
581
579
|
}
|
|
582
580
|
|
|
581
|
+
// src/lib/text-styles.ts
|
|
582
|
+
import { TextStyle } from "zca-js";
|
|
583
|
+
var TAG_STYLE_MAP = {
|
|
584
|
+
red: TextStyle.Red,
|
|
585
|
+
orange: TextStyle.Orange,
|
|
586
|
+
yellow: TextStyle.Yellow,
|
|
587
|
+
green: TextStyle.Green,
|
|
588
|
+
small: TextStyle.Small,
|
|
589
|
+
big: TextStyle.Big,
|
|
590
|
+
underline: TextStyle.Underline
|
|
591
|
+
};
|
|
592
|
+
var INLINE_MARKERS = [
|
|
593
|
+
{
|
|
594
|
+
pattern: new RegExp(`\\{(${Object.keys(TAG_STYLE_MAP).join("|")})\\}(.+?)\\{/\\1\\}`, "g"),
|
|
595
|
+
style: null
|
|
596
|
+
},
|
|
597
|
+
{ pattern: /\*\*\*(.+?)\*\*\*/g, style: TextStyle.Bold, extraStyles: [TextStyle.Italic] },
|
|
598
|
+
{ pattern: /\*\*(.+?)\*\*/g, style: TextStyle.Bold },
|
|
599
|
+
{ pattern: /(?<!\w)__(.+?)__(?!\w)/g, style: TextStyle.Bold },
|
|
600
|
+
{ pattern: /\*(.+?)\*/g, style: TextStyle.Italic },
|
|
601
|
+
{ pattern: /(?<!\w)_(.+?)_(?!\w)/g, style: TextStyle.Italic },
|
|
602
|
+
{ pattern: /~~(.+?)~~/g, style: TextStyle.StrikeThrough }
|
|
603
|
+
];
|
|
604
|
+
function parseTextStyles(input) {
|
|
605
|
+
const allStyles = [];
|
|
606
|
+
const codeLineIndices = extractCodeBlockLines(input);
|
|
607
|
+
input = stripCodeFences(input);
|
|
608
|
+
const escapeMap = [];
|
|
609
|
+
const escapedInput = input.replace(/\\([*_~#\\{}>+\-])/g, (_match, ch) => {
|
|
610
|
+
const index = escapeMap.length;
|
|
611
|
+
escapeMap.push(ch);
|
|
612
|
+
return `${index}`;
|
|
613
|
+
});
|
|
614
|
+
const lines = escapedInput.split("\n");
|
|
615
|
+
const lineStyles = [];
|
|
616
|
+
const processedLines = [];
|
|
617
|
+
for (let lineIndex = 0; lineIndex < lines.length; lineIndex += 1) {
|
|
618
|
+
let line = lines[lineIndex];
|
|
619
|
+
if (codeLineIndices.has(lineIndex)) {
|
|
620
|
+
processedLines.push(line);
|
|
621
|
+
continue;
|
|
622
|
+
}
|
|
623
|
+
const headingMatch = line.match(/^(#{1,4})\s(.*)$/);
|
|
624
|
+
if (headingMatch) {
|
|
625
|
+
const depth = headingMatch[1].length;
|
|
626
|
+
lineStyles.push({ lineIndex, style: TextStyle.Bold });
|
|
627
|
+
if (depth === 1) {
|
|
628
|
+
lineStyles.push({ lineIndex, style: TextStyle.Big });
|
|
629
|
+
} else if (depth === 3 || depth === 4) {
|
|
630
|
+
lineStyles.push({ lineIndex, style: TextStyle.Small });
|
|
631
|
+
}
|
|
632
|
+
processedLines.push(headingMatch[2]);
|
|
633
|
+
continue;
|
|
634
|
+
}
|
|
635
|
+
const quoteMatch = line.match(/^(>+)\s?(.*)$/);
|
|
636
|
+
if (quoteMatch) {
|
|
637
|
+
lineStyles.push({
|
|
638
|
+
lineIndex,
|
|
639
|
+
style: TextStyle.Indent,
|
|
640
|
+
indentSize: Math.min(5, quoteMatch[1].length)
|
|
641
|
+
});
|
|
642
|
+
line = quoteMatch[2];
|
|
643
|
+
}
|
|
644
|
+
const indentMatch = line.match(/^(\s+)(.*)$/);
|
|
645
|
+
let indentLevel = 0;
|
|
646
|
+
let content = line;
|
|
647
|
+
if (indentMatch) {
|
|
648
|
+
indentLevel = clampIndent(indentMatch[1].length);
|
|
649
|
+
content = indentMatch[2];
|
|
650
|
+
}
|
|
651
|
+
if (/^[-*+]\s\[[ xX]\]\s/.test(content)) {
|
|
652
|
+
if (indentLevel > 0) {
|
|
653
|
+
lineStyles.push({ lineIndex, style: TextStyle.Indent, indentSize: indentLevel });
|
|
654
|
+
}
|
|
655
|
+
processedLines.push(content);
|
|
656
|
+
continue;
|
|
657
|
+
}
|
|
658
|
+
const orderedListMatch = content.match(/^(\d+)\.\s(.*)$/);
|
|
659
|
+
if (orderedListMatch) {
|
|
660
|
+
if (indentLevel > 0) {
|
|
661
|
+
lineStyles.push({ lineIndex, style: TextStyle.Indent, indentSize: indentLevel });
|
|
662
|
+
}
|
|
663
|
+
lineStyles.push({ lineIndex, style: TextStyle.OrderedList });
|
|
664
|
+
processedLines.push(orderedListMatch[2]);
|
|
665
|
+
continue;
|
|
666
|
+
}
|
|
667
|
+
const unorderedListMatch = content.match(/^[-*+]\s(.*)$/);
|
|
668
|
+
if (unorderedListMatch) {
|
|
669
|
+
if (indentLevel > 0) {
|
|
670
|
+
lineStyles.push({ lineIndex, style: TextStyle.Indent, indentSize: indentLevel });
|
|
671
|
+
}
|
|
672
|
+
lineStyles.push({ lineIndex, style: TextStyle.UnorderedList });
|
|
673
|
+
processedLines.push(unorderedListMatch[1]);
|
|
674
|
+
continue;
|
|
675
|
+
}
|
|
676
|
+
if (indentLevel > 0) {
|
|
677
|
+
lineStyles.push({ lineIndex, style: TextStyle.Indent, indentSize: indentLevel });
|
|
678
|
+
processedLines.push(content);
|
|
679
|
+
continue;
|
|
680
|
+
}
|
|
681
|
+
processedLines.push(line);
|
|
682
|
+
}
|
|
683
|
+
for (const codeLineIndex of codeLineIndices) {
|
|
684
|
+
if (codeLineIndex >= processedLines.length) {
|
|
685
|
+
continue;
|
|
686
|
+
}
|
|
687
|
+
processedLines[codeLineIndex] = processedLines[codeLineIndex].replace(/[*_~{}]/g, (ch) => {
|
|
688
|
+
const index = escapeMap.length;
|
|
689
|
+
escapeMap.push(ch);
|
|
690
|
+
return `${index}`;
|
|
691
|
+
});
|
|
692
|
+
}
|
|
693
|
+
let segments = [{ text: processedLines.join("\n"), styles: [] }];
|
|
694
|
+
for (const marker of INLINE_MARKERS) {
|
|
695
|
+
const nextSegments = [];
|
|
696
|
+
for (const segment of segments) {
|
|
697
|
+
let lastIndex = 0;
|
|
698
|
+
const regex = new RegExp(marker.pattern.source, marker.pattern.flags);
|
|
699
|
+
let match;
|
|
700
|
+
while ((match = regex.exec(segment.text)) !== null) {
|
|
701
|
+
if (match.index > lastIndex) {
|
|
702
|
+
nextSegments.push({
|
|
703
|
+
text: segment.text.slice(lastIndex, match.index),
|
|
704
|
+
styles: [...segment.styles]
|
|
705
|
+
});
|
|
706
|
+
}
|
|
707
|
+
const isTagPattern = marker.style === null;
|
|
708
|
+
const innerText = isTagPattern ? match[2] : match[1];
|
|
709
|
+
const resolvedStyle = isTagPattern ? TAG_STYLE_MAP[match[1]] : marker.style;
|
|
710
|
+
const combinedStyles = [...segment.styles];
|
|
711
|
+
if (resolvedStyle) {
|
|
712
|
+
combinedStyles.push(resolvedStyle);
|
|
713
|
+
}
|
|
714
|
+
if (marker.extraStyles) {
|
|
715
|
+
combinedStyles.push(...marker.extraStyles);
|
|
716
|
+
}
|
|
717
|
+
nextSegments.push({
|
|
718
|
+
text: innerText,
|
|
719
|
+
styles: combinedStyles
|
|
720
|
+
});
|
|
721
|
+
lastIndex = regex.lastIndex;
|
|
722
|
+
}
|
|
723
|
+
if (lastIndex < segment.text.length) {
|
|
724
|
+
nextSegments.push({
|
|
725
|
+
text: segment.text.slice(lastIndex),
|
|
726
|
+
styles: [...segment.styles]
|
|
727
|
+
});
|
|
728
|
+
} else if (lastIndex === 0) {
|
|
729
|
+
nextSegments.push(segment);
|
|
730
|
+
}
|
|
731
|
+
}
|
|
732
|
+
segments = nextSegments;
|
|
733
|
+
}
|
|
734
|
+
let plainText = "";
|
|
735
|
+
for (const segment of segments) {
|
|
736
|
+
const start = plainText.length;
|
|
737
|
+
plainText += segment.text;
|
|
738
|
+
for (const style of segment.styles) {
|
|
739
|
+
allStyles.push({ start, len: segment.text.length, st: style });
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
const orphanMatches = [...plainText.matchAll(/\*([^*\n]+?)\*/g)];
|
|
743
|
+
for (let index = orphanMatches.length - 1; index >= 0; index -= 1) {
|
|
744
|
+
const match = orphanMatches[index];
|
|
745
|
+
const openPos = match.index ?? 0;
|
|
746
|
+
const content = match[1];
|
|
747
|
+
const closePos = openPos + content.length + 1;
|
|
748
|
+
allStyles.push({ start: openPos + 1, len: content.length, st: TextStyle.Italic });
|
|
749
|
+
plainText = plainText.slice(0, closePos) + plainText.slice(closePos + 1);
|
|
750
|
+
plainText = plainText.slice(0, openPos) + plainText.slice(openPos + 1);
|
|
751
|
+
for (const style of allStyles) {
|
|
752
|
+
if (style.start > closePos) {
|
|
753
|
+
style.start -= 1;
|
|
754
|
+
} else if (style.start + style.len > closePos) {
|
|
755
|
+
style.len -= 1;
|
|
756
|
+
}
|
|
757
|
+
if (style.start > openPos) {
|
|
758
|
+
style.start -= 1;
|
|
759
|
+
} else if (style.start + style.len > openPos) {
|
|
760
|
+
style.len -= 1;
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
if (escapeMap.length > 0) {
|
|
765
|
+
const escapeRegex = /\x01(\d+)\x02/g;
|
|
766
|
+
const shifts = [];
|
|
767
|
+
let cumulativeDelta = 0;
|
|
768
|
+
for (const match of plainText.matchAll(escapeRegex)) {
|
|
769
|
+
const escapeIndex = Number.parseInt(match[1], 10);
|
|
770
|
+
cumulativeDelta += match[0].length - escapeMap[escapeIndex].length;
|
|
771
|
+
shifts.push({ pos: (match.index ?? 0) + match[0].length, delta: cumulativeDelta });
|
|
772
|
+
}
|
|
773
|
+
for (const style of allStyles) {
|
|
774
|
+
let startDelta = 0;
|
|
775
|
+
let endDelta = 0;
|
|
776
|
+
const end = style.start + style.len;
|
|
777
|
+
for (const shift of shifts) {
|
|
778
|
+
if (shift.pos <= style.start) {
|
|
779
|
+
startDelta = shift.delta;
|
|
780
|
+
}
|
|
781
|
+
if (shift.pos <= end) {
|
|
782
|
+
endDelta = shift.delta;
|
|
783
|
+
}
|
|
784
|
+
}
|
|
785
|
+
style.start -= startDelta;
|
|
786
|
+
style.len -= endDelta - startDelta;
|
|
787
|
+
}
|
|
788
|
+
plainText = plainText.replace(escapeRegex, (_match, index) => escapeMap[Number.parseInt(index, 10)]);
|
|
789
|
+
}
|
|
790
|
+
const finalLines = plainText.split("\n");
|
|
791
|
+
let offset = 0;
|
|
792
|
+
for (let lineIndex = 0; lineIndex < finalLines.length; lineIndex += 1) {
|
|
793
|
+
const lineLength = finalLines[lineIndex].length;
|
|
794
|
+
if (lineLength > 0) {
|
|
795
|
+
for (const lineStyle of lineStyles) {
|
|
796
|
+
if (lineStyle.lineIndex !== lineIndex) {
|
|
797
|
+
continue;
|
|
798
|
+
}
|
|
799
|
+
if (lineStyle.style === TextStyle.Indent) {
|
|
800
|
+
allStyles.push({
|
|
801
|
+
start: offset,
|
|
802
|
+
len: lineLength,
|
|
803
|
+
st: TextStyle.Indent,
|
|
804
|
+
indentSize: lineStyle.indentSize
|
|
805
|
+
});
|
|
806
|
+
} else {
|
|
807
|
+
allStyles.push({ start: offset, len: lineLength, st: lineStyle.style });
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
offset += lineLength + 1;
|
|
812
|
+
}
|
|
813
|
+
return { text: plainText, styles: allStyles };
|
|
814
|
+
}
|
|
815
|
+
function extractCodeBlockLines(input) {
|
|
816
|
+
const codeLineIndices = /* @__PURE__ */ new Set();
|
|
817
|
+
const rawLines = input.split("\n");
|
|
818
|
+
let lineIndex = 0;
|
|
819
|
+
let inCodeBlock = false;
|
|
820
|
+
for (const rawLine of rawLines) {
|
|
821
|
+
if (/^```/.test(rawLine)) {
|
|
822
|
+
inCodeBlock = !inCodeBlock;
|
|
823
|
+
continue;
|
|
824
|
+
}
|
|
825
|
+
if (inCodeBlock) {
|
|
826
|
+
codeLineIndices.add(lineIndex);
|
|
827
|
+
}
|
|
828
|
+
lineIndex += 1;
|
|
829
|
+
}
|
|
830
|
+
return codeLineIndices;
|
|
831
|
+
}
|
|
832
|
+
function stripCodeFences(input) {
|
|
833
|
+
const keptLines = [];
|
|
834
|
+
let inCodeBlock = false;
|
|
835
|
+
for (const rawLine of input.split("\n")) {
|
|
836
|
+
if (/^```/.test(rawLine)) {
|
|
837
|
+
inCodeBlock = !inCodeBlock;
|
|
838
|
+
continue;
|
|
839
|
+
}
|
|
840
|
+
keptLines.push(rawLine);
|
|
841
|
+
}
|
|
842
|
+
return keptLines.join("\n");
|
|
843
|
+
}
|
|
844
|
+
function clampIndent(spaceCount) {
|
|
845
|
+
return Math.min(5, Math.max(1, Math.floor(spaceCount / 2)));
|
|
846
|
+
}
|
|
847
|
+
|
|
583
848
|
// src/cli.ts
|
|
584
849
|
var require2 = createRequire(import.meta.url);
|
|
585
850
|
var { version: PKG_VERSION } = require2("../package.json");
|
|
@@ -706,283 +971,6 @@ function output(value, asJson = false) {
|
|
|
706
971
|
function asThreadType(groupFlag) {
|
|
707
972
|
return groupFlag ? ThreadType.Group : ThreadType.User;
|
|
708
973
|
}
|
|
709
|
-
function parseTextStyles(input) {
|
|
710
|
-
const tagColorMap = {
|
|
711
|
-
red: TextStyle.Red,
|
|
712
|
-
orange: TextStyle.Orange,
|
|
713
|
-
yellow: TextStyle.Yellow,
|
|
714
|
-
green: TextStyle.Green,
|
|
715
|
-
small: TextStyle.Small,
|
|
716
|
-
big: TextStyle.Big,
|
|
717
|
-
underline: TextStyle.Underline
|
|
718
|
-
};
|
|
719
|
-
const tagNames = Object.keys(tagColorMap).join("|");
|
|
720
|
-
const tagRegex = new RegExp(`\\{(${tagNames})\\}([\\s\\S]+?)\\{/\\1\\}`, "g");
|
|
721
|
-
const tagSlots = [];
|
|
722
|
-
const maskedInput = input.replace(tagRegex, (_m, tagName, inner) => {
|
|
723
|
-
const idx = tagSlots.length;
|
|
724
|
-
const placeholder = `TAG${idx}`;
|
|
725
|
-
tagSlots.push({ placeholder, tagName, innerMd: inner });
|
|
726
|
-
return placeholder;
|
|
727
|
-
});
|
|
728
|
-
const tokens = marked.lexer(maskedInput);
|
|
729
|
-
const styles = [];
|
|
730
|
-
let text = "";
|
|
731
|
-
function emitLineStyles(lineStart, lineLen, lineStyles) {
|
|
732
|
-
if (lineLen <= 0) return;
|
|
733
|
-
for (const ls of lineStyles) {
|
|
734
|
-
if (ls.style === TextStyle.Indent) {
|
|
735
|
-
styles.push({ start: lineStart, len: lineLen, st: ls.style, indentSize: ls.indentSize });
|
|
736
|
-
} else {
|
|
737
|
-
styles.push({ start: lineStart, len: lineLen, st: ls.style });
|
|
738
|
-
}
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
function walkInline(tokens2, inheritedStyles) {
|
|
742
|
-
for (const tok of tokens2) {
|
|
743
|
-
switch (tok.type) {
|
|
744
|
-
case "text": {
|
|
745
|
-
const t = tok;
|
|
746
|
-
if (t.tokens && t.tokens.length > 0) {
|
|
747
|
-
walkInline(t.tokens, inheritedStyles);
|
|
748
|
-
} else {
|
|
749
|
-
const start = text.length;
|
|
750
|
-
text += t.text;
|
|
751
|
-
const len = t.text.length;
|
|
752
|
-
if (len > 0) {
|
|
753
|
-
for (const st of inheritedStyles) {
|
|
754
|
-
styles.push({ start, len, st });
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
}
|
|
758
|
-
break;
|
|
759
|
-
}
|
|
760
|
-
case "strong": {
|
|
761
|
-
const t = tok;
|
|
762
|
-
walkInline(t.tokens, [...inheritedStyles, TextStyle.Bold]);
|
|
763
|
-
break;
|
|
764
|
-
}
|
|
765
|
-
case "em": {
|
|
766
|
-
const t = tok;
|
|
767
|
-
walkInline(t.tokens, [...inheritedStyles, TextStyle.Italic]);
|
|
768
|
-
break;
|
|
769
|
-
}
|
|
770
|
-
case "del": {
|
|
771
|
-
const t = tok;
|
|
772
|
-
walkInline(t.tokens, [...inheritedStyles, TextStyle.StrikeThrough]);
|
|
773
|
-
break;
|
|
774
|
-
}
|
|
775
|
-
case "codespan": {
|
|
776
|
-
const t = tok;
|
|
777
|
-
const start = text.length;
|
|
778
|
-
text += t.text;
|
|
779
|
-
const len = t.text.length;
|
|
780
|
-
if (len > 0) {
|
|
781
|
-
for (const st of inheritedStyles) {
|
|
782
|
-
styles.push({ start, len, st });
|
|
783
|
-
}
|
|
784
|
-
}
|
|
785
|
-
break;
|
|
786
|
-
}
|
|
787
|
-
case "escape": {
|
|
788
|
-
const t = tok;
|
|
789
|
-
const start = text.length;
|
|
790
|
-
text += t.text;
|
|
791
|
-
if (t.text.length > 0) {
|
|
792
|
-
for (const st of inheritedStyles) {
|
|
793
|
-
styles.push({ start, len: t.text.length, st });
|
|
794
|
-
}
|
|
795
|
-
}
|
|
796
|
-
break;
|
|
797
|
-
}
|
|
798
|
-
case "link": {
|
|
799
|
-
const t = tok;
|
|
800
|
-
walkInline(t.tokens, inheritedStyles);
|
|
801
|
-
break;
|
|
802
|
-
}
|
|
803
|
-
case "image": {
|
|
804
|
-
const t = tok;
|
|
805
|
-
const start = text.length;
|
|
806
|
-
text += t.text;
|
|
807
|
-
if (t.text.length > 0) {
|
|
808
|
-
for (const st of inheritedStyles) {
|
|
809
|
-
styles.push({ start, len: t.text.length, st });
|
|
810
|
-
}
|
|
811
|
-
}
|
|
812
|
-
break;
|
|
813
|
-
}
|
|
814
|
-
case "br": {
|
|
815
|
-
text += "\n";
|
|
816
|
-
break;
|
|
817
|
-
}
|
|
818
|
-
case "checkbox": {
|
|
819
|
-
const t = tok;
|
|
820
|
-
text += t.checked ? "[x] " : "[ ] ";
|
|
821
|
-
break;
|
|
822
|
-
}
|
|
823
|
-
default: {
|
|
824
|
-
const t = tok;
|
|
825
|
-
if (t.tokens && t.tokens.length > 0) {
|
|
826
|
-
walkInline(t.tokens, inheritedStyles);
|
|
827
|
-
} else if (t.text != null) {
|
|
828
|
-
const start = text.length;
|
|
829
|
-
text += t.text;
|
|
830
|
-
if (t.text.length > 0) {
|
|
831
|
-
for (const st of inheritedStyles) {
|
|
832
|
-
styles.push({ start, len: t.text.length, st });
|
|
833
|
-
}
|
|
834
|
-
}
|
|
835
|
-
}
|
|
836
|
-
break;
|
|
837
|
-
}
|
|
838
|
-
}
|
|
839
|
-
}
|
|
840
|
-
}
|
|
841
|
-
function walkBlock(tokens2, blockLineStyles, depth) {
|
|
842
|
-
for (let ti = 0; ti < tokens2.length; ti++) {
|
|
843
|
-
const tok = tokens2[ti];
|
|
844
|
-
switch (tok.type) {
|
|
845
|
-
case "heading": {
|
|
846
|
-
const t = tok;
|
|
847
|
-
const headingStyles = [{ style: TextStyle.Bold }];
|
|
848
|
-
if (t.depth === 1) headingStyles.push({ style: TextStyle.Big });
|
|
849
|
-
else if (t.depth === 3 || t.depth === 4) headingStyles.push({ style: TextStyle.Small });
|
|
850
|
-
if (t.depth <= 4) {
|
|
851
|
-
const lineStart = text.length;
|
|
852
|
-
walkInline(t.tokens, []);
|
|
853
|
-
const lineLen = text.length - lineStart;
|
|
854
|
-
emitLineStyles(lineStart, lineLen, [...blockLineStyles, ...headingStyles]);
|
|
855
|
-
text += "\n";
|
|
856
|
-
} else {
|
|
857
|
-
const lineStart = text.length;
|
|
858
|
-
text += "#".repeat(t.depth) + " ";
|
|
859
|
-
walkInline(t.tokens, []);
|
|
860
|
-
const lineLen = text.length - lineStart;
|
|
861
|
-
emitLineStyles(lineStart, lineLen, blockLineStyles);
|
|
862
|
-
text += "\n";
|
|
863
|
-
}
|
|
864
|
-
break;
|
|
865
|
-
}
|
|
866
|
-
case "paragraph": {
|
|
867
|
-
const t = tok;
|
|
868
|
-
const lineStart = text.length;
|
|
869
|
-
walkInline(t.tokens, []);
|
|
870
|
-
const lineLen = text.length - lineStart;
|
|
871
|
-
emitLineStyles(lineStart, lineLen, blockLineStyles);
|
|
872
|
-
text += "\n";
|
|
873
|
-
break;
|
|
874
|
-
}
|
|
875
|
-
case "code": {
|
|
876
|
-
const t = tok;
|
|
877
|
-
text += t.text;
|
|
878
|
-
text += "\n";
|
|
879
|
-
break;
|
|
880
|
-
}
|
|
881
|
-
case "blockquote": {
|
|
882
|
-
const t = tok;
|
|
883
|
-
const bqDepth = depth + 1;
|
|
884
|
-
walkBlock(t.tokens, [...blockLineStyles, { style: TextStyle.Indent, indentSize: Math.min(5, bqDepth) }], bqDepth);
|
|
885
|
-
break;
|
|
886
|
-
}
|
|
887
|
-
case "list": {
|
|
888
|
-
const t = tok;
|
|
889
|
-
const listStyle = t.ordered ? TextStyle.OrderedList : TextStyle.UnorderedList;
|
|
890
|
-
for (const item of t.items) {
|
|
891
|
-
if (item.task) {
|
|
892
|
-
const lineStart = text.length;
|
|
893
|
-
text += item.checked ? "[x] " : "[ ] ";
|
|
894
|
-
const nonCheckboxTokens = item.tokens.filter((t2) => t2.type !== "checkbox");
|
|
895
|
-
walkInline(nonCheckboxTokens, []);
|
|
896
|
-
const lineLen = text.length - lineStart;
|
|
897
|
-
emitLineStyles(lineStart, lineLen, blockLineStyles);
|
|
898
|
-
text += "\n";
|
|
899
|
-
} else {
|
|
900
|
-
const hasSubList = item.tokens.some((t2) => t2.type === "list");
|
|
901
|
-
if (hasSubList) {
|
|
902
|
-
const inlineTokens = item.tokens.filter((t2) => t2.type !== "list");
|
|
903
|
-
const subLists = item.tokens.filter((t2) => t2.type === "list");
|
|
904
|
-
if (inlineTokens.length > 0) {
|
|
905
|
-
const lineStart = text.length;
|
|
906
|
-
walkInline(inlineTokens, []);
|
|
907
|
-
const lineLen = text.length - lineStart;
|
|
908
|
-
emitLineStyles(lineStart, lineLen, [...blockLineStyles, { style: listStyle }]);
|
|
909
|
-
text += "\n";
|
|
910
|
-
}
|
|
911
|
-
const subIndent = Math.min(5, depth + 1);
|
|
912
|
-
walkBlock(subLists, [...blockLineStyles, { style: TextStyle.Indent, indentSize: subIndent }], depth + 1);
|
|
913
|
-
} else {
|
|
914
|
-
const lineStart = text.length;
|
|
915
|
-
walkInline(item.tokens, []);
|
|
916
|
-
const lineLen = text.length - lineStart;
|
|
917
|
-
emitLineStyles(lineStart, lineLen, [...blockLineStyles, { style: listStyle }]);
|
|
918
|
-
text += "\n";
|
|
919
|
-
}
|
|
920
|
-
}
|
|
921
|
-
}
|
|
922
|
-
break;
|
|
923
|
-
}
|
|
924
|
-
case "hr": {
|
|
925
|
-
text += "---\n";
|
|
926
|
-
break;
|
|
927
|
-
}
|
|
928
|
-
case "html": {
|
|
929
|
-
const t = tok;
|
|
930
|
-
text += t.text;
|
|
931
|
-
break;
|
|
932
|
-
}
|
|
933
|
-
case "text": {
|
|
934
|
-
const t = tok;
|
|
935
|
-
const lineStart = text.length;
|
|
936
|
-
if (t.tokens && t.tokens.length > 0) {
|
|
937
|
-
walkInline(t.tokens, []);
|
|
938
|
-
} else {
|
|
939
|
-
text += t.text;
|
|
940
|
-
}
|
|
941
|
-
const lineLen = text.length - lineStart;
|
|
942
|
-
emitLineStyles(lineStart, lineLen, blockLineStyles);
|
|
943
|
-
text += "\n";
|
|
944
|
-
break;
|
|
945
|
-
}
|
|
946
|
-
case "space": {
|
|
947
|
-
break;
|
|
948
|
-
}
|
|
949
|
-
default: {
|
|
950
|
-
const t = tok;
|
|
951
|
-
if (t.raw) text += t.raw;
|
|
952
|
-
break;
|
|
953
|
-
}
|
|
954
|
-
}
|
|
955
|
-
}
|
|
956
|
-
}
|
|
957
|
-
walkBlock(tokens, [], 0);
|
|
958
|
-
if (text.endsWith("\n")) {
|
|
959
|
-
text = text.slice(0, -1);
|
|
960
|
-
}
|
|
961
|
-
for (const slot of tagSlots) {
|
|
962
|
-
const phIdx = text.indexOf(slot.placeholder);
|
|
963
|
-
if (phIdx === -1) continue;
|
|
964
|
-
const inner = parseTextStyles(slot.innerMd);
|
|
965
|
-
const replacement = inner.text;
|
|
966
|
-
const phLen = slot.placeholder.length;
|
|
967
|
-
text = text.slice(0, phIdx) + replacement + text.slice(phIdx + phLen);
|
|
968
|
-
const delta = replacement.length - phLen;
|
|
969
|
-
for (const s of styles) {
|
|
970
|
-
if (s.start >= phIdx + phLen) {
|
|
971
|
-
s.start += delta;
|
|
972
|
-
} else if (s.start + s.len > phIdx) {
|
|
973
|
-
s.len += delta;
|
|
974
|
-
}
|
|
975
|
-
}
|
|
976
|
-
const tagStyle = tagColorMap[slot.tagName];
|
|
977
|
-
if (tagStyle) {
|
|
978
|
-
styles.push({ start: phIdx, len: replacement.length, st: tagStyle });
|
|
979
|
-
}
|
|
980
|
-
for (const is of inner.styles) {
|
|
981
|
-
styles.push({ start: phIdx + is.start, len: is.len, st: is.st, ..."indentSize" in is ? { indentSize: is.indentSize } : {} });
|
|
982
|
-
}
|
|
983
|
-
}
|
|
984
|
-
return { text, styles };
|
|
985
|
-
}
|
|
986
974
|
function parseBooleanFromEnv(name, fallback) {
|
|
987
975
|
const raw = process.env[name]?.trim();
|
|
988
976
|
if (!raw) return fallback;
|
|
@@ -3166,7 +3154,7 @@ auth.command("cache-clear").description("Clear local cache").action(
|
|
|
3166
3154
|
})
|
|
3167
3155
|
);
|
|
3168
3156
|
var msg = program.command("msg").description("Messaging commands");
|
|
3169
|
-
msg.command("send <threadId> <message>").option("-g, --group", "Send to group").option("--raw", "Send raw text without parsing formatting markers").description("Send text message with formatting (**bold** *italic*
|
|
3157
|
+
msg.command("send <threadId> <message>").option("-g, --group", "Send to group").option("--raw", "Send raw text without parsing formatting markers").description("Send text message with formatting (**bold** *italic* __bold__ ~~strike~~ {underline}text{/underline} {red}color{/red} {big}size{/big} lists indents)").action(
|
|
3170
3158
|
wrapAction(async (threadId, message, opts, command) => {
|
|
3171
3159
|
const { api } = await requireApi(command);
|
|
3172
3160
|
if (opts.raw) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "openzca",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.38",
|
|
4
4
|
"description": "Open-source zca-compatible CLI to integrate Zalo with OpenClaw",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -44,7 +44,6 @@
|
|
|
44
44
|
"@types/qrcode-terminal": "^0.12.2",
|
|
45
45
|
"commander": "^14.0.3",
|
|
46
46
|
"image-size": "^2.0.2",
|
|
47
|
-
"marked": "^17.0.4",
|
|
48
47
|
"qrcode-terminal": "^0.12.0",
|
|
49
48
|
"zca-js": "^2.0.4"
|
|
50
49
|
},
|