docs-coderef 0.2.0 → 0.4.0

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.
@@ -824,38 +824,219 @@ function loadDocsignorePatterns(docsignoreFile) {
824
824
  return content.split("\n").map((line) => line.trim()).filter((line) => line && !line.startsWith("#"));
825
825
  }
826
826
 
827
- // src/utils/diff-display.ts
828
- var COLORS = {
829
- RED: "\x1B[31m",
830
- GREEN: "\x1B[32m",
831
- RESET: "\x1B[0m",
832
- DIM: "\x1B[2m"
827
+ // src/utils/message-formatter.ts
828
+ var import_chalk = __toESM(require("chalk"));
829
+ var COLOR_SCHEMES = {
830
+ error: import_chalk.default.redBright,
831
+ warning: import_chalk.default.yellow,
832
+ info: import_chalk.default.cyan,
833
+ success: import_chalk.default.green,
834
+ debug: import_chalk.default.gray,
835
+ neutral: import_chalk.default.white,
836
+ // Accent colors
837
+ highlight: import_chalk.default.cyan.bold,
838
+ dim: import_chalk.default.dim,
839
+ code: import_chalk.default.yellow
840
+ };
841
+ var EMOJIS = {
842
+ error: "\u274C",
843
+ warning: "\u26A0\uFE0F",
844
+ success: "\u2705",
845
+ info: "\u2139\uFE0F",
846
+ search: "\u{1F50D}",
847
+ fix: "\u{1F527}",
848
+ file: "\u{1F4C4}",
849
+ stats: "\u{1F4CA}",
850
+ backup: "\u{1F4BE}",
851
+ skip: "\u23ED\uFE0F"
852
+ };
853
+ var MessageFormatter = class {
854
+ /**
855
+ * Set verbose mode
856
+ * @param enabled Whether verbose mode is enabled
857
+ */
858
+ static setVerbose(enabled) {
859
+ this.verboseMode = enabled;
860
+ }
861
+ /**
862
+ * Format error message
863
+ * @param text Error message text
864
+ * @returns Formatted error message with emoji and color
865
+ */
866
+ static error(text) {
867
+ return `${COLOR_SCHEMES.error(`${EMOJIS.error} ${text}`)}`;
868
+ }
869
+ /**
870
+ * Format warning message
871
+ * @param text Warning message text
872
+ * @returns Formatted warning message with emoji and color
873
+ */
874
+ static warning(text) {
875
+ return `${COLOR_SCHEMES.warning(`${EMOJIS.warning} ${text}`)}`;
876
+ }
877
+ /**
878
+ * Format info message
879
+ * @param text Info message text
880
+ * @returns Formatted info message with emoji and color
881
+ */
882
+ static info(text) {
883
+ return `${COLOR_SCHEMES.info(`${EMOJIS.info} ${text}`)}`;
884
+ }
885
+ /**
886
+ * Format success message
887
+ * @param text Success message text
888
+ * @returns Formatted success message with emoji and color
889
+ */
890
+ static success(text) {
891
+ return `${COLOR_SCHEMES.success(`${EMOJIS.success} ${text}`)}`;
892
+ }
893
+ /**
894
+ * Format debug message (only shown in verbose mode)
895
+ * @param text Debug message text
896
+ * @returns Formatted debug message if verbose mode is enabled, empty string otherwise
897
+ */
898
+ static debug(text) {
899
+ if (!this.verboseMode) {
900
+ return "";
901
+ }
902
+ return COLOR_SCHEMES.debug(text);
903
+ }
904
+ /**
905
+ * Format neutral message (no emoji, white color)
906
+ * @param text Neutral message text
907
+ * @returns Formatted neutral message
908
+ */
909
+ static neutral(text) {
910
+ return COLOR_SCHEMES.neutral(text);
911
+ }
912
+ /**
913
+ * Format error detail with type, message, and optional location
914
+ * @param type Error type (e.g., 'CODE_CONTENT_MISMATCH')
915
+ * @param message Error message
916
+ * @param location Optional file location
917
+ * @returns Formatted error detail
918
+ */
919
+ static errorDetail(type, message, location) {
920
+ const lines = [];
921
+ lines.push(this.error(`${type}: ${message}`));
922
+ if (location) {
923
+ lines.push(` ${COLOR_SCHEMES.dim(`Reference: ${location}`)}`);
924
+ }
925
+ return lines.join("\n");
926
+ }
927
+ /**
928
+ * Format summary section
929
+ * @param successful Number of successful operations
930
+ * @param failed Number of failed operations
931
+ * @param backupPaths Array of backup file paths
932
+ * @returns Formatted summary section
933
+ */
934
+ static summary(successful, failed, backupPaths) {
935
+ const lines = [];
936
+ const separator = COLOR_SCHEMES.dim("\u2501".repeat(60));
937
+ lines.push("");
938
+ lines.push(separator);
939
+ lines.push(`${EMOJIS.stats} Fix Results Summary`);
940
+ lines.push("");
941
+ lines.push(COLOR_SCHEMES.success(`${EMOJIS.success} Successful: ${successful}`));
942
+ lines.push(COLOR_SCHEMES.error(`${EMOJIS.error} Failed: ${failed}`));
943
+ if (backupPaths.length > 0) {
944
+ lines.push("");
945
+ lines.push(`${EMOJIS.backup} Backup files: ${backupPaths.length}`);
946
+ backupPaths.forEach((path6) => {
947
+ lines.push(` ${COLOR_SCHEMES.dim(path6)}`);
948
+ });
949
+ }
950
+ return lines.join("\n");
951
+ }
952
+ /**
953
+ * Format start message for fix operation
954
+ * @param text Start message text
955
+ * @returns Formatted start message with fix emoji
956
+ */
957
+ static startFix(text) {
958
+ return `${COLOR_SCHEMES.info(`${EMOJIS.fix} ${text}`)}`;
959
+ }
960
+ /**
961
+ * Format start message for validation operation
962
+ * @param text Start message text
963
+ * @returns Formatted start message with search emoji
964
+ */
965
+ static startValidation(text) {
966
+ return `${COLOR_SCHEMES.info(`${EMOJIS.search} ${text}`)}`;
967
+ }
968
+ /**
969
+ * Format file reference
970
+ * @param text File path or reference
971
+ * @returns Formatted file reference with emoji
972
+ */
973
+ static file(text) {
974
+ return `${EMOJIS.file} ${COLOR_SCHEMES.neutral(text)}`;
975
+ }
976
+ /**
977
+ * Format backup notification
978
+ * @param text Backup message text
979
+ * @returns Formatted backup message with emoji
980
+ */
981
+ static backup(text) {
982
+ return `${COLOR_SCHEMES.info(`${EMOJIS.backup} ${text}`)}`;
983
+ }
984
+ /**
985
+ * Format skip notification
986
+ * @param text Skip message text
987
+ * @returns Formatted skip message with emoji
988
+ */
989
+ static skip(text) {
990
+ return `${COLOR_SCHEMES.neutral(`${EMOJIS.skip} ${text}`)}`;
991
+ }
992
+ /**
993
+ * Format context line (indented with dim color)
994
+ * @param text Context text
995
+ * @returns Formatted context line with 3 spaces indentation
996
+ */
997
+ static context(text) {
998
+ return ` ${COLOR_SCHEMES.dim(text)}`;
999
+ }
833
1000
  };
1001
+ MessageFormatter.verboseMode = false;
1002
+ var msg = {
1003
+ error: (text) => MessageFormatter.error(text),
1004
+ warning: (text) => MessageFormatter.warning(text),
1005
+ info: (text) => MessageFormatter.info(text),
1006
+ success: (text) => MessageFormatter.success(text),
1007
+ debug: (text) => MessageFormatter.debug(text),
1008
+ neutral: (text) => MessageFormatter.neutral(text),
1009
+ errorDetail: (type, message, location) => MessageFormatter.errorDetail(type, message, location),
1010
+ summary: (successful, failed, backupPaths) => MessageFormatter.summary(successful, failed, backupPaths),
1011
+ startFix: (text) => MessageFormatter.startFix(text),
1012
+ startValidation: (text) => MessageFormatter.startValidation(text),
1013
+ file: (text) => MessageFormatter.file(text),
1014
+ backup: (text) => MessageFormatter.backup(text),
1015
+ skip: (text) => MessageFormatter.skip(text),
1016
+ context: (text) => MessageFormatter.context(text),
1017
+ setVerbose: (enabled) => MessageFormatter.setVerbose(enabled)
1018
+ };
1019
+
1020
+ // src/utils/diff-display.ts
834
1021
  function displayLineRangeDiff(code, expectedRange, actualRange) {
835
1022
  const output = [];
1023
+ output.push(COLOR_SCHEMES.dim("\u2501".repeat(64)));
836
1024
  output.push(
837
- `${COLORS.DIM}\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501${COLORS.RESET}`
838
- );
839
- output.push(
840
- `${COLORS.RED}- Expected line range: ${expectedRange.start}-${expectedRange.end}${COLORS.RESET}`
841
- );
842
- output.push(
843
- `${COLORS.GREEN}+ Actual line range: ${actualRange.start}-${actualRange.end}${COLORS.RESET}`
1025
+ COLOR_SCHEMES.error(`- Expected line range: ${expectedRange.start}-${expectedRange.end}`)
844
1026
  );
845
1027
  output.push(
846
- `${COLORS.DIM}\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501${COLORS.RESET}`
1028
+ COLOR_SCHEMES.success(`+ Actual line range: ${actualRange.start}-${actualRange.end}`)
847
1029
  );
1030
+ output.push(COLOR_SCHEMES.dim("\u2501".repeat(64)));
848
1031
  const codeLines = code.split("\n");
849
1032
  codeLines.forEach((line, index) => {
850
1033
  const expectedLineNum = expectedRange.start + index;
851
1034
  const actualLineNum = actualRange.start + index;
852
1035
  output.push(
853
- `${COLORS.RED}${expectedLineNum.toString().padStart(4)}${COLORS.RESET} | ${COLORS.GREEN}${actualLineNum.toString().padStart(4)}${COLORS.RESET} | ${line}`
1036
+ `${COLOR_SCHEMES.error(expectedLineNum.toString().padStart(4))} | ${COLOR_SCHEMES.success(actualLineNum.toString().padStart(4))} | ${line}`
854
1037
  );
855
1038
  });
856
- output.push(
857
- `${COLORS.DIM}\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501${COLORS.RESET}`
858
- );
1039
+ output.push(COLOR_SCHEMES.dim("\u2501".repeat(64)));
859
1040
  return output.join("\n");
860
1041
  }
861
1042
 
@@ -888,14 +1069,16 @@ function resolveTargetFiles(targets, projectRoot, docsPath) {
888
1069
  resolvedFiles.add(absolutePath);
889
1070
  }
890
1071
  } else {
891
- console.warn(`\u26A0\uFE0F File not found: ${target}`);
1072
+ console.warn(msg.warning(`File not found: ${target}`));
892
1073
  }
