executable-stories-formatters 0.13.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +426 -103
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +43 -52
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +43 -52
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -15269,7 +15269,9 @@ var MarkdownFormatter = class {
|
|
|
15269
15269
|
ticketUrlTemplate: options.ticketUrlTemplate,
|
|
15270
15270
|
traceUrlTemplate: options.traceUrlTemplate,
|
|
15271
15271
|
includeSourceLinks: options.includeSourceLinks ?? true,
|
|
15272
|
-
customRenderers: options.customRenderers
|
|
15272
|
+
customRenderers: options.customRenderers,
|
|
15273
|
+
scenarioAnchor: options.scenarioAnchor,
|
|
15274
|
+
scenarioBadge: options.scenarioBadge
|
|
15273
15275
|
};
|
|
15274
15276
|
}
|
|
15275
15277
|
/**
|
|
@@ -15456,6 +15458,11 @@ var MarkdownFormatter = class {
|
|
|
15456
15458
|
* Render a single scenario.
|
|
15457
15459
|
*/
|
|
15458
15460
|
renderScenario(lines, tc) {
|
|
15461
|
+
const anchorId = this.options.scenarioAnchor?.(tc);
|
|
15462
|
+
if (anchorId) {
|
|
15463
|
+
lines.push(`<a id="${anchorId}"></a>`);
|
|
15464
|
+
lines.push("");
|
|
15465
|
+
}
|
|
15459
15466
|
if (this.options.customRenderers?.renderScenarioHeader) {
|
|
15460
15467
|
const custom = this.options.customRenderers.renderScenarioHeader(tc);
|
|
15461
15468
|
if (custom !== null) {
|
|
@@ -15471,6 +15478,10 @@ var MarkdownFormatter = class {
|
|
|
15471
15478
|
icon = this.getStatusIcon(tc.status) + " ";
|
|
15472
15479
|
}
|
|
15473
15480
|
lines.push(`${headingPrefix} ${icon}${tc.story.scenario}`);
|
|
15481
|
+
const badge = this.options.scenarioBadge?.(tc);
|
|
15482
|
+
if (badge) {
|
|
15483
|
+
lines.push(badge);
|
|
15484
|
+
}
|
|
15474
15485
|
if (this.options.includeSourceLinks && this.options.permalinkBaseUrl && tc.sourceFile !== "unknown") {
|
|
15475
15486
|
const permalink = this.buildPermalink(tc);
|
|
15476
15487
|
lines.push(`Source: [${tc.sourceFile}](${permalink})`);
|
|
@@ -18287,12 +18298,16 @@ function groupBy7(items, keyFn) {
|
|
|
18287
18298
|
var fs5 = __toESM(require("fs"), 1);
|
|
18288
18299
|
var path6 = __toESM(require("path"), 1);
|
|
18289
18300
|
var SKIP_PREFIXES = ["http://", "https://", "data:", "#"];
|
|
18290
|
-
function
|
|
18301
|
+
function isRemoteRef(src) {
|
|
18291
18302
|
const trimmed = src.trim();
|
|
18292
|
-
|
|
18293
|
-
|
|
18294
|
-
|
|
18295
|
-
|
|
18303
|
+
return SKIP_PREFIXES.some((prefix) => trimmed.startsWith(prefix));
|
|
18304
|
+
}
|
|
18305
|
+
function isAbsoluteRef(src) {
|
|
18306
|
+
const trimmed = src.trim();
|
|
18307
|
+
return path6.posix.isAbsolute(trimmed) || path6.win32.isAbsolute(trimmed);
|
|
18308
|
+
}
|
|
18309
|
+
function isRelativeLocalPath(src) {
|
|
18310
|
+
return !isRemoteRef(src) && !isAbsoluteRef(src);
|
|
18296
18311
|
}
|
|
18297
18312
|
function stripCodeContent(markdown) {
|
|
18298
18313
|
let result = markdown.replace(/^[ \t]*(`{3,}|~{3,})[^\n]*\n[\s\S]*?^[ \t]*\1\s*$/gm, "");
|
|
@@ -18308,21 +18323,21 @@ function scanMarkdownAssets(markdown) {
|
|
|
18308
18323
|
let match;
|
|
18309
18324
|
while ((match = mdImageRe.exec(stripped)) !== null) {
|
|
18310
18325
|
const src = match[1].trim();
|
|
18311
|
-
if (
|
|
18326
|
+
if (!isRemoteRef(src)) {
|
|
18312
18327
|
found.add(src);
|
|
18313
18328
|
}
|
|
18314
18329
|
}
|
|
18315
18330
|
const htmlSrcRe = /<(?:img|source|video)[^>]+\bsrc=["']([^"']+)["'][^>]*>/gi;
|
|
18316
18331
|
while ((match = htmlSrcRe.exec(stripped)) !== null) {
|
|
18317
18332
|
const src = match[1].trim();
|
|
18318
|
-
if (
|
|
18333
|
+
if (!isRemoteRef(src)) {
|
|
18319
18334
|
found.add(src);
|
|
18320
18335
|
}
|
|
18321
18336
|
}
|
|
18322
18337
|
const posterRe = /<video[^>]+\bposter=["']([^"']+)["'][^>]*>/gi;
|
|
18323
18338
|
while ((match = posterRe.exec(stripped)) !== null) {
|
|
18324
18339
|
const src = match[1].trim();
|
|
18325
|
-
if (
|
|
18340
|
+
if (!isRemoteRef(src)) {
|
|
18326
18341
|
found.add(src);
|
|
18327
18342
|
}
|
|
18328
18343
|
}
|
|
@@ -18348,48 +18363,21 @@ function isCode(segment) {
|
|
|
18348
18363
|
const trimmed = segment.trimStart();
|
|
18349
18364
|
return trimmed.startsWith("`") || trimmed.startsWith("~") || trimmed.startsWith("<pre") || trimmed.startsWith("<code");
|
|
18350
18365
|
}
|
|
18366
|
+
function resolveRewrite(trimmed, assetsBaseUrl, pathMap) {
|
|
18367
|
+
if (isRemoteRef(trimmed)) return null;
|
|
18368
|
+
if (pathMap) {
|
|
18369
|
+
const mapped = pathMap.get(trimmed);
|
|
18370
|
+
return mapped === void 0 ? null : `${assetsBaseUrl}/${mapped}`;
|
|
18371
|
+
}
|
|
18372
|
+
if (!isRelativeLocalPath(trimmed)) return null;
|
|
18373
|
+
return `${assetsBaseUrl}/${trimmed}`;
|
|
18374
|
+
}
|
|
18351
18375
|
function rewriteProseSegment(prose, assetsBaseUrl, pathMap) {
|
|
18352
|
-
|
|
18353
|
-
|
|
18354
|
-
|
|
18355
|
-
|
|
18356
|
-
|
|
18357
|
-
if (!isLocalPath(trimmed)) return full;
|
|
18358
|
-
if (pathMap) {
|
|
18359
|
-
const mapped = pathMap.get(trimmed);
|
|
18360
|
-
if (mapped === void 0) return full;
|
|
18361
|
-
return `${pre}${assetsBaseUrl}/${mapped}${post}`;
|
|
18362
|
-
}
|
|
18363
|
-
return `${pre}${assetsBaseUrl}/${trimmed}${post}`;
|
|
18364
|
-
}
|
|
18365
|
-
);
|
|
18366
|
-
result = result.replace(
|
|
18367
|
-
/(<(?:img|source|video)[^>]+\bsrc=["'])([^"']+)(["'][^>]*>)/gi,
|
|
18368
|
-
(full, pre, src, post) => {
|
|
18369
|
-
const trimmed = src.trim();
|
|
18370
|
-
if (!isLocalPath(trimmed)) return full;
|
|
18371
|
-
if (pathMap) {
|
|
18372
|
-
const mapped = pathMap.get(trimmed);
|
|
18373
|
-
if (mapped === void 0) return full;
|
|
18374
|
-
return `${pre}${assetsBaseUrl}/${mapped}${post}`;
|
|
18375
|
-
}
|
|
18376
|
-
return `${pre}${assetsBaseUrl}/${trimmed}${post}`;
|
|
18377
|
-
}
|
|
18378
|
-
);
|
|
18379
|
-
result = result.replace(
|
|
18380
|
-
/(<video[^>]+\bposter=["'])([^"']+)(["'][^>]*>)/gi,
|
|
18381
|
-
(full, pre, src, post) => {
|
|
18382
|
-
const trimmed = src.trim();
|
|
18383
|
-
if (!isLocalPath(trimmed)) return full;
|
|
18384
|
-
if (pathMap) {
|
|
18385
|
-
const mapped = pathMap.get(trimmed);
|
|
18386
|
-
if (mapped === void 0) return full;
|
|
18387
|
-
return `${pre}${assetsBaseUrl}/${mapped}${post}`;
|
|
18388
|
-
}
|
|
18389
|
-
return `${pre}${assetsBaseUrl}/${trimmed}${post}`;
|
|
18390
|
-
}
|
|
18391
|
-
);
|
|
18392
|
-
return result;
|
|
18376
|
+
const rewrite = (full, pre, src, post) => {
|
|
18377
|
+
const target = resolveRewrite(src.trim(), assetsBaseUrl, pathMap);
|
|
18378
|
+
return target === null ? full : `${pre}${target}${post}`;
|
|
18379
|
+
};
|
|
18380
|
+
return prose.replace(/(!\[[^\]]*\]\()([^)"'\s]+)((?:\s+["'][^"']*["'])?\s*\))/g, rewrite).replace(/(<(?:img|source|video)[^>]+\bsrc=["'])([^"']+)(["'][^>]*>)/gi, rewrite).replace(/(<video[^>]+\bposter=["'])([^"']+)(["'][^>]*>)/gi, rewrite);
|
|
18393
18381
|
}
|
|
18394
18382
|
function rewriteAssetPaths(markdown, assetsBaseUrl, pathMap) {
|
|
18395
18383
|
return splitByCode(markdown).map((seg) => isCode(seg) ? seg : rewriteProseSegment(seg, assetsBaseUrl, pathMap)).join("");
|
|
@@ -18406,8 +18394,9 @@ function copyMarkdownAssets(options) {
|
|
|
18406
18394
|
const pathMap = /* @__PURE__ */ new Map();
|
|
18407
18395
|
const missing = [];
|
|
18408
18396
|
for (const ref of refs) {
|
|
18409
|
-
const absPath = path6.resolve(markdownDir, ref);
|
|
18397
|
+
const absPath = isAbsoluteRef(ref) ? ref : path6.resolve(markdownDir, ref);
|
|
18410
18398
|
if (!fs5.existsSync(absPath)) {
|
|
18399
|
+
if (isAbsoluteRef(ref)) continue;
|
|
18411
18400
|
if (!allowMissing) {
|
|
18412
18401
|
throw new Error(`Asset not found: ${absPath}`);
|
|
18413
18402
|
}
|
|
@@ -22034,7 +22023,9 @@ var ReportGenerator = class {
|
|
|
22034
22023
|
permalinkBaseUrl: options.astro?.markdown?.permalinkBaseUrl,
|
|
22035
22024
|
ticketUrlTemplate: options.astro?.markdown?.ticketUrlTemplate,
|
|
22036
22025
|
traceUrlTemplate: options.astro?.markdown?.traceUrlTemplate,
|
|
22037
|
-
customRenderers: options.astro?.markdown?.customRenderers
|
|
22026
|
+
customRenderers: options.astro?.markdown?.customRenderers,
|
|
22027
|
+
scenarioAnchor: options.astro?.markdown?.scenarioAnchor,
|
|
22028
|
+
scenarioBadge: options.astro?.markdown?.scenarioBadge
|
|
22038
22029
|
}
|
|
22039
22030
|
},
|
|
22040
22031
|
assetMode: options.assetMode ?? "none",
|