feat(publish): auto-localize Leaflet CDN to platform assets
Memind CI / Test, build, and release guards (push) Failing after 3m57s
Memind CI / Test, build, and release guards (push) Failing after 3m57s
Ship Leaflet 1.9.4 under public/assets/leaflet and rewrite common CDN script/stylesheet URLs during publish and public HTML delivery, matching the existing Chart.js guard pattern. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -1,4 +1,8 @@
|
||||
const SCRIPT_SRC_PATTERN = /<script\b([^>]*)\bsrc\s*=\s*(['"])([^'"]+)\2([^>]*)>/gi;
|
||||
const STYLESHEET_HREF_PATTERN =
|
||||
/<link\b([^>]*)\brel\s*=\s*(['"])stylesheet\2([^>]*)\bhref\s*=\s*(['"])([^'"]+)\4([^>]*)>/gi;
|
||||
const STYLESHEET_HREF_ALT_PATTERN =
|
||||
/<link\b([^>]*)\bhref\s*=\s*(['"])([^'"]+)\2([^>]*)\brel\s*=\s*(['"])stylesheet\5([^>]*)>/gi;
|
||||
|
||||
export const KNOWN_PLATFORM_SCRIPT_ALIASES = [
|
||||
{
|
||||
@@ -10,6 +14,27 @@ export const KNOWN_PLATFORM_SCRIPT_ALIASES = [
|
||||
/unpkg\.com\/chart\.js(?:@[^/]+)?\/dist\/chart\.(?:umd\.)?min\.js/i,
|
||||
],
|
||||
},
|
||||
{
|
||||
id: 'leaflet',
|
||||
target: '/assets/leaflet/leaflet.js',
|
||||
patterns: [
|
||||
/cdn\.jsdelivr\.net\/npm\/leaflet(?:@[^/]+)?\/dist\/leaflet\.js/i,
|
||||
/cdnjs\.cloudflare\.com\/ajax\/libs\/leaflet\/[^/]+\/leaflet\.js/i,
|
||||
/unpkg\.com\/leaflet(?:@[^/]+)?\/dist\/leaflet\.js/i,
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
export const KNOWN_PLATFORM_STYLESHEET_ALIASES = [
|
||||
{
|
||||
id: 'leaflet',
|
||||
target: '/assets/leaflet/leaflet.css',
|
||||
patterns: [
|
||||
/cdn\.jsdelivr\.net\/npm\/leaflet(?:@[^/]+)?\/dist\/leaflet\.css/i,
|
||||
/cdnjs\.cloudflare\.com\/ajax\/libs\/leaflet\/[^/]+\/leaflet\.css/i,
|
||||
/unpkg\.com\/leaflet(?:@[^/]+)?\/dist\/leaflet\.css/i,
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
function normalizeScriptUrl(value) {
|
||||
@@ -24,11 +49,11 @@ export function isExternalScriptSrc(src) {
|
||||
return false;
|
||||
}
|
||||
|
||||
function resolveKnownPlatformScriptTarget(src) {
|
||||
function resolveKnownPlatformTarget(src, aliases) {
|
||||
const normalized = normalizeScriptUrl(src);
|
||||
if (!isExternalScriptSrc(normalized)) return null;
|
||||
const probe = normalized.startsWith('//') ? `https:${normalized}` : normalized;
|
||||
for (const alias of KNOWN_PLATFORM_SCRIPT_ALIASES) {
|
||||
for (const alias of aliases) {
|
||||
if (alias.patterns.some((pattern) => pattern.test(probe))) {
|
||||
return alias.target;
|
||||
}
|
||||
@@ -36,6 +61,14 @@ function resolveKnownPlatformScriptTarget(src) {
|
||||
return null;
|
||||
}
|
||||
|
||||
function resolveKnownPlatformScriptTarget(src) {
|
||||
return resolveKnownPlatformTarget(src, KNOWN_PLATFORM_SCRIPT_ALIASES);
|
||||
}
|
||||
|
||||
function resolveKnownPlatformStylesheetTarget(href) {
|
||||
return resolveKnownPlatformTarget(href, KNOWN_PLATFORM_STYLESHEET_ALIASES);
|
||||
}
|
||||
|
||||
export function findExternalScriptSources(html) {
|
||||
const sources = [];
|
||||
const seen = new Set();
|
||||
@@ -66,3 +99,43 @@ export function rewriteKnownCdnScriptSources(html) {
|
||||
rewrites,
|
||||
};
|
||||
}
|
||||
|
||||
export function rewriteKnownCdnStylesheetSources(html) {
|
||||
const rewrites = [];
|
||||
let next = String(html ?? '');
|
||||
|
||||
const replaceStylesheet = (full, before, quote, href, after) => {
|
||||
const normalized = normalizeScriptUrl(href);
|
||||
const target = resolveKnownPlatformStylesheetTarget(normalized);
|
||||
if (!target) return full;
|
||||
rewrites.push({ from: normalized, to: target });
|
||||
return `<link${before}href=${quote}${target}${quote}${after}>`;
|
||||
};
|
||||
|
||||
next = next.replace(
|
||||
STYLESHEET_HREF_PATTERN,
|
||||
(full, before, _relQuote, _middle, hrefQuote, href, after) =>
|
||||
replaceStylesheet(full, before, hrefQuote, href, after),
|
||||
);
|
||||
next = next.replace(
|
||||
STYLESHEET_HREF_ALT_PATTERN,
|
||||
(full, before, hrefQuote, href, _middle, _relQuote, after) =>
|
||||
replaceStylesheet(full, before, hrefQuote, href, after),
|
||||
);
|
||||
|
||||
return {
|
||||
html: next,
|
||||
rewrittenCount: rewrites.length,
|
||||
rewrites,
|
||||
};
|
||||
}
|
||||
|
||||
export function rewriteKnownCdnAssetSources(html) {
|
||||
const scripts = rewriteKnownCdnScriptSources(html);
|
||||
const stylesheets = rewriteKnownCdnStylesheetSources(scripts.html);
|
||||
return {
|
||||
html: stylesheets.html,
|
||||
rewrittenCount: scripts.rewrittenCount + stylesheets.rewrittenCount,
|
||||
rewrites: [...scripts.rewrites, ...stylesheets.rewrites],
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user