@forsakringskassan/docs-generator 2.0.0 → 2.1.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/README.md +0 -17
- package/dist/compile-example.js +9 -6
- package/dist/{create-markdown-renderer-Blvx866w.js → create-markdown-renderer-xVpSTRxi.js} +2 -1
- package/dist/index.d.ts +21 -3
- package/dist/index.js +1902 -1823
- package/dist/markdown.js +10 -7
- package/dist/processors/selectable-version.js +1984 -0
- package/dist/runtime.js +1 -1929
- package/dist/style/core.css +36 -0
- package/dist/style/index.css +36 -0
- package/dist/{vendor-DD1glhBC.js → vendor-D59s3fBh.js} +29500 -22681
- package/dist/{vue3-DIgl9PAu.js → vue3-0ybYLno6.js} +1 -1
- package/package.json +5 -4
package/dist/index.js
CHANGED
|
@@ -1,23 +1,25 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var fs = require('node:fs/promises');
|
|
4
|
+
var vendor = require('./vendor-D59s3fBh.js');
|
|
4
5
|
var path = require('node:path');
|
|
5
|
-
var vendor = require('./vendor-DD1glhBC.js');
|
|
6
|
-
var createMarkdownRenderer = require('./create-markdown-renderer-Blvx866w.js');
|
|
7
6
|
var require$$1 = require('crypto');
|
|
8
|
-
require('
|
|
9
|
-
var
|
|
7
|
+
var createMarkdownRenderer = require('./create-markdown-renderer-xVpSTRxi.js');
|
|
8
|
+
var node_child_process = require('node:child_process');
|
|
10
9
|
var path$1 = require('node:path/posix');
|
|
10
|
+
require('node:crypto');
|
|
11
|
+
var util = require('node:util');
|
|
11
12
|
var fs$1 = require('node:fs');
|
|
12
|
-
var
|
|
13
|
+
var vue = require('vue');
|
|
14
|
+
var vue3 = require('./vue3-0ybYLno6.js');
|
|
15
|
+
var vueDocgenApi = require('vue-docgen-api');
|
|
13
16
|
var sass = require('sass');
|
|
17
|
+
var node_url = require('node:url');
|
|
14
18
|
var esbuild = require('esbuild');
|
|
15
|
-
var util = require('node:util');
|
|
16
19
|
var nunjucks = require('nunjucks');
|
|
17
|
-
var vue = require('vue');
|
|
18
|
-
var vue3 = require('./vue3-DIgl9PAu.js');
|
|
19
20
|
var express = require('express');
|
|
20
|
-
|
|
21
|
+
require('@vue/compiler-sfc');
|
|
22
|
+
require('typescript');
|
|
21
23
|
require('fs');
|
|
22
24
|
require('node:events');
|
|
23
25
|
require('node:stream');
|
|
@@ -30,12 +32,13 @@ require('path');
|
|
|
30
32
|
require('readline');
|
|
31
33
|
require('events');
|
|
32
34
|
require('child_process');
|
|
33
|
-
require('node:
|
|
35
|
+
require('node:stream/promises');
|
|
34
36
|
require('node:process');
|
|
35
|
-
require('node:
|
|
37
|
+
require('node:tty');
|
|
36
38
|
require('node:timers/promises');
|
|
37
|
-
require('
|
|
38
|
-
require('
|
|
39
|
+
require('node:os');
|
|
40
|
+
require('node:v8');
|
|
41
|
+
require('node:buffer');
|
|
39
42
|
require('os');
|
|
40
43
|
require('http');
|
|
41
44
|
require('https');
|
|
@@ -47,8 +50,27 @@ require('tty');
|
|
|
47
50
|
require('querystring');
|
|
48
51
|
|
|
49
52
|
var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
|
|
50
|
-
function
|
|
51
|
-
return
|
|
53
|
+
function toArray$2(value) {
|
|
54
|
+
return Array.isArray(value) ? value : [value];
|
|
55
|
+
}
|
|
56
|
+
function matomoProcessor(options) {
|
|
57
|
+
const { enabled, siteId, apiUrl, trackerUrl, hostname } = options;
|
|
58
|
+
return {
|
|
59
|
+
after: "generate-docs",
|
|
60
|
+
name: "matomo-processor",
|
|
61
|
+
enabled,
|
|
62
|
+
handler(context) {
|
|
63
|
+
context.addTemplateBlock("head", "matomo", {
|
|
64
|
+
filename: "partials/matomo.html",
|
|
65
|
+
data: {
|
|
66
|
+
siteId,
|
|
67
|
+
apiUrl,
|
|
68
|
+
trackerUrl,
|
|
69
|
+
hostname: hostname ? toArray$2(hostname) : []
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
};
|
|
52
74
|
}
|
|
53
75
|
|
|
54
76
|
function formatSize(value) {
|
|
@@ -106,6 +128,41 @@ function getIntegrity(source) {
|
|
|
106
128
|
return `sha384-${hash}`;
|
|
107
129
|
}
|
|
108
130
|
|
|
131
|
+
function cacheKey$1(...args) {
|
|
132
|
+
return JSON.stringify(args);
|
|
133
|
+
}
|
|
134
|
+
function memoize(callback) {
|
|
135
|
+
const cache = /* @__PURE__ */ new Map();
|
|
136
|
+
return (...args) => {
|
|
137
|
+
const key = cacheKey$1(args);
|
|
138
|
+
if (!cache.has(key)) {
|
|
139
|
+
cache.set(key, callback(...args));
|
|
140
|
+
}
|
|
141
|
+
return cache.get(key);
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function runCommand(cmd, defaultValue) {
|
|
146
|
+
return new Promise((resolve) => {
|
|
147
|
+
node_child_process.exec(cmd, { encoding: "utf-8" }, (error, stdout) => {
|
|
148
|
+
if (error) {
|
|
149
|
+
console.error(error);
|
|
150
|
+
resolve(defaultValue);
|
|
151
|
+
} else {
|
|
152
|
+
resolve(stdout.trim());
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const gitCommitHash = memoize((format = "short") => {
|
|
159
|
+
if (format === "full") {
|
|
160
|
+
return runCommand(`git rev-parse HEAD`);
|
|
161
|
+
} else {
|
|
162
|
+
return runCommand(`git rev-parse --short HEAD`);
|
|
163
|
+
}
|
|
164
|
+
});
|
|
165
|
+
|
|
109
166
|
function haveOutput(doc) {
|
|
110
167
|
const { fileInfo } = doc;
|
|
111
168
|
return Boolean(fileInfo.outputName);
|
|
@@ -170,556 +227,274 @@ function slugify(value) {
|
|
|
170
227
|
return value.toLowerCase().replace(/\//g, "--").replace(/[^a-z]+/g, "-").replace(/(^-+|-+$)/, "");
|
|
171
228
|
}
|
|
172
229
|
|
|
173
|
-
function
|
|
174
|
-
return
|
|
230
|
+
function flattenOutline(outline) {
|
|
231
|
+
return outline.flatMap((entry) => {
|
|
232
|
+
return [
|
|
233
|
+
{ heading: entry.title, anchor: entry.anchor },
|
|
234
|
+
...flattenOutline(entry.subheadings)
|
|
235
|
+
];
|
|
236
|
+
});
|
|
175
237
|
}
|
|
176
|
-
function
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
return true;
|
|
180
|
-
}
|
|
181
|
-
if (parsed.name.toLowerCase() === "readme") {
|
|
182
|
-
return true;
|
|
183
|
-
}
|
|
184
|
-
if (parsed.name === "index") {
|
|
185
|
-
return true;
|
|
238
|
+
function findExamples(doc) {
|
|
239
|
+
if (doc.format !== "markdown") {
|
|
240
|
+
return [];
|
|
186
241
|
}
|
|
187
|
-
|
|
242
|
+
const collected = [];
|
|
243
|
+
const md = vendor.MarkdownIt();
|
|
244
|
+
md.renderer.rules.fence = (tokens, idx) => {
|
|
245
|
+
const { content, info, map } = tokens[idx];
|
|
246
|
+
const [language, ...tags] = info.split(/\s+/);
|
|
247
|
+
const hashContent = `${map?.[0]}:${map?.[1]}:${info}:${content}`;
|
|
248
|
+
const fingerprint = createMarkdownRenderer.getFingerprint(hashContent);
|
|
249
|
+
collected.push({
|
|
250
|
+
selector: `#example-${fingerprint}`,
|
|
251
|
+
language,
|
|
252
|
+
tags
|
|
253
|
+
});
|
|
254
|
+
return "";
|
|
255
|
+
};
|
|
256
|
+
md.render(doc.body);
|
|
257
|
+
return collected;
|
|
188
258
|
}
|
|
189
|
-
function
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
case "Experimentell":
|
|
198
|
-
return "error";
|
|
199
|
-
case "Prelimin\xE4r":
|
|
200
|
-
case "Draft":
|
|
201
|
-
case "Beta":
|
|
202
|
-
return "info";
|
|
203
|
-
default:
|
|
204
|
-
return "info";
|
|
205
|
-
}
|
|
259
|
+
function manifestPageFromDocument(doc) {
|
|
260
|
+
const { fileInfo } = doc;
|
|
261
|
+
return {
|
|
262
|
+
path: createMarkdownRenderer.getOutputFilePath("", fileInfo),
|
|
263
|
+
title: doc.attributes.title ?? doc.name ?? "",
|
|
264
|
+
outline: flattenOutline(doc.outline),
|
|
265
|
+
examples: findExamples(doc)
|
|
266
|
+
};
|
|
206
267
|
}
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
268
|
+
|
|
269
|
+
function renderMarkdown(manifest) {
|
|
270
|
+
return [
|
|
271
|
+
"## Documentation manifest",
|
|
272
|
+
"",
|
|
273
|
+
"> Do not edit this file. It is a automatically generated by `@forsakringskassan/docs-generator`.",
|
|
274
|
+
"",
|
|
275
|
+
"```",
|
|
276
|
+
...manifest.pages.map((it) => it.path),
|
|
277
|
+
"```",
|
|
278
|
+
""
|
|
279
|
+
].join("\n");
|
|
213
280
|
}
|
|
214
|
-
function
|
|
215
|
-
|
|
216
|
-
return void 0;
|
|
217
|
-
}
|
|
218
|
-
return toArray$3(attrs.component).map((it) => {
|
|
219
|
-
if (typeof it === "string") {
|
|
220
|
-
return {
|
|
221
|
-
name: it
|
|
222
|
-
};
|
|
223
|
-
} else {
|
|
224
|
-
return it;
|
|
225
|
-
}
|
|
226
|
-
});
|
|
281
|
+
function renderJSON(manifest) {
|
|
282
|
+
return JSON.stringify(manifest, null, 2);
|
|
227
283
|
}
|
|
228
|
-
function
|
|
229
|
-
const
|
|
230
|
-
const parsed = path.parse(relative);
|
|
231
|
-
const blocks = vendor.fm(content);
|
|
232
|
-
const attributes = blocks.attributes;
|
|
233
|
-
const isIndex = isIndexPage(parsed);
|
|
234
|
-
const filename = isIndex ? "index" : parsed.name.toLowerCase();
|
|
235
|
-
const name = attributes.name ? attributes.name : parsed.name;
|
|
236
|
-
const urlpath = parsed.dir;
|
|
237
|
-
const outline = getDocumentOutline(blocks.body);
|
|
238
|
-
const include = attributes.include ?? true;
|
|
284
|
+
function manifestProcessor(options = {}) {
|
|
285
|
+
const { markdown, json } = options;
|
|
239
286
|
return {
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
fileInfo: {
|
|
258
|
-
path: ["", "."].includes(urlpath) ? "." : `./${createMarkdownRenderer.normalizePath(urlpath)}`,
|
|
259
|
-
name: filename,
|
|
260
|
-
fullPath: createMarkdownRenderer.normalizePath(filePath),
|
|
261
|
-
outputName: include ? `${filename}.html` : false
|
|
287
|
+
name: "manifestProcessor",
|
|
288
|
+
before: "render",
|
|
289
|
+
async handler(context) {
|
|
290
|
+
const docs = context.docs.filter(haveOutput);
|
|
291
|
+
const pages = docs.map(manifestPageFromDocument);
|
|
292
|
+
pages.sort((a, b) => {
|
|
293
|
+
return a.path.localeCompare(b.path);
|
|
294
|
+
});
|
|
295
|
+
const manifest = { pages };
|
|
296
|
+
if (markdown) {
|
|
297
|
+
const content = renderMarkdown(manifest);
|
|
298
|
+
await fs.writeFile(markdown, content, "utf-8");
|
|
299
|
+
}
|
|
300
|
+
if (json) {
|
|
301
|
+
const content = renderJSON(manifest);
|
|
302
|
+
await fs.writeFile(json, content, "utf-8");
|
|
303
|
+
}
|
|
262
304
|
}
|
|
263
305
|
};
|
|
264
306
|
}
|
|
265
|
-
async function frontMatterFileReader(filePath, basePath) {
|
|
266
|
-
const content = await fs.readFile(filePath, "utf-8");
|
|
267
|
-
const doc = parseFile$1(filePath, basePath, content);
|
|
268
|
-
return [doc];
|
|
269
|
-
}
|
|
270
307
|
|
|
271
|
-
|
|
272
|
-
const
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
name: prop.name,
|
|
278
|
-
description: prop.description ?? EMPTY_CHAR,
|
|
279
|
-
type: prop.type?.name ?? EMPTY_CHAR,
|
|
280
|
-
required: prop.required ? "true" : "false",
|
|
281
|
-
default: prop.defaultValue?.value ?? EMPTY_CHAR
|
|
282
|
-
};
|
|
283
|
-
translatedProps.push(translatedProp);
|
|
284
|
-
}
|
|
285
|
-
return translatedProps;
|
|
308
|
+
function normalizeOptions(options) {
|
|
309
|
+
const defaults = {
|
|
310
|
+
enabled: true,
|
|
311
|
+
container: "body:begin"
|
|
312
|
+
};
|
|
313
|
+
return { ...defaults, ...options };
|
|
286
314
|
}
|
|
287
|
-
function
|
|
288
|
-
const
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
315
|
+
function motdProcessor(options) {
|
|
316
|
+
const { enabled, container, message } = normalizeOptions(options);
|
|
317
|
+
return {
|
|
318
|
+
name: "motd-processor",
|
|
319
|
+
after: "generate-docs",
|
|
320
|
+
handler(context) {
|
|
321
|
+
if (!enabled) {
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
context.addTemplateBlock(container, "version-banner", {
|
|
325
|
+
filename: "partials/version-banner.html",
|
|
326
|
+
data: { message }
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
};
|
|
298
330
|
}
|
|
299
|
-
function
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
}
|
|
305
|
-
if (!properties) {
|
|
306
|
-
return `<anonymous>: ${String(types)}`;
|
|
307
|
-
}
|
|
308
|
-
const translatedProperties = [];
|
|
309
|
-
for (let i = 0; i < properties.length; i++) {
|
|
310
|
-
const property = properties[i];
|
|
311
|
-
const name = property.name ?? "<anonymous>";
|
|
312
|
-
const eventType = types[i];
|
|
313
|
-
const hasEventType = !eventType || eventType !== "undefined";
|
|
314
|
-
const resolvedType = hasEventType ? eventType : String(property.type.names);
|
|
315
|
-
const type = `: ${resolvedType}`;
|
|
316
|
-
const description = property.description ? ` ${EM_DASH} ${property.description}` : "";
|
|
317
|
-
translatedProperties.push(`${name}${type}${description}`);
|
|
318
|
-
}
|
|
319
|
-
return translatedProperties.join("\n");
|
|
320
|
-
}
|
|
321
|
-
function translateSlots(slots) {
|
|
322
|
-
const translatedSlots = [];
|
|
323
|
-
for (const slot of slots) {
|
|
324
|
-
const translatedSlot = {
|
|
325
|
-
name: slot.name,
|
|
326
|
-
description: slot.description ?? EMPTY_CHAR,
|
|
327
|
-
bindings: translateSlotBindings(slot)
|
|
328
|
-
};
|
|
329
|
-
translatedSlots.push(translatedSlot);
|
|
330
|
-
}
|
|
331
|
-
return translatedSlots;
|
|
332
|
-
}
|
|
333
|
-
function translateSlotBindings(slot) {
|
|
334
|
-
if (!slot.bindings) {
|
|
335
|
-
return EMPTY_CHAR;
|
|
336
|
-
}
|
|
337
|
-
const translatedBindings = [];
|
|
338
|
-
for (const binding of slot.bindings) {
|
|
339
|
-
translatedBindings.push(binding.name ? binding.name : EMPTY_CHAR);
|
|
340
|
-
}
|
|
341
|
-
return translatedBindings.join("\n");
|
|
331
|
+
function versionBannerProcessorDeprecated(message, container) {
|
|
332
|
+
return motdProcessor({
|
|
333
|
+
enabled: true,
|
|
334
|
+
container,
|
|
335
|
+
message
|
|
336
|
+
});
|
|
342
337
|
}
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
338
|
+
const versionBannerProcessor = util.deprecate(
|
|
339
|
+
versionBannerProcessorDeprecated,
|
|
340
|
+
"versionBannerProcessor() is deprecated, use motdProcessor() instead"
|
|
341
|
+
);
|
|
342
|
+
|
|
343
|
+
function themeSelectProcessor() {
|
|
348
344
|
return {
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
345
|
+
name: "theme-select-processor",
|
|
346
|
+
after: "generate-docs",
|
|
347
|
+
handler(context) {
|
|
348
|
+
const sessionKey = "fkds-theme";
|
|
349
|
+
const data = {
|
|
350
|
+
defaultTheme: "exp",
|
|
351
|
+
sessionKey
|
|
352
|
+
};
|
|
353
|
+
context.addTemplateBlock("head", "theme-render-blocker", {
|
|
354
|
+
filename: "partials/theme-render-blocker.html",
|
|
355
|
+
data
|
|
356
|
+
});
|
|
357
|
+
context.addTemplateBlock("toolbar", "theme-select", {
|
|
358
|
+
filename: "partials/theme-select.html",
|
|
359
|
+
data
|
|
360
|
+
});
|
|
361
|
+
}
|
|
352
362
|
};
|
|
353
363
|
}
|
|
354
364
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
return [
|
|
358
|
-
"<thead><tr>",
|
|
359
|
-
...headers.map((header) => `<th>${header}</th>`),
|
|
360
|
-
"</tr></thead>"
|
|
361
|
-
].join("");
|
|
362
|
-
}
|
|
363
|
-
function generateTableBody(content) {
|
|
364
|
-
const rows = content.map((row) => {
|
|
365
|
-
return [
|
|
366
|
-
"<tr>",
|
|
367
|
-
...row.map((value) => `<td>${md.render(value)}</td>`),
|
|
368
|
-
"</tr>"
|
|
369
|
-
].join("");
|
|
370
|
-
});
|
|
371
|
-
return ["<tbody>", ...rows, "</tbody>"].join("");
|
|
372
|
-
}
|
|
373
|
-
function generateTable(caption, headers, content) {
|
|
374
|
-
return [
|
|
375
|
-
'<div class="docs-table"><table>',
|
|
376
|
-
`<caption>${caption}</caption>`,
|
|
377
|
-
generateTableHead(headers),
|
|
378
|
-
generateTableBody(content),
|
|
379
|
-
"</table></div>"
|
|
380
|
-
].join("");
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
function capitalize(text) {
|
|
384
|
-
return `${text.charAt(0).toUpperCase()}${text.slice(1)}`;
|
|
385
|
-
}
|
|
386
|
-
function parseAPIToArray(api) {
|
|
387
|
-
const content = [];
|
|
388
|
-
const headers = Object.keys(api[0]);
|
|
389
|
-
const capitalizedHeaders = headers.map(capitalize);
|
|
390
|
-
content.push(capitalizedHeaders);
|
|
391
|
-
for (const row of api) {
|
|
392
|
-
content.push(Object.values(row));
|
|
393
|
-
}
|
|
394
|
-
return content;
|
|
395
|
-
}
|
|
396
|
-
function parseAPI(filePath, api) {
|
|
397
|
-
const relative = createMarkdownRenderer.normalizePath(filePath);
|
|
398
|
-
const parsedPath = path.parse(relative);
|
|
399
|
-
const componentName = parsedPath.name;
|
|
400
|
-
let html = "";
|
|
401
|
-
if (api.props.length) {
|
|
402
|
-
const propsArray = parseAPIToArray(api.props);
|
|
403
|
-
html += generateTable("Props", propsArray[0], propsArray.slice(1));
|
|
404
|
-
}
|
|
405
|
-
if (api.events.length) {
|
|
406
|
-
const eventsArray = parseAPIToArray(api.events);
|
|
407
|
-
html += generateTable("Events", eventsArray[0], eventsArray.slice(1));
|
|
408
|
-
}
|
|
409
|
-
if (api.slots.length) {
|
|
410
|
-
const slotsArray = parseAPIToArray(api.slots);
|
|
411
|
-
html += generateTable("Slots", slotsArray[0], slotsArray.slice(1));
|
|
412
|
-
}
|
|
365
|
+
function selectableVersionProcessor(pkg, container, options) {
|
|
366
|
+
const { enabled = true } = options ?? {};
|
|
413
367
|
return {
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
368
|
+
name: "selectable-version-processor",
|
|
369
|
+
after: "generate-docs",
|
|
370
|
+
runtime: [
|
|
371
|
+
{
|
|
372
|
+
src: "src/runtime/select-version.ts"
|
|
373
|
+
}
|
|
374
|
+
],
|
|
375
|
+
handler(context) {
|
|
376
|
+
if (!enabled) {
|
|
377
|
+
return;
|
|
378
|
+
}
|
|
379
|
+
context.addTemplateBlock(container, "version", {
|
|
380
|
+
filename: "partials/selectable-version.html",
|
|
381
|
+
data: { pkg }
|
|
382
|
+
});
|
|
429
383
|
}
|
|
430
384
|
};
|
|
431
385
|
}
|
|
432
|
-
async function vueFileReader(filePath) {
|
|
433
|
-
const translated = await translateAPI(filePath);
|
|
434
|
-
const doc = parseAPI(filePath, translated);
|
|
435
|
-
return [doc];
|
|
436
|
-
}
|
|
437
386
|
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
}
|
|
448
|
-
async function getDocumentsForSource(src) {
|
|
449
|
-
const { transform } = src;
|
|
450
|
-
const include = await globAll(src.include);
|
|
451
|
-
const exclude = await globAll(src.exclude);
|
|
452
|
-
const files = Array.from(difference(include, exclude));
|
|
453
|
-
const promises = files.map(async (it) => {
|
|
454
|
-
const docs2 = await src.fileReader(it, src.basePath);
|
|
455
|
-
if (transform) {
|
|
456
|
-
return docs2.map((it2) => transform(it2));
|
|
457
|
-
} else {
|
|
458
|
-
return docs2;
|
|
459
|
-
}
|
|
387
|
+
function generateNavigation(entries) {
|
|
388
|
+
const children = entries.map((it, index) => {
|
|
389
|
+
const key = path$1.parse(it.path).name;
|
|
390
|
+
return {
|
|
391
|
+
key,
|
|
392
|
+
sortorder: index,
|
|
393
|
+
children: [],
|
|
394
|
+
...it
|
|
395
|
+
};
|
|
460
396
|
});
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
397
|
+
return {
|
|
398
|
+
key: ".",
|
|
399
|
+
path: "./index.html",
|
|
400
|
+
sortorder: Infinity,
|
|
401
|
+
children
|
|
402
|
+
};
|
|
467
403
|
}
|
|
468
|
-
function
|
|
404
|
+
function topnavProcessor(filename, title) {
|
|
469
405
|
return {
|
|
470
|
-
|
|
471
|
-
name: "
|
|
406
|
+
after: "generate-nav",
|
|
407
|
+
name: "topnav-processor",
|
|
472
408
|
async handler(context) {
|
|
473
|
-
const
|
|
474
|
-
|
|
475
|
-
|
|
409
|
+
const content = await fs.readFile(filename, "utf-8");
|
|
410
|
+
const parsed = JSON.parse(content);
|
|
411
|
+
const rootNode = generateNavigation(parsed);
|
|
412
|
+
context.setTopNavigation({
|
|
413
|
+
title,
|
|
414
|
+
...rootNode
|
|
415
|
+
});
|
|
476
416
|
}
|
|
477
417
|
};
|
|
478
418
|
}
|
|
479
419
|
|
|
480
|
-
function
|
|
481
|
-
const
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
throw new Error(`No title property set in "${filePath}"`);
|
|
420
|
+
async function getGitBranch() {
|
|
421
|
+
const { CHANGE_BRANCH, CHANGE_NAME } = process.env;
|
|
422
|
+
if (CHANGE_BRANCH) {
|
|
423
|
+
return CHANGE_BRANCH;
|
|
485
424
|
}
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
const filename = parsed.name.toLowerCase();
|
|
489
|
-
const name = parsed.name;
|
|
490
|
-
const urlpath = parsed.dir;
|
|
491
|
-
return {
|
|
492
|
-
id: `nav:${filePath.replace(/\\/g, "/")}`,
|
|
493
|
-
name,
|
|
494
|
-
alias: [],
|
|
495
|
-
visible: attributes.href ? true : false,
|
|
496
|
-
attributes: {
|
|
497
|
-
title,
|
|
498
|
-
href,
|
|
499
|
-
sortorder: attributes.sortorder ?? Infinity
|
|
500
|
-
},
|
|
501
|
-
body: content,
|
|
502
|
-
outline: [],
|
|
503
|
-
format: "json",
|
|
504
|
-
tags: [],
|
|
505
|
-
template: "default",
|
|
506
|
-
fileInfo: {
|
|
507
|
-
path: ["", "."].includes(urlpath) ? "." : `./${createMarkdownRenderer.normalizePath(urlpath)}`,
|
|
508
|
-
name: filename,
|
|
509
|
-
fullPath: createMarkdownRenderer.normalizePath(filePath),
|
|
510
|
-
outputName: false
|
|
511
|
-
}
|
|
512
|
-
};
|
|
513
|
-
}
|
|
514
|
-
async function navigationFileReader(filePath, basePath) {
|
|
515
|
-
const content = await fs.readFile(filePath, "utf-8");
|
|
516
|
-
const doc = parseFile(filePath, basePath, content);
|
|
517
|
-
return [doc];
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
function resolveScssImport(filePath) {
|
|
521
|
-
const { dir, base } = path$1.parse(filePath);
|
|
522
|
-
const search = [`${base}.css`, `${base}.scss`, `_${base}.scss`, `${base}`];
|
|
523
|
-
for (const variant of search) {
|
|
524
|
-
try {
|
|
525
|
-
const moduleName = path$1.join(dir, variant);
|
|
526
|
-
const resolved = require.resolve(moduleName);
|
|
527
|
-
return node_url.pathToFileURL(resolved);
|
|
528
|
-
} catch (err) {
|
|
529
|
-
if (err.code !== "MODULE_NOT_FOUND") {
|
|
530
|
-
throw err;
|
|
531
|
-
}
|
|
532
|
-
}
|
|
425
|
+
if (CHANGE_NAME) {
|
|
426
|
+
return CHANGE_NAME;
|
|
533
427
|
}
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
if (url.startsWith("file://")) {
|
|
543
|
-
const path$1 = node_url.fileURLToPath(url);
|
|
544
|
-
const relative = path.isAbsolute(path$1) ? path.relative(__dirname, path$1) : path$1;
|
|
545
|
-
return resolveScssImport(relative.replace(/\\/g, "/"));
|
|
546
|
-
}
|
|
547
|
-
return null;
|
|
548
|
-
},
|
|
549
|
-
async load(url) {
|
|
550
|
-
const filepath = node_url.fileURLToPath(url);
|
|
551
|
-
const parsed = path.parse(filepath);
|
|
552
|
-
const contents = await fs.readFile(filepath, "utf-8");
|
|
553
|
-
return {
|
|
554
|
-
contents,
|
|
555
|
-
syntax: parsed.ext.slice(1) === "scss" ? "scss" : "css"
|
|
556
|
-
};
|
|
428
|
+
const branch = await runCommand(
|
|
429
|
+
"git rev-parse --abbrev-ref HEAD",
|
|
430
|
+
"unknown"
|
|
431
|
+
);
|
|
432
|
+
if (branch === "HEAD" || branch === "") {
|
|
433
|
+
return "unknown";
|
|
434
|
+
} else {
|
|
435
|
+
return branch;
|
|
557
436
|
}
|
|
558
|
-
};
|
|
559
|
-
|
|
560
|
-
async function compileSassString(dst, style) {
|
|
561
|
-
const result = await sass.compileStringAsync(style, {
|
|
562
|
-
style: "expanded",
|
|
563
|
-
importers: [tildeImporter]
|
|
564
|
-
});
|
|
565
|
-
await fs.mkdir(path.dirname(dst), { recursive: true });
|
|
566
|
-
await fs.writeFile(dst, result.css, "utf-8");
|
|
567
437
|
}
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
const
|
|
572
|
-
|
|
573
|
-
await compileSassString(outfile, source);
|
|
574
|
-
const content = await fs.readFile(outfile, "utf-8");
|
|
575
|
-
const fingerprint = createMarkdownRenderer.getFingerprint(content);
|
|
576
|
-
const integrity = getIntegrity(content);
|
|
577
|
-
const filename = `${name}-${fingerprint}.css`;
|
|
578
|
-
const dst = path$1.join(assetFolder, filename);
|
|
579
|
-
await fs.rename(outfile, dst);
|
|
580
|
-
const stat = await fs.stat(dst);
|
|
581
|
-
return {
|
|
582
|
-
name,
|
|
583
|
-
filename,
|
|
584
|
-
publicPath: `./assets/${filename}`,
|
|
585
|
-
integrity,
|
|
586
|
-
size: stat.size,
|
|
587
|
-
type: "css"
|
|
588
|
-
};
|
|
589
|
-
} catch (err) {
|
|
590
|
-
console.error(err);
|
|
591
|
-
throw new Error(`Failed to compile style "${name}"`);
|
|
438
|
+
function getPullRequestID() {
|
|
439
|
+
if (process.env.JOB_BASE_NAME) {
|
|
440
|
+
const name = process.env.JOB_BASE_NAME;
|
|
441
|
+
const match = name.match(/PR-(\d+)/);
|
|
442
|
+
return match ? match[1] : void 0;
|
|
592
443
|
}
|
|
444
|
+
return void 0;
|
|
593
445
|
}
|
|
594
|
-
|
|
595
|
-
|
|
446
|
+
async function getSCMData(pkg, options) {
|
|
447
|
+
const commitHash = await gitCommitHash("full");
|
|
448
|
+
const commitShort = await gitCommitHash("short");
|
|
449
|
+
if (!commitHash || !commitShort) {
|
|
450
|
+
return null;
|
|
451
|
+
}
|
|
452
|
+
const { homepage } = pkg;
|
|
453
|
+
const pr = getPullRequestID();
|
|
454
|
+
const prUrl = pr ? interpolate(options.prUrlFormat, { homepage, pr }) : void 0;
|
|
596
455
|
return {
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
asset.src
|
|
608
|
-
);
|
|
609
|
-
const attrs = serializeAttrs(asset.options.attributes);
|
|
610
|
-
const inject = { ...info, attrs: Array.from(attrs).join(" ") };
|
|
611
|
-
assetInfo[asset.name] = info;
|
|
612
|
-
switch (asset.options.appendTo) {
|
|
613
|
-
case "none":
|
|
614
|
-
break;
|
|
615
|
-
case "head":
|
|
616
|
-
head.push(inject);
|
|
617
|
-
break;
|
|
618
|
-
case "body":
|
|
619
|
-
body.push(inject);
|
|
620
|
-
break;
|
|
621
|
-
}
|
|
622
|
-
context.setTemplateData("injectHead", head);
|
|
623
|
-
context.setTemplateData("injectBody", body);
|
|
624
|
-
context.log(info.filename, formatSize(info.size));
|
|
625
|
-
}
|
|
626
|
-
context.setTemplateData("assets", assetInfo);
|
|
627
|
-
}
|
|
456
|
+
branch: await getGitBranch(),
|
|
457
|
+
commitShort,
|
|
458
|
+
commitHash,
|
|
459
|
+
commitUrl: interpolate(options.commitUrlFormat, {
|
|
460
|
+
hash: commitHash,
|
|
461
|
+
short: commitShort,
|
|
462
|
+
homepage
|
|
463
|
+
}),
|
|
464
|
+
pr,
|
|
465
|
+
prUrl
|
|
628
466
|
};
|
|
629
467
|
}
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
if (Array.isArray(value)) {
|
|
633
|
-
return value;
|
|
634
|
-
} else {
|
|
635
|
-
return [value];
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
|
-
async function compileScript(assetFolder, name, src, options) {
|
|
639
|
-
const iconLib = process.env.DOCS_ICON_LIB ?? "@fkui/icon-lib-default";
|
|
640
|
-
try {
|
|
641
|
-
const outfile = path.join("temp", `asset-${name}.js`);
|
|
642
|
-
await esbuild.build({
|
|
643
|
-
entryPoints: toArray$2(src),
|
|
644
|
-
outfile,
|
|
645
|
-
bundle: true,
|
|
646
|
-
format: "iife",
|
|
647
|
-
platform: "browser",
|
|
648
|
-
external: ["vue", "@fkui/vue"],
|
|
649
|
-
tsconfig: path.join(__dirname, "../tsconfig-examples.json"),
|
|
650
|
-
define: {
|
|
651
|
-
"process.env.DOCS_ICON_LIB": JSON.stringify(iconLib)
|
|
652
|
-
},
|
|
653
|
-
...options
|
|
654
|
-
});
|
|
655
|
-
const content = await fs.readFile(outfile, "utf-8");
|
|
656
|
-
const fingerprint = createMarkdownRenderer.getFingerprint(content);
|
|
657
|
-
const integrity = getIntegrity(content);
|
|
658
|
-
const filename = `${name}-${fingerprint}.js`;
|
|
659
|
-
const dst = path.join(assetFolder, filename);
|
|
660
|
-
await fs.rename(outfile, dst);
|
|
661
|
-
const stat = await fs.stat(dst);
|
|
662
|
-
return {
|
|
663
|
-
name,
|
|
664
|
-
filename,
|
|
665
|
-
publicPath: `./assets/${filename}`,
|
|
666
|
-
integrity,
|
|
667
|
-
size: stat.size,
|
|
668
|
-
type: "js"
|
|
669
|
-
};
|
|
670
|
-
} catch {
|
|
671
|
-
throw new Error(`Failed to compile script "${name}"`);
|
|
672
|
-
}
|
|
673
|
-
}
|
|
674
|
-
|
|
675
|
-
function jsAssetProcessor(assetFolder, assets) {
|
|
468
|
+
function getBuildDatetime() {
|
|
469
|
+
const date = /* @__PURE__ */ new Date();
|
|
676
470
|
return {
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
const body = context.getTemplateData("injectBody") ?? [];
|
|
683
|
-
for (const asset of assets) {
|
|
684
|
-
const info = await compileScript(
|
|
685
|
-
assetFolder,
|
|
686
|
-
asset.name,
|
|
687
|
-
asset.src
|
|
688
|
-
);
|
|
689
|
-
const attrs = serializeAttrs(asset.options.attributes);
|
|
690
|
-
const inject = { ...info, attrs: Array.from(attrs).join(" ") };
|
|
691
|
-
assetInfo[asset.name] = info;
|
|
692
|
-
switch (asset.options.appendTo) {
|
|
693
|
-
case "none":
|
|
694
|
-
break;
|
|
695
|
-
case "head":
|
|
696
|
-
head.push(inject);
|
|
697
|
-
break;
|
|
698
|
-
case "body":
|
|
699
|
-
body.push(inject);
|
|
700
|
-
break;
|
|
701
|
-
}
|
|
702
|
-
context.setTemplateData("injectHead", head);
|
|
703
|
-
context.setTemplateData("injectBody", body);
|
|
704
|
-
context.log(info.filename, formatSize(info.size));
|
|
705
|
-
}
|
|
706
|
-
}
|
|
471
|
+
date: date.toLocaleDateString("sv-SE"),
|
|
472
|
+
time: date.toLocaleTimeString("sv-SE", {
|
|
473
|
+
hour: "2-digit",
|
|
474
|
+
minute: "2-digit"
|
|
475
|
+
})
|
|
707
476
|
};
|
|
708
477
|
}
|
|
709
|
-
|
|
710
|
-
|
|
478
|
+
function versionProcessor(pkg, container, options) {
|
|
479
|
+
const { enabled = true, scm = false } = options ?? {};
|
|
711
480
|
return {
|
|
712
|
-
name: "
|
|
713
|
-
after: "
|
|
481
|
+
name: "version-processor",
|
|
482
|
+
after: "generate-docs",
|
|
714
483
|
async handler(context) {
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
const dst = path$1.join(assetFolder, resource.to);
|
|
718
|
-
await fs.cp(src, dst, {
|
|
719
|
-
recursive: true
|
|
720
|
-
});
|
|
721
|
-
context.log(src, "->", dst);
|
|
484
|
+
if (!enabled) {
|
|
485
|
+
return;
|
|
722
486
|
}
|
|
487
|
+
const scmData = scm ? await getSCMData(pkg, scm) : null;
|
|
488
|
+
const buildData = getBuildDatetime();
|
|
489
|
+
const data = {
|
|
490
|
+
pkg,
|
|
491
|
+
scm: scmData,
|
|
492
|
+
build: buildData
|
|
493
|
+
};
|
|
494
|
+
context.addTemplateBlock(container, "version", {
|
|
495
|
+
filename: "partials/version.njk.html",
|
|
496
|
+
data
|
|
497
|
+
});
|
|
723
498
|
}
|
|
724
499
|
};
|
|
725
500
|
}
|
|
@@ -823,1467 +598,1769 @@ function generateStaticExample(options) {
|
|
|
823
598
|
};
|
|
824
599
|
}
|
|
825
600
|
|
|
826
|
-
function
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
}
|
|
839
|
-
function getParentKey(name) {
|
|
840
|
-
return name.split("/").slice(0, -1).join("/");
|
|
841
|
-
}
|
|
842
|
-
function generateNavtree(docs) {
|
|
843
|
-
const section = {};
|
|
844
|
-
function createSection(key, title, sortorder) {
|
|
845
|
-
const existing = section[key];
|
|
846
|
-
if (existing) {
|
|
847
|
-
existing.title = title;
|
|
848
|
-
existing.sortorder = sortorder;
|
|
849
|
-
} else {
|
|
850
|
-
const node = {
|
|
851
|
-
key,
|
|
852
|
-
title,
|
|
853
|
-
path: "",
|
|
854
|
-
sortorder,
|
|
855
|
-
children: []
|
|
856
|
-
};
|
|
857
|
-
section[key] = node;
|
|
858
|
-
if (key !== ".") {
|
|
859
|
-
const parent = attach(key);
|
|
860
|
-
parent.children.push(node);
|
|
861
|
-
}
|
|
862
|
-
}
|
|
863
|
-
}
|
|
864
|
-
function attach(key) {
|
|
865
|
-
const parentKey = getParentKey(key);
|
|
866
|
-
let parent = section[parentKey];
|
|
867
|
-
if (parent) {
|
|
868
|
-
return parent;
|
|
869
|
-
}
|
|
870
|
-
parent = {
|
|
871
|
-
key: parentKey,
|
|
872
|
-
title: parentKey.split("/").at(-1) ?? "(missing title)",
|
|
873
|
-
path: "",
|
|
874
|
-
sortorder: Infinity,
|
|
875
|
-
children: []
|
|
876
|
-
};
|
|
877
|
-
section[parentKey] = parent;
|
|
878
|
-
let anchestor = parentKey;
|
|
879
|
-
let current = parent;
|
|
880
|
-
while (anchestor !== ".") {
|
|
881
|
-
anchestor = getParentKey(anchestor);
|
|
882
|
-
if (section[anchestor]) {
|
|
883
|
-
section[anchestor].children.push(current);
|
|
884
|
-
break;
|
|
885
|
-
}
|
|
886
|
-
const node = {
|
|
887
|
-
key: anchestor,
|
|
888
|
-
title: "",
|
|
889
|
-
path: "",
|
|
890
|
-
sortorder: Infinity,
|
|
891
|
-
children: [current]
|
|
892
|
-
};
|
|
893
|
-
section[anchestor] = node;
|
|
894
|
-
current = node;
|
|
895
|
-
}
|
|
896
|
-
return parent;
|
|
897
|
-
}
|
|
898
|
-
for (const doc of docs) {
|
|
899
|
-
const [name, isSection] = pathFromDoc(doc);
|
|
900
|
-
const title = doc.attributes.title ?? doc.fileInfo.name;
|
|
901
|
-
const sortorder = doc.attributes.sortorder;
|
|
902
|
-
if (doc.attributes.href) {
|
|
903
|
-
const parent2 = attach(name);
|
|
904
|
-
const leafNode = {
|
|
905
|
-
id: doc.id,
|
|
906
|
-
title,
|
|
907
|
-
path: doc.attributes.href,
|
|
908
|
-
sortorder,
|
|
909
|
-
external: true
|
|
910
|
-
};
|
|
911
|
-
parent2.children.push(leafNode);
|
|
912
|
-
continue;
|
|
913
|
-
}
|
|
914
|
-
if (!doc.fileInfo.outputName) {
|
|
915
|
-
if (isSection) {
|
|
916
|
-
createSection(name, title, sortorder);
|
|
917
|
-
}
|
|
918
|
-
continue;
|
|
919
|
-
}
|
|
920
|
-
if (!doc.visible) {
|
|
921
|
-
if (isSection) {
|
|
922
|
-
createSection(name, title, sortorder);
|
|
601
|
+
function sourceUrlProcessor(options) {
|
|
602
|
+
const {
|
|
603
|
+
enabled = true,
|
|
604
|
+
urlFormat,
|
|
605
|
+
componentFileExtension = "vue"
|
|
606
|
+
} = options;
|
|
607
|
+
return {
|
|
608
|
+
after: "generate-docs",
|
|
609
|
+
name: "source-url-processor",
|
|
610
|
+
async handler(context) {
|
|
611
|
+
if (!enabled) {
|
|
612
|
+
return;
|
|
923
613
|
}
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
if (isSection) {
|
|
932
|
-
const leafNode = {
|
|
933
|
-
id: doc.id,
|
|
934
|
-
title,
|
|
935
|
-
path: `${name}/`,
|
|
936
|
-
sortorder,
|
|
937
|
-
external: false
|
|
938
|
-
};
|
|
939
|
-
const existing = section[name];
|
|
940
|
-
if (existing) {
|
|
941
|
-
existing.title = title;
|
|
942
|
-
existing.path = leafNode.path;
|
|
943
|
-
existing.sortorder = sortorder;
|
|
944
|
-
existing.children.unshift(leafNode);
|
|
945
|
-
} else {
|
|
946
|
-
const sectionNode = {
|
|
947
|
-
key: name,
|
|
948
|
-
title,
|
|
949
|
-
path: leafNode.path,
|
|
950
|
-
sortorder,
|
|
951
|
-
children: [leafNode]
|
|
952
|
-
};
|
|
953
|
-
section[name] = sectionNode;
|
|
954
|
-
parent.children.push(sectionNode);
|
|
614
|
+
const hash = await gitCommitHash("full") ?? "";
|
|
615
|
+
const short = await gitCommitHash("short") ?? "";
|
|
616
|
+
function componentSourceUrl(component) {
|
|
617
|
+
const { source, name } = component;
|
|
618
|
+
const filename = source ?? `${name}.${componentFileExtension}`;
|
|
619
|
+
const path = getExampleImport(["./"], filename);
|
|
620
|
+
return interpolate(urlFormat, { path, hash, short });
|
|
955
621
|
}
|
|
956
|
-
|
|
957
|
-
const leafNode = {
|
|
958
|
-
id: doc.id,
|
|
959
|
-
title,
|
|
960
|
-
path: `${doc.fileInfo.path}/${doc.fileInfo.outputName}`,
|
|
961
|
-
sortorder,
|
|
962
|
-
external: false
|
|
963
|
-
};
|
|
964
|
-
parent.children.push(leafNode);
|
|
622
|
+
context.setTemplateData("componentSourceUrl", componentSourceUrl);
|
|
965
623
|
}
|
|
966
|
-
}
|
|
967
|
-
const root = section["."];
|
|
968
|
-
if (root) {
|
|
969
|
-
return root;
|
|
970
|
-
} else {
|
|
971
|
-
return {
|
|
972
|
-
key: ".",
|
|
973
|
-
title: "",
|
|
974
|
-
path: "",
|
|
975
|
-
sortorder: Infinity,
|
|
976
|
-
children: []
|
|
977
|
-
};
|
|
978
|
-
}
|
|
624
|
+
};
|
|
979
625
|
}
|
|
980
626
|
|
|
981
|
-
function
|
|
627
|
+
function cookieProcessor(options = {}) {
|
|
628
|
+
const { enabled = true } = options;
|
|
982
629
|
return {
|
|
983
|
-
|
|
984
|
-
name: "
|
|
985
|
-
handler(context) {
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
630
|
+
after: "generate-docs",
|
|
631
|
+
name: "cookie-processor",
|
|
632
|
+
async handler(context) {
|
|
633
|
+
if (!enabled) {
|
|
634
|
+
return;
|
|
635
|
+
}
|
|
636
|
+
context.addTemplateBlock("body:begin", "cookie-warning", {
|
|
637
|
+
filename: "partials/cookie-warning.html"
|
|
638
|
+
});
|
|
989
639
|
}
|
|
990
640
|
};
|
|
991
641
|
}
|
|
992
642
|
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
}
|
|
1008
|
-
return 0;
|
|
1009
|
-
});
|
|
1010
|
-
for (const child of tree.children) {
|
|
1011
|
-
if (isNavigationSection(child)) {
|
|
1012
|
-
sortNavigationTree(child);
|
|
1013
|
-
}
|
|
1014
|
-
}
|
|
643
|
+
const availableProcessors = [
|
|
644
|
+
cookieProcessor(),
|
|
645
|
+
manifestProcessor(),
|
|
646
|
+
matomoProcessor({ siteId: "", trackerUrl: "" }),
|
|
647
|
+
motdProcessor({ message: "" }),
|
|
648
|
+
selectableVersionProcessor({ name: "", version: "" }, ""),
|
|
649
|
+
sourceUrlProcessor({ urlFormat: "" }),
|
|
650
|
+
themeSelectProcessor(),
|
|
651
|
+
topnavProcessor("", ""),
|
|
652
|
+
versionProcessor({ name: "", version: "", homepage: "" }, "")
|
|
653
|
+
];
|
|
654
|
+
|
|
655
|
+
function defineSources(sources) {
|
|
656
|
+
return sources;
|
|
1015
657
|
}
|
|
1016
658
|
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
659
|
+
function toArray$1(value) {
|
|
660
|
+
return Array.isArray(value) ? value : [value];
|
|
661
|
+
}
|
|
662
|
+
function isIndexPage(parsed) {
|
|
663
|
+
const folder = path.basename(parsed.dir);
|
|
664
|
+
if (parsed.name === folder) {
|
|
665
|
+
return true;
|
|
1024
666
|
}
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
const { content, filePath } = await this.resolveTemplate(name);
|
|
1028
|
-
callback(null, {
|
|
1029
|
-
src: content,
|
|
1030
|
-
path: filePath,
|
|
1031
|
-
noCache: false
|
|
1032
|
-
});
|
|
1033
|
-
} catch (err) {
|
|
1034
|
-
if (err instanceof Error) {
|
|
1035
|
-
callback(err, null);
|
|
1036
|
-
} else {
|
|
1037
|
-
callback(new Error(String(err)), null);
|
|
1038
|
-
}
|
|
1039
|
-
}
|
|
667
|
+
if (parsed.name.toLowerCase() === "readme") {
|
|
668
|
+
return true;
|
|
1040
669
|
}
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
const cached = templateCache.get(name);
|
|
1044
|
-
if (cached) {
|
|
1045
|
-
return cached;
|
|
1046
|
-
}
|
|
1047
|
-
const searchPaths = folders.map((it) => path.join(it, name));
|
|
1048
|
-
const filePath = searchPaths.find((it) => fs$1.existsSync(it));
|
|
1049
|
-
if (!filePath) {
|
|
1050
|
-
const searched = folders.map((it) => ` - "${it}"`).join("\n");
|
|
1051
|
-
const message = `Failed to resolve template "${name}", searched in:
|
|
1052
|
-
|
|
1053
|
-
${searched}
|
|
1054
|
-
|
|
1055
|
-
Make sure the name is correct and the template file exists in one of the listed directories.`;
|
|
1056
|
-
throw new Error(message);
|
|
1057
|
-
}
|
|
1058
|
-
const content = await fs.readFile(filePath, "utf-8");
|
|
1059
|
-
const resolved = { content, filePath };
|
|
1060
|
-
templateCache.set(name, resolved);
|
|
1061
|
-
return resolved;
|
|
670
|
+
if (parsed.name === "index") {
|
|
671
|
+
return true;
|
|
1062
672
|
}
|
|
673
|
+
return false;
|
|
1063
674
|
}
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
}
|
|
1068
|
-
|
|
1069
|
-
function json(value) {
|
|
1070
|
-
return JSON.stringify(value, null, 2);
|
|
1071
|
-
}
|
|
1072
|
-
|
|
1073
|
-
function isExternalUrl(url) {
|
|
1074
|
-
return url.startsWith("http://") || url.startsWith("https://") || url.startsWith("//");
|
|
1075
|
-
}
|
|
1076
|
-
function isAbsoluteUrl(url) {
|
|
1077
|
-
return url.startsWith("/");
|
|
1078
|
-
}
|
|
1079
|
-
function relative(url, { fileInfo }) {
|
|
1080
|
-
if (isExternalUrl(url)) {
|
|
1081
|
-
return url;
|
|
675
|
+
function getBadge(attrs) {
|
|
676
|
+
if (!attrs.status) {
|
|
677
|
+
return void 0;
|
|
1082
678
|
}
|
|
1083
|
-
|
|
1084
|
-
|
|
679
|
+
switch (attrs.status) {
|
|
680
|
+
case "Produktionsklar":
|
|
681
|
+
return "success";
|
|
682
|
+
case "Deprekerad":
|
|
683
|
+
case "Experimentell":
|
|
684
|
+
return "error";
|
|
685
|
+
case "Prelimin\xE4r":
|
|
686
|
+
case "Draft":
|
|
687
|
+
case "Beta":
|
|
688
|
+
return "info";
|
|
689
|
+
default:
|
|
690
|
+
return "info";
|
|
1085
691
|
}
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
if (
|
|
1089
|
-
return
|
|
692
|
+
}
|
|
693
|
+
function getComponentAlias(attrs) {
|
|
694
|
+
if (attrs.component) {
|
|
695
|
+
return toArray$1(attrs.component).map((it) => `component:${it}`);
|
|
696
|
+
} else {
|
|
697
|
+
return [];
|
|
1090
698
|
}
|
|
1091
|
-
const relative2 = path$1.relative(outputPath, url);
|
|
1092
|
-
const prefix = relative2.startsWith(".") ? "" : "./";
|
|
1093
|
-
const suffix = url.endsWith("/") ? "/" : "";
|
|
1094
|
-
return [prefix, relative2, suffix].join("");
|
|
1095
699
|
}
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
700
|
+
function getComponent(attrs) {
|
|
701
|
+
if (!attrs.component) {
|
|
702
|
+
return void 0;
|
|
703
|
+
}
|
|
704
|
+
return toArray$1(attrs.component).map((it) => {
|
|
705
|
+
if (typeof it === "string") {
|
|
706
|
+
return {
|
|
707
|
+
name: it
|
|
708
|
+
};
|
|
709
|
+
} else {
|
|
710
|
+
return it;
|
|
711
|
+
}
|
|
712
|
+
});
|
|
713
|
+
}
|
|
714
|
+
function parseFile$1(filePath, basePath, content) {
|
|
715
|
+
const relative = basePath ? path.relative(basePath, createMarkdownRenderer.normalizePath(filePath)) : createMarkdownRenderer.normalizePath(filePath);
|
|
716
|
+
const parsed = path.parse(relative);
|
|
717
|
+
const blocks = vendor.fm(content);
|
|
718
|
+
const attributes = blocks.attributes;
|
|
719
|
+
const isIndex = isIndexPage(parsed);
|
|
720
|
+
const filename = isIndex ? "index" : parsed.name.toLowerCase();
|
|
721
|
+
const name = attributes.name ? attributes.name : parsed.name;
|
|
722
|
+
const urlpath = parsed.dir;
|
|
723
|
+
const outline = getDocumentOutline(blocks.body);
|
|
724
|
+
const include = attributes.include ?? true;
|
|
725
|
+
return {
|
|
726
|
+
id: `fs:${filePath.replace(/\\/g, "/")}`,
|
|
727
|
+
name,
|
|
728
|
+
alias: [...getComponentAlias(attributes)],
|
|
729
|
+
visible: attributes.visible ?? true,
|
|
730
|
+
attributes: {
|
|
731
|
+
title: attributes.title ?? name,
|
|
732
|
+
layout: attributes.layout,
|
|
733
|
+
status: attributes.status,
|
|
734
|
+
badge: getBadge(attributes),
|
|
735
|
+
component: getComponent(attributes),
|
|
736
|
+
sortorder: attributes.sortorder ?? Infinity
|
|
737
|
+
},
|
|
738
|
+
body: blocks.body,
|
|
739
|
+
outline,
|
|
740
|
+
format: "markdown",
|
|
741
|
+
tags: [],
|
|
742
|
+
template: blocks.attributes.layout ?? "default",
|
|
743
|
+
fileInfo: {
|
|
744
|
+
path: ["", "."].includes(urlpath) ? "." : `./${createMarkdownRenderer.normalizePath(urlpath)}`,
|
|
745
|
+
name: filename,
|
|
746
|
+
fullPath: createMarkdownRenderer.normalizePath(filePath),
|
|
747
|
+
outputName: include ? `${filename}.html` : false
|
|
748
|
+
}
|
|
749
|
+
};
|
|
750
|
+
}
|
|
751
|
+
async function frontMatterFileReader(filePath, basePath) {
|
|
752
|
+
const content = await fs.readFile(filePath, "utf-8");
|
|
753
|
+
const doc = parseFile$1(filePath, basePath, content);
|
|
754
|
+
return [doc];
|
|
1099
755
|
}
|
|
1100
756
|
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
...this.searchDir.map((it) => ` - ${it}`)
|
|
1115
|
-
].join("\n");
|
|
757
|
+
const EMPTY_CHAR = "‐";
|
|
758
|
+
const EM_DASH = "—";
|
|
759
|
+
function translateProps(props) {
|
|
760
|
+
const translatedProps = [];
|
|
761
|
+
for (const prop of props) {
|
|
762
|
+
const translatedProp = {
|
|
763
|
+
name: prop.name,
|
|
764
|
+
description: prop.description ?? EMPTY_CHAR,
|
|
765
|
+
type: prop.type?.name ?? EMPTY_CHAR,
|
|
766
|
+
required: prop.required ? "true" : "false",
|
|
767
|
+
default: prop.defaultValue?.value ?? EMPTY_CHAR
|
|
768
|
+
};
|
|
769
|
+
translatedProps.push(translatedProp);
|
|
1116
770
|
}
|
|
771
|
+
return translatedProps;
|
|
1117
772
|
}
|
|
1118
|
-
|
|
1119
|
-
const
|
|
1120
|
-
|
|
1121
|
-
|
|
773
|
+
function translateEvents(events) {
|
|
774
|
+
const translatedEvents = [];
|
|
775
|
+
for (const event of events) {
|
|
776
|
+
const translatedEvent = {
|
|
777
|
+
name: event.name,
|
|
778
|
+
description: event.description ?? EMPTY_CHAR,
|
|
779
|
+
properties: translateEventProperties(event)
|
|
780
|
+
};
|
|
781
|
+
translatedEvents.push(translatedEvent);
|
|
782
|
+
}
|
|
783
|
+
return translatedEvents;
|
|
1122
784
|
}
|
|
1123
|
-
function
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
} else {
|
|
1129
|
-
layout = src.template;
|
|
1130
|
-
format = src.format !== "json" ? "html" : "json";
|
|
785
|
+
function translateEventProperties(event) {
|
|
786
|
+
const properties = event.properties;
|
|
787
|
+
const types = event.type ? Object.values(event.type.names) : [];
|
|
788
|
+
if (!properties && !types.length) {
|
|
789
|
+
return EMPTY_CHAR;
|
|
1131
790
|
}
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
if (cached) {
|
|
1135
|
-
return cached;
|
|
791
|
+
if (!properties) {
|
|
792
|
+
return `<anonymous>: ${String(types)}`;
|
|
1136
793
|
}
|
|
1137
|
-
const
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
794
|
+
const translatedProperties = [];
|
|
795
|
+
for (let i = 0; i < properties.length; i++) {
|
|
796
|
+
const property = properties[i];
|
|
797
|
+
const name = property.name ?? "<anonymous>";
|
|
798
|
+
const eventType = types[i];
|
|
799
|
+
const hasEventType = !eventType || eventType !== "undefined";
|
|
800
|
+
const resolvedType = hasEventType ? eventType : String(property.type.names);
|
|
801
|
+
const type = `: ${resolvedType}`;
|
|
802
|
+
const description = property.description ? ` ${EM_DASH} ${property.description}` : "";
|
|
803
|
+
translatedProperties.push(`${name}${type}${description}`);
|
|
1143
804
|
}
|
|
1144
|
-
|
|
1145
|
-
return template;
|
|
1146
|
-
}
|
|
1147
|
-
|
|
1148
|
-
const scriptPath = path.join(__dirname, "compile-example.js");
|
|
1149
|
-
let loader = null;
|
|
1150
|
-
function haveOutputFile(fileInfo) {
|
|
1151
|
-
return fileInfo.outputName !== false;
|
|
805
|
+
return translatedProperties.join("\n");
|
|
1152
806
|
}
|
|
1153
|
-
function
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
...node,
|
|
1161
|
-
active,
|
|
1162
|
-
children
|
|
1163
|
-
};
|
|
1164
|
-
} else {
|
|
1165
|
-
const active = doc.id === node.id;
|
|
1166
|
-
return {
|
|
1167
|
-
...node,
|
|
1168
|
-
active
|
|
807
|
+
function translateSlots(slots) {
|
|
808
|
+
const translatedSlots = [];
|
|
809
|
+
for (const slot of slots) {
|
|
810
|
+
const translatedSlot = {
|
|
811
|
+
name: slot.name,
|
|
812
|
+
description: slot.description ?? EMPTY_CHAR,
|
|
813
|
+
bindings: translateSlotBindings(slot)
|
|
1169
814
|
};
|
|
815
|
+
translatedSlots.push(translatedSlot);
|
|
1170
816
|
}
|
|
817
|
+
return translatedSlots;
|
|
1171
818
|
}
|
|
1172
|
-
function
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
819
|
+
function translateSlotBindings(slot) {
|
|
820
|
+
if (!slot.bindings) {
|
|
821
|
+
return EMPTY_CHAR;
|
|
822
|
+
}
|
|
823
|
+
const translatedBindings = [];
|
|
824
|
+
for (const binding of slot.bindings) {
|
|
825
|
+
translatedBindings.push(binding.name ? binding.name : EMPTY_CHAR);
|
|
1178
826
|
}
|
|
827
|
+
return translatedBindings.join("\n");
|
|
1179
828
|
}
|
|
1180
|
-
function
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
}
|
|
829
|
+
async function translateAPI(filePath) {
|
|
830
|
+
const api = await vueDocgenApi.parse(filePath);
|
|
831
|
+
const props = api.props ? translateProps(api.props) : [];
|
|
832
|
+
const events = api.events ? translateEvents(api.events) : [];
|
|
833
|
+
const slots = api.slots ? translateSlots(api.slots) : [];
|
|
834
|
+
return {
|
|
835
|
+
props,
|
|
836
|
+
events,
|
|
837
|
+
slots
|
|
1190
838
|
};
|
|
1191
839
|
}
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
};
|
|
1209
|
-
const result = await vendor.execa("node", [scriptPath], {
|
|
1210
|
-
input: JSON.stringify(batch),
|
|
1211
|
-
all: true
|
|
840
|
+
|
|
841
|
+
const md = vendor.MarkdownIt({ breaks: true });
|
|
842
|
+
function generateTableHead(headers) {
|
|
843
|
+
return [
|
|
844
|
+
"<thead><tr>",
|
|
845
|
+
...headers.map((header) => `<th>${header}</th>`),
|
|
846
|
+
"</tr></thead>"
|
|
847
|
+
].join("");
|
|
848
|
+
}
|
|
849
|
+
function generateTableBody(content) {
|
|
850
|
+
const rows = content.map((row) => {
|
|
851
|
+
return [
|
|
852
|
+
"<tr>",
|
|
853
|
+
...row.map((value) => `<td>${md.render(value)}</td>`),
|
|
854
|
+
"</tr>"
|
|
855
|
+
].join("");
|
|
1212
856
|
});
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
857
|
+
return ["<tbody>", ...rows, "</tbody>"].join("");
|
|
858
|
+
}
|
|
859
|
+
function generateTable(caption, headers, content) {
|
|
860
|
+
return [
|
|
861
|
+
'<div class="docs-table"><table>',
|
|
862
|
+
`<caption>${caption}</caption>`,
|
|
863
|
+
generateTableHead(headers),
|
|
864
|
+
generateTableBody(content),
|
|
865
|
+
"</table></div>"
|
|
866
|
+
].join("");
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
function capitalize(text) {
|
|
870
|
+
return `${text.charAt(0).toUpperCase()}${text.slice(1)}`;
|
|
871
|
+
}
|
|
872
|
+
function parseAPIToArray(api) {
|
|
873
|
+
const content = [];
|
|
874
|
+
const headers = Object.keys(api[0]);
|
|
875
|
+
const capitalizedHeaders = headers.map(capitalize);
|
|
876
|
+
content.push(capitalizedHeaders);
|
|
877
|
+
for (const row of api) {
|
|
878
|
+
content.push(Object.values(row));
|
|
1216
879
|
}
|
|
880
|
+
return content;
|
|
1217
881
|
}
|
|
1218
|
-
|
|
1219
|
-
const
|
|
1220
|
-
|
|
1221
|
-
|
|
882
|
+
function parseAPI(filePath, api) {
|
|
883
|
+
const relative = createMarkdownRenderer.normalizePath(filePath);
|
|
884
|
+
const parsedPath = path.parse(relative);
|
|
885
|
+
const componentName = parsedPath.name;
|
|
886
|
+
let html = "";
|
|
887
|
+
if (api.props.length) {
|
|
888
|
+
const propsArray = parseAPIToArray(api.props);
|
|
889
|
+
html += generateTable("Props", propsArray[0], propsArray.slice(1));
|
|
1222
890
|
}
|
|
1223
|
-
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
const content = await renderTemplate(standaloneTemplate, {
|
|
1231
|
-
...templateData,
|
|
1232
|
-
content: task.content
|
|
1233
|
-
});
|
|
1234
|
-
await fs.writeFile(outputFile, content, "utf-8");
|
|
891
|
+
if (api.events.length) {
|
|
892
|
+
const eventsArray = parseAPIToArray(api.events);
|
|
893
|
+
html += generateTable("Events", eventsArray[0], eventsArray.slice(1));
|
|
894
|
+
}
|
|
895
|
+
if (api.slots.length) {
|
|
896
|
+
const slotsArray = parseAPIToArray(api.slots);
|
|
897
|
+
html += generateTable("Slots", slotsArray[0], slotsArray.slice(1));
|
|
1235
898
|
}
|
|
899
|
+
return {
|
|
900
|
+
id: `fs:${filePath.replace(/\\/g, "/")}`,
|
|
901
|
+
name: `vue:${componentName}`,
|
|
902
|
+
alias: [],
|
|
903
|
+
visible: false,
|
|
904
|
+
attributes: { sortorder: Infinity },
|
|
905
|
+
body: html,
|
|
906
|
+
outline: [],
|
|
907
|
+
format: "html",
|
|
908
|
+
tags: [],
|
|
909
|
+
template: "",
|
|
910
|
+
fileInfo: {
|
|
911
|
+
path: "",
|
|
912
|
+
name: "",
|
|
913
|
+
fullPath: "",
|
|
914
|
+
outputName: false
|
|
915
|
+
}
|
|
916
|
+
};
|
|
1236
917
|
}
|
|
1237
|
-
function
|
|
1238
|
-
|
|
918
|
+
async function vueFileReader(filePath) {
|
|
919
|
+
const translated = await translateAPI(filePath);
|
|
920
|
+
const doc = parseAPI(filePath, translated);
|
|
921
|
+
return [doc];
|
|
1239
922
|
}
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
return null;
|
|
1245
|
-
}
|
|
1246
|
-
const dst = createMarkdownRenderer.getOutputFilePath(outputFolder, fileInfo);
|
|
1247
|
-
const mkdir = fs.mkdir(path.dirname(dst), { recursive: true });
|
|
1248
|
-
const topnav = nav.topnav;
|
|
1249
|
-
const sidenav = findSidenav(doc, nav.sidenav);
|
|
1250
|
-
if (sidenav && isNavigationSection(sidenav)) {
|
|
1251
|
-
sortNavigationTree(sidenav);
|
|
923
|
+
|
|
924
|
+
async function globAll(pattern) {
|
|
925
|
+
if (!pattern) {
|
|
926
|
+
return /* @__PURE__ */ new Set();
|
|
1252
927
|
}
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
const renderTemplate = asyncRender.bind(njk);
|
|
1256
|
-
const template = findTemplate(doc.fileInfo, doc);
|
|
1257
|
-
const templateData = {
|
|
1258
|
-
...options.templateData,
|
|
1259
|
-
site: options.site,
|
|
1260
|
-
doc,
|
|
1261
|
-
topnav,
|
|
1262
|
-
rootUrl(doc2) {
|
|
1263
|
-
const { fileInfo: fileInfo2 } = doc2;
|
|
1264
|
-
const relative = path$1.relative(fileInfo2.path, ".");
|
|
1265
|
-
return relative !== "" ? relative : ".";
|
|
1266
|
-
},
|
|
1267
|
-
sidenav,
|
|
1268
|
-
vendors
|
|
1269
|
-
};
|
|
1270
|
-
const generatedExamples = [];
|
|
1271
|
-
const generatedStandalone = [];
|
|
1272
|
-
const markdownRenderer = createMarkdownRenderer.createMarkdownRenderer({
|
|
1273
|
-
docs,
|
|
1274
|
-
generateExample({ source, language, filename, tags }) {
|
|
1275
|
-
const example = generateExample({
|
|
1276
|
-
source,
|
|
1277
|
-
language,
|
|
1278
|
-
filename,
|
|
1279
|
-
parent: fileInfo.fullPath,
|
|
1280
|
-
setupPath: options.setupPath,
|
|
1281
|
-
exampleFolders: options.exampleFolders,
|
|
1282
|
-
tags
|
|
1283
|
-
});
|
|
1284
|
-
if (example.output) {
|
|
1285
|
-
const { dir, name } = path.parse(example.output);
|
|
1286
|
-
generatedExamples.push(example.task);
|
|
1287
|
-
generatedStandalone.push({
|
|
1288
|
-
outputFile: path.join(dir, `${name}.html`),
|
|
1289
|
-
content: example.markup
|
|
1290
|
-
});
|
|
1291
|
-
}
|
|
1292
|
-
return example;
|
|
1293
|
-
},
|
|
1294
|
-
addResource(dst2, src) {
|
|
1295
|
-
if (!fs$1.existsSync(src)) {
|
|
1296
|
-
throw new Error(`Failed to find image "${src}"`);
|
|
1297
|
-
}
|
|
1298
|
-
options.addResource(dst2, src);
|
|
1299
|
-
},
|
|
1300
|
-
handleSoftError(error) {
|
|
1301
|
-
throw error;
|
|
1302
|
-
}
|
|
1303
|
-
});
|
|
1304
|
-
njk.addFilter("marked", (content2) => {
|
|
1305
|
-
return markdownRenderer.render(doc, content2);
|
|
1306
|
-
});
|
|
1307
|
-
njk.addFilter("json", json);
|
|
1308
|
-
njk.addFilter("dump", dump);
|
|
1309
|
-
njk.addFilter("relative", relative);
|
|
1310
|
-
njk.addFilter("take", take);
|
|
1311
|
-
njk.addExtension("BlockContainer", {
|
|
1312
|
-
tags: ["container"],
|
|
1313
|
-
parse(parser, nodes) {
|
|
1314
|
-
const tok = parser.nextToken();
|
|
1315
|
-
const args = parser.parseSignature(null, true);
|
|
1316
|
-
parser.advanceAfterBlockEnd(tok.value);
|
|
1317
|
-
return new nodes.CallExtensionAsync(this, "run", args, []);
|
|
1318
|
-
},
|
|
1319
|
-
async run({ ctx }, container, callback) {
|
|
1320
|
-
const blocks = options.templateBlocks.get(container) ?? [];
|
|
1321
|
-
const promises = blocks.map(({ renderer }) => {
|
|
1322
|
-
if ("filename" in renderer) {
|
|
1323
|
-
const data = renderer.data;
|
|
1324
|
-
return renderTemplate(renderer.filename, {
|
|
1325
|
-
...ctx,
|
|
1326
|
-
...data
|
|
1327
|
-
});
|
|
1328
|
-
}
|
|
1329
|
-
if ("render" in renderer) {
|
|
1330
|
-
return Promise.resolve(renderer.render());
|
|
1331
|
-
}
|
|
1332
|
-
return Promise.resolve("");
|
|
1333
|
-
});
|
|
1334
|
-
const content2 = await Promise.all(promises);
|
|
1335
|
-
const markup = content2.join("");
|
|
1336
|
-
return callback(null, new nunjucks.runtime.SafeString(markup));
|
|
1337
|
-
}
|
|
1338
|
-
});
|
|
1339
|
-
await mkdir;
|
|
1340
|
-
let content;
|
|
1341
|
-
try {
|
|
1342
|
-
content = await renderTemplate(template, templateData);
|
|
1343
|
-
} catch (err) {
|
|
1344
|
-
const prefix = `Failed to render "${fileInfo.fullPath}"`;
|
|
1345
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
1346
|
-
throw new Error(`${prefix}: ${message}`, { cause: err });
|
|
928
|
+
if (!Array.isArray(pattern)) {
|
|
929
|
+
return globAll([pattern]);
|
|
1347
930
|
}
|
|
1348
|
-
const
|
|
1349
|
-
|
|
1350
|
-
|
|
931
|
+
const results = await Promise.all(pattern.map((it) => vendor.glob(it)));
|
|
932
|
+
return new Set(results.flat());
|
|
933
|
+
}
|
|
934
|
+
async function getDocumentsForSource(src) {
|
|
935
|
+
const { transform } = src;
|
|
936
|
+
const include = await globAll(src.include);
|
|
937
|
+
const exclude = await globAll(src.exclude);
|
|
938
|
+
const files = Array.from(difference(include, exclude));
|
|
939
|
+
const promises = files.map(async (it) => {
|
|
940
|
+
const docs2 = await src.fileReader(it, src.basePath);
|
|
941
|
+
if (transform) {
|
|
942
|
+
return docs2.map((it2) => transform(it2));
|
|
1351
943
|
} else {
|
|
1352
|
-
return
|
|
944
|
+
return docs2;
|
|
1353
945
|
}
|
|
1354
946
|
});
|
|
1355
|
-
const
|
|
1356
|
-
|
|
1357
|
-
await compileExamples({
|
|
1358
|
-
fileInfo,
|
|
1359
|
-
cacheFolder,
|
|
1360
|
-
outputFolder,
|
|
1361
|
-
tasks: generatedExamples,
|
|
1362
|
-
vendors
|
|
1363
|
-
});
|
|
1364
|
-
} catch (err) {
|
|
1365
|
-
const prefix = `Failed to compile examples from "${fileInfo.fullPath}"`;
|
|
1366
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
1367
|
-
throw new Error(`${prefix}: ${message}`, { cause: err });
|
|
1368
|
-
}
|
|
1369
|
-
try {
|
|
1370
|
-
await compileStandalones({
|
|
1371
|
-
fileInfo,
|
|
1372
|
-
cacheFolder,
|
|
1373
|
-
outputFolder,
|
|
1374
|
-
tasks: generatedStandalone,
|
|
1375
|
-
renderTemplate,
|
|
1376
|
-
templateData
|
|
1377
|
-
});
|
|
1378
|
-
} catch (err) {
|
|
1379
|
-
const prefix = `Failed to render standalone examples from "${fileInfo.fullPath}"`;
|
|
1380
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
1381
|
-
throw new Error(`${prefix}: ${message}`, { cause: err });
|
|
1382
|
-
}
|
|
1383
|
-
await writeFile;
|
|
1384
|
-
return dst;
|
|
947
|
+
const docs = await Promise.all(promises);
|
|
948
|
+
return docs.flat();
|
|
1385
949
|
}
|
|
1386
|
-
|
|
1387
|
-
const
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
hideCursor: true,
|
|
1392
|
-
clearOnComplete: true
|
|
1393
|
-
});
|
|
1394
|
-
function nunjucksProcessor(options) {
|
|
950
|
+
async function getAllDocuments(sourceFiles) {
|
|
951
|
+
const result = await Promise.all(sourceFiles.map(getDocumentsForSource));
|
|
952
|
+
return result.flat();
|
|
953
|
+
}
|
|
954
|
+
function fileReaderProcessor(sourceFiles) {
|
|
1395
955
|
return {
|
|
1396
|
-
stage: "
|
|
1397
|
-
name: "
|
|
956
|
+
stage: "generate-docs",
|
|
957
|
+
name: "file-reader-processor",
|
|
1398
958
|
async handler(context) {
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
sidenav: context.sidenav
|
|
1403
|
-
};
|
|
1404
|
-
return render(doc, context.docs, nav, context.vendors, {
|
|
1405
|
-
...options,
|
|
1406
|
-
templateBlocks: context.getAllTemplateBlocks(),
|
|
1407
|
-
templateData: context.getAllTemplateData(),
|
|
1408
|
-
addResource(dst, src) {
|
|
1409
|
-
context.addResource(dst, src);
|
|
1410
|
-
}
|
|
1411
|
-
});
|
|
1412
|
-
}
|
|
1413
|
-
const docs = context.docs.filter((it) => {
|
|
1414
|
-
return it.fileInfo.outputName;
|
|
1415
|
-
});
|
|
1416
|
-
createTemplateLoader(options.templateFolders);
|
|
1417
|
-
progressbar.start(docs.length, 0, {
|
|
1418
|
-
filename: docs.length > 0 ? docs[0].fileInfo.fullPath : ""
|
|
1419
|
-
});
|
|
1420
|
-
const generatedFiles = [];
|
|
1421
|
-
try {
|
|
1422
|
-
for (const doc of context.docs) {
|
|
1423
|
-
const filePath = await renderDocument(doc);
|
|
1424
|
-
if (filePath) {
|
|
1425
|
-
generatedFiles.push(filePath);
|
|
1426
|
-
}
|
|
1427
|
-
progressbar.increment(1, {
|
|
1428
|
-
filename: doc.fileInfo.fullPath
|
|
1429
|
-
});
|
|
1430
|
-
}
|
|
1431
|
-
} finally {
|
|
1432
|
-
progressbar.stop();
|
|
1433
|
-
}
|
|
1434
|
-
context.log(docs.length, "documents rendered");
|
|
1435
|
-
return generatedFiles;
|
|
959
|
+
const result = await getAllDocuments(sourceFiles);
|
|
960
|
+
context.addDocument(result);
|
|
961
|
+
context.log(result.length, "documents found");
|
|
1436
962
|
}
|
|
1437
963
|
};
|
|
1438
964
|
}
|
|
1439
965
|
|
|
1440
|
-
function
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
];
|
|
1446
|
-
});
|
|
1447
|
-
}
|
|
1448
|
-
function findExamples(doc) {
|
|
1449
|
-
if (doc.format !== "markdown") {
|
|
1450
|
-
return [];
|
|
966
|
+
function parseFile(filePath, basePath, content) {
|
|
967
|
+
const attributes = JSON.parse(content);
|
|
968
|
+
const { title, href } = attributes;
|
|
969
|
+
if (!title) {
|
|
970
|
+
throw new Error(`No title property set in "${filePath}"`);
|
|
1451
971
|
}
|
|
1452
|
-
const
|
|
1453
|
-
const
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
const hashContent = `${map?.[0]}:${map?.[1]}:${info}:${content}`;
|
|
1458
|
-
const fingerprint = createMarkdownRenderer.getFingerprint(hashContent);
|
|
1459
|
-
collected.push({
|
|
1460
|
-
selector: `#example-${fingerprint}`,
|
|
1461
|
-
language,
|
|
1462
|
-
tags
|
|
1463
|
-
});
|
|
1464
|
-
return "";
|
|
1465
|
-
};
|
|
1466
|
-
md.render(doc.body);
|
|
1467
|
-
return collected;
|
|
1468
|
-
}
|
|
1469
|
-
function manifestPageFromDocument(doc) {
|
|
1470
|
-
const { fileInfo } = doc;
|
|
972
|
+
const relative = basePath ? path.relative(basePath, createMarkdownRenderer.normalizePath(filePath)) : createMarkdownRenderer.normalizePath(filePath);
|
|
973
|
+
const parsed = path.parse(relative);
|
|
974
|
+
const filename = parsed.name.toLowerCase();
|
|
975
|
+
const name = parsed.name;
|
|
976
|
+
const urlpath = parsed.dir;
|
|
1471
977
|
return {
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
978
|
+
id: `nav:${filePath.replace(/\\/g, "/")}`,
|
|
979
|
+
name,
|
|
980
|
+
alias: [],
|
|
981
|
+
visible: attributes.href ? true : false,
|
|
982
|
+
attributes: {
|
|
983
|
+
title,
|
|
984
|
+
href,
|
|
985
|
+
sortorder: attributes.sortorder ?? Infinity
|
|
986
|
+
},
|
|
987
|
+
body: content,
|
|
988
|
+
outline: [],
|
|
989
|
+
format: "json",
|
|
990
|
+
tags: [],
|
|
991
|
+
template: "default",
|
|
992
|
+
fileInfo: {
|
|
993
|
+
path: ["", "."].includes(urlpath) ? "." : `./${createMarkdownRenderer.normalizePath(urlpath)}`,
|
|
994
|
+
name: filename,
|
|
995
|
+
fullPath: createMarkdownRenderer.normalizePath(filePath),
|
|
996
|
+
outputName: false
|
|
997
|
+
}
|
|
1476
998
|
};
|
|
1477
999
|
}
|
|
1000
|
+
async function navigationFileReader(filePath, basePath) {
|
|
1001
|
+
const content = await fs.readFile(filePath, "utf-8");
|
|
1002
|
+
const doc = parseFile(filePath, basePath, content);
|
|
1003
|
+
return [doc];
|
|
1004
|
+
}
|
|
1478
1005
|
|
|
1479
|
-
function
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1006
|
+
function resolveScssImport(filePath) {
|
|
1007
|
+
const { dir, base } = path$1.parse(filePath);
|
|
1008
|
+
const search = [`${base}.css`, `${base}.scss`, `_${base}.scss`, `${base}`];
|
|
1009
|
+
for (const variant of search) {
|
|
1010
|
+
try {
|
|
1011
|
+
const moduleName = path$1.join(dir, variant);
|
|
1012
|
+
const resolved = require.resolve(moduleName);
|
|
1013
|
+
return node_url.pathToFileURL(resolved);
|
|
1014
|
+
} catch (err) {
|
|
1015
|
+
if (err.code !== "MODULE_NOT_FOUND") {
|
|
1016
|
+
throw err;
|
|
1017
|
+
}
|
|
1018
|
+
}
|
|
1486
1019
|
}
|
|
1487
|
-
|
|
1020
|
+
throw new Error(`Failed to resolve "${filePath}"`);
|
|
1488
1021
|
}
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
}
|
|
1495
|
-
if (asset.expose === "named") {
|
|
1496
|
-
lines.push(`import * as lib from "${pkg}";`);
|
|
1497
|
-
} else {
|
|
1498
|
-
lines.push(`import lib from "${pkg}";`);
|
|
1499
|
-
}
|
|
1500
|
-
asset.subpaths.map((subpath, index) => {
|
|
1501
|
-
if (asset.expose === "named") {
|
|
1502
|
-
lines.push(`import * as lib$${index} from "${subpath}";`);
|
|
1503
|
-
} else {
|
|
1504
|
-
lines.push(`import lib$${index} from "${subpath}";`);
|
|
1022
|
+
const tildeImporter = {
|
|
1023
|
+
canonicalize(url) {
|
|
1024
|
+
const indexOfTilde = url.indexOf("~");
|
|
1025
|
+
if (indexOfTilde >= 0) {
|
|
1026
|
+
return resolveScssImport(url.slice(indexOfTilde + 1));
|
|
1505
1027
|
}
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1028
|
+
if (url.startsWith("file://")) {
|
|
1029
|
+
const path$1 = node_url.fileURLToPath(url);
|
|
1030
|
+
const relative = path.isAbsolute(path$1) ? path.relative(__dirname, path$1) : path$1;
|
|
1031
|
+
return resolveScssImport(relative.replace(/\\/g, "/"));
|
|
1032
|
+
}
|
|
1033
|
+
return null;
|
|
1034
|
+
},
|
|
1035
|
+
async load(url) {
|
|
1036
|
+
const filepath = node_url.fileURLToPath(url);
|
|
1037
|
+
const parsed = path.parse(filepath);
|
|
1038
|
+
const contents = await fs.readFile(filepath, "utf-8");
|
|
1039
|
+
return {
|
|
1040
|
+
contents,
|
|
1041
|
+
syntax: parsed.ext.slice(1) === "scss" ? "scss" : "css"
|
|
1042
|
+
};
|
|
1512
1043
|
}
|
|
1513
|
-
|
|
1514
|
-
|
|
1044
|
+
};
|
|
1045
|
+
|
|
1046
|
+
async function compileSassString(dst, style) {
|
|
1047
|
+
const result = await sass.compileStringAsync(style, {
|
|
1048
|
+
style: "expanded",
|
|
1049
|
+
importers: [tildeImporter]
|
|
1515
1050
|
});
|
|
1516
|
-
|
|
1517
|
-
|
|
1051
|
+
await fs.mkdir(path.dirname(dst), { recursive: true });
|
|
1052
|
+
await fs.writeFile(dst, result.css, "utf-8");
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
async function compileStyle(assetFolder, name, src) {
|
|
1056
|
+
try {
|
|
1057
|
+
const outfile = path$1.join("temp", `asset-${name}.css`);
|
|
1058
|
+
const source = await fs.readFile(src, "utf-8");
|
|
1059
|
+
await compileSassString(outfile, source);
|
|
1060
|
+
const content = await fs.readFile(outfile, "utf-8");
|
|
1061
|
+
const fingerprint = createMarkdownRenderer.getFingerprint(content);
|
|
1062
|
+
const integrity = getIntegrity(content);
|
|
1063
|
+
const filename = `${name}-${fingerprint}.css`;
|
|
1064
|
+
const dst = path$1.join(assetFolder, filename);
|
|
1065
|
+
await fs.rename(outfile, dst);
|
|
1066
|
+
const stat = await fs.stat(dst);
|
|
1067
|
+
return {
|
|
1068
|
+
name,
|
|
1069
|
+
filename,
|
|
1070
|
+
publicPath: `./assets/${filename}`,
|
|
1071
|
+
integrity,
|
|
1072
|
+
size: stat.size,
|
|
1073
|
+
type: "css"
|
|
1074
|
+
};
|
|
1075
|
+
} catch (err) {
|
|
1076
|
+
console.error(err);
|
|
1077
|
+
throw new Error(`Failed to compile style "${name}"`);
|
|
1518
1078
|
}
|
|
1519
|
-
return lines.join("\n");
|
|
1520
1079
|
}
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
const slug = slugify(name);
|
|
1524
|
-
const outfile = `temp/vendor-${slug}.out.js`;
|
|
1525
|
-
const tmpfile = `temp/vendor-${slug}.in.js`;
|
|
1526
|
-
const source = getAssetSource(vendor, customRequire.toString());
|
|
1527
|
-
const tsconfig = path.resolve(__dirname, "../tsconfig-examples.json");
|
|
1528
|
-
await fs.writeFile(tmpfile, source, "utf-8");
|
|
1529
|
-
await esbuild.build({
|
|
1530
|
-
entryPoints: [tmpfile],
|
|
1531
|
-
outfile,
|
|
1532
|
-
bundle: true,
|
|
1533
|
-
format: "iife",
|
|
1534
|
-
platform: "browser",
|
|
1535
|
-
tsconfig,
|
|
1536
|
-
define: {
|
|
1537
|
-
"process.env.NODE_ENV": JSON.stringify(
|
|
1538
|
-
process.env.NODE_ENV ?? "production"
|
|
1539
|
-
)
|
|
1540
|
-
},
|
|
1541
|
-
alias: vendor.alias ? { [`${vendor.package}`]: vendor.alias } : void 0,
|
|
1542
|
-
...options
|
|
1543
|
-
});
|
|
1544
|
-
const content = await fs.readFile(outfile, "utf-8");
|
|
1545
|
-
const fingerprint = createMarkdownRenderer.getFingerprint(content);
|
|
1546
|
-
const integrity = getIntegrity(content);
|
|
1547
|
-
const filename = `vendor-${slug}-${fingerprint}.js`;
|
|
1548
|
-
const dst = path.join(assetFolder, filename).replace(/\\/g, "/");
|
|
1549
|
-
await fs.rename(outfile, dst);
|
|
1550
|
-
const stat = await fs.stat(dst);
|
|
1080
|
+
|
|
1081
|
+
function cssAssetProcessor(assetFolder, assets) {
|
|
1551
1082
|
return {
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1083
|
+
name: "css-asset-processor",
|
|
1084
|
+
after: "assets",
|
|
1085
|
+
async handler(context) {
|
|
1086
|
+
const assetInfo = context.getTemplateData("assets") ?? {};
|
|
1087
|
+
const head = context.getTemplateData("injectHead") ?? [];
|
|
1088
|
+
const body = context.getTemplateData("injectBody") ?? [];
|
|
1089
|
+
for (const asset of assets) {
|
|
1090
|
+
const info = await compileStyle(
|
|
1091
|
+
assetFolder,
|
|
1092
|
+
asset.name,
|
|
1093
|
+
asset.src
|
|
1094
|
+
);
|
|
1095
|
+
const attrs = serializeAttrs(asset.options.attributes);
|
|
1096
|
+
const inject = { ...info, attrs: Array.from(attrs).join(" ") };
|
|
1097
|
+
assetInfo[asset.name] = info;
|
|
1098
|
+
switch (asset.options.appendTo) {
|
|
1099
|
+
case "none":
|
|
1100
|
+
break;
|
|
1101
|
+
case "head":
|
|
1102
|
+
head.push(inject);
|
|
1103
|
+
break;
|
|
1104
|
+
case "body":
|
|
1105
|
+
body.push(inject);
|
|
1106
|
+
break;
|
|
1107
|
+
}
|
|
1108
|
+
context.setTemplateData("injectHead", head);
|
|
1109
|
+
context.setTemplateData("injectBody", body);
|
|
1110
|
+
context.log(info.filename, formatSize(info.size));
|
|
1111
|
+
}
|
|
1112
|
+
context.setTemplateData("assets", assetInfo);
|
|
1113
|
+
}
|
|
1557
1114
|
};
|
|
1558
1115
|
}
|
|
1559
1116
|
|
|
1560
|
-
function
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1117
|
+
async function compileScript(assetFolder, name, src, options) {
|
|
1118
|
+
const iconLib = process.env.DOCS_ICON_LIB ?? "@fkui/icon-lib-default";
|
|
1119
|
+
try {
|
|
1120
|
+
const entryPoints = [src instanceof URL ? node_url.fileURLToPath(src) : src];
|
|
1121
|
+
const outfile = path.join("temp", `asset-${name}.js`);
|
|
1122
|
+
await esbuild.build({
|
|
1123
|
+
entryPoints,
|
|
1124
|
+
outfile,
|
|
1125
|
+
bundle: true,
|
|
1126
|
+
format: "iife",
|
|
1127
|
+
platform: "browser",
|
|
1128
|
+
external: ["vue", "@fkui/vue"],
|
|
1129
|
+
tsconfig: path.join(__dirname, "../tsconfig-examples.json"),
|
|
1130
|
+
define: {
|
|
1131
|
+
"process.env.DOCS_ICON_LIB": JSON.stringify(iconLib)
|
|
1132
|
+
},
|
|
1133
|
+
...options
|
|
1134
|
+
});
|
|
1135
|
+
const content = await fs.readFile(outfile, "utf-8");
|
|
1136
|
+
const fingerprint = createMarkdownRenderer.getFingerprint(content);
|
|
1137
|
+
const integrity = getIntegrity(content);
|
|
1138
|
+
const filename = `${name}-${fingerprint}.js`;
|
|
1139
|
+
const dst = path.join(assetFolder, filename);
|
|
1140
|
+
await fs.mkdir(path.dirname(dst), { recursive: true });
|
|
1141
|
+
await fs.rename(outfile, dst);
|
|
1142
|
+
const stat = await fs.stat(dst);
|
|
1569
1143
|
return {
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1144
|
+
name,
|
|
1145
|
+
filename,
|
|
1146
|
+
publicPath: `./assets/${filename}`,
|
|
1147
|
+
integrity,
|
|
1148
|
+
size: stat.size,
|
|
1149
|
+
type: "js"
|
|
1575
1150
|
};
|
|
1151
|
+
} catch (err) {
|
|
1152
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
1153
|
+
throw new Error(`Failed to compile script "${name}": ${reason}`);
|
|
1576
1154
|
}
|
|
1577
1155
|
}
|
|
1578
1156
|
|
|
1579
|
-
function
|
|
1580
|
-
return typeof vendor === "string" ? vendor : vendor.package;
|
|
1581
|
-
}
|
|
1582
|
-
function generateVendorAssets(assetFolder, assets) {
|
|
1583
|
-
const packages = assets.map(getPackageName);
|
|
1584
|
-
const normalized = assets.map(normalizeVendorDefinition);
|
|
1585
|
-
const promises = normalized.map((it) => {
|
|
1586
|
-
const external = packages.filter((pkg) => pkg !== it.package);
|
|
1587
|
-
return compileVendor(assetFolder, it, {
|
|
1588
|
-
external
|
|
1589
|
-
});
|
|
1590
|
-
});
|
|
1591
|
-
return Promise.all(promises);
|
|
1592
|
-
}
|
|
1593
|
-
function vendorProcessor(assetFolder, vendor) {
|
|
1157
|
+
function jsAssetProcessor(assetFolder, assets) {
|
|
1594
1158
|
return {
|
|
1595
|
-
|
|
1596
|
-
|
|
1159
|
+
name: "js-asset-processor",
|
|
1160
|
+
after: "assets",
|
|
1597
1161
|
async handler(context) {
|
|
1598
|
-
const
|
|
1599
|
-
context.
|
|
1162
|
+
const assetInfo = context.getTemplateData("assets") ?? {};
|
|
1163
|
+
const head = context.getTemplateData("injectHead") ?? [];
|
|
1164
|
+
const body = context.getTemplateData("injectBody") ?? [];
|
|
1600
1165
|
for (const asset of assets) {
|
|
1601
|
-
const
|
|
1602
|
-
|
|
1166
|
+
const info = await compileScript(
|
|
1167
|
+
assetFolder,
|
|
1168
|
+
asset.name,
|
|
1169
|
+
asset.src
|
|
1170
|
+
);
|
|
1171
|
+
const attrs = serializeAttrs(asset.options.attributes);
|
|
1172
|
+
const inject = { ...info, attrs: Array.from(attrs).join(" ") };
|
|
1173
|
+
assetInfo[asset.name] = info;
|
|
1174
|
+
switch (asset.options.appendTo) {
|
|
1175
|
+
case "none":
|
|
1176
|
+
break;
|
|
1177
|
+
case "head":
|
|
1178
|
+
head.push(inject);
|
|
1179
|
+
break;
|
|
1180
|
+
case "body":
|
|
1181
|
+
body.push(inject);
|
|
1182
|
+
break;
|
|
1183
|
+
}
|
|
1184
|
+
context.setTemplateData("injectHead", head);
|
|
1185
|
+
context.setTemplateData("injectBody", body);
|
|
1186
|
+
context.log(info.filename, formatSize(info.size));
|
|
1603
1187
|
}
|
|
1604
1188
|
}
|
|
1605
1189
|
};
|
|
1606
1190
|
}
|
|
1607
1191
|
|
|
1608
|
-
function
|
|
1609
|
-
const { enabled } = options;
|
|
1192
|
+
function staticResourcesProcessor(assetFolder, resources) {
|
|
1610
1193
|
return {
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1194
|
+
name: "static-resources-processor",
|
|
1195
|
+
after: "render",
|
|
1196
|
+
async handler(context) {
|
|
1197
|
+
for (const resource of [...resources, ...context.resources]) {
|
|
1198
|
+
const src = resource.from;
|
|
1199
|
+
const dst = path$1.join(assetFolder, resource.to);
|
|
1200
|
+
await fs.cp(src, dst, {
|
|
1201
|
+
recursive: true
|
|
1202
|
+
});
|
|
1203
|
+
context.log(src, "->", dst);
|
|
1204
|
+
}
|
|
1618
1205
|
}
|
|
1619
1206
|
};
|
|
1620
1207
|
}
|
|
1621
1208
|
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
return
|
|
1626
|
-
process.stdin.once("data", (data) => {
|
|
1627
|
-
process.stdin.setRawMode(false);
|
|
1628
|
-
process.stdin.resume();
|
|
1629
|
-
resolve(data.toString("utf-8"));
|
|
1630
|
-
});
|
|
1631
|
-
});
|
|
1632
|
-
}
|
|
1633
|
-
|
|
1634
|
-
function printMenu(addr) {
|
|
1635
|
-
console.log();
|
|
1636
|
-
console.group(
|
|
1637
|
-
`Starting development server at http://localhost:${addr.port}`
|
|
1638
|
-
);
|
|
1639
|
-
console.log();
|
|
1640
|
-
console.log("[q] quit");
|
|
1641
|
-
console.log();
|
|
1642
|
-
console.groupEnd();
|
|
1209
|
+
function processorRuntimeName(processor, runtime) {
|
|
1210
|
+
const { name } = processor;
|
|
1211
|
+
const base = name.replace(/-processor/, "");
|
|
1212
|
+
return `processors/${runtime.name ?? base}`;
|
|
1643
1213
|
}
|
|
1644
1214
|
|
|
1645
|
-
function
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
let inflight = false;
|
|
1650
|
-
let queue = [];
|
|
1651
|
-
async function rebuild(filePath) {
|
|
1652
|
-
queue.push(filePath);
|
|
1653
|
-
if (inflight) {
|
|
1654
|
-
return;
|
|
1655
|
-
}
|
|
1656
|
-
inflight = true;
|
|
1657
|
-
try {
|
|
1658
|
-
while (queue.length > 0) {
|
|
1659
|
-
const modifiedFiles = queue;
|
|
1660
|
-
queue = [];
|
|
1661
|
-
const generatedFiles = await callback(modifiedFiles);
|
|
1662
|
-
livereload(generatedFiles);
|
|
1663
|
-
await sleep(200);
|
|
1664
|
-
}
|
|
1665
|
-
} finally {
|
|
1666
|
-
inflight = false;
|
|
1215
|
+
function compileProcessorRuntime(generator, distDir, processors) {
|
|
1216
|
+
for (const processor of processors) {
|
|
1217
|
+
if (processor.enabled === false) {
|
|
1218
|
+
continue;
|
|
1667
1219
|
}
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
return path$1.relative(options.outputFolder, it);
|
|
1682
|
-
});
|
|
1683
|
-
livereload.changed({ body: { files } });
|
|
1684
|
-
});
|
|
1685
|
-
watcher.on("change", async (filePath) => {
|
|
1686
|
-
rebuild(filePath);
|
|
1687
|
-
});
|
|
1688
|
-
for (; ; ) {
|
|
1689
|
-
const key = await keypress();
|
|
1690
|
-
switch (key) {
|
|
1691
|
-
case "":
|
|
1692
|
-
/* ctrl-c */
|
|
1693
|
-
case "q":
|
|
1694
|
-
console.log("Shutting down gracefully");
|
|
1695
|
-
server.close();
|
|
1696
|
-
watcher.close();
|
|
1697
|
-
livereload.close();
|
|
1698
|
-
process.stdin.unref();
|
|
1699
|
-
return;
|
|
1220
|
+
const { runtime } = processor;
|
|
1221
|
+
for (const entry of runtime ?? []) {
|
|
1222
|
+
const assetName = [
|
|
1223
|
+
"processors",
|
|
1224
|
+
processor.name.replace(/-processor/, ""),
|
|
1225
|
+
entry.name ?? path.parse(entry.src).name
|
|
1226
|
+
].join("/");
|
|
1227
|
+
const name = processorRuntimeName(processor, entry);
|
|
1228
|
+
const bundled = new URL(`${name}.js`, distDir);
|
|
1229
|
+
const scriptPath = fs$1.existsSync(bundled) ? bundled : entry.src;
|
|
1230
|
+
generator.compileScript(assetName, scriptPath, {
|
|
1231
|
+
appendTo: "body"
|
|
1232
|
+
});
|
|
1700
1233
|
}
|
|
1701
1234
|
}
|
|
1702
1235
|
}
|
|
1703
1236
|
|
|
1704
|
-
function
|
|
1705
|
-
return
|
|
1237
|
+
function isNavigationSection(node) {
|
|
1238
|
+
return "key" in node;
|
|
1706
1239
|
}
|
|
1707
|
-
function
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1240
|
+
function pathFromDoc({ fileInfo }) {
|
|
1241
|
+
if (fileInfo.name === "index") {
|
|
1242
|
+
return [fileInfo.path.replace(/\\/g, "/"), true];
|
|
1243
|
+
} else {
|
|
1244
|
+
return [
|
|
1245
|
+
`./${path.join(fileInfo.path, fileInfo.name).replace(/\\/g, "/")}`,
|
|
1246
|
+
false
|
|
1247
|
+
];
|
|
1248
|
+
}
|
|
1249
|
+
}
|
|
1250
|
+
function getParentKey(name) {
|
|
1251
|
+
return name.split("/").slice(0, -1).join("/");
|
|
1252
|
+
}
|
|
1253
|
+
function generateNavtree(docs) {
|
|
1254
|
+
const section = {};
|
|
1255
|
+
function createSection(key, title, sortorder) {
|
|
1256
|
+
const existing = section[key];
|
|
1257
|
+
if (existing) {
|
|
1258
|
+
existing.title = title;
|
|
1259
|
+
existing.sortorder = sortorder;
|
|
1260
|
+
} else {
|
|
1261
|
+
const node = {
|
|
1262
|
+
key,
|
|
1263
|
+
title,
|
|
1264
|
+
path: "",
|
|
1265
|
+
sortorder,
|
|
1266
|
+
children: []
|
|
1267
|
+
};
|
|
1268
|
+
section[key] = node;
|
|
1269
|
+
if (key !== ".") {
|
|
1270
|
+
const parent = attach(key);
|
|
1271
|
+
parent.children.push(node);
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
function attach(key) {
|
|
1276
|
+
const parentKey = getParentKey(key);
|
|
1277
|
+
let parent = section[parentKey];
|
|
1278
|
+
if (parent) {
|
|
1279
|
+
return parent;
|
|
1280
|
+
}
|
|
1281
|
+
parent = {
|
|
1282
|
+
key: parentKey,
|
|
1283
|
+
title: parentKey.split("/").at(-1) ?? "(missing title)",
|
|
1284
|
+
path: "",
|
|
1285
|
+
sortorder: Infinity,
|
|
1286
|
+
children: []
|
|
1287
|
+
};
|
|
1288
|
+
section[parentKey] = parent;
|
|
1289
|
+
let anchestor = parentKey;
|
|
1290
|
+
let current = parent;
|
|
1291
|
+
while (anchestor !== ".") {
|
|
1292
|
+
anchestor = getParentKey(anchestor);
|
|
1293
|
+
if (section[anchestor]) {
|
|
1294
|
+
section[anchestor].children.push(current);
|
|
1295
|
+
break;
|
|
1296
|
+
}
|
|
1297
|
+
const node = {
|
|
1298
|
+
key: anchestor,
|
|
1299
|
+
title: "",
|
|
1300
|
+
path: "",
|
|
1301
|
+
sortorder: Infinity,
|
|
1302
|
+
children: [current]
|
|
1303
|
+
};
|
|
1304
|
+
section[anchestor] = node;
|
|
1305
|
+
current = node;
|
|
1306
|
+
}
|
|
1307
|
+
return parent;
|
|
1308
|
+
}
|
|
1309
|
+
for (const doc of docs) {
|
|
1310
|
+
const [name, isSection] = pathFromDoc(doc);
|
|
1311
|
+
const title = doc.attributes.title ?? doc.fileInfo.name;
|
|
1312
|
+
const sortorder = doc.attributes.sortorder;
|
|
1313
|
+
if (doc.attributes.href) {
|
|
1314
|
+
const parent2 = attach(name);
|
|
1315
|
+
const leafNode = {
|
|
1316
|
+
id: doc.id,
|
|
1317
|
+
title,
|
|
1318
|
+
path: doc.attributes.href,
|
|
1319
|
+
sortorder,
|
|
1320
|
+
external: true
|
|
1321
|
+
};
|
|
1322
|
+
parent2.children.push(leafNode);
|
|
1713
1323
|
continue;
|
|
1714
1324
|
}
|
|
1715
|
-
if (
|
|
1716
|
-
|
|
1325
|
+
if (!doc.fileInfo.outputName) {
|
|
1326
|
+
if (isSection) {
|
|
1327
|
+
createSection(name, title, sortorder);
|
|
1328
|
+
}
|
|
1329
|
+
continue;
|
|
1717
1330
|
}
|
|
1718
|
-
if (
|
|
1719
|
-
|
|
1331
|
+
if (!doc.visible) {
|
|
1332
|
+
if (isSection) {
|
|
1333
|
+
createSection(name, title, sortorder);
|
|
1334
|
+
}
|
|
1335
|
+
continue;
|
|
1720
1336
|
}
|
|
1721
|
-
if (
|
|
1722
|
-
|
|
1337
|
+
if (name === ".") {
|
|
1338
|
+
createSection(name, title, sortorder);
|
|
1339
|
+
continue;
|
|
1340
|
+
}
|
|
1341
|
+
const parent = attach(name);
|
|
1342
|
+
if (isSection) {
|
|
1343
|
+
const leafNode = {
|
|
1344
|
+
id: doc.id,
|
|
1345
|
+
title,
|
|
1346
|
+
path: `${name}/`,
|
|
1347
|
+
sortorder,
|
|
1348
|
+
external: false
|
|
1349
|
+
};
|
|
1350
|
+
const existing = section[name];
|
|
1351
|
+
if (existing) {
|
|
1352
|
+
existing.title = title;
|
|
1353
|
+
existing.path = leafNode.path;
|
|
1354
|
+
existing.sortorder = sortorder;
|
|
1355
|
+
existing.children.unshift(leafNode);
|
|
1356
|
+
} else {
|
|
1357
|
+
const sectionNode = {
|
|
1358
|
+
key: name,
|
|
1359
|
+
title,
|
|
1360
|
+
path: leafNode.path,
|
|
1361
|
+
sortorder,
|
|
1362
|
+
children: [leafNode]
|
|
1363
|
+
};
|
|
1364
|
+
section[name] = sectionNode;
|
|
1365
|
+
parent.children.push(sectionNode);
|
|
1366
|
+
}
|
|
1367
|
+
} else {
|
|
1368
|
+
const leafNode = {
|
|
1369
|
+
id: doc.id,
|
|
1370
|
+
title,
|
|
1371
|
+
path: `${doc.fileInfo.path}/${doc.fileInfo.outputName}`,
|
|
1372
|
+
sortorder,
|
|
1373
|
+
external: false
|
|
1374
|
+
};
|
|
1375
|
+
parent.children.push(leafNode);
|
|
1723
1376
|
}
|
|
1724
1377
|
}
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1378
|
+
const root = section["."];
|
|
1379
|
+
if (root) {
|
|
1380
|
+
return root;
|
|
1381
|
+
} else {
|
|
1382
|
+
return {
|
|
1383
|
+
key: ".",
|
|
1384
|
+
title: "",
|
|
1385
|
+
path: "",
|
|
1386
|
+
sortorder: Infinity,
|
|
1387
|
+
children: []
|
|
1388
|
+
};
|
|
1730
1389
|
}
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1390
|
+
}
|
|
1391
|
+
|
|
1392
|
+
function navigationProcessor() {
|
|
1393
|
+
return {
|
|
1394
|
+
stage: "generate-nav",
|
|
1395
|
+
name: "navigation-processor",
|
|
1396
|
+
handler(context) {
|
|
1397
|
+
const navtree = generateNavtree(context.docs);
|
|
1398
|
+
context.setTopNavigation(navtree);
|
|
1399
|
+
context.setSideNavigation(navtree);
|
|
1400
|
+
}
|
|
1401
|
+
};
|
|
1402
|
+
}
|
|
1403
|
+
|
|
1404
|
+
function sortNavigationTree(tree) {
|
|
1405
|
+
tree.children.sort((a, b) => {
|
|
1406
|
+
if (a.sortorder < b.sortorder) {
|
|
1407
|
+
return -1;
|
|
1408
|
+
} else if (a.sortorder > b.sortorder) {
|
|
1409
|
+
return 1;
|
|
1410
|
+
}
|
|
1411
|
+
const titleA = a.title.toUpperCase();
|
|
1412
|
+
const titleB = b.title.toUpperCase();
|
|
1413
|
+
if (titleA < titleB) {
|
|
1414
|
+
return -1;
|
|
1415
|
+
}
|
|
1416
|
+
if (titleA > titleB) {
|
|
1417
|
+
return 1;
|
|
1418
|
+
}
|
|
1419
|
+
return 0;
|
|
1420
|
+
});
|
|
1421
|
+
for (const child of tree.children) {
|
|
1422
|
+
if (isNavigationSection(child)) {
|
|
1423
|
+
sortNavigationTree(child);
|
|
1738
1424
|
}
|
|
1425
|
+
}
|
|
1426
|
+
}
|
|
1427
|
+
|
|
1428
|
+
class TemplateLoader {
|
|
1429
|
+
async = true;
|
|
1430
|
+
folders;
|
|
1431
|
+
templateCache;
|
|
1432
|
+
constructor(folders = []) {
|
|
1433
|
+
this.folders = [...folders, path.join(__dirname, "../templates")];
|
|
1434
|
+
this.templateCache = /* @__PURE__ */ new Map();
|
|
1435
|
+
}
|
|
1436
|
+
async getSource(name, callback) {
|
|
1739
1437
|
try {
|
|
1740
|
-
const
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
}
|
|
1746
|
-
}
|
|
1438
|
+
const { content, filePath } = await this.resolveTemplate(name);
|
|
1439
|
+
callback(null, {
|
|
1440
|
+
src: content,
|
|
1441
|
+
path: filePath,
|
|
1442
|
+
noCache: false
|
|
1747
1443
|
});
|
|
1748
|
-
if (result) {
|
|
1749
|
-
generatedFiles = [...generatedFiles, ...result];
|
|
1750
|
-
}
|
|
1751
1444
|
} catch (err) {
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1445
|
+
if (err instanceof Error) {
|
|
1446
|
+
callback(err, null);
|
|
1447
|
+
} else {
|
|
1448
|
+
callback(new Error(String(err)), null);
|
|
1449
|
+
}
|
|
1755
1450
|
}
|
|
1756
1451
|
}
|
|
1757
|
-
|
|
1758
|
-
}
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
1769
|
-
|
|
1770
|
-
|
|
1771
|
-
|
|
1772
|
-
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
|
|
1788
|
-
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1452
|
+
async resolveTemplate(name) {
|
|
1453
|
+
const { templateCache, folders } = this;
|
|
1454
|
+
const cached = templateCache.get(name);
|
|
1455
|
+
if (cached) {
|
|
1456
|
+
return cached;
|
|
1457
|
+
}
|
|
1458
|
+
const searchPaths = folders.map((it) => path.join(it, name));
|
|
1459
|
+
const filePath = searchPaths.find((it) => fs$1.existsSync(it));
|
|
1460
|
+
if (!filePath) {
|
|
1461
|
+
const searched = folders.map((it) => ` - "${it}"`).join("\n");
|
|
1462
|
+
const message = `Failed to resolve template "${name}", searched in:
|
|
1463
|
+
|
|
1464
|
+
${searched}
|
|
1465
|
+
|
|
1466
|
+
Make sure the name is correct and the template file exists in one of the listed directories.`;
|
|
1467
|
+
throw new Error(message);
|
|
1468
|
+
}
|
|
1469
|
+
const content = await fs.readFile(filePath, "utf-8");
|
|
1470
|
+
const resolved = { content, filePath };
|
|
1471
|
+
templateCache.set(name, resolved);
|
|
1472
|
+
return resolved;
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
|
|
1476
|
+
function dump(value) {
|
|
1477
|
+
return `<pre>${JSON.stringify(value, null, 2)}</pre>`;
|
|
1478
|
+
}
|
|
1479
|
+
|
|
1480
|
+
function json(value) {
|
|
1481
|
+
return JSON.stringify(value, null, 2);
|
|
1482
|
+
}
|
|
1483
|
+
|
|
1484
|
+
function isExternalUrl(url) {
|
|
1485
|
+
return url.startsWith("http://") || url.startsWith("https://") || url.startsWith("//");
|
|
1486
|
+
}
|
|
1487
|
+
function isAbsoluteUrl(url) {
|
|
1488
|
+
return url.startsWith("/");
|
|
1489
|
+
}
|
|
1490
|
+
function relative(url, { fileInfo }) {
|
|
1491
|
+
if (isExternalUrl(url)) {
|
|
1492
|
+
return url;
|
|
1493
|
+
}
|
|
1494
|
+
if (isAbsoluteUrl(url)) {
|
|
1495
|
+
url = `.${url}`;
|
|
1496
|
+
}
|
|
1497
|
+
url = createMarkdownRenderer.normalizePath(url);
|
|
1498
|
+
const outputPath = createMarkdownRenderer.normalizePath(fileInfo.path);
|
|
1499
|
+
if (outputPath === url || `${outputPath}/` === url) {
|
|
1500
|
+
return "./";
|
|
1501
|
+
}
|
|
1502
|
+
const relative2 = path$1.relative(outputPath, url);
|
|
1503
|
+
const prefix = relative2.startsWith(".") ? "" : "./";
|
|
1504
|
+
const suffix = url.endsWith("/") ? "/" : "";
|
|
1505
|
+
return [prefix, relative2, suffix].join("");
|
|
1506
|
+
}
|
|
1507
|
+
|
|
1508
|
+
function take(haystack, key, value) {
|
|
1509
|
+
return haystack.filter((it) => it[key] === value);
|
|
1510
|
+
}
|
|
1511
|
+
|
|
1512
|
+
class MissingTemplateError extends Error {
|
|
1513
|
+
searchDir;
|
|
1514
|
+
constructor(fileInfo, template, format, searchDir) {
|
|
1515
|
+
const message = `Failed to find template "${template}" (${format} format) when rendering "${fileInfo.fullPath}"`;
|
|
1516
|
+
super(message);
|
|
1517
|
+
this.name = "MissingTemplateError";
|
|
1518
|
+
this.searchDir = searchDir;
|
|
1519
|
+
}
|
|
1520
|
+
prettyError() {
|
|
1521
|
+
return [
|
|
1522
|
+
this.message,
|
|
1523
|
+
"",
|
|
1524
|
+
"Searched the following directories:",
|
|
1525
|
+
...this.searchDir.map((it) => ` - ${it}`)
|
|
1526
|
+
].join("\n");
|
|
1527
|
+
}
|
|
1528
|
+
}
|
|
1529
|
+
const templateDirectory = path.join(__dirname, "../templates");
|
|
1530
|
+
const cache$1 = /* @__PURE__ */ new Map();
|
|
1531
|
+
function cacheKey(layout, extension) {
|
|
1532
|
+
return [layout, extension].join("|");
|
|
1533
|
+
}
|
|
1534
|
+
function findTemplate(from, src, format) {
|
|
1535
|
+
let layout;
|
|
1536
|
+
if (typeof src === "string") {
|
|
1537
|
+
layout = src;
|
|
1538
|
+
format ??= "html";
|
|
1539
|
+
} else {
|
|
1540
|
+
layout = src.template;
|
|
1541
|
+
format = src.format !== "json" ? "html" : "json";
|
|
1542
|
+
}
|
|
1543
|
+
const key = cacheKey(layout, format);
|
|
1544
|
+
const cached = cache$1.get(key);
|
|
1545
|
+
if (cached) {
|
|
1546
|
+
return cached;
|
|
1547
|
+
}
|
|
1548
|
+
const template = `${layout}.template.${format}`;
|
|
1549
|
+
const templateFile = path.join(templateDirectory, template);
|
|
1550
|
+
if (!fs$1.existsSync(templateFile)) {
|
|
1551
|
+
throw new MissingTemplateError(from, template, format, [
|
|
1552
|
+
templateDirectory
|
|
1553
|
+
]);
|
|
1554
|
+
}
|
|
1555
|
+
cache$1.set(key, template);
|
|
1556
|
+
return template;
|
|
1557
|
+
}
|
|
1558
|
+
|
|
1559
|
+
const scriptPath = path.join(__dirname, "compile-example.js");
|
|
1560
|
+
let loader = null;
|
|
1561
|
+
function haveOutputFile(fileInfo) {
|
|
1562
|
+
return fileInfo.outputName !== false;
|
|
1563
|
+
}
|
|
1564
|
+
function fillActiveNavigation(doc, node) {
|
|
1565
|
+
if (isNavigationSection(node)) {
|
|
1566
|
+
const children = node.children.map(
|
|
1567
|
+
(it) => fillActiveNavigation(doc, it)
|
|
1568
|
+
);
|
|
1569
|
+
const active = children.some((it) => it.active);
|
|
1570
|
+
return {
|
|
1571
|
+
...node,
|
|
1572
|
+
active,
|
|
1573
|
+
children
|
|
1574
|
+
};
|
|
1575
|
+
} else {
|
|
1576
|
+
const active = doc.id === node.id;
|
|
1577
|
+
return {
|
|
1578
|
+
...node,
|
|
1579
|
+
active
|
|
1580
|
+
};
|
|
1581
|
+
}
|
|
1582
|
+
}
|
|
1583
|
+
function findSidenav(doc, tree) {
|
|
1584
|
+
const { path: path2, name } = doc.fileInfo;
|
|
1585
|
+
const category = path2 === "." ? name : path2.split("/")[1];
|
|
1586
|
+
const sidenav = tree.children.filter(isNavigationSection).find((it) => it.key === `./${category}`);
|
|
1587
|
+
if (sidenav) {
|
|
1588
|
+
return fillActiveNavigation(doc, sidenav);
|
|
1589
|
+
}
|
|
1590
|
+
}
|
|
1591
|
+
function cache(cacheFolder, outputFolder) {
|
|
1592
|
+
return (it) => {
|
|
1593
|
+
const cacheFile = path.join(cacheFolder, it.outputFile);
|
|
1594
|
+
const outputFile = path.join(outputFolder, it.outputFile);
|
|
1595
|
+
if (fs$1.existsSync(cacheFile)) {
|
|
1596
|
+
fs$1.copyFileSync(cacheFile, outputFile);
|
|
1597
|
+
return false;
|
|
1598
|
+
} else {
|
|
1599
|
+
return true;
|
|
1600
|
+
}
|
|
1601
|
+
};
|
|
1602
|
+
}
|
|
1603
|
+
async function compileExamples(options) {
|
|
1604
|
+
const { fileInfo, tasks, vendors } = options;
|
|
1605
|
+
if (tasks.length === 0) {
|
|
1606
|
+
return;
|
|
1607
|
+
}
|
|
1608
|
+
const cacheFolder = path.posix.join(options.cacheFolder, fileInfo.path);
|
|
1609
|
+
const outputFolder = path.posix.join(options.outputFolder, fileInfo.path);
|
|
1610
|
+
const cacheMiss = cache(cacheFolder, outputFolder);
|
|
1611
|
+
const dirtyTasks = tasks.filter(cacheMiss);
|
|
1612
|
+
if (dirtyTasks.length === 0) {
|
|
1613
|
+
return;
|
|
1614
|
+
}
|
|
1615
|
+
const batch = {
|
|
1616
|
+
outputFolder,
|
|
1617
|
+
external: vendors.map((it) => it.package),
|
|
1618
|
+
tasks: dirtyTasks
|
|
1619
|
+
};
|
|
1620
|
+
const result = await vendor.execa("node", [scriptPath], {
|
|
1621
|
+
input: JSON.stringify(batch),
|
|
1622
|
+
all: true
|
|
1623
|
+
});
|
|
1624
|
+
const hasOutput = result.all ? result.all.length > 0 : false;
|
|
1625
|
+
if (hasOutput) {
|
|
1626
|
+
console.log(result.all);
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
1629
|
+
async function compileStandalones(options) {
|
|
1630
|
+
const { fileInfo, tasks, renderTemplate, templateData } = options;
|
|
1631
|
+
if (tasks.length === 0) {
|
|
1632
|
+
return;
|
|
1633
|
+
}
|
|
1634
|
+
const cacheFolder = path.posix.join(options.cacheFolder, fileInfo.path);
|
|
1635
|
+
const outputFolder = path.posix.join(options.outputFolder, fileInfo.path);
|
|
1636
|
+
const cacheMiss = cache(cacheFolder, outputFolder);
|
|
1637
|
+
const dirtyTasks = tasks.filter(cacheMiss);
|
|
1638
|
+
const standaloneTemplate = findTemplate(fileInfo, "example");
|
|
1639
|
+
for (const task of dirtyTasks) {
|
|
1640
|
+
const outputFile = path.join(outputFolder, task.outputFile);
|
|
1641
|
+
const content = await renderTemplate(standaloneTemplate, {
|
|
1642
|
+
...templateData,
|
|
1643
|
+
content: task.content
|
|
1644
|
+
});
|
|
1645
|
+
await fs.writeFile(outputFile, content, "utf-8");
|
|
1646
|
+
}
|
|
1647
|
+
}
|
|
1648
|
+
function createTemplateLoader(folders) {
|
|
1649
|
+
loader = new TemplateLoader(folders);
|
|
1650
|
+
}
|
|
1651
|
+
async function render(doc, docs, nav, vendors, options) {
|
|
1652
|
+
const { fileInfo } = doc;
|
|
1653
|
+
const { outputFolder, cacheFolder } = options;
|
|
1654
|
+
if (!haveOutputFile(fileInfo)) {
|
|
1655
|
+
return null;
|
|
1656
|
+
}
|
|
1657
|
+
const dst = createMarkdownRenderer.getOutputFilePath(outputFolder, fileInfo);
|
|
1658
|
+
const mkdir = fs.mkdir(path.dirname(dst), { recursive: true });
|
|
1659
|
+
const topnav = nav.topnav;
|
|
1660
|
+
const sidenav = findSidenav(doc, nav.sidenav);
|
|
1661
|
+
if (sidenav && isNavigationSection(sidenav)) {
|
|
1662
|
+
sortNavigationTree(sidenav);
|
|
1663
|
+
}
|
|
1664
|
+
const njk = new nunjucks.Environment(loader, { autoescape: false });
|
|
1665
|
+
const asyncRender = util.promisify(njk.render);
|
|
1666
|
+
const renderTemplate = asyncRender.bind(njk);
|
|
1667
|
+
const template = findTemplate(doc.fileInfo, doc);
|
|
1668
|
+
const templateData = {
|
|
1669
|
+
...options.templateData,
|
|
1670
|
+
site: options.site,
|
|
1671
|
+
doc,
|
|
1672
|
+
topnav,
|
|
1673
|
+
rootUrl(doc2) {
|
|
1674
|
+
const { fileInfo: fileInfo2 } = doc2;
|
|
1675
|
+
const relative = path$1.relative(fileInfo2.path, ".");
|
|
1676
|
+
return relative !== "" ? relative : ".";
|
|
1800
1677
|
},
|
|
1801
|
-
|
|
1802
|
-
|
|
1803
|
-
|
|
1804
|
-
|
|
1678
|
+
sidenav,
|
|
1679
|
+
vendors
|
|
1680
|
+
};
|
|
1681
|
+
const generatedExamples = [];
|
|
1682
|
+
const generatedStandalone = [];
|
|
1683
|
+
const markdownRenderer = createMarkdownRenderer.createMarkdownRenderer({
|
|
1684
|
+
docs,
|
|
1685
|
+
generateExample({ source, language, filename, tags }) {
|
|
1686
|
+
const example = generateExample({
|
|
1687
|
+
source,
|
|
1688
|
+
language,
|
|
1689
|
+
filename,
|
|
1690
|
+
parent: fileInfo.fullPath,
|
|
1691
|
+
setupPath: options.setupPath,
|
|
1692
|
+
exampleFolders: options.exampleFolders,
|
|
1693
|
+
tags
|
|
1805
1694
|
});
|
|
1695
|
+
if (example.output) {
|
|
1696
|
+
const { dir, name } = path.parse(example.output);
|
|
1697
|
+
generatedExamples.push(example.task);
|
|
1698
|
+
generatedStandalone.push({
|
|
1699
|
+
outputFile: path.join(dir, `${name}.html`),
|
|
1700
|
+
content: example.markup
|
|
1701
|
+
});
|
|
1702
|
+
}
|
|
1703
|
+
return example;
|
|
1806
1704
|
},
|
|
1807
|
-
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
};
|
|
1813
|
-
const list = templateBlocks.get(container) ?? [];
|
|
1814
|
-
templateBlocks.set(container, [...list, block]);
|
|
1815
|
-
},
|
|
1816
|
-
getAllTemplateBlocks() {
|
|
1817
|
-
return templateBlocks;
|
|
1818
|
-
},
|
|
1819
|
-
setTopNavigation(root) {
|
|
1820
|
-
topnav = root;
|
|
1821
|
-
},
|
|
1822
|
-
setSideNavigation(root) {
|
|
1823
|
-
sidenav = root;
|
|
1705
|
+
addResource(dst2, src) {
|
|
1706
|
+
if (!fs$1.existsSync(src)) {
|
|
1707
|
+
throw new Error(`Failed to find image "${src}"`);
|
|
1708
|
+
}
|
|
1709
|
+
options.addResource(dst2, src);
|
|
1824
1710
|
},
|
|
1825
|
-
|
|
1826
|
-
|
|
1711
|
+
handleSoftError(error) {
|
|
1712
|
+
throw error;
|
|
1713
|
+
}
|
|
1714
|
+
});
|
|
1715
|
+
njk.addFilter("marked", (content2) => {
|
|
1716
|
+
return markdownRenderer.render(doc, content2);
|
|
1717
|
+
});
|
|
1718
|
+
njk.addFilter("json", json);
|
|
1719
|
+
njk.addFilter("dump", dump);
|
|
1720
|
+
njk.addFilter("relative", relative);
|
|
1721
|
+
njk.addFilter("take", take);
|
|
1722
|
+
njk.addExtension("BlockContainer", {
|
|
1723
|
+
tags: ["container"],
|
|
1724
|
+
parse(parser, nodes) {
|
|
1725
|
+
const tok = parser.nextToken();
|
|
1726
|
+
const args = parser.parseSignature(null, true);
|
|
1727
|
+
parser.advanceAfterBlockEnd(tok.value);
|
|
1728
|
+
return new nodes.CallExtensionAsync(this, "run", args, []);
|
|
1827
1729
|
},
|
|
1828
|
-
|
|
1829
|
-
|
|
1730
|
+
async run({ ctx }, container, callback) {
|
|
1731
|
+
const blocks = options.templateBlocks.get(container) ?? [];
|
|
1732
|
+
const promises = blocks.map(({ renderer }) => {
|
|
1733
|
+
if ("filename" in renderer) {
|
|
1734
|
+
const data = renderer.data;
|
|
1735
|
+
return renderTemplate(renderer.filename, {
|
|
1736
|
+
...ctx,
|
|
1737
|
+
...data
|
|
1738
|
+
});
|
|
1739
|
+
}
|
|
1740
|
+
if ("render" in renderer) {
|
|
1741
|
+
return Promise.resolve(renderer.render());
|
|
1742
|
+
}
|
|
1743
|
+
return Promise.resolve("");
|
|
1744
|
+
});
|
|
1745
|
+
const content2 = await Promise.all(promises);
|
|
1746
|
+
const markup = content2.join("");
|
|
1747
|
+
return callback(null, new nunjucks.runtime.SafeString(markup));
|
|
1748
|
+
}
|
|
1749
|
+
});
|
|
1750
|
+
await mkdir;
|
|
1751
|
+
let content;
|
|
1752
|
+
try {
|
|
1753
|
+
content = await renderTemplate(template, templateData);
|
|
1754
|
+
} catch (err) {
|
|
1755
|
+
const prefix = `Failed to render "${fileInfo.fullPath}"`;
|
|
1756
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1757
|
+
throw new Error(`${prefix}: ${message}`, { cause: err });
|
|
1758
|
+
}
|
|
1759
|
+
const expandedDst = dst.replace(/\[([^]+)\]/g, (match, key) => {
|
|
1760
|
+
if (key === "hash") {
|
|
1761
|
+
return createMarkdownRenderer.getFingerprint(doc.body);
|
|
1762
|
+
} else {
|
|
1763
|
+
return match;
|
|
1764
|
+
}
|
|
1765
|
+
});
|
|
1766
|
+
const writeFile = fs.writeFile(expandedDst, content ?? "null", "utf-8");
|
|
1767
|
+
try {
|
|
1768
|
+
await compileExamples({
|
|
1769
|
+
fileInfo,
|
|
1770
|
+
cacheFolder,
|
|
1771
|
+
outputFolder,
|
|
1772
|
+
tasks: generatedExamples,
|
|
1773
|
+
vendors
|
|
1774
|
+
});
|
|
1775
|
+
} catch (err) {
|
|
1776
|
+
const prefix = `Failed to compile examples from "${fileInfo.fullPath}"`;
|
|
1777
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1778
|
+
throw new Error(`${prefix}: ${message}`, { cause: err });
|
|
1779
|
+
}
|
|
1780
|
+
try {
|
|
1781
|
+
await compileStandalones({
|
|
1782
|
+
fileInfo,
|
|
1783
|
+
cacheFolder,
|
|
1784
|
+
outputFolder,
|
|
1785
|
+
tasks: generatedStandalone,
|
|
1786
|
+
renderTemplate,
|
|
1787
|
+
templateData
|
|
1788
|
+
});
|
|
1789
|
+
} catch (err) {
|
|
1790
|
+
const prefix = `Failed to render standalone examples from "${fileInfo.fullPath}"`;
|
|
1791
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
1792
|
+
throw new Error(`${prefix}: ${message}`, { cause: err });
|
|
1793
|
+
}
|
|
1794
|
+
await writeFile;
|
|
1795
|
+
return dst;
|
|
1796
|
+
}
|
|
1797
|
+
|
|
1798
|
+
const progressbar = new vendor.cliProgress.SingleBar({
|
|
1799
|
+
format: " {bar} {percentage}% | {value}/{total} documents | {filename}",
|
|
1800
|
+
barCompleteChar: "\u2588",
|
|
1801
|
+
barIncompleteChar: "\u2591",
|
|
1802
|
+
hideCursor: true,
|
|
1803
|
+
clearOnComplete: true
|
|
1804
|
+
});
|
|
1805
|
+
function nunjucksProcessor(options) {
|
|
1806
|
+
return {
|
|
1807
|
+
stage: "render",
|
|
1808
|
+
name: "nunjucks-renderer",
|
|
1809
|
+
async handler(context) {
|
|
1810
|
+
function renderDocument(doc) {
|
|
1811
|
+
const nav = {
|
|
1812
|
+
topnav: context.topnav,
|
|
1813
|
+
sidenav: context.sidenav
|
|
1814
|
+
};
|
|
1815
|
+
return render(doc, context.docs, nav, context.vendors, {
|
|
1816
|
+
...options,
|
|
1817
|
+
templateBlocks: context.getAllTemplateBlocks(),
|
|
1818
|
+
templateData: context.getAllTemplateData(),
|
|
1819
|
+
addResource(dst, src) {
|
|
1820
|
+
context.addResource(dst, src);
|
|
1821
|
+
}
|
|
1822
|
+
});
|
|
1823
|
+
}
|
|
1824
|
+
const docs = context.docs.filter((it) => {
|
|
1825
|
+
return it.fileInfo.outputName;
|
|
1826
|
+
});
|
|
1827
|
+
createTemplateLoader(options.templateFolders);
|
|
1828
|
+
progressbar.start(docs.length, 0, {
|
|
1829
|
+
filename: docs.length > 0 ? docs[0].fileInfo.fullPath : ""
|
|
1830
|
+
});
|
|
1831
|
+
const generatedFiles = [];
|
|
1832
|
+
try {
|
|
1833
|
+
for (const doc of context.docs) {
|
|
1834
|
+
const filePath = await renderDocument(doc);
|
|
1835
|
+
if (filePath) {
|
|
1836
|
+
generatedFiles.push(filePath);
|
|
1837
|
+
}
|
|
1838
|
+
progressbar.increment(1, {
|
|
1839
|
+
filename: doc.fileInfo.fullPath
|
|
1840
|
+
});
|
|
1841
|
+
}
|
|
1842
|
+
} finally {
|
|
1843
|
+
progressbar.stop();
|
|
1844
|
+
}
|
|
1845
|
+
context.log(docs.length, "documents rendered");
|
|
1846
|
+
return generatedFiles;
|
|
1847
|
+
}
|
|
1848
|
+
};
|
|
1849
|
+
}
|
|
1850
|
+
|
|
1851
|
+
function customRequire(name) {
|
|
1852
|
+
if (typeof window.__modules__ === "undefined") {
|
|
1853
|
+
window.__modules__ = {};
|
|
1854
|
+
}
|
|
1855
|
+
const mod = window.__modules__[name];
|
|
1856
|
+
if (!mod) {
|
|
1857
|
+
throw new Error(`Cannot find module "${name}"`);
|
|
1858
|
+
}
|
|
1859
|
+
return mod;
|
|
1860
|
+
}
|
|
1861
|
+
function getAssetSource(asset, require) {
|
|
1862
|
+
const lines = [];
|
|
1863
|
+
const pkg = asset.package.replace(/\\/g, "/");
|
|
1864
|
+
if (!asset.expose) {
|
|
1865
|
+
return `import "${pkg}"`;
|
|
1866
|
+
}
|
|
1867
|
+
if (asset.expose === "named") {
|
|
1868
|
+
lines.push(`import * as lib from "${pkg}";`);
|
|
1869
|
+
} else {
|
|
1870
|
+
lines.push(`import lib from "${pkg}";`);
|
|
1871
|
+
}
|
|
1872
|
+
asset.subpaths.map((subpath, index) => {
|
|
1873
|
+
if (asset.expose === "named") {
|
|
1874
|
+
lines.push(`import * as lib$${index} from "${subpath}";`);
|
|
1875
|
+
} else {
|
|
1876
|
+
lines.push(`import lib$${index} from "${subpath}";`);
|
|
1877
|
+
}
|
|
1878
|
+
});
|
|
1879
|
+
lines.push(`window.require = window.require || ${require};`);
|
|
1880
|
+
lines.push(`window.__modules__ = window.__modules__ || {};`);
|
|
1881
|
+
lines.push(`window.__modules__["${asset.package}"] = lib;`);
|
|
1882
|
+
if (typeof asset.alias !== "undefined") {
|
|
1883
|
+
lines.push(`window.__modules__["${asset.alias}"] = lib;`);
|
|
1884
|
+
}
|
|
1885
|
+
asset.subpaths.map((subpath, index) => {
|
|
1886
|
+
lines.push(`window.__modules__["${subpath}"] = lib$${index};`);
|
|
1887
|
+
});
|
|
1888
|
+
if (typeof asset.global !== "undefined") {
|
|
1889
|
+
lines.push(`window["${asset.global}"] = lib;`);
|
|
1890
|
+
}
|
|
1891
|
+
return lines.join("\n");
|
|
1892
|
+
}
|
|
1893
|
+
async function compileVendor(assetFolder, vendor, options) {
|
|
1894
|
+
const name = path.isAbsolute(vendor.package) ? path.basename(vendor.package) : vendor.package;
|
|
1895
|
+
const slug = slugify(name);
|
|
1896
|
+
const outfile = `temp/vendor-${slug}.out.js`;
|
|
1897
|
+
const tmpfile = `temp/vendor-${slug}.in.js`;
|
|
1898
|
+
const source = getAssetSource(vendor, customRequire.toString());
|
|
1899
|
+
const tsconfig = path.resolve(__dirname, "../tsconfig-examples.json");
|
|
1900
|
+
await fs.writeFile(tmpfile, source, "utf-8");
|
|
1901
|
+
await esbuild.build({
|
|
1902
|
+
entryPoints: [tmpfile],
|
|
1903
|
+
outfile,
|
|
1904
|
+
bundle: true,
|
|
1905
|
+
format: "iife",
|
|
1906
|
+
platform: "browser",
|
|
1907
|
+
tsconfig,
|
|
1908
|
+
define: {
|
|
1909
|
+
"process.env.NODE_ENV": JSON.stringify(
|
|
1910
|
+
process.env.NODE_ENV ?? "production"
|
|
1911
|
+
)
|
|
1830
1912
|
},
|
|
1831
|
-
|
|
1832
|
-
|
|
1913
|
+
alias: vendor.alias ? { [`${vendor.package}`]: vendor.alias } : void 0,
|
|
1914
|
+
...options
|
|
1915
|
+
});
|
|
1916
|
+
const content = await fs.readFile(outfile, "utf-8");
|
|
1917
|
+
const fingerprint = createMarkdownRenderer.getFingerprint(content);
|
|
1918
|
+
const integrity = getIntegrity(content);
|
|
1919
|
+
const filename = `vendor-${slug}-${fingerprint}.js`;
|
|
1920
|
+
const dst = path.join(assetFolder, filename).replace(/\\/g, "/");
|
|
1921
|
+
await fs.rename(outfile, dst);
|
|
1922
|
+
const stat = await fs.stat(dst);
|
|
1923
|
+
return {
|
|
1924
|
+
package: vendor.package,
|
|
1925
|
+
filename,
|
|
1926
|
+
publicPath: `./assets/${filename}`,
|
|
1927
|
+
integrity,
|
|
1928
|
+
size: stat.size
|
|
1929
|
+
};
|
|
1930
|
+
}
|
|
1931
|
+
|
|
1932
|
+
function normalizeVendorDefinition(vendor) {
|
|
1933
|
+
if (typeof vendor === "string") {
|
|
1934
|
+
return {
|
|
1935
|
+
package: vendor,
|
|
1936
|
+
global: void 0,
|
|
1937
|
+
expose: "named",
|
|
1938
|
+
subpaths: []
|
|
1939
|
+
};
|
|
1940
|
+
} else {
|
|
1941
|
+
return {
|
|
1942
|
+
package: vendor.package,
|
|
1943
|
+
global: vendor.global,
|
|
1944
|
+
expose: vendor.expose ?? "named",
|
|
1945
|
+
subpaths: vendor.subpaths ?? [],
|
|
1946
|
+
alias: vendor.alias ?? void 0
|
|
1947
|
+
};
|
|
1948
|
+
}
|
|
1949
|
+
}
|
|
1950
|
+
|
|
1951
|
+
function getPackageName(vendor) {
|
|
1952
|
+
return typeof vendor === "string" ? vendor : vendor.package;
|
|
1953
|
+
}
|
|
1954
|
+
function generateVendorAssets(assetFolder, assets) {
|
|
1955
|
+
const packages = assets.map(getPackageName);
|
|
1956
|
+
const normalized = assets.map(normalizeVendorDefinition);
|
|
1957
|
+
const promises = normalized.map((it) => {
|
|
1958
|
+
const external = packages.filter((pkg) => pkg !== it.package);
|
|
1959
|
+
return compileVendor(assetFolder, it, {
|
|
1960
|
+
external
|
|
1961
|
+
});
|
|
1962
|
+
});
|
|
1963
|
+
return Promise.all(promises);
|
|
1964
|
+
}
|
|
1965
|
+
function vendorProcessor(assetFolder, vendor) {
|
|
1966
|
+
return {
|
|
1967
|
+
stage: "assets",
|
|
1968
|
+
name: "vendor-processor",
|
|
1969
|
+
async handler(context) {
|
|
1970
|
+
const assets = await generateVendorAssets(assetFolder, vendor);
|
|
1971
|
+
context.addVendorAsset(assets);
|
|
1972
|
+
for (const asset of assets) {
|
|
1973
|
+
const filename = path$1.basename(asset.publicPath);
|
|
1974
|
+
context.log(filename, formatSize(asset.size));
|
|
1975
|
+
}
|
|
1833
1976
|
}
|
|
1834
1977
|
};
|
|
1835
1978
|
}
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
|
|
1843
|
-
|
|
1844
|
-
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
styles;
|
|
1848
|
-
resources;
|
|
1849
|
-
sourceFiles;
|
|
1850
|
-
constructor(options) {
|
|
1851
|
-
if (typeof options.site === "undefined") {
|
|
1852
|
-
throw new Error("site metadata not set in configuration");
|
|
1979
|
+
|
|
1980
|
+
function livereloadProcessor(options) {
|
|
1981
|
+
const { enabled } = options;
|
|
1982
|
+
return {
|
|
1983
|
+
after: "generate-docs",
|
|
1984
|
+
name: "livereload-processor",
|
|
1985
|
+
enabled,
|
|
1986
|
+
handler(context) {
|
|
1987
|
+
context.addTemplateBlock("body:end", "livereload", {
|
|
1988
|
+
filename: "partials/livereload.html"
|
|
1989
|
+
});
|
|
1853
1990
|
}
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
this.resources = [];
|
|
1866
|
-
this.sourceFiles = [];
|
|
1867
|
-
const bootstrapUrl = new URL("runtime-bootstrap.js", (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.src || new URL('index.js', document.baseURI).href)));
|
|
1868
|
-
this.compileScript("bootstrap", node_url.fileURLToPath(bootstrapUrl), {
|
|
1869
|
-
appendTo: "head"
|
|
1870
|
-
});
|
|
1871
|
-
}
|
|
1872
|
-
compileScript(name, src, options) {
|
|
1873
|
-
this.scripts.push({
|
|
1874
|
-
name,
|
|
1875
|
-
src,
|
|
1876
|
-
options: {
|
|
1877
|
-
appendTo: "none",
|
|
1878
|
-
attributes: {},
|
|
1879
|
-
...options
|
|
1880
|
-
}
|
|
1991
|
+
};
|
|
1992
|
+
}
|
|
1993
|
+
|
|
1994
|
+
async function keypress() {
|
|
1995
|
+
process.stdin.setRawMode(true);
|
|
1996
|
+
process.stdin.resume();
|
|
1997
|
+
return new Promise((resolve) => {
|
|
1998
|
+
process.stdin.once("data", (data) => {
|
|
1999
|
+
process.stdin.setRawMode(false);
|
|
2000
|
+
process.stdin.resume();
|
|
2001
|
+
resolve(data.toString("utf-8"));
|
|
1881
2002
|
});
|
|
1882
|
-
}
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
2003
|
+
});
|
|
2004
|
+
}
|
|
2005
|
+
|
|
2006
|
+
function printMenu(addr) {
|
|
2007
|
+
console.log();
|
|
2008
|
+
console.group(
|
|
2009
|
+
`Starting development server at http://localhost:${addr.port}`
|
|
2010
|
+
);
|
|
2011
|
+
console.log();
|
|
2012
|
+
console.log("[q] quit");
|
|
2013
|
+
console.log();
|
|
2014
|
+
console.groupEnd();
|
|
2015
|
+
}
|
|
2016
|
+
|
|
2017
|
+
function sleep(ms) {
|
|
2018
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
2019
|
+
}
|
|
2020
|
+
function createRebuilder(callback, livereload) {
|
|
2021
|
+
let inflight = false;
|
|
2022
|
+
let queue = [];
|
|
2023
|
+
async function rebuild(filePath) {
|
|
2024
|
+
queue.push(filePath);
|
|
2025
|
+
if (inflight) {
|
|
2026
|
+
return;
|
|
2027
|
+
}
|
|
2028
|
+
inflight = true;
|
|
2029
|
+
try {
|
|
2030
|
+
while (queue.length > 0) {
|
|
2031
|
+
const modifiedFiles = queue;
|
|
2032
|
+
queue = [];
|
|
2033
|
+
const generatedFiles = await callback(modifiedFiles);
|
|
2034
|
+
livereload(generatedFiles);
|
|
2035
|
+
await sleep(200);
|
|
1891
2036
|
}
|
|
1892
|
-
}
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
* @param dst - Destination directory relative to asset folder.
|
|
1896
|
-
* @param src - File or directory to copy.
|
|
1897
|
-
*/
|
|
1898
|
-
copyResource(dst, src) {
|
|
1899
|
-
this.resources.push({
|
|
1900
|
-
from: src.replace(/\\/g, "/"),
|
|
1901
|
-
to: dst
|
|
1902
|
-
});
|
|
1903
|
-
}
|
|
1904
|
-
/**
|
|
1905
|
-
* Generate a manifest listing all generated documents that will be present
|
|
1906
|
-
* in `outputFolder`.
|
|
1907
|
-
*
|
|
1908
|
-
* Note: this only collects documents from the `generate-docs` stage,
|
|
1909
|
-
* potential documents generated at later stages will not be present.
|
|
1910
|
-
*
|
|
1911
|
-
* @public
|
|
1912
|
-
*/
|
|
1913
|
-
async manifest(sourceFiles) {
|
|
1914
|
-
const processors = [
|
|
1915
|
-
fileReaderProcessor(sourceFiles),
|
|
1916
|
-
...this.processors
|
|
1917
|
-
];
|
|
1918
|
-
const context = createContext();
|
|
1919
|
-
await stage("generate-docs", context, processors, { verbose: false });
|
|
1920
|
-
const docs = context.docs.filter(haveOutput);
|
|
1921
|
-
const pages = docs.map(manifestPageFromDocument);
|
|
1922
|
-
return { pages };
|
|
1923
|
-
}
|
|
1924
|
-
async build(sourceFiles) {
|
|
1925
|
-
this.sourceFiles = sourceFiles;
|
|
1926
|
-
const {
|
|
1927
|
-
site,
|
|
1928
|
-
outputFolder,
|
|
1929
|
-
cacheFolder,
|
|
1930
|
-
assetFolder,
|
|
1931
|
-
exampleFolders,
|
|
1932
|
-
templateFolders,
|
|
1933
|
-
setupPath
|
|
1934
|
-
} = this;
|
|
1935
|
-
await this._prepareFolders();
|
|
1936
|
-
const processors = [
|
|
1937
|
-
fileReaderProcessor(sourceFiles),
|
|
1938
|
-
vendorProcessor(assetFolder, this.vendor),
|
|
1939
|
-
cssAssetProcessor(assetFolder, this.styles),
|
|
1940
|
-
jsAssetProcessor(assetFolder, this.scripts),
|
|
1941
|
-
staticResourcesProcessor(assetFolder, this.resources),
|
|
1942
|
-
navigationProcessor(),
|
|
1943
|
-
nunjucksProcessor({
|
|
1944
|
-
site: {
|
|
1945
|
-
lang: "en",
|
|
1946
|
-
...site
|
|
1947
|
-
},
|
|
1948
|
-
outputFolder,
|
|
1949
|
-
cacheFolder,
|
|
1950
|
-
exampleFolders,
|
|
1951
|
-
templateFolders,
|
|
1952
|
-
setupPath
|
|
1953
|
-
}),
|
|
1954
|
-
...this.processors
|
|
1955
|
-
];
|
|
1956
|
-
const context = createContext();
|
|
1957
|
-
const generatedFiles = [
|
|
1958
|
-
await stage("generate-docs", context, processors),
|
|
1959
|
-
await stage("generate-nav", context, processors),
|
|
1960
|
-
await stage("assets", context, processors),
|
|
1961
|
-
await stage("render", context, processors)
|
|
1962
|
-
];
|
|
1963
|
-
return generatedFiles.flat();
|
|
2037
|
+
} finally {
|
|
2038
|
+
inflight = false;
|
|
2039
|
+
}
|
|
1964
2040
|
}
|
|
1965
|
-
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
1973
|
-
|
|
1974
|
-
|
|
1975
|
-
|
|
1976
|
-
|
|
2041
|
+
return rebuild;
|
|
2042
|
+
}
|
|
2043
|
+
async function serve(options) {
|
|
2044
|
+
const app = express();
|
|
2045
|
+
app.use(express.static(options.outputFolder));
|
|
2046
|
+
const server = app.listen(8080);
|
|
2047
|
+
printMenu(server.address());
|
|
2048
|
+
const livereload = vendor.tinylr();
|
|
2049
|
+
livereload.listen(35729);
|
|
2050
|
+
const watcher = vendor.chokidar.watch(options.watch);
|
|
2051
|
+
const rebuild = createRebuilder(options.rebuild, (filePath) => {
|
|
2052
|
+
const files = filePath.map((it) => {
|
|
2053
|
+
return path$1.relative(options.outputFolder, it);
|
|
1977
2054
|
});
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
|
|
2055
|
+
livereload.changed({ body: { files } });
|
|
2056
|
+
});
|
|
2057
|
+
watcher.on("change", async (filePath) => {
|
|
2058
|
+
rebuild(filePath);
|
|
2059
|
+
});
|
|
2060
|
+
for (; ; ) {
|
|
2061
|
+
const key = await keypress();
|
|
2062
|
+
switch (key) {
|
|
2063
|
+
case "":
|
|
2064
|
+
/* ctrl-c */
|
|
2065
|
+
case "q":
|
|
2066
|
+
console.log("Shutting down gracefully");
|
|
2067
|
+
server.close();
|
|
2068
|
+
watcher.close();
|
|
2069
|
+
livereload.close();
|
|
2070
|
+
process.stdin.unref();
|
|
2071
|
+
return;
|
|
1986
2072
|
}
|
|
1987
|
-
await fs.mkdir(outputFolder, { recursive: true });
|
|
1988
|
-
await fs.mkdir(assetFolder, { recursive: true });
|
|
1989
|
-
await fs.mkdir("temp", { recursive: true });
|
|
1990
2073
|
}
|
|
1991
2074
|
}
|
|
1992
2075
|
|
|
1993
2076
|
function toArray(value) {
|
|
1994
2077
|
return Array.isArray(value) ? value : [value];
|
|
1995
2078
|
}
|
|
1996
|
-
function
|
|
1997
|
-
const
|
|
1998
|
-
|
|
1999
|
-
|
|
2000
|
-
|
|
2001
|
-
enabled
|
|
2002
|
-
|
|
2003
|
-
context.addTemplateBlock("head", "matomo", {
|
|
2004
|
-
filename: "partials/matomo.html",
|
|
2005
|
-
data: {
|
|
2006
|
-
siteId,
|
|
2007
|
-
apiUrl,
|
|
2008
|
-
trackerUrl,
|
|
2009
|
-
hostname: hostname ? toArray(hostname) : []
|
|
2010
|
-
}
|
|
2011
|
-
});
|
|
2079
|
+
function filterProcessors(stage2, processors) {
|
|
2080
|
+
const before = [];
|
|
2081
|
+
const during = [];
|
|
2082
|
+
const after = [];
|
|
2083
|
+
for (const processor of processors) {
|
|
2084
|
+
if (processor.enabled === false) {
|
|
2085
|
+
continue;
|
|
2012
2086
|
}
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
function renderMarkdown(manifest) {
|
|
2017
|
-
return [
|
|
2018
|
-
"## Documentation manifest",
|
|
2019
|
-
"",
|
|
2020
|
-
"> Do not edit this file. It is a automatically generated by `@forsakringskassan/docs-generator`.",
|
|
2021
|
-
"",
|
|
2022
|
-
"```",
|
|
2023
|
-
...manifest.pages.map((it) => it.path),
|
|
2024
|
-
"```",
|
|
2025
|
-
""
|
|
2026
|
-
].join("\n");
|
|
2027
|
-
}
|
|
2028
|
-
function renderJSON(manifest) {
|
|
2029
|
-
return JSON.stringify(manifest, null, 2);
|
|
2030
|
-
}
|
|
2031
|
-
function manifestProcessor(options) {
|
|
2032
|
-
const { markdown, json } = options;
|
|
2033
|
-
return {
|
|
2034
|
-
name: "manifestProcessor",
|
|
2035
|
-
before: "render",
|
|
2036
|
-
async handler(context) {
|
|
2037
|
-
const docs = context.docs.filter(haveOutput);
|
|
2038
|
-
const pages = docs.map(manifestPageFromDocument);
|
|
2039
|
-
pages.sort((a, b) => {
|
|
2040
|
-
return a.path.localeCompare(b.path);
|
|
2041
|
-
});
|
|
2042
|
-
const manifest = { pages };
|
|
2043
|
-
if (markdown) {
|
|
2044
|
-
const content = renderMarkdown(manifest);
|
|
2045
|
-
await fs.writeFile(markdown, content, "utf-8");
|
|
2046
|
-
}
|
|
2047
|
-
if (json) {
|
|
2048
|
-
const content = renderJSON(manifest);
|
|
2049
|
-
await fs.writeFile(json, content, "utf-8");
|
|
2050
|
-
}
|
|
2087
|
+
if (processor.before === stage2) {
|
|
2088
|
+
before.push(processor);
|
|
2051
2089
|
}
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
function normalizeOptions(options) {
|
|
2056
|
-
const defaults = {
|
|
2057
|
-
enabled: true,
|
|
2058
|
-
container: "body:begin"
|
|
2059
|
-
};
|
|
2060
|
-
return { ...defaults, ...options };
|
|
2061
|
-
}
|
|
2062
|
-
function motdProcessor(options) {
|
|
2063
|
-
const { enabled, container, message } = normalizeOptions(options);
|
|
2064
|
-
return {
|
|
2065
|
-
name: "motd-processor",
|
|
2066
|
-
after: "generate-docs",
|
|
2067
|
-
handler(context) {
|
|
2068
|
-
if (!enabled) {
|
|
2069
|
-
return;
|
|
2070
|
-
}
|
|
2071
|
-
context.addTemplateBlock(container, "version-banner", {
|
|
2072
|
-
filename: "partials/version-banner.html",
|
|
2073
|
-
data: { message }
|
|
2074
|
-
});
|
|
2090
|
+
if (processor.stage === stage2) {
|
|
2091
|
+
during.push(processor);
|
|
2075
2092
|
}
|
|
2076
|
-
|
|
2077
|
-
|
|
2078
|
-
function versionBannerProcessorDeprecated(message, container) {
|
|
2079
|
-
return motdProcessor({
|
|
2080
|
-
enabled: true,
|
|
2081
|
-
container,
|
|
2082
|
-
message
|
|
2083
|
-
});
|
|
2084
|
-
}
|
|
2085
|
-
const versionBannerProcessor = util.deprecate(
|
|
2086
|
-
versionBannerProcessorDeprecated,
|
|
2087
|
-
"versionBannerProcessor() is deprecated, use motdProcessor() instead"
|
|
2088
|
-
);
|
|
2089
|
-
|
|
2090
|
-
function themeSelectProcessor() {
|
|
2091
|
-
return {
|
|
2092
|
-
name: "theme-select-processor",
|
|
2093
|
-
after: "generate-docs",
|
|
2094
|
-
handler(context) {
|
|
2095
|
-
const sessionKey = "fkds-theme";
|
|
2096
|
-
const data = {
|
|
2097
|
-
defaultTheme: "exp",
|
|
2098
|
-
sessionKey
|
|
2099
|
-
};
|
|
2100
|
-
context.addTemplateBlock("head", "theme-render-blocker", {
|
|
2101
|
-
filename: "partials/theme-render-blocker.html",
|
|
2102
|
-
data
|
|
2103
|
-
});
|
|
2104
|
-
context.addTemplateBlock("toolbar", "theme-select", {
|
|
2105
|
-
filename: "partials/theme-select.html",
|
|
2106
|
-
data
|
|
2107
|
-
});
|
|
2093
|
+
if (processor.after === stage2) {
|
|
2094
|
+
after.push(processor);
|
|
2108
2095
|
}
|
|
2109
|
-
}
|
|
2096
|
+
}
|
|
2097
|
+
return [...before, ...during, ...after];
|
|
2110
2098
|
}
|
|
2111
|
-
|
|
2112
|
-
|
|
2113
|
-
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2099
|
+
async function stage(stage2, context, processors, { verbose } = { verbose: true }) {
|
|
2100
|
+
if (verbose) {
|
|
2101
|
+
console.log(`stage:${stage2}`);
|
|
2102
|
+
}
|
|
2103
|
+
let generatedFiles = [];
|
|
2104
|
+
const filteredProcessors = filterProcessors(stage2, processors);
|
|
2105
|
+
for (let i = 0; i < filteredProcessors.length; i++) {
|
|
2106
|
+
const processor = filteredProcessors[i];
|
|
2107
|
+
const isLast = i === filteredProcessors.length - 1;
|
|
2108
|
+
if (verbose) {
|
|
2109
|
+
console.log(isLast ? " \u2514\u2500" : " \u251C\u2500", processor.name);
|
|
2110
|
+
}
|
|
2111
|
+
try {
|
|
2112
|
+
const result = await processor.handler({
|
|
2113
|
+
...context,
|
|
2114
|
+
log(...args) {
|
|
2115
|
+
if (verbose) {
|
|
2116
|
+
console.log(isLast ? " " : " \u2502 ", ...args);
|
|
2117
|
+
}
|
|
2118
|
+
}
|
|
2124
2119
|
});
|
|
2120
|
+
if (result) {
|
|
2121
|
+
generatedFiles = [...generatedFiles, ...result];
|
|
2122
|
+
}
|
|
2123
|
+
} catch (err) {
|
|
2124
|
+
console.error(`When running processor "${processor.name}":`);
|
|
2125
|
+
console.error(err);
|
|
2126
|
+
throw err;
|
|
2125
2127
|
}
|
|
2126
|
-
}
|
|
2128
|
+
}
|
|
2129
|
+
return generatedFiles;
|
|
2127
2130
|
}
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
sortorder: index,
|
|
2135
|
-
children: [],
|
|
2136
|
-
...it
|
|
2137
|
-
};
|
|
2138
|
-
});
|
|
2139
|
-
return {
|
|
2131
|
+
function createContext() {
|
|
2132
|
+
let docs = [];
|
|
2133
|
+
let vendors = [];
|
|
2134
|
+
const resources = [];
|
|
2135
|
+
const templateBlocks = /* @__PURE__ */ new Map();
|
|
2136
|
+
let topnav = {
|
|
2140
2137
|
key: ".",
|
|
2141
|
-
|
|
2138
|
+
title: "",
|
|
2139
|
+
path: "",
|
|
2142
2140
|
sortorder: Infinity,
|
|
2143
|
-
children
|
|
2141
|
+
children: []
|
|
2144
2142
|
};
|
|
2145
|
-
|
|
2146
|
-
|
|
2143
|
+
let sidenav = {
|
|
2144
|
+
key: ".",
|
|
2145
|
+
title: "",
|
|
2146
|
+
path: "",
|
|
2147
|
+
sortorder: Infinity,
|
|
2148
|
+
children: []
|
|
2149
|
+
};
|
|
2150
|
+
const templateData = {};
|
|
2147
2151
|
return {
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
2155
|
-
|
|
2156
|
-
|
|
2152
|
+
get docs() {
|
|
2153
|
+
return docs;
|
|
2154
|
+
},
|
|
2155
|
+
get vendors() {
|
|
2156
|
+
return vendors;
|
|
2157
|
+
},
|
|
2158
|
+
get resources() {
|
|
2159
|
+
return resources;
|
|
2160
|
+
},
|
|
2161
|
+
get topnav() {
|
|
2162
|
+
return topnav;
|
|
2163
|
+
},
|
|
2164
|
+
get sidenav() {
|
|
2165
|
+
return sidenav;
|
|
2166
|
+
},
|
|
2167
|
+
addDocument(document) {
|
|
2168
|
+
docs = [...docs, ...toArray(document)];
|
|
2169
|
+
},
|
|
2170
|
+
addVendorAsset(asset) {
|
|
2171
|
+
vendors = [...vendors, ...toArray(asset)];
|
|
2172
|
+
},
|
|
2173
|
+
addResource(dst, src) {
|
|
2174
|
+
resources.push({
|
|
2175
|
+
from: src.replace(/\\/g, "/"),
|
|
2176
|
+
to: dst
|
|
2157
2177
|
});
|
|
2178
|
+
},
|
|
2179
|
+
addTemplateBlock(container, id, renderer) {
|
|
2180
|
+
const block = {
|
|
2181
|
+
container,
|
|
2182
|
+
id,
|
|
2183
|
+
renderer
|
|
2184
|
+
};
|
|
2185
|
+
const list = templateBlocks.get(container) ?? [];
|
|
2186
|
+
templateBlocks.set(container, [...list, block]);
|
|
2187
|
+
},
|
|
2188
|
+
getAllTemplateBlocks() {
|
|
2189
|
+
return templateBlocks;
|
|
2190
|
+
},
|
|
2191
|
+
setTopNavigation(root) {
|
|
2192
|
+
topnav = root;
|
|
2193
|
+
},
|
|
2194
|
+
setSideNavigation(root) {
|
|
2195
|
+
sidenav = root;
|
|
2196
|
+
},
|
|
2197
|
+
getAllTemplateData() {
|
|
2198
|
+
return templateData;
|
|
2199
|
+
},
|
|
2200
|
+
getTemplateData(key) {
|
|
2201
|
+
return templateData[key];
|
|
2202
|
+
},
|
|
2203
|
+
setTemplateData(key, value) {
|
|
2204
|
+
templateData[key] = value;
|
|
2158
2205
|
}
|
|
2159
2206
|
};
|
|
2160
2207
|
}
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2208
|
+
class Generator {
|
|
2209
|
+
site;
|
|
2210
|
+
outputFolder;
|
|
2211
|
+
cacheFolder;
|
|
2212
|
+
assetFolder;
|
|
2213
|
+
exampleFolders;
|
|
2214
|
+
templateFolders;
|
|
2215
|
+
processors;
|
|
2216
|
+
vendor;
|
|
2217
|
+
setupPath;
|
|
2218
|
+
scripts;
|
|
2219
|
+
styles;
|
|
2220
|
+
resources;
|
|
2221
|
+
sourceFiles;
|
|
2222
|
+
constructor(options) {
|
|
2223
|
+
if (typeof options.site === "undefined") {
|
|
2224
|
+
throw new Error("site metadata not set in configuration");
|
|
2225
|
+
}
|
|
2226
|
+
this.site = options.site;
|
|
2227
|
+
this.outputFolder = options.outputFolder;
|
|
2228
|
+
this.cacheFolder = options.cacheFolder;
|
|
2229
|
+
this.assetFolder = path.posix.join(options.outputFolder, "assets");
|
|
2230
|
+
this.exampleFolders = options.exampleFolders;
|
|
2231
|
+
this.templateFolders = options.templateFolders ?? [];
|
|
2232
|
+
this.processors = options.processors ?? [];
|
|
2233
|
+
this.vendor = options.vendor ?? [];
|
|
2234
|
+
this.setupPath = options.setupPath.replace(/\\/g, "/");
|
|
2235
|
+
this.scripts = [];
|
|
2236
|
+
this.styles = [];
|
|
2237
|
+
this.resources = [];
|
|
2238
|
+
this.sourceFiles = [];
|
|
2239
|
+
const bootstrapUrl = new URL("runtime-bootstrap.js", (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.src || new URL('index.js', document.baseURI).href)));
|
|
2240
|
+
this.compileScript("bootstrap", bootstrapUrl, {
|
|
2241
|
+
appendTo: "head"
|
|
2242
|
+
});
|
|
2243
|
+
}
|
|
2244
|
+
compileScript(name, src, options) {
|
|
2245
|
+
this.scripts.push({
|
|
2246
|
+
name,
|
|
2247
|
+
src,
|
|
2248
|
+
options: {
|
|
2249
|
+
appendTo: "none",
|
|
2250
|
+
attributes: {},
|
|
2251
|
+
...options
|
|
2170
2252
|
}
|
|
2171
2253
|
});
|
|
2172
|
-
});
|
|
2173
|
-
}
|
|
2174
|
-
async function getGitBranch() {
|
|
2175
|
-
const { CHANGE_BRANCH, CHANGE_NAME } = process.env;
|
|
2176
|
-
if (CHANGE_BRANCH) {
|
|
2177
|
-
return CHANGE_BRANCH;
|
|
2178
2254
|
}
|
|
2179
|
-
|
|
2180
|
-
|
|
2255
|
+
compileStyle(name, src, options) {
|
|
2256
|
+
this.styles.push({
|
|
2257
|
+
name,
|
|
2258
|
+
src,
|
|
2259
|
+
options: {
|
|
2260
|
+
appendTo: "none",
|
|
2261
|
+
attributes: {},
|
|
2262
|
+
...options
|
|
2263
|
+
}
|
|
2264
|
+
});
|
|
2181
2265
|
}
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2266
|
+
/**
|
|
2267
|
+
* @param dst - Destination directory relative to asset folder.
|
|
2268
|
+
* @param src - File or directory to copy.
|
|
2269
|
+
*/
|
|
2270
|
+
copyResource(dst, src) {
|
|
2271
|
+
this.resources.push({
|
|
2272
|
+
from: src.replace(/\\/g, "/"),
|
|
2273
|
+
to: dst
|
|
2274
|
+
});
|
|
2187
2275
|
}
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2276
|
+
/**
|
|
2277
|
+
* Generate a manifest listing all generated documents that will be present
|
|
2278
|
+
* in `outputFolder`.
|
|
2279
|
+
*
|
|
2280
|
+
* Note: this only collects documents from the `generate-docs` stage,
|
|
2281
|
+
* potential documents generated at later stages will not be present.
|
|
2282
|
+
*
|
|
2283
|
+
* @public
|
|
2284
|
+
*/
|
|
2285
|
+
async manifest(sourceFiles) {
|
|
2286
|
+
const processors = [
|
|
2287
|
+
fileReaderProcessor(sourceFiles),
|
|
2288
|
+
...this.processors
|
|
2289
|
+
];
|
|
2290
|
+
const context = createContext();
|
|
2291
|
+
await stage("generate-docs", context, processors, { verbose: false });
|
|
2292
|
+
const docs = context.docs.filter(haveOutput);
|
|
2293
|
+
const pages = docs.map(manifestPageFromDocument);
|
|
2294
|
+
return { pages };
|
|
2194
2295
|
}
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2296
|
+
async build(sourceFiles) {
|
|
2297
|
+
this.sourceFiles = sourceFiles;
|
|
2298
|
+
const {
|
|
2299
|
+
site,
|
|
2300
|
+
outputFolder,
|
|
2301
|
+
cacheFolder,
|
|
2302
|
+
assetFolder,
|
|
2303
|
+
exampleFolders,
|
|
2304
|
+
templateFolders,
|
|
2305
|
+
setupPath
|
|
2306
|
+
} = this;
|
|
2307
|
+
await this._prepareFolders();
|
|
2308
|
+
const processors = [
|
|
2309
|
+
fileReaderProcessor(sourceFiles),
|
|
2310
|
+
vendorProcessor(assetFolder, this.vendor),
|
|
2311
|
+
cssAssetProcessor(assetFolder, this.styles),
|
|
2312
|
+
jsAssetProcessor(assetFolder, this.scripts),
|
|
2313
|
+
staticResourcesProcessor(assetFolder, this.resources),
|
|
2314
|
+
navigationProcessor(),
|
|
2315
|
+
nunjucksProcessor({
|
|
2316
|
+
site: {
|
|
2317
|
+
lang: "en",
|
|
2318
|
+
...site
|
|
2319
|
+
},
|
|
2320
|
+
outputFolder,
|
|
2321
|
+
cacheFolder,
|
|
2322
|
+
exampleFolders,
|
|
2323
|
+
templateFolders,
|
|
2324
|
+
setupPath
|
|
2325
|
+
}),
|
|
2326
|
+
...this.processors
|
|
2327
|
+
];
|
|
2328
|
+
compileProcessorRuntime(this, (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.src || new URL('index.js', document.baseURI).href)), processors);
|
|
2329
|
+
const context = createContext();
|
|
2330
|
+
const generatedFiles = [
|
|
2331
|
+
await stage("generate-docs", context, processors),
|
|
2332
|
+
await stage("generate-nav", context, processors),
|
|
2333
|
+
await stage("assets", context, processors),
|
|
2334
|
+
await stage("render", context, processors)
|
|
2335
|
+
];
|
|
2336
|
+
return generatedFiles.flat();
|
|
2202
2337
|
}
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
}),
|
|
2215
|
-
pr,
|
|
2216
|
-
prUrl
|
|
2217
|
-
};
|
|
2218
|
-
}
|
|
2219
|
-
function getBuildDatetime() {
|
|
2220
|
-
const date = /* @__PURE__ */ new Date();
|
|
2221
|
-
return {
|
|
2222
|
-
date: date.toLocaleDateString("sv-SE"),
|
|
2223
|
-
time: date.toLocaleTimeString("sv-SE")
|
|
2224
|
-
};
|
|
2225
|
-
}
|
|
2226
|
-
function versionProcessor(pkg, container, options) {
|
|
2227
|
-
const { enabled = true, scm = false } = options ?? {};
|
|
2228
|
-
return {
|
|
2229
|
-
name: "version-processor",
|
|
2230
|
-
after: "generate-docs",
|
|
2231
|
-
async handler(context) {
|
|
2232
|
-
if (!enabled) {
|
|
2233
|
-
return;
|
|
2338
|
+
/**
|
|
2339
|
+
* Start a development server hosting the generated documentation.
|
|
2340
|
+
*/
|
|
2341
|
+
serve() {
|
|
2342
|
+
const { outputFolder, sourceFiles } = this;
|
|
2343
|
+
const watch = sourceFiles.map((it) => it.include).flat();
|
|
2344
|
+
return serve({
|
|
2345
|
+
outputFolder,
|
|
2346
|
+
watch,
|
|
2347
|
+
rebuild: (_filePath) => {
|
|
2348
|
+
return this.build(sourceFiles);
|
|
2234
2349
|
}
|
|
2235
|
-
|
|
2236
|
-
const buildData = getBuildDatetime();
|
|
2237
|
-
const data = {
|
|
2238
|
-
pkg,
|
|
2239
|
-
scm: scmData,
|
|
2240
|
-
build: buildData
|
|
2241
|
-
};
|
|
2242
|
-
context.addTemplateBlock(container, "version", {
|
|
2243
|
-
filename: "partials/version.njk.html",
|
|
2244
|
-
data
|
|
2245
|
-
});
|
|
2246
|
-
}
|
|
2247
|
-
};
|
|
2248
|
-
}
|
|
2249
|
-
|
|
2250
|
-
function sourceUrlProcessor(options) {
|
|
2251
|
-
const {
|
|
2252
|
-
enabled = true,
|
|
2253
|
-
urlFormat,
|
|
2254
|
-
componentFileExtension = "vue"
|
|
2255
|
-
} = options;
|
|
2256
|
-
function componentSourceUrl(component) {
|
|
2257
|
-
const filename = component.source ?? `${component.name}.${componentFileExtension}`;
|
|
2258
|
-
const path = getExampleImport(["./"], filename);
|
|
2259
|
-
return interpolate(urlFormat, { path });
|
|
2350
|
+
});
|
|
2260
2351
|
}
|
|
2261
|
-
|
|
2262
|
-
|
|
2263
|
-
|
|
2264
|
-
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
}
|
|
2268
|
-
context.setTemplateData("componentSourceUrl", componentSourceUrl);
|
|
2269
|
-
}
|
|
2270
|
-
};
|
|
2271
|
-
}
|
|
2272
|
-
|
|
2273
|
-
function cookieProcessor(options = {}) {
|
|
2274
|
-
const { enabled = true } = options;
|
|
2275
|
-
return {
|
|
2276
|
-
after: "generate-docs",
|
|
2277
|
-
name: "cookie-processor",
|
|
2278
|
-
async handler(context) {
|
|
2279
|
-
if (!enabled) {
|
|
2280
|
-
return;
|
|
2281
|
-
}
|
|
2282
|
-
context.addTemplateBlock("body:begin", "cookie-warning", {
|
|
2283
|
-
filename: "partials/cookie-warning.html"
|
|
2284
|
-
});
|
|
2352
|
+
async _prepareFolders() {
|
|
2353
|
+
const { outputFolder, cacheFolder, assetFolder } = this;
|
|
2354
|
+
await fs.rm(cacheFolder, { force: true, recursive: true });
|
|
2355
|
+
if (fs$1.existsSync(outputFolder)) {
|
|
2356
|
+
await fs.mkdir(path.dirname(cacheFolder), { recursive: true });
|
|
2357
|
+
await vendor.fse.copy(outputFolder, cacheFolder);
|
|
2358
|
+
await fs.rm(outputFolder, { recursive: true });
|
|
2285
2359
|
}
|
|
2286
|
-
|
|
2360
|
+
await fs.mkdir(outputFolder, { recursive: true });
|
|
2361
|
+
await fs.mkdir(assetFolder, { recursive: true });
|
|
2362
|
+
await fs.mkdir("temp", { recursive: true });
|
|
2363
|
+
}
|
|
2287
2364
|
}
|
|
2288
2365
|
|
|
2289
2366
|
function generateIndex(entries) {
|
|
@@ -2375,6 +2452,7 @@ function searchProcessor() {
|
|
|
2375
2452
|
}
|
|
2376
2453
|
|
|
2377
2454
|
exports.Generator = Generator;
|
|
2455
|
+
exports.availableProcessors = availableProcessors;
|
|
2378
2456
|
exports.cookieProcessor = cookieProcessor;
|
|
2379
2457
|
exports.defineSources = defineSources;
|
|
2380
2458
|
exports.frontMatterFileReader = frontMatterFileReader;
|
|
@@ -2383,6 +2461,7 @@ exports.manifestProcessor = manifestProcessor;
|
|
|
2383
2461
|
exports.matomoProcessor = matomoProcessor;
|
|
2384
2462
|
exports.motdProcessor = motdProcessor;
|
|
2385
2463
|
exports.navigationFileReader = navigationFileReader;
|
|
2464
|
+
exports.processorRuntimeName = processorRuntimeName;
|
|
2386
2465
|
exports.searchProcessor = searchProcessor;
|
|
2387
2466
|
exports.selectableVersionProcessor = selectableVersionProcessor;
|
|
2388
2467
|
exports.sourceUrlProcessor = sourceUrlProcessor;
|