From 0c653ac6f43dbec161799651dcf6181862c1b144 Mon Sep 17 00:00:00 2001 From: "Zed A. Shaw" Date: Wed, 14 Dec 2022 20:03:08 -0500 Subject: [PATCH] A first attempt at a replacement for jsdoc. --- .eslintrc.json | 2 +- README.md | 4 +- commands/codedoc.js | 229 +++++++++++++++++++ lib/builderator.js | 16 +- package-lock.json | 417 ++++++++++++++++++++++++++++++++++ package.json | 1 + static/djenterator/command.js | 7 +- 7 files changed, 665 insertions(+), 11 deletions(-) create mode 100644 commands/codedoc.js diff --git a/.eslintrc.json b/.eslintrc.json index e0fcd48..4501e08 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -106,7 +106,7 @@ "max-statements": "off", "max-statements-per-line": "error", "multiline-comment-style": "off", - "new-cap": ["error", {"newIsCap": false, "capIsNew": true}], + "new-cap": ["off"], "new-parens": "error", "newline-after-var": "off", "newline-before-return": "off", diff --git a/README.md b/README.md index bb3bf9a..f16b4d7 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ -# bandolier-template +16. Then continue studying anything you find interesting and trying to change the existing pages. + +This should give you a quick crash course in how the framework operates while I work on better documentation and instructions.# bandolier-template The Bandolier (aka `bando`) is an educational web framework featured in the Learn JavaScript the Hard Way course. The Bandolier contains all of the features a full stack developer would need to learn, but with smaller easier to understand implementations that are fully visible in the project. It includes implementations of: diff --git a/commands/codedoc.js b/commands/codedoc.js new file mode 100644 index 0000000..7d5a869 --- /dev/null +++ b/commands/codedoc.js @@ -0,0 +1,229 @@ +// you may not need all of these but they come up a lot +import fs from "fs"; +import assert from "assert"; +import logging from '../lib/logging.js'; +import { mkdir, mkdir_to } from "../lib/builderator.js"; +import glob from "fast-glob"; +import path from "path"; +import template from "lodash/template.js"; +import * as acorn from "acorn"; +import * as acorn_walk from "acorn-walk"; + +const log = logging.create(import.meta.url); + +export const description = "Describe your command here." + +// your command uses the npm package commander's options format +export const options = [ +] + +// example of a positional argument, it's the 1st argument to main +export const argument = ["source", "source directory"]; + +// put required options in the required variable +export const required = [ + ["--output ", "Save to file rather than stdout."], +] + +// handy function for checking things are good and aborting +const check = (test, fail_message) => { + if(!test) { + log.error(fail_message); + process.exit(1); + } +} + +const dump = (obj) => { + return JSON.stringify(obj, null, 4); +} + +class ParseWalker { + constructor(comments) { + this.comments = comments; + this.exported = []; + } + + handle_class(root) { + const new_class = { + isa: "class", + name: root.declaration.id.name, + line_start: root.loc.start.line, + methods: [], + } + + new_class.comment = this.find_comment(new_class.line_start); + + acorn_walk.simple(root, { + ClassDeclaration: (cls_node) => { + assert(cls_node.id.name === new_class.name, "Name of class changed!"); + this.exported.push(new_class); + }, + + MethodDefinition: (meth_node) => { + const new_method = { + isa: "method", + static: meth_node.static, + async: meth_node.value.async, + generator: meth_node.value.generator, + name: meth_node.key.name, + line_start: meth_node.loc.start.line, + params: this.handle_params(meth_node.value.params), + comment: this.find_comment(meth_node.loc.start.line) + } + new_class.methods.push(new_method); + } + }); + } + + handle_params(param_list) { + const result = []; + + for(let param of param_list) { + acorn_walk.simple(param, { + Identifier: (_node) => { + result.push({isa: "identifier", name: _node.name}); + }, + + AssignmentPattern: (_node) => { + result.push({ + isa: "assignment", + name: _node.left.name, + right: { + type: _node.right.type.toLowerCase(), + raw: _node.right.raw, + value: _node.right.value, + name: _node.right.name, + }, + }); + } + }); + } + + return result; + } + + add_export(id, exp) { + exp.name = id.name; + exp.line_start = id.loc.start.line; + exp.comment = this.find_comment(exp.line_start); + this.exported.push(exp); + } + + handle_arrow_func(id, arrow) { + this.add_export(id, { + isa: "function", + async: arrow.async, + generator: arrow.generator, + expression: arrow.expression, + params: this.handle_params(arrow.params), + }); + } + + handle_variable(root) { + const declare = root.declaration.declarations[0]; + // console.log("VARIABLE", declare); + const id = declare.id; + + if(declare.init.type === "ArrowFunctionExpression") { + this.handle_arrow_func(id, declare.init); + } else { + acorn_walk.simple(root, { + Literal: (_node) => { + this.add_export(id, { + isa: _node.type.toLowerCase(), + value: _node.value, + raw: _node.raw + }); + }, + CallExpression: (_node) => { + this.add_export(id, { + isa: _node.type.toLowerCase(), + identifier: _node.callee.name, + arguments: this.handle_params(_node.arguments) + }); + }, + MemberExpression: (_node) => { + this.add_export(id, { + isa: _node.type.toLowerCase(), + object: _node.object.name, + property: _node.property.name, + computed: _node.computed, + options: _node.optional, + }); + } + }); + } + } + + /** + * Find the nearest comment to this line, giving + * about 2 lines of slack. + */ + find_comment(line) { + for(let c of this.comments) { + const distance = c.end - line; + if(!c.found && distance < 0 && distance > -3) { + c.found = true; + return c; + } + } + + return undefined; + } + + handle_export(_node) { + switch(_node.declaration.type) { + case "ClassDeclaration": + this.handle_class(_node); + break; + case "VariableDeclaration": { + this.handle_variable(_node); + break; + } + default: + console.log(">>>", _node.declaration.type); + } + } +} + +export const main = async (arg, opts) => { + const code = fs.readFileSync(arg); + + mkdir(opts.output); + let comments = []; + + const acorn_opts = { + sourceType: "module", + ecmaVersion: "2023", + locations: true, + sourceFile: arg, + ranges: true, + onComment: comments + } + + const parsed = acorn.parse(code, acorn_opts); + + comments = comments.filter(c => c.type === "Block").map(c => { + return { + start: c.loc.start.line, + end: c.loc.end.line, + value: c.value, + type: "comment", + found: false, + } + }); + + const walker = new ParseWalker(comments); + // acorn is stupid and they grab a reference to the functions so that _removes_ + // this from the object, instead of just...calling walker.function() like a normal person + acorn_walk.simple(parsed, { + ExportNamedDeclaration: (_node) => walker.handle_export(_node), + }); + + console.log(dump({ + exports: walker.exported, + orphan_comments: walker.comments.filter(c => !c.found) + })); + + process.exit(0); +} diff --git a/lib/builderator.js b/lib/builderator.js index d2121bd..a1aca24 100644 --- a/lib/builderator.js +++ b/lib/builderator.js @@ -5,7 +5,9 @@ import { log } from "./logging.js"; import Path from "path"; import { execSync } from "child_process"; -// fast-glob is old and can't do import as +/** + * Fixes some common problems with fast-glob on windows. + */ export const glob = (path) => { if(process.platform === "win32") { // fast-glob doesn't understand \\ or C:\ @@ -26,8 +28,8 @@ export const changed = (source, target) => { return !t_stat || s_stat.mtimeMs > t_stat.mtimeMs; } +/* Makes a directory recursively. */ export const mkdir = (dir) => { - /* Makes a directory recursively. */ if(!fs.existsSync(dir)) { log.debug(`making dir ${dir}`); fs.mkdirSync(dir, { recursive: true }); @@ -44,17 +46,17 @@ export const mkdir_to = (target) => { mkdir(dirs.dir); } +/* Convenience function that makes sure the dir is there then writes the data. */ export const write = (target, data) => { - /* Convenience function that makes sure the dir is there then writes the data. */ mkdir_to(target); fs.writeFileSync(target, data); } +/** Like write but does an OS copy after making the target dir. When given a + * filter it will give the filter function the arguments, let it return contents, + * then write those instead of a copy. + */ export const copy = (src, dest, filter=null) => { - /** Like write but does an OS copy after making the target dir. When given a - * filter it will give the filter function the arguments, let it return contents, - * then write those instead of a copy. - */ mkdir_to(dest); if(filter) { diff --git a/package-lock.json b/package-lock.json index 06f40e9..9b035e5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -87,6 +87,7 @@ "istanbul-lib-coverage": "^3.0.2", "istanbul-lib-report": "^3.0.0", "istanbul-reports": "^3.0.5", + "jsdoc": "^4.0.0", "lodash": "^4.17.21", "neat-csv": "^7.0.0", "normalize-path": "^3.0.0", @@ -1027,6 +1028,18 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "node_modules/@jsdoc/salty": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.2.tgz", + "integrity": "sha512-A1FrVnc7L9qI2gUGsfN0trTiJNK72Y0CL/VAyrmYEmeKI3pnHDawP64CEev31XLyAAOx2xmDo3tbadPxC0CSbw==", + "dev": true, + "dependencies": { + "lodash": "^4.17.21" + }, + "engines": { + "node": ">=v12.0.0" + } + }, "node_modules/@mapbox/node-pre-gyp": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz", @@ -1792,6 +1805,22 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/linkify-it": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz", + "integrity": "sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==", + "dev": true + }, + "node_modules/@types/markdown-it": { + "version": "12.2.3", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz", + "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==", + "dev": true, + "dependencies": { + "@types/linkify-it": "*", + "@types/mdurl": "*" + } + }, "node_modules/@types/mdast": { "version": "3.0.7", "dev": true, @@ -1800,6 +1829,12 @@ "@types/unist": "*" } }, + "node_modules/@types/mdurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz", + "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==", + "dev": true + }, "node_modules/@types/minimatch": { "version": "3.0.4", "dev": true, @@ -3049,6 +3084,12 @@ "node": ">= 6" } }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, "node_modules/blueimp-md5": { "version": "2.18.0", "license": "MIT" @@ -3455,6 +3496,18 @@ "url": "https://opencollective.com/browserslist" } }, + "node_modules/catharsis": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", + "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", + "dev": true, + "dependencies": { + "lodash": "^4.17.15" + }, + "engines": { + "node": ">= 10" + } + }, "node_modules/cbor": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", @@ -7964,6 +8017,77 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/js2xmlparser": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", + "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==", + "dev": true, + "dependencies": { + "xmlcreate": "^2.0.4" + } + }, + "node_modules/jsdoc": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.0.tgz", + "integrity": "sha512-tzTgkklbWKrlaQL2+e3NNgLcZu3NaK2vsHRx7tyHQ+H5jcB9Gx0txSd2eJWlMC/xU1+7LQu4s58Ry0RkuaEQVg==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.9.4", + "@jsdoc/salty": "^0.2.1", + "@types/markdown-it": "^12.2.3", + "bluebird": "^3.7.2", + "catharsis": "^0.9.0", + "escape-string-regexp": "^2.0.0", + "js2xmlparser": "^4.0.2", + "klaw": "^3.0.0", + "markdown-it": "^12.3.2", + "markdown-it-anchor": "^8.4.1", + "marked": "^4.0.10", + "mkdirp": "^1.0.4", + "requizzle": "^0.2.3", + "strip-json-comments": "^3.1.0", + "underscore": "~1.13.2" + }, + "bin": { + "jsdoc": "jsdoc.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/jsdoc/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jsdoc/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jsdoc/node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/jsesc": { "version": "2.5.2", "dev": true, @@ -8070,6 +8194,15 @@ "node": ">=0.10.0" } }, + "node_modules/klaw": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", + "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.9" + } + }, "node_modules/kleur": { "version": "3.0.3", "license": "MIT", @@ -8217,6 +8350,15 @@ "dev": true, "license": "MIT" }, + "node_modules/linkify-it": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", + "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", + "dev": true, + "dependencies": { + "uc.micro": "^1.0.1" + } + }, "node_modules/load-ip-set": { "version": "2.2.1", "dev": true, @@ -8621,6 +8763,59 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/markdown-it": { + "version": "12.3.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", + "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1", + "entities": "~2.1.0", + "linkify-it": "^3.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/markdown-it-anchor": { + "version": "8.6.5", + "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.5.tgz", + "integrity": "sha512-PI1qEHHkTNWT+X6Ip9w+paonfIQ+QZP9sCeMYi47oqhH+EsW8CrJ8J7CzV19QVOj6il8ATGbK2nTECj22ZHGvQ==", + "dev": true, + "peerDependencies": { + "@types/markdown-it": "*", + "markdown-it": "*" + } + }, + "node_modules/markdown-it/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/markdown-it/node_modules/entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/marked": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.2.4.tgz", + "integrity": "sha512-Wcc9ikX7Q5E4BYDPvh1C6QNSxrjC9tBgz+A/vAhp59KXUgachw++uMvMKiSW8oA85nopmPZcEvBoex/YLMsiyA==", + "dev": true, + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 12" + } + }, "node_modules/matcher": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/matcher/-/matcher-5.0.0.tgz", @@ -8717,6 +8912,12 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", + "dev": true + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -12081,6 +12282,15 @@ "dev": true, "license": "MIT" }, + "node_modules/requizzle": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.4.tgz", + "integrity": "sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==", + "dev": true, + "dependencies": { + "lodash": "^4.17.21" + } + }, "node_modules/resolve": { "version": "1.20.0", "license": "MIT", @@ -14690,6 +14900,12 @@ "node": "*" } }, + "node_modules/uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true + }, "node_modules/uid-safe": { "version": "2.1.5", "license": "MIT", @@ -14725,6 +14941,12 @@ "version": "2.0.5", "license": "MIT" }, + "node_modules/underscore": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", + "dev": true + }, "node_modules/unified": { "version": "9.2.2", "dev": true, @@ -15549,6 +15771,12 @@ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-2.0.3.tgz", "integrity": "sha512-jLN68Dx5kyFHaePoXWPsCGW5qdyZQtLYHkxkg02/Mz6g0kYpDx4FyP6XfArhQdlOC4b8Mv+EMxPo/8La7Tzghg==" }, + "node_modules/xmlcreate": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", + "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", + "dev": true + }, "node_modules/xmlhttprequest-ssl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", @@ -16319,6 +16547,15 @@ "@jridgewell/sourcemap-codec": "^1.4.10" } }, + "@jsdoc/salty": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/@jsdoc/salty/-/salty-0.2.2.tgz", + "integrity": "sha512-A1FrVnc7L9qI2gUGsfN0trTiJNK72Y0CL/VAyrmYEmeKI3pnHDawP64CEev31XLyAAOx2xmDo3tbadPxC0CSbw==", + "dev": true, + "requires": { + "lodash": "^4.17.21" + } + }, "@mapbox/node-pre-gyp": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz", @@ -16876,6 +17113,22 @@ "version": "2.0.3", "dev": true }, + "@types/linkify-it": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.2.tgz", + "integrity": "sha512-HZQYqbiFVWufzCwexrvh694SOim8z2d+xJl5UNamcvQFejLY/2YUtzXHYi3cHdI7PMlS8ejH2slRAOJQ32aNbA==", + "dev": true + }, + "@types/markdown-it": { + "version": "12.2.3", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-12.2.3.tgz", + "integrity": "sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==", + "dev": true, + "requires": { + "@types/linkify-it": "*", + "@types/mdurl": "*" + } + }, "@types/mdast": { "version": "3.0.7", "dev": true, @@ -16883,6 +17136,12 @@ "@types/unist": "*" } }, + "@types/mdurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.2.tgz", + "integrity": "sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==", + "dev": true + }, "@types/minimatch": { "version": "3.0.4", "dev": true @@ -17694,6 +17953,12 @@ } } }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, "blueimp-md5": { "version": "2.18.0" }, @@ -17963,6 +18228,15 @@ "version": "1.0.30001251", "dev": true }, + "catharsis": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/catharsis/-/catharsis-0.9.0.tgz", + "integrity": "sha512-prMTQVpcns/tzFgFVkVp6ak6RykZyWb3gu8ckUpd6YkTlacOd3DXGJjIpD4Q6zJirizvaiAjSSHlOsA+6sNh2A==", + "dev": true, + "requires": { + "lodash": "^4.17.15" + } + }, "cbor": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/cbor/-/cbor-8.1.0.tgz", @@ -20801,6 +21075,58 @@ "esprima": "^4.0.0" } }, + "js2xmlparser": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/js2xmlparser/-/js2xmlparser-4.0.2.tgz", + "integrity": "sha512-6n4D8gLlLf1n5mNLQPRfViYzu9RATblzPEtm1SthMX1Pjao0r9YI9nw7ZIfRxQMERS87mcswrg+r/OYrPRX6jA==", + "dev": true, + "requires": { + "xmlcreate": "^2.0.4" + } + }, + "jsdoc": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsdoc/-/jsdoc-4.0.0.tgz", + "integrity": "sha512-tzTgkklbWKrlaQL2+e3NNgLcZu3NaK2vsHRx7tyHQ+H5jcB9Gx0txSd2eJWlMC/xU1+7LQu4s58Ry0RkuaEQVg==", + "dev": true, + "requires": { + "@babel/parser": "^7.9.4", + "@jsdoc/salty": "^0.2.1", + "@types/markdown-it": "^12.2.3", + "bluebird": "^3.7.2", + "catharsis": "^0.9.0", + "escape-string-regexp": "^2.0.0", + "js2xmlparser": "^4.0.2", + "klaw": "^3.0.0", + "markdown-it": "^12.3.2", + "markdown-it-anchor": "^8.4.1", + "marked": "^4.0.10", + "mkdirp": "^1.0.4", + "requizzle": "^0.2.3", + "strip-json-comments": "^3.1.0", + "underscore": "~1.13.2" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + } + } + }, "jsesc": { "version": "2.5.2", "dev": true @@ -20881,6 +21207,15 @@ "version": "6.0.3", "dev": true }, + "klaw": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/klaw/-/klaw-3.0.0.tgz", + "integrity": "sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.9" + } + }, "kleur": { "version": "3.0.3" }, @@ -20968,6 +21303,15 @@ "version": "1.1.6", "dev": true }, + "linkify-it": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", + "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", + "dev": true, + "requires": { + "uc.micro": "^1.0.1" + } + }, "load-ip-set": { "version": "2.2.1", "dev": true, @@ -21219,6 +21563,46 @@ "version": "4.2.1", "dev": true }, + "markdown-it": { + "version": "12.3.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", + "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", + "dev": true, + "requires": { + "argparse": "^2.0.1", + "entities": "~2.1.0", + "linkify-it": "^3.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", + "dev": true + } + } + }, + "markdown-it-anchor": { + "version": "8.6.5", + "resolved": "https://registry.npmjs.org/markdown-it-anchor/-/markdown-it-anchor-8.6.5.tgz", + "integrity": "sha512-PI1qEHHkTNWT+X6Ip9w+paonfIQ+QZP9sCeMYi47oqhH+EsW8CrJ8J7CzV19QVOj6il8ATGbK2nTECj22ZHGvQ==", + "dev": true, + "requires": {} + }, + "marked": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/marked/-/marked-4.2.4.tgz", + "integrity": "sha512-Wcc9ikX7Q5E4BYDPvh1C6QNSxrjC9tBgz+A/vAhp59KXUgachw++uMvMKiSW8oA85nopmPZcEvBoex/YLMsiyA==", + "dev": true + }, "matcher": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/matcher/-/matcher-5.0.0.tgz", @@ -21280,6 +21664,12 @@ "version": "2.0.0", "dev": true }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==", + "dev": true + }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -23570,6 +23960,15 @@ "version": "0.8.7", "dev": true }, + "requizzle": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/requizzle/-/requizzle-0.2.4.tgz", + "integrity": "sha512-JRrFk1D4OQ4SqovXOgdav+K8EAhSB/LJZqCz8tbX0KObcdeM15Ss59ozWMBWmmINMagCwmqn4ZNryUGpBsl6Jw==", + "dev": true, + "requires": { + "lodash": "^4.17.21" + } + }, "resolve": { "version": "1.20.0", "requires": { @@ -25259,6 +25658,12 @@ "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.32.tgz", "integrity": "sha512-dXVsz3M4j+5tTiovFVyVqssXBu5HM47//YSOeZ9fQkdDKkfzv2v3PP1jmH6FUyPW+yCSn7aBVK1fGGKNhowdDA==" }, + "uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", + "dev": true + }, "uid-safe": { "version": "2.1.5", "requires": { @@ -25284,6 +25689,12 @@ "undefsafe": { "version": "2.0.5" }, + "underscore": { + "version": "1.13.6", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.6.tgz", + "integrity": "sha512-+A5Sja4HP1M08MaXya7p5LvjuM7K6q/2EaC0+iovj/wOcMsTzMvDFbasi/oSapiwOlt252IqsKqPjCl7huKS0A==", + "dev": true + }, "unified": { "version": "9.2.2", "dev": true, @@ -25810,6 +26221,12 @@ } } }, + "xmlcreate": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/xmlcreate/-/xmlcreate-2.0.4.tgz", + "integrity": "sha512-nquOebG4sngPmGPICTS5EnxqhKbCmz5Ox5hsszI2T6U5qdrJizBc+0ilYSEjTSzU0yZcmvppztXe/5Al5fUwdg==", + "dev": true + }, "xmlhttprequest-ssl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-2.0.0.tgz", diff --git a/package.json b/package.json index 30c845d..41532d6 100644 --- a/package.json +++ b/package.json @@ -43,6 +43,7 @@ "istanbul-lib-coverage": "^3.0.2", "istanbul-lib-report": "^3.0.0", "istanbul-reports": "^3.0.5", + "jsdoc": "^4.0.0", "lodash": "^4.17.21", "neat-csv": "^7.0.0", "normalize-path": "^3.0.0", diff --git a/static/djenterator/command.js b/static/djenterator/command.js index bd2650a..c41fa51 100644 --- a/static/djenterator/command.js +++ b/static/djenterator/command.js @@ -16,6 +16,9 @@ export const options = [ ["--min ", "A number option, no default."], ] +// example of a positional argument, it's the 1st argument to main +export const argument = ["source", "source directory"]; + // put required options in the required variable export const required = [ ["--output ", "Save to file rather than stdout."], @@ -29,7 +32,7 @@ const check = (test, fail_message) => { } } -export const main = async (opts) => { +export const main = async (arg, opts) => { // if they give an numeric option this is how you can convert it // yes, this is annoying and commander should handle it but oh well if(opts.min !== undefined) { @@ -39,7 +42,7 @@ export const main = async (opts) => { } // it's easier to debug options with console - console.log("OPTIONS", opts); + console.log("OPTIONS", opts, "ARG", arg); // due to how async/await works it's just easier to manually exit with exit codes process.exit(0);