@forsakringskassan/docs-generator 2.30.0 → 2.30.2

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/dist/index.mjs CHANGED
@@ -4,18 +4,18 @@ const require = $createRequire(import.meta.url);
4
4
 
5
5
  import fs from 'node:fs/promises';
6
6
  import path from 'node:path/posix';
7
- import { g as globSync, m as minimatch, M as MarkdownIt, d as dedent, b as closest, e as distance, f as fm, i as isCI, h as glob, j as moduleImporter, k as cliProgress, t as tinylr, w as watch, l as createInstance, n as fse, o as inter } from './vendor-B6t9njJr.mjs';
8
- import { g as generateId, p as parseInfostring, i as isDocumentPage, n as normalizePath, a as getFingerprint, h as hasTag, f as findTag, b as getOutputFilePath, d as htmlencode, e as exampleWorkerUrl, c as createMarkdownRenderer, j as generateExample } from './create-markdown-renderer-D5LtM0yF.mjs';
7
+ import { g as globSync, m as minimatch, M as MarkdownIt, d as dedent, b as closest, e as distance, f as fm, i as isCI, h as glob, j as moduleImporter, k as cliProgress, t as tinylr, w as watch, l as createInstance, n as fse, o as inter } from './vendor-0oN9XFM9.mjs';
8
+ import { g as generateId, p as parseInfostring, i as isDocumentPage, n as normalizePath, a as getFingerprint, h as hasTag, f as findTag, b as getOutputFilePath, d as htmlencode, e as exampleWorkerUrl, c as createMarkdownRenderer, j as generateExample } from './create-markdown-renderer-D5JN5FPy.mjs';
9
9
  import path$1 from 'node:path';
10
10
  import require$$1 from 'crypto';
11
11
  import 'node:crypto';
12
12
  import { exec } from 'node:child_process';
13
13
  import util, { promisify } from 'node:util';
14
14
  import { codeFrameColumns } from '@babel/code-frame';
15
- import { parse } from 'vue-docgen-api';
16
- import { parse as parse$2 } from '@babel/parser';
15
+ import { parse as parse$1 } from '@babel/parser';
17
16
  import traverseModule from '@babel/traverse';
18
- import { parse as parse$1, compileScript as compileScript$1, compileTemplate } from 'vue/compiler-sfc';
17
+ import { parse, compileScript as compileScript$1, compileTemplate } from 'vue/compiler-sfc';
18
+ import { parse as parse$2 } from 'vue-docgen-api';
19
19
  import fs__default, { existsSync, readFileSync, copyFileSync } from 'node:fs';
20
20
  import { fileURLToPath } from 'node:url';
21
21
  import { compileStringAsync, NodePackageImporter } from 'sass';
@@ -46,7 +46,7 @@ import 'tls';
46
46
  import 'tty';
47
47
  import 'querystring';
48
48
  import 'vue';
49
- import './vue3-CRwEnRGE.mjs';
49
+ import './vue3-Bvwupe7o.mjs';
50
50
 
51
51
  function toArray$2(value) {
52
52
  return Array.isArray(value) ? value : [value];
@@ -1117,193 +1117,213 @@ async function frontMatterFileReader(filePath, basePath) {
1117
1117
  return [doc];
1118
1118
  }
1119
1119
 
1120
- function getPropSlotDeprecated(prop) {
1121
- const tags = prop.tags;
1122
- if (!tags?.deprecated) {
1120
+ function isStringLiteral(node) {
1121
+ return node.type === "StringLiteral";
1122
+ }
1123
+ function isObjectExpression(node) {
1124
+ return node.type === "ObjectExpression";
1125
+ }
1126
+ function isDocComment(node) {
1127
+ return node.type === "CommentBlock";
1128
+ }
1129
+ function getDescription(node) {
1130
+ if (!node) {
1123
1131
  return null;
1124
1132
  }
1125
- const tag = tags.deprecated[0];
1126
- if (!tag?.description) {
1133
+ const text = node.value;
1134
+ if (!text.startsWith("*")) {
1127
1135
  return null;
1128
1136
  }
1129
- if (tag.description === true) {
1130
- return "";
1131
- } else {
1132
- return tag.description;
1133
- }
1137
+ return node.value.replace(/^\s*[*]\s/gm, "").replace(/\s+$/gm, "");
1134
1138
  }
1135
- function getEventDeprecated(event) {
1136
- const tags = event.tags;
1137
- if (!tags) {
1139
+ function flattenMemberExpression(node) {
1140
+ const { object, property } = node;
1141
+ if (property.type !== "Identifier") {
1138
1142
  return null;
1139
1143
  }
1140
- const tag = tags.find((it) => it.title === "deprecated");
1141
- if (!tag?.content) {
1142
- return null;
1144
+ if (object.type === "Identifier") {
1145
+ return [object.name, property.name].join(".");
1143
1146
  }
1144
- if (tag.content === true) {
1145
- return "";
1146
- } else {
1147
- return tag.content;
1147
+ if (object.type === "ThisExpression") {
1148
+ return ["this", property.name].join(".");
1148
1149
  }
1149
- }
1150
- function translateProps(props) {
1151
- const isRelevant = (prop) => {
1152
- return prop.tags?.ignore === void 0;
1153
- };
1154
- return props.filter(isRelevant).map((prop) => {
1155
- const defaultValue = prop.defaultValue ? { value: prop.defaultValue.value } : null;
1156
- return {
1157
- name: prop.name,
1158
- description: prop.description ?? null,
1159
- type: prop.type?.name ?? null,
1160
- required: Boolean(prop.required),
1161
- default: defaultValue,
1162
- deprecated: getPropSlotDeprecated(prop)
1163
- };
1164
- });
1165
- }
1166
- function translateEvents(events) {
1167
- const translatedEvents = [];
1168
- for (const event of events) {
1169
- if (event.tags?.find((it) => it.title === "ignore")) {
1170
- continue;
1150
+ if (object.type === "MemberExpression") {
1151
+ const nested = flattenMemberExpression(object);
1152
+ if (nested) {
1153
+ return [nested, property.name].join(".");
1171
1154
  }
1172
- const translatedEvent = {
1173
- name: event.name,
1174
- description: event.description ?? null,
1175
- properties: translateEventProperties(event),
1176
- deprecated: getEventDeprecated(event)
1177
- };
1178
- translatedEvents.push(translatedEvent);
1179
1155
  }
1180
- return translatedEvents;
1156
+ return null;
1181
1157
  }
1182
- function translateEventProperties(event) {
1183
- const properties = event.properties;
1184
- const types = event.type ? Object.values(event.type.names) : [];
1185
- if (!properties && !types.length) {
1158
+ function getParameters(node) {
1159
+ if (!node) {
1186
1160
  return [];
1187
1161
  }
1188
- if (!properties) {
1189
- return [
1190
- { name: "<anonymous>", type: String(types), description: null }
1191
- ];
1192
- }
1193
- const translatedProperties = [];
1194
- for (let i = 0; i < properties.length; i++) {
1195
- const property = properties[i];
1196
- const name = property.name ?? "<anonymous>";
1197
- const eventType = types[i];
1198
- const hasEventType = Boolean(eventType) && eventType !== "undefined";
1199
- const type = hasEventType ? eventType : property.type.names.join(" ");
1200
- const description = typeof property.description === "string" ? property.description : null;
1201
- translatedProperties.push({
1202
- name,
1203
- type,
1204
- description
1162
+ const parameters = [];
1163
+ for (const property of node.properties) {
1164
+ if (property.type !== "ObjectProperty") {
1165
+ continue;
1166
+ }
1167
+ if (property.key.type !== "Identifier") {
1168
+ continue;
1169
+ }
1170
+ const docComment = property.leadingComments?.find(isDocComment);
1171
+ parameters.push({
1172
+ name: property.key.name,
1173
+ description: getDescription(docComment)
1205
1174
  });
1206
1175
  }
1207
- return translatedProperties;
1176
+ return parameters;
1208
1177
  }
1209
- function translateSlots(slots) {
1210
- const translatedSlots = [];
1211
- for (const slot of slots) {
1212
- if (slot.tags?.ignore) {
1213
- continue;
1178
+ function isTranslateCall(node) {
1179
+ const allowedNames = [
1180
+ "this.$t",
1181
+ // options api (inside computed, methods, etc)
1182
+ "_ctx.$t",
1183
+ // options api (template)
1184
+ "$setup.$t",
1185
+ // script setup or setup in options api
1186
+ "TranslationService.provider.translate"
1187
+ // props call this directly
1188
+ ];
1189
+ if (node.callee.type === "MemberExpression") {
1190
+ const fullName = flattenMemberExpression(node.callee);
1191
+ return Boolean(fullName && allowedNames.includes(fullName));
1192
+ }
1193
+ if (node.callee.type === "Identifier") {
1194
+ return node.callee.name === "$t";
1195
+ }
1196
+ return false;
1197
+ }
1198
+ function findDocComment(path, node) {
1199
+ if (node.leadingComments) {
1200
+ const doc = node.leadingComments.find(isDocComment);
1201
+ if (doc) {
1202
+ return doc;
1214
1203
  }
1215
- const translatedSlot = {
1216
- name: slot.name,
1217
- description: slot.description ?? null,
1218
- bindings: translateSlotBindings(slot),
1219
- deprecated: getPropSlotDeprecated(slot)
1220
- };
1221
- translatedSlots.push(translatedSlot);
1222
1204
  }
1223
- return translatedSlots;
1205
+ const parent = path.parent;
1206
+ if (parent.leadingComments && (parent.type === "ReturnStatement" || parent.type === "ObjectProperty")) {
1207
+ const doc = parent.leadingComments.find(isDocComment);
1208
+ if (doc) {
1209
+ return doc;
1210
+ }
1211
+ }
1212
+ const grandparent = path.parentPath?.parent;
1213
+ if (parent.type === "VariableDeclarator" && grandparent?.leadingComments) {
1214
+ const doc = grandparent.leadingComments.find(isDocComment);
1215
+ if (doc) {
1216
+ return doc;
1217
+ }
1218
+ }
1219
+ return null;
1224
1220
  }
1225
- function translateSlotBindings(slot) {
1226
- if (!slot.bindings) {
1221
+ function findTranslations(filename, content) {
1222
+ const { descriptor, errors } = parse(content, { filename });
1223
+ if (errors.length > 0) {
1224
+ if (isCI) {
1225
+ const first = errors[0].message;
1226
+ throw new Error(
1227
+ `Errors occurred when trying to parse "${filename}": ${first}`
1228
+ );
1229
+ }
1227
1230
  return [];
1228
1231
  }
1229
- const translatedBindings = [];
1230
- for (const binding of slot.bindings) {
1231
- const name = binding.name ?? "<anonymous>";
1232
- const type = binding.type?.name ?? "unknown";
1233
- const description = typeof binding.description === "string" ? binding.description : null;
1234
- translatedBindings.push({
1235
- name,
1236
- type,
1237
- description
1232
+ const id = "faux-id";
1233
+ let sourcecode = "";
1234
+ let bindings = void 0;
1235
+ if (descriptor.script || descriptor.scriptSetup) {
1236
+ const script = compileScript$1(descriptor, {
1237
+ id,
1238
+ isProd: false,
1239
+ sourceMap: false,
1240
+ inlineTemplate: false,
1241
+ genDefaultAs: "exampleComponent",
1242
+ templateOptions: {
1243
+ filename,
1244
+ source: descriptor.template?.content,
1245
+ slotted: descriptor.slotted,
1246
+ compilerOptions: {
1247
+ comments: true,
1248
+ whitespace: "condense",
1249
+ mode: "module"
1250
+ }
1251
+ }
1238
1252
  });
1253
+ bindings = script.bindings;
1254
+ sourcecode += `${script.content}
1255
+
1256
+ `;
1239
1257
  }
1240
- return translatedBindings;
1241
- }
1242
- function filterModels(rawProps, rawEvents) {
1243
- const modelEvents = rawEvents.filter((it) => it.name.startsWith("update:"));
1244
- const rawModels = modelEvents.map((it) => {
1245
- const propName = it.name.slice("update:".length);
1246
- const prop = rawProps.find((it2) => it2.name === propName);
1247
- if (!prop) {
1248
- return null;
1249
- }
1250
- return {
1251
- ...prop,
1252
- name: propName === "modelValue" ? "v-model" : `v-model:${propName}`
1253
- };
1258
+ if (descriptor.template) {
1259
+ const template = compileTemplate({
1260
+ id,
1261
+ filename,
1262
+ source: descriptor.template.content,
1263
+ slotted: descriptor.slotted,
1264
+ preprocessLang: descriptor.template.lang,
1265
+ compilerOptions: {
1266
+ bindingMetadata: bindings,
1267
+ comments: true,
1268
+ whitespace: "condense",
1269
+ mode: "module"
1270
+ }
1271
+ });
1272
+ sourcecode += `${template.code}
1273
+
1274
+ `;
1275
+ }
1276
+ const ast = parse$1(sourcecode, {
1277
+ sourceType: "module",
1278
+ plugins: ["typescript"]
1254
1279
  });
1255
- const models = rawModels.filter((model) => model !== null);
1256
- const events = rawEvents.filter((it) => !it.name.startsWith("update:"));
1257
- const props = rawProps.filter((prop) => {
1258
- const hasModelName = models.some(
1259
- (model) => model.name.slice("v-model:".length) === prop.name
1260
- );
1261
- return !(hasModelName || prop.name.startsWith("modelValue"));
1280
+ const traverse = "default" in traverseModule ? traverseModule.default : traverseModule;
1281
+ const result = [];
1282
+ traverse(ast, {
1283
+ CallExpression(path) {
1284
+ const { node } = path;
1285
+ if (isTranslateCall(node)) {
1286
+ const [name, ...defaultOrParams] = node.arguments;
1287
+ const textArgument = defaultOrParams.find(isStringLiteral);
1288
+ const paramArgument = defaultOrParams.find(isObjectExpression);
1289
+ if (name.type !== "StringLiteral") {
1290
+ return;
1291
+ }
1292
+ const defaultTranslation = textArgument ? textArgument.value : null;
1293
+ const docComment = findDocComment(path, node);
1294
+ result.push({
1295
+ name: name.value,
1296
+ defaultTranslation,
1297
+ description: getDescription(docComment),
1298
+ parameters: getParameters(paramArgument)
1299
+ });
1300
+ }
1301
+ }
1262
1302
  });
1263
- return { models, props, events };
1264
- }
1265
- async function translateAPI(filePath) {
1266
- try {
1267
- const api = await parse(filePath);
1268
- const rawProps = api.props ? translateProps(api.props) : [];
1269
- const rawEvents = api.events ? translateEvents(api.events) : [];
1270
- const { models, props, events } = filterModels(rawProps, rawEvents);
1271
- const slots = api.slots ? translateSlots(api.slots) : [];
1272
- return {
1273
- name: api.displayName,
1274
- slug: slugify(api.displayName),
1275
- models,
1276
- props,
1277
- events,
1278
- slots
1279
- };
1280
- } catch (err) {
1281
- throw new Error(
1282
- `Failed to generate API description from "${filePath}"`,
1283
- { cause: err }
1284
- );
1285
- }
1303
+ return result;
1286
1304
  }
1287
1305
 
1288
1306
  const md$4 = MarkdownIt();
1289
1307
  const EMPTY_CHAR$4 = "&#8208;";
1308
+ const EM_DASH$2 = `<span role="presentation">&mdash;</span>`;
1290
1309
  function render$5(text) {
1291
1310
  return text ? md$4.render(text) : EMPTY_CHAR$4;
1292
1311
  }
1293
1312
  function renderInline$4(text) {
1294
1313
  return text ? md$4.renderInline(text) : EMPTY_CHAR$4;
1295
1314
  }
1296
- function generateModelTable(slug, models) {
1315
+ function generateEventTable(slug, events) {
1297
1316
  return (
1298
1317
  /* HTML */
1299
1318
  `
1300
- <next-heading-level id="${slug}-models">
1301
- <a class="header-anchor" href="#${slug}-models">Models</a>
1319
+ <next-heading-level id="${slug}-events">
1320
+ <a class="header-anchor" href="#${slug}-events">Events</a>
1302
1321
  </next-heading-level>
1303
- <dl class="docs-api docs-api--models">
1304
- ${models.map((model) => {
1305
- const { name } = model;
1306
- const id = `${slug}-model-${slugify(name)}`;
1322
+ <dl class="docs-api docs-api--events">
1323
+ ${events.map((event) => {
1324
+ const { name } = event;
1325
+ const id = `${slug}-event-${slugify(name)}`;
1326
+ const haveProperties = event.properties.length > 0;
1307
1327
  return (
1308
1328
  /* HTML */
1309
1329
  `
@@ -1312,16 +1332,23 @@ function generateModelTable(slug, models) {
1312
1332
  ><a class="docs-api__anchor" href="#${id}"
1313
1333
  ><span class="docs-api__name"
1314
1334
  >${htmlencode(name)}</span
1315
- >: ${htmlencode(model.type ?? "unknown")}</a
1335
+ ></a
1316
1336
  ></code
1317
1337
  >
1318
- ${model.required ? "" : `<span class="docs-tag docs-tag--default">Optional</span>`}
1319
- ${model.deprecated === null ? "" : `<span class="docs-tag docs-tag--deprecated">Deprecated</span>`}
1338
+ ${event.deprecated === null ? "" : `<span class="docs-tag docs-tag--deprecated">Deprecated</span>`}
1320
1339
  </dt>
1321
1340
  <dd>
1322
- ${render$5(model.description)}
1323
- ${model.default ? `<p class="doc-api__item">Default: <code>${htmlencode(model.default.value)}</code></p>` : ""}
1324
- ${model.deprecated ? `<p class="doc-api__item docs-deprecated">Deprecated: ${renderInline$4(model.deprecated)}</p>` : ""}
1341
+ ${render$5(event.description)}
1342
+ ${haveProperties ? `<p class="docs-api__list-title">Arguments:</p><ul class="docs-api__list">` : ""}
1343
+ ${event.properties.map((it) => {
1344
+ if (it.description) {
1345
+ return `<li><code>${htmlencode(it.name)}: ${htmlencode(it.type)}</code> ${EM_DASH$2} ${renderInline$4(it.description)}</li>`;
1346
+ } else {
1347
+ return `<li><code>${htmlencode(it.name)}: ${htmlencode(it.type)}</code></li>`;
1348
+ }
1349
+ }).join("")}
1350
+ ${haveProperties ? `</ul>` : ""}
1351
+ ${event.deprecated ? `<p class="docs-api__deprecated docs-deprecated">Deprecated: ${renderInline$4(event.deprecated)}</p>` : ""}
1325
1352
  </dd>
1326
1353
  `
1327
1354
  );
@@ -1339,17 +1366,17 @@ function render$4(text) {
1339
1366
  function renderInline$3(text) {
1340
1367
  return text ? md$3.renderInline(text) : EMPTY_CHAR$3;
1341
1368
  }
1342
- function generatePropTable(slug, props) {
1369
+ function generateModelTable(slug, models) {
1343
1370
  return (
1344
1371
  /* HTML */
1345
1372
  `
1346
- <next-heading-level id="${slug}-props">
1347
- <a class="header-anchor" href="#${slug}-props">Props</a>
1373
+ <next-heading-level id="${slug}-models">
1374
+ <a class="header-anchor" href="#${slug}-models">Models</a>
1348
1375
  </next-heading-level>
1349
- <dl class="docs-api docs-api--slots">
1350
- ${props.map((prop) => {
1351
- const { name } = prop;
1352
- const id = `${slug}-prop-${slugify(name)}`;
1376
+ <dl class="docs-api docs-api--models">
1377
+ ${models.map((model) => {
1378
+ const { name } = model;
1379
+ const id = `${slug}-model-${slugify(name)}`;
1353
1380
  return (
1354
1381
  /* HTML */
1355
1382
  `
@@ -1358,16 +1385,16 @@ function generatePropTable(slug, props) {
1358
1385
  ><a class="docs-api__anchor" href="#${id}"
1359
1386
  ><span class="docs-api__name"
1360
1387
  >${htmlencode(name)}</span
1361
- >: ${htmlencode(prop.type ?? "unknown")}</a
1388
+ >: ${htmlencode(model.type ?? "unknown")}</a
1362
1389
  ></code
1363
1390
  >
1364
- ${prop.required ? "" : `<span class="docs-tag docs-tag--default">Optional</span>`}
1365
- ${prop.deprecated === null ? "" : `<span class="docs-tag docs-tag--deprecated">Deprecated</span>`}
1391
+ ${model.required ? "" : `<span class="docs-tag docs-tag--default">Optional</span>`}
1392
+ ${model.deprecated === null ? "" : `<span class="docs-tag docs-tag--deprecated">Deprecated</span>`}
1366
1393
  </dt>
1367
1394
  <dd>
1368
- ${render$4(prop.description)}
1369
- ${prop.default ? `<p class="doc-api__item">Default: <code>${htmlencode(prop.default.value)}</code></p>` : ""}
1370
- ${prop.deprecated ? `<p class="doc-api__item docs-deprecated">Deprecated: ${renderInline$3(prop.deprecated)}</p>` : ""}
1395
+ ${render$4(model.description)}
1396
+ ${model.default ? `<p class="doc-api__item">Default: <code>${htmlencode(model.default.value)}</code></p>` : ""}
1397
+ ${model.deprecated ? `<p class="doc-api__item docs-deprecated">Deprecated: ${renderInline$3(model.deprecated)}</p>` : ""}
1371
1398
  </dd>
1372
1399
  `
1373
1400
  );
@@ -1379,25 +1406,23 @@ function generatePropTable(slug, props) {
1379
1406
 
1380
1407
  const md$2 = MarkdownIt();
1381
1408
  const EMPTY_CHAR$2 = "&#8208;";
1382
- const EM_DASH$2 = `<span role="presentation">&mdash;</span>`;
1383
1409
  function render$3(text) {
1384
1410
  return text ? md$2.render(text) : EMPTY_CHAR$2;
1385
1411
  }
1386
1412
  function renderInline$2(text) {
1387
1413
  return text ? md$2.renderInline(text) : EMPTY_CHAR$2;
1388
1414
  }
1389
- function generateEventTable(slug, events) {
1415
+ function generatePropTable(slug, props) {
1390
1416
  return (
1391
1417
  /* HTML */
1392
1418
  `
1393
- <next-heading-level id="${slug}-events">
1394
- <a class="header-anchor" href="#${slug}-events">Events</a>
1419
+ <next-heading-level id="${slug}-props">
1420
+ <a class="header-anchor" href="#${slug}-props">Props</a>
1395
1421
  </next-heading-level>
1396
- <dl class="docs-api docs-api--events">
1397
- ${events.map((event) => {
1398
- const { name } = event;
1399
- const id = `${slug}-event-${slugify(name)}`;
1400
- const haveProperties = event.properties.length > 0;
1422
+ <dl class="docs-api docs-api--slots">
1423
+ ${props.map((prop) => {
1424
+ const { name } = prop;
1425
+ const id = `${slug}-prop-${slugify(name)}`;
1401
1426
  return (
1402
1427
  /* HTML */
1403
1428
  `
@@ -1406,23 +1431,16 @@ function generateEventTable(slug, events) {
1406
1431
  ><a class="docs-api__anchor" href="#${id}"
1407
1432
  ><span class="docs-api__name"
1408
1433
  >${htmlencode(name)}</span
1409
- ></a
1434
+ >: ${htmlencode(prop.type ?? "unknown")}</a
1410
1435
  ></code
1411
1436
  >
1412
- ${event.deprecated === null ? "" : `<span class="docs-tag docs-tag--deprecated">Deprecated</span>`}
1437
+ ${prop.required ? "" : `<span class="docs-tag docs-tag--default">Optional</span>`}
1438
+ ${prop.deprecated === null ? "" : `<span class="docs-tag docs-tag--deprecated">Deprecated</span>`}
1413
1439
  </dt>
1414
1440
  <dd>
1415
- ${render$3(event.description)}
1416
- ${haveProperties ? `<p class="docs-api__list-title">Arguments:</p><ul class="docs-api__list">` : ""}
1417
- ${event.properties.map((it) => {
1418
- if (it.description) {
1419
- return `<li><code>${htmlencode(it.name)}: ${htmlencode(it.type)}</code> ${EM_DASH$2} ${renderInline$2(it.description)}</li>`;
1420
- } else {
1421
- return `<li><code>${htmlencode(it.name)}: ${htmlencode(it.type)}</code></li>`;
1422
- }
1423
- }).join("")}
1424
- ${haveProperties ? `</ul>` : ""}
1425
- ${event.deprecated ? `<p class="docs-api__deprecated docs-deprecated">Deprecated: ${renderInline$2(event.deprecated)}</p>` : ""}
1441
+ ${render$3(prop.description)}
1442
+ ${prop.default ? `<p class="doc-api__item">Default: <code>${htmlencode(prop.default.value)}</code></p>` : ""}
1443
+ ${prop.deprecated ? `<p class="doc-api__item docs-deprecated">Deprecated: ${renderInline$2(prop.deprecated)}</p>` : ""}
1426
1444
  </dd>
1427
1445
  `
1428
1446
  );
@@ -1471,13 +1489,64 @@ function generateSlotTable(slug, slots) {
1471
1489
  ${haveBindings ? `<p class="docs-api__list-title">Bindings:</p><ul class="docs-api__list">` : ""}
1472
1490
  ${slot.bindings.map((it) => {
1473
1491
  if (it.description) {
1474
- return `<li><code>${htmlencode(it.name)}: ${htmlencode(it.type)}</code> ${EM_DASH$1} ${renderInline$1(it.description)}</li>`;
1492
+ return `<li><code>${htmlencode(it.name)}: ${htmlencode(it.type)}</code> ${EM_DASH$1} ${renderInline$1(it.description)}</li>`;
1493
+ } else {
1494
+ return `<li><code>${htmlencode(it.name)}: ${htmlencode(it.type)}</code></li>`;
1495
+ }
1496
+ }).join("")}
1497
+ ${haveBindings ? `</ul>` : ""}
1498
+ ${slot.deprecated ? `<p class="docs-api__deprecated docs-deprecated">Deprecated: ${renderInline$1(slot.deprecated)}</p>` : ""}
1499
+ </dd>
1500
+ `
1501
+ );
1502
+ }).join("")}
1503
+ </dl>
1504
+ `
1505
+ );
1506
+ }
1507
+
1508
+ const md = MarkdownIt();
1509
+ const EMPTY_CHAR = "&#8208;";
1510
+ const EM_DASH = `<span role="presentation">&mdash;</span>`;
1511
+ function render$1(text) {
1512
+ return text ? md.render(text) : EMPTY_CHAR;
1513
+ }
1514
+ function renderInline(text) {
1515
+ return text ? md.renderInline(text) : EMPTY_CHAR;
1516
+ }
1517
+ function generateTranslationTable(slug, translations) {
1518
+ return (
1519
+ /* HTML */
1520
+ `
1521
+ <dl class="docs-api docs-api--translation">
1522
+ ${translations.map((translation) => {
1523
+ const { name } = translation;
1524
+ const id = `${slug}-translation-${slugify(name)}`;
1525
+ const haveParameters = translation.parameters.length > 0;
1526
+ return (
1527
+ /* HTML */
1528
+ `
1529
+ <dt>
1530
+ <code id="${id}"
1531
+ ><a class="docs-api__anchor" href="#${id}"
1532
+ ><span class="docs-api__name"
1533
+ >${htmlencode(name)}</span
1534
+ ></a
1535
+ ></code
1536
+ >
1537
+ </dt>
1538
+ <dd>
1539
+ ${render$1(translation.description)}
1540
+ ${translation.defaultTranslation ? `<p class="doc-api__item">Default: "${htmlencode(translation.defaultTranslation)}"</p>` : ""}
1541
+ ${haveParameters ? `<p class="docs-api__list-title">Parameters:</p><ul class="docs-api__list">` : ""}
1542
+ ${translation.parameters.map((it) => {
1543
+ if (it.description) {
1544
+ return `<li><code>${htmlencode(it.name)}</code> ${EM_DASH} ${renderInline(it.description)}</li>`;
1475
1545
  } else {
1476
- return `<li><code>${htmlencode(it.name)}: ${htmlencode(it.type)}</code></li>`;
1546
+ return `<li><code>${htmlencode(it.name)}</code></li>`;
1477
1547
  }
1478
1548
  }).join("")}
1479
- ${haveBindings ? `</ul>` : ""}
1480
- ${slot.deprecated ? `<p class="docs-api__deprecated docs-deprecated">Deprecated: ${renderInline$1(slot.deprecated)}</p>` : ""}
1549
+ ${haveParameters ? `</ul>` : ""}
1481
1550
  </dd>
1482
1551
  `
1483
1552
  );
@@ -1487,241 +1556,172 @@ function generateSlotTable(slug, slots) {
1487
1556
  );
1488
1557
  }
1489
1558
 
1490
- function isStringLiteral(node) {
1491
- return node.type === "StringLiteral";
1492
- }
1493
- function isObjectExpression(node) {
1494
- return node.type === "ObjectExpression";
1495
- }
1496
- function isDocComment(node) {
1497
- return node.type === "CommentBlock";
1498
- }
1499
- function getDescription(node) {
1500
- if (!node) {
1559
+ function getPropSlotDeprecated(prop) {
1560
+ const tags = prop.tags;
1561
+ if (!tags?.deprecated) {
1501
1562
  return null;
1502
1563
  }
1503
- const text = node.value;
1504
- if (!text.startsWith("*")) {
1564
+ const tag = tags.deprecated[0];
1565
+ if (!tag?.description) {
1505
1566
  return null;
1506
1567
  }
1507
- return node.value.replace(/^\s*[*]\s/gm, "").replace(/\s+$/gm, "");
1568
+ if (tag.description === true) {
1569
+ return "";
1570
+ } else {
1571
+ return tag.description;
1572
+ }
1508
1573
  }
1509
- function flattenMemberExpression(node) {
1510
- const { object, property } = node;
1511
- if (property.type !== "Identifier") {
1574
+ function getEventDeprecated(event) {
1575
+ const tags = event.tags;
1576
+ if (!tags) {
1512
1577
  return null;
1513
1578
  }
1514
- if (object.type === "Identifier") {
1515
- return [object.name, property.name].join(".");
1516
- }
1517
- if (object.type === "ThisExpression") {
1518
- return ["this", property.name].join(".");
1519
- }
1520
- if (object.type === "MemberExpression") {
1521
- const nested = flattenMemberExpression(object);
1522
- if (nested) {
1523
- return [nested, property.name].join(".");
1524
- }
1525
- }
1526
- return null;
1527
- }
1528
- function getParameters(node) {
1529
- if (!node) {
1530
- return [];
1579
+ const tag = tags.find((it) => it.title === "deprecated");
1580
+ if (!tag?.content) {
1581
+ return null;
1531
1582
  }
1532
- const parameters = [];
1533
- for (const property of node.properties) {
1534
- if (property.type !== "ObjectProperty") {
1535
- continue;
1536
- }
1537
- if (property.key.type !== "Identifier") {
1538
- continue;
1539
- }
1540
- const docComment = property.leadingComments?.find(isDocComment);
1541
- parameters.push({
1542
- name: property.key.name,
1543
- description: getDescription(docComment)
1544
- });
1583
+ if (tag.content === true) {
1584
+ return "";
1585
+ } else {
1586
+ return tag.content;
1545
1587
  }
1546
- return parameters;
1547
1588
  }
1548
- function isTranslateCall(node) {
1549
- const allowedNames = [
1550
- "this.$t",
1551
- // options api (inside computed, methods, etc)
1552
- "_ctx.$t",
1553
- // options api (template)
1554
- "$setup.$t",
1555
- // script setup or setup in options api
1556
- "TranslationService.provider.translate"
1557
- // props call this directly
1558
- ];
1559
- if (node.callee.type === "MemberExpression") {
1560
- const fullName = flattenMemberExpression(node.callee);
1561
- return Boolean(fullName && allowedNames.includes(fullName));
1562
- }
1563
- if (node.callee.type === "Identifier") {
1564
- return node.callee.name === "$t";
1565
- }
1566
- return false;
1589
+ function translateProps(props) {
1590
+ const isRelevant = (prop) => {
1591
+ return prop.tags?.ignore === void 0;
1592
+ };
1593
+ return props.filter(isRelevant).map((prop) => {
1594
+ const defaultValue = prop.defaultValue ? { value: prop.defaultValue.value } : null;
1595
+ return {
1596
+ name: prop.name,
1597
+ description: prop.description ?? null,
1598
+ type: prop.type?.name ?? null,
1599
+ required: Boolean(prop.required),
1600
+ default: defaultValue,
1601
+ deprecated: getPropSlotDeprecated(prop)
1602
+ };
1603
+ });
1567
1604
  }
1568
- function findDocComment(path, node) {
1569
- if (node.leadingComments) {
1570
- const doc = node.leadingComments.find(isDocComment);
1571
- if (doc) {
1572
- return doc;
1573
- }
1574
- }
1575
- const parent = path.parent;
1576
- if (parent.leadingComments && (parent.type === "ReturnStatement" || parent.type === "ObjectProperty")) {
1577
- const doc = parent.leadingComments.find(isDocComment);
1578
- if (doc) {
1579
- return doc;
1580
- }
1581
- }
1582
- const grandparent = path.parentPath?.parent;
1583
- if (parent.type === "VariableDeclarator" && grandparent?.leadingComments) {
1584
- const doc = grandparent.leadingComments.find(isDocComment);
1585
- if (doc) {
1586
- return doc;
1605
+ function translateEvents(events) {
1606
+ const translatedEvents = [];
1607
+ for (const event of events) {
1608
+ if (event.tags?.find((it) => it.title === "ignore")) {
1609
+ continue;
1587
1610
  }
1611
+ const translatedEvent = {
1612
+ name: event.name,
1613
+ description: event.description ?? null,
1614
+ properties: translateEventProperties(event),
1615
+ deprecated: getEventDeprecated(event)
1616
+ };
1617
+ translatedEvents.push(translatedEvent);
1588
1618
  }
1589
- return null;
1619
+ return translatedEvents;
1590
1620
  }
1591
- function findTranslations(filename, content) {
1592
- const { descriptor, errors } = parse$1(content, { filename });
1593
- if (errors.length > 0) {
1594
- if (isCI) {
1595
- const first = errors[0].message;
1596
- throw new Error(
1597
- `Errors occurred when trying to parse "${filename}": ${first}`
1598
- );
1599
- }
1621
+ function translateEventProperties(event) {
1622
+ const properties = event.properties;
1623
+ const types = event.type ? Object.values(event.type.names) : [];
1624
+ if (!properties && !types.length) {
1600
1625
  return [];
1601
1626
  }
1602
- const id = "faux-id";
1603
- let sourcecode = "";
1604
- let bindings = void 0;
1605
- if (descriptor.script || descriptor.scriptSetup) {
1606
- const script = compileScript$1(descriptor, {
1607
- id,
1608
- isProd: false,
1609
- sourceMap: false,
1610
- inlineTemplate: false,
1611
- genDefaultAs: "exampleComponent",
1612
- templateOptions: {
1613
- filename,
1614
- source: descriptor.template?.content,
1615
- slotted: descriptor.slotted,
1616
- compilerOptions: {
1617
- comments: true,
1618
- whitespace: "condense",
1619
- mode: "module"
1620
- }
1621
- }
1622
- });
1623
- bindings = script.bindings;
1624
- sourcecode += `${script.content}
1625
-
1626
- `;
1627
+ if (!properties) {
1628
+ return [
1629
+ { name: "<anonymous>", type: String(types), description: null }
1630
+ ];
1627
1631
  }
1628
- if (descriptor.template) {
1629
- const template = compileTemplate({
1630
- id,
1631
- filename,
1632
- source: descriptor.template.content,
1633
- slotted: descriptor.slotted,
1634
- preprocessLang: descriptor.template.lang,
1635
- compilerOptions: {
1636
- bindingMetadata: bindings,
1637
- comments: true,
1638
- whitespace: "condense",
1639
- mode: "module"
1640
- }
1632
+ const translatedProperties = [];
1633
+ for (let i = 0; i < properties.length; i++) {
1634
+ const property = properties[i];
1635
+ const name = property.name ?? "<anonymous>";
1636
+ const eventType = types[i];
1637
+ const hasEventType = Boolean(eventType) && eventType !== "undefined";
1638
+ const type = hasEventType ? eventType : property.type.names.join(" ");
1639
+ const description = typeof property.description === "string" ? property.description : null;
1640
+ translatedProperties.push({
1641
+ name,
1642
+ type,
1643
+ description
1641
1644
  });
1642
- sourcecode += `${template.code}
1643
-
1644
- `;
1645
1645
  }
1646
- const ast = parse$2(sourcecode, {
1647
- sourceType: "module",
1648
- plugins: ["typescript"]
1649
- });
1650
- const traverse = "default" in traverseModule ? traverseModule.default : traverseModule;
1651
- const result = [];
1652
- traverse(ast, {
1653
- CallExpression(path) {
1654
- const { node } = path;
1655
- if (isTranslateCall(node)) {
1656
- const [name, ...defaultOrParams] = node.arguments;
1657
- const textArgument = defaultOrParams.find(isStringLiteral);
1658
- const paramArgument = defaultOrParams.find(isObjectExpression);
1659
- if (name.type !== "StringLiteral") {
1660
- return;
1661
- }
1662
- const defaultTranslation = textArgument ? textArgument.value : null;
1663
- const docComment = findDocComment(path, node);
1664
- result.push({
1665
- name: name.value,
1666
- defaultTranslation,
1667
- description: getDescription(docComment),
1668
- parameters: getParameters(paramArgument)
1669
- });
1670
- }
1646
+ return translatedProperties;
1647
+ }
1648
+ function translateSlots(slots) {
1649
+ const translatedSlots = [];
1650
+ for (const slot of slots) {
1651
+ if (slot.tags?.ignore) {
1652
+ continue;
1671
1653
  }
1672
- });
1673
- return result;
1654
+ const translatedSlot = {
1655
+ name: slot.name,
1656
+ description: slot.description ?? null,
1657
+ bindings: translateSlotBindings(slot),
1658
+ deprecated: getPropSlotDeprecated(slot)
1659
+ };
1660
+ translatedSlots.push(translatedSlot);
1661
+ }
1662
+ return translatedSlots;
1674
1663
  }
1675
-
1676
- const md = MarkdownIt();
1677
- const EMPTY_CHAR = "&#8208;";
1678
- const EM_DASH = `<span role="presentation">&mdash;</span>`;
1679
- function render$1(text) {
1680
- return text ? md.render(text) : EMPTY_CHAR;
1664
+ function translateSlotBindings(slot) {
1665
+ if (!slot.bindings) {
1666
+ return [];
1667
+ }
1668
+ const translatedBindings = [];
1669
+ for (const binding of slot.bindings) {
1670
+ const name = binding.name ?? "<anonymous>";
1671
+ const type = binding.type?.name ?? "unknown";
1672
+ const description = typeof binding.description === "string" ? binding.description : null;
1673
+ translatedBindings.push({
1674
+ name,
1675
+ type,
1676
+ description
1677
+ });
1678
+ }
1679
+ return translatedBindings;
1681
1680
  }
1682
- function renderInline(text) {
1683
- return text ? md.renderInline(text) : EMPTY_CHAR;
1681
+ function filterModels(rawProps, rawEvents) {
1682
+ const modelEvents = rawEvents.filter((it) => it.name.startsWith("update:"));
1683
+ const rawModels = modelEvents.map((it) => {
1684
+ const propName = it.name.slice("update:".length);
1685
+ const prop = rawProps.find((it2) => it2.name === propName);
1686
+ if (!prop) {
1687
+ return null;
1688
+ }
1689
+ return {
1690
+ ...prop,
1691
+ name: propName === "modelValue" ? "v-model" : `v-model:${propName}`
1692
+ };
1693
+ });
1694
+ const models = rawModels.filter((model) => model !== null);
1695
+ const events = rawEvents.filter((it) => !it.name.startsWith("update:"));
1696
+ const props = rawProps.filter((prop) => {
1697
+ const hasModelName = models.some(
1698
+ (model) => model.name.slice("v-model:".length) === prop.name
1699
+ );
1700
+ return !(hasModelName || prop.name.startsWith("modelValue"));
1701
+ });
1702
+ return { models, props, events };
1684
1703
  }
1685
- function generateTranslationTable(slug, translations) {
1686
- return (
1687
- /* HTML */
1688
- `
1689
- <dl class="docs-api docs-api--translation">
1690
- ${translations.map((translation) => {
1691
- const { name } = translation;
1692
- const id = `${slug}-translation-${slugify(name)}`;
1693
- const haveParameters = translation.parameters.length > 0;
1694
- return (
1695
- /* HTML */
1696
- `
1697
- <dt>
1698
- <code id="${id}"
1699
- ><a class="docs-api__anchor" href="#${id}"
1700
- ><span class="docs-api__name"
1701
- >${htmlencode(name)}</span
1702
- ></a
1703
- ></code
1704
- >
1705
- </dt>
1706
- <dd>
1707
- ${render$1(translation.description)}
1708
- ${translation.defaultTranslation ? `<p class="doc-api__item">Default: "${htmlencode(translation.defaultTranslation)}"</p>` : ""}
1709
- ${haveParameters ? `<p class="docs-api__list-title">Parameters:</p><ul class="docs-api__list">` : ""}
1710
- ${translation.parameters.map((it) => {
1711
- if (it.description) {
1712
- return `<li><code>${htmlencode(it.name)}</code> ${EM_DASH} ${renderInline(it.description)}</li>`;
1713
- } else {
1714
- return `<li><code>${htmlencode(it.name)}</code></li>`;
1715
- }
1716
- }).join("")}
1717
- ${haveParameters ? `</ul>` : ""}
1718
- </dd>
1719
- `
1720
- );
1721
- }).join("")}
1722
- </dl>
1723
- `
1724
- );
1704
+ async function translateAPI(filePath) {
1705
+ try {
1706
+ const api = await parse$2(filePath);
1707
+ const rawProps = api.props ? translateProps(api.props) : [];
1708
+ const rawEvents = api.events ? translateEvents(api.events) : [];
1709
+ const { models, props, events } = filterModels(rawProps, rawEvents);
1710
+ const slots = api.slots ? translateSlots(api.slots) : [];
1711
+ return {
1712
+ name: api.displayName,
1713
+ slug: slugify(api.displayName),
1714
+ models,
1715
+ props,
1716
+ events,
1717
+ slots
1718
+ };
1719
+ } catch (err) {
1720
+ throw new Error(
1721
+ `Failed to generate API description from "${filePath}"`,
1722
+ { cause: err }
1723
+ );
1724
+ }
1725
1725
  }
1726
1726
 
1727
1727
  function parseAPI(filePath, api) {
@@ -2107,6 +2107,44 @@ function compileProcessorRuntime(generator, distDir, processors) {
2107
2107
  }
2108
2108
  }
2109
2109
 
2110
+ var translation$1 = {
2111
+ component: {
2112
+ component: "Component",
2113
+ status: "Status"
2114
+ },
2115
+ outline: {
2116
+ "in-this-article": "In this article"
2117
+ },
2118
+ search: {
2119
+ button: "Search",
2120
+ instructions: "<kbd>Esc</kbd> to close <kbd>Arrow up/down</kbd> to navigate <kbd>Enter</kbd> to select",
2121
+ title: "Search",
2122
+ placeholder: "Type to begin searching"
2123
+ }
2124
+ };
2125
+ var langEn = {
2126
+ translation: translation$1
2127
+ };
2128
+
2129
+ var translation = {
2130
+ component: {
2131
+ component: "Komponent",
2132
+ status: "Status"
2133
+ },
2134
+ outline: {
2135
+ "in-this-article": "Innehåll"
2136
+ },
2137
+ search: {
2138
+ button: "Sök",
2139
+ instructions: "<kbd>Esc</kbd> för att stänga <kbd>Pil upp/ner</kbd> för att navigera <kbd>Enter</kbd> för att välja",
2140
+ title: "Sök",
2141
+ placeholder: "Skriv för att börja söka"
2142
+ }
2143
+ };
2144
+ var langSv = {
2145
+ translation: translation
2146
+ };
2147
+
2110
2148
  function isNavigationSection(node) {
2111
2149
  return "key" in node;
2112
2150
  }
@@ -2312,68 +2350,6 @@ function sortNavigationTree(tree) {
2312
2350
  const templateUrl = new URL("../templates", import.meta.url);
2313
2351
  const templateDirectory = fileURLToPath(templateUrl);
2314
2352
 
2315
- class TemplateLoader {
2316
- async = true;
2317
- folders;
2318
- templateCache;
2319
- constructor(folders = []) {
2320
- this.folders = [...folders, templateDirectory];
2321
- this.templateCache = /* @__PURE__ */ new Map();
2322
- }
2323
- /* eslint-disable-next-line @typescript-eslint/no-misused-promises -- technical debt */
2324
- async getSource(name, callback) {
2325
- try {
2326
- const { content, filePath } = await this.resolveTemplate(name);
2327
- callback(null, {
2328
- src: content,
2329
- path: filePath,
2330
- noCache: false
2331
- });
2332
- } catch (err) {
2333
- if (err instanceof Error) {
2334
- callback(err, null);
2335
- } else {
2336
- callback(new Error(String(err)), null);
2337
- }
2338
- }
2339
- }
2340
- hasTemplate(name) {
2341
- const { templateCache } = this;
2342
- const cached = templateCache.get(name);
2343
- if (cached) {
2344
- return true;
2345
- }
2346
- const filePath = this.findTemplateFile(name);
2347
- return Boolean(filePath);
2348
- }
2349
- async resolveTemplate(name) {
2350
- const { templateCache, folders } = this;
2351
- const cached = templateCache.get(name);
2352
- if (cached) {
2353
- return cached;
2354
- }
2355
- const filePath = this.findTemplateFile(name);
2356
- if (!filePath) {
2357
- const searched = folders.map((it) => ` - "${it}"`).join("\n");
2358
- const message = `Failed to resolve template "${name}", searched in:
2359
-
2360
- ${searched}
2361
-
2362
- Make sure the name is correct and the template file exists in one of the listed directories.`;
2363
- throw new Error(message);
2364
- }
2365
- const content = await fs.readFile(filePath, "utf-8");
2366
- const resolved = { content, filePath };
2367
- templateCache.set(name, resolved);
2368
- return resolved;
2369
- }
2370
- findTemplateFile(name) {
2371
- const { folders } = this;
2372
- const searchPaths = folders.map((it) => path$1.join(it, name));
2373
- return searchPaths.find((it) => existsSync(it));
2374
- }
2375
- }
2376
-
2377
2353
  class MissingTemplateError extends Error {
2378
2354
  searchDir;
2379
2355
  constructor(fileInfo, template, format, searchDir) {
@@ -2404,22 +2380,84 @@ function findTemplate(folders, from, src, format) {
2404
2380
  layout = src.template;
2405
2381
  format = src.format !== "json" ? "html" : "json";
2406
2382
  }
2407
- const key = cacheKey(layout, format);
2408
- const cached = cache$1.get(key);
2409
- if (cached) {
2410
- return cached;
2383
+ const key = cacheKey(layout, format);
2384
+ const cached = cache$1.get(key);
2385
+ if (cached) {
2386
+ return cached;
2387
+ }
2388
+ folders = [...folders, templateDirectory];
2389
+ const template = `${layout}.template.${format}`;
2390
+ const searchPaths = folders.map((it) => {
2391
+ return path$1.join(it, template);
2392
+ });
2393
+ const found = searchPaths.find((it) => fs__default.existsSync(it));
2394
+ if (!found) {
2395
+ throw new MissingTemplateError(from, template, format, folders);
2396
+ }
2397
+ cache$1.set(key, template);
2398
+ return template;
2399
+ }
2400
+
2401
+ class TemplateLoader {
2402
+ async = true;
2403
+ folders;
2404
+ templateCache;
2405
+ constructor(folders = []) {
2406
+ this.folders = [...folders, templateDirectory];
2407
+ this.templateCache = /* @__PURE__ */ new Map();
2408
+ }
2409
+ /* eslint-disable-next-line @typescript-eslint/no-misused-promises -- technical debt */
2410
+ async getSource(name, callback) {
2411
+ try {
2412
+ const { content, filePath } = await this.resolveTemplate(name);
2413
+ callback(null, {
2414
+ src: content,
2415
+ path: filePath,
2416
+ noCache: false
2417
+ });
2418
+ } catch (err) {
2419
+ if (err instanceof Error) {
2420
+ callback(err, null);
2421
+ } else {
2422
+ callback(new Error(String(err)), null);
2423
+ }
2424
+ }
2425
+ }
2426
+ hasTemplate(name) {
2427
+ const { templateCache } = this;
2428
+ const cached = templateCache.get(name);
2429
+ if (cached) {
2430
+ return true;
2431
+ }
2432
+ const filePath = this.findTemplateFile(name);
2433
+ return Boolean(filePath);
2434
+ }
2435
+ async resolveTemplate(name) {
2436
+ const { templateCache, folders } = this;
2437
+ const cached = templateCache.get(name);
2438
+ if (cached) {
2439
+ return cached;
2440
+ }
2441
+ const filePath = this.findTemplateFile(name);
2442
+ if (!filePath) {
2443
+ const searched = folders.map((it) => ` - "${it}"`).join("\n");
2444
+ const message = `Failed to resolve template "${name}", searched in:
2445
+
2446
+ ${searched}
2447
+
2448
+ Make sure the name is correct and the template file exists in one of the listed directories.`;
2449
+ throw new Error(message);
2450
+ }
2451
+ const content = await fs.readFile(filePath, "utf-8");
2452
+ const resolved = { content, filePath };
2453
+ templateCache.set(name, resolved);
2454
+ return resolved;
2411
2455
  }
2412
- folders = [...folders, templateDirectory];
2413
- const template = `${layout}.template.${format}`;
2414
- const searchPaths = folders.map((it) => {
2415
- return path$1.join(it, template);
2416
- });
2417
- const found = searchPaths.find((it) => fs__default.existsSync(it));
2418
- if (!found) {
2419
- throw new MissingTemplateError(from, template, format, folders);
2456
+ findTemplateFile(name) {
2457
+ const { folders } = this;
2458
+ const searchPaths = folders.map((it) => path$1.join(it, name));
2459
+ return searchPaths.find((it) => existsSync(it));
2420
2460
  }
2421
- cache$1.set(key, template);
2422
- return template;
2423
2461
  }
2424
2462
 
2425
2463
  const messageRegex = /^[(][^)]+[)] \[Line \d+, Column \d+\]\n\s+Error: (.*)$/;
@@ -2818,132 +2856,6 @@ function nunjucksProcessor(options) {
2818
2856
  };
2819
2857
  }
2820
2858
 
2821
- var translation$1 = {
2822
- component: {
2823
- component: "Component",
2824
- status: "Status"
2825
- },
2826
- outline: {
2827
- "in-this-article": "In this article"
2828
- },
2829
- search: {
2830
- button: "Search",
2831
- instructions: "<kbd>Esc</kbd> to close <kbd>Arrow up/down</kbd> to navigate <kbd>Enter</kbd> to select",
2832
- title: "Search",
2833
- placeholder: "Type to begin searching"
2834
- }
2835
- };
2836
- var langEn = {
2837
- translation: translation$1
2838
- };
2839
-
2840
- var translation = {
2841
- component: {
2842
- component: "Komponent",
2843
- status: "Status"
2844
- },
2845
- outline: {
2846
- "in-this-article": "Innehåll"
2847
- },
2848
- search: {
2849
- button: "Sök",
2850
- instructions: "<kbd>Esc</kbd> för att stänga <kbd>Pil upp/ner</kbd> för att navigera <kbd>Enter</kbd> för att välja",
2851
- title: "Sök",
2852
- placeholder: "Skriv för att börja söka"
2853
- }
2854
- };
2855
- var langSv = {
2856
- translation: translation
2857
- };
2858
-
2859
- function getAssetSource(asset) {
2860
- const lines = [];
2861
- const pkg = asset.package.replace(/\\/g, "/");
2862
- lines.push(`export * from "${pkg}";`);
2863
- return lines.join("\n");
2864
- }
2865
- async function compileVendor(assetFolder, vendor, options) {
2866
- const name = path$1.isAbsolute(vendor.package) ? path$1.basename(vendor.package) : vendor.package;
2867
- const slug = slugify(name);
2868
- const outfile = `temp/vendor-${slug}.out.js`;
2869
- const tmpfile = `temp/vendor-${slug}.in.js`;
2870
- const source = getAssetSource(vendor);
2871
- await fs.writeFile(tmpfile, source, "utf-8");
2872
- await esbuild$1.build({
2873
- entryPoints: [tmpfile],
2874
- outfile,
2875
- bundle: true,
2876
- format: "esm",
2877
- platform: "browser",
2878
- tsconfig: tsconfigPath,
2879
- define: {
2880
- "process.env.NODE_ENV": JSON.stringify("development"),
2881
- __VUE_OPTIONS_API__: "true",
2882
- __VUE_PROD_DEVTOOLS__: "true",
2883
- __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: "false"
2884
- },
2885
- alias: vendor.alias ? { [vendor.package]: vendor.alias } : void 0,
2886
- ...options
2887
- });
2888
- const content = await fs.readFile(outfile, "utf-8");
2889
- const fingerprint = getFingerprint(content);
2890
- const integrity = getIntegrity(content);
2891
- const filename = `vendor-${slug}-${fingerprint}.js`;
2892
- const dst = path$1.join(assetFolder, filename).replace(/\\/g, "/");
2893
- await fs.rename(outfile, dst);
2894
- const stat = await fs.stat(dst);
2895
- return {
2896
- package: vendor.package,
2897
- filename,
2898
- publicPath: `./assets/${filename}`,
2899
- integrity,
2900
- size: stat.size
2901
- };
2902
- }
2903
-
2904
- function normalizeVendorDefinition(vendor) {
2905
- if (typeof vendor === "string") {
2906
- return {
2907
- package: vendor,
2908
- alias: void 0
2909
- };
2910
- } else {
2911
- return {
2912
- package: vendor.package,
2913
- alias: vendor.alias ?? void 0
2914
- };
2915
- }
2916
- }
2917
-
2918
- function getPackageName(vendor) {
2919
- return typeof vendor === "string" ? vendor : vendor.package;
2920
- }
2921
- function generateVendorAssets(assetFolder, assets) {
2922
- const packages = assets.map(getPackageName);
2923
- const normalized = assets.map(normalizeVendorDefinition);
2924
- const promises = normalized.map((it) => {
2925
- const external = packages.filter((pkg) => pkg !== it.package);
2926
- return compileVendor(assetFolder, it, {
2927
- external
2928
- });
2929
- });
2930
- return Promise.all(promises);
2931
- }
2932
- function vendorProcessor(assetFolder, vendor) {
2933
- return {
2934
- stage: "assets",
2935
- name: "vendor-processor",
2936
- async handler(context) {
2937
- const assets = await generateVendorAssets(assetFolder, vendor);
2938
- context.addVendorAsset(assets);
2939
- for (const asset of assets) {
2940
- const filename = path.basename(asset.publicPath);
2941
- context.log(filename, formatSize(asset.size));
2942
- }
2943
- }
2944
- };
2945
- }
2946
-
2947
2859
  function livereloadProcessor(options) {
2948
2860
  const { enabled } = options;
2949
2861
  return {
@@ -3059,6 +2971,94 @@ async function serve(options) {
3059
2971
  }
3060
2972
  }
3061
2973
 
2974
+ function getAssetSource(asset) {
2975
+ const lines = [];
2976
+ const pkg = asset.package.replace(/\\/g, "/");
2977
+ lines.push(`export * from "${pkg}";`);
2978
+ return lines.join("\n");
2979
+ }
2980
+ async function compileVendor(assetFolder, vendor, options) {
2981
+ const name = path$1.isAbsolute(vendor.package) ? path$1.basename(vendor.package) : vendor.package;
2982
+ const slug = slugify(name);
2983
+ const outfile = `temp/vendor-${slug}.out.js`;
2984
+ const tmpfile = `temp/vendor-${slug}.in.js`;
2985
+ const source = getAssetSource(vendor);
2986
+ await fs.writeFile(tmpfile, source, "utf-8");
2987
+ await esbuild$1.build({
2988
+ entryPoints: [tmpfile],
2989
+ outfile,
2990
+ bundle: true,
2991
+ format: "esm",
2992
+ platform: "browser",
2993
+ tsconfig: tsconfigPath,
2994
+ define: {
2995
+ "process.env.NODE_ENV": JSON.stringify("development"),
2996
+ __VUE_OPTIONS_API__: "true",
2997
+ __VUE_PROD_DEVTOOLS__: "true",
2998
+ __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: "false"
2999
+ },
3000
+ alias: vendor.alias ? { [vendor.package]: vendor.alias } : void 0,
3001
+ ...options
3002
+ });
3003
+ const content = await fs.readFile(outfile, "utf-8");
3004
+ const fingerprint = getFingerprint(content);
3005
+ const integrity = getIntegrity(content);
3006
+ const filename = `vendor-${slug}-${fingerprint}.js`;
3007
+ const dst = path$1.join(assetFolder, filename).replace(/\\/g, "/");
3008
+ await fs.rename(outfile, dst);
3009
+ const stat = await fs.stat(dst);
3010
+ return {
3011
+ package: vendor.package,
3012
+ filename,
3013
+ publicPath: `./assets/${filename}`,
3014
+ integrity,
3015
+ size: stat.size
3016
+ };
3017
+ }
3018
+
3019
+ function normalizeVendorDefinition(vendor) {
3020
+ if (typeof vendor === "string") {
3021
+ return {
3022
+ package: vendor,
3023
+ alias: void 0
3024
+ };
3025
+ } else {
3026
+ return {
3027
+ package: vendor.package,
3028
+ alias: vendor.alias ?? void 0
3029
+ };
3030
+ }
3031
+ }
3032
+
3033
+ function getPackageName(vendor) {
3034
+ return typeof vendor === "string" ? vendor : vendor.package;
3035
+ }
3036
+ function generateVendorAssets(assetFolder, assets) {
3037
+ const packages = assets.map(getPackageName);
3038
+ const normalized = assets.map(normalizeVendorDefinition);
3039
+ const promises = normalized.map((it) => {
3040
+ const external = packages.filter((pkg) => pkg !== it.package);
3041
+ return compileVendor(assetFolder, it, {
3042
+ external
3043
+ });
3044
+ });
3045
+ return Promise.all(promises);
3046
+ }
3047
+ function vendorProcessor(assetFolder, vendor) {
3048
+ return {
3049
+ stage: "assets",
3050
+ name: "vendor-processor",
3051
+ async handler(context) {
3052
+ const assets = await generateVendorAssets(assetFolder, vendor);
3053
+ context.addVendorAsset(assets);
3054
+ for (const asset of assets) {
3055
+ const filename = path.basename(asset.publicPath);
3056
+ context.log(filename, formatSize(asset.size));
3057
+ }
3058
+ }
3059
+ };
3060
+ }
3061
+
3062
3062
  function toArray(value) {
3063
3063
  return Array.isArray(value) ? value : [value];
3064
3064
  }