@travetto/doc 3.0.2 → 3.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  <!-- This file was generated by @travetto/doc and should not be modified directly -->
2
- <!-- Please modify https://github.com/travetto/travetto/tree/main/module/doc/DOC.ts and execute "npx trv doc" to rebuild -->
2
+ <!-- Please modify https://github.com/travetto/travetto/tree/main/module/doc/DOC.tsx and execute "npx trv doc" to rebuild -->
3
3
  # Documentation
4
+
4
5
  ## Documentation support for the Travetto framework
5
6
 
6
7
  **Install: @travetto/doc**
@@ -12,92 +13,80 @@ npm install @travetto/doc
12
13
  yarn add @travetto/doc
13
14
  ```
14
15
 
15
- This module provides the ability to generate documentation in [HTML](https://en.wikipedia.org/wiki/HTML) and/or [Markdown](https://en.wikipedia.org/wiki/Markdown). The module relies on integrating with the source of the project, and providing a fully referenced code-base. This allows for automatic updates when code is changed and/or refactored.
16
+ This module provides the ability to generate documentation in [HTML](https://en.wikipedia.org/wiki/HTML) and/or [Markdown](https://en.wikipedia.org/wiki/Markdown). The module relies on integrating with the source of the project, and providing a fully referenced code-base. This allows for automatic updates when code is changed and/or refactored.
16
17
 
17
18
  **Code: Document Sample**
18
19
  ```typescript
19
- import { d, mod } from '@travetto/doc';
20
-
21
- export const text = () => d`
22
- ${d.Header()}
23
-
24
- Sample documentation for fictional module. This module fictitiously relies upon ${mod.Cache} functionality.
20
+ /** @jsxImportSource @travetto/doc */
21
+ import { c } from '@travetto/doc';
25
22
 
26
- ${d.Ordered(
27
- 'First',
28
- 'Second',
29
- d.Path('Special')
30
- )}
23
+ export const text = <>
24
+ <c.StdHeader />
31
25
 
32
- ${d.Section('Content')}
26
+ Sample documentation for fictional module. This module fictitiously relies upon <c.Mod name='Cache' /> functionality.
33
27
 
34
- ${d.Code('Document Sample', './src/test.ts')}
28
+ <ol>
29
+ <li>First</li>
30
+ <li>Second</li>
31
+ <li><c.Path name='Special' /></li>
32
+ </ol>
35
33
 
36
- ${d.SubSection('Output')}
34
+ <c.Section title='Content'>
35
+ <c.Code title='Document Sample' src='./src/test.ts' />
37
36
 
38
- ${d.Execute('Run program', 'trv')}
39
- `;
37
+ <c.SubSection title='Output'>
38
+ <c.Execution title='Run program' cmd='trv' />
39
+ </c.SubSection>
40
+ </c.Section>
41
+ </>;
40
42
  ```
41
43
 
42
44
  **Code: Document Context**
43
45
  ```typescript
