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

documentalist

Package Overview
Dependencies
Maintainers
1
Versions
21
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

documentalist - npm Package Compare versions

Comparing version 0.0.2 to 0.0.3

dist/compiler.d.ts

10

cli.js

@@ -37,8 +37,8 @@ #!/usr/bin/env node

const doc = new Documentalist();
const docs = Documentalist.create();
plugins.forEach(({ pattern, plugin }) => {
doc.use(new RegExp(pattern), plugin);
docs.use(new RegExp(pattern), plugin);
});
const documentation = doc.documentGlobs(...argv._);
console.log(JSON.stringify(documentation, null, 2));
docs.documentGlobs(...argv._)
.then((data) => JSON.stringify(data, null, 2))
.then(console.log, console.error);

@@ -7,3 +7,2 @@ /**

*/
import { IInterfaceEntry } from "./plugins/typescript";
/** Represents a single `@tag <value>` line from a file. */

@@ -61,13 +60,2 @@ export interface ITag {

}
/**
* The root type of data exported by Documentalist.
* Each plugin emits its data in a separate key.
*/
export interface IDocumentalistData {
docs: {
[key: string]: IPageData;
};
ts: IInterfaceEntry[];
[plugin: string]: any;
}
/** One page entry in a layout tree. */

@@ -74,0 +62,0 @@ export interface ITreeEntry {

@@ -8,2 +8,3 @@ /**

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/** type guard to determine if a `contents` node is an `@tag` statement */

@@ -56,2 +57,1 @@ function isTag(node) {

exports.createNavigableTree = createNavigableTree;
//# sourceMappingURL=client.js.map
/// <reference types="marked" />
import { IDocumentalistData, StringOrTag } from "./client";
import { IFile, IPlugin } from "./plugins";
export interface IBlock {
content: string;
metadata: any;
renderedContent: StringOrTag[];
}
export interface IApi {
/** Process the given globs and emit all the data. */
documentGlobs: (...filesGlobs: string[]) => IDocumentalistData;
/** Process the given list of files and emit all the data. */
documentFiles: (files: IFile[]) => IDocumentalistData;
import { IFile, IMarkdownPluginData, IPlugin, ITypescriptPluginData } from "./plugins";
export interface IApi<T> {
/**
* Render a block of content by extracting metadata front matter and
* splitting text content into rendered HTML strings and `{ tag, value }` objects.
* Finds all files matching the provided variadic glob expressions and then
* runs `documentFiles` with them, emitting all the documentation data.
*
* @see documentFiles
*/
renderBlock: (blockContent: string, reservedTagWords?: string[]) => IBlock;
/** Use a plugin to process the files matching the pattern. */
use: (pattern: RegExp, plugin: IPlugin<any>) => IApi;
}
export declare class Documentalist implements IApi {
private markedOptions;
private plugins;
constructor(markedOptions?: MarkedOptions);
use(pattern: RegExp, plugin: IPlugin<any>): this;
documentGlobs(...filesGlobs: string[]): IDocumentalistData;
documentFiles(files: IFile[]): IDocumentalistData;
renderBlock(blockContent: string, reservedTagWords?: string[]): IBlock;
/** Expand an array of globs and flatten to a single array of files. */
private expandGlobs(filesGlobs);
documentGlobs: (...filesGlobs: string[]) => Promise<T>;
/**
* Converts the content string into an array of `ContentNode`s. If the
* `contents` option is `html`, the string nodes will also be rendered with
* markdown.
* Iterates over all plugins, passing all matching files to each in turn.
* The output of each plugin is merged to produce the resulting
* documentation object.
*
* The return type T is a composite type has a composite type of all the
* plugin data types.
*/
private renderContents(content, reservedTagWords);
documentFiles: (files: IFile[]) => Promise<T>;
/**
* Extracts optional YAML frontmatter metadata block from the beginning of a
* markdown file and parses it to a JS object.
* Adds the plugin to Documentalist. Returns a new instance of Documentalist
* with a template type that includes the data from the plugin. This way the
* `documentFiles` and `documentGlobs` methods will return an object that is
* already typed to include each plugin's output.
*
* The plugin is applied to all files whose absolute path matches the
* supplied pattern.
*
* @param pattern - A regexp pattern or a file extension string like "js"
* @param plugin - The plugin implementation
* @returns A new instance of `Documentalist` with an extended type
*/
private extractMetadata(text);
use: <P>(pattern: RegExp | string, plugin: IPlugin<P>) => IApi<T & P>;
/**
* Splits the content string when it encounters a line that begins with a
* `@tag`. You may prevent this splitting by specifying an array of reserved
* tag names.
* Returns a new instance of Documentalist with no plugins.
*/
private parseTags(content, reservedWords);
clearPlugins(): IApi<{}>;
}
/**
* Plugins are stored with the regex used to match against file paths.
*/
export interface IPluginEntry<T> {
pattern: RegExp;
plugin: IPlugin<T>;
}
export declare class Documentalist<T> implements IApi<T> {
private plugins;
private markedOptions;
static create(markedOptions?: MarkedOptions): IApi<IMarkdownPluginData & ITypescriptPluginData>;
constructor(plugins?: Array<IPluginEntry<T>>, markedOptions?: MarkedOptions);
use<P>(pattern: RegExp | string, plugin: IPlugin<P>): IApi<T & P>;
clearPlugins(): IApi<{}>;
documentGlobs(...filesGlobs: string[]): Promise<T>;
documentFiles(files: IFile[]): Promise<T>;
/**
* Expands an array of globs and flatten to a single array of files.
*/
private expandGlobs(filesGlobs);
/**
* Shallow-merges keys form source into destination object (modifying it in the process).
*/
private mergeInto(destination, source);
}

@@ -8,57 +8,57 @@ /**

"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const fs = require("fs");
const glob = require("glob");
const yaml = require("js-yaml");
const marked = require("marked");
const path = require("path");
const compiler_1 = require("./compiler");
const plugins_1 = require("./plugins");
/**
* Matches the triple-dash metadata block on the first line of markdown file.
* The first capture group contains YAML content.
*/
const METADATA_REGEX = /^---\n?((?:.|\n)*)\n---\n/;
/**
* Splits text content for lines that begin with `@tagName`.
*/
const TAG_REGEX = /^@(\S+)(?:\s+([^\n]+))?$/;
const TAG_SPLIT_REGEX = /^(@\S+(?:\s+[^\n]+)?)$/gm;
/**
* Ignored `@tag` names. Some languages already support `@tags`, so to separate
* Documentalist tags, we use these default reserved words to avoid conflicts.
*
* Plugins may define their own reserved words when calling the `renderBlock`
* method.
*/
const RESERVED_WORDS = [
"import",
];
class Documentalist {
constructor(markedOptions = {}) {
constructor(plugins = [], markedOptions = {}) {
this.plugins = plugins;
this.markedOptions = markedOptions;
this.plugins = [];
this.use(/\.md$/, new plugins_1.MarkdownPlugin());
this.use(/\.s?css$/, new plugins_1.CssPlugin());
this.use(/\.tsx?$/, new plugins_1.TypescriptPlugin());
}
static create(markedOptions) {
return new Documentalist([], markedOptions)
.use(/\.md$/, new plugins_1.MarkdownPlugin())
.use(/\.tsx?$/, new plugins_1.TypescriptPlugin());
}
use(pattern, plugin) {
this.plugins.push({ pattern, plugin });
return this;
if (typeof pattern === "string") {
pattern = new RegExp(`${pattern}$`);
}
const newPlugins = [...this.plugins, { pattern, plugin }];
return new Documentalist(newPlugins, this.markedOptions);
}
clearPlugins() {
return new Documentalist([], this.markedOptions);
}
documentGlobs(...filesGlobs) {
const files = this.expandGlobs(filesGlobs);
return this.documentFiles(files);
return __awaiter(this, void 0, void 0, function* () {
const files = this.expandGlobs(filesGlobs);
return this.documentFiles(files);
});
}
documentFiles(files) {
const documentation = {};
for (const { pattern, plugin } of this.plugins) {
documentation[plugin.name] = plugin.compile(this, files.filter((f) => pattern.test(f.path)));
}
return documentation;
return __awaiter(this, void 0, void 0, function* () {
const compiler = new compiler_1.Compiler(this.markedOptions);
const documentation = {};
for (const { pattern, plugin } of this.plugins) {
const pluginFiles = files.filter((f) => pattern.test(f.path));
const pluginDocumentation = yield plugin.compile(pluginFiles, compiler);
this.mergeInto(documentation, pluginDocumentation);
}
return documentation;
});
}
renderBlock(blockContent, reservedTagWords = RESERVED_WORDS) {
const { content, metadata } = this.extractMetadata(blockContent);
const renderedContent = this.renderContents(content, reservedTagWords);
return { content, metadata, renderedContent };
}
/** Expand an array of globs and flatten to a single array of files. */
/**
* Expands an array of globs and flatten to a single array of files.
*/
expandGlobs(filesGlobs) {

@@ -77,45 +77,16 @@ return filesGlobs

/**
* Converts the content string into an array of `ContentNode`s. If the
* `contents` option is `html`, the string nodes will also be rendered with
* markdown.
* Shallow-merges keys form source into destination object (modifying it in the process).
*/
renderContents(content, reservedTagWords) {
const splitContents = this.parseTags(content, reservedTagWords);
return splitContents
.map((node) => typeof node === "string" ? marked(node, this.markedOptions) : node)
.filter((node) => node !== "");
}
/**
* Extracts optional YAML frontmatter metadata block from the beginning of a
* markdown file and parses it to a JS object.
*/
extractMetadata(text) {
const match = METADATA_REGEX.exec(text);
if (match === null) {
return { content: text, metadata: {} };
mergeInto(destination, source) {
for (const key in source) {
if (source.hasOwnProperty(key)) {
if (destination.hasOwnProperty(key)) {
console.warn(`WARNING: Duplicate plugin key "${key}". Your plugins are overwriting each other.`);
}
destination[key] = source[key];
}
}
const content = text.substr(match[0].length);
return { content, metadata: yaml.load(match[1]) || {} };
return destination;
}
/**
* Splits the content string when it encounters a line that begins with a
* `@tag`. You may prevent this splitting by specifying an array of reserved
* tag names.
*/
parseTags(content, reservedWords) {
return content.split(TAG_SPLIT_REGEX).map((str) => {
const match = TAG_REGEX.exec(str);
if (match === null || reservedWords.indexOf(match[1]) >= 0) {
return str;
}
else {
return {
tag: match[1],
value: match[2],
};
}
});
}
}
exports.Documentalist = Documentalist;
//# sourceMappingURL=documentalist.js.map

@@ -7,3 +7,4 @@ /**

*/
export * from "./client";
export * from "./documentalist";
export * from "./client";
export * from "./plugins";

@@ -11,4 +11,5 @@ /**

}
Object.defineProperty(exports, "__esModule", { value: true });
__export(require("./client"));
__export(require("./documentalist"));
__export(require("./client"));
//# sourceMappingURL=index.js.map
__export(require("./plugins"));

@@ -8,10 +8,3 @@ /**

"use strict";
var __assign = (this && this.__assign) || Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
const path = require("path");

@@ -22,3 +15,3 @@ const client_1 = require("./client");

const reference = getReference(props);
return __assign({}, props, { reference, title });
return Object.assign({}, props, { reference, title });
}

@@ -42,2 +35,1 @@ exports.makePage = makePage;

}
//# sourceMappingURL=page.js.map

@@ -7,5 +7,5 @@ /**

*/
export * from "./css";
export * from "./kss";
export * from "./markdown";
export * from "./plugin";
export * from "./typescript";

@@ -11,5 +11,5 @@ /**

}
__export(require("./css"));
Object.defineProperty(exports, "__esModule", { value: true });
__export(require("./kss"));
__export(require("./markdown"));
__export(require("./typescript"));
//# sourceMappingURL=index.js.map

@@ -7,10 +7,10 @@ /**

*/
import { Documentalist } from "..";
import { IPageData } from "../client";
import { IFile, IPlugin } from "./plugin";
export declare type IPageMap = {
[key: string]: IPageData;
};
export declare class MarkdownPlugin implements IPlugin<IPageMap> {
name: string;
import { ICompiler, IFile, IPlugin } from "./plugin";
export interface IMarkdownPluginData {
docs: {
[key: string]: IPageData;
};
}
export declare class MarkdownPlugin implements IPlugin<IMarkdownPluginData> {
/**

@@ -20,5 +20,7 @@ * Reads the given set of markdown files and adds their data to the internal storage.

*/
compile(documentalist: Documentalist, markdownFiles: IFile[]): {
[key: string]: IPageData;
compile(markdownFiles: IFile[], {renderBlock}: ICompiler): {
docs: {
[key: string]: IPageData;
};
};
}

@@ -8,7 +8,5 @@ /**

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const page_1 = require("../page");
class MarkdownPlugin {
constructor() {
this.name = "docs";
}
/**

@@ -18,3 +16,3 @@ * Reads the given set of markdown files and adds their data to the internal storage.

*/
compile(documentalist, markdownFiles) {
compile(markdownFiles, { renderBlock }) {
const pageStore = new Map();

@@ -25,3 +23,3 @@ markdownFiles

const fileContents = file.read();
const { content, metadata, renderedContent } = documentalist.renderBlock(fileContents);
const { content, metadata, renderedContent } = renderBlock(fileContents);
const page = page_1.makePage({

@@ -57,3 +55,4 @@ absolutePath,

});
return mapToObject(pageStore);
const docs = mapToObject(pageStore);
return { docs };
}

@@ -69,2 +68,1 @@ }

}
//# sourceMappingURL=markdown.js.map

@@ -7,3 +7,7 @@ /**

*/
import { Documentalist } from "..";
import { StringOrTag } from "../client";
export { StringOrTag };
/**
* Abstract representation of a file, containing absolute path and synchronous `read` operation.
*/
export interface IFile {

@@ -13,5 +17,44 @@ path: string;

}
/**
* The output of `renderBlock` which parses a long form documentation block into
* metadata, rendered markdown, and tags.
*/
export interface IBlock {
/**
* The original string content block.
*/
content: string;
/**
* Parsed YAML front matter (if any) or {}.
*/
metadata: any;
/**
* An array of markdown-rendered HTML or tags.
*/
renderedContent: StringOrTag[];
}
/**
* Each plugin receives a `Compiler` instance to aid in the processing of source files.
*/
export interface ICompiler {
/**
* Converts an array of entries into a map of key to entry, using given
* callback to extract key from each item.
*/
objectify: <T>(array: T[], getKey: (item: T) => string) => {
[key: string]: T;
};
/**
* Render a block of content by extracting metadata (YAML front matter) and
* splitting text content into markdown-rendered HTML strings and `{ tag,
* value }` objects.
*
* To prevent special strings like "@include" from being parsed, a reserved
* tag words array may be provided, in which case the line will be left as
* is.
*/
renderBlock: (blockContent: string, reservedTagWords?: string[]) => IBlock;
}
export interface IPlugin<T> {
name: string;
compile: (doc: Documentalist, files: IFile[]) => T;
compile: (files: IFile[], doc: ICompiler) => T | Promise<T>;
}

@@ -8,2 +8,2 @@ /**

"use strict";
//# sourceMappingURL=plugin.js.map
Object.defineProperty(exports, "__esModule", { value: true });

@@ -8,5 +8,4 @@ /**

import { IJsDocTags } from "ts-quick-docs";
import { Documentalist, IBlock } from "..";
import { IFile, IPlugin } from "./plugin";
export interface IDocEntry {
import { IBlock, ICompiler, IFile, IPlugin } from "./plugin";
export interface ITsDocEntry {
documentation: IBlock;

@@ -18,12 +17,20 @@ fileName: string;

}
export interface IPropertyEntry extends IDocEntry {
export interface ITsPropertyEntry extends ITsDocEntry {
optional?: boolean;
}
export interface IInterfaceEntry extends IDocEntry {
export interface ITsInterfaceEntry extends ITsDocEntry {
extends?: string[];
properties: IPropertyEntry[];
properties: ITsPropertyEntry[];
}
export declare class TypescriptPlugin implements IPlugin<IInterfaceEntry[]> {
name: string;
compile(documentalist: Documentalist, files: IFile[]): IInterfaceEntry[];
export interface ITypescriptPluginData {
ts: {
[name: string]: ITsInterfaceEntry;
};
}
export declare class TypescriptPlugin implements IPlugin<ITypescriptPluginData> {
compile(files: IFile[], {renderBlock, objectify}: ICompiler): {
ts: {
[key: string]: ITsInterfaceEntry;
};
};
}

@@ -8,20 +8,11 @@ /**

"use strict";
var __assign = (this && this.__assign) || Object.assign || function(t) {
for (var s, i = 1, n = arguments.length; i < n; i++) {
s = arguments[i];
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
t[p] = s[p];
}
return t;
};
Object.defineProperty(exports, "__esModule", { value: true });
const ts_quick_docs_1 = require("ts-quick-docs");
class TypescriptPlugin {
constructor() {
this.name = "ts";
compile(files, { renderBlock, objectify }) {
const entries = ts_quick_docs_1.default.fromFiles(files.map((f) => f.path), {}).map((entry) => (Object.assign({}, entry, { documentation: renderBlock(entry.documentation), properties: entry.properties.map((prop) => (Object.assign({}, prop, { documentation: renderBlock(prop.documentation) }))) })));
const ts = objectify(entries, (e) => e.name);
return { ts };
}
compile(documentalist, files) {
return ts_quick_docs_1.default.fromFiles(files.map((f) => f.path), {}).map((entry) => (__assign({}, entry, { documentation: documentalist.renderBlock(entry.documentation), properties: entry.properties.map((prop) => (__assign({}, prop, { documentation: documentalist.renderBlock(prop.documentation) }))) })));
}
}
exports.TypescriptPlugin = TypescriptPlugin;
//# sourceMappingURL=typescript.js.map
{
"name": "documentalist",
"version": "0.0.2",
"version": "0.0.3",
"description": "documentation for the rest of us",

@@ -13,5 +13,4 @@ "main": "dist/index.js",

"js-yaml": "^3.7.0",
"kss": "3.0.0-beta.15",
"marked": "^0.3.6",
"postcss": "^5.2.13",
"postcss-scss": "^0.4.1",
"ts-quick-docs": "^0.5.3",

@@ -27,14 +26,12 @@ "yargs": "^6.6.0"

"@types/node": "^6.0.52",
"@types/react": "^15.0.14",
"@types/yargs": "^6.6.0",
"chai": "^3.5.0",
"circle-github-bot": "^0.4.0",
"highlights": "^1.4.1",
"mocha": "^3.2.0",
"npm-run-all": "^4.0.2",
"pug-cli": "^1.0.0-alpha6",
"react": "^15.4.2",
"react-dom": "^15.4.2",
"ts-node": "^1.7.2",
"tslint": "^4.0.2",
"typescript": "2.1.5"
"ts-node": "^2.1.0",
"tslint": "^4.5.1",
"typescript": "^2.2.1"
},

@@ -41,0 +38,0 @@ "scripts": {

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