New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@moonbit/markdown-linter

Package Overview
Dependencies
Maintainers
2
Versions
12
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@moonbit/markdown-linter - npm Package Compare versions

Comparing version 0.1.13 to 0.1.14

markdown-linter.ts

311

markdown-linter.js
#!/usr/bin/env node
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
// @ts-check

@@ -7,182 +9,167 @@ /*

*/
const { parseArgs } = require("node:util");
const cli = parseArgs({
options: {
version: {
type: "boolean",
short: "v",
var MarkdownIt = require("markdown-it");
var node_child_process_1 = require("node:child_process");
var node_fs_1 = require("node:fs");
var node_path_1 = require("node:path");
var node_util_1 = require("node:util");
var temp_1 = require("temp");
var cli = (0, node_util_1.parseArgs)({
options: {
version: {
type: "boolean",
short: "v",
},
},
},
allowPositionals: true,
allowPositionals: true,
});
if (cli.values.version) {
console.log(`Markdown linter ${require("./package.json").version}`);
globalThis.process.exit(0);
console.log("Markdown linter ".concat(require("./package.json").version));
globalThis.process.exit(0);
}
const files = cli.positionals;
const MarkdownIt = require("markdown-it");
const fs = require("node:fs");
const path = require("node:path");
const { execSync } = require("node:child_process");
const temp = require("temp").track();
const md = new MarkdownIt();
var files = cli.positionals;
var temp = (0, temp_1.track)();
var md = new MarkdownIt();
var hasErrors = false;
for (const inputFile of files) {
processMarkdown(inputFile);
for (var _i = 0, files_1 = files; _i < files_1.length; _i++) {
var inputFile = files_1[_i];
processMarkdown(inputFile);
}
function executeCommandLine(workingDir, command) {
try {
const output = execSync(command, { encoding: "utf-8", stdio: "pipe", cwd: workingDir });
return output.trim();
} catch (error) {
return error.stdout.trim() + error.stderr.trim();
}
try {
var output = (0, node_child_process_1.execSync)(command, { encoding: "utf-8", stdio: "pipe", cwd: workingDir });
return output.trim();
}
catch (error) {
return error.stdout.trim() + error.stderr.trim();
}
}
function makeTempProject(projectName) {
const projectPath = temp.mkdirSync();
fs.writeFileSync(path.join(projectPath, "/moon.mod.json"), `{ "name": "${projectName}" }`, "utf-8");
fs.writeFileSync(path.join(projectPath, "/moon.pkg.json"), `{}`, "utf-8");
return projectPath;
var projectPath = temp.mkdirSync();
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(projectPath, "/moon.mod.json"), "{ \"name\": \"".concat(projectName, "\" }"), "utf-8");
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(projectPath, "/moon.pkg.json"), "{}", "utf-8");
return projectPath;
}
function processMarkdown(inputFile) {
const readmeFilename = path.basename(inputFile);
const readme = fs.readFileSync(inputFile, "utf-8");
// parse readme and find codeblocks
const tokens = md.parse(readme, {});
var codeBlocks = [];
tokens.forEach((token, index) => {
const codeInfo = token.info.trim()
if (codeInfo.toLowerCase().startsWith("mbt") || codeInfo.toLowerCase().startsWith("moonbit")) {
const info = codeInfo.split(" ").map(s => s.trim());
var kind;
if (info.length > 1) {
switch (info[1].toLowerCase()) {
case "expr":
kind = "expr";
break;
case "no-check":
kind = "no-check";
break;
default:
kind = "normal";
var readmeFilename = (0, node_path_1.basename)(inputFile);
var readme = (0, node_fs_1.readFileSync)(inputFile, "utf-8");
// parse readme and find codeblocks
var tokens = md.parse(readme, {});
var codeBlocks = [];
tokens.forEach(function (token, index) {
var codeInfo = token.info.trim();
if (codeInfo.toLowerCase().startsWith("mbt") || codeInfo.toLowerCase().startsWith("moonbit")) {
var info = codeInfo.split(" ").map(function (s) { return s.trim(); });
var kind;
if (info.length > 1) {
switch (info[1].toLowerCase()) {
case "expr":
kind = "expr";
break;
case "no-check":
kind = "no-check";
break;
default:
kind = "normal";
}
}
else {
kind = "normal";
}
var content = token.content, map = token.map;
if (map) {
codeBlocks.push({
content: content,
kind: kind,
beginLine: map[0] + 1,
endLine: map[1] + 1
});
}
}
} else {
kind = "normal";
}
const { content, map } = token;
if (map) {
codeBlocks.push({ content, kind, beginLine: map[0] + 1, endLine: map[1] + 1 });
}
});
// generate source map
var sourceMap = [];
var line = 1;
function countLines(str) {
return str.split("\n").length - 1;
}
});
// generate source map
var sourceMap = [];
var line = 1;
function countLines(str) {
return str.split("\n").length - 1;
}
var processedCodeBlocks = []
codeBlocks.forEach(block => {
var wrapper;
switch (block.kind) {
case "expr":
wrapper = { leading: "fn init {debug({\n", trailing: "\n})}\n" };
break;
case "no-check":
return;
default:
wrapper = { leading: "", trailing: "" };
break;
}
const leadingLines = countLines(wrapper.leading);
const contentLines = countLines(block.content);
const trailingLines = countLines(wrapper.trailing);
sourceMap.push({
original: block.beginLine + 1, // 1 based line number in markdown
generated: line + leadingLines, // 1 based line number in the generated mbt source
var processedCodeBlocks = [];
codeBlocks.forEach(function (block) {
var wrapper;
switch (block.kind) {
case "expr":
wrapper = { leading: "fn init {debug({\n", trailing: "\n})}\n" };
break;
case "no-check":
return;
default:
wrapper = { leading: "", trailing: "" };
break;
}
var leadingLines = countLines(wrapper.leading);
var contentLines = countLines(block.content);
var trailingLines = countLines(wrapper.trailing);
sourceMap.push({
originalLine: block.beginLine + 1, // 1 based line number in markdown
generatedLine: line + leadingLines, // 1 based line number in the generated mbt source
});
sourceMap.push({
originalLine: block.endLine - 1,
generatedLine: line + leadingLines + contentLines
});
line += leadingLines + contentLines + trailingLines;
block.content = wrapper.leading + block.content + wrapper.trailing;
processedCodeBlocks.push(block);
});
sourceMap.push({
original: block.endLine - 1,
generated: line + leadingLines + contentLines
});
line += leadingLines + contentLines + trailingLines;
block.content = wrapper.leading + block.content + wrapper.trailing;
processedCodeBlocks.push(block);
});
// map location to real location in markdown
function getRealLine(sourceMap, line) {
function find(line, l, r) {
if (l > r) return sourceMap[l];
var m = Math.floor((l + r) / 2);
const currentLine = sourceMap[m].generated;
if (currentLine > line) return find(line, l, m - 1);
if (currentLine < line) return find(line, m + 1, r);
return sourceMap[m];
console.log(sourceMap);
// map location to real location in markdown
function getRealLine(sourceMap, line) {
function find(line, l, r) {
if (l >= r)
return sourceMap[l];
var m = Math.floor((l + r) / 2);
console.log("m:", m, "len:", sourceMap.length, "item:", sourceMap[m]);
var currentLine = sourceMap[m].generatedLine;
if (currentLine > line)
return find(line, l, m - 1);
if (currentLine < line)
return find(line, m + 1, r);
return sourceMap[m];
}
var _a = find(line, 0, sourceMap.length - 1), originalLine = _a.originalLine, generatedLine = _a.generatedLine;
return originalLine + (line - generatedLine);
}
const { original, generated } = find(line, 0, sourceMap.length);
return original + (line - generated);
}
const source = processedCodeBlocks.reduce((acc, { content }) => acc + content, "");
// create a temporary project to run type checking and testing
const projectPath = makeTempProject(path.basename(inputFile, ".md"));
fs.writeFileSync(path.join(projectPath, "main.mbt"), source, "utf-8");
// run moon test
const checkOutput = executeCommandLine(projectPath, `moon test`);
// cleanup the temporary project
temp.cleanupSync();
// process the diagnostics
const diagnosticPattern = /^(.+\.mbt):(\d+):(\d+)-(\d+):(\d+)/gm;
const moonFailedPattern = /failed: moonc .+\n/g;
const diagnostics = checkOutput
.replace( // replace location with real location in markdown
diagnosticPattern,
(_, file, beginLine, beginColumn, endLine, endColumn) => {
const realBeginLine = getRealLine(sourceMap, parseInt(beginLine));
const realEndLine = getRealLine(sourceMap, parseInt(endLine));
return `${readmeFilename}:${realBeginLine}:${beginColumn}-${realEndLine}:${endColumn}`;
}
)
.replace( // remove unused output
moonFailedPattern,
_ => {
var source = processedCodeBlocks.reduce(function (acc, _a) {
var content = _a.content;
return acc + content;
}, "");
// create a temporary project to run type checking and testing
var projectPath = makeTempProject((0, node_path_1.basename)(inputFile, ".md"));
(0, node_fs_1.writeFileSync)((0, node_path_1.join)(projectPath, "main.mbt"), source, "utf-8");
// run moon test
var checkOutput = executeCommandLine(projectPath, "moon test");
// cleanup the temporary project
temp.cleanupSync();
// process the diagnostics
var diagnosticPattern = /^(.+\.mbt):(\d+):(\d+)-(\d+):(\d+)/gm;
var moonFailedPattern = /failed: moonc .+\n/g;
var diagnostics = checkOutput
.replace(// replace location with real location in markdown
diagnosticPattern, function (_, file, beginLine, beginColumn, endLine, endColumn) {
var realBeginLine = getRealLine(sourceMap, parseInt(beginLine));
var realEndLine = getRealLine(sourceMap, parseInt(endLine));
var fullPath = (0, node_path_1.join)(process.cwd(), inputFile);
return "".concat(fullPath, ":").concat(realBeginLine, ":").concat(beginColumn, "-").concat(realEndLine, ":").concat(endColumn);
})
.replace(// remove unused output
moonFailedPattern, function (_) {
hasErrors = true;
return ""
}
)
console.log(diagnostics);
return "";
});
console.log(diagnostics);
}
if (hasErrors) {
process.exit(1)
} else {
process.exit(0)
process.exit(1);
}
else {
process.exit(0);
}
{
"name": "@moonbit/markdown-linter",
"version": "0.1.13",
"version": "0.1.14",
"description": "markdown linter for MoonBit",

@@ -14,3 +14,13 @@ "main": "./markdown-linter.js",

"temp": "^0.9.4"
},
"devDependencies": {
"@types/markdown-it": "^13.0.7",
"@types/node": "^20.11.28",
"@types/temp": "^0.9.4",
"typescript": "^5.4.2"
},
"scripts": {
"dev": "tsc markdown-linter.ts && node markdown-linter.js",
"prepublishOnly": "tsc markdown-linter.ts"
}
}
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc