blogger-plugin 0.0.9 → 0.0.11
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/tailwind.cjs +5 -2
- package/dist/tailwind.cjs.map +1 -1
- package/dist/tailwind.mjs +5 -2
- package/dist/tailwind.mjs.map +1 -1
- package/dist/utils.cjs +17 -0
- package/dist/utils.cjs.map +1 -1
- package/dist/utils.mjs +17 -1
- package/dist/utils.mjs.map +1 -1
- package/dist/vite.cjs +23 -5
- package/dist/vite.cjs.map +1 -1
- package/dist/vite.d.cts +6 -1
- package/dist/vite.d.mts +6 -1
- package/dist/vite.mjs +24 -6
- package/dist/vite.mjs.map +1 -1
- package/package.json +4 -3
package/dist/tailwind.cjs
CHANGED
|
@@ -51,9 +51,12 @@ function clearTailwindCache(root) {
|
|
|
51
51
|
function removeTailwindCache(root) {
|
|
52
52
|
removeFile(getTailwindCacheFile(root));
|
|
53
53
|
}
|
|
54
|
-
async function updateTailwindCache(root, content) {
|
|
54
|
+
async function updateTailwindCache(root, content, extension) {
|
|
55
55
|
var _readTailwindCache;
|
|
56
|
-
const classes = await (0, tailwindcss_iso.getTailwindClasses)({
|
|
56
|
+
const classes = await (0, tailwindcss_iso.getTailwindClasses)({
|
|
57
|
+
content,
|
|
58
|
+
extension
|
|
59
|
+
});
|
|
57
60
|
writeTailwindCache(root, [...new Set([...(_readTailwindCache = readTailwindCache(root)) !== null && _readTailwindCache !== void 0 ? _readTailwindCache : [], ...classes])]);
|
|
58
61
|
}
|
|
59
62
|
//#endregion
|
package/dist/tailwind.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tailwind.cjs","names":["fs","path"],"sources":["../src/tailwind.ts"],"sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { getTailwindClasses } from 'tailwindcss-iso';\n\nconst TAILWIND_CACHE_FILE = '.tailwind-classes.json';\n\nfunction readFileContent(file: string): string | null {\n if (!fs.existsSync(file)) {\n return null;\n }\n return fs.readFileSync(file, 'utf-8');\n}\n\nfunction writeFileContent(file: string, content: string): boolean {\n const dirname = path.dirname(file);\n\n if (!fs.existsSync(dirname)) {\n fs.mkdirSync(dirname, { recursive: true });\n }\n\n const current = readFileContent(file);\n if (current === null || content !== current) {\n fs.writeFileSync(file, content, 'utf8');\n return true;\n }\n\n return false;\n}\n\nfunction removeFile(file: string): boolean {\n if (!fs.existsSync(file)) {\n return false;\n }\n fs.rmSync(file);\n return true;\n}\n\nfunction getTailwindCacheFile(root: string): string {\n return path.resolve(root, TAILWIND_CACHE_FILE);\n}\n\nexport function readTailwindCache(root: string): string[] | null {\n const content = readFileContent(getTailwindCacheFile(root));\n if (!content) {\n return null;\n }\n try {\n return JSON.parse(content);\n } catch {\n return null;\n }\n}\n\nexport function writeTailwindCache(root: string, classes: string[]): { updated: boolean; content: string } {\n const file = getTailwindCacheFile(root);\n const content = JSON.stringify(classes, null, 2);\n const updated = writeFileContent(file, content);\n return { updated, content };\n}\n\nexport function clearTailwindCache(root: string): void {\n writeTailwindCache(root, []);\n}\n\nexport function removeTailwindCache(root: string): void {\n removeFile(getTailwindCacheFile(root));\n}\n\nexport async function updateTailwindCache(root: string, content: string): Promise<void> {\n const classes = (await getTailwindClasses({\n content,\n })) as string[];\n\n writeTailwindCache(root, [...new Set([...(readTailwindCache(root) ?? []), ...classes])]);\n}\n"],"mappings":";;;;;;;AAIA,MAAM,sBAAsB;AAE5B,SAAS,gBAAgB,MAA6B;
|
|
1
|
+
{"version":3,"file":"tailwind.cjs","names":["fs","path"],"sources":["../src/tailwind.ts"],"sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { getTailwindClasses } from 'tailwindcss-iso';\n\nconst TAILWIND_CACHE_FILE = '.tailwind-classes.json';\n\nfunction readFileContent(file: string): string | null {\n if (!fs.existsSync(file)) {\n return null;\n }\n return fs.readFileSync(file, 'utf-8');\n}\n\nfunction writeFileContent(file: string, content: string): boolean {\n const dirname = path.dirname(file);\n\n if (!fs.existsSync(dirname)) {\n fs.mkdirSync(dirname, { recursive: true });\n }\n\n const current = readFileContent(file);\n if (current === null || content !== current) {\n fs.writeFileSync(file, content, 'utf8');\n return true;\n }\n\n return false;\n}\n\nfunction removeFile(file: string): boolean {\n if (!fs.existsSync(file)) {\n return false;\n }\n fs.rmSync(file);\n return true;\n}\n\nfunction getTailwindCacheFile(root: string): string {\n return path.resolve(root, TAILWIND_CACHE_FILE);\n}\n\nexport function readTailwindCache(root: string): string[] | null {\n const content = readFileContent(getTailwindCacheFile(root));\n if (!content) {\n return null;\n }\n try {\n return JSON.parse(content);\n } catch {\n return null;\n }\n}\n\nexport function writeTailwindCache(root: string, classes: string[]): { updated: boolean; content: string } {\n const file = getTailwindCacheFile(root);\n const content = JSON.stringify(classes, null, 2);\n const updated = writeFileContent(file, content);\n return { updated, content };\n}\n\nexport function clearTailwindCache(root: string): void {\n writeTailwindCache(root, []);\n}\n\nexport function removeTailwindCache(root: string): void {\n removeFile(getTailwindCacheFile(root));\n}\n\nexport async function updateTailwindCache(root: string, content: string, extension?: string): Promise<void> {\n const classes = (await getTailwindClasses({\n content,\n extension,\n })) as string[];\n\n writeTailwindCache(root, [...new Set([...(readTailwindCache(root) ?? []), ...classes])]);\n}\n"],"mappings":";;;;;;;AAIA,MAAM,sBAAsB;AAE5B,SAAS,gBAAgB,MAA6B;CACpD,IAAI,CAACA,QAAG,WAAW,KAAK,EACtB,OAAO;CAET,OAAOA,QAAG,aAAa,MAAM,QAAQ;;AAGvC,SAAS,iBAAiB,MAAc,SAA0B;CAChE,MAAM,UAAUC,UAAK,QAAQ,KAAK;CAElC,IAAI,CAACD,QAAG,WAAW,QAAQ,EACzB,QAAG,UAAU,SAAS,EAAE,WAAW,MAAM,CAAC;CAG5C,MAAM,UAAU,gBAAgB,KAAK;CACrC,IAAI,YAAY,QAAQ,YAAY,SAAS;EAC3C,QAAG,cAAc,MAAM,SAAS,OAAO;EACvC,OAAO;;CAGT,OAAO;;AAGT,SAAS,WAAW,MAAuB;CACzC,IAAI,CAACA,QAAG,WAAW,KAAK,EACtB,OAAO;CAET,QAAG,OAAO,KAAK;CACf,OAAO;;AAGT,SAAS,qBAAqB,MAAsB;CAClD,OAAOC,UAAK,QAAQ,MAAM,oBAAoB;;AAGhD,SAAgB,kBAAkB,MAA+B;CAC/D,MAAM,UAAU,gBAAgB,qBAAqB,KAAK,CAAC;CAC3D,IAAI,CAAC,SACH,OAAO;CAET,IAAI;EACF,OAAO,KAAK,MAAM,QAAQ;mBACpB;EACN,OAAO;;;AAIX,SAAgB,mBAAmB,MAAc,SAA0D;CACzG,MAAM,OAAO,qBAAqB,KAAK;CACvC,MAAM,UAAU,KAAK,UAAU,SAAS,MAAM,EAAE;CAEhD,OAAO;EAAE,SADO,iBAAiB,MAAM,QACvB;EAAE;EAAS;;AAG7B,SAAgB,mBAAmB,MAAoB;CACrD,mBAAmB,MAAM,EAAE,CAAC;;AAG9B,SAAgB,oBAAoB,MAAoB;CACtD,WAAW,qBAAqB,KAAK,CAAC;;AAGxC,eAAsB,oBAAoB,MAAc,SAAiB,WAAmC;;CAC1G,MAAM,UAAW,OAAA,GAAA,gBAAA,oBAAyB;EACxC;EACA;EACD,CAAC;CAEF,mBAAmB,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,IAAA,qBAAI,kBAAkB,KAAK,MAAA,QAAA,uBAAA,KAAA,IAAA,qBAAI,EAAE,EAAG,GAAG,QAAQ,CAAC,CAAC,CAAC"}
|
package/dist/tailwind.mjs
CHANGED
|
@@ -48,9 +48,12 @@ function clearTailwindCache(root) {
|
|
|
48
48
|
function removeTailwindCache(root) {
|
|
49
49
|
removeFile(getTailwindCacheFile(root));
|
|
50
50
|
}
|
|
51
|
-
async function updateTailwindCache(root, content) {
|
|
51
|
+
async function updateTailwindCache(root, content, extension) {
|
|
52
52
|
var _readTailwindCache;
|
|
53
|
-
const classes = await getTailwindClasses({
|
|
53
|
+
const classes = await getTailwindClasses({
|
|
54
|
+
content,
|
|
55
|
+
extension
|
|
56
|
+
});
|
|
54
57
|
writeTailwindCache(root, [...new Set([...(_readTailwindCache = readTailwindCache(root)) !== null && _readTailwindCache !== void 0 ? _readTailwindCache : [], ...classes])]);
|
|
55
58
|
}
|
|
56
59
|
//#endregion
|
package/dist/tailwind.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tailwind.mjs","names":[],"sources":["../src/tailwind.ts"],"sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { getTailwindClasses } from 'tailwindcss-iso';\n\nconst TAILWIND_CACHE_FILE = '.tailwind-classes.json';\n\nfunction readFileContent(file: string): string | null {\n if (!fs.existsSync(file)) {\n return null;\n }\n return fs.readFileSync(file, 'utf-8');\n}\n\nfunction writeFileContent(file: string, content: string): boolean {\n const dirname = path.dirname(file);\n\n if (!fs.existsSync(dirname)) {\n fs.mkdirSync(dirname, { recursive: true });\n }\n\n const current = readFileContent(file);\n if (current === null || content !== current) {\n fs.writeFileSync(file, content, 'utf8');\n return true;\n }\n\n return false;\n}\n\nfunction removeFile(file: string): boolean {\n if (!fs.existsSync(file)) {\n return false;\n }\n fs.rmSync(file);\n return true;\n}\n\nfunction getTailwindCacheFile(root: string): string {\n return path.resolve(root, TAILWIND_CACHE_FILE);\n}\n\nexport function readTailwindCache(root: string): string[] | null {\n const content = readFileContent(getTailwindCacheFile(root));\n if (!content) {\n return null;\n }\n try {\n return JSON.parse(content);\n } catch {\n return null;\n }\n}\n\nexport function writeTailwindCache(root: string, classes: string[]): { updated: boolean; content: string } {\n const file = getTailwindCacheFile(root);\n const content = JSON.stringify(classes, null, 2);\n const updated = writeFileContent(file, content);\n return { updated, content };\n}\n\nexport function clearTailwindCache(root: string): void {\n writeTailwindCache(root, []);\n}\n\nexport function removeTailwindCache(root: string): void {\n removeFile(getTailwindCacheFile(root));\n}\n\nexport async function updateTailwindCache(root: string, content: string): Promise<void> {\n const classes = (await getTailwindClasses({\n content,\n })) as string[];\n\n writeTailwindCache(root, [...new Set([...(readTailwindCache(root) ?? []), ...classes])]);\n}\n"],"mappings":";;;;AAIA,MAAM,sBAAsB;AAE5B,SAAS,gBAAgB,MAA6B;
|
|
1
|
+
{"version":3,"file":"tailwind.mjs","names":[],"sources":["../src/tailwind.ts"],"sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { getTailwindClasses } from 'tailwindcss-iso';\n\nconst TAILWIND_CACHE_FILE = '.tailwind-classes.json';\n\nfunction readFileContent(file: string): string | null {\n if (!fs.existsSync(file)) {\n return null;\n }\n return fs.readFileSync(file, 'utf-8');\n}\n\nfunction writeFileContent(file: string, content: string): boolean {\n const dirname = path.dirname(file);\n\n if (!fs.existsSync(dirname)) {\n fs.mkdirSync(dirname, { recursive: true });\n }\n\n const current = readFileContent(file);\n if (current === null || content !== current) {\n fs.writeFileSync(file, content, 'utf8');\n return true;\n }\n\n return false;\n}\n\nfunction removeFile(file: string): boolean {\n if (!fs.existsSync(file)) {\n return false;\n }\n fs.rmSync(file);\n return true;\n}\n\nfunction getTailwindCacheFile(root: string): string {\n return path.resolve(root, TAILWIND_CACHE_FILE);\n}\n\nexport function readTailwindCache(root: string): string[] | null {\n const content = readFileContent(getTailwindCacheFile(root));\n if (!content) {\n return null;\n }\n try {\n return JSON.parse(content);\n } catch {\n return null;\n }\n}\n\nexport function writeTailwindCache(root: string, classes: string[]): { updated: boolean; content: string } {\n const file = getTailwindCacheFile(root);\n const content = JSON.stringify(classes, null, 2);\n const updated = writeFileContent(file, content);\n return { updated, content };\n}\n\nexport function clearTailwindCache(root: string): void {\n writeTailwindCache(root, []);\n}\n\nexport function removeTailwindCache(root: string): void {\n removeFile(getTailwindCacheFile(root));\n}\n\nexport async function updateTailwindCache(root: string, content: string, extension?: string): Promise<void> {\n const classes = (await getTailwindClasses({\n content,\n extension,\n })) as string[];\n\n writeTailwindCache(root, [...new Set([...(readTailwindCache(root) ?? []), ...classes])]);\n}\n"],"mappings":";;;;AAIA,MAAM,sBAAsB;AAE5B,SAAS,gBAAgB,MAA6B;CACpD,IAAI,CAAC,GAAG,WAAW,KAAK,EACtB,OAAO;CAET,OAAO,GAAG,aAAa,MAAM,QAAQ;;AAGvC,SAAS,iBAAiB,MAAc,SAA0B;CAChE,MAAM,UAAU,KAAK,QAAQ,KAAK;CAElC,IAAI,CAAC,GAAG,WAAW,QAAQ,EACzB,GAAG,UAAU,SAAS,EAAE,WAAW,MAAM,CAAC;CAG5C,MAAM,UAAU,gBAAgB,KAAK;CACrC,IAAI,YAAY,QAAQ,YAAY,SAAS;EAC3C,GAAG,cAAc,MAAM,SAAS,OAAO;EACvC,OAAO;;CAGT,OAAO;;AAGT,SAAS,WAAW,MAAuB;CACzC,IAAI,CAAC,GAAG,WAAW,KAAK,EACtB,OAAO;CAET,GAAG,OAAO,KAAK;CACf,OAAO;;AAGT,SAAS,qBAAqB,MAAsB;CAClD,OAAO,KAAK,QAAQ,MAAM,oBAAoB;;AAGhD,SAAgB,kBAAkB,MAA+B;CAC/D,MAAM,UAAU,gBAAgB,qBAAqB,KAAK,CAAC;CAC3D,IAAI,CAAC,SACH,OAAO;CAET,IAAI;EACF,OAAO,KAAK,MAAM,QAAQ;mBACpB;EACN,OAAO;;;AAIX,SAAgB,mBAAmB,MAAc,SAA0D;CACzG,MAAM,OAAO,qBAAqB,KAAK;CACvC,MAAM,UAAU,KAAK,UAAU,SAAS,MAAM,EAAE;CAEhD,OAAO;EAAE,SADO,iBAAiB,MAAM,QACvB;EAAE;EAAS;;AAG7B,SAAgB,mBAAmB,MAAoB;CACrD,mBAAmB,MAAM,EAAE,CAAC;;AAG9B,SAAgB,oBAAoB,MAAoB;CACtD,WAAW,qBAAqB,KAAK,CAAC;;AAGxC,eAAsB,oBAAoB,MAAc,SAAiB,WAAmC;;CAC1G,MAAM,UAAW,MAAM,mBAAmB;EACxC;EACA;EACD,CAAC;CAEF,mBAAmB,MAAM,CAAC,GAAG,IAAI,IAAI,CAAC,IAAA,qBAAI,kBAAkB,KAAK,MAAA,QAAA,uBAAA,KAAA,IAAA,qBAAI,EAAE,EAAG,GAAG,QAAQ,CAAC,CAAC,CAAC"}
|
package/dist/utils.cjs
CHANGED
|
@@ -13,6 +13,22 @@ function escapeHtml(str) {
|
|
|
13
13
|
}
|
|
14
14
|
});
|
|
15
15
|
}
|
|
16
|
+
function unescapeHTML(str, xml = false) {
|
|
17
|
+
if (str === "") return "";
|
|
18
|
+
const regex = new RegExp(`&(?:amp|lt|gt|quot${xml ? "|apos" : ""}|#39|#96);`, "g");
|
|
19
|
+
return str.replace(regex, (entity) => {
|
|
20
|
+
switch (entity) {
|
|
21
|
+
case "&": return "&";
|
|
22
|
+
case "<": return "<";
|
|
23
|
+
case ">": return ">";
|
|
24
|
+
case """: return "\"";
|
|
25
|
+
case "'":
|
|
26
|
+
case "'": return "'";
|
|
27
|
+
case "`": return "`";
|
|
28
|
+
default: return entity;
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
16
32
|
function escapeRegex(str) {
|
|
17
33
|
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
18
34
|
}
|
|
@@ -163,5 +179,6 @@ exports.isTailwindPlugin = isTailwindPlugin;
|
|
|
163
179
|
exports.replaceBloggerPluginHeadComment = replaceBloggerPluginHeadComment;
|
|
164
180
|
exports.replaceHost = replaceHost;
|
|
165
181
|
exports.toWebHeaders = toWebHeaders;
|
|
182
|
+
exports.unescapeHTML = unescapeHTML;
|
|
166
183
|
|
|
167
184
|
//# sourceMappingURL=utils.cjs.map
|
package/dist/utils.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.cjs","names":[],"sources":["../src/utils.ts"],"sourcesContent":["import type { IncomingHttpHeaders, OutgoingHttpHeaders } from 'node:http';\nimport type { Connect } from 'vite';\n\nexport function escapeHtml(str: string) {\n if (str === '') return '';\n return str.replace(/[&<>\"'`]/g, (ch) => {\n switch (ch) {\n case '&':\n return '&';\n case '<':\n return '<';\n case '>':\n return '>';\n case '\"':\n return '"';\n case \"'\":\n return ''';\n case '`':\n return '`';\n default:\n return ch;\n }\n });\n}\n\nexport function escapeRegex(str: string) {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nexport function toWebHeaders(httpHeaders: IncomingHttpHeaders | OutgoingHttpHeaders): Headers {\n const headers = new Headers();\n for (const [name, value] of Object.entries(httpHeaders)) {\n if (Array.isArray(value)) {\n for (const item of value) {\n headers.append(name, item);\n }\n } else {\n headers.set(name, String(value ?? ''));\n }\n }\n return headers;\n}\n\nexport const BLOGGER_PLUGIN_HEAD_COMMENT_REGEX = /(<!--blogger-plugin:head:begin-->)([\\s\\S]*?)(<!--blogger-plugin:head:end-->)/;\n\nexport const BLOGGER_PLUGIN_HEAD_BCOMMENT_REGEX =\n /(<b:comment><!--blogger-plugin:head:begin--><\\/b:comment>)([\\s\\S]*?)(<b:comment><!--blogger-plugin:head:end--><\\/b:comment>)/;\n\nexport function replaceBloggerPluginHeadComment(input: string, replacement: string, bcomment = false) {\n if (bcomment) {\n return input.replace(BLOGGER_PLUGIN_HEAD_BCOMMENT_REGEX, (_, start: string, _content: string, end: string) => `${start}${replacement}${end}`);\n }\n return input.replace(BLOGGER_PLUGIN_HEAD_COMMENT_REGEX, (_, start: string, _content: string, end: string) => `${start}${replacement}${end}`);\n}\n\nexport function getBloggerPluginHeadComment(input: string, bcomment = false) {\n if (bcomment) {\n return input.match(BLOGGER_PLUGIN_HEAD_BCOMMENT_REGEX)?.[2] ?? null;\n }\n return input.match(BLOGGER_PLUGIN_HEAD_COMMENT_REGEX)?.[2] ?? null;\n}\n\nexport function replaceHost(input: string, oldHost: string, newHost: string, newProtocol?: string) {\n return input.replace(\n new RegExp(`(https?:)?(\\\\/\\\\/|\\\\\\\\/\\\\\\\\/)${escapeRegex(oldHost)}`, 'g'),\n (_, protocol, slash) => `${protocol ? (newProtocol ?? protocol) : ''}${slash ?? ''}${newHost}`,\n );\n}\n\nexport function getRequestUrl(req: Connect.IncomingMessage): URL | null {\n const xForwardedProtoHeader = req.headers['x-forwarded-proto'];\n const xForwardedHostHeader = req.headers['x-forwarded-host'];\n const hostHeader = req.headers.host;\n\n const protocol = Array.isArray(xForwardedProtoHeader)\n ? xForwardedProtoHeader[0]\n : (xForwardedProtoHeader ?? (req.socket && 'encrypted' in req.socket && req.socket.encrypted ? 'https' : 'http'));\n const host = Array.isArray(xForwardedHostHeader) ? xForwardedHostHeader[0] : (xForwardedHostHeader ?? hostHeader);\n\n if (host && req.originalUrl) {\n return new URL(`${protocol}://${host}${req.originalUrl}`);\n }\n\n return null;\n}\n\nexport function isBloggerPath(path: string) {\n return (\n path === '/' ||\n path === '/search' ||\n /^\\/search\\/label(\\/[^/]+)?\\/?$/.test(path) ||\n /^p\\/.+\\.html$/.test(path) ||\n /^\\/\\d{4}\\/\\d{2}(\\/?|\\/[^/\\s]+\\.html)$/.test(path)\n );\n}\n\nconst TAILWIND_PLUGIN_NAMES = new Set(['@tailwindcss/vite:scan']);\n\nexport function isTailwindPlugin(plugin: { name: string }): boolean {\n return TAILWIND_PLUGIN_NAMES.has(plugin.name);\n}\n\nexport function errorHtml(reqUrl: string) {\n return `<!DOCTYPE html>\n<html>\n\n<head>\n <meta charset='UTF-8'/>\n <meta content='width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=5, user-scalable=yes' name='viewport'/>\n <title>500 Internal Server Error</title>\n <link rel='icon' href='data:,' />\n <style>\n *, ::before, ::after {\n box-sizing: border-box;\n }\n body {\n min-height: 100svh;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n margin: 0;\n padding: 20px;\n background-color: #f5f5f5;\n font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, Noto Sans, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", Segoe UI Symbol, \"Noto Color Emoji\";\n }\n .card {\n padding: 24px;\n background-color: #ffffff;\n border: 1px solid #e5e5e5;\n max-width: 448px;\n border-radius: 14px;\n box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);\n display: flex;\n flex-direction: column;\n gap: 24px;\n }\n .card-content {\n display: flex;\n flex-direction: column;\n gap: 6px;\n }\n .card-title {\n font-weight: 600;\n }\n .card-description {\n font-size: 14px;\n opacity: 0.85;\n }\n .card-footer {\n display: flex;\n align-items: center;\n }\n .button {\n display: inline-flex;\n white-space: nowrap;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 8px 16px;\n font-weight: 500;\n background-color: #171717;\n outline: none;\n border: none;\n color: #ffffff;\n border-radius: 8px;\n min-height: 36px;\n }\n .button:hover {\n opacity: 0.9;\n }\n .button svg {\n wiheadersdth: 16px;\n height: 16px;\n flex-shrink: 0;\n }\n .card-footer .button {\n flex-grow: 1;\n }\n </style>\n</head>\n\n<body>\n <div class='card'>\n <div class='card-content'>\n <div class='card-title'>500 Internal Server Error</div>\n <div class='card-description'>Failed to fetch: ${escapeHtml(reqUrl)}</div>\n </div>\n <div class='card-footer'>\n <button class='button' type='button'>\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-refresh-ccw\" aria-hidden=\"true\"><path d=\"M21 12a9 9 0 0 0-9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\"></path><path d=\"M3 3v5h5\"></path><path d=\"M3 12a9 9 0 0 0 9 9 9.75 9.75 0 0 0 6.74-2.74L21 16\"></path><path d=\"M16 16h5v5\"></path></svg>\n Reload\n </button>\n </div>\n </div>\n <script>\n const button = document.getElementsByTagName('button')[0];\n button.addEventListener('click', () => {\n window.location.reload();\n });\n </script>\n</body>\n\n</html>`;\n}\n"],"mappings":";AAGA,SAAgB,WAAW,
|
|
1
|
+
{"version":3,"file":"utils.cjs","names":[],"sources":["../src/utils.ts"],"sourcesContent":["import type { IncomingHttpHeaders, OutgoingHttpHeaders } from 'node:http';\nimport type { Connect } from 'vite';\n\nexport function escapeHtml(str: string): string {\n if (str === '') return '';\n return str.replace(/[&<>\"'`]/g, (ch) => {\n switch (ch) {\n case '&':\n return '&';\n case '<':\n return '<';\n case '>':\n return '>';\n case '\"':\n return '"';\n case \"'\":\n return ''';\n case '`':\n return '`';\n default:\n return ch;\n }\n });\n}\n\nexport function unescapeHTML(str: string, xml = false): string {\n if (str === '') return '';\n const regex = new RegExp(`&(?:amp|lt|gt|quot${xml ? '|apos' : ''}|#39|#96);`, 'g');\n return str.replace(regex, (entity) => {\n switch (entity) {\n case '&':\n return '&';\n case '<':\n return '<';\n case '>':\n return '>';\n case '"':\n return '\"';\n case ''':\n case ''':\n return \"'\";\n case '`':\n return '`';\n default:\n return entity;\n }\n });\n}\n\nexport function escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nexport function toWebHeaders(httpHeaders: IncomingHttpHeaders | OutgoingHttpHeaders): Headers {\n const headers = new Headers();\n for (const [name, value] of Object.entries(httpHeaders)) {\n if (Array.isArray(value)) {\n for (const item of value) {\n headers.append(name, item);\n }\n } else {\n headers.set(name, String(value ?? ''));\n }\n }\n return headers;\n}\n\nexport const BLOGGER_PLUGIN_HEAD_COMMENT_REGEX = /(<!--blogger-plugin:head:begin-->)([\\s\\S]*?)(<!--blogger-plugin:head:end-->)/;\n\nexport const BLOGGER_PLUGIN_HEAD_BCOMMENT_REGEX =\n /(<b:comment><!--blogger-plugin:head:begin--><\\/b:comment>)([\\s\\S]*?)(<b:comment><!--blogger-plugin:head:end--><\\/b:comment>)/;\n\nexport function replaceBloggerPluginHeadComment(input: string, replacement: string, bcomment = false): string {\n if (bcomment) {\n return input.replace(BLOGGER_PLUGIN_HEAD_BCOMMENT_REGEX, (_, start: string, _content: string, end: string) => `${start}${replacement}${end}`);\n }\n return input.replace(BLOGGER_PLUGIN_HEAD_COMMENT_REGEX, (_, start: string, _content: string, end: string) => `${start}${replacement}${end}`);\n}\n\nexport function getBloggerPluginHeadComment(input: string, bcomment = false): string | null {\n if (bcomment) {\n return input.match(BLOGGER_PLUGIN_HEAD_BCOMMENT_REGEX)?.[2] ?? null;\n }\n return input.match(BLOGGER_PLUGIN_HEAD_COMMENT_REGEX)?.[2] ?? null;\n}\n\nexport function replaceHost(input: string, oldHost: string, newHost: string, newProtocol?: string): string {\n return input.replace(\n new RegExp(`(https?:)?(\\\\/\\\\/|\\\\\\\\/\\\\\\\\/)${escapeRegex(oldHost)}`, 'g'),\n (_, protocol, slash) => `${protocol ? (newProtocol ?? protocol) : ''}${slash ?? ''}${newHost}`,\n );\n}\n\nexport function getRequestUrl(req: Connect.IncomingMessage): URL | null {\n const xForwardedProtoHeader = req.headers['x-forwarded-proto'];\n const xForwardedHostHeader = req.headers['x-forwarded-host'];\n const hostHeader = req.headers.host;\n\n const protocol = Array.isArray(xForwardedProtoHeader)\n ? xForwardedProtoHeader[0]\n : (xForwardedProtoHeader ?? (req.socket && 'encrypted' in req.socket && req.socket.encrypted ? 'https' : 'http'));\n const host = Array.isArray(xForwardedHostHeader) ? xForwardedHostHeader[0] : (xForwardedHostHeader ?? hostHeader);\n\n if (host && req.originalUrl) {\n return new URL(`${protocol}://${host}${req.originalUrl}`);\n }\n\n return null;\n}\n\nexport function isBloggerPath(path: string): boolean {\n return (\n path === '/' ||\n path === '/search' ||\n /^\\/search\\/label(\\/[^/]+)?\\/?$/.test(path) ||\n /^p\\/.+\\.html$/.test(path) ||\n /^\\/\\d{4}\\/\\d{2}(\\/?|\\/[^/\\s]+\\.html)$/.test(path)\n );\n}\n\nconst TAILWIND_PLUGIN_NAMES = new Set(['@tailwindcss/vite:scan']);\n\nexport function isTailwindPlugin(plugin: { name: string }): boolean {\n return TAILWIND_PLUGIN_NAMES.has(plugin.name);\n}\n\nexport function errorHtml(reqUrl: string): string {\n return `<!DOCTYPE html>\n<html>\n\n<head>\n <meta charset='UTF-8'/>\n <meta content='width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=5, user-scalable=yes' name='viewport'/>\n <title>500 Internal Server Error</title>\n <link rel='icon' href='data:,' />\n <style>\n *, ::before, ::after {\n box-sizing: border-box;\n }\n body {\n min-height: 100svh;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n margin: 0;\n padding: 20px;\n background-color: #f5f5f5;\n font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, Noto Sans, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", Segoe UI Symbol, \"Noto Color Emoji\";\n }\n .card {\n padding: 24px;\n background-color: #ffffff;\n border: 1px solid #e5e5e5;\n max-width: 448px;\n border-radius: 14px;\n box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);\n display: flex;\n flex-direction: column;\n gap: 24px;\n }\n .card-content {\n display: flex;\n flex-direction: column;\n gap: 6px;\n }\n .card-title {\n font-weight: 600;\n }\n .card-description {\n font-size: 14px;\n opacity: 0.85;\n }\n .card-footer {\n display: flex;\n align-items: center;\n }\n .button {\n display: inline-flex;\n white-space: nowrap;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 8px 16px;\n font-weight: 500;\n background-color: #171717;\n outline: none;\n border: none;\n color: #ffffff;\n border-radius: 8px;\n min-height: 36px;\n }\n .button:hover {\n opacity: 0.9;\n }\n .button svg {\n wiheadersdth: 16px;\n height: 16px;\n flex-shrink: 0;\n }\n .card-footer .button {\n flex-grow: 1;\n }\n </style>\n</head>\n\n<body>\n <div class='card'>\n <div class='card-content'>\n <div class='card-title'>500 Internal Server Error</div>\n <div class='card-description'>Failed to fetch: ${escapeHtml(reqUrl)}</div>\n </div>\n <div class='card-footer'>\n <button class='button' type='button'>\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-refresh-ccw\" aria-hidden=\"true\"><path d=\"M21 12a9 9 0 0 0-9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\"></path><path d=\"M3 3v5h5\"></path><path d=\"M3 12a9 9 0 0 0 9 9 9.75 9.75 0 0 0 6.74-2.74L21 16\"></path><path d=\"M16 16h5v5\"></path></svg>\n Reload\n </button>\n </div>\n </div>\n <script>\n const button = document.getElementsByTagName('button')[0];\n button.addEventListener('click', () => {\n window.location.reload();\n });\n </script>\n</body>\n\n</html>`;\n}\n"],"mappings":"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"}
|
package/dist/utils.mjs
CHANGED
|
@@ -13,6 +13,22 @@ function escapeHtml(str) {
|
|
|
13
13
|
}
|
|
14
14
|
});
|
|
15
15
|
}
|
|
16
|
+
function unescapeHTML(str, xml = false) {
|
|
17
|
+
if (str === "") return "";
|
|
18
|
+
const regex = new RegExp(`&(?:amp|lt|gt|quot${xml ? "|apos" : ""}|#39|#96);`, "g");
|
|
19
|
+
return str.replace(regex, (entity) => {
|
|
20
|
+
switch (entity) {
|
|
21
|
+
case "&": return "&";
|
|
22
|
+
case "<": return "<";
|
|
23
|
+
case ">": return ">";
|
|
24
|
+
case """: return "\"";
|
|
25
|
+
case "'":
|
|
26
|
+
case "'": return "'";
|
|
27
|
+
case "`": return "`";
|
|
28
|
+
default: return entity;
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
}
|
|
16
32
|
function escapeRegex(str) {
|
|
17
33
|
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
18
34
|
}
|
|
@@ -156,6 +172,6 @@ function errorHtml(reqUrl) {
|
|
|
156
172
|
</html>`;
|
|
157
173
|
}
|
|
158
174
|
//#endregion
|
|
159
|
-
export { errorHtml, getBloggerPluginHeadComment, getRequestUrl, isTailwindPlugin, replaceBloggerPluginHeadComment, replaceHost, toWebHeaders };
|
|
175
|
+
export { errorHtml, getBloggerPluginHeadComment, getRequestUrl, isTailwindPlugin, replaceBloggerPluginHeadComment, replaceHost, toWebHeaders, unescapeHTML };
|
|
160
176
|
|
|
161
177
|
//# sourceMappingURL=utils.mjs.map
|
package/dist/utils.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.mjs","names":[],"sources":["../src/utils.ts"],"sourcesContent":["import type { IncomingHttpHeaders, OutgoingHttpHeaders } from 'node:http';\nimport type { Connect } from 'vite';\n\nexport function escapeHtml(str: string) {\n if (str === '') return '';\n return str.replace(/[&<>\"'`]/g, (ch) => {\n switch (ch) {\n case '&':\n return '&';\n case '<':\n return '<';\n case '>':\n return '>';\n case '\"':\n return '"';\n case \"'\":\n return ''';\n case '`':\n return '`';\n default:\n return ch;\n }\n });\n}\n\nexport function escapeRegex(str: string) {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nexport function toWebHeaders(httpHeaders: IncomingHttpHeaders | OutgoingHttpHeaders): Headers {\n const headers = new Headers();\n for (const [name, value] of Object.entries(httpHeaders)) {\n if (Array.isArray(value)) {\n for (const item of value) {\n headers.append(name, item);\n }\n } else {\n headers.set(name, String(value ?? ''));\n }\n }\n return headers;\n}\n\nexport const BLOGGER_PLUGIN_HEAD_COMMENT_REGEX = /(<!--blogger-plugin:head:begin-->)([\\s\\S]*?)(<!--blogger-plugin:head:end-->)/;\n\nexport const BLOGGER_PLUGIN_HEAD_BCOMMENT_REGEX =\n /(<b:comment><!--blogger-plugin:head:begin--><\\/b:comment>)([\\s\\S]*?)(<b:comment><!--blogger-plugin:head:end--><\\/b:comment>)/;\n\nexport function replaceBloggerPluginHeadComment(input: string, replacement: string, bcomment = false) {\n if (bcomment) {\n return input.replace(BLOGGER_PLUGIN_HEAD_BCOMMENT_REGEX, (_, start: string, _content: string, end: string) => `${start}${replacement}${end}`);\n }\n return input.replace(BLOGGER_PLUGIN_HEAD_COMMENT_REGEX, (_, start: string, _content: string, end: string) => `${start}${replacement}${end}`);\n}\n\nexport function getBloggerPluginHeadComment(input: string, bcomment = false) {\n if (bcomment) {\n return input.match(BLOGGER_PLUGIN_HEAD_BCOMMENT_REGEX)?.[2] ?? null;\n }\n return input.match(BLOGGER_PLUGIN_HEAD_COMMENT_REGEX)?.[2] ?? null;\n}\n\nexport function replaceHost(input: string, oldHost: string, newHost: string, newProtocol?: string) {\n return input.replace(\n new RegExp(`(https?:)?(\\\\/\\\\/|\\\\\\\\/\\\\\\\\/)${escapeRegex(oldHost)}`, 'g'),\n (_, protocol, slash) => `${protocol ? (newProtocol ?? protocol) : ''}${slash ?? ''}${newHost}`,\n );\n}\n\nexport function getRequestUrl(req: Connect.IncomingMessage): URL | null {\n const xForwardedProtoHeader = req.headers['x-forwarded-proto'];\n const xForwardedHostHeader = req.headers['x-forwarded-host'];\n const hostHeader = req.headers.host;\n\n const protocol = Array.isArray(xForwardedProtoHeader)\n ? xForwardedProtoHeader[0]\n : (xForwardedProtoHeader ?? (req.socket && 'encrypted' in req.socket && req.socket.encrypted ? 'https' : 'http'));\n const host = Array.isArray(xForwardedHostHeader) ? xForwardedHostHeader[0] : (xForwardedHostHeader ?? hostHeader);\n\n if (host && req.originalUrl) {\n return new URL(`${protocol}://${host}${req.originalUrl}`);\n }\n\n return null;\n}\n\nexport function isBloggerPath(path: string) {\n return (\n path === '/' ||\n path === '/search' ||\n /^\\/search\\/label(\\/[^/]+)?\\/?$/.test(path) ||\n /^p\\/.+\\.html$/.test(path) ||\n /^\\/\\d{4}\\/\\d{2}(\\/?|\\/[^/\\s]+\\.html)$/.test(path)\n );\n}\n\nconst TAILWIND_PLUGIN_NAMES = new Set(['@tailwindcss/vite:scan']);\n\nexport function isTailwindPlugin(plugin: { name: string }): boolean {\n return TAILWIND_PLUGIN_NAMES.has(plugin.name);\n}\n\nexport function errorHtml(reqUrl: string) {\n return `<!DOCTYPE html>\n<html>\n\n<head>\n <meta charset='UTF-8'/>\n <meta content='width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=5, user-scalable=yes' name='viewport'/>\n <title>500 Internal Server Error</title>\n <link rel='icon' href='data:,' />\n <style>\n *, ::before, ::after {\n box-sizing: border-box;\n }\n body {\n min-height: 100svh;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n margin: 0;\n padding: 20px;\n background-color: #f5f5f5;\n font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, Noto Sans, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", Segoe UI Symbol, \"Noto Color Emoji\";\n }\n .card {\n padding: 24px;\n background-color: #ffffff;\n border: 1px solid #e5e5e5;\n max-width: 448px;\n border-radius: 14px;\n box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);\n display: flex;\n flex-direction: column;\n gap: 24px;\n }\n .card-content {\n display: flex;\n flex-direction: column;\n gap: 6px;\n }\n .card-title {\n font-weight: 600;\n }\n .card-description {\n font-size: 14px;\n opacity: 0.85;\n }\n .card-footer {\n display: flex;\n align-items: center;\n }\n .button {\n display: inline-flex;\n white-space: nowrap;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 8px 16px;\n font-weight: 500;\n background-color: #171717;\n outline: none;\n border: none;\n color: #ffffff;\n border-radius: 8px;\n min-height: 36px;\n }\n .button:hover {\n opacity: 0.9;\n }\n .button svg {\n wiheadersdth: 16px;\n height: 16px;\n flex-shrink: 0;\n }\n .card-footer .button {\n flex-grow: 1;\n }\n </style>\n</head>\n\n<body>\n <div class='card'>\n <div class='card-content'>\n <div class='card-title'>500 Internal Server Error</div>\n <div class='card-description'>Failed to fetch: ${escapeHtml(reqUrl)}</div>\n </div>\n <div class='card-footer'>\n <button class='button' type='button'>\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-refresh-ccw\" aria-hidden=\"true\"><path d=\"M21 12a9 9 0 0 0-9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\"></path><path d=\"M3 3v5h5\"></path><path d=\"M3 12a9 9 0 0 0 9 9 9.75 9.75 0 0 0 6.74-2.74L21 16\"></path><path d=\"M16 16h5v5\"></path></svg>\n Reload\n </button>\n </div>\n </div>\n <script>\n const button = document.getElementsByTagName('button')[0];\n button.addEventListener('click', () => {\n window.location.reload();\n });\n </script>\n</body>\n\n</html>`;\n}\n"],"mappings":";AAGA,SAAgB,WAAW,
|
|
1
|
+
{"version":3,"file":"utils.mjs","names":[],"sources":["../src/utils.ts"],"sourcesContent":["import type { IncomingHttpHeaders, OutgoingHttpHeaders } from 'node:http';\nimport type { Connect } from 'vite';\n\nexport function escapeHtml(str: string): string {\n if (str === '') return '';\n return str.replace(/[&<>\"'`]/g, (ch) => {\n switch (ch) {\n case '&':\n return '&';\n case '<':\n return '<';\n case '>':\n return '>';\n case '\"':\n return '"';\n case \"'\":\n return ''';\n case '`':\n return '`';\n default:\n return ch;\n }\n });\n}\n\nexport function unescapeHTML(str: string, xml = false): string {\n if (str === '') return '';\n const regex = new RegExp(`&(?:amp|lt|gt|quot${xml ? '|apos' : ''}|#39|#96);`, 'g');\n return str.replace(regex, (entity) => {\n switch (entity) {\n case '&':\n return '&';\n case '<':\n return '<';\n case '>':\n return '>';\n case '"':\n return '\"';\n case ''':\n case ''':\n return \"'\";\n case '`':\n return '`';\n default:\n return entity;\n }\n });\n}\n\nexport function escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\nexport function toWebHeaders(httpHeaders: IncomingHttpHeaders | OutgoingHttpHeaders): Headers {\n const headers = new Headers();\n for (const [name, value] of Object.entries(httpHeaders)) {\n if (Array.isArray(value)) {\n for (const item of value) {\n headers.append(name, item);\n }\n } else {\n headers.set(name, String(value ?? ''));\n }\n }\n return headers;\n}\n\nexport const BLOGGER_PLUGIN_HEAD_COMMENT_REGEX = /(<!--blogger-plugin:head:begin-->)([\\s\\S]*?)(<!--blogger-plugin:head:end-->)/;\n\nexport const BLOGGER_PLUGIN_HEAD_BCOMMENT_REGEX =\n /(<b:comment><!--blogger-plugin:head:begin--><\\/b:comment>)([\\s\\S]*?)(<b:comment><!--blogger-plugin:head:end--><\\/b:comment>)/;\n\nexport function replaceBloggerPluginHeadComment(input: string, replacement: string, bcomment = false): string {\n if (bcomment) {\n return input.replace(BLOGGER_PLUGIN_HEAD_BCOMMENT_REGEX, (_, start: string, _content: string, end: string) => `${start}${replacement}${end}`);\n }\n return input.replace(BLOGGER_PLUGIN_HEAD_COMMENT_REGEX, (_, start: string, _content: string, end: string) => `${start}${replacement}${end}`);\n}\n\nexport function getBloggerPluginHeadComment(input: string, bcomment = false): string | null {\n if (bcomment) {\n return input.match(BLOGGER_PLUGIN_HEAD_BCOMMENT_REGEX)?.[2] ?? null;\n }\n return input.match(BLOGGER_PLUGIN_HEAD_COMMENT_REGEX)?.[2] ?? null;\n}\n\nexport function replaceHost(input: string, oldHost: string, newHost: string, newProtocol?: string): string {\n return input.replace(\n new RegExp(`(https?:)?(\\\\/\\\\/|\\\\\\\\/\\\\\\\\/)${escapeRegex(oldHost)}`, 'g'),\n (_, protocol, slash) => `${protocol ? (newProtocol ?? protocol) : ''}${slash ?? ''}${newHost}`,\n );\n}\n\nexport function getRequestUrl(req: Connect.IncomingMessage): URL | null {\n const xForwardedProtoHeader = req.headers['x-forwarded-proto'];\n const xForwardedHostHeader = req.headers['x-forwarded-host'];\n const hostHeader = req.headers.host;\n\n const protocol = Array.isArray(xForwardedProtoHeader)\n ? xForwardedProtoHeader[0]\n : (xForwardedProtoHeader ?? (req.socket && 'encrypted' in req.socket && req.socket.encrypted ? 'https' : 'http'));\n const host = Array.isArray(xForwardedHostHeader) ? xForwardedHostHeader[0] : (xForwardedHostHeader ?? hostHeader);\n\n if (host && req.originalUrl) {\n return new URL(`${protocol}://${host}${req.originalUrl}`);\n }\n\n return null;\n}\n\nexport function isBloggerPath(path: string): boolean {\n return (\n path === '/' ||\n path === '/search' ||\n /^\\/search\\/label(\\/[^/]+)?\\/?$/.test(path) ||\n /^p\\/.+\\.html$/.test(path) ||\n /^\\/\\d{4}\\/\\d{2}(\\/?|\\/[^/\\s]+\\.html)$/.test(path)\n );\n}\n\nconst TAILWIND_PLUGIN_NAMES = new Set(['@tailwindcss/vite:scan']);\n\nexport function isTailwindPlugin(plugin: { name: string }): boolean {\n return TAILWIND_PLUGIN_NAMES.has(plugin.name);\n}\n\nexport function errorHtml(reqUrl: string): string {\n return `<!DOCTYPE html>\n<html>\n\n<head>\n <meta charset='UTF-8'/>\n <meta content='width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=5, user-scalable=yes' name='viewport'/>\n <title>500 Internal Server Error</title>\n <link rel='icon' href='data:,' />\n <style>\n *, ::before, ::after {\n box-sizing: border-box;\n }\n body {\n min-height: 100svh;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n margin: 0;\n padding: 20px;\n background-color: #f5f5f5;\n font-family: ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Helvetica Neue, Arial, Noto Sans, sans-serif, \"Apple Color Emoji\", \"Segoe UI Emoji\", Segoe UI Symbol, \"Noto Color Emoji\";\n }\n .card {\n padding: 24px;\n background-color: #ffffff;\n border: 1px solid #e5e5e5;\n max-width: 448px;\n border-radius: 14px;\n box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);\n display: flex;\n flex-direction: column;\n gap: 24px;\n }\n .card-content {\n display: flex;\n flex-direction: column;\n gap: 6px;\n }\n .card-title {\n font-weight: 600;\n }\n .card-description {\n font-size: 14px;\n opacity: 0.85;\n }\n .card-footer {\n display: flex;\n align-items: center;\n }\n .button {\n display: inline-flex;\n white-space: nowrap;\n align-items: center;\n justify-content: center;\n gap: 8px;\n padding: 8px 16px;\n font-weight: 500;\n background-color: #171717;\n outline: none;\n border: none;\n color: #ffffff;\n border-radius: 8px;\n min-height: 36px;\n }\n .button:hover {\n opacity: 0.9;\n }\n .button svg {\n wiheadersdth: 16px;\n height: 16px;\n flex-shrink: 0;\n }\n .card-footer .button {\n flex-grow: 1;\n }\n </style>\n</head>\n\n<body>\n <div class='card'>\n <div class='card-content'>\n <div class='card-title'>500 Internal Server Error</div>\n <div class='card-description'>Failed to fetch: ${escapeHtml(reqUrl)}</div>\n </div>\n <div class='card-footer'>\n <button class='button' type='button'>\n <svg xmlns=\"http://www.w3.org/2000/svg\" width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" class=\"lucide lucide-refresh-ccw\" aria-hidden=\"true\"><path d=\"M21 12a9 9 0 0 0-9-9 9.75 9.75 0 0 0-6.74 2.74L3 8\"></path><path d=\"M3 3v5h5\"></path><path d=\"M3 12a9 9 0 0 0 9 9 9.75 9.75 0 0 0 6.74-2.74L21 16\"></path><path d=\"M16 16h5v5\"></path></svg>\n Reload\n </button>\n </div>\n </div>\n <script>\n const button = document.getElementsByTagName('button')[0];\n button.addEventListener('click', () => {\n window.location.reload();\n });\n </script>\n</body>\n\n</html>`;\n}\n"],"mappings":"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"}
|
package/dist/vite.cjs
CHANGED
|
@@ -6,6 +6,7 @@ let node_fs = require("node:fs");
|
|
|
6
6
|
node_fs = require_runtime.__toESM(node_fs, 1);
|
|
7
7
|
let node_path = require("node:path");
|
|
8
8
|
node_path = require_runtime.__toESM(node_path, 1);
|
|
9
|
+
let minify_xml = require("minify-xml");
|
|
9
10
|
//#region src/vite.ts
|
|
10
11
|
function blogger(userOptions) {
|
|
11
12
|
const ctx = new BloggerPluginContext(userOptions);
|
|
@@ -28,7 +29,7 @@ function blogger(userOptions) {
|
|
|
28
29
|
ctx.tailwind = config.plugins.flat(Number.POSITIVE_INFINITY).some((plugin) => require_utils.isTailwindPlugin(plugin));
|
|
29
30
|
if (ctx.tailwind) {
|
|
30
31
|
require_tailwind.clearTailwindCache(ctx.root);
|
|
31
|
-
if (config.command === "build") require_tailwind.updateTailwindCache(ctx.root, node_fs.readFileSync(ctx.template, "utf-8"));
|
|
32
|
+
if (config.command === "build") require_tailwind.updateTailwindCache(ctx.root, require_utils.unescapeHTML(node_fs.readFileSync(ctx.template, "utf-8"), true), "xml");
|
|
32
33
|
} else require_tailwind.removeTailwindCache(ctx.root);
|
|
33
34
|
},
|
|
34
35
|
resolveId(source) {
|
|
@@ -74,7 +75,9 @@ Without this, your assets may fail to load in Blogger.
|
|
|
74
75
|
});
|
|
75
76
|
}).replace(/<(link|meta|img|br|hr|input)([^>]*?)>/gi, (_, $1, $2) => `<${$1}${$2}/>`).replace(/>\s+</g, "><").trim();
|
|
76
77
|
const modifiedTemplateXmlContent = require_utils.replaceBloggerPluginHeadComment(node_fs.readFileSync(ctx.template, "utf8"), headContent, true);
|
|
77
|
-
|
|
78
|
+
node_fs.writeFileSync(node_path.resolve(ctx.viteConfig.build.outDir, "template.xml"), modifiedTemplateXmlContent);
|
|
79
|
+
if (ctx.xml.tags) {
|
|
80
|
+
const templateTagsXmlContent = `<?xml version="1.0" encoding="UTF-8" ?>
|
|
78
81
|
<!DOCTYPE html>
|
|
79
82
|
<html>
|
|
80
83
|
<head>
|
|
@@ -96,8 +99,18 @@ Without this, your assets may fail to load in Blogger.
|
|
|
96
99
|
<!--body:beforeend:end-->
|
|
97
100
|
</body>
|
|
98
101
|
</html>`;
|
|
99
|
-
|
|
100
|
-
|
|
102
|
+
node_fs.writeFileSync(node_path.resolve(ctx.viteConfig.build.outDir, "template.tags.xml"), templateTagsXmlContent);
|
|
103
|
+
}
|
|
104
|
+
if (ctx.xml.minify) {
|
|
105
|
+
const minifiedTemplateXmlContent = (0, minify_xml.minify)(modifiedTemplateXmlContent, {
|
|
106
|
+
removeComments: false,
|
|
107
|
+
shortenNamespaces: false,
|
|
108
|
+
removeUnusedNamespaces: false,
|
|
109
|
+
removeUnusedDefaultNamespace: false,
|
|
110
|
+
ignoreCData: true
|
|
111
|
+
});
|
|
112
|
+
node_fs.writeFileSync(node_path.resolve(ctx.viteConfig.build.outDir, "template.min.xml"), minifiedTemplateXmlContent);
|
|
113
|
+
}
|
|
101
114
|
},
|
|
102
115
|
closeBundle() {
|
|
103
116
|
const htmlDir = node_path.resolve(ctx.viteConfig.build.outDir, "virtual:blogger-plugin");
|
|
@@ -113,6 +126,7 @@ Without this, your assets may fail to load in Blogger.
|
|
|
113
126
|
}
|
|
114
127
|
var BloggerPluginContext = class {
|
|
115
128
|
constructor(options) {
|
|
129
|
+
var _options$xml$tags, _options$xml, _options$xml$minify, _options$xml2;
|
|
116
130
|
if (typeof options.template !== "undefined" && typeof options.template !== "string") throw new Error("Option 'template' must be a string");
|
|
117
131
|
if (typeof options.modules !== "undefined" && !Array.isArray(options.modules)) throw new Error("Option 'modules' must be an array");
|
|
118
132
|
if (typeof options.styles !== "undefined" && !Array.isArray(options.styles)) throw new Error("Option 'styles' must be an array");
|
|
@@ -130,6 +144,10 @@ var BloggerPluginContext = class {
|
|
|
130
144
|
this.template = void 0;
|
|
131
145
|
this.name = void 0;
|
|
132
146
|
this.proxyBlog = proxyBlog;
|
|
147
|
+
this.xml = {
|
|
148
|
+
tags: (_options$xml$tags = (_options$xml = options.xml) === null || _options$xml === void 0 ? void 0 : _options$xml.tags) !== null && _options$xml$tags !== void 0 ? _options$xml$tags : false,
|
|
149
|
+
minify: (_options$xml$minify = (_options$xml2 = options.xml) === null || _options$xml2 === void 0 ? void 0 : _options$xml2.minify) !== null && _options$xml$minify !== void 0 ? _options$xml$minify : false
|
|
150
|
+
};
|
|
133
151
|
this.viteConfig = void 0;
|
|
134
152
|
this.tailwind = false;
|
|
135
153
|
this.input = void 0;
|
|
@@ -258,7 +276,7 @@ function useServerMiddleware(server, ctx, _this) {
|
|
|
258
276
|
let htmlTemplateContent = await proxyResponse.text();
|
|
259
277
|
const secFetchDestHeader = req.headers["sec-fetch-dest"];
|
|
260
278
|
const secFetchModeHeader = req.headers["sec-fetch-mode"];
|
|
261
|
-
if (ctx.tailwind && isViteDevServer(server) && secFetchDestHeader === "document" && secFetchModeHeader === "navigate") await require_tailwind.updateTailwindCache(ctx.root, htmlTemplateContent);
|
|
279
|
+
if (ctx.tailwind && isViteDevServer(server) && secFetchDestHeader === "document" && secFetchModeHeader === "navigate") await require_tailwind.updateTailwindCache(ctx.root, htmlTemplateContent, "html");
|
|
262
280
|
htmlTemplateContent = require_utils.replaceHost(htmlTemplateContent, proxyUrl.host, url.host, url.protocol);
|
|
263
281
|
if (isViteDevServer(server)) {
|
|
264
282
|
const template = await server.transformIndexHtml(req.url, require_utils.replaceBloggerPluginHeadComment(htmlTemplateContent, ctx.headTags.join("")), req.originalUrl);
|
package/dist/vite.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite.cjs","names":["VITE_BUNDLER_KEY","replaceBloggerPluginHeadComment","fs","isTailwindPlugin","path","DEFAULT_MODULES","DEFAULT_TEMPLATES","getRequestUrl","toWebHeaders","updateTailwindCache","replaceHost","getBloggerPluginHeadComment","errorHtml"],"sources":["../src/vite.ts"],"sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { MinimalPluginContextWithoutEnvironment, Plugin, PreviewServer, ResolvedConfig, UserConfig, ViteDevServer } from 'vite';\nimport { DEFAULT_MODULES, DEFAULT_TEMPLATES, VITE_BUNDLER_KEY } from './constants';\nimport { clearTailwindCache, removeTailwindCache, updateTailwindCache } from './tailwind';\nimport {\n errorHtml,\n getBloggerPluginHeadComment,\n getRequestUrl,\n isTailwindPlugin,\n replaceBloggerPluginHeadComment,\n replaceHost,\n toWebHeaders,\n} from './utils';\n\nexport interface BloggerPluginOptions {\n modules?: string[];\n styles?: string[];\n template?: string;\n proxyBlog: string;\n}\n\nexport default function blogger(userOptions: BloggerPluginOptions): Plugin {\n const ctx = new BloggerPluginContext(userOptions);\n\n return {\n name: '@blogger-plugin/vite',\n config(config) {\n // resolve plugin context\n ctx.resolve(config);\n\n // modify vite config\n config.build ||= {};\n config.build[VITE_BUNDLER_KEY] ||= {};\n const bundlerOptions = config.build[VITE_BUNDLER_KEY];\n if (Array.isArray(bundlerOptions.input)) {\n bundlerOptions.input = [...bundlerOptions.input, ctx.input];\n } else if (typeof bundlerOptions.input === 'object' && bundlerOptions.input !== null) {\n bundlerOptions.input[ctx.input] = ctx.input;\n } else {\n bundlerOptions.input = ctx.input;\n }\n\n const originalTemplateXmlContent = fs.readFileSync(ctx.template, 'utf8');\n // remove contents between comments from template\n const modifiedTemplateXmlContent = replaceBloggerPluginHeadComment(replaceBloggerPluginHeadComment(originalTemplateXmlContent, ''), '', true);\n\n fs.writeFileSync(ctx.template, modifiedTemplateXmlContent, 'utf-8');\n },\n configResolved(config) {\n ctx.viteConfig = config;\n ctx.tailwind = config.plugins.flat(Number.POSITIVE_INFINITY).some((plugin) => isTailwindPlugin(plugin));\n\n if (ctx.tailwind) {\n clearTailwindCache(ctx.root);\n\n if (config.command === 'build') {\n updateTailwindCache(ctx.root, fs.readFileSync(ctx.template, 'utf-8'));\n }\n } else {\n removeTailwindCache(ctx.root);\n }\n },\n resolveId(source) {\n if (source === ctx.input) {\n return ctx.input;\n }\n },\n load(id) {\n if (id === ctx.input) {\n return ctx.html;\n }\n },\n buildStart() {\n if (ctx.viteConfig.command === 'build' && !/^https?:\\/\\//.test(ctx.viteConfig.base)) {\n this.warn(`\"base\" should be a CDN URL in production\n----------------------\nBlogger cannot serve static assets (JS, CSS, etc.), so you must use\nan absolute URL (http:// or https://).\n\nCurrent value:\n base: \"${ctx.viteConfig.base}\"\n\nQuick fix:\n VITE_BASE=https://cdn.jsdelivr.net/gh/<username>/<repository>@latest/dist/ npm run build\n\nVite config (recommended):\n export default defineConfig({\n base: process.env.VITE_BASE ?? \"/\"\n });\n\nWithout this, your assets may fail to load in Blogger.\n----------------------`);\n }\n },\n writeBundle(_, bundle) {\n if (!(ctx.input in bundle)) {\n return;\n }\n const asset = bundle[ctx.input];\n delete bundle[ctx.input];\n\n if (asset.type !== 'asset' || typeof asset.source !== 'string') {\n return;\n }\n const regex =\n /<!DOCTYPE html>\\s*<html[^>]*>\\s*<head>([\\s\\S]*?)<!--head-->([\\s\\S]*?)<\\/head>\\s*<body>([\\s\\S]*?)<!--body-->([\\s\\S]*?)<\\/body>\\s*<\\/html>/i;\n const match = asset.source.match(regex);\n if (!match) {\n return;\n }\n\n const afterHeadBegin = match[1];\n const beforeHeadEnd = match[2];\n const afterBodyBegin = match[3];\n const beforeBodyEnd = match[4];\n\n const headContent = (afterHeadBegin + beforeHeadEnd)\n .replace(/<[^>]+>/g, (openingTag: string) => {\n return (\n openingTag\n // boolean attributes to empty string\n .replace(/\\b(crossorigin|defer|async|disabled|checked)\\b(?!\\s*=)/g, (_, $1: string) =>\n $1 === 'crossorigin' ? 'crossorigin=\"anonymous\"' : `${$1}=\"\"`,\n )\n // convert attributes to single quotes safely\n .replace(/(\\w+)=(\".*?\"|'.*?')/g, (_, $1: string, $2: string) => {\n const v = $2\n // remove quotes\n .slice(1, -1)\n // escape special XML chars\n .replace(/&/g, '&')\n .replace(/'/g, ''')\n .replace(/\"/g, '"')\n .replace(/</g, '<')\n .replace(/>/g, '>');\n return `${$1}='${v}'`;\n })\n );\n })\n // self-close void tags\n .replace(/<(link|meta|img|br|hr|input)([^>]*?)>/gi, (_, $1: string, $2: string) => `<${$1}${$2}/>`)\n // remove whitespace between tags\n .replace(/>\\s+</g, '><')\n // trim overall\n .trim();\n\n const originalTemplateXmlContent = fs.readFileSync(ctx.template, 'utf8');\n const modifiedTemplateXmlContent = replaceBloggerPluginHeadComment(originalTemplateXmlContent, headContent, true);\n\n const templateTagsXmlContent = `<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<!DOCTYPE html>\n<html>\n<head>\n <!--head:afterbegin:begin-->\n\n <!--head:afterbegin:end-->\n\n <!--head:beforeend:begin-->\n ${headContent}\n <!--head:beforeend:end-->\n</head>\n<body>\n <!--body:afterbegin:begin-->\n ${afterBodyBegin.trim()}\n <!--body:afterbegin:end-->\n\n <!--body:beforeend:begin-->\n ${beforeBodyEnd.trim()}\n <!--body:beforeend:end-->\n</body>\n</html>`;\n\n fs.writeFileSync(path.resolve(ctx.viteConfig.build.outDir, 'template.xml'), modifiedTemplateXmlContent);\n fs.writeFileSync(path.resolve(ctx.viteConfig.build.outDir, 'template-tags.xml'), templateTagsXmlContent);\n },\n closeBundle() {\n const htmlDir = path.resolve(ctx.viteConfig.build.outDir, 'virtual:blogger-plugin');\n if (fs.existsSync(htmlDir)) {\n fs.rmSync(htmlDir, { recursive: true });\n }\n },\n configureServer(server) {\n return useServerMiddleware(server, ctx, this);\n },\n configurePreviewServer(server) {\n return useServerMiddleware(server, ctx, this);\n },\n };\n}\n\nclass BloggerPluginContext {\n options: BloggerPluginOptions;\n root: string;\n modules: string[];\n styles: string[];\n template: string;\n name: string;\n proxyBlog: URL;\n viteConfig: ResolvedConfig;\n tailwind: boolean;\n input: string;\n html: string;\n headTags: string[];\n\n constructor(options: BloggerPluginOptions) {\n if (typeof options.template !== 'undefined' && typeof options.template !== 'string') {\n throw new Error(\"Option 'template' must be a string\");\n }\n if (typeof options.modules !== 'undefined' && !Array.isArray(options.modules)) {\n throw new Error(\"Option 'modules' must be an array\");\n }\n if (typeof options.styles !== 'undefined' && !Array.isArray(options.styles)) {\n throw new Error(\"Option 'styles' must be an array\");\n }\n if (typeof options.proxyBlog !== 'string') {\n throw new Error(\"Option 'proxyBlog' must be a string\");\n }\n let proxyBlog: URL;\n try {\n proxyBlog = new URL(options.proxyBlog);\n } catch {\n throw new Error(\"Option 'proxyBlog' must be a valid url\");\n }\n\n this.options = options;\n this.root = process.cwd();\n this.modules = [];\n this.styles = [];\n this.template = undefined as unknown as string;\n this.name = undefined as unknown as string;\n this.proxyBlog = proxyBlog;\n this.viteConfig = undefined as unknown as ResolvedConfig;\n this.tailwind = false;\n this.input = undefined as unknown as string;\n this.headTags = [];\n this.html = undefined as unknown as string;\n }\n\n resolve(config: UserConfig) {\n this.root = config.root ? path.resolve(config.root) : this.root;\n\n if (this.options.modules) {\n for (let i = 0; i < this.options.modules.length; i++) {\n const module = this.options.modules[i];\n const modulePath = path.resolve(this.root, module);\n if (this.modules.includes(modulePath)) {\n continue;\n }\n if (fs.existsSync(modulePath)) {\n this.modules.push(modulePath);\n } else {\n throw new Error(`The path provided at modules[${i}] does not exist: ${modulePath}`);\n }\n }\n } else {\n for (const module of DEFAULT_MODULES) {\n const modulePath = path.resolve(this.root, module);\n if (fs.existsSync(modulePath)) {\n this.modules.push(modulePath);\n break;\n }\n }\n }\n\n if (this.options.styles) {\n for (let i = 0; i < this.options.styles.length; i++) {\n const style = this.options.styles[i];\n const stylePath = path.resolve(this.root, style);\n if (this.styles.includes(stylePath)) {\n continue;\n }\n if (fs.existsSync(stylePath)) {\n this.styles.push(stylePath);\n } else {\n throw new Error(`The path provided at styles[${i}] does not exist: ${stylePath}`);\n }\n }\n }\n\n if (this.options.template) {\n const templatePath = path.resolve(this.root, this.options.template);\n if (fs.existsSync(templatePath)) {\n this.template = templatePath;\n } else {\n throw new Error(`Provided template file does not exist: ${templatePath}`);\n }\n } else {\n for (const file of DEFAULT_TEMPLATES) {\n const fullPath = path.resolve(this.root, file);\n if (fs.existsSync(fullPath)) {\n this.template = fullPath;\n break;\n }\n }\n\n if (!this.template) {\n throw new Error(\n 'No template file found.\\n' +\n `Tried: ${DEFAULT_TEMPLATES.join(', ')}\\n` +\n '👉 Tip: You can pass a custom template as shown:\\n' +\n ' blogger({ template: \"src/my-template.xml\" })',\n );\n }\n }\n\n this.name = path.basename(this.template, path.extname(this.template));\n\n for (const modulePath of this.modules) {\n this.headTags.push(`<script type=\"module\" src=\"/${path.relative(this.root, modulePath).replaceAll('\\\\', '/')}\"></script>`);\n }\n for (const stylePath of this.styles) {\n this.headTags.push(`<link rel=\"stylesheet\" href=\"/${path.relative(this.root, stylePath).replaceAll('\\\\', '/')}\">`);\n }\n\n this.input = `virtual:blogger-plugin/${this.name}.html`;\n this.html = `<!DOCTYPE html>\n<html>\n<head>\n <!--head-->${this.headTags.length > 0 ? `\\n ${this.headTags.join('\\n ')}` : ''}\n</head>\n<body>\n <!--body-->\n</body>\n</html>`;\n }\n}\n\nfunction useServerMiddleware(server: ViteDevServer | PreviewServer, ctx: BloggerPluginContext, _this: MinimalPluginContextWithoutEnvironment) {\n const input = ctx.viteConfig.build[VITE_BUNDLER_KEY].input;\n const htmlPathnames: string[] = [];\n for (const entry of Array.isArray(input) ? input : typeof input === 'object' ? Object.values(input) : typeof input === 'string' ? [input] : []) {\n if (entry === ctx.input) {\n continue;\n }\n const entryPath = path.resolve(ctx.root, entry);\n if (!entryPath.endsWith('.html')) {\n continue;\n }\n const relativePath = path.relative(ctx.root, entry).replaceAll('\\\\', '/');\n htmlPathnames.push(`/${relativePath}`);\n if (relativePath.endsWith('index.html')) {\n htmlPathnames.push(`/${relativePath.replace(/index\\.html$/, '')}`);\n }\n }\n\n return () => {\n server.httpServer?.once('listening', () => {\n setTimeout(() => {\n _this.info(`Unhandled requests will be proxied to ${ctx.proxyBlog.origin}`);\n }, 0);\n });\n\n server.middlewares.use(async (req, res, next) => {\n const url = getRequestUrl(req);\n\n if (\n !req.url ||\n !req.originalUrl ||\n !url ||\n !req.method ||\n !['GET', 'HEAD'].includes(req.method.toUpperCase()) ||\n htmlPathnames.includes(url.pathname.replace(/\\/+/g, '/'))\n ) {\n next();\n return;\n }\n\n const start = Date.now();\n\n const proxyUrl = new URL(`${ctx.proxyBlog.origin}${req.originalUrl}`);\n\n const viewParam = proxyUrl.searchParams.get('view');\n proxyUrl.searchParams.set('view', `${isViteDevServer(server) ? '-DevServer' : '-PreviewServer'}${viewParam?.startsWith('-') ? viewParam : ''}`);\n\n const proxyRequest = new Request(proxyUrl, {\n method: req.method,\n headers: toWebHeaders(req.headers),\n redirect: 'manual',\n });\n\n const proxyResponse = await fetch(proxyRequest).catch((error) => {\n if (error instanceof Error) {\n _this.warn({\n message: `${error.name}: ${error.message}`,\n cause: error.cause,\n stack: error.stack,\n });\n } else {\n _this.warn('Fetch failed');\n }\n return null;\n });\n\n if (proxyResponse) {\n res.statusCode = proxyResponse.status;\n res.statusMessage = proxyResponse.statusText;\n\n proxyResponse.headers.forEach((value, key) => {\n if (key === 'location') {\n const redirectUrl = new URL(value, proxyUrl);\n if (redirectUrl.host === url.host || redirectUrl.host === proxyUrl.host) {\n redirectUrl.host = url.host;\n redirectUrl.protocol = url.protocol;\n const viewParam = redirectUrl.searchParams.get('view')?.replaceAll('-DevServer', '').replaceAll('-PreviewServer', '');\n if (viewParam) {\n redirectUrl.searchParams.set('view', viewParam);\n } else {\n redirectUrl.searchParams.delete('view');\n }\n res.setHeader('location', redirectUrl.pathname + redirectUrl.search + redirectUrl.hash);\n } else {\n res.setHeader('location', redirectUrl.href);\n }\n } else if (['content-type', 'x-robots-tag', 'date', 'location'].includes(key)) {\n res.setHeader(key, value);\n }\n });\n\n const contentType = proxyResponse.headers.get('content-type');\n\n if (contentType?.startsWith('text/html')) {\n let htmlTemplateContent = await proxyResponse.text();\n\n const secFetchDestHeader = req.headers['sec-fetch-dest'];\n const secFetchModeHeader = req.headers['sec-fetch-mode'];\n if (ctx.tailwind && isViteDevServer(server) && secFetchDestHeader === 'document' && secFetchModeHeader === 'navigate') {\n await updateTailwindCache(ctx.root, htmlTemplateContent);\n }\n\n htmlTemplateContent = replaceHost(htmlTemplateContent, proxyUrl.host, url.host, url.protocol);\n\n if (isViteDevServer(server)) {\n const template = await server.transformIndexHtml(\n req.url,\n replaceBloggerPluginHeadComment(htmlTemplateContent, ctx.headTags.join('')),\n req.originalUrl,\n );\n\n res.end(template);\n } else {\n const xmlTemplateContent = fs.readFileSync(path.resolve(ctx.viteConfig.build.outDir, 'template.xml'), 'utf8');\n\n const htmlTagsStr = getBloggerPluginHeadComment(xmlTemplateContent, true);\n\n const template = replaceBloggerPluginHeadComment(htmlTemplateContent, htmlTagsStr ?? '');\n\n res.end(template);\n }\n } else if (contentType && /^(text\\/)|(application\\/(.*\\+)?(xml|json))/.test(contentType)) {\n const content = await proxyResponse.text();\n\n res.end(replaceHost(content, proxyUrl.host, url.host, url.protocol));\n } else {\n res.end(new Uint8Array(await proxyResponse.arrayBuffer()));\n }\n } else {\n res.statusCode = 500;\n res.statusMessage = 'Internal Server Error';\n\n res.setHeader('Content-Type', 'text/html');\n\n res.end(errorHtml(proxyUrl.href));\n }\n\n const duration = Date.now() - start;\n\n _this.info(`${req.method} ${req.originalUrl} -> ${res.statusCode} ${res.statusMessage} (${duration}ms)`);\n });\n };\n}\n\nfunction isViteDevServer(server: ViteDevServer | PreviewServer): server is ViteDevServer {\n return 'hot' in server && 'transformRequest' in server && 'transformIndexHtml' in server;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"vite.cjs","names":["VITE_BUNDLER_KEY","replaceBloggerPluginHeadComment","fs","isTailwindPlugin","unescapeHTML","path","DEFAULT_MODULES","DEFAULT_TEMPLATES","getRequestUrl","toWebHeaders","updateTailwindCache","replaceHost","getBloggerPluginHeadComment","errorHtml"],"sources":["../src/vite.ts"],"sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { type MinifyOptions, minify } from 'minify-xml';\nimport type { MinimalPluginContextWithoutEnvironment, Plugin, PreviewServer, ResolvedConfig, UserConfig, ViteDevServer } from 'vite';\nimport { DEFAULT_MODULES, DEFAULT_TEMPLATES, VITE_BUNDLER_KEY } from './constants';\nimport { clearTailwindCache, removeTailwindCache, updateTailwindCache } from './tailwind';\nimport {\n errorHtml,\n getBloggerPluginHeadComment,\n getRequestUrl,\n isTailwindPlugin,\n replaceBloggerPluginHeadComment,\n replaceHost,\n toWebHeaders,\n unescapeHTML,\n} from './utils';\n\nexport interface XMLOptions {\n tags?: boolean;\n minify?: boolean;\n}\n\nexport interface BloggerPluginOptions {\n modules?: string[];\n styles?: string[];\n template?: string;\n proxyBlog: string;\n xml?: XMLOptions;\n}\n\nexport default function blogger(userOptions: BloggerPluginOptions): Plugin {\n const ctx = new BloggerPluginContext(userOptions);\n\n return {\n name: '@blogger-plugin/vite',\n config(config) {\n // resolve plugin context\n ctx.resolve(config);\n\n // modify vite config\n config.build ||= {};\n config.build[VITE_BUNDLER_KEY] ||= {};\n const bundlerOptions = config.build[VITE_BUNDLER_KEY];\n if (Array.isArray(bundlerOptions.input)) {\n bundlerOptions.input = [...bundlerOptions.input, ctx.input];\n } else if (typeof bundlerOptions.input === 'object' && bundlerOptions.input !== null) {\n bundlerOptions.input[ctx.input] = ctx.input;\n } else {\n bundlerOptions.input = ctx.input;\n }\n\n const originalTemplateXmlContent = fs.readFileSync(ctx.template, 'utf8');\n // remove contents between comments from template\n const modifiedTemplateXmlContent = replaceBloggerPluginHeadComment(replaceBloggerPluginHeadComment(originalTemplateXmlContent, ''), '', true);\n\n fs.writeFileSync(ctx.template, modifiedTemplateXmlContent, 'utf-8');\n },\n configResolved(config) {\n ctx.viteConfig = config;\n ctx.tailwind = config.plugins.flat(Number.POSITIVE_INFINITY).some((plugin) => isTailwindPlugin(plugin));\n\n if (ctx.tailwind) {\n clearTailwindCache(ctx.root);\n\n if (config.command === 'build') {\n updateTailwindCache(ctx.root, unescapeHTML(fs.readFileSync(ctx.template, 'utf-8'), true), 'xml');\n }\n } else {\n removeTailwindCache(ctx.root);\n }\n },\n resolveId(source) {\n if (source === ctx.input) {\n return ctx.input;\n }\n },\n load(id) {\n if (id === ctx.input) {\n return ctx.html;\n }\n },\n buildStart() {\n if (ctx.viteConfig.command === 'build' && !/^https?:\\/\\//.test(ctx.viteConfig.base)) {\n this.warn(`\"base\" should be a CDN URL in production\n----------------------\nBlogger cannot serve static assets (JS, CSS, etc.), so you must use\nan absolute URL (http:// or https://).\n\nCurrent value:\n base: \"${ctx.viteConfig.base}\"\n\nQuick fix:\n VITE_BASE=https://cdn.jsdelivr.net/gh/<username>/<repository>@latest/dist/ npm run build\n\nVite config (recommended):\n export default defineConfig({\n base: process.env.VITE_BASE ?? \"/\"\n });\n\nWithout this, your assets may fail to load in Blogger.\n----------------------`);\n }\n },\n writeBundle(_, bundle) {\n if (!(ctx.input in bundle)) {\n return;\n }\n const asset = bundle[ctx.input];\n delete bundle[ctx.input];\n\n if (asset.type !== 'asset' || typeof asset.source !== 'string') {\n return;\n }\n const regex =\n /<!DOCTYPE html>\\s*<html[^>]*>\\s*<head>([\\s\\S]*?)<!--head-->([\\s\\S]*?)<\\/head>\\s*<body>([\\s\\S]*?)<!--body-->([\\s\\S]*?)<\\/body>\\s*<\\/html>/i;\n const match = asset.source.match(regex);\n if (!match) {\n return;\n }\n\n const afterHeadBegin = match[1];\n const beforeHeadEnd = match[2];\n const afterBodyBegin = match[3];\n const beforeBodyEnd = match[4];\n\n const headContent = (afterHeadBegin + beforeHeadEnd)\n .replace(/<[^>]+>/g, (openingTag: string) => {\n return (\n openingTag\n // boolean attributes to empty string\n .replace(/\\b(crossorigin|defer|async|disabled|checked)\\b(?!\\s*=)/g, (_, $1: string) =>\n $1 === 'crossorigin' ? 'crossorigin=\"anonymous\"' : `${$1}=\"\"`,\n )\n // convert attributes to single quotes safely\n .replace(/(\\w+)=(\".*?\"|'.*?')/g, (_, $1: string, $2: string) => {\n const v = $2\n // remove quotes\n .slice(1, -1)\n // escape special XML chars\n .replace(/&/g, '&')\n .replace(/'/g, ''')\n .replace(/\"/g, '"')\n .replace(/</g, '<')\n .replace(/>/g, '>');\n return `${$1}='${v}'`;\n })\n );\n })\n // self-close void tags\n .replace(/<(link|meta|img|br|hr|input)([^>]*?)>/gi, (_, $1: string, $2: string) => `<${$1}${$2}/>`)\n // remove whitespace between tags\n .replace(/>\\s+</g, '><')\n // trim overall\n .trim();\n\n const originalTemplateXmlContent = fs.readFileSync(ctx.template, 'utf8');\n const modifiedTemplateXmlContent = replaceBloggerPluginHeadComment(originalTemplateXmlContent, headContent, true);\n\n fs.writeFileSync(path.resolve(ctx.viteConfig.build.outDir, 'template.xml'), modifiedTemplateXmlContent);\n\n if (ctx.xml.tags) {\n const templateTagsXmlContent = `<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<!DOCTYPE html>\n<html>\n<head>\n <!--head:afterbegin:begin-->\n\n <!--head:afterbegin:end-->\n\n <!--head:beforeend:begin-->\n ${headContent}\n <!--head:beforeend:end-->\n</head>\n<body>\n <!--body:afterbegin:begin-->\n ${afterBodyBegin.trim()}\n <!--body:afterbegin:end-->\n\n <!--body:beforeend:begin-->\n ${beforeBodyEnd.trim()}\n <!--body:beforeend:end-->\n</body>\n</html>`;\n fs.writeFileSync(path.resolve(ctx.viteConfig.build.outDir, 'template.tags.xml'), templateTagsXmlContent);\n }\n\n if (ctx.xml.minify) {\n const minifiedTemplateXmlContent = minify(modifiedTemplateXmlContent, {\n removeComments: false,\n shortenNamespaces: false,\n removeUnusedNamespaces: false,\n removeUnusedDefaultNamespace: false,\n ignoreCData: true,\n } as MinifyOptions);\n fs.writeFileSync(path.resolve(ctx.viteConfig.build.outDir, 'template.min.xml'), minifiedTemplateXmlContent);\n }\n },\n closeBundle() {\n const htmlDir = path.resolve(ctx.viteConfig.build.outDir, 'virtual:blogger-plugin');\n if (fs.existsSync(htmlDir)) {\n fs.rmSync(htmlDir, { recursive: true });\n }\n },\n configureServer(server) {\n return useServerMiddleware(server, ctx, this);\n },\n configurePreviewServer(server) {\n return useServerMiddleware(server, ctx, this);\n },\n };\n}\n\nclass BloggerPluginContext {\n private options: BloggerPluginOptions;\n root: string;\n modules: string[];\n styles: string[];\n template: string;\n name: string;\n proxyBlog: URL;\n xml: Required<XMLOptions>;\n viteConfig: ResolvedConfig;\n tailwind: boolean;\n input: string;\n html: string;\n headTags: string[];\n\n constructor(options: BloggerPluginOptions) {\n if (typeof options.template !== 'undefined' && typeof options.template !== 'string') {\n throw new Error(\"Option 'template' must be a string\");\n }\n if (typeof options.modules !== 'undefined' && !Array.isArray(options.modules)) {\n throw new Error(\"Option 'modules' must be an array\");\n }\n if (typeof options.styles !== 'undefined' && !Array.isArray(options.styles)) {\n throw new Error(\"Option 'styles' must be an array\");\n }\n if (typeof options.proxyBlog !== 'string') {\n throw new Error(\"Option 'proxyBlog' must be a string\");\n }\n let proxyBlog: URL;\n try {\n proxyBlog = new URL(options.proxyBlog);\n } catch {\n throw new Error(\"Option 'proxyBlog' must be a valid url\");\n }\n\n this.options = options;\n this.root = process.cwd();\n this.modules = [];\n this.styles = [];\n this.template = undefined as unknown as string;\n this.name = undefined as unknown as string;\n this.proxyBlog = proxyBlog;\n this.xml = {\n tags: options.xml?.tags ?? false,\n minify: options.xml?.minify ?? false,\n };\n this.viteConfig = undefined as unknown as ResolvedConfig;\n this.tailwind = false;\n this.input = undefined as unknown as string;\n this.headTags = [];\n this.html = undefined as unknown as string;\n }\n\n resolve(config: UserConfig) {\n this.root = config.root ? path.resolve(config.root) : this.root;\n\n if (this.options.modules) {\n for (let i = 0; i < this.options.modules.length; i++) {\n const module = this.options.modules[i];\n const modulePath = path.resolve(this.root, module);\n if (this.modules.includes(modulePath)) {\n continue;\n }\n if (fs.existsSync(modulePath)) {\n this.modules.push(modulePath);\n } else {\n throw new Error(`The path provided at modules[${i}] does not exist: ${modulePath}`);\n }\n }\n } else {\n for (const module of DEFAULT_MODULES) {\n const modulePath = path.resolve(this.root, module);\n if (fs.existsSync(modulePath)) {\n this.modules.push(modulePath);\n break;\n }\n }\n }\n\n if (this.options.styles) {\n for (let i = 0; i < this.options.styles.length; i++) {\n const style = this.options.styles[i];\n const stylePath = path.resolve(this.root, style);\n if (this.styles.includes(stylePath)) {\n continue;\n }\n if (fs.existsSync(stylePath)) {\n this.styles.push(stylePath);\n } else {\n throw new Error(`The path provided at styles[${i}] does not exist: ${stylePath}`);\n }\n }\n }\n\n if (this.options.template) {\n const templatePath = path.resolve(this.root, this.options.template);\n if (fs.existsSync(templatePath)) {\n this.template = templatePath;\n } else {\n throw new Error(`Provided template file does not exist: ${templatePath}`);\n }\n } else {\n for (const file of DEFAULT_TEMPLATES) {\n const fullPath = path.resolve(this.root, file);\n if (fs.existsSync(fullPath)) {\n this.template = fullPath;\n break;\n }\n }\n\n if (!this.template) {\n throw new Error(\n 'No template file found.\\n' +\n `Tried: ${DEFAULT_TEMPLATES.join(', ')}\\n` +\n '👉 Tip: You can pass a custom template as shown:\\n' +\n ' blogger({ template: \"src/my-template.xml\" })',\n );\n }\n }\n\n this.name = path.basename(this.template, path.extname(this.template));\n\n for (const modulePath of this.modules) {\n this.headTags.push(`<script type=\"module\" src=\"/${path.relative(this.root, modulePath).replaceAll('\\\\', '/')}\"></script>`);\n }\n for (const stylePath of this.styles) {\n this.headTags.push(`<link rel=\"stylesheet\" href=\"/${path.relative(this.root, stylePath).replaceAll('\\\\', '/')}\">`);\n }\n\n this.input = `virtual:blogger-plugin/${this.name}.html`;\n this.html = `<!DOCTYPE html>\n<html>\n<head>\n <!--head-->${this.headTags.length > 0 ? `\\n ${this.headTags.join('\\n ')}` : ''}\n</head>\n<body>\n <!--body-->\n</body>\n</html>`;\n }\n}\n\nfunction useServerMiddleware(server: ViteDevServer | PreviewServer, ctx: BloggerPluginContext, _this: MinimalPluginContextWithoutEnvironment) {\n const input = ctx.viteConfig.build[VITE_BUNDLER_KEY].input;\n const htmlPathnames: string[] = [];\n for (const entry of Array.isArray(input) ? input : typeof input === 'object' ? Object.values(input) : typeof input === 'string' ? [input] : []) {\n if (entry === ctx.input) {\n continue;\n }\n const entryPath = path.resolve(ctx.root, entry);\n if (!entryPath.endsWith('.html')) {\n continue;\n }\n const relativePath = path.relative(ctx.root, entry).replaceAll('\\\\', '/');\n htmlPathnames.push(`/${relativePath}`);\n if (relativePath.endsWith('index.html')) {\n htmlPathnames.push(`/${relativePath.replace(/index\\.html$/, '')}`);\n }\n }\n\n return () => {\n server.httpServer?.once('listening', () => {\n setTimeout(() => {\n _this.info(`Unhandled requests will be proxied to ${ctx.proxyBlog.origin}`);\n }, 0);\n });\n\n server.middlewares.use(async (req, res, next) => {\n const url = getRequestUrl(req);\n\n if (\n !req.url ||\n !req.originalUrl ||\n !url ||\n !req.method ||\n !['GET', 'HEAD'].includes(req.method.toUpperCase()) ||\n htmlPathnames.includes(url.pathname.replace(/\\/+/g, '/'))\n ) {\n next();\n return;\n }\n\n const start = Date.now();\n\n const proxyUrl = new URL(`${ctx.proxyBlog.origin}${req.originalUrl}`);\n\n const viewParam = proxyUrl.searchParams.get('view');\n proxyUrl.searchParams.set('view', `${isViteDevServer(server) ? '-DevServer' : '-PreviewServer'}${viewParam?.startsWith('-') ? viewParam : ''}`);\n\n const proxyRequest = new Request(proxyUrl, {\n method: req.method,\n headers: toWebHeaders(req.headers),\n redirect: 'manual',\n });\n\n const proxyResponse = await fetch(proxyRequest).catch((error) => {\n if (error instanceof Error) {\n _this.warn({\n message: `${error.name}: ${error.message}`,\n cause: error.cause,\n stack: error.stack,\n });\n } else {\n _this.warn('Fetch failed');\n }\n return null;\n });\n\n if (proxyResponse) {\n res.statusCode = proxyResponse.status;\n res.statusMessage = proxyResponse.statusText;\n\n proxyResponse.headers.forEach((value, key) => {\n if (key === 'location') {\n const redirectUrl = new URL(value, proxyUrl);\n if (redirectUrl.host === url.host || redirectUrl.host === proxyUrl.host) {\n redirectUrl.host = url.host;\n redirectUrl.protocol = url.protocol;\n const viewParam = redirectUrl.searchParams.get('view')?.replaceAll('-DevServer', '').replaceAll('-PreviewServer', '');\n if (viewParam) {\n redirectUrl.searchParams.set('view', viewParam);\n } else {\n redirectUrl.searchParams.delete('view');\n }\n res.setHeader('location', redirectUrl.pathname + redirectUrl.search + redirectUrl.hash);\n } else {\n res.setHeader('location', redirectUrl.href);\n }\n } else if (['content-type', 'x-robots-tag', 'date', 'location'].includes(key)) {\n res.setHeader(key, value);\n }\n });\n\n const contentType = proxyResponse.headers.get('content-type');\n\n if (contentType?.startsWith('text/html')) {\n let htmlTemplateContent = await proxyResponse.text();\n\n const secFetchDestHeader = req.headers['sec-fetch-dest'];\n const secFetchModeHeader = req.headers['sec-fetch-mode'];\n if (ctx.tailwind && isViteDevServer(server) && secFetchDestHeader === 'document' && secFetchModeHeader === 'navigate') {\n await updateTailwindCache(ctx.root, htmlTemplateContent, 'html');\n }\n\n htmlTemplateContent = replaceHost(htmlTemplateContent, proxyUrl.host, url.host, url.protocol);\n\n if (isViteDevServer(server)) {\n const template = await server.transformIndexHtml(\n req.url,\n replaceBloggerPluginHeadComment(htmlTemplateContent, ctx.headTags.join('')),\n req.originalUrl,\n );\n\n res.end(template);\n } else {\n const xmlTemplateContent = fs.readFileSync(path.resolve(ctx.viteConfig.build.outDir, 'template.xml'), 'utf8');\n\n const htmlTagsStr = getBloggerPluginHeadComment(xmlTemplateContent, true);\n\n const template = replaceBloggerPluginHeadComment(htmlTemplateContent, htmlTagsStr ?? '');\n\n res.end(template);\n }\n } else if (contentType && /^(text\\/)|(application\\/(.*\\+)?(xml|json))/.test(contentType)) {\n const content = await proxyResponse.text();\n\n res.end(replaceHost(content, proxyUrl.host, url.host, url.protocol));\n } else {\n res.end(new Uint8Array(await proxyResponse.arrayBuffer()));\n }\n } else {\n res.statusCode = 500;\n res.statusMessage = 'Internal Server Error';\n\n res.setHeader('Content-Type', 'text/html');\n\n res.end(errorHtml(proxyUrl.href));\n }\n\n const duration = Date.now() - start;\n\n _this.info(`${req.method} ${req.originalUrl} -> ${res.statusCode} ${res.statusMessage} (${duration}ms)`);\n });\n };\n}\n\nfunction isViteDevServer(server: ViteDevServer | PreviewServer): server is ViteDevServer {\n return 'hot' in server && 'transformRequest' in server && 'transformIndexHtml' in server;\n}\n"],"mappings":"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"}
|
package/dist/vite.d.cts
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import { Plugin } from "vite";
|
|
2
2
|
|
|
3
3
|
//#region src/vite.d.ts
|
|
4
|
+
interface XMLOptions {
|
|
5
|
+
tags?: boolean;
|
|
6
|
+
minify?: boolean;
|
|
7
|
+
}
|
|
4
8
|
interface BloggerPluginOptions {
|
|
5
9
|
modules?: string[];
|
|
6
10
|
styles?: string[];
|
|
7
11
|
template?: string;
|
|
8
12
|
proxyBlog: string;
|
|
13
|
+
xml?: XMLOptions;
|
|
9
14
|
}
|
|
10
15
|
declare function blogger(userOptions: BloggerPluginOptions): Plugin;
|
|
11
16
|
//#endregion
|
|
12
|
-
export { BloggerPluginOptions, blogger as default };
|
|
17
|
+
export { BloggerPluginOptions, XMLOptions, blogger as default };
|
|
13
18
|
//# sourceMappingURL=vite.d.cts.map
|
package/dist/vite.d.mts
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
import { Plugin } from "vite";
|
|
2
2
|
|
|
3
3
|
//#region src/vite.d.ts
|
|
4
|
+
interface XMLOptions {
|
|
5
|
+
tags?: boolean;
|
|
6
|
+
minify?: boolean;
|
|
7
|
+
}
|
|
4
8
|
interface BloggerPluginOptions {
|
|
5
9
|
modules?: string[];
|
|
6
10
|
styles?: string[];
|
|
7
11
|
template?: string;
|
|
8
12
|
proxyBlog: string;
|
|
13
|
+
xml?: XMLOptions;
|
|
9
14
|
}
|
|
10
15
|
declare function blogger(userOptions: BloggerPluginOptions): Plugin;
|
|
11
16
|
//#endregion
|
|
12
|
-
export { BloggerPluginOptions, blogger as default };
|
|
17
|
+
export { BloggerPluginOptions, XMLOptions, blogger as default };
|
|
13
18
|
//# sourceMappingURL=vite.d.mts.map
|
package/dist/vite.mjs
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { DEFAULT_MODULES, DEFAULT_TEMPLATES, VITE_BUNDLER_KEY } from "./constants.mjs";
|
|
2
2
|
import { clearTailwindCache, removeTailwindCache, updateTailwindCache } from "./tailwind.mjs";
|
|
3
|
-
import { errorHtml, getBloggerPluginHeadComment, getRequestUrl, isTailwindPlugin, replaceBloggerPluginHeadComment, replaceHost, toWebHeaders } from "./utils.mjs";
|
|
3
|
+
import { errorHtml, getBloggerPluginHeadComment, getRequestUrl, isTailwindPlugin, replaceBloggerPluginHeadComment, replaceHost, toWebHeaders, unescapeHTML } from "./utils.mjs";
|
|
4
4
|
import * as fs from "node:fs";
|
|
5
5
|
import * as path from "node:path";
|
|
6
|
+
import { minify } from "minify-xml";
|
|
6
7
|
//#region src/vite.ts
|
|
7
8
|
function blogger(userOptions) {
|
|
8
9
|
const ctx = new BloggerPluginContext(userOptions);
|
|
@@ -25,7 +26,7 @@ function blogger(userOptions) {
|
|
|
25
26
|
ctx.tailwind = config.plugins.flat(Number.POSITIVE_INFINITY).some((plugin) => isTailwindPlugin(plugin));
|
|
26
27
|
if (ctx.tailwind) {
|
|
27
28
|
clearTailwindCache(ctx.root);
|
|
28
|
-
if (config.command === "build") updateTailwindCache(ctx.root, fs.readFileSync(ctx.template, "utf-8"));
|
|
29
|
+
if (config.command === "build") updateTailwindCache(ctx.root, unescapeHTML(fs.readFileSync(ctx.template, "utf-8"), true), "xml");
|
|
29
30
|
} else removeTailwindCache(ctx.root);
|
|
30
31
|
},
|
|
31
32
|
resolveId(source) {
|
|
@@ -71,7 +72,9 @@ Without this, your assets may fail to load in Blogger.
|
|
|
71
72
|
});
|
|
72
73
|
}).replace(/<(link|meta|img|br|hr|input)([^>]*?)>/gi, (_, $1, $2) => `<${$1}${$2}/>`).replace(/>\s+</g, "><").trim();
|
|
73
74
|
const modifiedTemplateXmlContent = replaceBloggerPluginHeadComment(fs.readFileSync(ctx.template, "utf8"), headContent, true);
|
|
74
|
-
|
|
75
|
+
fs.writeFileSync(path.resolve(ctx.viteConfig.build.outDir, "template.xml"), modifiedTemplateXmlContent);
|
|
76
|
+
if (ctx.xml.tags) {
|
|
77
|
+
const templateTagsXmlContent = `<?xml version="1.0" encoding="UTF-8" ?>
|
|
75
78
|
<!DOCTYPE html>
|
|
76
79
|
<html>
|
|
77
80
|
<head>
|
|
@@ -93,8 +96,18 @@ Without this, your assets may fail to load in Blogger.
|
|
|
93
96
|
<!--body:beforeend:end-->
|
|
94
97
|
</body>
|
|
95
98
|
</html>`;
|
|
96
|
-
|
|
97
|
-
|
|
99
|
+
fs.writeFileSync(path.resolve(ctx.viteConfig.build.outDir, "template.tags.xml"), templateTagsXmlContent);
|
|
100
|
+
}
|
|
101
|
+
if (ctx.xml.minify) {
|
|
102
|
+
const minifiedTemplateXmlContent = minify(modifiedTemplateXmlContent, {
|
|
103
|
+
removeComments: false,
|
|
104
|
+
shortenNamespaces: false,
|
|
105
|
+
removeUnusedNamespaces: false,
|
|
106
|
+
removeUnusedDefaultNamespace: false,
|
|
107
|
+
ignoreCData: true
|
|
108
|
+
});
|
|
109
|
+
fs.writeFileSync(path.resolve(ctx.viteConfig.build.outDir, "template.min.xml"), minifiedTemplateXmlContent);
|
|
110
|
+
}
|
|
98
111
|
},
|
|
99
112
|
closeBundle() {
|
|
100
113
|
const htmlDir = path.resolve(ctx.viteConfig.build.outDir, "virtual:blogger-plugin");
|
|
@@ -110,6 +123,7 @@ Without this, your assets may fail to load in Blogger.
|
|
|
110
123
|
}
|
|
111
124
|
var BloggerPluginContext = class {
|
|
112
125
|
constructor(options) {
|
|
126
|
+
var _options$xml$tags, _options$xml, _options$xml$minify, _options$xml2;
|
|
113
127
|
if (typeof options.template !== "undefined" && typeof options.template !== "string") throw new Error("Option 'template' must be a string");
|
|
114
128
|
if (typeof options.modules !== "undefined" && !Array.isArray(options.modules)) throw new Error("Option 'modules' must be an array");
|
|
115
129
|
if (typeof options.styles !== "undefined" && !Array.isArray(options.styles)) throw new Error("Option 'styles' must be an array");
|
|
@@ -127,6 +141,10 @@ var BloggerPluginContext = class {
|
|
|
127
141
|
this.template = void 0;
|
|
128
142
|
this.name = void 0;
|
|
129
143
|
this.proxyBlog = proxyBlog;
|
|
144
|
+
this.xml = {
|
|
145
|
+
tags: (_options$xml$tags = (_options$xml = options.xml) === null || _options$xml === void 0 ? void 0 : _options$xml.tags) !== null && _options$xml$tags !== void 0 ? _options$xml$tags : false,
|
|
146
|
+
minify: (_options$xml$minify = (_options$xml2 = options.xml) === null || _options$xml2 === void 0 ? void 0 : _options$xml2.minify) !== null && _options$xml$minify !== void 0 ? _options$xml$minify : false
|
|
147
|
+
};
|
|
130
148
|
this.viteConfig = void 0;
|
|
131
149
|
this.tailwind = false;
|
|
132
150
|
this.input = void 0;
|
|
@@ -255,7 +273,7 @@ function useServerMiddleware(server, ctx, _this) {
|
|
|
255
273
|
let htmlTemplateContent = await proxyResponse.text();
|
|
256
274
|
const secFetchDestHeader = req.headers["sec-fetch-dest"];
|
|
257
275
|
const secFetchModeHeader = req.headers["sec-fetch-mode"];
|
|
258
|
-
if (ctx.tailwind && isViteDevServer(server) && secFetchDestHeader === "document" && secFetchModeHeader === "navigate") await updateTailwindCache(ctx.root, htmlTemplateContent);
|
|
276
|
+
if (ctx.tailwind && isViteDevServer(server) && secFetchDestHeader === "document" && secFetchModeHeader === "navigate") await updateTailwindCache(ctx.root, htmlTemplateContent, "html");
|
|
259
277
|
htmlTemplateContent = replaceHost(htmlTemplateContent, proxyUrl.host, url.host, url.protocol);
|
|
260
278
|
if (isViteDevServer(server)) {
|
|
261
279
|
const template = await server.transformIndexHtml(req.url, replaceBloggerPluginHeadComment(htmlTemplateContent, ctx.headTags.join("")), req.originalUrl);
|
package/dist/vite.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vite.mjs","names":[],"sources":["../src/vite.ts"],"sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { MinimalPluginContextWithoutEnvironment, Plugin, PreviewServer, ResolvedConfig, UserConfig, ViteDevServer } from 'vite';\nimport { DEFAULT_MODULES, DEFAULT_TEMPLATES, VITE_BUNDLER_KEY } from './constants';\nimport { clearTailwindCache, removeTailwindCache, updateTailwindCache } from './tailwind';\nimport {\n errorHtml,\n getBloggerPluginHeadComment,\n getRequestUrl,\n isTailwindPlugin,\n replaceBloggerPluginHeadComment,\n replaceHost,\n toWebHeaders,\n} from './utils';\n\nexport interface BloggerPluginOptions {\n modules?: string[];\n styles?: string[];\n template?: string;\n proxyBlog: string;\n}\n\nexport default function blogger(userOptions: BloggerPluginOptions): Plugin {\n const ctx = new BloggerPluginContext(userOptions);\n\n return {\n name: '@blogger-plugin/vite',\n config(config) {\n // resolve plugin context\n ctx.resolve(config);\n\n // modify vite config\n config.build ||= {};\n config.build[VITE_BUNDLER_KEY] ||= {};\n const bundlerOptions = config.build[VITE_BUNDLER_KEY];\n if (Array.isArray(bundlerOptions.input)) {\n bundlerOptions.input = [...bundlerOptions.input, ctx.input];\n } else if (typeof bundlerOptions.input === 'object' && bundlerOptions.input !== null) {\n bundlerOptions.input[ctx.input] = ctx.input;\n } else {\n bundlerOptions.input = ctx.input;\n }\n\n const originalTemplateXmlContent = fs.readFileSync(ctx.template, 'utf8');\n // remove contents between comments from template\n const modifiedTemplateXmlContent = replaceBloggerPluginHeadComment(replaceBloggerPluginHeadComment(originalTemplateXmlContent, ''), '', true);\n\n fs.writeFileSync(ctx.template, modifiedTemplateXmlContent, 'utf-8');\n },\n configResolved(config) {\n ctx.viteConfig = config;\n ctx.tailwind = config.plugins.flat(Number.POSITIVE_INFINITY).some((plugin) => isTailwindPlugin(plugin));\n\n if (ctx.tailwind) {\n clearTailwindCache(ctx.root);\n\n if (config.command === 'build') {\n updateTailwindCache(ctx.root, fs.readFileSync(ctx.template, 'utf-8'));\n }\n } else {\n removeTailwindCache(ctx.root);\n }\n },\n resolveId(source) {\n if (source === ctx.input) {\n return ctx.input;\n }\n },\n load(id) {\n if (id === ctx.input) {\n return ctx.html;\n }\n },\n buildStart() {\n if (ctx.viteConfig.command === 'build' && !/^https?:\\/\\//.test(ctx.viteConfig.base)) {\n this.warn(`\"base\" should be a CDN URL in production\n----------------------\nBlogger cannot serve static assets (JS, CSS, etc.), so you must use\nan absolute URL (http:// or https://).\n\nCurrent value:\n base: \"${ctx.viteConfig.base}\"\n\nQuick fix:\n VITE_BASE=https://cdn.jsdelivr.net/gh/<username>/<repository>@latest/dist/ npm run build\n\nVite config (recommended):\n export default defineConfig({\n base: process.env.VITE_BASE ?? \"/\"\n });\n\nWithout this, your assets may fail to load in Blogger.\n----------------------`);\n }\n },\n writeBundle(_, bundle) {\n if (!(ctx.input in bundle)) {\n return;\n }\n const asset = bundle[ctx.input];\n delete bundle[ctx.input];\n\n if (asset.type !== 'asset' || typeof asset.source !== 'string') {\n return;\n }\n const regex =\n /<!DOCTYPE html>\\s*<html[^>]*>\\s*<head>([\\s\\S]*?)<!--head-->([\\s\\S]*?)<\\/head>\\s*<body>([\\s\\S]*?)<!--body-->([\\s\\S]*?)<\\/body>\\s*<\\/html>/i;\n const match = asset.source.match(regex);\n if (!match) {\n return;\n }\n\n const afterHeadBegin = match[1];\n const beforeHeadEnd = match[2];\n const afterBodyBegin = match[3];\n const beforeBodyEnd = match[4];\n\n const headContent = (afterHeadBegin + beforeHeadEnd)\n .replace(/<[^>]+>/g, (openingTag: string) => {\n return (\n openingTag\n // boolean attributes to empty string\n .replace(/\\b(crossorigin|defer|async|disabled|checked)\\b(?!\\s*=)/g, (_, $1: string) =>\n $1 === 'crossorigin' ? 'crossorigin=\"anonymous\"' : `${$1}=\"\"`,\n )\n // convert attributes to single quotes safely\n .replace(/(\\w+)=(\".*?\"|'.*?')/g, (_, $1: string, $2: string) => {\n const v = $2\n // remove quotes\n .slice(1, -1)\n // escape special XML chars\n .replace(/&/g, '&')\n .replace(/'/g, ''')\n .replace(/\"/g, '"')\n .replace(/</g, '<')\n .replace(/>/g, '>');\n return `${$1}='${v}'`;\n })\n );\n })\n // self-close void tags\n .replace(/<(link|meta|img|br|hr|input)([^>]*?)>/gi, (_, $1: string, $2: string) => `<${$1}${$2}/>`)\n // remove whitespace between tags\n .replace(/>\\s+</g, '><')\n // trim overall\n .trim();\n\n const originalTemplateXmlContent = fs.readFileSync(ctx.template, 'utf8');\n const modifiedTemplateXmlContent = replaceBloggerPluginHeadComment(originalTemplateXmlContent, headContent, true);\n\n const templateTagsXmlContent = `<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<!DOCTYPE html>\n<html>\n<head>\n <!--head:afterbegin:begin-->\n\n <!--head:afterbegin:end-->\n\n <!--head:beforeend:begin-->\n ${headContent}\n <!--head:beforeend:end-->\n</head>\n<body>\n <!--body:afterbegin:begin-->\n ${afterBodyBegin.trim()}\n <!--body:afterbegin:end-->\n\n <!--body:beforeend:begin-->\n ${beforeBodyEnd.trim()}\n <!--body:beforeend:end-->\n</body>\n</html>`;\n\n fs.writeFileSync(path.resolve(ctx.viteConfig.build.outDir, 'template.xml'), modifiedTemplateXmlContent);\n fs.writeFileSync(path.resolve(ctx.viteConfig.build.outDir, 'template-tags.xml'), templateTagsXmlContent);\n },\n closeBundle() {\n const htmlDir = path.resolve(ctx.viteConfig.build.outDir, 'virtual:blogger-plugin');\n if (fs.existsSync(htmlDir)) {\n fs.rmSync(htmlDir, { recursive: true });\n }\n },\n configureServer(server) {\n return useServerMiddleware(server, ctx, this);\n },\n configurePreviewServer(server) {\n return useServerMiddleware(server, ctx, this);\n },\n };\n}\n\nclass BloggerPluginContext {\n options: BloggerPluginOptions;\n root: string;\n modules: string[];\n styles: string[];\n template: string;\n name: string;\n proxyBlog: URL;\n viteConfig: ResolvedConfig;\n tailwind: boolean;\n input: string;\n html: string;\n headTags: string[];\n\n constructor(options: BloggerPluginOptions) {\n if (typeof options.template !== 'undefined' && typeof options.template !== 'string') {\n throw new Error(\"Option 'template' must be a string\");\n }\n if (typeof options.modules !== 'undefined' && !Array.isArray(options.modules)) {\n throw new Error(\"Option 'modules' must be an array\");\n }\n if (typeof options.styles !== 'undefined' && !Array.isArray(options.styles)) {\n throw new Error(\"Option 'styles' must be an array\");\n }\n if (typeof options.proxyBlog !== 'string') {\n throw new Error(\"Option 'proxyBlog' must be a string\");\n }\n let proxyBlog: URL;\n try {\n proxyBlog = new URL(options.proxyBlog);\n } catch {\n throw new Error(\"Option 'proxyBlog' must be a valid url\");\n }\n\n this.options = options;\n this.root = process.cwd();\n this.modules = [];\n this.styles = [];\n this.template = undefined as unknown as string;\n this.name = undefined as unknown as string;\n this.proxyBlog = proxyBlog;\n this.viteConfig = undefined as unknown as ResolvedConfig;\n this.tailwind = false;\n this.input = undefined as unknown as string;\n this.headTags = [];\n this.html = undefined as unknown as string;\n }\n\n resolve(config: UserConfig) {\n this.root = config.root ? path.resolve(config.root) : this.root;\n\n if (this.options.modules) {\n for (let i = 0; i < this.options.modules.length; i++) {\n const module = this.options.modules[i];\n const modulePath = path.resolve(this.root, module);\n if (this.modules.includes(modulePath)) {\n continue;\n }\n if (fs.existsSync(modulePath)) {\n this.modules.push(modulePath);\n } else {\n throw new Error(`The path provided at modules[${i}] does not exist: ${modulePath}`);\n }\n }\n } else {\n for (const module of DEFAULT_MODULES) {\n const modulePath = path.resolve(this.root, module);\n if (fs.existsSync(modulePath)) {\n this.modules.push(modulePath);\n break;\n }\n }\n }\n\n if (this.options.styles) {\n for (let i = 0; i < this.options.styles.length; i++) {\n const style = this.options.styles[i];\n const stylePath = path.resolve(this.root, style);\n if (this.styles.includes(stylePath)) {\n continue;\n }\n if (fs.existsSync(stylePath)) {\n this.styles.push(stylePath);\n } else {\n throw new Error(`The path provided at styles[${i}] does not exist: ${stylePath}`);\n }\n }\n }\n\n if (this.options.template) {\n const templatePath = path.resolve(this.root, this.options.template);\n if (fs.existsSync(templatePath)) {\n this.template = templatePath;\n } else {\n throw new Error(`Provided template file does not exist: ${templatePath}`);\n }\n } else {\n for (const file of DEFAULT_TEMPLATES) {\n const fullPath = path.resolve(this.root, file);\n if (fs.existsSync(fullPath)) {\n this.template = fullPath;\n break;\n }\n }\n\n if (!this.template) {\n throw new Error(\n 'No template file found.\\n' +\n `Tried: ${DEFAULT_TEMPLATES.join(', ')}\\n` +\n '👉 Tip: You can pass a custom template as shown:\\n' +\n ' blogger({ template: \"src/my-template.xml\" })',\n );\n }\n }\n\n this.name = path.basename(this.template, path.extname(this.template));\n\n for (const modulePath of this.modules) {\n this.headTags.push(`<script type=\"module\" src=\"/${path.relative(this.root, modulePath).replaceAll('\\\\', '/')}\"></script>`);\n }\n for (const stylePath of this.styles) {\n this.headTags.push(`<link rel=\"stylesheet\" href=\"/${path.relative(this.root, stylePath).replaceAll('\\\\', '/')}\">`);\n }\n\n this.input = `virtual:blogger-plugin/${this.name}.html`;\n this.html = `<!DOCTYPE html>\n<html>\n<head>\n <!--head-->${this.headTags.length > 0 ? `\\n ${this.headTags.join('\\n ')}` : ''}\n</head>\n<body>\n <!--body-->\n</body>\n</html>`;\n }\n}\n\nfunction useServerMiddleware(server: ViteDevServer | PreviewServer, ctx: BloggerPluginContext, _this: MinimalPluginContextWithoutEnvironment) {\n const input = ctx.viteConfig.build[VITE_BUNDLER_KEY].input;\n const htmlPathnames: string[] = [];\n for (const entry of Array.isArray(input) ? input : typeof input === 'object' ? Object.values(input) : typeof input === 'string' ? [input] : []) {\n if (entry === ctx.input) {\n continue;\n }\n const entryPath = path.resolve(ctx.root, entry);\n if (!entryPath.endsWith('.html')) {\n continue;\n }\n const relativePath = path.relative(ctx.root, entry).replaceAll('\\\\', '/');\n htmlPathnames.push(`/${relativePath}`);\n if (relativePath.endsWith('index.html')) {\n htmlPathnames.push(`/${relativePath.replace(/index\\.html$/, '')}`);\n }\n }\n\n return () => {\n server.httpServer?.once('listening', () => {\n setTimeout(() => {\n _this.info(`Unhandled requests will be proxied to ${ctx.proxyBlog.origin}`);\n }, 0);\n });\n\n server.middlewares.use(async (req, res, next) => {\n const url = getRequestUrl(req);\n\n if (\n !req.url ||\n !req.originalUrl ||\n !url ||\n !req.method ||\n !['GET', 'HEAD'].includes(req.method.toUpperCase()) ||\n htmlPathnames.includes(url.pathname.replace(/\\/+/g, '/'))\n ) {\n next();\n return;\n }\n\n const start = Date.now();\n\n const proxyUrl = new URL(`${ctx.proxyBlog.origin}${req.originalUrl}`);\n\n const viewParam = proxyUrl.searchParams.get('view');\n proxyUrl.searchParams.set('view', `${isViteDevServer(server) ? '-DevServer' : '-PreviewServer'}${viewParam?.startsWith('-') ? viewParam : ''}`);\n\n const proxyRequest = new Request(proxyUrl, {\n method: req.method,\n headers: toWebHeaders(req.headers),\n redirect: 'manual',\n });\n\n const proxyResponse = await fetch(proxyRequest).catch((error) => {\n if (error instanceof Error) {\n _this.warn({\n message: `${error.name}: ${error.message}`,\n cause: error.cause,\n stack: error.stack,\n });\n } else {\n _this.warn('Fetch failed');\n }\n return null;\n });\n\n if (proxyResponse) {\n res.statusCode = proxyResponse.status;\n res.statusMessage = proxyResponse.statusText;\n\n proxyResponse.headers.forEach((value, key) => {\n if (key === 'location') {\n const redirectUrl = new URL(value, proxyUrl);\n if (redirectUrl.host === url.host || redirectUrl.host === proxyUrl.host) {\n redirectUrl.host = url.host;\n redirectUrl.protocol = url.protocol;\n const viewParam = redirectUrl.searchParams.get('view')?.replaceAll('-DevServer', '').replaceAll('-PreviewServer', '');\n if (viewParam) {\n redirectUrl.searchParams.set('view', viewParam);\n } else {\n redirectUrl.searchParams.delete('view');\n }\n res.setHeader('location', redirectUrl.pathname + redirectUrl.search + redirectUrl.hash);\n } else {\n res.setHeader('location', redirectUrl.href);\n }\n } else if (['content-type', 'x-robots-tag', 'date', 'location'].includes(key)) {\n res.setHeader(key, value);\n }\n });\n\n const contentType = proxyResponse.headers.get('content-type');\n\n if (contentType?.startsWith('text/html')) {\n let htmlTemplateContent = await proxyResponse.text();\n\n const secFetchDestHeader = req.headers['sec-fetch-dest'];\n const secFetchModeHeader = req.headers['sec-fetch-mode'];\n if (ctx.tailwind && isViteDevServer(server) && secFetchDestHeader === 'document' && secFetchModeHeader === 'navigate') {\n await updateTailwindCache(ctx.root, htmlTemplateContent);\n }\n\n htmlTemplateContent = replaceHost(htmlTemplateContent, proxyUrl.host, url.host, url.protocol);\n\n if (isViteDevServer(server)) {\n const template = await server.transformIndexHtml(\n req.url,\n replaceBloggerPluginHeadComment(htmlTemplateContent, ctx.headTags.join('')),\n req.originalUrl,\n );\n\n res.end(template);\n } else {\n const xmlTemplateContent = fs.readFileSync(path.resolve(ctx.viteConfig.build.outDir, 'template.xml'), 'utf8');\n\n const htmlTagsStr = getBloggerPluginHeadComment(xmlTemplateContent, true);\n\n const template = replaceBloggerPluginHeadComment(htmlTemplateContent, htmlTagsStr ?? '');\n\n res.end(template);\n }\n } else if (contentType && /^(text\\/)|(application\\/(.*\\+)?(xml|json))/.test(contentType)) {\n const content = await proxyResponse.text();\n\n res.end(replaceHost(content, proxyUrl.host, url.host, url.protocol));\n } else {\n res.end(new Uint8Array(await proxyResponse.arrayBuffer()));\n }\n } else {\n res.statusCode = 500;\n res.statusMessage = 'Internal Server Error';\n\n res.setHeader('Content-Type', 'text/html');\n\n res.end(errorHtml(proxyUrl.href));\n }\n\n const duration = Date.now() - start;\n\n _this.info(`${req.method} ${req.originalUrl} -> ${res.statusCode} ${res.statusMessage} (${duration}ms)`);\n });\n };\n}\n\nfunction isViteDevServer(server: ViteDevServer | PreviewServer): server is ViteDevServer {\n return 'hot' in server && 'transformRequest' in server && 'transformIndexHtml' in server;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"vite.mjs","names":[],"sources":["../src/vite.ts"],"sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport { type MinifyOptions, minify } from 'minify-xml';\nimport type { MinimalPluginContextWithoutEnvironment, Plugin, PreviewServer, ResolvedConfig, UserConfig, ViteDevServer } from 'vite';\nimport { DEFAULT_MODULES, DEFAULT_TEMPLATES, VITE_BUNDLER_KEY } from './constants';\nimport { clearTailwindCache, removeTailwindCache, updateTailwindCache } from './tailwind';\nimport {\n errorHtml,\n getBloggerPluginHeadComment,\n getRequestUrl,\n isTailwindPlugin,\n replaceBloggerPluginHeadComment,\n replaceHost,\n toWebHeaders,\n unescapeHTML,\n} from './utils';\n\nexport interface XMLOptions {\n tags?: boolean;\n minify?: boolean;\n}\n\nexport interface BloggerPluginOptions {\n modules?: string[];\n styles?: string[];\n template?: string;\n proxyBlog: string;\n xml?: XMLOptions;\n}\n\nexport default function blogger(userOptions: BloggerPluginOptions): Plugin {\n const ctx = new BloggerPluginContext(userOptions);\n\n return {\n name: '@blogger-plugin/vite',\n config(config) {\n // resolve plugin context\n ctx.resolve(config);\n\n // modify vite config\n config.build ||= {};\n config.build[VITE_BUNDLER_KEY] ||= {};\n const bundlerOptions = config.build[VITE_BUNDLER_KEY];\n if (Array.isArray(bundlerOptions.input)) {\n bundlerOptions.input = [...bundlerOptions.input, ctx.input];\n } else if (typeof bundlerOptions.input === 'object' && bundlerOptions.input !== null) {\n bundlerOptions.input[ctx.input] = ctx.input;\n } else {\n bundlerOptions.input = ctx.input;\n }\n\n const originalTemplateXmlContent = fs.readFileSync(ctx.template, 'utf8');\n // remove contents between comments from template\n const modifiedTemplateXmlContent = replaceBloggerPluginHeadComment(replaceBloggerPluginHeadComment(originalTemplateXmlContent, ''), '', true);\n\n fs.writeFileSync(ctx.template, modifiedTemplateXmlContent, 'utf-8');\n },\n configResolved(config) {\n ctx.viteConfig = config;\n ctx.tailwind = config.plugins.flat(Number.POSITIVE_INFINITY).some((plugin) => isTailwindPlugin(plugin));\n\n if (ctx.tailwind) {\n clearTailwindCache(ctx.root);\n\n if (config.command === 'build') {\n updateTailwindCache(ctx.root, unescapeHTML(fs.readFileSync(ctx.template, 'utf-8'), true), 'xml');\n }\n } else {\n removeTailwindCache(ctx.root);\n }\n },\n resolveId(source) {\n if (source === ctx.input) {\n return ctx.input;\n }\n },\n load(id) {\n if (id === ctx.input) {\n return ctx.html;\n }\n },\n buildStart() {\n if (ctx.viteConfig.command === 'build' && !/^https?:\\/\\//.test(ctx.viteConfig.base)) {\n this.warn(`\"base\" should be a CDN URL in production\n----------------------\nBlogger cannot serve static assets (JS, CSS, etc.), so you must use\nan absolute URL (http:// or https://).\n\nCurrent value:\n base: \"${ctx.viteConfig.base}\"\n\nQuick fix:\n VITE_BASE=https://cdn.jsdelivr.net/gh/<username>/<repository>@latest/dist/ npm run build\n\nVite config (recommended):\n export default defineConfig({\n base: process.env.VITE_BASE ?? \"/\"\n });\n\nWithout this, your assets may fail to load in Blogger.\n----------------------`);\n }\n },\n writeBundle(_, bundle) {\n if (!(ctx.input in bundle)) {\n return;\n }\n const asset = bundle[ctx.input];\n delete bundle[ctx.input];\n\n if (asset.type !== 'asset' || typeof asset.source !== 'string') {\n return;\n }\n const regex =\n /<!DOCTYPE html>\\s*<html[^>]*>\\s*<head>([\\s\\S]*?)<!--head-->([\\s\\S]*?)<\\/head>\\s*<body>([\\s\\S]*?)<!--body-->([\\s\\S]*?)<\\/body>\\s*<\\/html>/i;\n const match = asset.source.match(regex);\n if (!match) {\n return;\n }\n\n const afterHeadBegin = match[1];\n const beforeHeadEnd = match[2];\n const afterBodyBegin = match[3];\n const beforeBodyEnd = match[4];\n\n const headContent = (afterHeadBegin + beforeHeadEnd)\n .replace(/<[^>]+>/g, (openingTag: string) => {\n return (\n openingTag\n // boolean attributes to empty string\n .replace(/\\b(crossorigin|defer|async|disabled|checked)\\b(?!\\s*=)/g, (_, $1: string) =>\n $1 === 'crossorigin' ? 'crossorigin=\"anonymous\"' : `${$1}=\"\"`,\n )\n // convert attributes to single quotes safely\n .replace(/(\\w+)=(\".*?\"|'.*?')/g, (_, $1: string, $2: string) => {\n const v = $2\n // remove quotes\n .slice(1, -1)\n // escape special XML chars\n .replace(/&/g, '&')\n .replace(/'/g, ''')\n .replace(/\"/g, '"')\n .replace(/</g, '<')\n .replace(/>/g, '>');\n return `${$1}='${v}'`;\n })\n );\n })\n // self-close void tags\n .replace(/<(link|meta|img|br|hr|input)([^>]*?)>/gi, (_, $1: string, $2: string) => `<${$1}${$2}/>`)\n // remove whitespace between tags\n .replace(/>\\s+</g, '><')\n // trim overall\n .trim();\n\n const originalTemplateXmlContent = fs.readFileSync(ctx.template, 'utf8');\n const modifiedTemplateXmlContent = replaceBloggerPluginHeadComment(originalTemplateXmlContent, headContent, true);\n\n fs.writeFileSync(path.resolve(ctx.viteConfig.build.outDir, 'template.xml'), modifiedTemplateXmlContent);\n\n if (ctx.xml.tags) {\n const templateTagsXmlContent = `<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n<!DOCTYPE html>\n<html>\n<head>\n <!--head:afterbegin:begin-->\n\n <!--head:afterbegin:end-->\n\n <!--head:beforeend:begin-->\n ${headContent}\n <!--head:beforeend:end-->\n</head>\n<body>\n <!--body:afterbegin:begin-->\n ${afterBodyBegin.trim()}\n <!--body:afterbegin:end-->\n\n <!--body:beforeend:begin-->\n ${beforeBodyEnd.trim()}\n <!--body:beforeend:end-->\n</body>\n</html>`;\n fs.writeFileSync(path.resolve(ctx.viteConfig.build.outDir, 'template.tags.xml'), templateTagsXmlContent);\n }\n\n if (ctx.xml.minify) {\n const minifiedTemplateXmlContent = minify(modifiedTemplateXmlContent, {\n removeComments: false,\n shortenNamespaces: false,\n removeUnusedNamespaces: false,\n removeUnusedDefaultNamespace: false,\n ignoreCData: true,\n } as MinifyOptions);\n fs.writeFileSync(path.resolve(ctx.viteConfig.build.outDir, 'template.min.xml'), minifiedTemplateXmlContent);\n }\n },\n closeBundle() {\n const htmlDir = path.resolve(ctx.viteConfig.build.outDir, 'virtual:blogger-plugin');\n if (fs.existsSync(htmlDir)) {\n fs.rmSync(htmlDir, { recursive: true });\n }\n },\n configureServer(server) {\n return useServerMiddleware(server, ctx, this);\n },\n configurePreviewServer(server) {\n return useServerMiddleware(server, ctx, this);\n },\n };\n}\n\nclass BloggerPluginContext {\n private options: BloggerPluginOptions;\n root: string;\n modules: string[];\n styles: string[];\n template: string;\n name: string;\n proxyBlog: URL;\n xml: Required<XMLOptions>;\n viteConfig: ResolvedConfig;\n tailwind: boolean;\n input: string;\n html: string;\n headTags: string[];\n\n constructor(options: BloggerPluginOptions) {\n if (typeof options.template !== 'undefined' && typeof options.template !== 'string') {\n throw new Error(\"Option 'template' must be a string\");\n }\n if (typeof options.modules !== 'undefined' && !Array.isArray(options.modules)) {\n throw new Error(\"Option 'modules' must be an array\");\n }\n if (typeof options.styles !== 'undefined' && !Array.isArray(options.styles)) {\n throw new Error(\"Option 'styles' must be an array\");\n }\n if (typeof options.proxyBlog !== 'string') {\n throw new Error(\"Option 'proxyBlog' must be a string\");\n }\n let proxyBlog: URL;\n try {\n proxyBlog = new URL(options.proxyBlog);\n } catch {\n throw new Error(\"Option 'proxyBlog' must be a valid url\");\n }\n\n this.options = options;\n this.root = process.cwd();\n this.modules = [];\n this.styles = [];\n this.template = undefined as unknown as string;\n this.name = undefined as unknown as string;\n this.proxyBlog = proxyBlog;\n this.xml = {\n tags: options.xml?.tags ?? false,\n minify: options.xml?.minify ?? false,\n };\n this.viteConfig = undefined as unknown as ResolvedConfig;\n this.tailwind = false;\n this.input = undefined as unknown as string;\n this.headTags = [];\n this.html = undefined as unknown as string;\n }\n\n resolve(config: UserConfig) {\n this.root = config.root ? path.resolve(config.root) : this.root;\n\n if (this.options.modules) {\n for (let i = 0; i < this.options.modules.length; i++) {\n const module = this.options.modules[i];\n const modulePath = path.resolve(this.root, module);\n if (this.modules.includes(modulePath)) {\n continue;\n }\n if (fs.existsSync(modulePath)) {\n this.modules.push(modulePath);\n } else {\n throw new Error(`The path provided at modules[${i}] does not exist: ${modulePath}`);\n }\n }\n } else {\n for (const module of DEFAULT_MODULES) {\n const modulePath = path.resolve(this.root, module);\n if (fs.existsSync(modulePath)) {\n this.modules.push(modulePath);\n break;\n }\n }\n }\n\n if (this.options.styles) {\n for (let i = 0; i < this.options.styles.length; i++) {\n const style = this.options.styles[i];\n const stylePath = path.resolve(this.root, style);\n if (this.styles.includes(stylePath)) {\n continue;\n }\n if (fs.existsSync(stylePath)) {\n this.styles.push(stylePath);\n } else {\n throw new Error(`The path provided at styles[${i}] does not exist: ${stylePath}`);\n }\n }\n }\n\n if (this.options.template) {\n const templatePath = path.resolve(this.root, this.options.template);\n if (fs.existsSync(templatePath)) {\n this.template = templatePath;\n } else {\n throw new Error(`Provided template file does not exist: ${templatePath}`);\n }\n } else {\n for (const file of DEFAULT_TEMPLATES) {\n const fullPath = path.resolve(this.root, file);\n if (fs.existsSync(fullPath)) {\n this.template = fullPath;\n break;\n }\n }\n\n if (!this.template) {\n throw new Error(\n 'No template file found.\\n' +\n `Tried: ${DEFAULT_TEMPLATES.join(', ')}\\n` +\n '👉 Tip: You can pass a custom template as shown:\\n' +\n ' blogger({ template: \"src/my-template.xml\" })',\n );\n }\n }\n\n this.name = path.basename(this.template, path.extname(this.template));\n\n for (const modulePath of this.modules) {\n this.headTags.push(`<script type=\"module\" src=\"/${path.relative(this.root, modulePath).replaceAll('\\\\', '/')}\"></script>`);\n }\n for (const stylePath of this.styles) {\n this.headTags.push(`<link rel=\"stylesheet\" href=\"/${path.relative(this.root, stylePath).replaceAll('\\\\', '/')}\">`);\n }\n\n this.input = `virtual:blogger-plugin/${this.name}.html`;\n this.html = `<!DOCTYPE html>\n<html>\n<head>\n <!--head-->${this.headTags.length > 0 ? `\\n ${this.headTags.join('\\n ')}` : ''}\n</head>\n<body>\n <!--body-->\n</body>\n</html>`;\n }\n}\n\nfunction useServerMiddleware(server: ViteDevServer | PreviewServer, ctx: BloggerPluginContext, _this: MinimalPluginContextWithoutEnvironment) {\n const input = ctx.viteConfig.build[VITE_BUNDLER_KEY].input;\n const htmlPathnames: string[] = [];\n for (const entry of Array.isArray(input) ? input : typeof input === 'object' ? Object.values(input) : typeof input === 'string' ? [input] : []) {\n if (entry === ctx.input) {\n continue;\n }\n const entryPath = path.resolve(ctx.root, entry);\n if (!entryPath.endsWith('.html')) {\n continue;\n }\n const relativePath = path.relative(ctx.root, entry).replaceAll('\\\\', '/');\n htmlPathnames.push(`/${relativePath}`);\n if (relativePath.endsWith('index.html')) {\n htmlPathnames.push(`/${relativePath.replace(/index\\.html$/, '')}`);\n }\n }\n\n return () => {\n server.httpServer?.once('listening', () => {\n setTimeout(() => {\n _this.info(`Unhandled requests will be proxied to ${ctx.proxyBlog.origin}`);\n }, 0);\n });\n\n server.middlewares.use(async (req, res, next) => {\n const url = getRequestUrl(req);\n\n if (\n !req.url ||\n !req.originalUrl ||\n !url ||\n !req.method ||\n !['GET', 'HEAD'].includes(req.method.toUpperCase()) ||\n htmlPathnames.includes(url.pathname.replace(/\\/+/g, '/'))\n ) {\n next();\n return;\n }\n\n const start = Date.now();\n\n const proxyUrl = new URL(`${ctx.proxyBlog.origin}${req.originalUrl}`);\n\n const viewParam = proxyUrl.searchParams.get('view');\n proxyUrl.searchParams.set('view', `${isViteDevServer(server) ? '-DevServer' : '-PreviewServer'}${viewParam?.startsWith('-') ? viewParam : ''}`);\n\n const proxyRequest = new Request(proxyUrl, {\n method: req.method,\n headers: toWebHeaders(req.headers),\n redirect: 'manual',\n });\n\n const proxyResponse = await fetch(proxyRequest).catch((error) => {\n if (error instanceof Error) {\n _this.warn({\n message: `${error.name}: ${error.message}`,\n cause: error.cause,\n stack: error.stack,\n });\n } else {\n _this.warn('Fetch failed');\n }\n return null;\n });\n\n if (proxyResponse) {\n res.statusCode = proxyResponse.status;\n res.statusMessage = proxyResponse.statusText;\n\n proxyResponse.headers.forEach((value, key) => {\n if (key === 'location') {\n const redirectUrl = new URL(value, proxyUrl);\n if (redirectUrl.host === url.host || redirectUrl.host === proxyUrl.host) {\n redirectUrl.host = url.host;\n redirectUrl.protocol = url.protocol;\n const viewParam = redirectUrl.searchParams.get('view')?.replaceAll('-DevServer', '').replaceAll('-PreviewServer', '');\n if (viewParam) {\n redirectUrl.searchParams.set('view', viewParam);\n } else {\n redirectUrl.searchParams.delete('view');\n }\n res.setHeader('location', redirectUrl.pathname + redirectUrl.search + redirectUrl.hash);\n } else {\n res.setHeader('location', redirectUrl.href);\n }\n } else if (['content-type', 'x-robots-tag', 'date', 'location'].includes(key)) {\n res.setHeader(key, value);\n }\n });\n\n const contentType = proxyResponse.headers.get('content-type');\n\n if (contentType?.startsWith('text/html')) {\n let htmlTemplateContent = await proxyResponse.text();\n\n const secFetchDestHeader = req.headers['sec-fetch-dest'];\n const secFetchModeHeader = req.headers['sec-fetch-mode'];\n if (ctx.tailwind && isViteDevServer(server) && secFetchDestHeader === 'document' && secFetchModeHeader === 'navigate') {\n await updateTailwindCache(ctx.root, htmlTemplateContent, 'html');\n }\n\n htmlTemplateContent = replaceHost(htmlTemplateContent, proxyUrl.host, url.host, url.protocol);\n\n if (isViteDevServer(server)) {\n const template = await server.transformIndexHtml(\n req.url,\n replaceBloggerPluginHeadComment(htmlTemplateContent, ctx.headTags.join('')),\n req.originalUrl,\n );\n\n res.end(template);\n } else {\n const xmlTemplateContent = fs.readFileSync(path.resolve(ctx.viteConfig.build.outDir, 'template.xml'), 'utf8');\n\n const htmlTagsStr = getBloggerPluginHeadComment(xmlTemplateContent, true);\n\n const template = replaceBloggerPluginHeadComment(htmlTemplateContent, htmlTagsStr ?? '');\n\n res.end(template);\n }\n } else if (contentType && /^(text\\/)|(application\\/(.*\\+)?(xml|json))/.test(contentType)) {\n const content = await proxyResponse.text();\n\n res.end(replaceHost(content, proxyUrl.host, url.host, url.protocol));\n } else {\n res.end(new Uint8Array(await proxyResponse.arrayBuffer()));\n }\n } else {\n res.statusCode = 500;\n res.statusMessage = 'Internal Server Error';\n\n res.setHeader('Content-Type', 'text/html');\n\n res.end(errorHtml(proxyUrl.href));\n }\n\n const duration = Date.now() - start;\n\n _this.info(`${req.method} ${req.originalUrl} -> ${res.statusCode} ${res.statusMessage} (${duration}ms)`);\n });\n };\n}\n\nfunction isViteDevServer(server: ViteDevServer | PreviewServer): server is ViteDevServer {\n return 'hot' in server && 'transformRequest' in server && 'transformIndexHtml' in server;\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "blogger-plugin",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.11",
|
|
4
4
|
"description": "A plugin which allows you to use frontend frameworks in a blogger template.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"blogger"
|
|
@@ -58,11 +58,12 @@
|
|
|
58
58
|
"vite": "^7.0.0 || ^8.0.0"
|
|
59
59
|
},
|
|
60
60
|
"dependencies": {
|
|
61
|
+
"minify-xml": "^4.5.2",
|
|
61
62
|
"tailwindcss-iso": "^1.0.6"
|
|
62
63
|
},
|
|
63
64
|
"devDependencies": {
|
|
64
|
-
"@types/node": "^25.
|
|
65
|
-
"tsdown": "^0.
|
|
65
|
+
"@types/node": "^25.7.0",
|
|
66
|
+
"tsdown": "^0.22.0",
|
|
66
67
|
"vite": "^7.0.0"
|
|
67
68
|
},
|
|
68
69
|
"scripts": {
|