tryscript 0.1.5 → 0.1.7

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.
@@ -37,6 +37,7 @@ let tree_kill = require("tree-kill");
37
37
  tree_kill = __toESM(tree_kill);
38
38
  let strip_ansi = require("strip-ansi");
39
39
  strip_ansi = __toESM(strip_ansi);
40
+ let atomically = require("atomically");
40
41
 
41
42
  //#region src/lib/config.ts
42
43
  /** Default coverage configuration values. */
@@ -66,7 +67,8 @@ function resolveCoverageConfig(config) {
66
67
  skipFull: config?.skipFull ?? DEFAULT_COVERAGE_CONFIG.skipFull,
67
68
  allowExternal: config?.allowExternal ?? DEFAULT_COVERAGE_CONFIG.allowExternal,
68
69
  src: config?.src ?? DEFAULT_COVERAGE_CONFIG.src,
69
- monocart: config?.monocart ?? DEFAULT_COVERAGE_CONFIG.monocart
70
+ monocart: config?.monocart ?? DEFAULT_COVERAGE_CONFIG.monocart,
71
+ mergeLcov: config?.mergeLcov
70
72
  };
71
73
  }
72
74
  const CONFIG_FILES = [
@@ -119,8 +121,6 @@ function defineConfig(config) {
119
121
  //#region src/lib/parser.ts
120
122
  /** Regex to match YAML frontmatter at the start of a file */
121
123
  const FRONTMATTER_REGEX = /^---\r?\n([\s\S]*?)\r?\n---\r?\n/;
122
- /** Regex to match fenced code blocks with console/bash info string */
123
- const CODE_BLOCK_REGEX = /```(console|bash)\r?\n([\s\S]*?)```/g;
124
124
  /** Regex to match markdown headings (for test names) */
125
125
  const HEADING_REGEX = /^#+\s+(?:Test:\s*)?(.+)$/m;
126
126
  /** Regex to match skip annotation in heading or nearby HTML comment */
@@ -128,6 +128,55 @@ const SKIP_ANNOTATION_REGEX = /<!--\s*skip\s*-->/i;
128
128
  /** Regex to match only annotation in heading or nearby HTML comment */
129
129
  const ONLY_ANNOTATION_REGEX = /<!--\s*only\s*-->/i;
130
130
  /**
131
+ * Find console/bash fenced code blocks, supporting extended fences (4+ backticks).
132
+ *
133
+ * Extended fences allow embedding triple-backtick blocks in expected output.
134
+ * A closing fence must have at least as many backticks as the opening fence
135
+ * (per CommonMark spec).
136
+ */
137
+ function findConsoleCodeBlocks(text) {
138
+ const results = [];
139
+ const lines = text.split("\n");
140
+ const offsets = new Array(lines.length);
141
+ offsets[0] = 0;
142
+ for (let j = 1; j < lines.length; j++) offsets[j] = offsets[j - 1] + lines[j - 1].length + 1;
143
+ let i = 0;
144
+ while (i < lines.length) {
145
+ const line = lines[i];
146
+ const trimmed = line.endsWith("\r") ? line.slice(0, -1) : line;
147
+ const openMatch = /^(`{3,})(console|bash)\s*$/.exec(trimmed);
148
+ if (!openMatch) {
149
+ i++;
150
+ continue;
151
+ }
152
+ const fenceLen = openMatch[1].length;
153
+ const infoString = openMatch[2];
154
+ const openLineIdx = i;
155
+ const closingRe = /* @__PURE__ */ new RegExp(`^\`{${fenceLen},}\\s*$`);
156
+ i++;
157
+ while (i < lines.length) {
158
+ const cur = lines[i];
159
+ const curTrimmed = cur.endsWith("\r") ? cur.slice(0, -1) : cur;
160
+ if (closingRe.test(curTrimmed)) {
161
+ const startOffset = offsets[openLineIdx];
162
+ const endOffset = offsets[i] + lines[i].length;
163
+ const contentStart = offsets[openLineIdx + 1];
164
+ const contentEnd = offsets[i];
165
+ results.push({
166
+ fullMatch: text.slice(startOffset, endOffset),
167
+ infoString,
168
+ content: text.slice(contentStart, contentEnd),
169
+ index: startOffset
170
+ });
171
+ i++;
172
+ break;
173
+ }
174
+ i++;
175
+ }
176
+ }
177
+ return results;
178
+ }
179
+ /**
131
180
  * Parse a .tryscript.md file into structured test data.
132
181
  */
133
182
  function parseTestFile(content, filePath) {
@@ -140,12 +189,11 @@ function parseTestFile(content, filePath) {
140
189
  body = content.slice(frontmatterMatch[0].length);
141
190
  }
142
191
  const blocks = [];
143
- CODE_BLOCK_REGEX.lastIndex = 0;
144
- let match;
145
- while ((match = CODE_BLOCK_REGEX.exec(body)) !== null) {
146
- const blockContent = match[2] ?? "";
147
- const blockStart = match.index;
148
- const lineNumber = content.slice(0, content.indexOf(match[0])).split("\n").length;
192
+ const codeBlocks = findConsoleCodeBlocks(body);
193
+ for (const codeBlock of codeBlocks) {
194
+ const blockContent = codeBlock.content;
195
+ const blockStart = codeBlock.index;
196
+ const lineNumber = content.slice(0, content.indexOf(codeBlock.fullMatch)).split("\n").length;
149
197
  const contentBefore = body.slice(0, blockStart);
150
198
  const lastHeadingMatch = [...contentBefore.matchAll(new RegExp(HEADING_REGEX.source, "gm"))].pop();
151
199
  const name = lastHeadingMatch?.[1]?.trim();
@@ -160,7 +208,7 @@ function parseTestFile(content, filePath) {
160
208
  expectedStderr: parsed.expectedStderr,
161
209
  expectedExitCode: parsed.expectedExitCode,
162
210
  lineNumber,
163
- rawContent: match[0],
211
+ rawContent: codeBlock.fullMatch,
164
212
  skip,
165
213
  only
166
214
  });
@@ -535,9 +583,15 @@ function patternToRegex(expected, customPatterns = {}) {
535
583
  const dotdotMarker = getMarker();
536
584
  replacements.set(dotdotMarker, "[^\\n]*");
537
585
  processed = processed.replaceAll("[..]", dotdotMarker);
586
+ const unknownDotdotMarker = getMarker();
587
+ replacements.set(unknownDotdotMarker, "[^\\n]*");
588
+ processed = processed.replaceAll("[??]", unknownDotdotMarker);
538
589
  const ellipsisMarker = getMarker();
539
590
  replacements.set(ellipsisMarker, "(?:[^\\n]*\\n)*");
540
591
  processed = processed.replace(/\.\.\.\n/g, ellipsisMarker);
592
+ const unknownEllipsisMarker = getMarker();
593
+ replacements.set(unknownEllipsisMarker, "(?:[^\\n]*\\n)*");
594
+ processed = processed.replace(/\?\?\?\n/g, unknownEllipsisMarker);
541
595
  const exeMarker = getMarker();
542
596
  const exe = process.platform === "win32" ? "\\.exe" : "";
543
597
  replacements.set(exeMarker, exe);
@@ -580,6 +634,82 @@ function normalizeOutput(output) {
580
634
  return normalized;
581
635
  }
582
636
  /**
637
+ * Like `patternToRegex()` but wraps each wildcard in a capturing group and
638
+ * returns metadata describing what each group represents.
639
+ *
640
+ * Each occurrence gets a unique marker so that the `groups` array is ordered
641
+ * by position in the string, matching the regex capture group indices.
642
+ */
643
+ function patternToCapturingRegex(expected, customPatterns = {}) {
644
+ const replacements = /* @__PURE__ */ new Map();
645
+ const markerMeta = /* @__PURE__ */ new Map();
646
+ let markerIndex = 0;
647
+ const getMarker = () => {
648
+ return `${MARKER}${markerIndex++}${MARKER}`;
649
+ };
650
+ const replaceEach = (processed$1, pattern, regexStr, meta) => {
651
+ let result = processed$1;
652
+ if (typeof pattern === "string") while (result.includes(pattern)) {
653
+ const marker = getMarker();
654
+ replacements.set(marker, regexStr);
655
+ markerMeta.set(marker, meta);
656
+ result = result.replace(pattern, marker);
657
+ }
658
+ else {
659
+ let m;
660
+ while ((m = pattern.exec(result)) !== null) {
661
+ const marker = getMarker();
662
+ replacements.set(marker, regexStr);
663
+ markerMeta.set(marker, meta);
664
+ result = result.slice(0, m.index) + marker + result.slice(m.index + m[0].length);
665
+ }
666
+ }
667
+ return result;
668
+ };
669
+ let processed = expected;
670
+ processed = replaceEach(processed, "[..]", "([^\\n]*)", {
671
+ category: "generic",
672
+ multiline: false
673
+ });
674
+ processed = replaceEach(processed, "[??]", "([^\\n]*)", {
675
+ category: "unknown",
676
+ multiline: false
677
+ });
678
+ processed = replaceEach(processed, /\.\.\.\n/, "((?:[^\\n]*\\n)*)", {
679
+ category: "generic",
680
+ multiline: true
681
+ });
682
+ processed = replaceEach(processed, /\?\?\?\n/, "((?:[^\\n]*\\n)*)", {
683
+ category: "unknown",
684
+ multiline: true
685
+ });
686
+ const exe = process.platform === "win32" ? "\\.exe" : "";
687
+ processed = replaceEach(processed, "[EXE]", exe, null);
688
+ for (const [name, pattern] of Object.entries(customPatterns)) {
689
+ const placeholder = `[${name}]`;
690
+ const patternStr = pattern instanceof RegExp ? pattern.source : pattern;
691
+ processed = replaceEach(processed, placeholder, `(${patternStr})`, {
692
+ category: "named",
693
+ name,
694
+ multiline: false
695
+ });
696
+ }
697
+ const sortedEntries = [...replacements.entries()].sort((a, b) => {
698
+ return processed.indexOf(a[0]) - processed.indexOf(b[0]);
699
+ });
700
+ let regex = escapeRegex(processed);
701
+ const groups = [];
702
+ for (const [marker, replacement] of sortedEntries) {
703
+ const meta = markerMeta.get(marker);
704
+ if (meta) groups.push(meta);
705
+ regex = regex.replaceAll(escapeRegex(marker), replacement);
706
+ }
707
+ return {
708
+ regex: new RegExp(`^${regex}$`, "s"),
709
+ groups
710
+ };
711
+ }
712
+ /**
583
713
  * Check if actual output matches expected pattern.
584
714
  */
585
715
  function matchOutput(actual, expected, context, customPatterns = {}) {
@@ -588,10 +718,307 @@ function matchOutput(actual, expected, context, customPatterns = {}) {
588
718
  if (normalizedExpected === "" && normalizedActual === "") return true;
589
719
  return patternToRegex(preprocessPaths(normalizedExpected, context), customPatterns).test(normalizedActual);
590
720
  }
721
+ /**
722
+ * Match actual output against expected pattern and return wildcard captures.
723
+ * Returns `null` if the output does not match.
724
+ */
725
+ function matchAndCapture(actual, expected, context, customPatterns = {}) {
726
+ const normalizedActual = normalizeOutput(actual);
727
+ const normalizedExpected = normalizeOutput(expected);
728
+ if (normalizedExpected === "" && normalizedActual === "") return { captures: [] };
729
+ const { regex, groups } = patternToCapturingRegex(preprocessPaths(normalizedExpected, context), customPatterns);
730
+ const match = regex.exec(normalizedActual);
731
+ if (!match) return null;
732
+ return { captures: groups.map((meta, i) => ({
733
+ category: meta.category,
734
+ name: meta.name,
735
+ multiline: meta.multiline,
736
+ captured: match[i + 1] ?? ""
737
+ })) };
738
+ }
739
+
740
+ //#endregion
741
+ //#region src/lib/expander.ts
742
+ /**
743
+ * Whether a wildcard category should be expanded at the given level.
744
+ *
745
+ * The hierarchy is: unknown < generic < all.
746
+ */
747
+ function shouldExpandCategory(category, level) {
748
+ switch (level) {
749
+ case "unknown": return category === "unknown";
750
+ case "generic": return category === "unknown" || category === "generic";
751
+ case "all": return true;
752
+ }
753
+ }
754
+ const WILDCARD_TOKENS = [
755
+ {
756
+ token: "[..]",
757
+ category: "generic",
758
+ multiline: false
759
+ },
760
+ {
761
+ token: "[??]",
762
+ category: "unknown",
763
+ multiline: false
764
+ },
765
+ {
766
+ token: /\.\.\.\n/,
767
+ category: "generic",
768
+ multiline: true
769
+ },
770
+ {
771
+ token: /\?\?\?\n/,
772
+ category: "unknown",
773
+ multiline: true
774
+ }
775
+ ];
776
+ /**
777
+ * Expand wildcards in expected output by replacing them with captured actual text.
778
+ *
779
+ * Only wildcards whose category is targeted by `level` are replaced; others are
780
+ * left intact. Returns `null` if actual output doesn't match expected pattern.
781
+ */
782
+ function expandExpectedOutput(expected, actual, context, level, customPatterns) {
783
+ const normalizedExpected = normalizeOutput(expected);
784
+ const normalizedActual = normalizeOutput(actual);
785
+ if (normalizedExpected === "" && normalizedActual === "") return {
786
+ expandedOutput: "",
787
+ captures: [],
788
+ expandedCount: 0
789
+ };
790
+ const result = matchAndCapture(actual, expected, context, customPatterns);
791
+ if (!result) return null;
792
+ let output = normalizedExpected;
793
+ let expandedCount = 0;
794
+ const tokenPositions = [];
795
+ for (const wt of WILDCARD_TOKENS) {
796
+ let searchFrom = 0;
797
+ if (typeof wt.token === "string") while (true) {
798
+ const pos = output.indexOf(wt.token, searchFrom);
799
+ if (pos === -1) break;
800
+ tokenPositions.push({
801
+ pos,
802
+ length: wt.token.length
803
+ });
804
+ searchFrom = pos + wt.token.length;
805
+ }
806
+ else {
807
+ const re = new RegExp(wt.token.source, "g");
808
+ let m;
809
+ while ((m = re.exec(output)) !== null) tokenPositions.push({
810
+ pos: m.index,
811
+ length: m[0].length
812
+ });
813
+ }
814
+ }
815
+ if (customPatterns) for (const name of Object.keys(customPatterns)) {
816
+ const placeholder = `[${name}]`;
817
+ let searchFrom = 0;
818
+ while (true) {
819
+ const pos = output.indexOf(placeholder, searchFrom);
820
+ if (pos === -1) break;
821
+ tokenPositions.push({
822
+ pos,
823
+ length: placeholder.length
824
+ });
825
+ searchFrom = pos + placeholder.length;
826
+ }
827
+ }
828
+ tokenPositions.sort((a, b) => a.pos - b.pos);
829
+ const replacements = tokenPositions.map((tp, i) => ({
830
+ ...tp,
831
+ capture: result.captures[i]
832
+ }));
833
+ for (let i = replacements.length - 1; i >= 0; i--) {
834
+ const r = replacements[i];
835
+ if (shouldExpandCategory(r.capture.category, level)) {
836
+ const replacement = r.capture.captured;
837
+ output = output.slice(0, r.pos) + replacement + output.slice(r.pos + r.length);
838
+ expandedCount++;
839
+ }
840
+ }
841
+ return {
842
+ expandedOutput: output,
843
+ captures: result.captures,
844
+ expandedCount
845
+ };
846
+ }
847
+ /**
848
+ * Expand wildcards in a test file in place.
849
+ *
850
+ * Uses the same reverse-order strategy as `updater.ts` to maintain correct
851
+ * string offsets when modifying multiple blocks.
852
+ */
853
+ async function expandTestFile(file, results, level, context, customPatterns) {
854
+ let content = file.rawContent;
855
+ const changes = [];
856
+ let totalExpanded = 0;
857
+ const resultByBlock = new Map(results.map((result) => [result.block, result]));
858
+ const blocksWithResults = [...file.blocks].map((block) => ({
859
+ block,
860
+ result: resultByBlock.get(block)
861
+ })).reverse();
862
+ for (const { block, result } of blocksWithResults) {
863
+ if (!result || !block.expectedOutput) continue;
864
+ const expansion = expandExpectedOutput(block.expectedOutput, result.actualOutput, context, level, customPatterns);
865
+ if (!expansion || expansion.expandedCount === 0) continue;
866
+ const fence = "`".repeat(/^(`+)/.exec(block.rawContent)?.[1]?.length ?? 3);
867
+ const commandLines = block.command.split("\n").map((line, i) => {
868
+ return i === 0 ? `$ ${line}` : `> ${line}`;
869
+ });
870
+ const lines = [`${fence}console`, ...commandLines];
871
+ const trimmedOutput = expansion.expandedOutput.trimEnd();
872
+ if (trimmedOutput) lines.push(trimmedOutput);
873
+ lines.push(`? ${block.expectedExitCode ?? result.actualExitCode}`, fence);
874
+ const newBlockContent = lines.join("\n");
875
+ const blockStart = content.indexOf(block.rawContent);
876
+ if (blockStart !== -1) {
877
+ content = content.slice(0, blockStart) + newBlockContent + content.slice(blockStart + block.rawContent.length);
878
+ changes.push(block.name ?? `Line ${block.lineNumber}`);
879
+ totalExpanded += expansion.expandedCount;
880
+ }
881
+ }
882
+ if (changes.length > 0) await (0, atomically.writeFile)(file.path, content);
883
+ return {
884
+ expanded: changes.length > 0,
885
+ expandedCount: totalExpanded,
886
+ changes
887
+ };
888
+ }
889
+
890
+ //#endregion
891
+ //#region src/lib/yaml-utils.ts
892
+ /**
893
+ * Manual key order comparator for YAML `sortMapEntries`.
894
+ *
895
+ * Keys listed in `order` appear first (in that order); unlisted keys sort
896
+ * to the end alphabetically. Adapted from tbd sorting patterns
897
+ * (`ordering.manual`).
898
+ */
899
+ function manualKeyOrder(order) {
900
+ const orderMap = new Map(order.map((key, index) => [key, index]));
901
+ return (a, b) => {
902
+ const indexA = orderMap.get(a.key.value);
903
+ const indexB = orderMap.get(b.key.value);
904
+ if (indexA === void 0 && indexB === void 0) return a.key.value.localeCompare(b.key.value);
905
+ if (indexA === void 0) return 1;
906
+ if (indexB === void 0) return -1;
907
+ return indexA - indexB;
908
+ };
909
+ }
910
+ const DEFAULT_YAML_LINE_WIDTH = 88;
911
+ const YAML_STRINGIFY_OPTIONS = {
912
+ lineWidth: DEFAULT_YAML_LINE_WIDTH,
913
+ defaultStringType: "PLAIN",
914
+ defaultKeyType: "PLAIN"
915
+ };
916
+ function stringifyYaml(data, options) {
917
+ return (0, yaml.stringify)(data, {
918
+ ...YAML_STRINGIFY_OPTIONS,
919
+ ...options
920
+ });
921
+ }
922
+
923
+ //#endregion
924
+ //#region src/lib/capture-log.ts
925
+ const TOP_LEVEL_ORDER = manualKeyOrder(["generated", "files"]);
926
+ const FILE_ORDER = manualKeyOrder(["path", "blocks"]);
927
+ const BLOCK_ORDER = manualKeyOrder([
928
+ "name",
929
+ "command",
930
+ "expected_exit_code",
931
+ "actual_exit_code",
932
+ "expected_output",
933
+ "actual_output",
934
+ "captures",
935
+ "passed"
936
+ ]);
937
+ const CAPTURE_ORDER = manualKeyOrder([
938
+ "category",
939
+ "name",
940
+ "multiline",
941
+ "matched"
942
+ ]);
943
+ /**
944
+ * Sort comparator for `yaml.stringify`'s `sortMapEntries`.
945
+ *
946
+ * Dispatches to the correct field ordering based on which keys are present,
947
+ * since the `yaml` package calls this for every map node in the document.
948
+ */
949
+ const BLOCK_KEYS = new Set([
950
+ "name",
951
+ "command",
952
+ "expected_exit_code",
953
+ "actual_exit_code",
954
+ "expected_output",
955
+ "actual_output",
956
+ "captures",
957
+ "passed"
958
+ ]);
959
+ const CAPTURE_KEYS = new Set([
960
+ "category",
961
+ "name",
962
+ "multiline",
963
+ "matched"
964
+ ]);
965
+ function captureLogSortMapEntries(a, b) {
966
+ const aKey = a.key.value;
967
+ const bKey = b.key.value;
968
+ if (aKey === "generated" || aKey === "files" || bKey === "generated" || bKey === "files") return TOP_LEVEL_ORDER(a, b);
969
+ if (aKey === "blocks" || bKey === "blocks") return FILE_ORDER(a, b);
970
+ if (BLOCK_KEYS.has(aKey) && BLOCK_KEYS.has(bKey)) return BLOCK_ORDER(a, b);
971
+ if (CAPTURE_KEYS.has(aKey) && CAPTURE_KEYS.has(bKey)) return CAPTURE_ORDER(a, b);
972
+ return aKey.localeCompare(bKey);
973
+ }
974
+ /**
975
+ * Build the capture log document structure from test results.
976
+ *
977
+ * `customPatterns` can be a static object or a per-file callback.
978
+ * Separated from `writeCaptureLog` for testability.
979
+ */
980
+ function buildCaptureLogDoc(fileResults, matchContext, customPatterns) {
981
+ const files = fileResults.map((fr) => {
982
+ const ctx = matchContext(fr.file);
983
+ const patterns = typeof customPatterns === "function" ? customPatterns(fr.file) : customPatterns;
984
+ const blocks = fr.results.map((r) => {
985
+ const captures = (matchAndCapture(r.actualOutput, r.block.expectedOutput, ctx, patterns)?.captures ?? []).map((c) => ({
986
+ category: c.category,
987
+ ...c.name ? { name: c.name } : {},
988
+ multiline: c.multiline,
989
+ matched: c.captured
990
+ }));
991
+ return {
992
+ name: r.block.name,
993
+ command: r.block.command,
994
+ expected_exit_code: r.block.expectedExitCode,
995
+ actual_exit_code: r.actualExitCode,
996
+ expected_output: r.block.expectedOutput,
997
+ actual_output: r.actualOutput,
998
+ captures,
999
+ passed: r.passed
1000
+ };
1001
+ });
1002
+ return {
1003
+ path: fr.file.path,
1004
+ blocks
1005
+ };
1006
+ });
1007
+ return {
1008
+ generated: (/* @__PURE__ */ new Date()).toISOString(),
1009
+ files
1010
+ };
1011
+ }
1012
+ /**
1013
+ * Write a YAML capture log file recording wildcard captures and execution metadata.
1014
+ */
1015
+ async function writeCaptureLog(path, fileResults, matchContext, customPatterns) {
1016
+ await (0, atomically.writeFile)(path, "# tryscript capture log\n" + stringifyYaml(buildCaptureLogDoc(fileResults, matchContext, customPatterns), { sortMapEntries: captureLogSortMapEntries }));
1017
+ }
591
1018
 
592
1019
  //#endregion
593
1020
  //#region src/index.ts
594
- const VERSION = "0.1.5";
1021
+ const VERSION = "0.1.7";
595
1022
 
596
1023
  //#endregion
597
1024
  Object.defineProperty(exports, 'VERSION', {
@@ -606,6 +1033,12 @@ Object.defineProperty(exports, '__toESM', {
606
1033
  return __toESM;
607
1034
  }
608
1035
  });
1036
+ Object.defineProperty(exports, 'buildCaptureLogDoc', {
1037
+ enumerable: true,
1038
+ get: function () {
1039
+ return buildCaptureLogDoc;
1040
+ }
1041
+ });
609
1042
  Object.defineProperty(exports, 'cleanupExecutionContext', {
610
1043
  enumerable: true,
611
1044
  get: function () {
@@ -624,12 +1057,36 @@ Object.defineProperty(exports, 'defineConfig', {
624
1057
  return defineConfig;
625
1058
  }
626
1059
  });
1060
+ Object.defineProperty(exports, 'expandExpectedOutput', {
1061
+ enumerable: true,
1062
+ get: function () {
1063
+ return expandExpectedOutput;
1064
+ }
1065
+ });
1066
+ Object.defineProperty(exports, 'expandTestFile', {
1067
+ enumerable: true,
1068
+ get: function () {
1069
+ return expandTestFile;
1070
+ }
1071
+ });
627
1072
  Object.defineProperty(exports, 'loadConfig', {
628
1073
  enumerable: true,
629
1074
  get: function () {
630
1075
  return loadConfig;
631
1076
  }
632
1077
  });
1078
+ Object.defineProperty(exports, 'manualKeyOrder', {
1079
+ enumerable: true,
1080
+ get: function () {
1081
+ return manualKeyOrder;
1082
+ }
1083
+ });
1084
+ Object.defineProperty(exports, 'matchAndCapture', {
1085
+ enumerable: true,
1086
+ get: function () {
1087
+ return matchAndCapture;
1088
+ }
1089
+ });
633
1090
  Object.defineProperty(exports, 'matchOutput', {
634
1091
  enumerable: true,
635
1092
  get: function () {
@@ -672,4 +1129,22 @@ Object.defineProperty(exports, 'runBlock', {
672
1129
  return runBlock;
673
1130
  }
674
1131
  });
675
- //# sourceMappingURL=src-D-bd-j9T.cjs.map
1132
+ Object.defineProperty(exports, 'shouldExpandCategory', {
1133
+ enumerable: true,
1134
+ get: function () {
1135
+ return shouldExpandCategory;
1136
+ }
1137
+ });
1138
+ Object.defineProperty(exports, 'stringifyYaml', {
1139
+ enumerable: true,
1140
+ get: function () {
1141
+ return stringifyYaml;
1142
+ }
1143
+ });
1144
+ Object.defineProperty(exports, 'writeCaptureLog', {
1145
+ enumerable: true,
1146
+ get: function () {
1147
+ return writeCaptureLog;
1148
+ }
1149
+ });
1150
+ //# sourceMappingURL=src-BIZMxxIt.cjs.map