@forsakringskassan/docs-generator 1.27.0 → 1.29.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.
@@ -1,37 +1,37 @@
1
1
  'use strict';
2
2
 
3
- var fs$1 = require('node:fs');
4
3
  var fs = require('node:fs/promises');
5
4
  var path = require('node:path');
6
- var vendor = require('./vendor-Dmnzl4fQ.js');
5
+ var vendor = require('./vendor-uab7h6x-.js');
6
+ var createMarkdownRenderer = require('./create-markdown-renderer-D1cATjO1.js');
7
7
  var require$$1 = require('crypto');
8
8
  require('node:crypto');
9
+ var vueDocgenApi = require('vue-docgen-api');
9
10
  var path$1 = require('node:path/posix');
11
+ var fs$1 = require('node:fs');
10
12
  var sass = require('sass');
11
13
  var node_url = require('node:url');
12
- var createMarkdownRenderer = require('./create-markdown-renderer--V6N9Daq.js');
13
14
  var esbuild = require('esbuild');
14
- var vueDocgenApi = require('vue-docgen-api');
15
15
  var node_util = require('node:util');
16
16
  var nunjucks = require('nunjucks');
17
17
  var vue = require('vue');
18
- var vue2 = require('./vue2-DYKDshbg.js');
19
- var vue3 = require('./vue3-CEA3zw16.js');
18
+ var vue2 = require('./vue2-CBDrnmVO.js');
19
+ var vue3 = require('./vue3-xJIC7Aol.js');
20
20
  var express = require('express');
21
- require('fs');
22
- require('constants');
23
- require('stream');
24
- require('util');
25
- require('assert');
21
+ var childProcess = require('node:child_process');
26
22
  require('path');
27
23
  require('url');
24
+ require('fs');
28
25
  require('fs/promises');
29
26
  require('events');
27
+ require('stream');
30
28
  require('string_decoder');
29
+ require('constants');
30
+ require('util');
31
+ require('assert');
31
32
  require('readline');
32
33
  require('child_process');
33
34
  require('node:buffer');
34
- require('node:child_process');
35
35
  require('node:process');
36
36
  require('node:os');
37
37
  require('node:timers/promises');
@@ -46,6 +46,10 @@ require('tls');
46
46
  require('tty');
47
47
  require('querystring');
48
48
 
