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.5 to 0.0.6

47

cli.js

@@ -15,30 +15,41 @@ #!/usr/bin/env node

const glob = require("glob");
const { Documentalist } = require("./dist/");
const { Documentalist, KssPlugin, MarkdownPlugin, TypescriptPlugin } = require("./dist/");
const argv = yargs
.alias("v", "version")
.version(require("./package.json").version)
.usage("$0 [options] <files>")
.option("md", {
default: true,
desc: "use MarkdownPlugin for .md files",
type: "boolean",
})
.option("ts", {
default: true,
desc: "use TypescriptPlugin for .tsx? files",
type: "boolean",
})
.option("css", {
desc: "use KssPlugin for .(css|less|scss) files",
type: "boolean",
})
.demandCommand(1, "Requires at least one file")
// TODO: how to specify plugin on CLI?
// .option("--use [pattern:plugin]", "Use a plugin to process files matching the pattern")
.argv;
// ensure `use` option is always an array
const plugins = [].concat(argv.use)
.filter((use) => use !== undefined)
.map((/** @type {string} */ use) => {
const [pattern, plugin] = use.split(":");
if (plugin === undefined) {
console.error("invalid --use option '%s'", use);
process.exit(1);
}
return { pattern, plugin };
});
let docs = Documentalist.create();
const docs = Documentalist.create();
plugins.forEach(({ pattern, plugin }) => {
docs.use(new RegExp(pattern), plugin);
});
if (argv.md) {
docs = docs.use(".md", new MarkdownPlugin());
}
if (argv.ts) {
docs = docs.use(/\.tsx?$/, new TypescriptPlugin({
excludePaths: ["__tests__"],
}));
}
if (argv.css) {
docs = docs.use(/\.(css|less|s[ac]ss)$/, new KssPlugin());
}
docs.documentGlobs(...argv._)
.then((data) => JSON.stringify(data, null, 2))
.then(console.log, console.error);

@@ -71,5 +71,6 @@ /**

const { contents } = API.renderBlock(FILE, ["interface"]);
expect(contents).toHaveLength(3);
// reserved @tag is emitted as separate string cuz it's still split by regex
expect(contents[1]).toEqual("<p>@interface IButtonProps</p>\n");
// only one string (reserved @word does not get split to its own entry)
expect(contents).toHaveLength(1);
// @tag value comes out exactly as written in source, on its own line
expect(contents[0].split("\n")).toContain("@interface IButtonProps");
});

@@ -76,0 +77,0 @@ });

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

const index_1 = require("../index");
const markdown_1 = require("../plugins/markdown");
const TEST_MARKDOWN = `---

@@ -42,4 +43,6 @@ key: value

describe("Plugins", () => {
const dm = index_1.Documentalist.create()
.use(".md", new markdown_1.MarkdownPlugin());
it("can document Markdown files", () => __awaiter(this, void 0, void 0, function* () {
const docs = yield index_1.Documentalist.create().documentFiles(TEST_FILES);
const docs = yield dm.documentFiles(TEST_FILES);
const page = docs.pages["test"];

@@ -46,0 +49,0 @@ expect(page).toBeDefined();

/// <reference types="marked" />
import { IBlock, ICompiler } from "./plugins/plugin";
export interface ICompilerOptions {
/** Options for markdown rendering. See https://github.com/chjj/marked#options-1. */
markdown?: MarkedOptions;
/**
* Reserved @tags that should be preserved in the contents string.
* A common use case is allowing specific code constructs, like `@Decorator` names.
* Do not include the `@` prefix in the strings.
*/
reservedTags?: string[];
}
export declare class Compiler implements ICompiler {
private markedOptions;
constructor(markedOptions: MarkedOptions);
private options;
constructor(options: ICompilerOptions);
objectify<T>(array: T[], getKey: (item: T) => string): {
[key: string]: T;
};
renderBlock: (blockContent: string, reservedTagWords?: string[]) => IBlock;
renderBlock: (blockContent: string, reservedTagWords?: string[] | undefined) => IBlock;
renderMarkdown: (markdown: string) => string;

@@ -16,3 +26,3 @@ /**

*/
private renderContents(content, reservedTagWords);
private renderContents(content, reservedTagWords?);
/**

@@ -28,3 +38,3 @@ * Extracts optional YAML frontmatter metadata block from the beginning of a

*/
private parseTags(content, reservedWords);
private parseTags(content, reservedWords?);
}