893
1074
  }
894
1075
  return Array.from(resolvedFiles);
895
1076
  }
896
1077
  async function main(args = process.argv.slice(2)) {
897
1078
  const options = parseCliArgs(args);
898
- console.log("\u{1F50D} Validating CODE_REF references in documentation...\n");
1079
+ msg.setVerbose(options.verbose);
1080
+ console.log(`${msg.startValidation("Validating CODE_REF references in documentation...")}
1081
+ `);
899
1082
  const config = loadConfig({
900
1083
  targets: options.files.length > 0 ? options.files : void 0,
901
1084
  verbose: options.verbose
@@ -903,13 +1086,13 @@ async function main(args = process.argv.slice(2)) {
903
1086
  const docsPath = getDocsPath(config);
904
1087
  const allMarkdownFiles = resolveTargetFiles(options.files, config.projectRoot, docsPath);
905
1088
  if (options.files.length > 0 && options.verbose) {
906
- console.log(`\u{1F4CB} Specified files/directories: ${options.files.join(", ")}
1089
+ console.log(`${msg.debug(`Specified files/directories: ${options.files.join(", ")}`)}
907
1090
  `);
908
1091
  }
909
1092
  const ignoreFilePath = getIgnoreFilePath(config);
910
1093
  const ignorePatterns = ignoreFilePath ? loadDocsignorePatterns(ignoreFilePath) : [];
911
1094
  if (options.verbose) {
912
- console.log(`\u{1F4CB} Loaded ${ignorePatterns.length} ignore patterns
1095
+ console.log(`${msg.debug(`Loaded ${ignorePatterns.length} ignore patterns`)}
913
1096
  `);
914
1097
  }
915
1098
  const markdownFiles = allMarkdownFiles.filter((file) => {
@@ -918,11 +1101,11 @@ async function main(args = process.argv.slice(2)) {
918
1101
  });
919
1102
  if (options.verbose && allMarkdownFiles.length > markdownFiles.length) {
920
1103
  console.log(
921
- `\u{1F4CB} ${allMarkdownFiles.length - markdownFiles.length} files excluded by ignore patterns
1104
+ `${msg.debug(`${allMarkdownFiles.length - markdownFiles.length} files excluded by ignore patterns`)}
922
1105
  `
923
1106
  );
924
1107
  }
925
- console.log(`\u{1F4C4} Found ${markdownFiles.length} markdown files
1108
+ console.log(`${msg.file(`Found ${markdownFiles.length} markdown files`)}
926
1109
  `);
927
1110
  let totalRefs = 0;
928
1111
  const allRefs = [];
@@ -933,25 +1116,25 @@ async function main(args = process.argv.slice(2)) {
933
1116
  totalRefs += refs.length;
934
1117
  refs.forEach((ref) => allRefs.push({ ref, file }));
935
1118
  if (options.verbose) {
936
- console.log(` ${path5.relative(docsPath, file)}: ${refs.length} references`);
1119
+ console.log(msg.debug(` ${path5.relative(docsPath, file)}: ${refs.length} references`));
937
1120
  }
938
1121
  }
939
1122
  }
940
1123
  console.log(`
941
- \u{1F4CC} Found ${totalRefs} CODE_REF references
1124
+ ${msg.info(`Found ${totalRefs} CODE_REF references`)}
942
1125
  `);
943
1126
  if (totalRefs === 0) {
944
- console.log("\u2705 No CODE_REF references found (no validation needed)");
1127
+ console.log(msg.success("No CODE_REF references found (no validation needed)"));
945
1128
  process.exit(0);
946
1129
  }
947
1130
  const allErrors = await Promise.all(allRefs.map(({ ref }) => validateCodeRef(ref, config))).then(
948
1131
  (results) => results.flat()
949
1132
  );
950
1133
  if (allErrors.length === 0) {
951
- console.log("\u2705 All CODE_REF references are valid!");
1134
+ console.log(msg.success("All CODE_REF references are valid!"));
952
1135
  process.exit(0);
953
1136
  } else {
954
- console.log(`\u274C Found ${allErrors.length} errors:
1137
+ console.log(`${msg.error(`Found ${allErrors.length} errors:`)}
955
1138
  `);
956
1139
  const errorsByDoc = {};
957
1140
  for (const error of allErrors) {
@@ -962,12 +1145,12 @@ async function main(args = process.argv.slice(2)) {
962
1145
  errorsByDoc[docFile].push(error);
963
1146
  }
964
1147
  for (const [docFile, errors] of Object.entries(errorsByDoc)) {
965
- console.log(`\u{1F4C4} ${docFile}:`);
1148
+ console.log(`${msg.file(docFile)}:`);
966
1149
  for (const error of errors) {
967
- console.log(` \u274C ${error.type}: ${error.message}`);
1150
+ console.log(` ${msg.error(`${error.type}: ${error.message}`)}`);
968
1151
  const filePath = path5.relative(config.projectRoot, error.ref.docFile);
969
1152
  const lineInfo = error.ref.docLineNumber ? `:${error.ref.docLineNumber}` : "";
970
- console.log(` ${filePath}${lineInfo}: ${error.ref.fullMatch}`);
1153
+ console.log(msg.context(` ${filePath}${lineInfo}: ${error.ref.fullMatch}`));
971
1154
  if (error.type === "CODE_LOCATION_MISMATCH" && error.suggestedLines && options.verbose) {
972
1155
  const filePath2 = path5.join(config.projectRoot, error.ref.refPath);
973
1156
  const actualCode = extractLinesFromFile(
@@ -990,7 +1173,7 @@ async function main(args = process.argv.slice(2)) {
990
1173
  }
991
1174
  if (require.main === module) {
992
1175
  main().catch((error) => {
993
- console.error("Error:", error);
1176
+ console.error(msg.error(`Error: ${error}`));
994
1177
  process.exit(1);
995
1178
  });
996
1179
  }
@@ -4,8 +4,9 @@ import {
4
4
  loadDocsignorePatterns
5
5
  } from "../chunk-AQ3QIGEV.mjs";
6
6
  import {
7
- displayLineRangeDiff
8
- } from "../chunk-NTTV47AI.mjs";
7
+ displayLineRangeDiff,
8
+ msg
9
+ } from "../chunk-U3LM2QL7.mjs";
9
10
  import {
10
11
  __require,
11
12
  extractCodeRefs,
@@ -48,14 +49,16 @@ function resolveTargetFiles(targets, projectRoot, docsPath) {
48
49
  resolvedFiles.add(absolutePath);
49
50
  }
50
51
  } else {
51
- console.warn(`\u26A0\uFE0F File not found: ${target}`);
52
+ console.warn(msg.warning(`File not found: ${target}`));
52
53
  }
53
54
  }
54
55
  return Array.from(resolvedFiles);
55
56
  }
56
57
  async function main(args = process.argv.slice(2)) {
57
58
  const options = parseCliArgs(args);
58
- console.log("\u{1F50D} Validating CODE_REF references in documentation...\n");
59
+ msg.setVerbose(options.verbose);
60
+ console.log(`${msg.startValidation("Validating CODE_REF references in documentation...")}
61
+ `);
59
62
  const config = loadConfig({
60
63
  targets: options.files.length > 0 ? options.files : void 0,
61
64
  verbose: options.verbose
@@ -63,13 +66,13 @@ async function main(args = process.argv.slice(2)) {
63
66
  const docsPath = getDocsPath(config);
64
67
  const allMarkdownFiles = resolveTargetFiles(options.files, config.projectRoot, docsPath);
65
68
  if (options.files.length > 0 && options.verbose) {
66
- console.log(`\u{1F4CB} Specified files/directories: ${options.files.join(", ")}
69
+ console.log(`${msg.debug(`Specified files/directories: ${options.files.join(", ")}`)}
67
70
  `);
68
71
  }
69
72
  const ignoreFilePath = getIgnoreFilePath(config);
70
73
  const ignorePatterns = ignoreFilePath ? loadDocsignorePatterns(ignoreFilePath) : [];
71
74
  if (options.verbose) {
72
- console.log(`\u{1F4CB} Loaded ${ignorePatterns.length} ignore patterns
75
+ console.log(`${msg.debug(`Loaded ${ignorePatterns.length} ignore patterns`)}
73
76
  `);
74
77
  }
75
78
  const markdownFiles = allMarkdownFiles.filter((file) => {
@@ -78,11 +81,11 @@ async function main(args = process.argv.slice(2)) {
78
81
  });
79
82
  if (options.verbose && allMarkdownFiles.length > markdownFiles.length) {
80
83
  console.log(
81
- `\u{1F4CB} ${allMarkdownFiles.length - markdownFiles.length} files excluded by ignore patterns
84
+ `${msg.debug(`${allMarkdownFiles.length - markdownFiles.length} files excluded by ignore patterns`)}
82
85
  `
83
86
  );
84
87
  }
85
- console.log(`\u{1F4C4} Found ${markdownFiles.length} markdown files
88
+ console.log(`${msg.file(`Found ${markdownFiles.length} markdown files`)}
86
89
  `);
87
90
  let totalRefs = 0;
88
91
  const allRefs = [];
@@ -93,25 +96,25 @@ async function main(args = process.argv.slice(2)) {
93
96
  totalRefs += refs.length;
94
97
  refs.forEach((ref) => allRefs.push({ ref, file }));
95
98
  if (options.verbose) {
96
- console.log(` ${path.relative(docsPath, file)}: ${refs.length} references`);
99
+ console.log(msg.debug(` ${path.relative(docsPath, file)}: ${refs.length} references`));
97
100
  }
98
101
  }
99
102
  }
100
103
  console.log(`
101
- \u{1F4CC} Found ${totalRefs} CODE_REF references
104
+ ${msg.info(`Found ${totalRefs} CODE_REF references`)}
102
105
  `);
103
106
  if (totalRefs === 0) {
104
- console.log("\u2705 No CODE_REF references found (no validation needed)");
107
+ console.log(msg.success("No CODE_REF references found (no validation needed)"));
105
108
  process.exit(0);
106
109
  }
107
110
  const allErrors = await Promise.all(allRefs.map(({ ref }) => validateCodeRef(ref, config))).then(
108
111
  (results) => results.flat()
109
112
  );
110
113
  if (allErrors.length === 0) {
111
- console.log("\u2705 All CODE_REF references are valid!");
114
+ console.log(msg.success("All CODE_REF references are valid!"));
112
115
  process.exit(0);
113
116
  } else {
114
- console.log(`\u274C Found ${allErrors.length} errors:
117
+ console.log(`${msg.error(`Found ${allErrors.length} errors:`)}
115
118
  `);
116
119
  const errorsByDoc = {};
117
120
  for (const error of allErrors) {
@@ -122,12 +125,12 @@ async function main(args = process.argv.slice(2)) {
122
125
  errorsByDoc[docFile].push(error);
123
126
  }
124
127
  for (const [docFile, errors] of Object.entries(errorsByDoc)) {
125
- console.log(`\u{1F4C4} ${docFile}:`);
128
+ console.log(`${msg.file(docFile)}:`);
126
129
  for (const error of errors) {
127
- console.log(` \u274C ${error.type}: ${error.message}`);
130
+ console.log(` ${msg.error(`${error.type}: ${error.message}`)}`);
128
131
  const filePath = path.relative(config.projectRoot, error.ref.docFile);
129
132
  const lineInfo = error.ref.docLineNumber ? `:${error.ref.docLineNumber}` : "";
130
- console.log(` ${filePath}${lineInfo}: ${error.ref.fullMatch}`);
133
+ console.log(msg.context(` ${filePath}${lineInfo}: ${error.ref.fullMatch}`));
131
134
  if (error.type === "CODE_LOCATION_MISMATCH" && error.suggestedLines && options.verbose) {
132
135
  const filePath2 = path.join(config.projectRoot, error.ref.refPath);
133
136
  const actualCode = extractLinesFromFile(
@@ -150,7 +153,7 @@ async function main(args = process.argv.slice(2)) {
150
153
  }
151
154
  if (__require.main === module) {
152
155
  main().catch((error) => {
153
- console.error("Error:", error);
156
+ console.error(msg.error(`Error: ${error}`));
154
157
  process.exit(1);
155
158
  });
156
159
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "docs-coderef",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "Validate and fix code references in markdown documentation",
5
5
  "keywords": [
6
6
  "markdown",
@@ -46,6 +46,13 @@
46
46
  "format:check": "prettier --check \"src/**/*.ts\" \"*.{js,json,md}\"",
47
47
  "type-check": "tsc --noEmit",
48
48
  "docs:validate": "tsx scripts/validate-docs.ts",
49
+ "demo:validate": "npm run build && cd demo && npx docs-coderef validate docs",
50
+ "demo:validate:valid": "npm run build && cd demo && npx docs-coderef validate docs/valid",
51
+ "demo:validate:invalid": "npm run build && cd demo && npx docs-coderef validate docs/invalid",
52
+ "demo:fix": "npm run build && cd demo && npx docs-coderef fix",
53
+ "demo:fix:dry": "npm run build && cd demo && npx docs-coderef fix --dry-run",
54
+ "demo:fix:auto": "npm run build && cd demo && npx docs-coderef fix --auto",
55
+ "demo:reset": "git checkout demo/docs/ && rm -f demo/docs/**/*.backup 2>/dev/null || true",
49
56
  "prepublishOnly": "npm run build && npm test"
50
57
  },
51
58
  "engines": {
@@ -1,73 +0,0 @@
1
- // src/utils/diff-display.ts
2
- var COLORS = {
3
- RED: "\x1B[31m",
4
- GREEN: "\x1B[32m",
5
- RESET: "\x1B[0m",
6
- DIM: "\x1B[2m"
7
- };
8
- function displayCodeDiff(expected, actual) {
9
- const expectedLines = expected.split("\n");
10
- const actualLines = actual.split("\n");
11
- const output = [];
12
- const maxLines = Math.max(expectedLines.length, actualLines.length);
13
- output.push(
14
- `${COLORS.DIM}\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501${COLORS.RESET}`
15
- );
16
- output.push(`${COLORS.RED}- Expected code (in document)${COLORS.RESET}`);
17
- output.push(`${COLORS.GREEN}+ Actual code (in file)${COLORS.RESET}`);
18
- output.push(
19
- `${COLORS.DIM}\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501${COLORS.RESET}`
20
- );
21
- for (let i = 0; i < maxLines; i++) {
22
- const expectedLine = expectedLines[i];
23
- const actualLine = actualLines[i];
24
- if (expectedLine === actualLine) {
25
- if (expectedLine !== void 0) {
26
- output.push(` ${expectedLine}`);
27
- }
28
- } else {
29
- if (expectedLine !== void 0) {
30
- output.push(`${COLORS.RED}- ${expectedLine}${COLORS.RESET}`);
31
- }
32
- if (actualLine !== void 0) {
33
- output.push(`${COLORS.GREEN}+ ${actualLine}${COLORS.RESET}`);
34
- }
35
- }
36
- }
37
- output.push(
38
- `${COLORS.DIM}\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501${COLORS.RESET}`
39
- );
40
- return output.join("\n");
41
- }
42
- function displayLineRangeDiff(code, expectedRange, actualRange) {
43
- const output = [];
44
- output.push(
45
- `${COLORS.DIM}\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501${COLORS.RESET}`
46
- );
47
- output.push(
48
- `${COLORS.RED}- Expected line range: ${expectedRange.start}-${expectedRange.end}${COLORS.RESET}`
49
- );
50
- output.push(
51
- `${COLORS.GREEN}+ Actual line range: ${actualRange.start}-${actualRange.end}${COLORS.RESET}`
52
- );
53
- output.push(
54
- `${COLORS.DIM}\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501${COLORS.RESET}`
55
- );
56
- const codeLines = code.split("\n");
57
- codeLines.forEach((line, index) => {
58
- const expectedLineNum = expectedRange.start + index;
59
- const actualLineNum = actualRange.start + index;
60
- output.push(
61
- `${COLORS.RED}${expectedLineNum.toString().padStart(4)}${COLORS.RESET} | ${COLORS.GREEN}${actualLineNum.toString().padStart(4)}${COLORS.RESET} | ${line}`
62
- );
63
- });
64
- output.push(
65
- `${COLORS.DIM}\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501${COLORS.RESET}`
66
- );
67
- return output.join("\n");
68
- }
69
-
70
- export {
71
- displayCodeDiff,
72
- displayLineRangeDiff
73
- };