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