@doc-kit/core 1.2.0 → 1.3.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.
- package/CHANGELOG.md +16 -0
- package/README.md +1 -1
- package/package.json +6 -7
- package/src/generators/ast/generate.mjs +7 -3
- package/src/generators/ast/index.mjs +9 -0
- package/src/generators/index.mjs +1 -0
- package/src/generators/json/README.md +1 -1
- package/src/generators/json/generated/schema.d.ts +1 -1
- package/src/generators/json/index.mjs +9 -0
- package/src/generators/json/utils/markdown.mjs +2 -2
- package/src/generators/json-all/README.md +1 -1
- package/src/generators/json-simple/README.md +1 -1
- package/src/generators/loader.mjs +14 -0
- package/src/generators/metadata/generate.mjs +4 -2
- package/src/generators/metadata/index.mjs +9 -0
- package/src/generators/metadata/maps/mdn.json +3 -0
- package/src/generators/metadata/types.d.ts +1 -1
- package/src/generators/metadata/utils/parse.mjs +2 -4
- package/src/generators/metadata/utils/transformers.mjs +1 -1
- package/src/generators/metadata/utils/visitors.mjs +2 -2
- package/src/generators/types.d.ts +8 -0
- package/src/generators.mjs +4 -0
- package/src/logger/constants.mjs +35 -0
- package/src/logger/transports/github.mjs +48 -15
- package/src/plugins/shiki/highlighter.mjs +373 -0
- package/src/plugins/shiki/rehype.mjs +38 -0
- package/src/{utils/type-annotations/highlighted.mjs → plugins/type-annotations/highlighter.mjs} +14 -19
- package/src/{utils → plugins}/type-annotations/remark.mjs +6 -2
- package/src/threading/chunk-worker.mjs +4 -0
- package/src/threading/constants.mjs +10 -0
- package/src/threading/index.mjs +6 -1
- package/src/utils/configuration/constants.mjs +3 -3
- package/src/utils/configuration/index.mjs +86 -20
- package/src/utils/configuration/types.d.ts +27 -0
- package/src/utils/loaders.mjs +23 -1
- package/src/utils/markdown/constants.mjs +7 -0
- package/src/utils/markdown/plugins.mjs +232 -0
- package/src/utils/markdown/processor.mjs +60 -0
- package/src/utils/highlighter.mjs +0 -198
- package/src/utils/remark-shiki.mjs +0 -29
- package/src/utils/remark.mjs +0 -90
- /package/src/{utils → plugins}/type-annotations/hast.mjs +0 -0
- /package/src/{utils → plugins}/type-annotations/mdast.mjs +0 -0
- /package/src/{utils → plugins}/type-annotations/syntax.mjs +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @doc-kit/core
|
|
2
2
|
|
|
3
|
+
## 1.3.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#1156](https://github.com/nodejs/doc-kit/pull/1156) [`6d5f9d1`](https://github.com/nodejs/doc-kit/commit/6d5f9d17d9f265c62db0f878c4e03903881b11c9) Thanks [@ovflowd](https://github.com/ovflowd)! - Builds take about half the memory and a third of the time (measured on the Node.js API docs): Shiki registers each language once code in it is highlighted, highlighted code reaches pages as static markup rather than a tree per token, `all.html` is rendered by the worker pool, output is no longer minified by default (serve it compressed instead), idle workers end after 250ms, and each worker's heap is limited to 512MB, which Node.js's `--max-old-space-size` raises.
|
|
8
|
+
|
|
9
|
+
- [#1127](https://github.com/nodejs/doc-kit/pull/1127) [`c50e75f`](https://github.com/nodejs/doc-kit/commit/c50e75f8f50c84b6ff3b16b84059bd0f53ca5d1c) Thanks [@ovflowd](https://github.com/ovflowd)! - Add the `llms-txt-full` generator, writing a `llms-full.txt` file holding the Markdown of every page, each preceded by its URL.
|
|
10
|
+
|
|
11
|
+
- [#1157](https://github.com/nodejs/doc-kit/pull/1157) [`a4c9684`](https://github.com/nodejs/doc-kit/commit/a4c9684fd46f14b3bcbaf2e8f01a246a47ee27cd) Thanks [@ovflowd](https://github.com/ovflowd)! - Add a `markdown` option to add remark, rehype, and recma plugins to the generators processing Markdown, or configure the ones they use, such as Shiki. The `@doc-kit/core` modules the generators' pipelines replace are removed (`utils/remark.mjs`, `utils/remark-shiki.mjs`, and `utils/highlighter.mjs`), and `utils/type-annotations` moves to `plugins/type-annotations`
|
|
12
|
+
|
|
13
|
+
## 1.2.1
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- [#1105](https://github.com/nodejs/doc-kit/pull/1105) [`615aabe`](https://github.com/nodejs/doc-kit/commit/615aabeb1955a8028146e26fd4589c1172f58367) Thanks [@ryzrr](https://github.com/ryzrr)! - fix(metadata): link class types whose name starts with an acronym
|
|
18
|
+
|
|
3
19
|
## 1.2.0
|
|
4
20
|
|
|
5
21
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ debugging-only `json-simple`); the rest come from companion packages:
|
|
|
15
15
|
|
|
16
16
|
| Package | Generators |
|
|
17
17
|
| -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
|
|
18
|
-
| [`@doc-kit/generator-react`](https://www.npmjs.com/package/@doc-kit/generator-react) | `html` (the modern site), `orama-db`, `llms-txt`, `sitemap`
|
|
18
|
+
| [`@doc-kit/generator-react`](https://www.npmjs.com/package/@doc-kit/generator-react) | `html` (the modern site), `orama-db`, `llms-txt`, `llms-txt-full`, `sitemap` |
|
|
19
19
|
| [`@node-core/doc-kit-legacy`](https://www.npmjs.com/package/@node-core/doc-kit-legacy) | `legacy-html`, `legacy-html-all`, `legacy-json`, `legacy-json-all` (Node.js-specific) |
|
|
20
20
|
| [`@node-core/doc-kit`](https://www.npmjs.com/package/@node-core/doc-kit) | `man-page`, `api-links`, `addon-verify` (Node.js-specific) |
|
|
21
21
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@doc-kit/core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.3.0",
|
|
5
5
|
"description": "The doc-kit engine: the pipeline and shared APIs that power the doc-kit generators and CLI",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
"./src/parsers/*",
|
|
34
34
|
"./src/parsers/*.d.ts"
|
|
35
35
|
],
|
|
36
|
+
"#plugins/*": "./src/plugins/*",
|
|
36
37
|
"#utils/*": "./src/utils/*"
|
|
37
38
|
},
|
|
38
39
|
"files": [
|
|
@@ -45,19 +46,17 @@
|
|
|
45
46
|
"README.md"
|
|
46
47
|
],
|
|
47
48
|
"dependencies": {
|
|
48
|
-
"@
|
|
49
|
-
"@
|
|
50
|
-
"@swc/html-wasm": "^1.15.46",
|
|
49
|
+
"@node-core/rehype-shiki": "^1.5.1",
|
|
50
|
+
"@swc/html-wasm": "^1.16.2",
|
|
51
51
|
"@swc/wasm": "^1.15.46",
|
|
52
52
|
"acorn": "^8.17.0",
|
|
53
53
|
"cosmiconfig": "^9.0.2",
|
|
54
54
|
"dedent": "^1.7.2",
|
|
55
55
|
"github-slugger": "^2.0.0",
|
|
56
56
|
"glob-parent": "^6.0.2",
|
|
57
|
-
"hastscript": "^9.0.1",
|
|
58
57
|
"mdast-util-slice-markdown": "^2.0.1",
|
|
59
58
|
"mdast-util-to-string": "^4.0.0",
|
|
60
|
-
"piscina": "^5.3.
|
|
59
|
+
"piscina": "^5.3.2",
|
|
61
60
|
"rehype-stringify": "^10.0.1",
|
|
62
61
|
"remark-gfm": "^4.0.1",
|
|
63
62
|
"remark-mdx": "^3.1.1",
|
|
@@ -74,7 +73,7 @@
|
|
|
74
73
|
"unist-util-remove": "^4.0.0",
|
|
75
74
|
"unist-util-select": "^5.1.0",
|
|
76
75
|
"unist-util-visit": "^5.1.0",
|
|
77
|
-
"yaml": "^2.9.
|
|
76
|
+
"yaml": "^2.9.1"
|
|
78
77
|
},
|
|
79
78
|
"devDependencies": {
|
|
80
79
|
"ajv": "^8.20.0",
|
|
@@ -9,8 +9,8 @@ import { parse as parseYaml } from 'yaml';
|
|
|
9
9
|
|
|
10
10
|
import getConfig from '#utils/configuration/index.mjs';
|
|
11
11
|
import { withExt } from '#utils/file.mjs';
|
|
12
|
+
import { getProcessor } from '#utils/markdown/processor.mjs';
|
|
12
13
|
import { QUERIES } from '#utils/queries/index.mjs';
|
|
13
|
-
import { getRemark as remark, getRemarkMdx } from '#utils/remark.mjs';
|
|
14
14
|
|
|
15
15
|
import { STABILITY_INDEX_URL } from './constants.mjs';
|
|
16
16
|
|
|
@@ -67,6 +67,8 @@ export async function processChunk(inputSlice, itemIndices) {
|
|
|
67
67
|
// The path is the relative path minus the extension
|
|
68
68
|
const relativePath = sep + withExt(relative(parent, path));
|
|
69
69
|
|
|
70
|
+
const processor = getProcessor('ast', { mdx });
|
|
71
|
+
|
|
70
72
|
let tree;
|
|
71
73
|
|
|
72
74
|
if (mdx) {
|
|
@@ -79,7 +81,7 @@ export async function processChunk(inputSlice, itemIndices) {
|
|
|
79
81
|
''
|
|
80
82
|
);
|
|
81
83
|
|
|
82
|
-
tree =
|
|
84
|
+
tree = processor.parse(source);
|
|
83
85
|
|
|
84
86
|
if (frontmatter) {
|
|
85
87
|
tree.children.unshift({
|
|
@@ -93,9 +95,11 @@ export async function processChunk(inputSlice, itemIndices) {
|
|
|
93
95
|
(_, yaml) => `<!-- YAML\n${yaml}\n-->`
|
|
94
96
|
);
|
|
95
97
|
|
|
96
|
-
tree =
|
|
98
|
+
tree = processor.parse(value);
|
|
97
99
|
}
|
|
98
100
|
|
|
101
|
+
tree = await processor.run(tree, { path });
|
|
102
|
+
|
|
99
103
|
results.push({ tree, path: relativePath, mdx });
|
|
100
104
|
}
|
|
101
105
|
|
package/src/generators/index.mjs
CHANGED
|
@@ -22,6 +22,7 @@ export const publicGenerators = {
|
|
|
22
22
|
'api-links': '@node-core/doc-kit/api-links',
|
|
23
23
|
'orama-db': '@doc-kit/generator-react/orama-db',
|
|
24
24
|
'llms-txt': '@doc-kit/generator-react/llms-txt',
|
|
25
|
+
'llms-txt-full': '@doc-kit/generator-react/llms-txt-full',
|
|
25
26
|
sitemap: '@doc-kit/generator-react/sitemap',
|
|
26
27
|
html: '@doc-kit/generator-react/html',
|
|
27
28
|
'section-pages': '@doc-kit/generator-react/section-pages',
|
|
@@ -18,7 +18,7 @@ Files keep the input's directory layout: `doc/api/some/fs.md` becomes `out/some/
|
|
|
18
18
|
|
|
19
19
|
- `output` {string} The directory to write the documents to.
|
|
20
20
|
- `minify` {boolean} Whether to minify the output. Inherited from `global`.
|
|
21
|
-
**Default:** `
|
|
21
|
+
**Default:** `false`.
|
|
22
22
|
- `repository` {string} The `owner/name` repository source links resolve
|
|
23
23
|
against. Inherited from `global`; without one, `sourceLink.url` is `null`.
|
|
24
24
|
- `schemaURL` {string} Where the schema is published. `{schemaVersion}` is
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { u as createTree } from 'unist-builder';
|
|
4
4
|
import { visit } from 'unist-util-visit';
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { getProcessor } from '#utils/markdown/processor.mjs';
|
|
7
7
|
|
|
8
8
|
import { DISPLAY_NAME } from '../constants.mjs';
|
|
9
9
|
|
|
@@ -19,7 +19,7 @@ export const blocksToMarkdown = (nodes, mdx = false) => {
|
|
|
19
19
|
return '';
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
const processor =
|
|
22
|
+
const processor = getProcessor('json', { mdx });
|
|
23
23
|
|
|
24
24
|
return processor.stringify(createTree('root', nodes)).trim();
|
|
25
25
|
};
|
|
@@ -23,7 +23,7 @@ generator's schema for the documents.
|
|
|
23
23
|
|
|
24
24
|
- `output` {string} The directory where `all.json` will be written.
|
|
25
25
|
- `minify` {boolean} Whether to minify the output. Inherited from `global`.
|
|
26
|
-
**Default:** `
|
|
26
|
+
**Default:** `false`.
|
|
27
27
|
- `index` {Array} The `{ api }` objects defining the document order. Inherited
|
|
28
28
|
from `global`.
|
|
29
29
|
- `schemaURL` {string} Where the bundle's schema is published.
|
|
@@ -6,4 +6,4 @@ The `json-simple` generator creates a simplified JSON version of the API documen
|
|
|
6
6
|
|
|
7
7
|
- `output` {string} The directory where `api-docs.json` will be written.
|
|
8
8
|
- `minify` {boolean} Whether to minify the output JSON. Inherited from
|
|
9
|
-
`global`. **Default:** `
|
|
9
|
+
`global`. **Default:** `false`.
|
|
@@ -7,6 +7,9 @@ import { enforceArray } from '#utils/array.mjs';
|
|
|
7
7
|
|
|
8
8
|
import { allGenerators } from './index.mjs';
|
|
9
9
|
|
|
10
|
+
// The module each loaded generator comes from
|
|
11
|
+
const generatorModules = new WeakMap();
|
|
12
|
+
|
|
10
13
|
/**
|
|
11
14
|
* Resolves a CLI/configuration target into an import specifier. Shorthand
|
|
12
15
|
* names map through the alias table; filesystem paths become file URLs;
|
|
@@ -64,9 +67,20 @@ export const loadGenerator = async specifier => {
|
|
|
64
67
|
);
|
|
65
68
|
}
|
|
66
69
|
|
|
70
|
+
generatorModules.set(generator, import.meta.resolve(resolved));
|
|
71
|
+
|
|
67
72
|
return generator;
|
|
68
73
|
};
|
|
69
74
|
|
|
75
|
+
/**
|
|
76
|
+
* The URL of the module a generator was loaded from, which the specifiers of
|
|
77
|
+
* its Markdown pipeline resolve against.
|
|
78
|
+
*
|
|
79
|
+
* @param {GeneratorMetadata} generator - A generator loaded by `loadGenerator`
|
|
80
|
+
* @returns {string | undefined}
|
|
81
|
+
*/
|
|
82
|
+
export const getGeneratorModule = generator => generatorModules.get(generator);
|
|
83
|
+
|
|
70
84
|
/**
|
|
71
85
|
* Loads the given generators plus the transitive closure of their
|
|
72
86
|
* dependencies (via `dependsOn`) and dependents (via `dependent`).
|
|
@@ -3,8 +3,6 @@
|
|
|
3
3
|
import getConfig from '#utils/configuration/index.mjs';
|
|
4
4
|
import { loadFromURL } from '#utils/loaders.mjs';
|
|
5
5
|
|
|
6
|
-
import { parseApiDoc } from './utils/parse.mjs';
|
|
7
|
-
|
|
8
6
|
/**
|
|
9
7
|
* Process a chunk of API doc files in a worker thread.
|
|
10
8
|
* Called by chunk-worker.mjs for parallel processing.
|
|
@@ -12,6 +10,10 @@ import { parseApiDoc } from './utils/parse.mjs';
|
|
|
12
10
|
* @type {import('./types').Generator['processChunk']}
|
|
13
11
|
*/
|
|
14
12
|
export async function processChunk(fullInput, itemIndices, typeMap) {
|
|
13
|
+
// Loaded on first use rather than with the generator, so the main thread,
|
|
14
|
+
// which never parses, does not load the TypeScript parser (~40MB of WASM)
|
|
15
|
+
const { parseApiDoc } = await import('./utils/parse.mjs');
|
|
16
|
+
|
|
15
17
|
const results = [];
|
|
16
18
|
|
|
17
19
|
for (const idx of itemIndices) {
|
|
@@ -475,6 +475,7 @@
|
|
|
475
475
|
"magnetometer": "https://developer.mozilla.org/docs/Web/API/Magnetometer",
|
|
476
476
|
"managedmediasource": "https://developer.mozilla.org/docs/Web/API/ManagedMediaSource",
|
|
477
477
|
"managedsourcebuffer": "https://developer.mozilla.org/docs/Web/API/ManagedSourceBuffer",
|
|
478
|
+
"mathmlanchorelement": "https://developer.mozilla.org/docs/Web/API/MathMLAnchorElement",
|
|
478
479
|
"mathmlelement": "https://developer.mozilla.org/docs/Web/API/MathMLElement",
|
|
479
480
|
"mediacapabilities": "https://developer.mozilla.org/docs/Web/API/MediaCapabilities",
|
|
480
481
|
"mediadeviceinfo": "https://developer.mozilla.org/docs/Web/API/MediaDeviceInfo",
|
|
@@ -553,6 +554,7 @@
|
|
|
553
554
|
"oes_vertex_array_object": "https://developer.mozilla.org/docs/Web/API/OES_vertex_array_object",
|
|
554
555
|
"otpcredential": "https://developer.mozilla.org/docs/Web/API/OTPCredential",
|
|
555
556
|
"ovr_multiview2": "https://developer.mozilla.org/docs/Web/API/OVR_multiview2",
|
|
557
|
+
"observable": "https://developer.mozilla.org/docs/Web/API/Observable",
|
|
556
558
|
"offlineaudiocompletionevent": "https://developer.mozilla.org/docs/Web/API/OfflineAudioCompletionEvent",
|
|
557
559
|
"offlineaudiocontext": "https://developer.mozilla.org/docs/Web/API/OfflineAudioContext",
|
|
558
560
|
"offscreencanvas": "https://developer.mozilla.org/docs/Web/API/OffscreenCanvas",
|
|
@@ -826,6 +828,7 @@
|
|
|
826
828
|
"stylesheet": "https://developer.mozilla.org/docs/Web/API/StyleSheet",
|
|
827
829
|
"stylesheetlist": "https://developer.mozilla.org/docs/Web/API/StyleSheetList",
|
|
828
830
|
"submitevent": "https://developer.mozilla.org/docs/Web/API/SubmitEvent",
|
|
831
|
+
"subscriber": "https://developer.mozilla.org/docs/Web/API/Subscriber",
|
|
829
832
|
"subtlecrypto": "https://developer.mozilla.org/docs/Web/API/SubtleCrypto",
|
|
830
833
|
"summarizer": "https://developer.mozilla.org/docs/Web/API/Summarizer",
|
|
831
834
|
"syncevent": "https://developer.mozilla.org/docs/Web/API/SyncEvent",
|
|
@@ -14,7 +14,6 @@ import {
|
|
|
14
14
|
IGNORE_STABILITY_STEMS,
|
|
15
15
|
} from '#generators/metadata/constants.mjs';
|
|
16
16
|
import { UNIST } from '#utils/queries/index.mjs';
|
|
17
|
-
import { getRemark as remark } from '#utils/remark.mjs';
|
|
18
17
|
import { relative } from '#utils/url.mjs';
|
|
19
18
|
|
|
20
19
|
import { resolveTypeAnnotations } from './resolveTypes.mjs';
|
|
@@ -147,9 +146,8 @@ export const parseApiDoc = ({ path, tree, mdx = false }, typeMap) => {
|
|
|
147
146
|
// Remove processed YAML nodes from the content
|
|
148
147
|
remove(subTree, [UNIST.isYamlNode]);
|
|
149
148
|
|
|
150
|
-
//
|
|
151
|
-
|
|
152
|
-
metadata.content = parsedSubTree;
|
|
149
|
+
// The remark plugins already ran on the whole document, in `ast`
|
|
150
|
+
metadata.content = subTree;
|
|
153
151
|
|
|
154
152
|
// Add to collection
|
|
155
153
|
metadataCollection.push(metadata);
|
|
@@ -72,7 +72,7 @@ export const resolveTypeReference = (name, typeMap) => {
|
|
|
72
72
|
// Transform Node.js types like 'vm.Something'.
|
|
73
73
|
if (MODULE_QUALIFIED_NAME.test(name)) {
|
|
74
74
|
const [mod, ...pieces] = name.split('.');
|
|
75
|
-
const isClass = pieces.at(-1).match(/^[A-Z][a-z]/);
|
|
75
|
+
const isClass = pieces.at(-1).match(/^[A-Z](?=.*[a-z])/);
|
|
76
76
|
|
|
77
77
|
return `${mod}.html#${isClass ? 'class-' : ''}${slug(name)}`;
|
|
78
78
|
}
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
import { SKIP } from 'unist-util-visit';
|
|
4
4
|
|
|
5
|
+
import { getProcessor } from '#utils/markdown/processor.mjs';
|
|
5
6
|
import { QUERIES } from '#utils/queries/index.mjs';
|
|
6
|
-
import { getRemark as remark } from '#utils/remark.mjs';
|
|
7
7
|
import { transformNodesToString } from '#utils/unist.mjs';
|
|
8
8
|
|
|
9
9
|
import { transformUnixManualToLink } from './transformers.mjs';
|
|
@@ -41,7 +41,7 @@ const updateReferences = (query, transformer, node, parent) => {
|
|
|
41
41
|
// and adding those nodes to the parent.
|
|
42
42
|
const {
|
|
43
43
|
children: [newNode],
|
|
44
|
-
} =
|
|
44
|
+
} = getProcessor('metadata').parse(replacedTypes);
|
|
45
45
|
|
|
46
46
|
// Find the index of the original node in the parent
|
|
47
47
|
const index = parent.children.indexOf(node);
|
|
@@ -70,6 +70,14 @@ declare global {
|
|
|
70
70
|
|
|
71
71
|
hasParallelProcessor?: boolean;
|
|
72
72
|
|
|
73
|
+
/**
|
|
74
|
+
* The unified plugins this generator processes Markdown with, listed as
|
|
75
|
+
* in the `markdown` option, with paths relative to its module. Each list
|
|
76
|
+
* takes the configured plugins in place of its `'...'`.
|
|
77
|
+
* `getProcessor(name)` gives its processor.
|
|
78
|
+
*/
|
|
79
|
+
markdown?: import('../utils/configuration/types').MarkdownPipeline;
|
|
80
|
+
|
|
73
81
|
/**
|
|
74
82
|
* The immediate generator that this generator depends on.
|
|
75
83
|
* For example, the `html` generator depends on the `react` generator.
|
package/src/generators.mjs
CHANGED
|
@@ -9,6 +9,7 @@ import { resolvePipeline } from './generators/pipeline.mjs';
|
|
|
9
9
|
import logger from './logger/index.mjs';
|
|
10
10
|
import createWorkerPool from './threading/index.mjs';
|
|
11
11
|
import createParallelWorker from './threading/parallel.mjs';
|
|
12
|
+
import { loadMarkdownPlugins } from './utils/markdown/plugins.mjs';
|
|
12
13
|
import { isAsyncIterable } from './utils/misc.mjs';
|
|
13
14
|
|
|
14
15
|
const generatorsLogger = logger.child('generators');
|
|
@@ -78,6 +79,9 @@ const createGenerator = () => {
|
|
|
78
79
|
|
|
79
80
|
generatorsLogger.debug(`Starting "${name}"`);
|
|
80
81
|
|
|
82
|
+
// Load its Markdown pipeline, for what it processes on this thread
|
|
83
|
+
await loadMarkdownPlugins(generator, configuration[name]?.markdown);
|
|
84
|
+
|
|
81
85
|
// Create parallel worker for streaming generators
|
|
82
86
|
const worker = hasParallelProcessor
|
|
83
87
|
? createParallelWorker(specifier, generator, pool, configuration)
|
package/src/logger/constants.mjs
CHANGED
|
@@ -32,3 +32,38 @@ export const levelToColorMap = {
|
|
|
32
32
|
[LogLevel.error]: 'magenta',
|
|
33
33
|
[LogLevel.fatal]: 'red',
|
|
34
34
|
};
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Maps log level numbers to the GitHub Actions workflow commands reporting
|
|
38
|
+
* them.
|
|
39
|
+
*/
|
|
40
|
+
export const levelToGitHubCommand = {
|
|
41
|
+
[LogLevel.debug]: 'debug',
|
|
42
|
+
[LogLevel.info]: 'notice',
|
|
43
|
+
[LogLevel.warn]: 'warning',
|
|
44
|
+
[LogLevel.error]: 'error',
|
|
45
|
+
[LogLevel.fatal]: 'error',
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Maps the characters a workflow command's message can't hold to their
|
|
50
|
+
* escapes. A command is a line, `::command key=value,key=value::message`,
|
|
51
|
+
* so its message, which runs to the end of the line, can't break it, nor hold
|
|
52
|
+
* the `%` an escape starts with.
|
|
53
|
+
*/
|
|
54
|
+
export const commandDataEscapes = {
|
|
55
|
+
'%': '%25',
|
|
56
|
+
'\r': '%0D',
|
|
57
|
+
'\n': '%0A',
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Maps the characters a workflow command's property can't hold to their
|
|
62
|
+
* escapes: those its message can't, and the `,` separating properties and
|
|
63
|
+
* the `:` of the `::` ending them.
|
|
64
|
+
*/
|
|
65
|
+
export const commandPropertyEscapes = {
|
|
66
|
+
...commandDataEscapes,
|
|
67
|
+
':': '%3A',
|
|
68
|
+
',': '%2C',
|
|
69
|
+
};
|
|
@@ -1,23 +1,35 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { EOL } from 'node:os';
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
commandDataEscapes,
|
|
7
|
+
commandPropertyEscapes,
|
|
8
|
+
levelToGitHubCommand,
|
|
9
|
+
} from '#logger/constants.mjs';
|
|
6
10
|
import { prettifyLevel } from '#logger/utils/colors.mjs';
|
|
7
11
|
import { prettifyTimestamp } from '#logger/utils/time.mjs';
|
|
8
12
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
13
|
+
/**
|
|
14
|
+
* Escapes a value of a workflow command: its message, with
|
|
15
|
+
* `commandDataEscapes`, or one of its properties, with
|
|
16
|
+
* `commandPropertyEscapes`.
|
|
17
|
+
*
|
|
18
|
+
* @param {string | number} value - The value
|
|
19
|
+
* @param {Record<string, string>} escapes - The escapes of the characters it can't hold
|
|
20
|
+
* @returns {string}
|
|
21
|
+
*/
|
|
22
|
+
const escapeCommandValue = (value, escapes) =>
|
|
23
|
+
String(value).replace(
|
|
24
|
+
/[%\r\n:,]/g,
|
|
25
|
+
character => escapes[character] ?? character
|
|
26
|
+
);
|
|
16
27
|
|
|
17
28
|
/**
|
|
18
|
-
* Logs messages to GitHub Actions
|
|
19
|
-
*
|
|
29
|
+
* Logs messages to GitHub Actions as workflow commands, with the file and
|
|
30
|
+
* lines they're about, for them to annotate.
|
|
20
31
|
*
|
|
32
|
+
* @see https://docs.github.com/en/actions/reference/workflows-and-actions/workflow-commands
|
|
21
33
|
* @param {import('../types').TransportContext} context
|
|
22
34
|
* @returns {void}
|
|
23
35
|
*/
|
|
@@ -30,13 +42,34 @@ const github = ({ level, message, timestamp, metadata = {}, module }) => {
|
|
|
30
42
|
|
|
31
43
|
const logMessage = `[${time}] ${prettyLevel}${module ? ` (${module})` : ''}: ${message}`;
|
|
32
44
|
|
|
33
|
-
const
|
|
45
|
+
const command = levelToGitHubCommand[level] ?? 'notice';
|
|
46
|
+
|
|
47
|
+
const data = escapeCommandValue(logMessage, commandDataEscapes);
|
|
34
48
|
|
|
35
|
-
|
|
49
|
+
// Debug messages take no properties
|
|
50
|
+
if (command === 'debug') {
|
|
51
|
+
process.stdout.write(`::debug::${data}${EOL}`);
|
|
52
|
+
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const properties = {
|
|
36
57
|
file: file?.path,
|
|
37
|
-
|
|
58
|
+
line: file?.position?.start.line,
|
|
38
59
|
endLine: file?.position?.end.line,
|
|
39
|
-
}
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const annotations = [];
|
|
63
|
+
|
|
64
|
+
for (const [key, value] of Object.entries(properties)) {
|
|
65
|
+
if (value) {
|
|
66
|
+
annotations.push(
|
|
67
|
+
`${key}=${escapeCommandValue(value, commandPropertyEscapes)}`
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
process.stdout.write(`::${command} ${annotations.join(',')}::${data}${EOL}`);
|
|
40
73
|
};
|
|
41
74
|
|
|
42
75
|
export default github;
|