Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

elm-doc-preview

Package Overview
Dependencies
Maintainers
1
Versions
29
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

elm-doc-preview - npm Package Compare versions

Comparing version 1.0.7 to 2.0.0

lib/elm-doc-server.js

250

cli.js
#!/usr/bin/env node
const fs = require("fs");
const path = require("path");
const sane = require("sane");
const spawn = require("cross-spawn");
const express = require("express");
const tmp = require("tmp");
const chalk = require("chalk");
const program = require("commander");
const commander = require("commander");
const latestVersion = require("latest-version");
const DocServer = require("./lib/elm-doc-server");
const pkg = require(path.join(__dirname, "package.json"));
const npmPackage = require(path.join(__dirname, "package.json"));
function error(log) {
console.log(chalk.red("Error:"), chalk.red(log));
}
program
.version(pkg.version)
.arguments("[path_to_package]")
.action(dir => {
if (fs.existsSync(dir)) {
try {
process.chdir(dir);
} catch (err) {
error(`cannot change directory to ${dir} (${err})`);
process.exit(1);
}
}
})
.option("-p, --port <port>", "the server listening port", Math.floor, 8000)
.parse(process.argv);
function getFile(filepath) {
if (!fs.existsSync(filepath)) {
return "";
}
const data = fs.readFileSync(filepath, "utf8");
if (data) {
return data;
}
return "";
}
/*
* Get temp file for docs.json
* Program options and usage
*/
tmp.setGracefulCleanup();
function init() {
let pkgPath = ".";
const program = commander
.version(npmPackage.version)
.arguments("[path_to_package_or_application]")
.action(dir => {
if (dir !== undefined) {
pkgPath = dir;
}
})
.option("-p, --port <port>", "the server listening port", Math.floor, 8000);
const docs = tmp.fileSync({
prefix: "elm-docs-",
postfix: ".json"
});
program.on("--help", () => {
console.log("");
console.log("Environment variables:");
console.log(" ELM_HOME Elm home directory (cache)");
});
process.on("SIGINT", () => {
docs.removeCallback();
process.exit(0);
});
/*
* Check package
*/
let elmJson = {};
try {
elmJson = JSON.parse(fs.readFileSync("elm.json", "utf8"));
} catch (e) {
error(`invalid elm.json file (${e})`);
process.exit(1);
program.parse(process.argv);
program.dir = pkgPath;
return program;
}
if (!("type" in elmJson) || elmJson.type !== "package") {
const type = "type" in elmJson ? elmJson.type : "program";
error(
`unsupported Elm ${type}, only packages documentation can be previewed`
);
process.exit(1);
}
let pkgName = "name" in elmJson ? elmJson.name : "package";
if ("version" in elmJson) {
pkgName += ` ${elmJson.version}`;
}
/*
* Find and check Elm
* Check if a newer version is available
*/
let elm = args => spawn.sync("npx", ["--no-install", "elm"].concat(args));
let exec = elm(["--version"]);
if (exec.error || exec.status !== 0 || exec.stderr.toString().length > 0) {
elm = args => spawn.sync("elm", args);
exec = elm(["--version"]);
function checkUpdate(currentVersion) {
latestVersion("elm-doc-preview").then(lastVersion => {
if (lastVersion !== currentVersion) {
console.log(chalk.yellow(`elm-doc-preview ${lastVersion} is available`));
}
});
}
if (exec.error) {
error(`cannot run 'elm --version' (${exec.error})`);
process.exit(1);
} else if (exec.status !== 0) {
error(`cannot run 'elm --version':`);
process.stderr.write(exec.stderr);
process.exit(exec.status);
}
const elmVersion = exec.stdout.toString().trim();
if (!elmVersion.startsWith("0.19")) {
error(`unsupported Elm version ${elmVersion}`);
process.exit(1);
}
function buildDoc() {
console.log(" |> building documentation");
const build = elm(["make", `--docs=${docs.name}`, "--report=json"]);
if (build.error) {
error(`cannot build documentation (${build.error})`);
process.exit(1);
}
return build.stderr.toString();
}
/*
* Starting message
* Run program
*/
console.log(
chalk`{bold elm-doc-preview ${pkg.version}} using elm ${elmVersion}`
);
console.log(chalk`Previewing {magenta ${pkgName}} from ${process.cwd()}`);
const program = init();
checkUpdate(npmPackage.version);
/*
* Set web server
*/
let ws = null;
const docServer = new DocServer(program.dir);
function send(type, data) {
if (ws !== null) {
ws.send(JSON.stringify({ type, data }));
}
}
function sendCompilation(output) {
console.log(" |>", "updating compilation status");
send("compilation", output);
}
function sendReadme() {
console.log(" |>", "updating README preview");
send("readme", getFile("README.md"));
}
function sendDocs() {
console.log(" |>", `updating ${docs.name} preview`);
send("docs", getFile(docs.name));
}
const app = express();
require("express-ws")(app);
app.use(
"/",
express.static(path.join(__dirname, "public"), { index: "local.html" })
);
let buildReport = buildDoc();
app.ws("/", _ws => {
ws = _ws;
sendCompilation(buildReport);
sendReadme();
sendDocs();
});
app.get("*", (req, res) => {
res.sendFile(path.join(__dirname, "public/local.html"));
});
let timeout = null;
function onChange(filepath) {
/* Try to batch consecutive updates.
* (for example the way vim saves files would lead to 3 rebuilds else)
*/
if (timeout) {
clearTimeout(timeout);
}
timeout = setTimeout(() => {
timeout = null;
console.log(" |>", "detected", filepath, "modification");
if (filepath.endsWith("README.md")) {
sendReadme();
process
.on("SIGINT", () => {
process.exit(0);
})
.on("uncaughtException", e => {
if (e.errno === "EADDRINUSE") {
console.log(
chalk.red(`port ${program.port} already used, use --port option`)
);
} else {
buildReport = buildDoc();
sendCompilation(buildReport);
sendDocs();
console.log(chalk.red(e));
}
}, 100);
}
process.exit(1);
});
/*
* Set files watcher
*/
const watcher = sane(".", {
glob: ["**/elm.json", "src/**/*.elm", "**/README.md"]
});
console.log(` |> watching elm.json, README.md and *.elm files`);
function ready() {
console.log(
chalk`{blue Browse} {bold {green <http://localhost:${
program.port
}>}} {blue to see your documentation}`
);
}
watcher.on("ready", () => {
ready();
});
watcher.on("change", filepath => {
onChange(filepath);
});
watcher.on("add", filepath => {
onChange(filepath);
});
watcher.on("delete", filepath => {
onChange(filepath);
});
/*
* Run web server
*/
app.listen(program.port);
docServer.listen(program.port);

@@ -6,3 +6,3 @@ # License information

Copyright (c) 2014-2018, Evan Czaplicki
Copyright (c) 2018, Rémi Lefèvre
Copyright (c) 2018-2019, Rémi Lefèvre

@@ -9,0 +9,0 @@ All rights reserved.

@@ -9,5 +9,7 @@ {

"express-ws": "^4.0.0",
"latest-version": "^4.0.0",
"sane": "^4.0.2",
"serve-static": "^1.13.2",
"tmp": "0.0.33"
"tmp": "0.0.33",
"ws": "^6.2.0"
},

@@ -30,3 +32,3 @@ "devDependencies": {

},
"license": "SEE LICENSE in LICENSE.md",
"license": "SEE LICENSE IN LICENSE.md",
"description": "Elm packages documentation previewer with hot reloading.",

@@ -37,7 +39,8 @@ "bugs": {

"homepage": "https://github.com/dmy/elm-doc-preview#readme",
"version": "1.0.7",
"version": "2.0.0",
"bin": {
"elm-doc-preview": "./cli.js"
"elm-doc-preview": "./cli.js",
"edp": "./cli.js"
},
"main": "./cli.js",
"main": "./lib/elm-doc-server.js",
"scripts": {

@@ -44,0 +47,0 @@ "test": "echo \"Error: no test specified\" && exit 1",

@@ -46,4 +46,7 @@ var app = Elm.Main.init({

switch (msg.type) {
case "name":
app.ports.nameUpdated.send(msg.data);
break;
case "compilation":
app.ports.compilationCompleted.send(msg.data);
app.ports.compilationUpdated.send(msg.data);
break;

@@ -56,3 +59,6 @@ case "readme":

break;
case "deps":
app.ports.depsUpdated.send(msg.data);
break;
}
};
# elm-doc-preview
This is a documentation previewer for Elm packages (>= 0.19).
It allows previewing `README.md` and `docs.json` files (generated with `elm make --docs=docs.json`).
This is an Elm 0.19 documentation previewer for **packages**, **applications**
and their **dependencies**.
It aims at rendering documentation exactly like the [official package website](https://package.elm-lang.org).
## Online version
There is an online version supporting documentation loading from github that can be used for reviews:
It aims at rendering documentation exactly like the
[official package website](https://package.elm-lang.org) to avoid
any surprise when releasing a package.
https://elm-doc-preview.netlify.com
Note that applications documentation is
[not yet supported by Elm](https://github.com/elm/compiler/issues/1835#issuecomment-440080525),
so only the `README` and dependencies are supported for those at the moment.
## Local version
There is also a local version that supports **hot reloading** for convenient packages documentation editing:
<p align="center">
<img src="https://raw.githubusercontent.com/dmy/elm-doc-preview/master/screenshots/regex.png" width="400" />
<img src="https://raw.githubusercontent.com/dmy/elm-doc-preview/master/screenshots/elm-doc-preview.png" width="400" />
<img src="https://raw.githubusercontent.com/dmy/elm-doc-preview/master/screenshots/compilation.png" width="400" />
<img src="https://raw.githubusercontent.com/dmy/elm-doc-preview/master/screenshots/term.png" width="400" />
</p>
# Features
- **Packages** full support with **hot reloading**
- **Offline dependencies documentation** for packages and applications
- **Regex filtering** for focused documentation
- **Compilation errors display** (packages only)
- **Online documentations sharing** for reviews (using the
[online version](#online-version))
# Installation
```sh
$ npm install -g elm-doc-preview
```
Then, from the directory where your package `elm.json` is:
# Usage
```sh
Usage: edp|elm-doc-preview [options] [path_to_package_or_application]
Options:
-V, --version output the version number
-p, --port <port> the server listening port (default: 8000)
-h, --help output usage information
Environment variables:
ELM_HOME Elm home directory (cache)
```
For example, from the directory where your package `elm.json` is:
```sh
$ elm-doc-preview
```
or
```
$ edp
```
or from anywhere:
```sh
$ elm-doc-preview path/to/package
$ elm-doc-preview path/to/package_or_application
```
As a side effect, this also allows to view installed packages documentation offline from the local cache:
# Online version
There is also an online version supporting documentations loading from github
to share them for online reviews:
https://elm-doc-preview.netlify.com
It does not support hot-reloading or dependencies documentation though.
# API
```javascript
const DocServer = require('elm-doc-preview');
// constructor(path_to_elm_json = ".")
const server = new DocServer();
// Optionaly exit cleanly on SIGINT to let temporary files be removed
process.on("SIGINT", () => { process.exit(0); });
// listen(port = 8000)
server.listen();
```
$ elm-doc-preview ~/.elm/0.19.0/package/elm/html/1.0.0/
```
# Credits
* Documentation rendering from [package.elm-lang.org](https://github.com/elm/package.elm-lang.org) by Evan Czaplicki.
* Markdown rendering from [Marked.js](https://github.com/markedjs/marked) by Christopher Jeffrey.
* Code highlighting from [highlight.js](https://github.com/highlightjs/highlight.js) by Ivan Sagalaev.
* Code highlighting theme from [Solarized](ethanschoonover.com/solarized) by Jeremy Hull.
* CSS spinner from [SpinKit](https://github.com/tobiasahlin/SpinKit) by Tobias Ahlin.
- Documentation rendering from [package.elm-lang.org](https://github.com/elm/package.elm-lang.org) by Evan Czaplicki.
- Markdown rendering from [Marked.js](https://github.com/markedjs/marked) by Christopher Jeffrey.
- Code highlighting from [highlight.js](https://github.com/highlightjs/highlight.js) by Ivan Sagalaev.
- Code highlighting theme from [Solarized](ethanschoonover.com/solarized) by Jeremy Hull.
- CSS spinner from [SpinKit](https://github.com/tobiasahlin/SpinKit) by Tobias Ahlin.

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

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