@@ -15,16 +15,6 @@ "use strict";

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 Compiler {
constructor(markedOptions) {
this.markedOptions = markedOptions;
this.renderBlock = (blockContent, reservedTagWords = RESERVED_WORDS) => {
constructor(options) {
this.options = options;
this.renderBlock = (blockContent, reservedTagWords = this.options.reservedTags) => {
const { contentsRaw, metadata } = this.extractMetadata(blockContent);

@@ -34,3 +24,3 @@ const contents = this.renderContents(contentsRaw, reservedTagWords);

};
this.renderMarkdown = (markdown) => marked(markdown, this.markedOptions);
this.renderMarkdown = (markdown) => marked(markdown, this.options.markdown);
}

@@ -71,20 +61,30 @@ objectify(array, getKey) {

*/
parseTags(content, reservedWords) {
return content.split(TAG_SPLIT_REGEX).map((str) => {
parseTags(content, reservedWords = []) {
// using reduce so we can squash consecutive strings (<= 1 entry per iteration)
return content.split(TAG_SPLIT_REGEX).reduce((arr, str) => {
const match = TAG_REGEX.exec(str);
if (match === null || reservedWords.indexOf(match[1]) >= 0) {
return str;
if (typeof arr[arr.length - 1] === "string") {
// merge consecutive strings to avoid breaking up code blocks
arr[arr.length - 1] += str;
}
else {
arr.push(str);
}
}
const tag = match[1];
const value = match[2];
if (/#+/.test(tag)) {
// NOTE: not enough information to populate `route` field yet
return { tag: "heading", value, level: tag.length };
}
else {
return { tag, value };
const tag = match[1];
const value = match[2];
if (/#+/.test(tag)) {
// NOTE: not enough information to populate `route` field yet
arr.push({ tag: "heading", value, level: tag.length });
}
else {
arr.push({ tag, value });
}
}
});
return arr;
}, []);
}
}
exports.Compiler = Compiler;

@@ -1,3 +0,3 @@

/// <reference types="marked" />
import { IFile, IMarkdownPluginData, IPlugin, ITypescriptPluginData } from "./plugins";
import { ICompilerOptions } from "./compiler";
import { IFile, IPlugin } from "./plugins";
export interface IApi<T> {

@@ -47,6 +47,6 @@ /**

export declare class Documentalist<T> implements IApi<T> {
private options;
private plugins;
private markedOptions;
static create(markedOptions?: MarkedOptions): IApi<IMarkdownPluginData & ITypescriptPluginData>;
constructor(plugins?: Array<IPluginEntry<T>>, markedOptions?: MarkedOptions);
static create(options?: ICompilerOptions): IApi<{}>;
constructor(options?: ICompilerOptions, plugins?: Array<IPluginEntry<T>>);
use<P>(pattern: RegExp | string, plugin: IPlugin<P>): IApi<T & P>;

@@ -53,0 +53,0 @@ clearPlugins(): IApi<{}>;

@@ -21,12 +21,9 @@ /**

const compiler_1 = require("./compiler");
const plugins_1 = require("./plugins");
class Documentalist {
constructor(plugins = [], markedOptions = {}) {
constructor(options = {}, plugins = []) {
this.options = options;
this.plugins = plugins;
this.markedOptions = markedOptions;
}
static create(markedOptions) {
return new Documentalist([], markedOptions)
.use(/\.md$/, new plugins_1.MarkdownPlugin())
.use(/\.tsx?$/, new plugins_1.TypescriptPlugin());
static create(options) {
return new Documentalist(options, []);
}

@@ -38,6 +35,6 @@ use(pattern, plugin) {

const newPlugins = [...this.plugins, { pattern, plugin }];
return new Documentalist(newPlugins, this.markedOptions);
return new Documentalist(this.options, newPlugins);
}
clearPlugins() {
return new Documentalist([], this.markedOptions);
return new Documentalist(this.options, []);
}

@@ -52,3 +49,3 @@ documentGlobs(...filesGlobs) {

return __awaiter(this, void 0, void 0, function* () {
const compiler = new compiler_1.Compiler(this.markedOptions);
const compiler = new compiler_1.Compiler(this.options);
const documentation = {};

@@ -55,0 +52,0 @@ for (const { pattern, plugin } of this.plugins) {

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

*/
import { IJsDocTags } from "ts-quick-docs";
import { IDocumentationOptions, IJsDocTags } from "ts-quick-docs";
import { IBlock, ICompiler, IFile, IPlugin } from "./plugin";

@@ -30,2 +30,23 @@ export interface ITsDocEntry {

export declare class TypescriptPlugin implements IPlugin<ITypescriptPluginData> {
/**
* Options to `ts-quick-docs`, mostly for customizing which symbols appear in the output.
*/
private options;
/**
* Compiler options for Typescript program used to "read" your typings.
* (This is distinct from whatever options you need to build your typings.)
* If omitted, the default compiler options are used.
*/
private compilerOptions;
constructor(
/**
* Options to `ts-quick-docs`, mostly for customizing which symbols appear in the output.
*/
options?: IDocumentationOptions,
/**
* Compiler options for Typescript program used to "read" your typings.
* (This is distinct from whatever options you need to build your typings.)
* If omitted, the default compiler options are used.
*/
compilerOptions?: any);
compile(files: IFile[], {renderBlock, objectify}: ICompiler): {

@@ -32,0 +53,0 @@ ts: {

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

class TypescriptPlugin {
constructor(
/**
* Options to `ts-quick-docs`, mostly for customizing which symbols appear in the output.
*/
options = {},
/**
* Compiler options for Typescript program used to "read" your typings.
* (This is distinct from whatever options you need to build your typings.)
* If omitted, the default compiler options are used.
*/
// HACK: using any to avoid duplicate typings issue with ts.CompilerOptions
compilerOptions = {}) {
this.options = options;
this.compilerOptions = compilerOptions;
}
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 entries = ts_quick_docs_1.default.fromFiles(files.map((f) => f.path), this.compilerOptions, this.options)
.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);

@@ -15,0 +31,0 @@ return { ts };

{
"name": "documentalist",
"version": "0.0.5",
"version": "0.0.6",
"description": "documentation for the rest of us",

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

@@ -5,2 +5,5 @@ # Documentalist

[![npm](https://img.shields.io/npm/v/documentalist.svg)](https://www.npmjs.com/package/documentalist)
[![CircleCI](https://circleci.com/gh/palantir/documentalist.svg?style=shield&circle-token=1dbd27fe833e64bafb3e8de8ee111a2aee9bb79d)](https://circleci.com/gh/palantir/documentalist)
## Documentalism 101

@@ -16,10 +19,13 @@

- `.ts`, `.tsx` files for JSDoc comments on interfaces in TypeScript source code
- `.css`, `.scss` files for comments on CSS selectors
- `.css`, `.less`, `.scss` files for comments on CSS selectors
With the JavaScript API, nothing comes for free. All plugins must be registered with `.use()`.
```js
const { Documentalist } = require("documentalist");
const { Documentalist, MarkdownPlugin } = require("documentalist");
const { writeFileSync } = require("fs");
const dm = new Documentalist();
const docs = dm.documentGlobs("src/**/*");
const docs = new Documentalist()
.use(".md", new MarkdownPlugin())
.documentGlobs("src/**/*");

@@ -29,2 +35,9 @@ writeFileSync("docs.json", JSON.stringify(docs, null, 2));

With the CLI, the Markdown and Typescript plugins are enabled by default.
The CSS plugin can be enabled with `--css`.
```sh
documentalist "src/**/*" --css --no-ts > docs.json
```
# License

@@ -31,0 +44,0 @@

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