@doc-kit/core 0.0.0

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.
Files changed (75) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/LICENSE +21 -0
  3. package/README.md +36 -0
  4. package/package.json +88 -0
  5. package/shiki.config.mjs +50 -0
  6. package/src/caching.mjs +183 -0
  7. package/src/generators/ast/README.md +8 -0
  8. package/src/generators/ast/constants.mjs +1 -0
  9. package/src/generators/ast/generate.mjs +125 -0
  10. package/src/generators/ast/index.mjs +20 -0
  11. package/src/generators/ast/types.d.ts +7 -0
  12. package/src/generators/ast-js/README.md +8 -0
  13. package/src/generators/ast-js/generate.mjs +56 -0
  14. package/src/generators/ast-js/index.mjs +24 -0
  15. package/src/generators/ast-js/types.d.ts +5 -0
  16. package/src/generators/index.mjs +48 -0
  17. package/src/generators/json-simple/README.md +9 -0
  18. package/src/generators/json-simple/generate.mjs +33 -0
  19. package/src/generators/json-simple/index.mjs +23 -0
  20. package/src/generators/json-simple/types.d.ts +6 -0
  21. package/src/generators/loader.mjs +96 -0
  22. package/src/generators/metadata/README.md +8 -0
  23. package/src/generators/metadata/constants.mjs +68 -0
  24. package/src/generators/metadata/generate.mjs +40 -0
  25. package/src/generators/metadata/index.mjs +21 -0
  26. package/src/generators/metadata/maps/builtin.json +16 -0
  27. package/src/generators/metadata/maps/mdn.json +1114 -0
  28. package/src/generators/metadata/types.d.ts +145 -0
  29. package/src/generators/metadata/utils/parse.mjs +160 -0
  30. package/src/generators/metadata/utils/resolveTypes.mjs +204 -0
  31. package/src/generators/metadata/utils/slugger.mjs +39 -0
  32. package/src/generators/metadata/utils/transformers.mjs +109 -0
  33. package/src/generators/metadata/utils/visitors.mjs +134 -0
  34. package/src/generators/metadata/utils/yaml.mjs +58 -0
  35. package/src/generators/types.d.ts +129 -0
  36. package/src/generators.mjs +145 -0
  37. package/src/logger/constants.mjs +34 -0
  38. package/src/logger/index.mjs +27 -0
  39. package/src/logger/logger.mjs +177 -0
  40. package/src/logger/transports/console.mjs +54 -0
  41. package/src/logger/transports/github.mjs +42 -0
  42. package/src/logger/transports/index.mjs +11 -0
  43. package/src/logger/types.d.ts +29 -0
  44. package/src/logger/utils/colors.mjs +18 -0
  45. package/src/logger/utils/time.mjs +21 -0
  46. package/src/parsers/markdown.mjs +49 -0
  47. package/src/parsers/types.d.ts +7 -0
  48. package/src/threading/chunk-worker.mjs +23 -0
  49. package/src/threading/index.mjs +27 -0
  50. package/src/threading/parallel.mjs +140 -0
  51. package/src/utils/array.mjs +7 -0
  52. package/src/utils/configuration/index.mjs +263 -0
  53. package/src/utils/configuration/templates.mjs +21 -0
  54. package/src/utils/configuration/types.d.ts +64 -0
  55. package/src/utils/file.mjs +20 -0
  56. package/src/utils/generators.mjs +71 -0
  57. package/src/utils/highlighter.mjs +198 -0
  58. package/src/utils/html-minifier.mjs +12 -0
  59. package/src/utils/loaders.mjs +48 -0
  60. package/src/utils/misc.mjs +72 -0
  61. package/src/utils/queries/constants.mjs +3 -0
  62. package/src/utils/queries/index.mjs +93 -0
  63. package/src/utils/queries/utils.mjs +45 -0
  64. package/src/utils/remark.mjs +97 -0
  65. package/src/utils/signature/constants.mjs +12 -0
  66. package/src/utils/signature/parseList.mjs +133 -0
  67. package/src/utils/signature/parseSignature.mjs +208 -0
  68. package/src/utils/signature/types.d.ts +66 -0
  69. package/src/utils/swc.mjs +34 -0
  70. package/src/utils/type-annotations/hast.mjs +115 -0
  71. package/src/utils/type-annotations/mdast.mjs +75 -0
  72. package/src/utils/type-annotations/remark.mjs +24 -0
  73. package/src/utils/type-annotations/syntax.mjs +188 -0
  74. package/src/utils/unist.mjs +75 -0
  75. package/src/utils/url.mjs +27 -0
