hono-decks 0.2.1 → 0.2.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/advanced.js +26 -6
- package/dist/bin.js +72 -9
- package/dist/cli.js +72 -9
- package/dist/mod.js +19 -4
- package/dist/node.js +84 -12
- package/dist/vite.js +72 -9
- package/package.json +1 -1
package/dist/advanced.js
CHANGED
|
@@ -514,7 +514,7 @@ function localAssetRelativePath(sourcePath) {
|
|
|
514
514
|
return markerIndex === -1 ? normalized.split("/").at(-1) ?? normalized : normalized.slice(markerIndex + 8);
|
|
515
515
|
}
|
|
516
516
|
function normalizeVoidElementSpacing(html) {
|
|
517
|
-
return html.replace(/<(img|br|hr)([
|
|
517
|
+
return html.replace(/<(img|br|hr)([^<>]*)\/>/g, "<$1$2 />");
|
|
518
518
|
}
|
|
519
519
|
//#endregion
|
|
520
520
|
//#region src/renderer/control-icons.ts
|
|
@@ -1612,7 +1612,11 @@ function createDeckPaths(mountPath, slug) {
|
|
|
1612
1612
|
function normalizeMountPath(value) {
|
|
1613
1613
|
const trimmed = value.trim();
|
|
1614
1614
|
if (!trimmed || trimmed === "/") return "/";
|
|
1615
|
-
|
|
1615
|
+
let start = 0;
|
|
1616
|
+
let end = trimmed.length;
|
|
1617
|
+
while (trimmed[start] === "/") start += 1;
|
|
1618
|
+
while (end > start && trimmed[end - 1] === "/") end -= 1;
|
|
1619
|
+
return `/${trimmed.slice(start, end)}`;
|
|
1616
1620
|
}
|
|
1617
1621
|
//#endregion
|
|
1618
1622
|
//#region src/server/browser-export.ts
|
|
@@ -1749,7 +1753,12 @@ function recordValue(value) {
|
|
|
1749
1753
|
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : {};
|
|
1750
1754
|
}
|
|
1751
1755
|
function safeFilename$1(value) {
|
|
1752
|
-
|
|
1756
|
+
const sanitized = value.trim().replaceAll(/[^a-zA-Z0-9._-]+/g, "-");
|
|
1757
|
+
let start = 0;
|
|
1758
|
+
let end = sanitized.length;
|
|
1759
|
+
while (sanitized[start] === "-") start += 1;
|
|
1760
|
+
while (end > start && sanitized[end - 1] === "-") end -= 1;
|
|
1761
|
+
return sanitized.slice(start, end) || "deck";
|
|
1753
1762
|
}
|
|
1754
1763
|
//#endregion
|
|
1755
1764
|
//#region src/server/viewer-script.ts
|
|
@@ -3225,7 +3234,7 @@ async function resolveBucket(bucket, c) {
|
|
|
3225
3234
|
return typeof bucket === "function" ? bucket(c) : bucket;
|
|
3226
3235
|
}
|
|
3227
3236
|
function findRoutableAsset(assets, slug, assetPath) {
|
|
3228
|
-
const normalized = assetPath
|
|
3237
|
+
const normalized = stripLeadingSlashes(assetPath);
|
|
3229
3238
|
return assets.find((asset) => {
|
|
3230
3239
|
if (asset.type !== "local" && asset.type !== "r2") return false;
|
|
3231
3240
|
const suffix = `/${slug}/assets/${normalized}`;
|
|
@@ -3236,8 +3245,19 @@ function resolveR2Key(input, options) {
|
|
|
3236
3245
|
if (options.key) return options.key(input);
|
|
3237
3246
|
if (input.asset.r2Key) return input.asset.r2Key;
|
|
3238
3247
|
const key = input.asset.sourcePath || `${input.slug}/assets/${input.assetPath}`;
|
|
3239
|
-
const prefix = options.keyPrefix
|
|
3240
|
-
|
|
3248
|
+
const prefix = options.keyPrefix ? stripTrailingSlashes(options.keyPrefix) : void 0;
|
|
3249
|
+
const normalizedKey = stripLeadingSlashes(key);
|
|
3250
|
+
return prefix ? `${prefix}/${normalizedKey}` : normalizedKey;
|
|
3251
|
+
}
|
|
3252
|
+
function stripLeadingSlashes(value) {
|
|
3253
|
+
let index = 0;
|
|
3254
|
+
while (value[index] === "/") index += 1;
|
|
3255
|
+
return value.slice(index);
|
|
3256
|
+
}
|
|
3257
|
+
function stripTrailingSlashes(value) {
|
|
3258
|
+
let end = value.length;
|
|
3259
|
+
while (end > 0 && value[end - 1] === "/") end -= 1;
|
|
3260
|
+
return value.slice(0, end);
|
|
3241
3261
|
}
|
|
3242
3262
|
async function responseFromR2Object(object, input, options) {
|
|
3243
3263
|
const body = object.body ?? (object.arrayBuffer ? await object.arrayBuffer() : void 0);
|
package/dist/bin.js
CHANGED
|
@@ -350,8 +350,8 @@ function addExternalAssetWarnings(warnings, assets) {
|
|
|
350
350
|
}
|
|
351
351
|
function collectMarkdownAssetCandidates(markdown) {
|
|
352
352
|
const candidates = [];
|
|
353
|
-
|
|
354
|
-
|
|
353
|
+
candidates.push(...collectDirectiveAssetCandidates(markdown));
|
|
354
|
+
candidates.push(...collectMarkdownImageCandidates(markdown));
|
|
355
355
|
for (const match of markdown.matchAll(/\b(?:src|href|image|background)=["']([^"']+)["']/g)) candidates.push(match[1].trim());
|
|
356
356
|
return candidates;
|
|
357
357
|
}
|
|
@@ -361,12 +361,75 @@ function collectFrontmatterAssetCandidates(value) {
|
|
|
361
361
|
return [];
|
|
362
362
|
}
|
|
363
363
|
function contentTypeForPath(path) {
|
|
364
|
-
const
|
|
365
|
-
|
|
366
|
-
if (
|
|
367
|
-
if (
|
|
368
|
-
if (
|
|
369
|
-
if (
|
|
364
|
+
const queryIndex = path.indexOf("?");
|
|
365
|
+
const pathname = (queryIndex === -1 ? path : path.slice(0, queryIndex)).toLowerCase();
|
|
366
|
+
if (hasExtension(pathname, ".png")) return "image/png";
|
|
367
|
+
if (hasExtension(pathname, ".jpg") || hasExtension(pathname, ".jpeg")) return "image/jpeg";
|
|
368
|
+
if (hasExtension(pathname, ".gif")) return "image/gif";
|
|
369
|
+
if (hasExtension(pathname, ".svg")) return "image/svg+xml";
|
|
370
|
+
if (hasExtension(pathname, ".webp")) return "image/webp";
|
|
371
|
+
}
|
|
372
|
+
function hasExtension(path, extension) {
|
|
373
|
+
return path.endsWith(extension) || path.includes(`${extension}#`);
|
|
374
|
+
}
|
|
375
|
+
function collectDirectiveAssetCandidates(markdown) {
|
|
376
|
+
const candidates = [];
|
|
377
|
+
for (const sourceLine of markdown.split("\n")) {
|
|
378
|
+
const line = sourceLine.endsWith("\r") ? sourceLine.slice(0, -1).trim() : sourceLine.trim();
|
|
379
|
+
const separator = line.indexOf(":");
|
|
380
|
+
if (separator === -1) continue;
|
|
381
|
+
const key = line.slice(0, separator).toLowerCase();
|
|
382
|
+
if (key !== "background" && key !== "image" && key !== "src" && key !== "asset") continue;
|
|
383
|
+
let value = line.slice(separator + 1).trim();
|
|
384
|
+
if (value.startsWith("\"") || value.startsWith("'")) value = value.slice(1);
|
|
385
|
+
if (value.endsWith("\"") || value.endsWith("'")) value = value.slice(0, -1);
|
|
386
|
+
value = value.trim();
|
|
387
|
+
if (value && !value.includes("\"") && !value.includes("'")) candidates.push(value);
|
|
388
|
+
}
|
|
389
|
+
return candidates;
|
|
390
|
+
}
|
|
391
|
+
function collectMarkdownImageCandidates(markdown) {
|
|
392
|
+
const candidates = [];
|
|
393
|
+
let index = 0;
|
|
394
|
+
while (index < markdown.length - 1) {
|
|
395
|
+
const imageStart = markdown.indexOf("![", index);
|
|
396
|
+
if (imageStart === -1) break;
|
|
397
|
+
const labelEnd = markdown.indexOf("]", imageStart + 2);
|
|
398
|
+
if (labelEnd === -1) break;
|
|
399
|
+
if (markdown[labelEnd + 1] !== "(") {
|
|
400
|
+
index = labelEnd + 1;
|
|
401
|
+
continue;
|
|
402
|
+
}
|
|
403
|
+
let cursor = labelEnd + 2;
|
|
404
|
+
const destinationStart = cursor;
|
|
405
|
+
while (cursor < markdown.length && markdown[cursor] !== ")" && !isMarkdownWhitespace(markdown[cursor])) cursor += 1;
|
|
406
|
+
if (cursor === destinationStart) {
|
|
407
|
+
index = cursor + 1;
|
|
408
|
+
continue;
|
|
409
|
+
}
|
|
410
|
+
const destination = markdown.slice(destinationStart, cursor);
|
|
411
|
+
while (cursor < markdown.length && isMarkdownWhitespace(markdown[cursor])) cursor += 1;
|
|
412
|
+
if (markdown[cursor] !== ")") {
|
|
413
|
+
const quote = markdown[cursor];
|
|
414
|
+
if (quote !== "\"" && quote !== "'") {
|
|
415
|
+
index = cursor + 1;
|
|
416
|
+
continue;
|
|
417
|
+
}
|
|
418
|
+
cursor += 1;
|
|
419
|
+
while (cursor < markdown.length && markdown[cursor] !== "\"" && markdown[cursor] !== "'") cursor += 1;
|
|
420
|
+
if (cursor >= markdown.length) break;
|
|
421
|
+
cursor += 1;
|
|
422
|
+
while (cursor < markdown.length && isMarkdownWhitespace(markdown[cursor])) cursor += 1;
|
|
423
|
+
}
|
|
424
|
+
if (markdown[cursor] === ")") {
|
|
425
|
+
candidates.push(destination);
|
|
426
|
+
index = cursor + 1;
|
|
427
|
+
} else index = cursor + 1;
|
|
428
|
+
}
|
|
429
|
+
return candidates;
|
|
430
|
+
}
|
|
431
|
+
function isMarkdownWhitespace(value) {
|
|
432
|
+
return value === " " || value === " " || value === "\r" || value === "\n";
|
|
370
433
|
}
|
|
371
434
|
function assetRefType(value) {
|
|
372
435
|
if (/^https?:\/\//i.test(value)) return "remote";
|
|
@@ -1720,7 +1783,7 @@ function absoluteUrl(value, base) {
|
|
|
1720
1783
|
}
|
|
1721
1784
|
}
|
|
1722
1785
|
function decodeHtmlEntities(value) {
|
|
1723
|
-
return value.replaceAll("&
|
|
1786
|
+
return value.replaceAll(""", "\"").replaceAll("'", "'").replaceAll("<", "<").replaceAll(">", ">").replaceAll("&", "&");
|
|
1724
1787
|
}
|
|
1725
1788
|
function isHttpUrl(value) {
|
|
1726
1789
|
try {
|
package/dist/cli.js
CHANGED
|
@@ -349,8 +349,8 @@ function addExternalAssetWarnings(warnings, assets) {
|
|
|
349
349
|
}
|
|
350
350
|
function collectMarkdownAssetCandidates(markdown) {
|
|
351
351
|
const candidates = [];
|
|
352
|
-
|
|
353
|
-
|
|
352
|
+
candidates.push(...collectDirectiveAssetCandidates(markdown));
|
|
353
|
+
candidates.push(...collectMarkdownImageCandidates(markdown));
|
|
354
354
|
for (const match of markdown.matchAll(/\b(?:src|href|image|background)=["']([^"']+)["']/g)) candidates.push(match[1].trim());
|
|
355
355
|
return candidates;
|
|
356
356
|
}
|
|
@@ -360,12 +360,75 @@ function collectFrontmatterAssetCandidates(value) {
|
|
|
360
360
|
return [];
|
|
361
361
|
}
|
|
362
362
|
function contentTypeForPath(path) {
|
|
363
|
-
const
|
|
364
|
-
|
|
365
|
-
if (
|
|
366
|
-
if (
|
|
367
|
-
if (
|
|
368
|
-
if (
|
|
363
|
+
const queryIndex = path.indexOf("?");
|
|
364
|
+
const pathname = (queryIndex === -1 ? path : path.slice(0, queryIndex)).toLowerCase();
|
|
365
|
+
if (hasExtension(pathname, ".png")) return "image/png";
|
|
366
|
+
if (hasExtension(pathname, ".jpg") || hasExtension(pathname, ".jpeg")) return "image/jpeg";
|
|
367
|
+
if (hasExtension(pathname, ".gif")) return "image/gif";
|
|
368
|
+
if (hasExtension(pathname, ".svg")) return "image/svg+xml";
|
|
369
|
+
if (hasExtension(pathname, ".webp")) return "image/webp";
|
|
370
|
+
}
|
|
371
|
+
function hasExtension(path, extension) {
|
|
372
|
+
return path.endsWith(extension) || path.includes(`${extension}#`);
|
|
373
|
+
}
|
|
374
|
+
function collectDirectiveAssetCandidates(markdown) {
|
|
375
|
+
const candidates = [];
|
|
376
|
+
for (const sourceLine of markdown.split("\n")) {
|
|
377
|
+
const line = sourceLine.endsWith("\r") ? sourceLine.slice(0, -1).trim() : sourceLine.trim();
|
|
378
|
+
const separator = line.indexOf(":");
|
|
379
|
+
if (separator === -1) continue;
|
|
380
|
+
const key = line.slice(0, separator).toLowerCase();
|
|
381
|
+
if (key !== "background" && key !== "image" && key !== "src" && key !== "asset") continue;
|
|
382
|
+
let value = line.slice(separator + 1).trim();
|
|
383
|
+
if (value.startsWith("\"") || value.startsWith("'")) value = value.slice(1);
|
|
384
|
+
if (value.endsWith("\"") || value.endsWith("'")) value = value.slice(0, -1);
|
|
385
|
+
value = value.trim();
|
|
386
|
+
if (value && !value.includes("\"") && !value.includes("'")) candidates.push(value);
|
|
387
|
+
}
|
|
388
|
+
return candidates;
|
|
389
|
+
}
|
|
390
|
+
function collectMarkdownImageCandidates(markdown) {
|
|
391
|
+
const candidates = [];
|
|
392
|
+
let index = 0;
|
|
393
|
+
while (index < markdown.length - 1) {
|
|
394
|
+
const imageStart = markdown.indexOf("![", index);
|
|
395
|
+
if (imageStart === -1) break;
|
|
396
|
+
const labelEnd = markdown.indexOf("]", imageStart + 2);
|
|
397
|
+
if (labelEnd === -1) break;
|
|
398
|
+
if (markdown[labelEnd + 1] !== "(") {
|
|
399
|
+
index = labelEnd + 1;
|
|
400
|
+
continue;
|
|
401
|
+
}
|
|
402
|
+
let cursor = labelEnd + 2;
|
|
403
|
+
const destinationStart = cursor;
|
|
404
|
+
while (cursor < markdown.length && markdown[cursor] !== ")" && !isMarkdownWhitespace(markdown[cursor])) cursor += 1;
|
|
405
|
+
if (cursor === destinationStart) {
|
|
406
|
+
index = cursor + 1;
|
|
407
|
+
continue;
|
|
408
|
+
}
|
|
409
|
+
const destination = markdown.slice(destinationStart, cursor);
|
|
410
|
+
while (cursor < markdown.length && isMarkdownWhitespace(markdown[cursor])) cursor += 1;
|
|
411
|
+
if (markdown[cursor] !== ")") {
|
|
412
|
+
const quote = markdown[cursor];
|
|
413
|
+
if (quote !== "\"" && quote !== "'") {
|
|
414
|
+
index = cursor + 1;
|
|
415
|
+
continue;
|
|
416
|
+
}
|
|
417
|
+
cursor += 1;
|
|
418
|
+
while (cursor < markdown.length && markdown[cursor] !== "\"" && markdown[cursor] !== "'") cursor += 1;
|
|
419
|
+
if (cursor >= markdown.length) break;
|
|
420
|
+
cursor += 1;
|
|
421
|
+
while (cursor < markdown.length && isMarkdownWhitespace(markdown[cursor])) cursor += 1;
|
|
422
|
+
}
|
|
423
|
+
if (markdown[cursor] === ")") {
|
|
424
|
+
candidates.push(destination);
|
|
425
|
+
index = cursor + 1;
|
|
426
|
+
} else index = cursor + 1;
|
|
427
|
+
}
|
|
428
|
+
return candidates;
|
|
429
|
+
}
|
|
430
|
+
function isMarkdownWhitespace(value) {
|
|
431
|
+
return value === " " || value === " " || value === "\r" || value === "\n";
|
|
369
432
|
}
|
|
370
433
|
function assetRefType(value) {
|
|
371
434
|
if (/^https?:\/\//i.test(value)) return "remote";
|
|
@@ -1719,7 +1782,7 @@ function absoluteUrl(value, base) {
|
|
|
1719
1782
|
}
|
|
1720
1783
|
}
|
|
1721
1784
|
function decodeHtmlEntities(value) {
|
|
1722
|
-
return value.replaceAll("&
|
|
1785
|
+
return value.replaceAll(""", "\"").replaceAll("'", "'").replaceAll("<", "<").replaceAll(">", ">").replaceAll("&", "&");
|
|
1723
1786
|
}
|
|
1724
1787
|
function isHttpUrl(value) {
|
|
1725
1788
|
try {
|
package/dist/mod.js
CHANGED
|
@@ -431,7 +431,11 @@ function createDeckPaths(mountPath, slug) {
|
|
|
431
431
|
function normalizeMountPath(value) {
|
|
432
432
|
const trimmed = value.trim();
|
|
433
433
|
if (!trimmed || trimmed === "/") return "/";
|
|
434
|
-
|
|
434
|
+
let start = 0;
|
|
435
|
+
let end = trimmed.length;
|
|
436
|
+
while (trimmed[start] === "/") start += 1;
|
|
437
|
+
while (end > start && trimmed[end - 1] === "/") end -= 1;
|
|
438
|
+
return `/${trimmed.slice(start, end)}`;
|
|
435
439
|
}
|
|
436
440
|
//#endregion
|
|
437
441
|
//#region src/server/viewer-script.ts
|
|
@@ -1068,7 +1072,7 @@ async function resolveBucket(bucket, c) {
|
|
|
1068
1072
|
return typeof bucket === "function" ? bucket(c) : bucket;
|
|
1069
1073
|
}
|
|
1070
1074
|
function findRoutableAsset(assets, slug, assetPath) {
|
|
1071
|
-
const normalized = assetPath
|
|
1075
|
+
const normalized = stripLeadingSlashes(assetPath);
|
|
1072
1076
|
return assets.find((asset) => {
|
|
1073
1077
|
if (asset.type !== "local" && asset.type !== "r2") return false;
|
|
1074
1078
|
const suffix = `/${slug}/assets/${normalized}`;
|
|
@@ -1079,8 +1083,19 @@ function resolveR2Key(input, options) {
|
|
|
1079
1083
|
if (options.key) return options.key(input);
|
|
1080
1084
|
if (input.asset.r2Key) return input.asset.r2Key;
|
|
1081
1085
|
const key = input.asset.sourcePath || `${input.slug}/assets/${input.assetPath}`;
|
|
1082
|
-
const prefix = options.keyPrefix
|
|
1083
|
-
|
|
1086
|
+
const prefix = options.keyPrefix ? stripTrailingSlashes(options.keyPrefix) : void 0;
|
|
1087
|
+
const normalizedKey = stripLeadingSlashes(key);
|
|
1088
|
+
return prefix ? `${prefix}/${normalizedKey}` : normalizedKey;
|
|
1089
|
+
}
|
|
1090
|
+
function stripLeadingSlashes(value) {
|
|
1091
|
+
let index = 0;
|
|
1092
|
+
while (value[index] === "/") index += 1;
|
|
1093
|
+
return value.slice(index);
|
|
1094
|
+
}
|
|
1095
|
+
function stripTrailingSlashes(value) {
|
|
1096
|
+
let end = value.length;
|
|
1097
|
+
while (end > 0 && value[end - 1] === "/") end -= 1;
|
|
1098
|
+
return value.slice(0, end);
|
|
1084
1099
|
}
|
|
1085
1100
|
async function responseFromR2Object(object, input, options) {
|
|
1086
1101
|
const body = object.body ?? (object.arrayBuffer ? await object.arrayBuffer() : void 0);
|
package/dist/node.js
CHANGED
|
@@ -363,8 +363,8 @@ function addExternalAssetWarnings(warnings, assets) {
|
|
|
363
363
|
}
|
|
364
364
|
function collectMarkdownAssetCandidates(markdown) {
|
|
365
365
|
const candidates = [];
|
|
366
|
-
|
|
367
|
-
|
|
366
|
+
candidates.push(...collectDirectiveAssetCandidates(markdown));
|
|
367
|
+
candidates.push(...collectMarkdownImageCandidates(markdown));
|
|
368
368
|
for (const match of markdown.matchAll(/\b(?:src|href|image|background)=["']([^"']+)["']/g)) candidates.push(match[1].trim());
|
|
369
369
|
return candidates;
|
|
370
370
|
}
|
|
@@ -379,12 +379,75 @@ function isLocalRelativeAssetCandidate(value) {
|
|
|
379
379
|
return /^[^/:?#]+\.(?:png|jpe?g|gif|svg|webp)(?:[?#].*)?$/i.test(value);
|
|
380
380
|
}
|
|
381
381
|
function contentTypeForPath(path) {
|
|
382
|
-
const
|
|
383
|
-
|
|
384
|
-
if (
|
|
385
|
-
if (
|
|
386
|
-
if (
|
|
387
|
-
if (
|
|
382
|
+
const queryIndex = path.indexOf("?");
|
|
383
|
+
const pathname = (queryIndex === -1 ? path : path.slice(0, queryIndex)).toLowerCase();
|
|
384
|
+
if (hasExtension(pathname, ".png")) return "image/png";
|
|
385
|
+
if (hasExtension(pathname, ".jpg") || hasExtension(pathname, ".jpeg")) return "image/jpeg";
|
|
386
|
+
if (hasExtension(pathname, ".gif")) return "image/gif";
|
|
387
|
+
if (hasExtension(pathname, ".svg")) return "image/svg+xml";
|
|
388
|
+
if (hasExtension(pathname, ".webp")) return "image/webp";
|
|
389
|
+
}
|
|
390
|
+
function hasExtension(path, extension) {
|
|
391
|
+
return path.endsWith(extension) || path.includes(`${extension}#`);
|
|
392
|
+
}
|
|
393
|
+
function collectDirectiveAssetCandidates(markdown) {
|
|
394
|
+
const candidates = [];
|
|
395
|
+
for (const sourceLine of markdown.split("\n")) {
|
|
396
|
+
const line = sourceLine.endsWith("\r") ? sourceLine.slice(0, -1).trim() : sourceLine.trim();
|
|
397
|
+
const separator = line.indexOf(":");
|
|
398
|
+
if (separator === -1) continue;
|
|
399
|
+
const key = line.slice(0, separator).toLowerCase();
|
|
400
|
+
if (key !== "background" && key !== "image" && key !== "src" && key !== "asset") continue;
|
|
401
|
+
let value = line.slice(separator + 1).trim();
|
|
402
|
+
if (value.startsWith("\"") || value.startsWith("'")) value = value.slice(1);
|
|
403
|
+
if (value.endsWith("\"") || value.endsWith("'")) value = value.slice(0, -1);
|
|
404
|
+
value = value.trim();
|
|
405
|
+
if (value && !value.includes("\"") && !value.includes("'")) candidates.push(value);
|
|
406
|
+
}
|
|
407
|
+
return candidates;
|
|
408
|
+
}
|
|
409
|
+
function collectMarkdownImageCandidates(markdown) {
|
|
410
|
+
const candidates = [];
|
|
411
|
+
let index = 0;
|
|
412
|
+
while (index < markdown.length - 1) {
|
|
413
|
+
const imageStart = markdown.indexOf("![", index);
|
|
414
|
+
if (imageStart === -1) break;
|
|
415
|
+
const labelEnd = markdown.indexOf("]", imageStart + 2);
|
|
416
|
+
if (labelEnd === -1) break;
|
|
417
|
+
if (markdown[labelEnd + 1] !== "(") {
|
|
418
|
+
index = labelEnd + 1;
|
|
419
|
+
continue;
|
|
420
|
+
}
|
|
421
|
+
let cursor = labelEnd + 2;
|
|
422
|
+
const destinationStart = cursor;
|
|
423
|
+
while (cursor < markdown.length && markdown[cursor] !== ")" && !isMarkdownWhitespace(markdown[cursor])) cursor += 1;
|
|
424
|
+
if (cursor === destinationStart) {
|
|
425
|
+
index = cursor + 1;
|
|
426
|
+
continue;
|
|
427
|
+
}
|
|
428
|
+
const destination = markdown.slice(destinationStart, cursor);
|
|
429
|
+
while (cursor < markdown.length && isMarkdownWhitespace(markdown[cursor])) cursor += 1;
|
|
430
|
+
if (markdown[cursor] !== ")") {
|
|
431
|
+
const quote = markdown[cursor];
|
|
432
|
+
if (quote !== "\"" && quote !== "'") {
|
|
433
|
+
index = cursor + 1;
|
|
434
|
+
continue;
|
|
435
|
+
}
|
|
436
|
+
cursor += 1;
|
|
437
|
+
while (cursor < markdown.length && markdown[cursor] !== "\"" && markdown[cursor] !== "'") cursor += 1;
|
|
438
|
+
if (cursor >= markdown.length) break;
|
|
439
|
+
cursor += 1;
|
|
440
|
+
while (cursor < markdown.length && isMarkdownWhitespace(markdown[cursor])) cursor += 1;
|
|
441
|
+
}
|
|
442
|
+
if (markdown[cursor] === ")") {
|
|
443
|
+
candidates.push(destination);
|
|
444
|
+
index = cursor + 1;
|
|
445
|
+
} else index = cursor + 1;
|
|
446
|
+
}
|
|
447
|
+
return candidates;
|
|
448
|
+
}
|
|
449
|
+
function isMarkdownWhitespace(value) {
|
|
450
|
+
return value === " " || value === " " || value === "\r" || value === "\n";
|
|
388
451
|
}
|
|
389
452
|
function assetRefType(value) {
|
|
390
453
|
if (/^https?:\/\//i.test(value)) return "remote";
|
|
@@ -2066,7 +2129,7 @@ function absoluteUrl(value, base) {
|
|
|
2066
2129
|
}
|
|
2067
2130
|
}
|
|
2068
2131
|
function decodeHtmlEntities(value) {
|
|
2069
|
-
return value.replaceAll("&
|
|
2132
|
+
return value.replaceAll(""", "\"").replaceAll("'", "'").replaceAll("<", "<").replaceAll(">", ">").replaceAll("&", "&");
|
|
2070
2133
|
}
|
|
2071
2134
|
function isHttpUrl(value) {
|
|
2072
2135
|
try {
|
|
@@ -2874,7 +2937,7 @@ function localAssetRelativePath(sourcePath) {
|
|
|
2874
2937
|
return markerIndex === -1 ? normalized.split("/").at(-1) ?? normalized : normalized.slice(markerIndex + 8);
|
|
2875
2938
|
}
|
|
2876
2939
|
function normalizeVoidElementSpacing(html) {
|
|
2877
|
-
return html.replace(/<(img|br|hr)([
|
|
2940
|
+
return html.replace(/<(img|br|hr)([^<>]*)\/>/g, "<$1$2 />");
|
|
2878
2941
|
}
|
|
2879
2942
|
//#endregion
|
|
2880
2943
|
//#region src/renderer/control-icons.ts
|
|
@@ -3909,7 +3972,11 @@ function createDeckPaths(mountPath, slug) {
|
|
|
3909
3972
|
function normalizeMountPath(value) {
|
|
3910
3973
|
const trimmed = value.trim();
|
|
3911
3974
|
if (!trimmed || trimmed === "/") return "/";
|
|
3912
|
-
|
|
3975
|
+
let start = 0;
|
|
3976
|
+
let end = trimmed.length;
|
|
3977
|
+
while (trimmed[start] === "/") start += 1;
|
|
3978
|
+
while (end > start && trimmed[end - 1] === "/") end -= 1;
|
|
3979
|
+
return `/${trimmed.slice(start, end)}`;
|
|
3913
3980
|
}
|
|
3914
3981
|
//#endregion
|
|
3915
3982
|
//#region src/server/browser-export.ts
|
|
@@ -4046,7 +4113,12 @@ function recordValue(value) {
|
|
|
4046
4113
|
return typeof value === "object" && value !== null && !Array.isArray(value) ? value : {};
|
|
4047
4114
|
}
|
|
4048
4115
|
function safeFilename$1(value) {
|
|
4049
|
-
|
|
4116
|
+
const sanitized = value.trim().replaceAll(/[^a-zA-Z0-9._-]+/g, "-");
|
|
4117
|
+
let start = 0;
|
|
4118
|
+
let end = sanitized.length;
|
|
4119
|
+
while (sanitized[start] === "-") start += 1;
|
|
4120
|
+
while (end > start && sanitized[end - 1] === "-") end -= 1;
|
|
4121
|
+
return sanitized.slice(start, end) || "deck";
|
|
4050
4122
|
}
|
|
4051
4123
|
//#endregion
|
|
4052
4124
|
//#region src/server/viewer-script.ts
|
package/dist/vite.js
CHANGED
|
@@ -349,8 +349,8 @@ function addExternalAssetWarnings(warnings, assets) {
|
|
|
349
349
|
}
|
|
350
350
|
function collectMarkdownAssetCandidates(markdown) {
|
|
351
351
|
const candidates = [];
|
|
352
|
-
|
|
353
|
-
|
|
352
|
+
candidates.push(...collectDirectiveAssetCandidates(markdown));
|
|
353
|
+
candidates.push(...collectMarkdownImageCandidates(markdown));
|
|
354
354
|
for (const match of markdown.matchAll(/\b(?:src|href|image|background)=["']([^"']+)["']/g)) candidates.push(match[1].trim());
|
|
355
355
|
return candidates;
|
|
356
356
|
}
|
|
@@ -360,12 +360,75 @@ function collectFrontmatterAssetCandidates(value) {
|
|
|
360
360
|
return [];
|
|
361
361
|
}
|
|
362
362
|
function contentTypeForPath(path) {
|
|
363
|
-
const
|
|
364
|
-
|
|
365
|
-
if (
|
|
366
|
-
if (
|
|
367
|
-
if (
|
|
368
|
-
if (
|
|
363
|
+
const queryIndex = path.indexOf("?");
|
|
364
|
+
const pathname = (queryIndex === -1 ? path : path.slice(0, queryIndex)).toLowerCase();
|
|
365
|
+
if (hasExtension(pathname, ".png")) return "image/png";
|
|
366
|
+
if (hasExtension(pathname, ".jpg") || hasExtension(pathname, ".jpeg")) return "image/jpeg";
|
|
367
|
+
if (hasExtension(pathname, ".gif")) return "image/gif";
|
|
368
|
+
if (hasExtension(pathname, ".svg")) return "image/svg+xml";
|
|
369
|
+
if (hasExtension(pathname, ".webp")) return "image/webp";
|
|
370
|
+
}
|
|
371
|
+
function hasExtension(path, extension) {
|
|
372
|
+
return path.endsWith(extension) || path.includes(`${extension}#`);
|
|
373
|
+
}
|
|
374
|
+
function collectDirectiveAssetCandidates(markdown) {
|
|
375
|
+
const candidates = [];
|
|
376
|
+
for (const sourceLine of markdown.split("\n")) {
|
|
377
|
+
const line = sourceLine.endsWith("\r") ? sourceLine.slice(0, -1).trim() : sourceLine.trim();
|
|
378
|
+
const separator = line.indexOf(":");
|
|
379
|
+
if (separator === -1) continue;
|
|
380
|
+
const key = line.slice(0, separator).toLowerCase();
|
|
381
|
+
if (key !== "background" && key !== "image" && key !== "src" && key !== "asset") continue;
|
|
382
|
+
let value = line.slice(separator + 1).trim();
|
|
383
|
+
if (value.startsWith("\"") || value.startsWith("'")) value = value.slice(1);
|
|
384
|
+
if (value.endsWith("\"") || value.endsWith("'")) value = value.slice(0, -1);
|
|
385
|
+
value = value.trim();
|
|
386
|
+
if (value && !value.includes("\"") && !value.includes("'")) candidates.push(value);
|
|
387
|
+
}
|
|
388
|
+
return candidates;
|
|
389
|
+
}
|
|
390
|
+
function collectMarkdownImageCandidates(markdown) {
|
|
391
|
+
const candidates = [];
|
|
392
|
+
let index = 0;
|
|
393
|
+
while (index < markdown.length - 1) {
|
|
394
|
+
const imageStart = markdown.indexOf("![", index);
|
|
395
|
+
if (imageStart === -1) break;
|
|
396
|
+
const labelEnd = markdown.indexOf("]", imageStart + 2);
|
|
397
|
+
if (labelEnd === -1) break;
|
|
398
|
+
if (markdown[labelEnd + 1] !== "(") {
|
|
399
|
+
index = labelEnd + 1;
|
|
400
|
+
continue;
|
|
401
|
+
}
|
|
402
|
+
let cursor = labelEnd + 2;
|
|
403
|
+
const destinationStart = cursor;
|
|
404
|
+
while (cursor < markdown.length && markdown[cursor] !== ")" && !isMarkdownWhitespace(markdown[cursor])) cursor += 1;
|
|
405
|
+
if (cursor === destinationStart) {
|
|
406
|
+
index = cursor + 1;
|
|
407
|
+
continue;
|
|
408
|
+
}
|
|
409
|
+
const destination = markdown.slice(destinationStart, cursor);
|
|
410
|
+
while (cursor < markdown.length && isMarkdownWhitespace(markdown[cursor])) cursor += 1;
|
|
411
|
+
if (markdown[cursor] !== ")") {
|
|
412
|
+
const quote = markdown[cursor];
|
|
413
|
+
if (quote !== "\"" && quote !== "'") {
|
|
414
|
+
index = cursor + 1;
|
|
415
|
+
continue;
|
|
416
|
+
}
|
|
417
|
+
cursor += 1;
|
|
418
|
+
while (cursor < markdown.length && markdown[cursor] !== "\"" && markdown[cursor] !== "'") cursor += 1;
|
|
419
|
+
if (cursor >= markdown.length) break;
|
|
420
|
+
cursor += 1;
|
|
421
|
+
while (cursor < markdown.length && isMarkdownWhitespace(markdown[cursor])) cursor += 1;
|
|
422
|
+
}
|
|
423
|
+
if (markdown[cursor] === ")") {
|
|
424
|
+
candidates.push(destination);
|
|
425
|
+
index = cursor + 1;
|
|
426
|
+
} else index = cursor + 1;
|
|
427
|
+
}
|
|
428
|
+
return candidates;
|
|
429
|
+
}
|
|
430
|
+
function isMarkdownWhitespace(value) {
|
|
431
|
+
return value === " " || value === " " || value === "\r" || value === "\n";
|
|
369
432
|
}
|
|
370
433
|
function assetRefType(value) {
|
|
371
434
|
if (/^https?:\/\//i.test(value)) return "remote";
|
|
@@ -1719,7 +1782,7 @@ function absoluteUrl(value, base) {
|
|
|
1719
1782
|
}
|
|
1720
1783
|
}
|
|
1721
1784
|
function decodeHtmlEntities(value) {
|
|
1722
|
-
return value.replaceAll("&
|
|
1785
|
+
return value.replaceAll(""", "\"").replaceAll("'", "'").replaceAll("<", "<").replaceAll(">", ">").replaceAll("&", "&");
|
|
1723
1786
|
}
|
|
1724
1787
|
function isHttpUrl(value) {
|
|
1725
1788
|
try {
|