49
+ function defineSources(sources) {
50
+ return sources;
51
+ }
52
+
49
53
  function formatSize(value) {
50
54
  const suffices = ["kB", "MB"];
51
55
  if (value < 1e3) {
@@ -106,6 +110,13 @@ function haveOutput(doc) {
106
110
  return Boolean(fileInfo.outputName);
107
111
  }
108
112
 
113
+ function interpolate(value, data) {
114
+ return value.replace(/{{([^}]+)}}/g, (match, raw) => {
115
+ const key = raw.trim();
116
+ return data[key] ?? match;
117
+ });
118
+ }
119
+
109
120
  function parseImport(raw) {
110
121
  const comments = [];
111
122
  const stripped = raw.replace(/<!--.*?-->/gms, (match) => {
@@ -158,214 +169,7 @@ function slugify(value) {
158
169
  return value.toLowerCase().replace(/\//g, "--").replace(/[^a-z]+/g, "-").replace(/(^-+|-+$)/, "");
159
170
  }
160
171
 
161
- function resolveScssImport(filePath) {
162
- const { dir, base } = path$1.parse(filePath);
163
- const search = [`${base}.css`, `${base}.scss`, `_${base}.scss`, `${base}`];
164
- for (const variant of search) {
165
- try {
166
- const moduleName = path$1.join(dir, variant);
167
- const resolved = require.resolve(moduleName);
168
- return node_url.pathToFileURL(resolved);
169
- } catch (err) {
170
- if (err.code !== "MODULE_NOT_FOUND") {
171
- throw err;
172
- }
173
- }
174
- }
175
- throw new Error(`Failed to resolve "${filePath}"`);
176
- }
177
- const tildeImporter = {
178
- canonicalize(url) {
179
- const indexOfTilde = url.indexOf("~");
180
- if (indexOfTilde >= 0) {
181
- return resolveScssImport(url.slice(indexOfTilde + 1));
182
- }
183
- if (url.startsWith("file://")) {
184
- const path$1 = node_url.fileURLToPath(url);
185
- const relative = path.isAbsolute(path$1) ? path.relative(__dirname, path$1) : path$1;
186
- return resolveScssImport(relative.replace(/\\/g, "/"));
187
- }
188
- return null;
189
- },
190
- async load(url) {
191
- const filepath = node_url.fileURLToPath(url);
192
- const parsed = path.parse(filepath);
193
- const contents = await fs.readFile(filepath, "utf-8");
194
- return {
195
- contents,
196
- syntax: parsed.ext.slice(1) === "scss" ? "scss" : "css"
197
- };
198
- }
199
- };
200
-
201
- async function compileSassString(dst, style) {
202
- const result = await sass.compileStringAsync(style, {
203
- style: "expanded",
204
- importers: [tildeImporter]
205
- });
206
- await fs.mkdir(path.dirname(dst), { recursive: true });
207
- await fs.writeFile(dst, result.css, "utf-8");
208
- }
209
-
210
- async function compileStyle(assetFolder, name, src) {
211
- try {
212
- const outfile = path$1.join("temp", `asset-${name}.css`);
213
- const source = await fs.readFile(src, "utf-8");
214
- await compileSassString(outfile, source);
215
- const content = await fs.readFile(outfile, "utf-8");
216
- const fingerprint = createMarkdownRenderer.getFingerprint(content);
217
- const integrity = getIntegrity(content);
218
- const filename = `${name}-${fingerprint}.css`;
219
- const dst = path$1.join(assetFolder, filename);
220
- await fs.rename(outfile, dst);
221
- const stat = await fs.stat(dst);
222
- return {
223
- name,
224
- filename,
225
- publicPath: `./assets/${filename}`,
226
- integrity,
227
- size: stat.size,
228
- type: "css"
229
- };
230
- } catch (err) {
231
- console.error(err);
232
- throw new Error(`Failed to compile style "${name}"`);
233
- }
234
- }
235
-
236
- function cssAssetProcessor(assetFolder, assets) {
237
- return {
238
- name: "css-asset-processor",
239
- after: "assets",
240
- async handler(context) {
241
- const assetInfo = context.getTemplateData("assets") ?? {};
242
- const head = context.getTemplateData("injectHead") ?? [];
243
- const body = context.getTemplateData("injectBody") ?? [];
244
- for (const asset of assets) {
245
- const info = await compileStyle(
246
- assetFolder,
247
- asset.name,
248
- asset.src
249
- );
250
- const attrs = serializeAttrs(asset.options.attributes);
251
- const inject = { ...info, attrs: Array.from(attrs).join(" ") };
252
- assetInfo[asset.name] = info;
253
- switch (asset.options.appendTo) {
254
- case "none":
255
- break;
256
- case "head":
257
- head.push(inject);
258
- break;
259
- case "body":
260
- body.push(inject);
261
- break;
262
- }
263
- context.setTemplateData("injectHead", head);
264
- context.setTemplateData("injectBody", body);
265
- context.log(info.filename, formatSize(info.size));
266
- }
267
- context.setTemplateData("assets", assetInfo);
268
- }
269
- };
270
- }
271
-
272
172
  function toArray$3(value) {
273
- if (Array.isArray(value)) {
274
- return value;
275
- } else {
276
- return [value];
277
- }
278
- }
279
- async function compileScript(assetFolder, name, src, options) {
280
- const iconLib = process.env.DOCS_ICON_LIB ?? "@fkui/icon-lib-default";
281
- try {
282
- const outfile = path.join("temp", `asset-${name}.js`);
283
- await esbuild.build({
284
- entryPoints: toArray$3(src),
285
- outfile,
286
- bundle: true,
287
- format: "iife",
288
- platform: "browser",
289
- external: ["vue", "@fkui/vue"],
290
- tsconfig: path.join(__dirname, "../tsconfig-examples.json"),
291
- define: {
292
- "process.env.DOCS_ICON_LIB": JSON.stringify(iconLib)
293
- },
294
- ...options
295
- });
296
- const content = await fs.readFile(outfile, "utf-8");
297
- const fingerprint = createMarkdownRenderer.getFingerprint(content);
298
- const integrity = getIntegrity(content);
299
- const filename = `${name}-${fingerprint}.js`;
300
- const dst = path.join(assetFolder, filename);
301
- await fs.rename(outfile, dst);
302
- const stat = await fs.stat(dst);
303
- return {
304
- name,
305
- filename,
306
- publicPath: `./assets/${filename}`,
307
- integrity,
308
- size: stat.size,
309
- type: "js"
310
- };
311
- } catch {
312
- throw new Error(`Failed to compile script "${name}"`);
313
- }
314
- }
315
-
316
- function jsAssetProcessor(assetFolder, assets) {
317
- return {
318
- name: "js-asset-processor",
319
- after: "assets",
320
- async handler(context) {
321
- const assetInfo = context.getTemplateData("assets") ?? {};
322
- const head = context.getTemplateData("injectHead") ?? [];
323
- const body = context.getTemplateData("injectBody") ?? [];
324
- for (const asset of assets) {
325
- const info = await compileScript(
326
- assetFolder,
327
- asset.name,
328
- asset.src
329
- );
330
- const attrs = serializeAttrs(asset.options.attributes);
331
- const inject = { ...info, attrs: Array.from(attrs).join(" ") };
332
- assetInfo[asset.name] = info;
333
- switch (asset.options.appendTo) {
334
- case "none":
335
- break;
336
- case "head":
337
- head.push(inject);
338
- break;
339
- case "body":
340
- body.push(inject);
341
- break;
342
- }
343
- context.setTemplateData("injectHead", head);
344
- context.setTemplateData("injectBody", body);
345
- context.log(info.filename, formatSize(info.size));
346
- }
347
- }
348
- };
349
- }
350
-
351
- function staticResourcesProcessor(assetFolder, resources) {
352
- return {
353
- name: "static-resources-processor",
354
- after: "render",
355
- async handler(context) {
356
- for (const resource of [...resources, ...context.resources]) {
357
- const src = resource.from;
358
- const dst = path$1.join(assetFolder, resource.to);
359
- await fs.cp(src, dst, {
360
- recursive: true
361
- });
362
- context.log(src, "->", dst);
363
- }
364
- }
365
- };
366
- }
367
-
368
- function toArray$2(value) {
369
173
  return Array.isArray(value) ? value : [value];
370
174
  }
371
175
  function isIndexPage(parsed) {
@@ -401,7 +205,7 @@ function getBadge(attrs) {
401
205
  }
402
206
  function getComponentAlias(attrs) {
403
207
  if (attrs.component) {
404
- return toArray$2(attrs.component).map((it) => `component:${it}`);
208
+ return toArray$3(attrs.component).map((it) => `component:${it}`);
405
209
  } else {
406
210
  return [];
407
211
  }
@@ -416,6 +220,7 @@ function parseFile$1(filePath, basePath, content) {
416
220
  const name = attributes.name ? attributes.name : parsed.name;
417
221
  const urlpath = parsed.dir;
418
222
  const outline = getDocumentOutline(blocks.body);
223
+ const include = attributes.include ?? true;
419
224
  return {
420
225
  id: `fs:${filePath.replace(/\\/g, "/")}`,
421
226
  name,
@@ -426,7 +231,7 @@ function parseFile$1(filePath, basePath, content) {
426
231
  layout: attributes.layout,
427
232
  status: attributes.status,
428
233
  badge: getBadge(attributes),
429
- component: attributes.component ? toArray$2(attributes.component) : void 0,
234
+ component: attributes.component ? toArray$3(attributes.component) : void 0,
430
235
  sortorder: attributes.sortorder ?? Infinity
431
236
  },
432
237
  body: blocks.body,
@@ -438,7 +243,7 @@ function parseFile$1(filePath, basePath, content) {
438
243
  path: ["", "."].includes(urlpath) ? "." : `./${createMarkdownRenderer.normalizePath(urlpath)}`,
439
244
  name: filename,
440
245
  fullPath: createMarkdownRenderer.normalizePath(filePath),
441
- outputName: `${filename}.html`
246
+ outputName: include ? `${filename}.html` : false
442
247
  }
443
248
  };
444
249
  }
@@ -698,25 +503,232 @@ async function navigationFileReader(filePath, basePath) {
698
503
  return [doc];
699
504
  }
700
505
 
701
- function getExampleImport(searchDirs, filename) {
702
- const pattern = searchDirs.map((dir) => `${dir}/**/${filename}`);
703
- const matches = vendor.globSync(pattern);
704
- if (matches.length === 0) {
705
- const message = `No files matched import "${filename}"`;
706
- throw new Error(message);
707
- } else if (matches.length > 1) {
708
- const message = `Multiple files matched import "${filename}"`;
709
- throw new Error(message);
710
- } else {
711
- return createMarkdownRenderer.normalizePath(matches[0]);
506
+ function resolveScssImport(filePath) {
507
+ const { dir, base } = path$1.parse(filePath);
508
+ const search = [`${base}.css`, `${base}.scss`, `_${base}.scss`, `${base}`];
509
+ for (const variant of search) {
510
+ try {
511
+ const moduleName = path$1.join(dir, variant);
512
+ const resolved = require.resolve(moduleName);
513
+ return node_url.pathToFileURL(resolved);
514
+ } catch (err) {
515
+ if (err.code !== "MODULE_NOT_FOUND") {
516
+ throw err;
517
+ }
518
+ }
712
519
  }
520
+ throw new Error(`Failed to resolve "${filePath}"`);
713
521
  }
714
-
715
- function getExampleName(filename) {
716
- return path.parse(filename).name;
717
- }
718
-
719
- const vueMajor = parseInt(vue.version.split(".", 2)[0], 10);
522
+ const tildeImporter = {
523
+ canonicalize(url) {
524
+ const indexOfTilde = url.indexOf("~");
525
+ if (indexOfTilde >= 0) {
526
+ return resolveScssImport(url.slice(indexOfTilde + 1));
527
+ }
528
+ if (url.startsWith("file://")) {
529
+ const path$1 = node_url.fileURLToPath(url);
530
+ const relative = path.isAbsolute(path$1) ? path.relative(__dirname, path$1) : path$1;
531
+ return resolveScssImport(relative.replace(/\\/g, "/"));
532
+ }
533
+ return null;
534
+ },
535
+ async load(url) {
536
+ const filepath = node_url.fileURLToPath(url);
537
+ const parsed = path.parse(filepath);
538
+ const contents = await fs.readFile(filepath, "utf-8");
539
+ return {
540
+ contents,
541
+ syntax: parsed.ext.slice(1) === "scss" ? "scss" : "css"
542
+ };
543
+ }
544
+ };
545
+
546
+ async function compileSassString(dst, style) {
547
+ const result = await sass.compileStringAsync(style, {
548
+ style: "expanded",
549
+ importers: [tildeImporter]
550
+ });
551
+ await fs.mkdir(path.dirname(dst), { recursive: true });
552
+ await fs.writeFile(dst, result.css, "utf-8");
553
+ }
554
+
555
+ async function compileStyle(assetFolder, name, src) {
556
+ try {
557
+ const outfile = path$1.join("temp", `asset-${name}.css`);
558
+ const source = await fs.readFile(src, "utf-8");
559
+ await compileSassString(outfile, source);
560
+ const content = await fs.readFile(outfile, "utf-8");
561
+ const fingerprint = createMarkdownRenderer.getFingerprint(content);
562
+ const integrity = getIntegrity(content);
563
+ const filename = `${name}-${fingerprint}.css`;
564
+ const dst = path$1.join(assetFolder, filename);
565
+ await fs.rename(outfile, dst);
566
+ const stat = await fs.stat(dst);
567
+ return {
568
+ name,
569
+ filename,
570
+ publicPath: `./assets/${filename}`,
571
+ integrity,
572
+ size: stat.size,
573
+ type: "css"
574
+ };
575
+ } catch (err) {
576
+ console.error(err);
577
+ throw new Error(`Failed to compile style "${name}"`);
578
+ }
579
+ }
580
+
581
+ function cssAssetProcessor(assetFolder, assets) {
582
+ return {
583
+ name: "css-asset-processor",
584
+ after: "assets",
585
+ async handler(context) {
586
+ const assetInfo = context.getTemplateData("assets") ?? {};
587
+ const head = context.getTemplateData("injectHead") ?? [];
588
+ const body = context.getTemplateData("injectBody") ?? [];
589
+ for (const asset of assets) {
590
+ const info = await compileStyle(
591
+ assetFolder,
592
+ asset.name,
593
+ asset.src
594
+ );
595
+ const attrs = serializeAttrs(asset.options.attributes);
596
+ const inject = { ...info, attrs: Array.from(attrs).join(" ") };
597
+ assetInfo[asset.name] = info;
598
+ switch (asset.options.appendTo) {
599
+ case "none":
600
+ break;
601
+ case "head":
602
+ head.push(inject);
603
+ break;
604
+ case "body":
605
+ body.push(inject);
606
+ break;
607
+ }
608
+ context.setTemplateData("injectHead", head);
609
+ context.setTemplateData("injectBody", body);
610
+ context.log(info.filename, formatSize(info.size));
611
+ }
612
+ context.setTemplateData("assets", assetInfo);
613
+ }
614
+ };
615
+ }
616
+
617
+ function toArray$2(value) {
618
+ if (Array.isArray(value)) {
619
+ return value;
620
+ } else {
621
+ return [value];
622
+ }
623
+ }
624
+ async function compileScript(assetFolder, name, src, options) {
625
+ const iconLib = process.env.DOCS_ICON_LIB ?? "@fkui/icon-lib-default";
626
+ try {
627
+ const outfile = path.join("temp", `asset-${name}.js`);
628
+ await esbuild.build({
629
+ entryPoints: toArray$2(src),
630
+ outfile,
631
+ bundle: true,
632
+ format: "iife",
633
+ platform: "browser",
634
+ external: ["vue", "@fkui/vue"],
635
+ tsconfig: path.join(__dirname, "../tsconfig-examples.json"),
636
+ define: {
637
+ "process.env.DOCS_ICON_LIB": JSON.stringify(iconLib)
638
+ },
639
+ ...options
640
+ });
641
+ const content = await fs.readFile(outfile, "utf-8");
642
+ const fingerprint = createMarkdownRenderer.getFingerprint(content);
643
+ const integrity = getIntegrity(content);
644
+ const filename = `${name}-${fingerprint}.js`;
645
+ const dst = path.join(assetFolder, filename);
646
+ await fs.rename(outfile, dst);
647
+ const stat = await fs.stat(dst);
648
+ return {
649
+ name,
650
+ filename,
651
+ publicPath: `./assets/${filename}`,
652
+ integrity,
653
+ size: stat.size,
654
+ type: "js"
655
+ };
656
+ } catch {
657
+ throw new Error(`Failed to compile script "${name}"`);
658
+ }
659
+ }
660
+
661
+ function jsAssetProcessor(assetFolder, assets) {
662
+ return {
663
+ name: "js-asset-processor",
664
+ after: "assets",
665
+ async handler(context) {
666
+ const assetInfo = context.getTemplateData("assets") ?? {};
667
+ const head = context.getTemplateData("injectHead") ?? [];
668
+ const body = context.getTemplateData("injectBody") ?? [];
669
+ for (const asset of assets) {
670
+ const info = await compileScript(
671
+ assetFolder,
672
+ asset.name,
673
+ asset.src
674
+ );
675
+ const attrs = serializeAttrs(asset.options.attributes);
676
+ const inject = { ...info, attrs: Array.from(attrs).join(" ") };
677
+ assetInfo[asset.name] = info;
678
+ switch (asset.options.appendTo) {
679
+ case "none":
680
+ break;
681
+ case "head":
682
+ head.push(inject);
683
+ break;
684
+ case "body":
685
+ body.push(inject);
686
+ break;
687
+ }
688
+ context.setTemplateData("injectHead", head);
689
+ context.setTemplateData("injectBody", body);
690
+ context.log(info.filename, formatSize(info.size));
691
+ }
692
+ }
693
+ };
694
+ }
695
+
696
+ function staticResourcesProcessor(assetFolder, resources) {
697
+ return {
698
+ name: "static-resources-processor",
699
+ after: "render",
700
+ async handler(context) {
701
+ for (const resource of [...resources, ...context.resources]) {
702
+ const src = resource.from;
703
+ const dst = path$1.join(assetFolder, resource.to);
704
+ await fs.cp(src, dst, {
705
+ recursive: true
706
+ });
707
+ context.log(src, "->", dst);
708
+ }
709
+ }
710
+ };
711
+ }
712
+
713
+ function getExampleImport(searchDirs, filename) {
714
+ const pattern = searchDirs.map((dir) => `${dir}/**/${filename}`);
715
+ const matches = vendor.globSync(pattern);
716
+ if (matches.length === 0) {
717
+ const message = `No files matched import "${filename}"`;
718
+ throw new Error(message);
719
+ } else if (matches.length > 1) {
720
+ const message = `Multiple files matched import "${filename}"`;
721
+ throw new Error(message);
722
+ } else {
723
+ return createMarkdownRenderer.normalizePath(matches[0]);
724
+ }
725
+ }
726
+
727
+ function getExampleName(filename) {
728
+ return path.parse(filename).name;
729
+ }
730
+
731
+ const vueMajor = parseInt(vue.version.split(".", 2)[0], 10);
720
732
  const vueGenerator = {
721
733
  [2]: vue2.generateCode,
722
734
  [3]: vue3.generateCode
@@ -982,6 +994,54 @@ function sortNavigationTree(tree) {
982
994
  }
983
995
  }
984
996
 
997
+ class TemplateLoader {
998
+ async = true;
999
+ folders;
1000
+ templateCache;
1001
+ constructor(folders = []) {
1002
+ this.folders = [...folders, path.join(__dirname, "../templates")];
1003
+ this.templateCache = /* @__PURE__ */ new Map();
1004
+ }
1005
+ async getSource(name, callback) {
1006
+ try {
1007
+ const { content, filePath } = await this.resolveTemplate(name);
1008
+ callback(null, {
1009
+ src: content,
1010
+ path: filePath,
1011
+ noCache: false
1012
+ });
1013
+ } catch (err) {
1014
+ if (err instanceof Error) {
1015
+ callback(err, null);
1016
+ } else {
1017
+ callback(new Error(String(err)), null);
1018
+ }
1019
+ }
1020
+ }
1021
+ async resolveTemplate(name) {
1022
+ const { templateCache, folders } = this;
1023
+ const cached = templateCache.get(name);
1024
+ if (cached) {
1025
+ return cached;
1026
+ }
1027
+ const searchPaths = folders.map((it) => path.join(it, name));
1028
+ const filePath = searchPaths.find((it) => fs$1.existsSync(it));
1029
+ if (!filePath) {
1030
+ const searched = folders.map((it) => ` - "${it}"`).join("\n");
1031
+ const message = `Failed to resolve template "${name}", searched in:
1032
+
1033
+ ${searched}
1034
+
1035
+ Make sure the name is correct and the template file exists in one of the listed directories.`;
1036
+ throw new Error(message);
1037
+ }
1038
+ const content = await fs.readFile(filePath, "utf-8");
1039
+ const resolved = { content, filePath };
1040
+ templateCache.set(name, resolved);
1041
+ return resolved;
1042
+ }
1043
+ }
1044
+
985
1045
  function dump(value) {
986
1046
  return `<pre>${JSON.stringify(value, null, 2)}</pre>`;
987
1047
  }
@@ -1065,53 +1125,6 @@ function findTemplate(from, src, format) {
1065
1125
  return template;
1066
1126
  }
1067
1127
 
1068
- class Loader {
1069
- async = true;
1070
- folders;
1071
- templateCache;
1072
- constructor(folders) {
1073
- this.folders = [...folders, path.join(__dirname, "../templates")];
1074
- this.templateCache = /* @__PURE__ */ new Map();
1075
- }
1076
- async getSource(name, callback) {
1077
- try {
1078
- const { content, filePath } = await this.resolveTemplate(name);
1079
- callback(null, {
1080
- src: content,
1081
- path: filePath,
1082
- noCache: false
1083
- });
1084
- } catch (err) {
1085
- if (err instanceof Error) {
1086
- callback(err, null);
1087
- } else {
1088
- callback(new Error(String(err)), null);
1089
- }
1090
- }
1091
- }
1092
- async resolveTemplate(name) {
1093
- const { templateCache, folders } = this;
1094
- const cached = templateCache.get(name);
1095
- if (cached) {
1096
- return cached;
1097
- }
1098
- const searchPaths = folders.map((it) => path.join(it, name));
1099
- const filePath = searchPaths.find((it) => fs$1.existsSync(it));
1100
- if (!filePath) {
1101
- const searched = folders.map((it) => ` - "${it}"`).join("\n");
1102
- const message = `Failed to resolve template "${name}", searched in:
1103
-
1104
- ${searched}
1105
-
1106
- Make sure the name is correct and the template file exists in one of the listed directories.`;
1107
- throw new Error(message);
1108
- }
1109
- const content = await fs.readFile(filePath, "utf-8");
1110
- const resolved = { content, filePath };
1111
- templateCache.set(name, resolved);
1112
- return resolved;
1113
- }
1114
- }
1115
1128
  const scriptPath = path.join(__dirname, "compile-example.js");
1116
1129
  let loader = null;
1117
1130
  function haveOutputFile(fileInfo) {
@@ -1165,6 +1178,9 @@ async function compileExamples(options) {
1165
1178
  const outputFolder = path.posix.join(options.outputFolder, fileInfo.path);
1166
1179
  const cacheMiss = cache(cacheFolder, outputFolder);
1167
1180
  const dirtyTasks = tasks.filter(cacheMiss);
1181
+ if (dirtyTasks.length === 0) {
1182
+ return;
1183
+ }
1168
1184
  const batch = {
1169
1185
  outputFolder,
1170
1186
  external: vendors.map((it) => it.package),
@@ -1199,7 +1215,7 @@ async function compileStandalones(options) {
1199
1215
  }
1200
1216
  }
1201
1217
  function createTemplateLoader(folders) {
1202
- loader = new Loader(folders);
1218
+ loader = new TemplateLoader(folders);
1203
1219
  }
1204
1220
  async function render(doc, docs, nav, vendors, options) {
1205
1221
  const { fileInfo } = doc;
@@ -1279,9 +1295,10 @@ async function render(doc, docs, nav, vendors, options) {
1279
1295
  const blocks = options.templateBlocks.get(container) ?? [];
1280
1296
  const promises = blocks.map(({ renderer }) => {
1281
1297
  if ("filename" in renderer) {
1298
+ const data = renderer.data;
1282
1299
  return renderTemplate(renderer.filename, {
1283
1300
  ...ctx,
1284
- ...renderer.data
1301
+ ...data
1285
1302
  });
1286
1303
  }
1287
1304
  if ("render" in renderer) {
@@ -1661,214 +1678,6 @@ async function serve(options) {
1661
1678
  function toArray$1(value) {
1662
1679
  return Array.isArray(value) ? value : [value];
1663
1680
  }
1664
- function matomoProcessor(options) {
1665
- const { enabled, siteId, apiUrl, trackerUrl, hostname } = options;
1666
- return {
1667
- after: "generate-docs",
1668
- name: "matomo-processor",
1669
- enabled,
1670
- handler(context) {
1671
- context.addTemplateBlock("head", "matomo", {
1672
- filename: "partials/matomo.html",
1673
- data: {
1674
- siteId,
1675
- apiUrl,
1676
- trackerUrl,
1677
- hostname: hostname ? toArray$1(hostname) : []
1678
- }
1679
- });
1680
- }
1681
- };
1682
- }
1683
-
1684
- function renderMarkdown(manifest) {
1685
- return [
1686
- "## Documentation manifest",
1687
- "",
1688
- "> Do not edit this file. It is a automatically generated by `@forsakringskassan/docs-generator`.",
1689
- "",
1690
- "```",
1691
- ...manifest.pages.map((it) => it.path),
1692
- "```",
1693
- ""
1694
- ].join("\n");
1695
- }
1696
- function renderJSON(manifest) {
1697
- return JSON.stringify(manifest, null, 2);
1698
- }
1699
- function manifestProcessor(options) {
1700
- const { markdown, json } = options;
1701
- return {
1702
- name: "manifestProcessor",
1703
- before: "render",
1704
- async handler(context) {
1705
- const docs = context.docs.filter(haveOutput);
1706
- const pages = docs.map(manifestPageFromDocument);
1707
- pages.sort((a, b) => {
1708
- return a.path.localeCompare(b.path);
1709
- });
1710
- const manifest = { pages };
1711
- if (markdown) {
1712
- const content = renderMarkdown(manifest);
1713
- await fs.writeFile(markdown, content, "utf-8");
1714
- }
1715
- if (json) {
1716
- const content = renderJSON(manifest);
1717
- await fs.writeFile(json, content, "utf-8");
1718
- }
1719
- }
1720
- };
1721
- }
1722
-
1723
- function themeSelectProcessor() {
1724
- return {
1725
- name: "theme-select-processor",
1726
- after: "generate-docs",
1727
- handler(context) {
1728
- context.addTemplateBlock("toolbar", "theme-select", {
1729
- filename: "partials/theme-select.html"
1730
- });
1731
- }
1732
- };
1733
- }
1734
-
1735
- function versionProcessor(pkg, container) {
1736
- return {
1737
- name: "version-processor",
1738
- after: "generate-docs",
1739
- handler(context) {
1740
- context.addTemplateBlock(container, "version", {
1741
- filename: "partials/version.html",
1742
- data: { pkg }
1743
- });
1744
- }
1745
- };
1746
- }
1747
-
1748
- function selectableVersionProcessor(pkg, container) {
1749
- return {
1750
- name: "selectable-version-processor",
1751
- after: "generate-docs",
1752
- handler(context) {
1753
- context.addTemplateBlock(container, "version", {
1754
- filename: "partials/selectable-version.html",
1755
- data: { pkg }
1756
- });
1757
- }
1758
- };
1759
- }
1760
-
1761
- function versionBannerProcessor(message, container) {
1762
- return {
1763
- name: "version-banner-processor",
1764
- after: "generate-docs",
1765
- handler(context) {
1766
- context.addTemplateBlock(container, "version-banner", {
1767
- filename: "partials/version-banner.html",
1768
- data: { message }
1769
- });
1770
- }
1771
- };
1772
- }
1773
-
1774
- function generateIndex(entries) {
1775
- const index = {
1776
- terms: [],
1777
- results: [],
1778
- mapping: {}
1779
- };
1780
- for (const entry of entries) {
1781
- index.results.push({
1782
- url: entry.url,
1783
- title: entry.title
1784
- });
1785
- const resultIndex = index.results.length - 1;
1786
- for (const word of entry.words) {
1787
- index.terms.push(word);
1788
- const termIndex = index.terms.length - 1;
1789
- index.mapping[termIndex] = resultIndex;
1790
- }
1791
- }
1792
- return index;
1793
- }
1794
-
1795
- function extractTerms(doc) {
1796
- const { title, component } = doc.attributes;
1797
- if (title && component) {
1798
- return component.map((it) => `${title} (${it})`);
1799
- } else if (component) {
1800
- return component;
1801
- } else if (title) {
1802
- return [title];
1803
- } else {
1804
- return [];
1805
- }
1806
- }
1807
- function isIndexable(doc) {
1808
- return Boolean(doc.visible && doc.fileInfo.outputName);
1809
- }
1810
- function getTerms(doc) {
1811
- return {
1812
- url: createMarkdownRenderer.getOutputFilePath(".", doc.fileInfo) ?? "",
1813
- title: doc.name,
1814
- words: extractTerms(doc)
1815
- };
1816
- }
1817
- function searchProcessor() {
1818
- return {
1819
- after: "generate-docs",
1820
- name: "search-processor",
1821
- handler(context) {
1822
- const entries = context.docs.filter(isIndexable).map(getTerms);
1823
- const index = generateIndex(entries);
1824
- const body = JSON.stringify(index);
1825
- const fingerprint = createMarkdownRenderer.getFingerprint(body);
1826
- const integrity = getIntegrity(body);
1827
- const outputName = `search-data-[hash].json`;
1828
- const expandedName = `search-data-${fingerprint}.json`;
1829
- context.setTemplateData("searchDataUrl", expandedName);
1830
- context.setTemplateData("searchDataIntegrity", integrity);
1831
- context.addDocument({
1832
- id: "search:data",
1833
- name: "search-data",
1834
- alias: [],
1835
- visible: false,
1836
- attributes: {
1837
- sortorder: Infinity
1838
- },
1839
- body,
1840
- outline: [],
1841
- format: "json",
1842
- tags: [],
1843
- template: "json",
1844
- fileInfo: {
1845
- path: "",
1846
- name: "virtual:search-data",
1847
- fullPath: "virtual:search-data",
1848
- outputName
1849
- }
1850
- });
1851
- context.addTemplateBlock("toolbar", "search-toolbar", {
1852
- filename: "partials/search-toolbar.html",
1853
- data: {
1854
- rootUrl(doc) {
1855
- const { fileInfo } = doc;
1856
- const relative = path$1.relative(fileInfo.path, ".");
1857
- return relative !== "" ? relative : ".";
1858
- }
1859
- }
1860
- });
1861
- context.addTemplateBlock("body:end", "search-dialog", {
1862
- filename: "partials/search-dialog.html"
1863
- });
1864
- context.log("Indexed", entries.length, "documents");
1865
- }
1866
- };
1867
- }
1868
-
1869
- function toArray(value) {
1870
- return Array.isArray(value) ? value : [value];
1871
- }
1872
1681
  function filterProcessors(stage2, processors) {
1873
1682
  const before = [];
1874
1683
  const during = [];
@@ -1958,10 +1767,10 @@ function createContext() {
1958
1767
  return sidenav;
1959
1768
  },
1960
1769
  addDocument(document) {
1961
- docs = [...docs, ...toArray(document)];
1770
+ docs = [...docs, ...toArray$1(document)];
1962
1771
  },
1963
1772
  addVendorAsset(asset) {
1964
- vendors = [...vendors, ...toArray(asset)];
1773
+ vendors = [...vendors, ...toArray$1(asset)];
1965
1774
  },
1966
1775
  addResource(dst, src) {
1967
1776
  resources.push({
@@ -2151,7 +1960,319 @@ class Generator {
2151
1960
  }
2152
1961
  }
2153
1962
 
1963
+ function toArray(value) {
1964
+ return Array.isArray(value) ? value : [value];
1965
+ }
1966
+ function matomoProcessor(options) {
1967
+ const { enabled, siteId, apiUrl, trackerUrl, hostname } = options;
1968
+ return {
1969
+ after: "generate-docs",
1970
+ name: "matomo-processor",
1971
+ enabled,
1972
+ handler(context) {
1973
+ context.addTemplateBlock("head", "matomo", {
1974
+ filename: "partials/matomo.html",
1975
+ data: {
1976
+ siteId,
1977
+ apiUrl,
1978
+ trackerUrl,
1979
+ hostname: hostname ? toArray(hostname) : []
1980
+ }
1981
+ });
1982
+ }
1983
+ };
1984
+ }
1985
+
1986
+ function renderMarkdown(manifest) {
1987
+ return [
1988
+ "## Documentation manifest",
1989
+ "",
1990
+ "> Do not edit this file. It is a automatically generated by `@forsakringskassan/docs-generator`.",
1991
+ "",
1992
+ "```",
1993
+ ...manifest.pages.map((it) => it.path),
1994
+ "```",
1995
+ ""
1996
+ ].join("\n");
1997
+ }
1998
+ function renderJSON(manifest) {
1999
+ return JSON.stringify(manifest, null, 2);
2000
+ }
2001
+ function manifestProcessor(options) {
2002
+ const { markdown, json } = options;
2003
+ return {
2004
+ name: "manifestProcessor",
2005
+ before: "render",
2006
+ async handler(context) {
2007
+ const docs = context.docs.filter(haveOutput);
2008
+ const pages = docs.map(manifestPageFromDocument);
2009
+ pages.sort((a, b) => {
2010
+ return a.path.localeCompare(b.path);
2011
+ });
2012
+ const manifest = { pages };
2013
+ if (markdown) {
2014
+ const content = renderMarkdown(manifest);
2015
+ await fs.writeFile(markdown, content, "utf-8");
2016
+ }
2017
+ if (json) {
2018
+ const content = renderJSON(manifest);
2019
+ await fs.writeFile(json, content, "utf-8");
2020
+ }
2021
+ }
2022
+ };
2023
+ }
2024
+
2025
+ function themeSelectProcessor() {
2026
+ return {
2027
+ name: "theme-select-processor",
2028
+ after: "generate-docs",
2029
+ handler(context) {
2030
+ context.addTemplateBlock("toolbar", "theme-select", {
2031
+ filename: "partials/theme-select.html"
2032
+ });
2033
+ }
2034
+ };
2035
+ }
2036
+
2037
+ function selectableVersionProcessor(pkg, container) {
2038
+ return {
2039
+ name: "selectable-version-processor",
2040
+ after: "generate-docs",
2041
+ handler(context) {
2042
+ context.addTemplateBlock(container, "version", {
2043
+ filename: "partials/selectable-version.html",
2044
+ data: { pkg }
2045
+ });
2046
+ }
2047
+ };
2048
+ }
2049
+
2050
+ function generateNavigation(entries) {
2051
+ const children = entries.map((it, index) => {
2052
+ const key = path$1.parse(it.path).name;
2053
+ return {
2054
+ key,
2055
+ sortorder: index,
2056
+ children: [],
2057
+ ...it
2058
+ };
2059
+ });
2060
+ return {
2061
+ key: ".",
2062
+ path: "./index.html",
2063
+ sortorder: Infinity,
2064
+ children
2065
+ };
2066
+ }
2067
+ function topnavProcessor(filename, title) {
2068
+ return {
2069
+ after: "generate-nav",
2070
+ name: "topnav-processor",
2071
+ async handler(context) {
2072
+ const content = await fs.readFile(filename, "utf-8");
2073
+ const parsed = JSON.parse(content);
2074
+ const rootNode = generateNavigation(parsed);
2075
+ context.setTopNavigation({
2076
+ title,
2077
+ ...rootNode
2078
+ });
2079
+ }
2080
+ };
2081
+ }
2082
+
2083
+ function run(cmd, defaultValue) {
2084
+ return new Promise((resolve) => {
2085
+ childProcess.exec(cmd, { encoding: "utf-8" }, (error, stdout) => {
2086
+ if (error) {
2087
+ console.error(error);
2088
+ resolve(defaultValue);
2089
+ } else {
2090
+ resolve(stdout.trim());
2091
+ }
2092
+ });
2093
+ });
2094
+ }
2095
+ async function getGitBranch() {
2096
+ const { CHANGE_BRANCH, CHANGE_NAME } = process.env;
2097
+ if (CHANGE_BRANCH) {
2098
+ return CHANGE_BRANCH;
2099
+ }
2100
+ if (CHANGE_NAME) {
2101
+ return CHANGE_NAME;
2102
+ }
2103
+ const branch = await run("git rev-parse --abbrev-ref HEAD", "unknown");
2104
+ if (branch === "HEAD" || branch === "") {
2105
+ return "unknown";
2106
+ } else {
2107
+ return branch;
2108
+ }
2109
+ }
2110
+ function getPullRequestID() {
2111
+ return process.env.JOB_BASE_NAME;
2112
+ }
2113
+ async function getSCMData(pkg, options) {
2114
+ const commitHash = await run(`git rev-parse HEAD`);
2115
+ const commitShort = await run(`git rev-parse --short HEAD`);
2116
+ if (!commitHash || !commitShort) {
2117
+ return null;
2118
+ }
2119
+ const { homepage } = pkg;
2120
+ const pr = getPullRequestID();
2121
+ const prUrl = pr ? interpolate(options.prUrlFormat, { homepage, pr }) : void 0;
2122
+ return {
2123
+ branch: await getGitBranch(),
2124
+ commitShort,
2125
+ commitHash,
2126
+ commitUrl: interpolate(options.commitUrlFormat, {
2127
+ hash: commitHash,
2128
+ short: commitShort,
2129
+ homepage
2130
+ }),
2131
+ pr,
2132
+ prUrl
2133
+ };
2134
+ }
2135
+ function getBuildDatetime() {
2136
+ const date = /* @__PURE__ */ new Date();
2137
+ return {
2138
+ date: date.toLocaleDateString("sv-SE"),
2139
+ time: date.toLocaleTimeString("sv-SE")
2140
+ };
2141
+ }
2142
+ function versionProcessor(pkg, container, options) {
2143
+ const { enabled = true, scm = false } = options ?? {};
2144
+ return {
2145
+ name: "version-processor",
2146
+ after: "generate-docs",
2147
+ async handler(context) {
2148
+ if (!enabled) {
2149
+ return;
2150
+ }
2151
+ const scmData = scm ? await getSCMData(pkg, scm) : null;
2152
+ const buildData = getBuildDatetime();
2153
+ const data = {
2154
+ pkg,
2155
+ scm: scmData,
2156
+ build: buildData
2157
+ };
2158
+ context.addTemplateBlock(container, "version", {
2159
+ filename: "partials/version.njk.html",
2160
+ data
2161
+ });
2162
+ }
2163
+ };
2164
+ }
2165
+
2166
+ function versionBannerProcessor(message, container) {
2167
+ return {
2168
+ name: "version-banner-processor",
2169
+ after: "generate-docs",
2170
+ handler(context) {
2171
+ context.addTemplateBlock(container, "version-banner", {
2172
+ filename: "partials/version-banner.html",
2173
+ data: { message }
2174
+ });
2175
+ }
2176
+ };
2177
+ }
2178
+
2179
+ function generateIndex(entries) {
2180
+ const index = {
2181
+ terms: [],
2182
+ results: [],
2183
+ mapping: {}
2184
+ };
2185
+ for (const entry of entries) {
2186
+ index.results.push({
2187
+ url: entry.url,
2188
+ title: entry.title
2189
+ });
2190
+ const resultIndex = index.results.length - 1;
2191
+ for (const word of entry.words) {
2192
+ index.terms.push(word);
2193
+ const termIndex = index.terms.length - 1;
2194
+ index.mapping[termIndex] = resultIndex;
2195
+ }
2196
+ }
2197
+ return index;
2198
+ }
2199
+
2200
+ function extractTerms(doc) {
2201
+ const { title, component } = doc.attributes;
2202
+ if (title && component) {
2203
+ return component.map((it) => `${title} (${it})`);
2204
+ } else if (component) {
2205
+ return component;
2206
+ } else if (title) {
2207
+ return [title];
2208
+ } else {
2209
+ return [];
2210
+ }
2211
+ }
2212
+ function isIndexable(doc) {
2213
+ return Boolean(doc.visible && doc.fileInfo.outputName);
2214
+ }
2215
+ function getTerms(doc) {
2216
+ return {
2217
+ url: createMarkdownRenderer.getOutputFilePath(".", doc.fileInfo) ?? "",
2218
+ title: doc.name,
2219
+ words: extractTerms(doc)
2220
+ };
2221
+ }
2222
+ function searchProcessor() {
2223
+ return {
2224
+ after: "generate-docs",
2225
+ name: "search-processor",
2226
+ handler(context) {
2227
+ const entries = context.docs.filter(isIndexable).map(getTerms);
2228
+ const index = generateIndex(entries);
2229
+ const body = JSON.stringify(index);
2230
+ const fingerprint = createMarkdownRenderer.getFingerprint(body);
2231
+ const integrity = getIntegrity(body);
2232
+ const outputName = `search-data-[hash].json`;
2233
+ const expandedName = `search-data-${fingerprint}.json`;
2234
+ context.setTemplateData("searchDataUrl", expandedName);
2235
+ context.setTemplateData("searchDataIntegrity", integrity);
2236
+ context.addDocument({
2237
+ id: "search:data",
2238
+ name: "search-data",
2239
+ alias: [],
2240
+ visible: false,
2241
+ attributes: {
2242
+ sortorder: Infinity
2243
+ },
2244
+ body,
2245
+ outline: [],
2246
+ format: "json",
2247
+ tags: [],
2248
+ template: "json",
2249
+ fileInfo: {
2250
+ path: "",
2251
+ name: "virtual:search-data",
2252
+ fullPath: "virtual:search-data",
2253
+ outputName
2254
+ }
2255
+ });
2256
+ context.addTemplateBlock("toolbar", "search-toolbar", {
2257
+ filename: "partials/search-toolbar.html",
2258
+ data: {
2259
+ rootUrl(doc) {
2260
+ const { fileInfo } = doc;
2261
+ const relative = path$1.relative(fileInfo.path, ".");
2262
+ return relative !== "" ? relative : ".";
2263
+ }
2264
+ }
2265
+ });
2266
+ context.addTemplateBlock("body:end", "search-dialog", {
2267
+ filename: "partials/search-dialog.html"
2268
+ });
2269
+ context.log("Indexed", entries.length, "documents");
2270
+ }
2271
+ };
2272
+ }
2273
+
2154
2274
  exports.Generator = Generator;
2275
+ exports.defineSources = defineSources;
2155
2276
  exports.frontMatterFileReader = frontMatterFileReader;
2156
2277
  exports.livereloadProcessor = livereloadProcessor;
2157
2278
  exports.manifestProcessor = manifestProcessor;
@@ -2160,6 +2281,7 @@ exports.navigationFileReader = navigationFileReader;
2160
2281
  exports.searchProcessor = searchProcessor;
2161
2282
  exports.selectableVersionProcessor = selectableVersionProcessor;
2162
2283
  exports.themeSelectProcessor = themeSelectProcessor;
2284
+ exports.topnavProcessor = topnavProcessor;
2163
2285
  exports.versionBannerProcessor = versionBannerProcessor;
2164
2286
  exports.versionProcessor = versionProcessor;
2165
2287
  exports.vueFileReader = vueFileReader;