@@ -0,0 +1,48 @@
1
+ 'use strict';
2
+
3
+ /**
4
+ * Maps the shorthand names accepted by the CLI and configuration files
5
+ * (e.g. `--target html`) to the import specifiers they resolve to.
6
+ *
7
+ * Generators are loaded dynamically by specifier (see `./loader.mjs`), so this
8
+ * module must not import any generator code — it is purely a lookup table.
9
+ * Anything that is not listed here is treated as a raw import specifier,
10
+ * which is how third-party generator packages are loaded.
11
+ */
12
+ export const publicGenerators = {
13
+ 'json-simple': '@doc-kit/core/json-simple',
14
+ 'legacy-html': '@node-core/doc-kit-legacy/legacy-html',
15
+ 'legacy-html-all': '@node-core/doc-kit-legacy/legacy-html-all',
16
+ 'man-page': '@node-core/doc-kit/man-page',
17
+ 'legacy-json': '@node-core/doc-kit-legacy/legacy-json',
18
+ 'legacy-json-all': '@node-core/doc-kit-legacy/legacy-json-all',
19
+ 'addon-verify': '@node-core/doc-kit/addon-verify',
20
+ 'api-links': '@node-core/doc-kit/api-links',
21
+ 'orama-db': '@doc-kit/generator-react/orama-db',
22
+ 'llms-txt': '@doc-kit/generator-react/llms-txt',
23
+ sitemap: '@doc-kit/generator-react/sitemap',
24
+ html: '@doc-kit/generator-react/html',
25
+ };
26
+
27
+ // These ones are special since they don't produce standard output,
28
+ // and hence, we don't expose them to the CLI. They can still be referenced
29
+ // by shorthand (e.g. as configuration keys or generator dependencies).
30
+ const internalGenerators = {
31
+ ast: '@doc-kit/core/ast',
32
+ metadata: '@doc-kit/core/metadata',
33
+ 'jsx-ast': '@doc-kit/generator-react/jsx-ast',
34
+ 'ast-js': '@doc-kit/core/ast-js',
35
+ };
36
+
37
+ // Former names kept resolvable for existing invocations and config files.
38
+ // Unlike the maps above, keys here intentionally differ from the generator's
39
+ // `name` property.
40
+ export const deprecatedGenerators = {
41
+ web: '@doc-kit/generator-react/html',
42
+ };
43
+
44
+ export const allGenerators = {
45
+ ...publicGenerators,
46
+ ...internalGenerators,
47
+ ...deprecatedGenerators,
48
+ };
@@ -0,0 +1,9 @@
1
+ # `json-simple` Generator
2
+
3
+ The `json-simple` generator creates a simplified JSON version of the API documentation, primarily for debugging and testing purposes.
4
+
5
+ ## Configuring
6
+
7
+ - `output` {string} The directory where `api-docs.json` will be written.
8
+ - `minify` {boolean} Whether to minify the output JSON. Inherited from
9
+ `global`. **Default:** `true`.
@@ -0,0 +1,33 @@
1
+ 'use strict';
2
+
3
+ import { join } from 'node:path';
4
+
5
+ import { remove } from 'unist-util-remove';
6
+
7
+ import getConfig from '../../utils/configuration/index.mjs';
8
+ import { writeFile } from '../../utils/file.mjs';
9
+ import { UNIST } from '../../utils/queries/index.mjs';
10
+
11
+ /**
12
+ * Generates the simplified JSON version of the API docs
13
+ *
14
+ * @type {import('./types').Generator['generate']}
15
+ */
16
+ export async function generate(input) {
17
+ const config = getConfig('json-simple');
18
+
19
+ input.forEach(node =>
20
+ remove(node.content, [UNIST.isStabilityNode, UNIST.isHeading])
21
+ );
22
+
23
+ if (config.output) {
24
+ // Writes all the API docs stringified content into one file
25
+ // Note: The full JSON generator in the future will create one JSON file per top-level API doc file
26
+ await writeFile(
27
+ join(config.output, 'api-docs.json'),
28
+ config.minify ? JSON.stringify(input) : JSON.stringify(input, null, 2)
29
+ );
30
+ }
31
+
32
+ return input;
33
+ }
@@ -0,0 +1,23 @@
1
+ 'use strict';
2
+
3
+ import { generate } from './generate.mjs';
4
+
5
+ /**
6
+ * This generator generates a simplified JSON version of the API docs and returns it as a string
7
+ * this is not meant to be used for the final API docs, but for debugging and testing purposes
8
+ *
9
+ * This generator is a top-level generator, and it takes the raw AST tree of the API doc files
10
+ * and returns a stringified JSON version of the API docs.
11
+ *
12
+ * @type {import('./types').Generator}
13
+ */
14
+ export default {
15
+ name: 'json-simple',
16
+
17
+ description:
18
+ 'Generates the simple JSON version of the API docs, and returns it as a string',
19
+
20
+ dependsOn: '@doc-kit/core/metadata',
21
+
22
+ generate,
23
+ };
@@ -0,0 +1,6 @@
1
+ import type { MetadataEntry } from '../metadata/types';
2
+
3
+ export type Generator = GeneratorMetadata<
4
+ {},
5
+ Generate<Array<MetadataEntry>, Promise<Array<MetadataEntry>>>
6
+ >;
@@ -0,0 +1,96 @@
1
+ 'use strict';
2
+
3
+ import { isAbsolute } from 'node:path';
4
+ import { pathToFileURL } from 'node:url';
5
+
6
+ import { allGenerators } from './index.mjs';
7
+
8
+ /**
9
+ * Resolves a CLI/configuration target into an import specifier. Shorthand
10
+ * names map through the alias table; filesystem paths become file URLs;
11
+ * anything else is treated as an import specifier already.
12
+ *
13
+ * Resolution is idempotent, so already-resolved specifiers pass through.
14
+ *
15
+ * @param {string} target - Shorthand name, path, or import specifier
16
+ * @returns {string} The import specifier to load the generator from
17
+ */
18
+ export const resolveGeneratorSpecifier = target => {
19
+ if (target in allGenerators) {
20
+ return allGenerators[target];
21
+ }
22
+
23
+ if (target.startsWith('.') || isAbsolute(target)) {
24
+ return pathToFileURL(target).href;
25
+ }
26
+
27
+ return target;
28
+ };
29
+
30
+ /**
31
+ * Imports a generator by specifier and returns its default export.
32
+ *
33
+ * @param {string} specifier - Shorthand name, path, or import specifier
34
+ * @returns {Promise<GeneratorMetadata>}
35
+ */
36
+ export const loadGenerator = async specifier => {
37
+ const resolved = resolveGeneratorSpecifier(specifier);
38
+
39
+ /** @type {{ default?: GeneratorMetadata }} */
40
+ let module;
41
+
42
+ try {
43
+ module = await import(resolved);
44
+ } catch (error) {
45
+ if (error.code === 'ERR_MODULE_NOT_FOUND') {
46
+ throw new Error(
47
+ `Could not load generator "${specifier}" (resolved to "${resolved}"). ` +
48
+ 'If it lives in a separate package, make sure that package is installed.',
49
+ { cause: error }
50
+ );
51
+ }
52
+
53
+ throw error;
54
+ }
55
+
56
+ const generator = module.default;
57
+
58
+ if (!generator?.name || typeof generator.generate !== 'function') {
59
+ throw new Error(
60
+ `"${specifier}" is not a generator: expected a default export ` +
61
+ 'with a `name` and a `generate` function.'
62
+ );
63
+ }
64
+
65
+ return generator;
66
+ };
67
+
68
+ /**
69
+ * Loads the given generators plus the transitive closure of their
70
+ * dependencies (via `dependsOn`).
71
+ *
72
+ * @param {string[]} targets - Shorthand names, paths, or import specifiers
73
+ * @returns {Promise<Map<string, GeneratorMetadata>>} Loaded generators keyed
74
+ * by their resolved specifier
75
+ */
76
+ export const loadGenerators = async targets => {
77
+ const generators = new Map();
78
+ const queue = targets.map(resolveGeneratorSpecifier);
79
+
80
+ while (queue.length > 0) {
81
+ const specifier = queue.shift();
82
+
83
+ if (generators.has(specifier)) {
84
+ continue;
85
+ }
86
+
87
+ const generator = await loadGenerator(specifier);
88
+ generators.set(specifier, generator);
89
+
90
+ if (generator.dependsOn) {
91
+ queue.push(resolveGeneratorSpecifier(generator.dependsOn));
92
+ }
93
+ }
94
+
95
+ return generators;
96
+ };
@@ -0,0 +1,8 @@
1
+ # `metadata` Generator
2
+
3
+ The `metadata` generator creates a flattened list of metadata entries from API documentation, extracting structured information about functions, classes, methods, and other API elements.
4
+
5
+ ## Configuring
6
+
7
+ - `typeMap` {string} URL or path to the type mapping configuration file.
8
+ **Default:** `'typeMap.json'`.
@@ -0,0 +1,68 @@
1
+ // On "About this Documentation", we define the stability indices, and thus
2
+ // we don't need to check it for stability references
3
+ export const IGNORE_STABILITY_STEMS = ['documentation'];
4
+
5
+ // These are string replacements specific to Node.js API docs for anchor IDs
6
+ export const DOC_API_SLUGS_REPLACEMENTS = [
7
+ { from: /node.js/i, to: 'nodejs' }, // Replace Node.js
8
+ { from: /&/, to: '-and-' }, // Replace &
9
+ { from: /[/,:;\\ ]/g, to: '-' }, // Replace /,:;\. and whitespace
10
+ { from: /^-(?!-|$)/g, to: '' }, // Remove a single leading hyphen
11
+ { from: /(?<!^-*)-+$/g, to: '' }, // Remove any trailing hyphens
12
+ { from: /^(?!-)(?!-+$).*?(--+)/g, to: '-' }, // Replace multiple hyphens
13
+ ];
14
+
15
+ // Matches Node.js deprecation headings such as "DEP0001: Description".
16
+ export const DEPRECATION_HEADING_REGEX = /^(DEP\d+):/;
17
+
18
+ // A dotted identifier path, e.g. `vm.Module` or `os.constants.dlopen`. Names
19
+ // that merely contain a dot (prose, `Object.<string, string>`, `1.5`) must not
20
+ // be turned into a module link.
21
+ export const MODULE_QUALIFIED_NAME = /^[A-Za-z_]\w*(?:\.[A-Za-z_]\w*)+$/;
22
+
23
+ // These are regular expressions used to determine if a given Markdown heading
24
+ // is a specific type of API Doc entry (e.g., Event, Class, Method, etc)
25
+ // and to extract the inner content of said Heading to be used as the API doc entry name
26
+ const CAMEL_CASE = '\\w+(?:\\.\\w+)*';
27
+ const FUNCTION_CALL = '\\([^)]*\\)';
28
+
29
+ // Matches "bar":
30
+ // Group 1: foo[bar]
31
+ // Group 2: foo.bar
32
+ const PROPERTY = `${CAMEL_CASE}(?:(\\[[^\\]]+\\])|\\.(\\w+))`;
33
+
34
+ // An array of objects defining the different types of API doc headings we want to
35
+ // capture and their respective regex to match against the heading text.
36
+ // The regex are case-insensitive.
37
+ export const DOC_API_HEADING_TYPES = [
38
+ {
39
+ type: 'method',
40
+ regex: new RegExp(
41
+ `^\`(?:${PROPERTY}|(${CAMEL_CASE}))${FUNCTION_CALL}\`$`,
42
+ 'i'
43
+ ),
44
+ },
45
+ { type: 'event', regex: /^Event: +`'?([^`]*?)'?`$/i },
46
+ {
47
+ type: 'class',
48
+ regex: new RegExp(
49
+ `^Class: +\`(${CAMEL_CASE}(?: extends +${CAMEL_CASE})?)\`$`,
50
+ 'i'
51
+ ),
52
+ },
53
+ {
54
+ type: 'ctor',
55
+ regex: new RegExp(`^\`new +(${CAMEL_CASE})${FUNCTION_CALL}\`$`, 'i'),
56
+ },
57
+ {
58
+ type: 'classMethod',
59
+ regex: new RegExp(`^Static method: +\`${PROPERTY}${FUNCTION_CALL}\`$`, 'i'),
60
+ },
61
+ {
62
+ type: 'property',
63
+ regex: new RegExp(`^\`${PROPERTY}\`$`, 'i'),
64
+ },
65
+ ];
66
+
67
+ // This is the base URL of the Man7 documentation
68
+ export const DOC_MAN_BASE_URL = 'http://man7.org/linux/man-pages/man';
@@ -0,0 +1,40 @@
1
+ 'use strict';
2
+
3
+ import { parseApiDoc } from './utils/parse.mjs';
4
+ import getConfig from '../../utils/configuration/index.mjs';
5
+ import { loadFromURL } from '../../utils/loaders.mjs';
6
+
7
+ /**
8
+ * Process a chunk of API doc files in a worker thread.
9
+ * Called by chunk-worker.mjs for parallel processing.
10
+ *
11
+ * @type {import('./types').Generator['processChunk']}
12
+ */
13
+ export async function processChunk(fullInput, itemIndices, typeMap) {
14
+ const results = [];
15
+
16
+ for (const idx of itemIndices) {
17
+ results.push(...parseApiDoc(fullInput[idx], typeMap));
18
+ }
19
+
20
+ return results;
21
+ }
22
+
23
+ /**
24
+ * Generates a flattened list of metadata entries from API docs.
25
+ *
26
+ * @type {import('./types').Generator['generate']}
27
+ */
28
+ export async function* generate(inputs, worker) {
29
+ const { metadata: config } = getConfig();
30
+
31
+ const typeMap = config.typeMap
32
+ ? JSON.parse(await loadFromURL(config.typeMap))
33
+ : {};
34
+
35
+ // Stream chunks as they complete - allows dependent generators
36
+ // to start collecting/preparing while we're still processing
37
+ for await (const chunkResult of worker.stream(inputs, typeMap)) {
38
+ yield chunkResult.flat();
39
+ }
40
+ }
@@ -0,0 +1,21 @@
1
+ 'use strict';
2
+
3
+ import { generate, processChunk } from './generate.mjs';
4
+
5
+ /**
6
+ * This generator generates a flattened list of metadata entries from a API doc
7
+ *
8
+ * @type {import('./types').Generator}
9
+ */
10
+ export default {
11
+ name: 'metadata',
12
+
13
+ description: 'generates a flattened list of API doc metadata entries',
14
+
15
+ dependsOn: '@doc-kit/core/ast',
16
+
17
+ hasParallelProcessor: true,
18
+
19
+ generate,
20
+ processChunk,
21
+ };
@@ -0,0 +1,16 @@
1
+ {
2
+ "asynciterable": "https://tc39.github.io/ecma262/#sec-asynciterable-interface",
3
+ "iterable": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols#the_iterable_protocol",
4
+ "void": "https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/void",
5
+ "module namespace object": "https://tc39.github.io/ecma262/#sec-module-namespace-exotic-objects",
6
+ "null": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#null_type",
7
+ "undefined": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#undefined_type",
8
+ "boolean": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#boolean_type",
9
+ "number": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#number_type",
10
+ "bigint": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#bigint_type",
11
+ "string": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#string_type",
12
+ "symbol": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#symbol_type",
13
+ "integer": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#number_type",
14
+ "any": "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Data_structures#Data_types",
15
+ "this": "https://developer.mozilla.org/docs/Web/JavaScript/Reference/Operators/this"
16
+ }