130 lines
4.5 KiB
JavaScript
130 lines
4.5 KiB
JavaScript
|
"use strict";
|
||
|
|
||
|
const { resolve } = require("path");
|
||
|
const fs = require("fs");
|
||
|
|
||
|
const ts = require("typescript");
|
||
|
|
||
|
function getDefinitions(source) {
|
||
|
const sourceFile = ts.createSourceFile("filename.ts", source);
|
||
|
|
||
|
const defs = [ ];
|
||
|
|
||
|
function add(type, name, pos) {
|
||
|
const lineNo = sourceFile.getLineAndCharacterOfPosition(pos).line + 1;
|
||
|
name = type + "." + name
|
||
|
defs.push({ type, name, lineNo });
|
||
|
}
|
||
|
|
||
|
let lastClass = null, lastEnum = null;
|
||
|
function visit(node, depth) {
|
||
|
if (ts.isConstructorDeclaration(node)) {
|
||
|
add("constructor", lastClass, node.body.pos);
|
||
|
} else if (ts.isFunctionDeclaration(node)) {
|
||
|
add("function", node.name.text, node.name.end);
|
||
|
} else if (ts.isConstructorDeclaration(node)) {
|
||
|
add("constructor", lastClass, node.pos);
|
||
|
} else if (ts.isClassDeclaration(node)) {
|
||
|
lastClass = node.name.escapedText;
|
||
|
add("class", lastClass, node.name.end);
|
||
|
} else if (ts.isMethodDeclaration(node)) {
|
||
|
if (lastClass == null) { throw new Error("missing class"); }
|
||
|
if (ts.hasStaticModifier(node)) {
|
||
|
add("staticmethod", (lastClass + "." + node.name.text), node.name.end);
|
||
|
} else {
|
||
|
add("method", (lastClass + "." + node.name.text), node.name.end);
|
||
|
}
|
||
|
} else if (ts.isEnumDeclaration(node)) {
|
||
|
lastEnum = node.name.escapedText;
|
||
|
add("enum", lastEnum, node.name.end);
|
||
|
} else if (ts.isEnumMember(node)) {
|
||
|
add("enum", (lastEnum + "." + node.name.escapedText), node.name.end);
|
||
|
} else if (ts.isVariableDeclaration(node)) {
|
||
|
if (depth === 3) {
|
||
|
add("var", node.name.escapedText, node.name.end);
|
||
|
}
|
||
|
}
|
||
|
ts.forEachChild(node, (node) => { return visit(node, depth + 1); });
|
||
|
}
|
||
|
|
||
|
visit(sourceFile, 0);
|
||
|
|
||
|
return defs;
|
||
|
}
|
||
|
|
||
|
const getSourceUrl = (function(path, include, exclude) {
|
||
|
console.log("Scanning TypeScript Sources...");
|
||
|
const Link = "https://github.com/ethers-io/ethers.js/blob/ethers-v5-beta/packages$FILENAME#L$LINE";
|
||
|
const Root = resolve(__dirname, path);
|
||
|
|
||
|
const readdir = function(path) {
|
||
|
if (path.match(exclude)) { return [ ]; }
|
||
|
|
||
|
const stat = fs.statSync(path);
|
||
|
if (stat.isDirectory()) {
|
||
|
return fs.readdirSync(path).reduce((result, filename) => {
|
||
|
readdir(resolve(path, filename)).forEach((file) => {
|
||
|
result.push(file);
|
||
|
});
|
||
|
return result;
|
||
|
}, [ ]);
|
||
|
}
|
||
|
|
||
|
if (path.match(include)) {
|
||
|
const source = fs.readFileSync(path).toString();
|
||
|
return [ { filename: path.substring(Root.length), defs: getDefinitions(source) } ]
|
||
|
}
|
||
|
|
||
|
return [ ];
|
||
|
}
|
||
|
|
||
|
const defs = readdir(Root);
|
||
|
|
||
|
return function getSourceUrl(key) {
|
||
|
const comps = key.split(":");
|
||
|
if (comps.length !== 2) { throw new Error("unsupported key"); }
|
||
|
|
||
|
const pathCheck = new RegExp("(^|[^a-zA-Z0-9_])" + comps[0].split("/").join("/(.*/)*") + "($|[^a-zA-Z0-9_])");
|
||
|
|
||
|
let match = comps[1];
|
||
|
if (match.indexOf("(" /* fix: )*/)) {
|
||
|
match = new RegExp("(^|\\.)" + match.split("(" /* fix: ) */)[0] + "$");
|
||
|
} else if (match[0] === "=") {
|
||
|
match = new RegExp("^" + match.substring(1) + "$");
|
||
|
} else {
|
||
|
match = new RegExp("(^|\\.)" + match + "$");
|
||
|
}
|
||
|
|
||
|
const result = [ ];
|
||
|
defs.forEach((def) => {
|
||
|
if (!def.filename.match(pathCheck)) { return; }
|
||
|
def.defs.forEach((d) => {
|
||
|
if (!d.name.match(match)) { return; }
|
||
|
result.push({ filename: def.filename, lineNo: d.lineNo });
|
||
|
});
|
||
|
});
|
||
|
|
||
|
if (result.length > 1) {
|
||
|
throw new Error(`Amibguous TypeScript link: ${ key } in [ ${ result.map((r) => JSON.stringify(r.filename + ":" + r.lineNo)).join(", ") }]`);
|
||
|
} else if (result.length === 0) {
|
||
|
throw new Error(`No matching TypeScript link: ${ key }`);
|
||
|
}
|
||
|
|
||
|
return Link
|
||
|
.replace("$LINE", String(result[0].lineNo))
|
||
|
.replace("$FILENAME", result[0].filename);
|
||
|
}
|
||
|
})("../packages/", new RegExp("packages/.*/src.ts/.*\.ts$"), new RegExp("/node_modules/|src.ts/.*browser.*"));
|
||
|
|
||
|
module.exports = {
|
||
|
title: "ethers",
|
||
|
foo: "Bat",
|
||
|
subtitle: "v5.0-beta",
|
||
|
logo: "logo.svg",
|
||
|
link: "https://docs-beta.ethers.io",
|
||
|
markdown: {
|
||
|
"banner": "-----\n\nDocumentation: [html](https://docs-beta.ethers.io/)\n\n-----\n\n"
|
||
|
},
|
||
|
getSourceUrl: getSourceUrl
|
||
|
};
|