44
- export interface DocumentShape<T extends DocNode = DocNode> {
45
- text: () => (T | Promise<T>);
46
+ export interface DocumentShape {
47
+ text: JSXElement | JSXElement[] | (() => Promise<JSXElement | JSXElement[]>);
46
48
  wrap?: Wrapper;
47
49
  }
48
50
  ```
49
51
 
50
- As you can see, you need to export a field named `text` as the body of the help text. The `text` field can be either a direct invocation or an async function that returns the expected document output.
52
+ As you can see, you need to export a field named `text` as the body of the help text. The `text` field can be either a direct invocation or an async function that returns the expected document output.
51
53
 
52
54
  **Note**: By design all the node types provided are synchronous in nature. This is intentionally, specifically with respect to invoking commands and ensuring singular operation.
53
55
 
54
56
  ## Node Types
55
57
 
56
-
57
58
  * `Anchor` - In page anchor reference
58
59
  * `Class` - Class reference
59
60
  * `Code` - Code sample
61
+ * `CodeLink` - Code link with regexp for detecting line
60
62
  * `Command` - Command invocation
61
- * `Comment` - Comment
62
- * `Config` - Configuration Block
63
- * `Execute` - Run a command, and include the output as part of the document
63
+ * `Config` - Configuration block
64
+ * `Execution` - Run a command, and include the output as part of the document
64
65
  * `Field` - Field reference
65
- * `Group` - Group of content nodes
66
- * `Header` - Standard header
66
+ * `File` - File reference
67
+ * `Header` - Basic module header
67
68
  * `Image` - Image reference
68
69
  * `Input` - Input text
69
- * `Install` - Installing a package or program
70
- * `Item` - List item
70
+ * `Install` - Installing a package or a program
71
71
  * `Library` - Library reference
72
- * `List` - Standard List
73
72
  * `Method` - Method declaration
74
73
  * `Mod` - Node Module Reference
75
74
  * `Note` - A note
76
- * `Ordered` - Ordered List
77
75
  * `Path` - Path reference
78
- * `RawHeader` - Raw Doc Header
79
76
  * `Ref` - File reference
80
- * `Section` - Primary Section
81
- * `Snippet` - Code Snippet
82
- * `SnippetLink` - Link to a snippet of code, including line number
83
- * `Strong` - Strong Content
77
+ * `Section` - Primary section
78
+ * `StdHeader` - Standard module header
84
79
  * `SubSection` - Sub-section
85
80
  * `SubSubSection` - Sub-sub-section
86
- * `Table` - Table
87
- * `TableOfContents` - Table Of Contents
88
81
  * `Terminal` - Terminal output
89
- * `Text` - Simple Text Contentf
90
82
 
91
83
  ## Libraries
92
-
93
- Some of the more common libraries are provided as the `lib` field. The purpose of this is to have consistent references to common utilities to help keep external linking simple.
84
+ Some of the more common libraries are provided as the `d.library` method. The purpose of this is to have consistent references to common utilities to help keep external linking simple.
94
85
 
95
86
  ## Modules
96
-
97
- You can also link to other [Travetto](https://travetto.dev) based modules as needed. The `mod` object relies on what is already imported into your project, and reference the package.json of the related module. If the module is not installed, doc generation will fail.
87
+ You can also link to other [Travetto](https://travetto.dev) based modules as needed. The `d.mod` object relies on what is already imported into your project, and reference the package.json of the related module. If the module is not installed, doc generation will fail.
98
88
 
99
89
  ## CLI - doc
100
-
101
90
  The run command allows for generating documentation output.
102
91
 
103
92
  **Terminal: CLI Doc Help**
@@ -107,7 +96,7 @@ $ trv doc --help
107
96
  Usage: doc [options]
108
97
 
109
98
  Options:
110
- -i, --input <input> Input File (default: "DOC.ts")
99
+ -i, --input <input> Input File (default: "DOC.tsx")
111
100
  -o, --outputs <outputs> Outputs (default: [])
112
101
  -w, --watch Watch
113
102
  -h, --help display help for command
@@ -120,46 +109,45 @@ By default, running the command will output the [Markdown](https://en.wikipedia.
120
109
  $ trv doc -o html
121
110
 
122
111
  <!-- This file was generated by @travetto/doc and should not be modified directly -->
123
- <!-- Please modify ./doc-exec/DOC.ts and execute "npx trv doc" to rebuild -->
124
- <h1>@travetto-doc/doc
125
-
126
- </h1>
112
+ <!-- Please modify ./doc-exec/DOC.tsx and execute "npx trv doc" to rebuild -->
113
+ <h1>@travetto-doc/doc</h1>
127
114
 
128
- <figure class="install">
129
- <figcaption class="install">Install @travetto-doc/doc
130
-
131
- </figcaption>
132
- <pre><code class="language-bash"><span class="token function">npm</span> <span class="token function">install</span> @travetto-doc/doc
115
+ <figure class="install">
116
+ <figcaption class="install">Install @travetto-doc/doc
117
+
118
+ </figcaption>
119
+ <pre><code class="language-bash"><span class="token function">npm</span> <span class="token function">install</span> @travetto-doc/doc
133
120
 
134
121
  <span class="token comment"># or</span>
135
122
 
136
- <span class="token function">yarn</span> <span class="token function">add</span> @travetto-doc/doc</code></pre>
137
- </figure>
123
+ <span class="token function">yarn</span> <span class="token function">add</span> @travetto-doc/doc</code></pre>
124
+ </figure>
138
125
 
139
126
  Sample documentation for fictional module. This module fictitiously relies upon <a class="module-link" href="https://github.com/travetto/travetto/tree/main/module/cache" title="Caching functionality with decorators for declarative use.">Caching</a> functionality.
140
-
141
127
  <ol> <li>First</li>
142
- <li>Second</li>
143
- <li><code class="item path">Special</code></li></ol>
128
+ <li>Second</li>
129
+ <li><code class="item path">Special</code></li>
130
+ </ol>
144
131
 
145
132
  <h2 id="content">Content</h2>
146
133
 
147
- <figure class="code">
148
- <figcaption class="code">Document Sample
149
- <cite><a target="_blank" href="./doc-exec/src/test.ts">Source</a></cite>
150
- </figcaption>
151
- <pre><code class="language-typescript"><span class="token keyword">class</span> <span class="token class-name">TestFile</span> <span class="token punctuation">{{'{'}}</span>
134
+ <figure class="code">
135
+ <figcaption class="code">Document Sample
136
+ <cite><a target="_blank" href="./doc-exec/src/test.ts">Source</a></cite>
137
+
138
+ </figcaption>
139
+ <pre><code class="language-typescript"><span class="token keyword">class</span> <span class="token class-name">TestFile</span> <span class="token punctuation">{{'{'}}</span>
152
140
  <span class="token keyword">static</span> <span class="token function">method</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">:</span> <span class="token keyword">void</span> <span class="token punctuation">{{'{'}}</span> <span class="token punctuation">{{'}'}}</span>
153
- <span class="token punctuation">{{'}'}}</span></code></pre>
154
- </figure>
141
+ <span class="token punctuation">{{'}'}}</span></code></pre>
142
+ </figure>
155
143
 
156
144
  <h3 id="output">Output</h3>
157
145
 
158
- <figure class="terminal">
159
- <figcaption class="terminal">Run program
160
-
161
- </figcaption>
162
- <pre><code class="language-bash">$ trv
146
+ <figure class="terminal">
147
+ <figcaption class="terminal">Run program
148
+
149
+ </figcaption>
150
+ <pre><code class="language-bash">$ trv
163
151
 
164
152
  Usage: <span class="token punctuation">[</span>options<span class="token punctuation">]</span> <span class="token punctuation">[</span>command<span class="token punctuation">]</span>
165
153
 
@@ -170,6 +158,6 @@ Options:
170
158
  Commands:
171
159
  doc <span class="token punctuation">[</span>options<span class="token punctuation">]</span>
172
160
  main <span class="token operator">&lt;</span>fileOrImport<span class="token operator">></span> <span class="token punctuation">[</span>args<span class="token punctuation">..</span>.<span class="token punctuation">]</span>
173
- <span class="token builtin class-name">help</span> <span class="token punctuation">[</span>command<span class="token punctuation">]</span> display <span class="token builtin class-name">help</span> <span class="token keyword">for</span> <span class="token builtin class-name">command</span></code></pre>
174
- </figure>
161
+ <span class="token builtin class-name">help</span> <span class="token punctuation">[</span>command<span class="token punctuation">]</span> display <span class="token builtin class-name">help</span> <span class="token keyword">for</span> <span class="token builtin class-name">command</span></code></pre>
162
+ </figure>
175
163
  ```
package/__index__.ts CHANGED
@@ -1,4 +1,3 @@
1
- export { node } from './src/nodes';
2
- export { lib } from './src/lib';
3
- export { mod } from './src/mod';
4
- export { doc, d } from './src/doc';
1
+ export { JSXElement as DocJSXElement, isJSXElement as isDocJSXElement } from './jsx-runtime';
2
+ export { c, d, JSXElementByFn as DocJSXElementByFn } from './src/jsx';
3
+ export { MOD_MAPPING as mod } from './src/mapping/mod-mapping';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@travetto/doc",
3
- "version": "3.0.2",
3
+ "version": "3.0.3",
4
4
  "description": "Documentation support for the Travetto framework",
5
5
  "keywords": [
6
6
  "docs",
@@ -24,12 +24,12 @@
24
24
  "directory": "module/doc"
25
25
  },
26
26
  "dependencies": {
27
- "@travetto/base": "^3.0.2",
27
+ "@travetto/base": "^3.0.3",
28
28
  "@types/prismjs": "^1.26.0",
29
29
  "prismjs": "^1.29.0"
30
30
  },
31
31
  "peerDependencies": {
32
- "@travetto/cli": "^3.0.2"
32
+ "@travetto/cli": "^3.0.3"
33
33
  },
34
34
  "peerDependenciesMeta": {
35
35
  "@travetto/cli": {
package/src/jsx.ts ADDED
@@ -0,0 +1,107 @@
1
+ import { createElement, JSXElement, JSXComponentFunction as CompFn } from '@travetto/doc/jsx-runtime';
2
+ import { TypedObject } from '@travetto/base';
3
+
4
+ import { LIB_MAPPING } from './mapping/lib-mapping';
5
+ import { MOD_MAPPING } from './mapping/mod-mapping';
6
+ import { RunConfig } from './util/run';
7
+
8
+ type CodeProps = { title: string, src: string | Function, language?: string, outline?: boolean, startRe?: RegExp, endRe?: RegExp };
9
+ type InstallProps = { title: string, pkg: string };
10
+ type ExecProps = { title: string, cmd: string, args?: string[], config?: RunConfig & { formatCommand?(cmd: string, args: string[]): string } };
11
+ type StdHeaderProps = { mod?: string, install?: boolean };
12
+ type HeaderProps = { title: string, description?: string };
13
+ type ModProps = { name: keyof typeof MOD_MAPPING };
14
+ type LibraryProps = { name: keyof typeof LIB_MAPPING };
15
+ type LinkProps = { title: string, href: string, line?: number };
16
+ type CodeLinkProps = { title: string, src: string | Function, startRe: RegExp };
17
+ type Named = { name: string };
18
+ type Titled = { title: string };
19
+
20
+ const EMPTY: JSXElement = { type: '', key: '', props: {} };
21
+
22
+ const Input: CompFn<Named> = () => EMPTY; // Input text
23
+ const Field: CompFn<Named> = () => EMPTY; // Field reference
24
+ const Method: CompFn<Named> = () => EMPTY; // Method declaration
25
+ const Command: CompFn<Named> = () => EMPTY; // Command invocation
26
+ const Path: CompFn<Named> = () => EMPTY; // Path reference
27
+ const Class: CompFn<Named> = () => EMPTY; // Class reference
28
+
29
+ const CodeLink: CompFn<CodeLinkProps> = () => EMPTY; // Code link with regexp for detecting line
30
+ const Anchor: CompFn<LinkProps> = () => EMPTY; // In page anchor reference
31
+ const Ref: CompFn<LinkProps> = () => EMPTY; // File reference
32
+ const File: CompFn<LinkProps> = () => EMPTY; // File reference
33
+ const Image: CompFn<LinkProps> = () => EMPTY; // Image reference
34
+
35
+ const Note: CompFn = () => EMPTY; // A note
36
+ const Section: CompFn<Titled> = () => EMPTY; // Primary section
37
+ const SubSection: CompFn<Titled> = () => EMPTY; // Sub-section
38
+ const SubSubSection: CompFn<Titled> = () => EMPTY; // Sub-sub-section
39
+
40
+ const Code: CompFn<CodeProps> = () => EMPTY; // Code sample
41
+ const Terminal: CompFn<CodeProps> = () => EMPTY; // Terminal output
42
+ const Install: CompFn<InstallProps> = () => EMPTY; // Installing a package or a program
43
+ const Config: CompFn<CodeProps> = () => EMPTY; // Configuration block
44
+
45
+ const StdHeader: CompFn<StdHeaderProps> = () => EMPTY; // Standard module header
46
+ const Header: CompFn<HeaderProps> = () => EMPTY; // Basic module header
47
+ const Execution: CompFn<ExecProps> = () => EMPTY; // Run a command, and include the output as part of the document
48
+
49
+ const Mod: CompFn<ModProps> = () => EMPTY; // Node Module Reference
50
+ const Library: CompFn<LibraryProps> = () => EMPTY; // Library reference
51
+
52
+ export const c = {
53
+ Input, Field, Method, Command, Path, Class,
54
+ Anchor, Library, Ref, File, Image, CodeLink,
55
+ Mod, Note, Header, StdHeader,
56
+ Section, SubSection, SubSubSection,
57
+ Code, Execution, Terminal, Install, Config
58
+ } as const;
59
+
60
+ type C = typeof c;
61
+
62
+ // @ts-expect-error
63
+ export type JSXElementByFn<K extends keyof C> = JSXElement<C[K], Parameters<C[K]>[0]>;
64
+ export type JSXElements = { [K in keyof C]: JSXElementByFn<K>; };
65
+
66
+ export const EMPTY_ELEMENT = EMPTY;
67
+
68
+ const invertedC = new Map<Function, string>(TypedObject.entries(c).map(p => [p[1], p[0]] as [CompFn, string]));
69
+
70
+ export function getComponentName(fn: Function | string): string {
71
+ if (typeof fn === 'string') {
72
+ return fn;
73
+ }
74
+ return invertedC.get(fn) ?? fn.name;
75
+ }
76
+
77
+ function CodeLinker(node: JSXElement): JSXElementByFn<'CodeLink'>;
78
+ function CodeLinker(title: string, src: string, startRe: RegExp): JSXElementByFn<'CodeLink'>;
79
+ function CodeLinker(titleOrNode: string | JSXElement, src?: string, startRe?: RegExp): JSXElementByFn<'CodeLink'> {
80
+ let props: CodeLinkProps;
81
+ if (typeof titleOrNode === 'string') {
82
+ props = { title: titleOrNode, src: src!, startRe: startRe! };
83
+ } else if (titleOrNode.type === Code) {
84
+ const node = titleOrNode as unknown as JSXElementByFn<'Code'>;
85
+ props = {
86
+ title: node.props.title,
87
+ src: node.props.src,
88
+ startRe: node.props.startRe!
89
+ };
90
+ } else {
91
+ throw new Error(`Unsupported element type: ${titleOrNode.type}`);
92
+ }
93
+ return createElement(c.CodeLink, props) as JSXElementByFn<'CodeLink'>;
94
+ }
95
+
96
+ export const d = {
97
+ ref: (title: string, src: string) => createElement(c.Ref, { title, href: src }),
98
+ codeLink: CodeLinker,
99
+ input: (name: string) => createElement(c.Input, { name }),
100
+ method: (name: string) => createElement(c.Method, { name }),
101
+ class: (name: string) => createElement(c.Class, { name }),
102
+ path: (name: string) => createElement(c.Path, { name }),
103
+ command: (name: string) => createElement(c.Command, { name }),
104
+ field: (name: string) => createElement(c.Field, { name }),
105
+ library: (name: keyof typeof LIB_MAPPING) => createElement(c.Library, { name }),
106
+ mod: (name: keyof typeof MOD_MAPPING) => createElement(c.Mod, { name }),
107
+ };
@@ -0,0 +1,107 @@
1
+ export const LIB_MAPPING = {
2
+ Travetto: { title: 'Travetto', href: 'https://travetto.dev' },
3
+ Typescript: { title: 'Typescript', href: 'https://typescriptlang.org' },
4
+ Javascript: { title: 'Javascript', href: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript' },
5
+ Node: { title: 'Node', href: 'https://nodejs.org' },
6
+ TravettoPlugin: { title: 'VSCode plugin', href: 'https://marketplace.visualstudio.com/items?itemName=arcsine.travetto-plugin' },
7
+ Npm: { title: 'Npm', href: 'https://docs.npmjs.com/downloading-and-installing-node-js-and-npm' },
8
+ Yarn: { title: 'Yarn', href: 'https://yarnpg.com' },
9
+ Eslint: { title: 'ESLint', href: 'https://eslint.org/' },
10
+ Rollup: { title: 'Rollup', href: 'https://rollupjs.org/' },
11
+ TSConfig: { title: 'TS Config', href: 'https://www.typescriptlang.org/docs/handbook/tsconfig-json.html' },
12
+
13
+ // Module
14
+ CommonJS: { title: 'CommonJS', href: 'https://nodejs.org/api/modules.html' },
15
+ EcmascriptModule: { title: 'Ecmascript Module', href: 'https://nodejs.org/api/esm.html' },
16
+ PackageJson: { title: 'Package JSON', href: 'https://docs.npmjs.com/cli/v9/configuring-npm/package-json' },
17
+
18
+ // Download
19
+ NodeDownload: { title: 'Node', href: 'https://nodejs.org/en/download/current/' },
20
+ MongoDownload: { title: 'Mongodb', href: 'https://docs.mongodb.com/manual/administration/install-community/' },
21
+ VSCodeDownload: { title: 'VSCode', href: 'https://code.visualstudio.com/download' },
22
+
23
+ // Data formats
24
+ YAML: { title: 'YAML', href: 'https://en.wikipedia.org/wiki/YAML' },
25
+ JSON: { title: 'JSON', href: 'https://www.json.org' },
26
+ Base64: { title: 'Base64', href: 'https://en.wikipedia.org/wiki/Base64' },
27
+ TAP: { title: 'TAP 13', href: 'https://testanything.org/tap-version-13-specification.html' },
28
+ XUnit: { title: 'xUnit', href: 'https://en.wikipedia.org/wiki/XUnit' },
29
+ Markdown: { title: 'Markdown', href: 'https://en.wikipedia.org/wiki/Markdown' },
30
+ HTML: { title: 'HTML', href: 'https://en.wikipedia.org/wiki/HTML' },
31
+ JSX: { title: 'JSX', href: 'https://en.wikipedia.org/wiki/JSX_(JavaScript)' },
32
+
33
+ // Info
34
+ DependencyInjection: { title: 'Dependency injection', href: 'https://en.wikipedia.org/wiki/Dependency_injection' },
35
+ OpenAPI: { title: 'OpenAPI', href: 'https://github.com/OAI/OpenAPI-Specification' },
36
+ JSDoc: { title: 'JSDoc', href: 'http://usejsdoc.org/about-getting-started.html' },
37
+ CodeLens: { title: 'CodeLens', href: 'https://code.visualstudio.com/api/language-extensions/programmatic-language-features#codelens-show-actionable-context-information-within-source-code' },
38
+ ORM: { title: 'Object Relationship Mapping', href: 'https://en.wikipedia.org/wiki/Object%E2%80%93relational_mapping' },
39
+ UUID: { title: 'UUID', href: 'https://en.wikipedia.org/wiki/Universally_unique_identifier' },
40
+
41
+ // Node
42
+ ChildProcess: { title: 'child_process', href: 'https://nodejs.org/api/child_process.html' },
43
+ AsyncHooks: { title: 'async_hooks', href: 'https://nodejs.org/api/async_hooks.html' },
44
+ Http: { title: 'http', href: 'https://nodejs.org/api/http.html' },
45
+ Path: { title: 'http', href: 'https://nodejs.org/api/path.html' },
46
+ Https: { title: 'https', href: 'https://nodejs.org/api/https.html' },
47
+ Console: { title: 'console', href: 'https://nodejs.org/api/console.html' },
48
+ Assert: { title: 'assert', href: 'https://nodejs.org/api/assert.html' },
49
+
50
+ // Cloud
51
+ AwsCloudwatch: { title: 'AWS Cloudwatch', href: 'https://aws.amazon.com/cloudwatch/' },
52
+
53
+ // Utils
54
+ Lodash: { title: 'lodash', href: 'https://lodash.com' },
55
+ NodeForge: { title: 'node-forge', href: 'https://www.npmjs.com/package/node-forge' },
56
+ Docker: { title: 'docker', href: 'https://www.docker.com/community-edition' },
57
+ Debug: { title: 'debug', href: 'https://www.npmjs.com/package/debug' },
58
+ OpenAPIGenerator: { title: 'OpenAPI client generation tools', href: 'https://github.com/OpenAPITools/openapi-generator' },
59
+ Gaze: { title: 'gaze', href: 'https://github.com/shama/gaze' },
60
+ Chokidar: { title: 'chokidar', href: 'https://github.com/paulmillr/chokidar' },
61
+ Faker: { title: 'faker', href: 'https://github.com/faker-js/faker' },
62
+ Yeoman: { title: 'yeoman', href: 'http://yeoman.io' },
63
+ Commander: { title: 'commander', href: 'https://www.npmjs.com/package/commander' },
64
+ Curl: { title: 'curl', href: 'https://curl.haxx.se/' },
65
+ Fetch: { title: 'fetch', href: 'https://www.npmjs.com/package/node-fetch' },
66
+ ParcelWatcher: { title: 'fetch', href: 'https://www.npmjs.com/package/@parcel/watcher' },
67
+ Preact: { title: 'preact', href: 'https://preactjs.com' },
68
+ PreactRenderToString: { title: 'preact', href: 'https://github.com/preactjs/preact-render-to-string' },
69
+
70
+ // JWT
71
+ JWT: { title: 'JWT', href: 'https://jwt.io/' },
72
+ NodeJWT: { title: 'node-jsonwebtoken', href: 'https://github.com/auth0/node-jsonwebtoken' },
73
+
74
+ // Email
75
+ NodeMailer: { title: 'nodemailer', href: 'https://nodemailer.com/about/' },
76
+ Inky: { title: 'inky', href: 'https://github.com/zurb/inky' },
77
+ Sass: { title: 'sass', href: 'https://github.com/sass/dart-sass' },
78
+ Mustache: { title: 'mustache', href: 'https://github.com/janl/mustache.js/' },
79
+
80
+ // Image
81
+ ImageMagick: { title: 'ImageMagick', href: 'https://imagemagick.org/index.php' },
82
+ PngQuant: { title: 'pngquant', href: 'https://pngquant.org/' },
83
+ JpegOptim: { title: 'Jpegoptim', href: 'https://github.com/tjko/jpegoptim' },
84
+
85
+ // Dbs
86
+ MongoDB: { title: 'mongodb', href: 'https://mongodb.com' },
87
+ S3: { title: 's3', href: 'https://aws.amazon.com/documentation/s3/' },
88
+ Redis: { title: 'redis', href: 'https://redis.io' },
89
+ Memcached: { title: 'memcached', href: 'https://memcached.org' },
90
+ Elasticsearch: { title: 'elasticsearch', href: 'https://elastic.co' },
91
+ SQL: { title: 'SQL', href: 'https://en.wikipedia.org/wiki/SQL' },
92
+ MySQL: { title: 'MySQL', href: 'https://www.mysql.com/' },
93
+ Postgres: { title: 'Postgres', href: 'https://postgresql.org' },
94
+ DynamoDB: { title: 'DynamoDB', href: 'https://aws.amazon.com/dynamodb/' },
95
+ Firestore: { title: 'Firestore', href: 'https://firebase.google.com/docs/firestore' },
96
+ SQLite: { title: 'SQLite', href: 'https://www.sqlite.org/' },
97
+
98
+ // Rest
99
+ Express: { title: 'express', href: 'https://expressjs.com' },
100
+ Passport: { title: 'passport', href: 'http://passportjs.org' },
101
+ Busboy: { title: 'busboy', href: 'https://github.com/mscdex/busboy' },
102
+ Cookies: { title: 'cookies', href: 'https://www.npmjs.com/package/cookies' },
103
+ ServerlessExpress: { title: 'aws-serverless-express', href: 'https://github.com/awslabs/aws-serverless-express/blob/master/README.md' },
104
+ AwsLambdaFastify: { title: '@fastify/aws-lambda', href: 'https://github.com/fastify/aws-lambda-fastify/blob/master/README.md' },
105
+ Fastify: { title: 'fastify', href: 'https://www.fastify.io/' },
106
+ Koa: { title: 'koa', href: 'https://koajs.com/' },
107
+ } as const;