blogger-plugin 0.0.12 → 0.0.13

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.
@@ -1,7 +1,6 @@
1
- require("./_virtual/_rolldown/runtime.cjs");
2
1
  let vite = require("vite");
3
2
  //#region src/constants.ts
4
- const DEFAULT_MODULES = [
3
+ const DEFAULT_MODULE_FILES = new Set([
5
4
  "src/index.tsx",
6
5
  "src/index.ts",
7
6
  "src/index.jsx",
@@ -10,19 +9,27 @@ const DEFAULT_MODULES = [
10
9
  "src/main.ts",
11
10
  "src/main.jsx",
12
11
  "src/main.js"
13
- ];
14
- const DEFAULT_TEMPLATES = [
12
+ ]);
13
+ const DEFAULT_TEMPLATE_FILES = new Set([
15
14
  "index.xml",
16
15
  "template.xml",
17
16
  "theme.xml",
18
17
  "src/index.xml",
19
18
  "src/template.xml",
20
19
  "src/theme.xml"
21
- ];
20
+ ]);
21
+ const TAILWIND_CACHE_FILE = ".tailwind-classes.json";
22
+ const TEMPLATE_OUT_FILE = "template.xml";
23
+ const TEMPLATE_TAGS_OUT_FILE = "template.tags.xml";
24
+ const TEMPLATE_MINIFIED_OUT_FILE = "template.min.xml";
22
25
  const VITE_BUNDLER_KEY = Number(vite.version.split(".")[0]) >= 8 ? "rolldownOptions" : "rollupOptions";
23
26
  //#endregion
24
- exports.DEFAULT_MODULES = DEFAULT_MODULES;
25
- exports.DEFAULT_TEMPLATES = DEFAULT_TEMPLATES;
27
+ exports.DEFAULT_MODULE_FILES = DEFAULT_MODULE_FILES;
28
+ exports.DEFAULT_TEMPLATE_FILES = DEFAULT_TEMPLATE_FILES;
29
+ exports.TAILWIND_CACHE_FILE = TAILWIND_CACHE_FILE;
30
+ exports.TEMPLATE_MINIFIED_OUT_FILE = TEMPLATE_MINIFIED_OUT_FILE;
31
+ exports.TEMPLATE_OUT_FILE = TEMPLATE_OUT_FILE;
32
+ exports.TEMPLATE_TAGS_OUT_FILE = TEMPLATE_TAGS_OUT_FILE;
26
33
  exports.VITE_BUNDLER_KEY = VITE_BUNDLER_KEY;
27
34
 
28
35
  //# sourceMappingURL=constants.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.cjs","names":["viteVersion"],"sources":["../src/constants.ts"],"sourcesContent":["import { version as viteVersion } from 'vite';\n\nexport const DEFAULT_MODULES = [\n 'src/index.tsx',\n 'src/index.ts',\n 'src/index.jsx',\n 'src/index.js',\n 'src/main.tsx',\n 'src/main.ts',\n 'src/main.jsx',\n 'src/main.js',\n] as const;\n\nexport const DEFAULT_TEMPLATES = ['index.xml', 'template.xml', 'theme.xml', 'src/index.xml', 'src/template.xml', 'src/theme.xml'] as const;\n\nexport const VITE_MAJOR = Number(viteVersion.split('.')[0]);\nexport const VITE_BUNDLER_KEY = (VITE_MAJOR >= 8 ? 'rolldownOptions' : 'rollupOptions') as 'rollupOptions';\n"],"mappings":";;;AAEA,MAAa,kBAAkB;CAC7B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAED,MAAa,oBAAoB;CAAC;CAAa;CAAgB;CAAa;CAAiB;CAAoB;CAAgB;AAGjI,MAAa,mBADa,OAAOA,KAAAA,QAAY,MAAM,IAAI,CAAC,GACvB,IAAc,IAAI,oBAAoB"}
1
+ {"version":3,"file":"constants.cjs","names":["viteVersion"],"sources":["../src/constants.ts"],"sourcesContent":["import { version as viteVersion } from 'vite';\n\nexport const DEFAULT_MODULE_FILES: Set<string> = new Set([\n 'src/index.tsx',\n 'src/index.ts',\n 'src/index.jsx',\n 'src/index.js',\n 'src/main.tsx',\n 'src/main.ts',\n 'src/main.jsx',\n 'src/main.js',\n]);\n\nexport const DEFAULT_TEMPLATE_FILES: Set<string> = new Set([\n 'index.xml',\n 'template.xml',\n 'theme.xml',\n 'src/index.xml',\n 'src/template.xml',\n 'src/theme.xml',\n]);\n\nexport const TAILWIND_CACHE_FILE: string = '.tailwind-classes.json';\n\nexport const TEMPLATE_OUT_FILE: string = 'template.xml';\nexport const TEMPLATE_TAGS_OUT_FILE: string = 'template.tags.xml';\nexport const TEMPLATE_MINIFIED_OUT_FILE: string = 'template.min.xml';\n\nexport const VITE_MAJOR: number = Number(viteVersion.split('.')[0]);\nexport const VITE_BUNDLER_KEY = (VITE_MAJOR >= 8 ? 'rolldownOptions' : 'rollupOptions') as 'rollupOptions';\n"],"mappings":";;AAEA,MAAa,uBAAoC,IAAI,IAAI;CACvD;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,MAAa,yBAAsC,IAAI,IAAI;CACzD;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,MAAa,sBAA8B;AAE3C,MAAa,oBAA4B;AACzC,MAAa,yBAAiC;AAC9C,MAAa,6BAAqC;AAGlD,MAAa,mBADqB,OAAOA,KAAAA,QAAY,MAAM,GAAG,EAAE,EAC/B,KAAc,IAAI,oBAAoB"}
@@ -1,6 +1,6 @@
1
1
  import { version } from "vite";
2
2
  //#region src/constants.ts
3
- const DEFAULT_MODULES = [
3
+ const DEFAULT_MODULE_FILES = new Set([
4
4
  "src/index.tsx",
5
5
  "src/index.ts",
6
6
  "src/index.jsx",
@@ -9,17 +9,21 @@ const DEFAULT_MODULES = [
9
9
  "src/main.ts",
10
10
  "src/main.jsx",
11
11
  "src/main.js"
12
- ];
13
- const DEFAULT_TEMPLATES = [
12
+ ]);
13
+ const DEFAULT_TEMPLATE_FILES = new Set([
14
14
  "index.xml",
15
15
  "template.xml",
16
16
  "theme.xml",
17
17
  "src/index.xml",
18
18
  "src/template.xml",
19
19
  "src/theme.xml"
20
- ];
20
+ ]);
21
+ const TAILWIND_CACHE_FILE = ".tailwind-classes.json";
22
+ const TEMPLATE_OUT_FILE = "template.xml";
23
+ const TEMPLATE_TAGS_OUT_FILE = "template.tags.xml";
24
+ const TEMPLATE_MINIFIED_OUT_FILE = "template.min.xml";
21
25
  const VITE_BUNDLER_KEY = Number(version.split(".")[0]) >= 8 ? "rolldownOptions" : "rollupOptions";
22
26
  //#endregion
23
- export { DEFAULT_MODULES, DEFAULT_TEMPLATES, VITE_BUNDLER_KEY };
27
+ export { DEFAULT_MODULE_FILES, DEFAULT_TEMPLATE_FILES, TAILWIND_CACHE_FILE, TEMPLATE_MINIFIED_OUT_FILE, TEMPLATE_OUT_FILE, TEMPLATE_TAGS_OUT_FILE, VITE_BUNDLER_KEY };
24
28
 
25
29
  //# sourceMappingURL=constants.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.mjs","names":["viteVersion"],"sources":["../src/constants.ts"],"sourcesContent":["import { version as viteVersion } from 'vite';\n\nexport const DEFAULT_MODULES = [\n 'src/index.tsx',\n 'src/index.ts',\n 'src/index.jsx',\n 'src/index.js',\n 'src/main.tsx',\n 'src/main.ts',\n 'src/main.jsx',\n 'src/main.js',\n] as const;\n\nexport const DEFAULT_TEMPLATES = ['index.xml', 'template.xml', 'theme.xml', 'src/index.xml', 'src/template.xml', 'src/theme.xml'] as const;\n\nexport const VITE_MAJOR = Number(viteVersion.split('.')[0]);\nexport const VITE_BUNDLER_KEY = (VITE_MAJOR >= 8 ? 'rolldownOptions' : 'rollupOptions') as 'rollupOptions';\n"],"mappings":";;AAEA,MAAa,kBAAkB;CAC7B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACD;AAED,MAAa,oBAAoB;CAAC;CAAa;CAAgB;CAAa;CAAiB;CAAoB;CAAgB;AAGjI,MAAa,mBADa,OAAOA,QAAY,MAAM,IAAI,CAAC,GACvB,IAAc,IAAI,oBAAoB"}
1
+ {"version":3,"file":"constants.mjs","names":["viteVersion"],"sources":["../src/constants.ts"],"sourcesContent":["import { version as viteVersion } from 'vite';\n\nexport const DEFAULT_MODULE_FILES: Set<string> = new Set([\n 'src/index.tsx',\n 'src/index.ts',\n 'src/index.jsx',\n 'src/index.js',\n 'src/main.tsx',\n 'src/main.ts',\n 'src/main.jsx',\n 'src/main.js',\n]);\n\nexport const DEFAULT_TEMPLATE_FILES: Set<string> = new Set([\n 'index.xml',\n 'template.xml',\n 'theme.xml',\n 'src/index.xml',\n 'src/template.xml',\n 'src/theme.xml',\n]);\n\nexport const TAILWIND_CACHE_FILE: string = '.tailwind-classes.json';\n\nexport const TEMPLATE_OUT_FILE: string = 'template.xml';\nexport const TEMPLATE_TAGS_OUT_FILE: string = 'template.tags.xml';\nexport const TEMPLATE_MINIFIED_OUT_FILE: string = 'template.min.xml';\n\nexport const VITE_MAJOR: number = Number(viteVersion.split('.')[0]);\nexport const VITE_BUNDLER_KEY = (VITE_MAJOR >= 8 ? 'rolldownOptions' : 'rollupOptions') as 'rollupOptions';\n"],"mappings":";;AAEA,MAAa,uBAAoC,IAAI,IAAI;CACvD;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,MAAa,yBAAsC,IAAI,IAAI;CACzD;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,MAAa,sBAA8B;AAE3C,MAAa,oBAA4B;AACzC,MAAa,yBAAiC;AAC9C,MAAa,6BAAqC;AAGlD,MAAa,mBADqB,OAAOA,QAAY,MAAM,GAAG,EAAE,EAC/B,KAAc,IAAI,oBAAoB"}
package/dist/tailwind.cjs CHANGED
@@ -1,67 +1,66 @@
1
1
  const require_runtime = require("./_virtual/_rolldown/runtime.cjs");
2
- let node_fs = require("node:fs");
3
- node_fs = require_runtime.__toESM(node_fs, 1);
2
+ const require_utils = require("./utils.cjs");
3
+ let node_fs_promises = require("node:fs/promises");
4
+ node_fs_promises = require_runtime.__toESM(node_fs_promises, 1);
4
5
  let node_path = require("node:path");
5
6
  node_path = require_runtime.__toESM(node_path, 1);
6
7
  let tailwindcss_iso = require("tailwindcss-iso");
7
8
  //#region src/tailwind.ts
8
- const TAILWIND_CACHE_FILE = ".tailwind-classes.json";
9
- function readFileContent(file) {
10
- if (!node_fs.existsSync(file)) return null;
11
- return node_fs.readFileSync(file, "utf-8");
12
- }
13
- function writeFileContent(file, content) {
14
- const dirname = node_path.dirname(file);
15
- if (!node_fs.existsSync(dirname)) node_fs.mkdirSync(dirname, { recursive: true });
16
- const current = readFileContent(file);
17
- if (current === null || content !== current) {
18
- node_fs.writeFileSync(file, content, "utf8");
9
+ var TailwindCache = class {
10
+ constructor(file) {
11
+ this._file = node_path.resolve(file);
12
+ }
13
+ async _readContent() {
14
+ if (!await require_utils.fsExists(this._file)) return null;
15
+ return node_fs_promises.readFile(this._file, "utf-8");
16
+ }
17
+ async _writeContent(content) {
18
+ const dirname = node_path.dirname(this._file);
19
+ if (!await require_utils.fsExists(dirname)) await node_fs_promises.mkdir(dirname, { recursive: true });
20
+ const current = await this._readContent();
21
+ if (current === null || content !== current) {
22
+ await node_fs_promises.writeFile(this._file, content, "utf8");
23
+ return true;
24
+ }
25
+ return false;
26
+ }
27
+ async remove() {
28
+ if (!await require_utils.fsExists(this._file)) return false;
29
+ await node_fs_promises.rm(this._file);
19
30
  return true;
20
31
  }
21
- return false;
22
- }
23
- function removeFile(file) {
24
- if (!node_fs.existsSync(file)) return false;
25
- node_fs.rmSync(file);
26
- return true;
27
- }
28
- function getTailwindCacheFile(root) {
29
- return node_path.resolve(root, TAILWIND_CACHE_FILE);
30
- }
31
- function readTailwindCache(root) {
32
- const content = readFileContent(getTailwindCacheFile(root));
33
- if (!content) return null;
34
- try {
35
- return JSON.parse(content);
36
- } catch (_unused) {
37
- return null;
32
+ async read() {
33
+ const content = await this._readContent();
34
+ if (!content) return null;
35
+ try {
36
+ return JSON.parse(content);
37
+ } catch (_unused) {
38
+ return null;
39
+ }
40
+ }
41
+ async write(classes) {
42
+ const content = JSON.stringify(classes, null, 2);
43
+ return this._writeContent(content);
44
+ }
45
+ async clear() {
46
+ await this.write([]);
47
+ }
48
+ async add(classes) {
49
+ var _await$this$read;
50
+ const existing = (_await$this$read = await this.read()) !== null && _await$this$read !== void 0 ? _await$this$read : [];
51
+ const merged = [...new Set([...existing, ...classes])];
52
+ await this.write(merged);
53
+ return merged;
54
+ }
55
+ async update(content, extension) {
56
+ const classes = await (0, tailwindcss_iso.getTailwindClasses)({
57
+ content,
58
+ extension
59
+ });
60
+ return this.add(classes);
38
61
  }
39
- }
40
- function writeTailwindCache(root, classes) {
41
- const file = getTailwindCacheFile(root);
42
- const content = JSON.stringify(classes, null, 2);
43
- return {
44
- updated: writeFileContent(file, content),
45
- content
46
- };
47
- }
48
- function clearTailwindCache(root) {
49
- writeTailwindCache(root, []);
50
- }
51
- function removeTailwindCache(root) {
52
- removeFile(getTailwindCacheFile(root));
53
- }
54
- async function updateTailwindCache(root, content, extension) {
55
- var _readTailwindCache;
56
- const classes = await (0, tailwindcss_iso.getTailwindClasses)({
57
- content,
58
- extension
59
- });
60
- writeTailwindCache(root, [...new Set([...(_readTailwindCache = readTailwindCache(root)) !== null && _readTailwindCache !== void 0 ? _readTailwindCache : [], ...classes])]);
61
- }
62
+ };
62
63
  //#endregion
63
- exports.clearTailwindCache = clearTailwindCache;
64
- exports.removeTailwindCache = removeTailwindCache;
65
- exports.updateTailwindCache = updateTailwindCache;
64
+ exports.TailwindCache = TailwindCache;
66
65
 
67
66
  //# sourceMappingURL=tailwind.cjs.map
@@ -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, 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"}
1
+ {"version":3,"file":"tailwind.cjs","names":["path","fsExists","fs"],"sources":["../src/tailwind.ts"],"sourcesContent":["import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { getTailwindClasses } from 'tailwindcss-iso';\nimport { fsExists } from './utils';\n\nexport class TailwindCache {\n private readonly _file: string;\n\n constructor(file: string) {\n this._file = path.resolve(file);\n }\n\n private async _readContent(): Promise<string | null> {\n const exists = await fsExists(this._file);\n\n if (!exists) {\n return null;\n }\n\n return fs.readFile(this._file, 'utf-8');\n }\n\n private async _writeContent(content: string): Promise<boolean> {\n const dirname = path.dirname(this._file);\n\n const exists = await fsExists(dirname);\n\n if (!exists) {\n await fs.mkdir(dirname, { recursive: true });\n }\n\n const current = await this._readContent();\n if (current === null || content !== current) {\n await fs.writeFile(this._file, content, 'utf8');\n return true;\n }\n\n return false;\n }\n\n async remove(): Promise<boolean> {\n const exists = await fsExists(this._file);\n\n if (!exists) {\n return false;\n }\n\n await fs.rm(this._file);\n return true;\n }\n\n async read(): Promise<string[] | null> {\n const content = await this._readContent();\n\n if (!content) {\n return null;\n }\n\n try {\n return JSON.parse(content);\n } catch {\n return null;\n }\n }\n\n async write(classes: string[]): Promise<boolean> {\n const content = JSON.stringify(classes, null, 2);\n return this._writeContent(content);\n }\n\n async clear(): Promise<void> {\n await this.write([]);\n }\n\n async add(classes: string[]): Promise<string[]> {\n const existing = (await this.read()) ?? [];\n const merged = [...new Set([...existing, ...classes])];\n\n await this.write(merged);\n\n return merged;\n }\n\n async update(content: string, extension?: string): Promise<string[]> {\n const classes = (await getTailwindClasses({\n content,\n extension,\n })) as string[];\n\n return this.add(classes);\n }\n}\n"],"mappings":";;;;;;;;AAKA,IAAa,gBAAb,MAA2B;CAGzB,YAAY,MAAc;EACxB,KAAK,QAAQA,UAAK,QAAQ,IAAI;CAChC;CAEA,MAAc,eAAuC;EAGnD,IAAI,CAAC,MAFgBC,cAAAA,SAAS,KAAK,KAAK,GAGtC,OAAO;EAGT,OAAOC,iBAAG,SAAS,KAAK,OAAO,OAAO;CACxC;CAEA,MAAc,cAAc,SAAmC;EAC7D,MAAM,UAAUF,UAAK,QAAQ,KAAK,KAAK;EAIvC,IAAI,CAAC,MAFgBC,cAAAA,SAAS,OAAO,GAGnC,MAAMC,iBAAG,MAAM,SAAS,EAAE,WAAW,KAAK,CAAC;EAG7C,MAAM,UAAU,MAAM,KAAK,aAAa;EACxC,IAAI,YAAY,QAAQ,YAAY,SAAS;GAC3C,MAAMA,iBAAG,UAAU,KAAK,OAAO,SAAS,MAAM;GAC9C,OAAO;EACT;EAEA,OAAO;CACT;CAEA,MAAM,SAA2B;EAG/B,IAAI,CAAC,MAFgBD,cAAAA,SAAS,KAAK,KAAK,GAGtC,OAAO;EAGT,MAAMC,iBAAG,GAAG,KAAK,KAAK;EACtB,OAAO;CACT;CAEA,MAAM,OAAiC;EACrC,MAAM,UAAU,MAAM,KAAK,aAAa;EAExC,IAAI,CAAC,SACH,OAAO;EAGT,IAAI;GACF,OAAO,KAAK,MAAM,OAAO;EAC3B,SAAA,SAAQ;GACN,OAAO;EACT;CACF;CAEA,MAAM,MAAM,SAAqC;EAC/C,MAAM,UAAU,KAAK,UAAU,SAAS,MAAM,CAAC;EAC/C,OAAO,KAAK,cAAc,OAAO;CACnC;CAEA,MAAM,QAAuB;EAC3B,MAAM,KAAK,MAAM,CAAC,CAAC;CACrB;CAEA,MAAM,IAAI,SAAsC;;EAC9C,MAAM,YAAA,mBAAY,MAAM,KAAK,KAAK,OAAA,QAAA,qBAAA,KAAA,IAAA,mBAAM,CAAC;EACzC,MAAM,SAAS,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,UAAU,GAAG,OAAO,CAAC,CAAC;EAErD,MAAM,KAAK,MAAM,MAAM;EAEvB,OAAO;CACT;CAEA,MAAM,OAAO,SAAiB,WAAuC;EACnE,MAAM,UAAW,OAAA,GAAA,gBAAA,oBAAyB;GACxC;GACA;EACF,CAAC;EAED,OAAO,KAAK,IAAI,OAAO;CACzB;AACF"}
package/dist/tailwind.mjs CHANGED
@@ -1,62 +1,63 @@
1
- import * as fs from "node:fs";
1
+ import { fsExists } from "./utils.mjs";
2
+ import * as fs from "node:fs/promises";
2
3
  import * as path from "node:path";
3
4
  import { getTailwindClasses } from "tailwindcss-iso";
4
5
  //#region src/tailwind.ts
5
- const TAILWIND_CACHE_FILE = ".tailwind-classes.json";
6
- function readFileContent(file) {
7
- if (!fs.existsSync(file)) return null;
8
- return fs.readFileSync(file, "utf-8");
9
- }
10
- function writeFileContent(file, content) {
11
- const dirname = path.dirname(file);
12
- if (!fs.existsSync(dirname)) fs.mkdirSync(dirname, { recursive: true });
13
- const current = readFileContent(file);
14
- if (current === null || content !== current) {
15
- fs.writeFileSync(file, content, "utf8");
6
+ var TailwindCache = class {
7
+ constructor(file) {
8
+ this._file = path.resolve(file);
9
+ }
10
+ async _readContent() {
11
+ if (!await fsExists(this._file)) return null;
12
+ return fs.readFile(this._file, "utf-8");
13
+ }
14
+ async _writeContent(content) {
15
+ const dirname = path.dirname(this._file);
16
+ if (!await fsExists(dirname)) await fs.mkdir(dirname, { recursive: true });
17
+ const current = await this._readContent();
18
+ if (current === null || content !== current) {
19
+ await fs.writeFile(this._file, content, "utf8");
20
+ return true;
21
+ }
22
+ return false;
23
+ }
24
+ async remove() {
25
+ if (!await fsExists(this._file)) return false;
26
+ await fs.rm(this._file);
16
27
  return true;
17
28
  }
18
- return false;
19
- }
20
- function removeFile(file) {
21
- if (!fs.existsSync(file)) return false;
22
- fs.rmSync(file);
23
- return true;
24
- }
25
- function getTailwindCacheFile(root) {
26
- return path.resolve(root, TAILWIND_CACHE_FILE);
27
- }
28
- function readTailwindCache(root) {
29
- const content = readFileContent(getTailwindCacheFile(root));
30
- if (!content) return null;
31
- try {
32
- return JSON.parse(content);
33
- } catch (_unused) {
34
- return null;
35
- }
36
- }
37
- function writeTailwindCache(root, classes) {
38
- const file = getTailwindCacheFile(root);
39
- const content = JSON.stringify(classes, null, 2);
40
- return {
41
- updated: writeFileContent(file, content),
42
- content
43
- };
44
- }
45
- function clearTailwindCache(root) {
46
- writeTailwindCache(root, []);
47
- }
48
- function removeTailwindCache(root) {
49
- removeFile(getTailwindCacheFile(root));
50
- }
51
- async function updateTailwindCache(root, content, extension) {
52
- var _readTailwindCache;
53
- const classes = await getTailwindClasses({
54
- content,
55
- extension
56
- });
57
- writeTailwindCache(root, [...new Set([...(_readTailwindCache = readTailwindCache(root)) !== null && _readTailwindCache !== void 0 ? _readTailwindCache : [], ...classes])]);
58
- }
29
+ async read() {
30
+ const content = await this._readContent();
31
+ if (!content) return null;
32
+ try {
33
+ return JSON.parse(content);
34
+ } catch (_unused) {
35
+ return null;
36
+ }
37
+ }
38
+ async write(classes) {
39
+ const content = JSON.stringify(classes, null, 2);
40
+ return this._writeContent(content);
41
+ }
42
+ async clear() {
43
+ await this.write([]);
44
+ }
45
+ async add(classes) {
46
+ var _await$this$read;
47
+ const existing = (_await$this$read = await this.read()) !== null && _await$this$read !== void 0 ? _await$this$read : [];
48
+ const merged = [...new Set([...existing, ...classes])];
49
+ await this.write(merged);
50
+ return merged;
51
+ }
52
+ async update(content, extension) {
53
+ const classes = await getTailwindClasses({
54
+ content,
55
+ extension
56
+ });
57
+ return this.add(classes);
58
+ }
59
+ };
59
60
  //#endregion
60
- export { clearTailwindCache, removeTailwindCache, updateTailwindCache };
61
+ export { TailwindCache };
61
62
 
62
63
  //# sourceMappingURL=tailwind.mjs.map
@@ -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, 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"}
1
+ {"version":3,"file":"tailwind.mjs","names":[],"sources":["../src/tailwind.ts"],"sourcesContent":["import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { getTailwindClasses } from 'tailwindcss-iso';\nimport { fsExists } from './utils';\n\nexport class TailwindCache {\n private readonly _file: string;\n\n constructor(file: string) {\n this._file = path.resolve(file);\n }\n\n private async _readContent(): Promise<string | null> {\n const exists = await fsExists(this._file);\n\n if (!exists) {\n return null;\n }\n\n return fs.readFile(this._file, 'utf-8');\n }\n\n private async _writeContent(content: string): Promise<boolean> {\n const dirname = path.dirname(this._file);\n\n const exists = await fsExists(dirname);\n\n if (!exists) {\n await fs.mkdir(dirname, { recursive: true });\n }\n\n const current = await this._readContent();\n if (current === null || content !== current) {\n await fs.writeFile(this._file, content, 'utf8');\n return true;\n }\n\n return false;\n }\n\n async remove(): Promise<boolean> {\n const exists = await fsExists(this._file);\n\n if (!exists) {\n return false;\n }\n\n await fs.rm(this._file);\n return true;\n }\n\n async read(): Promise<string[] | null> {\n const content = await this._readContent();\n\n if (!content) {\n return null;\n }\n\n try {\n return JSON.parse(content);\n } catch {\n return null;\n }\n }\n\n async write(classes: string[]): Promise<boolean> {\n const content = JSON.stringify(classes, null, 2);\n return this._writeContent(content);\n }\n\n async clear(): Promise<void> {\n await this.write([]);\n }\n\n async add(classes: string[]): Promise<string[]> {\n const existing = (await this.read()) ?? [];\n const merged = [...new Set([...existing, ...classes])];\n\n await this.write(merged);\n\n return merged;\n }\n\n async update(content: string, extension?: string): Promise<string[]> {\n const classes = (await getTailwindClasses({\n content,\n extension,\n })) as string[];\n\n return this.add(classes);\n }\n}\n"],"mappings":";;;;;AAKA,IAAa,gBAAb,MAA2B;CAGzB,YAAY,MAAc;EACxB,KAAK,QAAQ,KAAK,QAAQ,IAAI;CAChC;CAEA,MAAc,eAAuC;EAGnD,IAAI,CAAC,MAFgB,SAAS,KAAK,KAAK,GAGtC,OAAO;EAGT,OAAO,GAAG,SAAS,KAAK,OAAO,OAAO;CACxC;CAEA,MAAc,cAAc,SAAmC;EAC7D,MAAM,UAAU,KAAK,QAAQ,KAAK,KAAK;EAIvC,IAAI,CAAC,MAFgB,SAAS,OAAO,GAGnC,MAAM,GAAG,MAAM,SAAS,EAAE,WAAW,KAAK,CAAC;EAG7C,MAAM,UAAU,MAAM,KAAK,aAAa;EACxC,IAAI,YAAY,QAAQ,YAAY,SAAS;GAC3C,MAAM,GAAG,UAAU,KAAK,OAAO,SAAS,MAAM;GAC9C,OAAO;EACT;EAEA,OAAO;CACT;CAEA,MAAM,SAA2B;EAG/B,IAAI,CAAC,MAFgB,SAAS,KAAK,KAAK,GAGtC,OAAO;EAGT,MAAM,GAAG,GAAG,KAAK,KAAK;EACtB,OAAO;CACT;CAEA,MAAM,OAAiC;EACrC,MAAM,UAAU,MAAM,KAAK,aAAa;EAExC,IAAI,CAAC,SACH,OAAO;EAGT,IAAI;GACF,OAAO,KAAK,MAAM,OAAO;EAC3B,SAAA,SAAQ;GACN,OAAO;EACT;CACF;CAEA,MAAM,MAAM,SAAqC;EAC/C,MAAM,UAAU,KAAK,UAAU,SAAS,MAAM,CAAC;EAC/C,OAAO,KAAK,cAAc,OAAO;CACnC;CAEA,MAAM,QAAuB;EAC3B,MAAM,KAAK,MAAM,CAAC,CAAC;CACrB;CAEA,MAAM,IAAI,SAAsC;;EAC9C,MAAM,YAAA,mBAAY,MAAM,KAAK,KAAK,OAAA,QAAA,qBAAA,KAAA,IAAA,mBAAM,CAAC;EACzC,MAAM,SAAS,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,UAAU,GAAG,OAAO,CAAC,CAAC;EAErD,MAAM,KAAK,MAAM,MAAM;EAEvB,OAAO;CACT;CAEA,MAAM,OAAO,SAAiB,WAAuC;EACnE,MAAM,UAAW,MAAM,mBAAmB;GACxC;GACA;EACF,CAAC;EAED,OAAO,KAAK,IAAI,OAAO;CACzB;AACF"}
package/dist/utils.cjs CHANGED
@@ -1,4 +1,10 @@
1
+ const require_runtime = require("./_virtual/_rolldown/runtime.cjs");
2
+ let node_fs_promises = require("node:fs/promises");
3
+ node_fs_promises = require_runtime.__toESM(node_fs_promises, 1);
1
4
  //#region src/utils.ts
5
+ async function fsExists(path) {
6
+ return node_fs_promises.access(path, node_fs_promises.constants.F_OK).then(() => true, () => false);
7
+ }
2
8
  function escapeHtml(str) {
3
9
  if (str === "") return "";
4
10
  return str.replace(/[&<>"'`]/g, (ch) => {
@@ -30,7 +36,7 @@ function unescapeHTML(str, xml = false) {
30
36
  });
31
37
  }
32
38
  function escapeRegex(str) {
33
- return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
39
+ return str.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&").replace(/-/g, "\\x2d");
34
40
  }
35
41
  function toWebHeaders(httpHeaders) {
36
42
  const headers = new Headers();
@@ -173,6 +179,7 @@ function errorHtml(reqUrl) {
173
179
  }
174
180
  //#endregion
175
181
  exports.errorHtml = errorHtml;
182
+ exports.fsExists = fsExists;
176
183
  exports.getBloggerPluginHeadComment = getBloggerPluginHeadComment;
177
184
  exports.getRequestUrl = getRequestUrl;
178
185
  exports.isTailwindPlugin = isTailwindPlugin;
@@ -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): string {\n if (str === '') return '';\n return str.replace(/[&<>\"'`]/g, (ch) => {\n switch (ch) {\n case '&':\n return '&amp;';\n case '<':\n return '&lt;';\n case '>':\n return '&gt;';\n case '\"':\n return '&quot;';\n case \"'\":\n return '&#39;';\n case '`':\n return '&#96;';\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 '&amp;':\n return '&';\n case '&lt;':\n return '<';\n case '&gt;':\n return '>';\n case '&quot;':\n return '\"';\n case '&apos;':\n case '&#39;':\n return \"'\";\n case '&#96;':\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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"}
1
+ {"version":3,"file":"utils.cjs","names":["fs"],"sources":["../src/utils.ts"],"sourcesContent":["import * as fs from 'node:fs/promises';\nimport type { IncomingHttpHeaders, OutgoingHttpHeaders } from 'node:http';\nimport type { Connect } from 'vite';\n\nexport async function fsExists(path: string): Promise<boolean> {\n return fs.access(path, fs.constants.F_OK).then(\n () => true,\n () => false,\n );\n}\n\nexport function escapeHtml(str: string): string {\n if (str === '') return '';\n return str.replace(/[&<>\"'`]/g, (ch) => {\n switch (ch) {\n case '&':\n return '&amp;';\n case '<':\n return '&lt;';\n case '>':\n return '&gt;';\n case '\"':\n return '&quot;';\n case \"'\":\n return '&#39;';\n case '`':\n return '&#96;';\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 '&amp;':\n return '&';\n case '&lt;':\n return '<';\n case '&gt;':\n return '>';\n case '&quot;':\n return '\"';\n case '&apos;':\n case '&#39;':\n return \"'\";\n case '&#96;':\n return '`';\n default:\n return entity;\n }\n });\n}\n\nexport function escapeRegex(str: string): string {\n return str.replace(/[|\\\\{}()[\\]^$+*?.]/g, '\\\\$&').replace(/-/g, '\\\\x2d');\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
@@ -1,4 +1,8 @@
1
+ import * as fs from "node:fs/promises";
1
2
  //#region src/utils.ts
3
+ async function fsExists(path) {
4
+ return fs.access(path, fs.constants.F_OK).then(() => true, () => false);
5
+ }
2
6
  function escapeHtml(str) {
3
7
  if (str === "") return "";
4
8
  return str.replace(/[&<>"'`]/g, (ch) => {
@@ -30,7 +34,7 @@ function unescapeHTML(str, xml = false) {
30
34
  });
31
35
  }
32
36
  function escapeRegex(str) {
33
- return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
37
+ return str.replace(/[|\\{}()[\]^$+*?.]/g, "\\$&").replace(/-/g, "\\x2d");
34
38
  }
35
39
  function toWebHeaders(httpHeaders) {
36
40
  const headers = new Headers();
@@ -172,6 +176,6 @@ function errorHtml(reqUrl) {
172
176
  </html>`;
173
177
  }
174
178
  //#endregion
175
- export { errorHtml, getBloggerPluginHeadComment, getRequestUrl, isTailwindPlugin, replaceBloggerPluginHeadComment, replaceHost, toWebHeaders, unescapeHTML };
179
+ export { errorHtml, fsExists, getBloggerPluginHeadComment, getRequestUrl, isTailwindPlugin, replaceBloggerPluginHeadComment, replaceHost, toWebHeaders, unescapeHTML };
176
180
 
177
181
  //# sourceMappingURL=utils.mjs.map
@@ -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): string {\n if (str === '') return '';\n return str.replace(/[&<>\"'`]/g, (ch) => {\n switch (ch) {\n case '&':\n return '&amp;';\n case '<':\n return '&lt;';\n case '>':\n return '&gt;';\n case '\"':\n return '&quot;';\n case \"'\":\n return '&#39;';\n case '`':\n return '&#96;';\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 '&amp;':\n return '&';\n case '&lt;':\n return '<';\n case '&gt;':\n return '>';\n case '&quot;':\n return '\"';\n case '&apos;':\n case '&#39;':\n return \"'\";\n case '&#96;':\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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"}
1
+ {"version":3,"file":"utils.mjs","names":[],"sources":["../src/utils.ts"],"sourcesContent":["import * as fs from 'node:fs/promises';\nimport type { IncomingHttpHeaders, OutgoingHttpHeaders } from 'node:http';\nimport type { Connect } from 'vite';\n\nexport async function fsExists(path: string): Promise<boolean> {\n return fs.access(path, fs.constants.F_OK).then(\n () => true,\n () => false,\n );\n}\n\nexport function escapeHtml(str: string): string {\n if (str === '') return '';\n return str.replace(/[&<>\"'`]/g, (ch) => {\n switch (ch) {\n case '&':\n return '&amp;';\n case '<':\n return '&lt;';\n case '>':\n return '&gt;';\n case '\"':\n return '&quot;';\n case \"'\":\n return '&#39;';\n case '`':\n return '&#96;';\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 '&amp;':\n return '&';\n case '&lt;':\n return '<';\n case '&gt;':\n return '>';\n case '&quot;':\n return '\"';\n case '&apos;':\n case '&#39;':\n return \"'\";\n case '&#96;':\n return '`';\n default:\n return entity;\n }\n });\n}\n\nexport function escapeRegex(str: string): string {\n return str.replace(/[|\\\\{}()[\\]^$+*?.]/g, '\\\\$&').replace(/-/g, '\\\\x2d');\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":";;AAIA,eAAsB,SAAS,MAAgC;CAC7D,OAAO,GAAG,OAAO,MAAM,GAAG,UAAU,IAAI,EAAE,WAClC,YACA,KACR;AACF;AAEA,SAAgB,WAAW,KAAqB;CAC9C,IAAI,QAAQ,IAAI,OAAO;CACvB,OAAO,IAAI,QAAQ,cAAc,OAAO;EACtC,QAAQ,IAAR;GACE,KAAK,KACH,OAAO;GACT,KAAK,KACH,OAAO;GACT,KAAK,KACH,OAAO;GACT,KAAK,MACH,OAAO;GACT,KAAK,KACH,OAAO;GACT,KAAK,KACH,OAAO;GACT,SACE,OAAO;EACX;CACF,CAAC;AACH;AAEA,SAAgB,aAAa,KAAa,MAAM,OAAe;CAC7D,IAAI,QAAQ,IAAI,OAAO;CACvB,MAAM,QAAQ,IAAI,OAAO,qBAAqB,MAAM,UAAU,GAAG,aAAa,GAAG;CACjF,OAAO,IAAI,QAAQ,QAAQ,WAAW;EACpC,QAAQ,QAAR;GACE,KAAK,SACH,OAAO;GACT,KAAK,QACH,OAAO;GACT,KAAK,QACH,OAAO;GACT,KAAK,UACH,OAAO;GACT,KAAK;GACL,KAAK,SACH,OAAO;GACT,KAAK,SACH,OAAO;GACT,SACE,OAAO;EACX;CACF,CAAC;AACH;AAEA,SAAgB,YAAY,KAAqB;CAC/C,OAAO,IAAI,QAAQ,uBAAuB,MAAM,EAAE,QAAQ,MAAM,OAAO;AACzE;AAEA,SAAgB,aAAa,aAAiE;CAC5F,MAAM,UAAU,IAAI,QAAQ;CAC5B,KAAK,MAAM,CAAC,MAAM,UAAU,OAAO,QAAQ,WAAW,GACpD,IAAI,MAAM,QAAQ,KAAK,GACrB,KAAK,MAAM,QAAQ,OACjB,QAAQ,OAAO,MAAM,IAAI;MAG3B,QAAQ,IAAI,MAAM,OAAO,UAAA,QAAA,UAAA,KAAA,IAAA,QAAS,EAAE,CAAC;CAGzC,OAAO;AACT;AAEA,MAAa,oCAAoC;AAEjD,MAAa,qCACX;AAEF,SAAgB,gCAAgC,OAAe,aAAqB,WAAW,OAAe;CAC5G,IAAI,UACF,OAAO,MAAM,QAAQ,qCAAqC,GAAG,OAAe,UAAkB,QAAgB,GAAG,QAAQ,cAAc,KAAK;CAE9I,OAAO,MAAM,QAAQ,oCAAoC,GAAG,OAAe,UAAkB,QAAgB,GAAG,QAAQ,cAAc,KAAK;AAC7I;AAEA,SAAgB,4BAA4B,OAAe,WAAW,OAAsB;;CAC1F,IAAI,UAAU;;EACZ,QAAA,iBAAA,eAAO,MAAM,MAAM,kCAAkC,OAAA,QAAA,iBAAA,KAAA,IAAA,KAAA,IAAA,aAAI,QAAA,QAAA,kBAAA,KAAA,IAAA,gBAAM;CACjE;CACA,QAAA,kBAAA,gBAAO,MAAM,MAAM,iCAAiC,OAAA,QAAA,kBAAA,KAAA,IAAA,KAAA,IAAA,cAAI,QAAA,QAAA,mBAAA,KAAA,IAAA,iBAAM;AAChE;AAEA,SAAgB,YAAY,OAAe,SAAiB,SAAiB,aAA8B;CACzG,OAAO,MAAM,QACX,IAAI,OAAO,gCAAgC,YAAY,OAAO,KAAK,GAAG,IACrE,GAAG,UAAU,UAAU,GAAG,WAAY,gBAAA,QAAA,gBAAA,KAAA,IAAA,cAAe,WAAY,KAAK,UAAA,QAAA,UAAA,KAAA,IAAA,QAAS,KAAK,SACvF;AACF;AAEA,SAAgB,cAAc,KAA0C;CACtE,MAAM,wBAAwB,IAAI,QAAQ;CAC1C,MAAM,uBAAuB,IAAI,QAAQ;CACzC,MAAM,aAAa,IAAI,QAAQ;CAE/B,MAAM,WAAW,MAAM,QAAQ,qBAAqB,IAChD,sBAAsB,KACrB,0BAAA,QAAA,0BAAA,KAAA,IAAA,wBAA0B,IAAI,UAAU,eAAe,IAAI,UAAU,IAAI,OAAO,YAAY,UAAU;CAC3G,MAAM,OAAO,MAAM,QAAQ,oBAAoB,IAAI,qBAAqB,KAAM,yBAAA,QAAA,yBAAA,KAAA,IAAA,uBAAwB;CAEtG,IAAI,QAAQ,IAAI,aACd,OAAO,IAAI,IAAI,GAAG,SAAS,KAAK,OAAO,IAAI,aAAa;CAG1D,OAAO;AACT;AAYA,MAAM,wBAAwB,IAAI,IAAI,CAAC,wBAAwB,CAAC;AAEhE,SAAgB,iBAAiB,QAAmC;CAClE,OAAO,sBAAsB,IAAI,OAAO,IAAI;AAC9C;AAEA,SAAgB,UAAU,QAAwB;CAChD,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uDAmF8C,WAAW,MAAM,EAAE;;;;;;;;;;;;;;;;;;AAkB1E"}
package/dist/vite.cjs CHANGED
@@ -1,9 +1,9 @@
1
1
  const require_runtime = require("./_virtual/_rolldown/runtime.cjs");
2
2
  const require_constants = require("./constants.cjs");
3
- const require_tailwind = require("./tailwind.cjs");
4
3
  const require_utils = require("./utils.cjs");
5
- let node_fs = require("node:fs");
6
- node_fs = require_runtime.__toESM(node_fs, 1);
4
+ const require_tailwind = require("./tailwind.cjs");
5
+ let node_fs_promises = require("node:fs/promises");
6
+ node_fs_promises = require_runtime.__toESM(node_fs_promises, 1);
7
7
  let node_path = require("node:path");
8
8
  node_path = require_runtime.__toESM(node_path, 1);
9
9
  let minify_xml = require("minify-xml");
@@ -12,25 +12,30 @@ function blogger(userOptions) {
12
12
  const ctx = new BloggerPluginContext(userOptions);
13
13
  return {
14
14
  name: "@blogger-plugin/vite",
15
- config(config) {
15
+ async config(config) {
16
16
  var _config$build;
17
- ctx.resolve(config);
17
+ await ctx.resolve(config);
18
18
  config.build || (config.build = {});
19
19
  (_config$build = config.build)[require_constants.VITE_BUNDLER_KEY] || (_config$build[require_constants.VITE_BUNDLER_KEY] = {});
20
20
  const bundlerOptions = config.build[require_constants.VITE_BUNDLER_KEY];
21
21
  if (Array.isArray(bundlerOptions.input)) bundlerOptions.input = [...bundlerOptions.input, ctx.input];
22
22
  else if (typeof bundlerOptions.input === "object" && bundlerOptions.input !== null) bundlerOptions.input[ctx.input] = ctx.input;
23
23
  else bundlerOptions.input = ctx.input;
24
- const modifiedTemplateXmlContent = require_utils.replaceBloggerPluginHeadComment(require_utils.replaceBloggerPluginHeadComment(node_fs.readFileSync(ctx.template, "utf8"), ""), "", true);
25
- node_fs.writeFileSync(ctx.template, modifiedTemplateXmlContent, "utf-8");
24
+ const modifiedTemplateXmlContent = require_utils.replaceBloggerPluginHeadComment(require_utils.replaceBloggerPluginHeadComment(await node_fs_promises.readFile(ctx.template, "utf8"), ""), "", true);
25
+ await node_fs_promises.writeFile(ctx.template, modifiedTemplateXmlContent, "utf-8");
26
26
  },
27
- configResolved(config) {
27
+ async configResolved(config) {
28
28
  ctx.viteConfig = config;
29
- ctx.tailwind = config.plugins.flat(Number.POSITIVE_INFINITY).some((plugin) => require_utils.isTailwindPlugin(plugin));
30
- if (ctx.tailwind) {
31
- require_tailwind.clearTailwindCache(ctx.root);
32
- if (config.command === "build") require_tailwind.updateTailwindCache(ctx.root, require_utils.unescapeHTML(node_fs.readFileSync(ctx.template, "utf-8"), true), "xml");
33
- } else require_tailwind.removeTailwindCache(ctx.root);
29
+ const hasTailwindPlugin = config.plugins.flat(Number.POSITIVE_INFINITY).some((plugin) => require_utils.isTailwindPlugin(plugin));
30
+ const tailwindCache = new require_tailwind.TailwindCache(node_path.resolve(ctx.root, require_constants.TAILWIND_CACHE_FILE));
31
+ if (hasTailwindPlugin) ctx.tailwindCache = tailwindCache;
32
+ if (hasTailwindPlugin) {
33
+ await tailwindCache.clear();
34
+ if (config.command === "build") {
35
+ const unescapedXmlContent = require_utils.unescapeHTML(await node_fs_promises.readFile(ctx.template, "utf-8"), true);
36
+ await tailwindCache.update(unescapedXmlContent, "xml");
37
+ }
38
+ } else await tailwindCache.remove();
34
39
  },
35
40
  resolveId(source) {
36
41
  if (source === ctx.input) return ctx.input;
@@ -58,7 +63,7 @@ Vite config (recommended):
58
63
  Without this, your assets may fail to load in Blogger.
59
64
  ----------------------`);
60
65
  },
61
- writeBundle(_, bundle) {
66
+ async writeBundle(_, bundle) {
62
67
  if (!(ctx.input in bundle)) return;
63
68
  const asset = bundle[ctx.input];
64
69
  delete bundle[ctx.input];
@@ -74,8 +79,8 @@ Without this, your assets may fail to load in Blogger.
74
79
  return `${$1}='${$2.slice(1, -1).replace(/&/g, "&amp;").replace(/'/g, "&apos;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;")}'`;
75
80
  });
76
81
  }).replace(/<(link|meta|img|br|hr|input)([^>]*?)>/gi, (_, $1, $2) => `<${$1}${$2}/>`).replace(/>\s+</g, "><").trim();
77
- const modifiedTemplateXmlContent = require_utils.replaceBloggerPluginHeadComment(node_fs.readFileSync(ctx.template, "utf8"), headContent, true);
78
- node_fs.writeFileSync(node_path.resolve(ctx.viteConfig.build.outDir, "template.xml"), modifiedTemplateXmlContent);
82
+ const modifiedTemplateXmlContent = require_utils.replaceBloggerPluginHeadComment(await node_fs_promises.readFile(ctx.template, "utf8"), headContent, true);
83
+ await node_fs_promises.writeFile(node_path.resolve(ctx.viteConfig.build.outDir, require_constants.TEMPLATE_OUT_FILE), modifiedTemplateXmlContent);
79
84
  if (ctx.xml.tags) {
80
85
  const templateTagsXmlContent = `<?xml version="1.0" encoding="UTF-8" ?>
81
86
  <!DOCTYPE html>
@@ -99,7 +104,7 @@ Without this, your assets may fail to load in Blogger.
99
104
  <!--body:beforeend:end-->
100
105
  </body>
101
106
  </html>`;
102
- node_fs.writeFileSync(node_path.resolve(ctx.viteConfig.build.outDir, "template.tags.xml"), templateTagsXmlContent);
107
+ await node_fs_promises.writeFile(node_path.resolve(ctx.viteConfig.build.outDir, require_constants.TEMPLATE_TAGS_OUT_FILE), templateTagsXmlContent);
103
108
  }
104
109
  if (ctx.xml.minify) {
105
110
  const minifiedTemplateXmlContent = (0, minify_xml.minify)(modifiedTemplateXmlContent, {
@@ -109,12 +114,12 @@ Without this, your assets may fail to load in Blogger.
109
114
  removeUnusedDefaultNamespace: false,
110
115
  ignoreCData: true
111
116
  });
112
- node_fs.writeFileSync(node_path.resolve(ctx.viteConfig.build.outDir, "template.min.xml"), minifiedTemplateXmlContent);
117
+ await node_fs_promises.writeFile(node_path.resolve(ctx.viteConfig.build.outDir, require_constants.TEMPLATE_MINIFIED_OUT_FILE), minifiedTemplateXmlContent);
113
118
  }
114
119
  },
115
- closeBundle() {
120
+ async closeBundle() {
116
121
  const htmlDir = node_path.resolve(ctx.viteConfig.build.outDir, "virtual:blogger-plugin");
117
- if (node_fs.existsSync(htmlDir)) node_fs.rmSync(htmlDir, { recursive: true });
122
+ if (await require_utils.fsExists(htmlDir)) await node_fs_promises.rm(htmlDir, { recursive: true });
118
123
  },
119
124
  configureServer(server) {
120
125
  return useServerMiddleware(server, ctx, this);
@@ -149,23 +154,23 @@ var BloggerPluginContext = class {
149
154
  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
155
  };
151
156
  this.viteConfig = void 0;
152
- this.tailwind = false;
157
+ this.tailwindCache = null;
153
158
  this.input = void 0;
154
159
  this.headTags = [];
155
160
  this.html = void 0;
156
161
  }
157
- resolve(config) {
162
+ async resolve(config) {
158
163
  this.root = config.root ? node_path.resolve(config.root) : this.root;
159
164
  if (this.options.modules) for (let i = 0; i < this.options.modules.length; i++) {
160
165
  const module = this.options.modules[i];
161
166
  const modulePath = node_path.resolve(this.root, module);
162
167
  if (this.modules.includes(modulePath)) continue;
163
- if (node_fs.existsSync(modulePath)) this.modules.push(modulePath);
168
+ if (await require_utils.fsExists(modulePath)) this.modules.push(modulePath);
164
169
  else throw new Error(`The path provided at modules[${i}] does not exist: ${modulePath}`);
165
170
  }
166
- else for (const module of require_constants.DEFAULT_MODULES) {
171
+ else for (const module of require_constants.DEFAULT_MODULE_FILES) {
167
172
  const modulePath = node_path.resolve(this.root, module);
168
- if (node_fs.existsSync(modulePath)) {
173
+ if (await require_utils.fsExists(modulePath)) {
169
174
  this.modules.push(modulePath);
170
175
  break;
171
176
  }
@@ -174,23 +179,23 @@ var BloggerPluginContext = class {
174
179
  const style = this.options.styles[i];
175
180
  const stylePath = node_path.resolve(this.root, style);
176
181
  if (this.styles.includes(stylePath)) continue;
177
- if (node_fs.existsSync(stylePath)) this.styles.push(stylePath);
182
+ if (await require_utils.fsExists(stylePath)) this.styles.push(stylePath);
178
183
  else throw new Error(`The path provided at styles[${i}] does not exist: ${stylePath}`);
179
184
  }
180
185
  if (this.options.template) {
181
186
  const templatePath = node_path.resolve(this.root, this.options.template);
182
- if (node_fs.existsSync(templatePath)) this.template = templatePath;
187
+ if (await require_utils.fsExists(templatePath)) this.template = templatePath;
183
188
  else throw new Error(`Provided template file does not exist: ${templatePath}`);
184
189
  } else {
185
- for (const file of require_constants.DEFAULT_TEMPLATES) {
190
+ for (const file of require_constants.DEFAULT_TEMPLATE_FILES) {
186
191
  const fullPath = node_path.resolve(this.root, file);
187
- if (node_fs.existsSync(fullPath)) {
192
+ if (await require_utils.fsExists(fullPath)) {
188
193
  this.template = fullPath;
189
194
  break;
190
195
  }
191
196
  }
192
197
  if (!this.template) throw new Error(`No template file found.
193
- Tried: ${require_constants.DEFAULT_TEMPLATES.join(", ")}\n👉 Tip: You can pass a custom template as shown:
198
+ Tried: ${[...require_constants.DEFAULT_TEMPLATE_FILES].join(", ")}\n👉 Tip: You can pass a custom template as shown:
194
199
  blogger({ template: "src/my-template.xml" })`);
195
200
  }
196
201
  this.name = node_path.basename(this.template, node_path.extname(this.template));
@@ -276,13 +281,13 @@ function useServerMiddleware(server, ctx, _this) {
276
281
  let htmlTemplateContent = await proxyResponse.text();
277
282
  const secFetchDestHeader = req.headers["sec-fetch-dest"];
278
283
  const secFetchModeHeader = req.headers["sec-fetch-mode"];
279
- if (ctx.tailwind && isViteDevServer(server) && secFetchDestHeader === "document" && secFetchModeHeader === "navigate") await require_tailwind.updateTailwindCache(ctx.root, htmlTemplateContent, "html");
284
+ if (ctx.tailwindCache && isViteDevServer(server) && secFetchDestHeader === "document" && secFetchModeHeader === "navigate") await ctx.tailwindCache.update(htmlTemplateContent, "html");
280
285
  htmlTemplateContent = require_utils.replaceHost(htmlTemplateContent, proxyUrl.host, url.host, url.protocol);
281
286
  if (isViteDevServer(server)) {
282
287
  const template = await server.transformIndexHtml(req.url, require_utils.replaceBloggerPluginHeadComment(htmlTemplateContent, ctx.headTags.join("")), req.originalUrl);
283
288
  res.end(template);
284
289
  } else {
285
- const htmlTagsStr = require_utils.getBloggerPluginHeadComment(node_fs.readFileSync(node_path.resolve(ctx.viteConfig.build.outDir, "template.xml"), "utf8"), true);
290
+ const htmlTagsStr = require_utils.getBloggerPluginHeadComment(await node_fs_promises.readFile(node_path.resolve(ctx.viteConfig.build.outDir, require_constants.TEMPLATE_OUT_FILE), "utf8"), true);
286
291
  const template = require_utils.replaceBloggerPluginHeadComment(htmlTemplateContent, htmlTagsStr !== null && htmlTagsStr !== void 0 ? htmlTagsStr : "");
287
292
  res.end(template);
288
293
  }
package/dist/vite.cjs.map CHANGED
@@ -1 +1 @@
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, '&amp;')\n .replace(/'/g, '&apos;')\n .replace(/\"/g, '&quot;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;');\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 url.pathname.startsWith('/@')\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":";;;;;;;;;;AA8BA,SAAwB,QAAQ,aAA2C;CACzE,MAAM,MAAM,IAAI,qBAAqB,YAAY;CAEjD,OAAO;EACL,MAAM;EACN,OAAO,QAAQ;;GAEb,IAAI,QAAQ,OAAO;GAGnB,OAAO,UAAP,OAAO,QAAU,EAAE;GACnB,CAAA,gBAAA,OAAO,OAAMA,kBAAAA,sBAAAA,cAAAA,kBAAAA,oBAAsB,EAAE;GACrC,MAAM,iBAAiB,OAAO,MAAMA,kBAAAA;GACpC,IAAI,MAAM,QAAQ,eAAe,MAAM,EACrC,eAAe,QAAQ,CAAC,GAAG,eAAe,OAAO,IAAI,MAAM;QACtD,IAAI,OAAO,eAAe,UAAU,YAAY,eAAe,UAAU,MAC9E,eAAe,MAAM,IAAI,SAAS,IAAI;QAEtC,eAAe,QAAQ,IAAI;GAK7B,MAAM,6BAA6BC,cAAAA,gCAAgCA,cAAAA,gCAFhCC,QAAG,aAAa,IAAI,UAAU,OAE4D,EAAE,GAAG,EAAE,IAAI,KAAK;GAE7I,QAAG,cAAc,IAAI,UAAU,4BAA4B,QAAQ;;EAErE,eAAe,QAAQ;GACrB,IAAI,aAAa;GACjB,IAAI,WAAW,OAAO,QAAQ,KAAK,OAAO,kBAAkB,CAAC,MAAM,WAAWC,cAAAA,iBAAiB,OAAO,CAAC;GAEvG,IAAI,IAAI,UAAU;IAChB,iBAAA,mBAAmB,IAAI,KAAK;IAE5B,IAAI,OAAO,YAAY,SACrB,iBAAA,oBAAoB,IAAI,MAAMC,cAAAA,aAAaF,QAAG,aAAa,IAAI,UAAU,QAAQ,EAAE,KAAK,EAAE,MAAM;UAGlG,iBAAA,oBAAoB,IAAI,KAAK;;EAGjC,UAAU,QAAQ;GAChB,IAAI,WAAW,IAAI,OACjB,OAAO,IAAI;;EAGf,KAAK,IAAI;GACP,IAAI,OAAO,IAAI,OACb,OAAO,IAAI;;EAGf,aAAa;GACX,IAAI,IAAI,WAAW,YAAY,WAAW,CAAC,eAAe,KAAK,IAAI,WAAW,KAAK,EACjF,KAAK,KAAK;;;;;;WAMP,IAAI,WAAW,KAAK;;;;;;;;;;;wBAWP;;EAGpB,YAAY,GAAG,QAAQ;GACrB,IAAI,EAAE,IAAI,SAAS,SACjB;GAEF,MAAM,QAAQ,OAAO,IAAI;GACzB,OAAO,OAAO,IAAI;GAElB,IAAI,MAAM,SAAS,WAAW,OAAO,MAAM,WAAW,UACpD;GAIF,MAAM,QAAQ,MAAM,OAAO,MAAM,4IAAM;GACvC,IAAI,CAAC,OACH;GAGF,MAAM,iBAAiB,MAAM;GAC7B,MAAM,gBAAgB,MAAM;GAC5B,MAAM,iBAAiB,MAAM;GAC7B,MAAM,gBAAgB,MAAM;GAE5B,MAAM,eAAe,iBAAiB,eACnC,QAAQ,aAAa,eAAuB;IAC3C,OACE,WAEG,QAAQ,4DAA4D,GAAG,OACtE,OAAO,gBAAgB,8BAA4B,GAAG,GAAG,KAC1D,CAEA,QAAQ,yBAAyB,GAAG,IAAY,OAAe;KAU9D,OAAO,GAAG,GAAG,IATH,GAEP,MAAM,GAAG,GAAG,CAEZ,QAAQ,MAAM,QAAQ,CACtB,QAAQ,MAAM,SAAS,CACvB,QAAQ,MAAM,SAAS,CACvB,QAAQ,MAAM,OAAO,CACrB,QAAQ,MAAM,OACC,CAAC;MACnB;KAEN,CAED,QAAQ,4CAA4C,GAAG,IAAY,OAAe,IAAI,KAAK,GAAG,IAAI,CAElG,QAAQ,UAAU,KAAK,CAEvB,MAAM;GAGT,MAAM,6BAA6BD,cAAAA,gCADAC,QAAG,aAAa,IAAI,UAAU,OAC4B,EAAE,aAAa,KAAK;GAEjH,QAAG,cAAcG,UAAK,QAAQ,IAAI,WAAW,MAAM,QAAQ,eAAe,EAAE,2BAA2B;GAEvG,IAAI,IAAI,IAAI,MAAM;IAChB,MAAM,yBAAyB;;;;;;;;;IASnC,YAAY;;;;;IAKZ,eAAe,MAAM,CAAC;;;;IAItB,cAAc,MAAM,CAAC;;;;IAIjB,QAAG,cAAcA,UAAK,QAAQ,IAAI,WAAW,MAAM,QAAQ,oBAAoB,EAAE,uBAAuB;;GAG1G,IAAI,IAAI,IAAI,QAAQ;IAClB,MAAM,8BAAA,GAAA,WAAA,QAAoC,4BAA4B;KACpE,gBAAgB;KAChB,mBAAmB;KACnB,wBAAwB;KACxB,8BAA8B;KAC9B,aAAa;KACd,CAAkB;IACnB,QAAG,cAAcA,UAAK,QAAQ,IAAI,WAAW,MAAM,QAAQ,mBAAmB,EAAE,2BAA2B;;;EAG/G,cAAc;GACZ,MAAM,UAAUA,UAAK,QAAQ,IAAI,WAAW,MAAM,QAAQ,yBAAyB;GACnF,IAAIH,QAAG,WAAW,QAAQ,EACxB,QAAG,OAAO,SAAS,EAAE,WAAW,MAAM,CAAC;;EAG3C,gBAAgB,QAAQ;GACtB,OAAO,oBAAoB,QAAQ,KAAK,KAAK;;EAE/C,uBAAuB,QAAQ;GAC7B,OAAO,oBAAoB,QAAQ,KAAK,KAAK;;EAEhD;;AAGH,IAAM,uBAAN,MAA2B;CAezB,YAAY,SAA+B;;EACzC,IAAI,OAAO,QAAQ,aAAa,eAAe,OAAO,QAAQ,aAAa,UACzE,MAAM,IAAI,MAAM,qCAAqC;EAEvD,IAAI,OAAO,QAAQ,YAAY,eAAe,CAAC,MAAM,QAAQ,QAAQ,QAAQ,EAC3E,MAAM,IAAI,MAAM,oCAAoC;EAEtD,IAAI,OAAO,QAAQ,WAAW,eAAe,CAAC,MAAM,QAAQ,QAAQ,OAAO,EACzE,MAAM,IAAI,MAAM,mCAAmC;EAErD,IAAI,OAAO,QAAQ,cAAc,UAC/B,MAAM,IAAI,MAAM,sCAAsC;EAExD,IAAI;EACJ,IAAI;GACF,YAAY,IAAI,IAAI,QAAQ,UAAU;oBAChC;GACN,MAAM,IAAI,MAAM,yCAAyC;;EAG3D,KAAK,UAAU;EACf,KAAK,OAAO,QAAQ,KAAK;EACzB,KAAK,UAAU,EAAE;EACjB,KAAK,SAAS,EAAE;EAChB,KAAK,WAAW,KAAA;EAChB,KAAK,OAAO,KAAA;EACZ,KAAK,YAAY;EACjB,KAAK,MAAM;GACT,OAAA,qBAAA,eAAM,QAAQ,SAAA,QAAA,iBAAA,KAAA,IAAA,KAAA,IAAA,aAAK,UAAA,QAAA,sBAAA,KAAA,IAAA,oBAAQ;GAC3B,SAAA,uBAAA,gBAAQ,QAAQ,SAAA,QAAA,kBAAA,KAAA,IAAA,KAAA,IAAA,cAAK,YAAA,QAAA,wBAAA,KAAA,IAAA,sBAAU;GAChC;EACD,KAAK,aAAa,KAAA;EAClB,KAAK,WAAW;EAChB,KAAK,QAAQ,KAAA;EACb,KAAK,WAAW,EAAE;EAClB,KAAK,OAAO,KAAA;;CAGd,QAAQ,QAAoB;EAC1B,KAAK,OAAO,OAAO,OAAOG,UAAK,QAAQ,OAAO,KAAK,GAAG,KAAK;EAE3D,IAAI,KAAK,QAAQ,SACf,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,QAAQ,QAAQ,KAAK;GACpD,MAAM,SAAS,KAAK,QAAQ,QAAQ;GACpC,MAAM,aAAaA,UAAK,QAAQ,KAAK,MAAM,OAAO;GAClD,IAAI,KAAK,QAAQ,SAAS,WAAW,EACnC;GAEF,IAAIH,QAAG,WAAW,WAAW,EAC3B,KAAK,QAAQ,KAAK,WAAW;QAE7B,MAAM,IAAI,MAAM,gCAAgC,EAAE,oBAAoB,aAAa;;OAIvF,KAAK,MAAM,UAAUI,kBAAAA,iBAAiB;GACpC,MAAM,aAAaD,UAAK,QAAQ,KAAK,MAAM,OAAO;GAClD,IAAIH,QAAG,WAAW,WAAW,EAAE;IAC7B,KAAK,QAAQ,KAAK,WAAW;IAC7B;;;EAKN,IAAI,KAAK,QAAQ,QACf,KAAK,IAAI,IAAI,GAAG,IAAI,KAAK,QAAQ,OAAO,QAAQ,KAAK;GACnD,MAAM,QAAQ,KAAK,QAAQ,OAAO;GAClC,MAAM,YAAYG,UAAK,QAAQ,KAAK,MAAM,MAAM;GAChD,IAAI,KAAK,OAAO,SAAS,UAAU,EACjC;GAEF,IAAIH,QAAG,WAAW,UAAU,EAC1B,KAAK,OAAO,KAAK,UAAU;QAE3B,MAAM,IAAI,MAAM,+BAA+B,EAAE,oBAAoB,YAAY;;EAKvF,IAAI,KAAK,QAAQ,UAAU;GACzB,MAAM,eAAeG,UAAK,QAAQ,KAAK,MAAM,KAAK,QAAQ,SAAS;GACnE,IAAIH,QAAG,WAAW,aAAa,EAC7B,KAAK,WAAW;QAEhB,MAAM,IAAI,MAAM,0CAA0C,eAAe;SAEtE;GACL,KAAK,MAAM,QAAQK,kBAAAA,mBAAmB;IACpC,MAAM,WAAWF,UAAK,QAAQ,KAAK,MAAM,KAAK;IAC9C,IAAIH,QAAG,WAAW,SAAS,EAAE;KAC3B,KAAK,WAAW;KAChB;;;GAIJ,IAAI,CAAC,KAAK,UACR,MAAM,IAAI,MACR;SACYK,kBAAAA,kBAAkB,KAAK,KAAK,CAAC;iDAG1C;;EAIL,KAAK,OAAOF,UAAK,SAAS,KAAK,UAAUA,UAAK,QAAQ,KAAK,SAAS,CAAC;EAErE,KAAK,MAAM,cAAc,KAAK,SAC5B,KAAK,SAAS,KAAK,+BAA+BA,UAAK,SAAS,KAAK,MAAM,WAAW,CAAC,WAAW,MAAM,IAAI,CAAC,cAAa;EAE5H,KAAK,MAAM,aAAa,KAAK,QAC3B,KAAK,SAAS,KAAK,iCAAiCA,UAAK,SAAS,KAAK,MAAM,UAAU,CAAC,WAAW,MAAM,IAAI,CAAC,IAAI;EAGpH,KAAK,QAAQ,0BAA0B,KAAK,KAAK;EACjD,KAAK,OAAO;;;eAGD,KAAK,SAAS,SAAS,IAAI,OAAO,KAAK,SAAS,KAAK,OAAO,KAAK,GAAG;;;;;;;;AASnF,SAAS,oBAAoB,QAAuC,KAA2B,OAA+C;CAC5I,MAAM,QAAQ,IAAI,WAAW,MAAML,kBAAAA,kBAAkB;CACrD,MAAM,gBAA0B,EAAE;CAClC,KAAK,MAAM,SAAS,MAAM,QAAQ,MAAM,GAAG,QAAQ,OAAO,UAAU,WAAW,OAAO,OAAO,MAAM,GAAG,OAAO,UAAU,WAAW,CAAC,MAAM,GAAG,EAAE,EAAE;EAC9I,IAAI,UAAU,IAAI,OAChB;EAGF,IAAI,CADcK,UAAK,QAAQ,IAAI,MAAM,MAC3B,CAAC,SAAS,QAAQ,EAC9B;EAEF,MAAM,eAAeA,UAAK,SAAS,IAAI,MAAM,MAAM,CAAC,WAAW,MAAM,IAAI;EACzE,cAAc,KAAK,IAAI,eAAe;EACtC,IAAI,aAAa,SAAS,aAAa,EACrC,cAAc,KAAK,IAAI,aAAa,QAAQ,gBAAgB,GAAG,GAAG;;CAItE,aAAa;;EACX,CAAA,qBAAA,OAAO,gBAAA,QAAA,uBAAA,KAAA,KAAA,mBAAY,KAAK,mBAAmB;GACzC,iBAAiB;IACf,MAAM,KAAK,yCAAyC,IAAI,UAAU,SAAS;MAC1E,EAAE;IACL;EAEF,OAAO,YAAY,IAAI,OAAO,KAAK,KAAK,SAAS;GAC/C,MAAM,MAAMG,cAAAA,cAAc,IAAI;GAE9B,IACE,CAAC,IAAI,OACL,CAAC,IAAI,eACL,CAAC,OACD,CAAC,IAAI,UACL,CAAC,CAAC,OAAO,OAAO,CAAC,SAAS,IAAI,OAAO,aAAa,CAAC,IACnD,cAAc,SAAS,IAAI,SAAS,QAAQ,QAAQ,IAAI,CAAC,IACzD,IAAI,SAAS,WAAW,KAAK,EAC7B;IACA,MAAM;IACN;;GAGF,MAAM,QAAQ,KAAK,KAAK;GAExB,MAAM,WAAW,IAAI,IAAI,GAAG,IAAI,UAAU,SAAS,IAAI,cAAc;GAErE,MAAM,YAAY,SAAS,aAAa,IAAI,OAAO;GACnD,SAAS,aAAa,IAAI,QAAQ,GAAG,gBAAgB,OAAO,GAAG,eAAe,oBAAA,cAAA,QAAA,cAAA,KAAA,IAAA,KAAA,IAAmB,UAAW,WAAW,IAAI,IAAG,YAAY,KAAK;GAE/I,MAAM,eAAe,IAAI,QAAQ,UAAU;IACzC,QAAQ,IAAI;IACZ,SAASC,cAAAA,aAAa,IAAI,QAAQ;IAClC,UAAU;IACX,CAAC;GAEF,MAAM,gBAAgB,MAAM,MAAM,aAAa,CAAC,OAAO,UAAU;IAC/D,IAAI,iBAAiB,OACnB,MAAM,KAAK;KACT,SAAS,GAAG,MAAM,KAAK,IAAI,MAAM;KACjC,OAAO,MAAM;KACb,OAAO,MAAM;KACd,CAAC;SAEF,MAAM,KAAK,eAAe;IAE5B,OAAO;KACP;GAEF,IAAI,eAAe;IACjB,IAAI,aAAa,cAAc;IAC/B,IAAI,gBAAgB,cAAc;IAElC,cAAc,QAAQ,SAAS,OAAO,QAAQ;KAC5C,IAAI,QAAQ,YAAY;MACtB,MAAM,cAAc,IAAI,IAAI,OAAO,SAAS;MAC5C,IAAI,YAAY,SAAS,IAAI,QAAQ,YAAY,SAAS,SAAS,MAAM;;OACvE,YAAY,OAAO,IAAI;OACvB,YAAY,WAAW,IAAI;OAC3B,MAAM,aAAA,wBAAY,YAAY,aAAa,IAAI,OAAO,MAAA,QAAA,0BAAA,KAAA,IAAA,KAAA,IAAA,sBAAE,WAAW,cAAc,GAAG,CAAC,WAAW,kBAAkB,GAAG;OACrH,IAAI,WACF,YAAY,aAAa,IAAI,QAAQ,UAAU;YAE/C,YAAY,aAAa,OAAO,OAAO;OAEzC,IAAI,UAAU,YAAY,YAAY,WAAW,YAAY,SAAS,YAAY,KAAK;aAEvF,IAAI,UAAU,YAAY,YAAY,KAAK;YAExC,IAAI;MAAC;MAAgB;MAAgB;MAAQ;MAAW,CAAC,SAAS,IAAI,EAC3E,IAAI,UAAU,KAAK,MAAM;MAE3B;IAEF,MAAM,cAAc,cAAc,QAAQ,IAAI,eAAe;IAE7D,IAAA,gBAAA,QAAA,gBAAA,KAAA,IAAA,KAAA,IAAI,YAAa,WAAW,YAAY,EAAE;KACxC,IAAI,sBAAsB,MAAM,cAAc,MAAM;KAEpD,MAAM,qBAAqB,IAAI,QAAQ;KACvC,MAAM,qBAAqB,IAAI,QAAQ;KACvC,IAAI,IAAI,YAAY,gBAAgB,OAAO,IAAI,uBAAuB,cAAc,uBAAuB,YACzG,MAAMC,iBAAAA,oBAAoB,IAAI,MAAM,qBAAqB,OAAO;KAGlE,sBAAsBC,cAAAA,YAAY,qBAAqB,SAAS,MAAM,IAAI,MAAM,IAAI,SAAS;KAE7F,IAAI,gBAAgB,OAAO,EAAE;MAC3B,MAAM,WAAW,MAAM,OAAO,mBAC5B,IAAI,KACJV,cAAAA,gCAAgC,qBAAqB,IAAI,SAAS,KAAK,GAAG,CAAC,EAC3E,IAAI,YACL;MAED,IAAI,IAAI,SAAS;YACZ;MAGL,MAAM,cAAcW,cAAAA,4BAFOV,QAAG,aAAaG,UAAK,QAAQ,IAAI,WAAW,MAAM,QAAQ,eAAe,EAAE,OAEpC,EAAE,KAAK;MAEzE,MAAM,WAAWJ,cAAAA,gCAAgC,qBAAqB,gBAAA,QAAA,gBAAA,KAAA,IAAA,cAAe,GAAG;MAExF,IAAI,IAAI,SAAS;;WAEd,IAAI,eAAe,6CAA6C,KAAK,YAAY,EAAE;KACxF,MAAM,UAAU,MAAM,cAAc,MAAM;KAE1C,IAAI,IAAIU,cAAAA,YAAY,SAAS,SAAS,MAAM,IAAI,MAAM,IAAI,SAAS,CAAC;WAEpE,IAAI,IAAI,IAAI,WAAW,MAAM,cAAc,aAAa,CAAC,CAAC;UAEvD;IACL,IAAI,aAAa;IACjB,IAAI,gBAAgB;IAEpB,IAAI,UAAU,gBAAgB,YAAY;IAE1C,IAAI,IAAIE,cAAAA,UAAU,SAAS,KAAK,CAAC;;GAGnC,MAAM,WAAW,KAAK,KAAK,GAAG;GAE9B,MAAM,KAAK,GAAG,IAAI,OAAO,GAAG,IAAI,YAAY,MAAM,IAAI,WAAW,GAAG,IAAI,cAAc,IAAI,SAAS,KAAK;IACxG;;;AAIN,SAAS,gBAAgB,QAAgE;CACvF,OAAO,SAAS,UAAU,sBAAsB,UAAU,wBAAwB"}
1
+ {"version":3,"file":"vite.cjs","names":["VITE_BUNDLER_KEY","replaceBloggerPluginHeadComment","fs","isTailwindPlugin","TailwindCache","path","TAILWIND_CACHE_FILE","unescapeHTML","TEMPLATE_OUT_FILE","TEMPLATE_TAGS_OUT_FILE","TEMPLATE_MINIFIED_OUT_FILE","fsExists","DEFAULT_MODULE_FILES","DEFAULT_TEMPLATE_FILES","getRequestUrl","toWebHeaders","replaceHost","getBloggerPluginHeadComment","errorHtml"],"sources":["../src/vite.ts"],"sourcesContent":["import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { type MinifyOptions, minify } from 'minify-xml';\nimport type { MinimalPluginContextWithoutEnvironment, Plugin, PreviewServer, ResolvedConfig, UserConfig, ViteDevServer } from 'vite';\nimport {\n DEFAULT_MODULE_FILES,\n DEFAULT_TEMPLATE_FILES,\n TAILWIND_CACHE_FILE,\n TEMPLATE_MINIFIED_OUT_FILE,\n TEMPLATE_OUT_FILE,\n TEMPLATE_TAGS_OUT_FILE,\n VITE_BUNDLER_KEY,\n} from './constants';\nimport { TailwindCache } from './tailwind';\nimport {\n errorHtml,\n fsExists,\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 async config(config) {\n // resolve plugin context\n await 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 // remove contents between comments from template\n const originalTemplateXmlContent = await fs.readFile(ctx.template, 'utf8');\n const modifiedTemplateXmlContent = replaceBloggerPluginHeadComment(replaceBloggerPluginHeadComment(originalTemplateXmlContent, ''), '', true);\n\n await fs.writeFile(ctx.template, modifiedTemplateXmlContent, 'utf-8');\n },\n async configResolved(config) {\n ctx.viteConfig = config;\n\n const hasTailwindPlugin = config.plugins.flat(Number.POSITIVE_INFINITY).some((plugin) => isTailwindPlugin(plugin));\n const tailwindCache = new TailwindCache(path.resolve(ctx.root, TAILWIND_CACHE_FILE));\n\n if (hasTailwindPlugin) {\n ctx.tailwindCache = tailwindCache;\n }\n\n if (hasTailwindPlugin) {\n await tailwindCache.clear();\n\n if (config.command === 'build') {\n const xmlContent = await fs.readFile(ctx.template, 'utf-8');\n const unescapedXmlContent = unescapeHTML(xmlContent, true);\n await tailwindCache.update(unescapedXmlContent, 'xml');\n }\n } else {\n await tailwindCache.remove();\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 async 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, '&amp;')\n .replace(/'/g, '&apos;')\n .replace(/\"/g, '&quot;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;');\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 = await fs.readFile(ctx.template, 'utf8');\n const modifiedTemplateXmlContent = replaceBloggerPluginHeadComment(originalTemplateXmlContent, headContent, true);\n\n await fs.writeFile(path.resolve(ctx.viteConfig.build.outDir, TEMPLATE_OUT_FILE), 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 await fs.writeFile(path.resolve(ctx.viteConfig.build.outDir, TEMPLATE_TAGS_OUT_FILE), 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 await fs.writeFile(path.resolve(ctx.viteConfig.build.outDir, TEMPLATE_MINIFIED_OUT_FILE), minifiedTemplateXmlContent);\n }\n },\n async closeBundle() {\n const htmlDir = path.resolve(ctx.viteConfig.build.outDir, 'virtual:blogger-plugin');\n\n const exists = await fsExists(htmlDir);\n\n if (exists) {\n await fs.rm(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 tailwindCache: TailwindCache | null;\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.tailwindCache = null;\n this.input = undefined as unknown as string;\n this.headTags = [];\n this.html = undefined as unknown as string;\n }\n\n async resolve(config: UserConfig): Promise<void> {\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 (await fsExists(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_MODULE_FILES) {\n const modulePath = path.resolve(this.root, module);\n if (await fsExists(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 (await fsExists(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 (await fsExists(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_TEMPLATE_FILES) {\n const fullPath = path.resolve(this.root, file);\n if (await fsExists(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_TEMPLATE_FILES].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(\n server: ViteDevServer | PreviewServer,\n ctx: BloggerPluginContext,\n _this: MinimalPluginContextWithoutEnvironment,\n): () => void {\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 url.pathname.startsWith('/@')\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.tailwindCache && isViteDevServer(server) && secFetchDestHeader === 'document' && secFetchModeHeader === 'navigate') {\n await ctx.tailwindCache.update(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 = await fs.readFile(path.resolve(ctx.viteConfig.build.outDir, TEMPLATE_OUT_FILE), '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.mjs CHANGED
@@ -1,7 +1,7 @@
1
- import { DEFAULT_MODULES, DEFAULT_TEMPLATES, VITE_BUNDLER_KEY } from "./constants.mjs";
2
- import { clearTailwindCache, removeTailwindCache, updateTailwindCache } from "./tailwind.mjs";
3
- import { errorHtml, getBloggerPluginHeadComment, getRequestUrl, isTailwindPlugin, replaceBloggerPluginHeadComment, replaceHost, toWebHeaders, unescapeHTML } from "./utils.mjs";
4
- import * as fs from "node:fs";
1
+ import { DEFAULT_MODULE_FILES, DEFAULT_TEMPLATE_FILES, TAILWIND_CACHE_FILE, TEMPLATE_MINIFIED_OUT_FILE, TEMPLATE_OUT_FILE, TEMPLATE_TAGS_OUT_FILE, VITE_BUNDLER_KEY } from "./constants.mjs";
2
+ import { errorHtml, fsExists, getBloggerPluginHeadComment, getRequestUrl, isTailwindPlugin, replaceBloggerPluginHeadComment, replaceHost, toWebHeaders, unescapeHTML } from "./utils.mjs";
3
+ import { TailwindCache } from "./tailwind.mjs";
4
+ import * as fs from "node:fs/promises";
5
5
  import * as path from "node:path";
6
6
  import { minify } from "minify-xml";
7
7
  //#region src/vite.ts
@@ -9,25 +9,30 @@ function blogger(userOptions) {
9
9
  const ctx = new BloggerPluginContext(userOptions);
10
10
  return {
11
11
  name: "@blogger-plugin/vite",
12
- config(config) {
12
+ async config(config) {
13
13
  var _config$build;
14
- ctx.resolve(config);
14
+ await ctx.resolve(config);
15
15
  config.build || (config.build = {});
16
16
  (_config$build = config.build)[VITE_BUNDLER_KEY] || (_config$build[VITE_BUNDLER_KEY] = {});
17
17
  const bundlerOptions = config.build[VITE_BUNDLER_KEY];
18
18
  if (Array.isArray(bundlerOptions.input)) bundlerOptions.input = [...bundlerOptions.input, ctx.input];
19
19
  else if (typeof bundlerOptions.input === "object" && bundlerOptions.input !== null) bundlerOptions.input[ctx.input] = ctx.input;
20
20
  else bundlerOptions.input = ctx.input;
21
- const modifiedTemplateXmlContent = replaceBloggerPluginHeadComment(replaceBloggerPluginHeadComment(fs.readFileSync(ctx.template, "utf8"), ""), "", true);
22
- fs.writeFileSync(ctx.template, modifiedTemplateXmlContent, "utf-8");
21
+ const modifiedTemplateXmlContent = replaceBloggerPluginHeadComment(replaceBloggerPluginHeadComment(await fs.readFile(ctx.template, "utf8"), ""), "", true);
22
+ await fs.writeFile(ctx.template, modifiedTemplateXmlContent, "utf-8");
23
23
  },
24
- configResolved(config) {
24
+ async configResolved(config) {
25
25
  ctx.viteConfig = config;
26
- ctx.tailwind = config.plugins.flat(Number.POSITIVE_INFINITY).some((plugin) => isTailwindPlugin(plugin));
27
- if (ctx.tailwind) {
28
- clearTailwindCache(ctx.root);
29
- if (config.command === "build") updateTailwindCache(ctx.root, unescapeHTML(fs.readFileSync(ctx.template, "utf-8"), true), "xml");
30
- } else removeTailwindCache(ctx.root);
26
+ const hasTailwindPlugin = config.plugins.flat(Number.POSITIVE_INFINITY).some((plugin) => isTailwindPlugin(plugin));
27
+ const tailwindCache = new TailwindCache(path.resolve(ctx.root, TAILWIND_CACHE_FILE));
28
+ if (hasTailwindPlugin) ctx.tailwindCache = tailwindCache;
29
+ if (hasTailwindPlugin) {
30
+ await tailwindCache.clear();
31
+ if (config.command === "build") {
32
+ const unescapedXmlContent = unescapeHTML(await fs.readFile(ctx.template, "utf-8"), true);
33
+ await tailwindCache.update(unescapedXmlContent, "xml");
34
+ }
35
+ } else await tailwindCache.remove();
31
36
  },
32
37
  resolveId(source) {
33
38
  if (source === ctx.input) return ctx.input;
@@ -55,7 +60,7 @@ Vite config (recommended):
55
60
  Without this, your assets may fail to load in Blogger.
56
61
  ----------------------`);
57
62
  },
58
- writeBundle(_, bundle) {
63
+ async writeBundle(_, bundle) {
59
64
  if (!(ctx.input in bundle)) return;
60
65
  const asset = bundle[ctx.input];
61
66
  delete bundle[ctx.input];
@@ -71,8 +76,8 @@ Without this, your assets may fail to load in Blogger.
71
76
  return `${$1}='${$2.slice(1, -1).replace(/&/g, "&amp;").replace(/'/g, "&apos;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;")}'`;
72
77
  });
73
78
  }).replace(/<(link|meta|img|br|hr|input)([^>]*?)>/gi, (_, $1, $2) => `<${$1}${$2}/>`).replace(/>\s+</g, "><").trim();
74
- const modifiedTemplateXmlContent = replaceBloggerPluginHeadComment(fs.readFileSync(ctx.template, "utf8"), headContent, true);
75
- fs.writeFileSync(path.resolve(ctx.viteConfig.build.outDir, "template.xml"), modifiedTemplateXmlContent);
79
+ const modifiedTemplateXmlContent = replaceBloggerPluginHeadComment(await fs.readFile(ctx.template, "utf8"), headContent, true);
80
+ await fs.writeFile(path.resolve(ctx.viteConfig.build.outDir, TEMPLATE_OUT_FILE), modifiedTemplateXmlContent);
76
81
  if (ctx.xml.tags) {
77
82
  const templateTagsXmlContent = `<?xml version="1.0" encoding="UTF-8" ?>
78
83
  <!DOCTYPE html>
@@ -96,7 +101,7 @@ Without this, your assets may fail to load in Blogger.
96
101
  <!--body:beforeend:end-->
97
102
  </body>
98
103
  </html>`;
99
- fs.writeFileSync(path.resolve(ctx.viteConfig.build.outDir, "template.tags.xml"), templateTagsXmlContent);
104
+ await fs.writeFile(path.resolve(ctx.viteConfig.build.outDir, TEMPLATE_TAGS_OUT_FILE), templateTagsXmlContent);
100
105
  }
101
106
  if (ctx.xml.minify) {
102
107
  const minifiedTemplateXmlContent = minify(modifiedTemplateXmlContent, {
@@ -106,12 +111,12 @@ Without this, your assets may fail to load in Blogger.
106
111
  removeUnusedDefaultNamespace: false,
107
112
  ignoreCData: true
108
113
  });
109
- fs.writeFileSync(path.resolve(ctx.viteConfig.build.outDir, "template.min.xml"), minifiedTemplateXmlContent);
114
+ await fs.writeFile(path.resolve(ctx.viteConfig.build.outDir, TEMPLATE_MINIFIED_OUT_FILE), minifiedTemplateXmlContent);
110
115
  }
111
116
  },
112
- closeBundle() {
117
+ async closeBundle() {
113
118
  const htmlDir = path.resolve(ctx.viteConfig.build.outDir, "virtual:blogger-plugin");
114
- if (fs.existsSync(htmlDir)) fs.rmSync(htmlDir, { recursive: true });
119
+ if (await fsExists(htmlDir)) await fs.rm(htmlDir, { recursive: true });
115
120
  },
116
121
  configureServer(server) {
117
122
  return useServerMiddleware(server, ctx, this);
@@ -146,23 +151,23 @@ var BloggerPluginContext = class {
146
151
  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
152
  };
148
153
  this.viteConfig = void 0;
149
- this.tailwind = false;
154
+ this.tailwindCache = null;
150
155
  this.input = void 0;
151
156
  this.headTags = [];
152
157
  this.html = void 0;
153
158
  }
154
- resolve(config) {
159
+ async resolve(config) {
155
160
  this.root = config.root ? path.resolve(config.root) : this.root;
156
161
  if (this.options.modules) for (let i = 0; i < this.options.modules.length; i++) {
157
162
  const module = this.options.modules[i];
158
163
  const modulePath = path.resolve(this.root, module);
159
164
  if (this.modules.includes(modulePath)) continue;
160
- if (fs.existsSync(modulePath)) this.modules.push(modulePath);
165
+ if (await fsExists(modulePath)) this.modules.push(modulePath);
161
166
  else throw new Error(`The path provided at modules[${i}] does not exist: ${modulePath}`);
162
167
  }
163
- else for (const module of DEFAULT_MODULES) {
168
+ else for (const module of DEFAULT_MODULE_FILES) {
164
169
  const modulePath = path.resolve(this.root, module);
165
- if (fs.existsSync(modulePath)) {
170
+ if (await fsExists(modulePath)) {
166
171
  this.modules.push(modulePath);
167
172
  break;
168
173
  }
@@ -171,23 +176,23 @@ var BloggerPluginContext = class {
171
176
  const style = this.options.styles[i];
172
177
  const stylePath = path.resolve(this.root, style);
173
178
  if (this.styles.includes(stylePath)) continue;
174
- if (fs.existsSync(stylePath)) this.styles.push(stylePath);
179
+ if (await fsExists(stylePath)) this.styles.push(stylePath);
175
180
  else throw new Error(`The path provided at styles[${i}] does not exist: ${stylePath}`);
176
181
  }
177
182
  if (this.options.template) {
178
183
  const templatePath = path.resolve(this.root, this.options.template);
179
- if (fs.existsSync(templatePath)) this.template = templatePath;
184
+ if (await fsExists(templatePath)) this.template = templatePath;
180
185
  else throw new Error(`Provided template file does not exist: ${templatePath}`);
181
186
  } else {
182
- for (const file of DEFAULT_TEMPLATES) {
187
+ for (const file of DEFAULT_TEMPLATE_FILES) {
183
188
  const fullPath = path.resolve(this.root, file);
184
- if (fs.existsSync(fullPath)) {
189
+ if (await fsExists(fullPath)) {
185
190
  this.template = fullPath;
186
191
  break;
187
192
  }
188
193
  }
189
194
  if (!this.template) throw new Error(`No template file found.
190
- Tried: ${DEFAULT_TEMPLATES.join(", ")}\n👉 Tip: You can pass a custom template as shown:
195
+ Tried: ${[...DEFAULT_TEMPLATE_FILES].join(", ")}\n👉 Tip: You can pass a custom template as shown:
191
196
  blogger({ template: "src/my-template.xml" })`);
192
197
  }
193
198
  this.name = path.basename(this.template, path.extname(this.template));
@@ -273,13 +278,13 @@ function useServerMiddleware(server, ctx, _this) {
273
278
  let htmlTemplateContent = await proxyResponse.text();
274
279
  const secFetchDestHeader = req.headers["sec-fetch-dest"];
275
280
  const secFetchModeHeader = req.headers["sec-fetch-mode"];
276
- if (ctx.tailwind && isViteDevServer(server) && secFetchDestHeader === "document" && secFetchModeHeader === "navigate") await updateTailwindCache(ctx.root, htmlTemplateContent, "html");
281
+ if (ctx.tailwindCache && isViteDevServer(server) && secFetchDestHeader === "document" && secFetchModeHeader === "navigate") await ctx.tailwindCache.update(htmlTemplateContent, "html");
277
282
  htmlTemplateContent = replaceHost(htmlTemplateContent, proxyUrl.host, url.host, url.protocol);
278
283
  if (isViteDevServer(server)) {
279
284
  const template = await server.transformIndexHtml(req.url, replaceBloggerPluginHeadComment(htmlTemplateContent, ctx.headTags.join("")), req.originalUrl);
280
285
  res.end(template);
281
286
  } else {
282
- const htmlTagsStr = getBloggerPluginHeadComment(fs.readFileSync(path.resolve(ctx.viteConfig.build.outDir, "template.xml"), "utf8"), true);
287
+ const htmlTagsStr = getBloggerPluginHeadComment(await fs.readFile(path.resolve(ctx.viteConfig.build.outDir, TEMPLATE_OUT_FILE), "utf8"), true);
283
288
  const template = replaceBloggerPluginHeadComment(htmlTemplateContent, htmlTagsStr !== null && htmlTagsStr !== void 0 ? htmlTagsStr : "");
284
289
  res.end(template);
285
290
  }
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 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, '&amp;')\n .replace(/'/g, '&apos;')\n .replace(/\"/g, '&quot;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;');\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 url.pathname.startsWith('/@')\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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"}
1
+ {"version":3,"file":"vite.mjs","names":[],"sources":["../src/vite.ts"],"sourcesContent":["import * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport { type MinifyOptions, minify } from 'minify-xml';\nimport type { MinimalPluginContextWithoutEnvironment, Plugin, PreviewServer, ResolvedConfig, UserConfig, ViteDevServer } from 'vite';\nimport {\n DEFAULT_MODULE_FILES,\n DEFAULT_TEMPLATE_FILES,\n TAILWIND_CACHE_FILE,\n TEMPLATE_MINIFIED_OUT_FILE,\n TEMPLATE_OUT_FILE,\n TEMPLATE_TAGS_OUT_FILE,\n VITE_BUNDLER_KEY,\n} from './constants';\nimport { TailwindCache } from './tailwind';\nimport {\n errorHtml,\n fsExists,\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 async config(config) {\n // resolve plugin context\n await 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 // remove contents between comments from template\n const originalTemplateXmlContent = await fs.readFile(ctx.template, 'utf8');\n const modifiedTemplateXmlContent = replaceBloggerPluginHeadComment(replaceBloggerPluginHeadComment(originalTemplateXmlContent, ''), '', true);\n\n await fs.writeFile(ctx.template, modifiedTemplateXmlContent, 'utf-8');\n },\n async configResolved(config) {\n ctx.viteConfig = config;\n\n const hasTailwindPlugin = config.plugins.flat(Number.POSITIVE_INFINITY).some((plugin) => isTailwindPlugin(plugin));\n const tailwindCache = new TailwindCache(path.resolve(ctx.root, TAILWIND_CACHE_FILE));\n\n if (hasTailwindPlugin) {\n ctx.tailwindCache = tailwindCache;\n }\n\n if (hasTailwindPlugin) {\n await tailwindCache.clear();\n\n if (config.command === 'build') {\n const xmlContent = await fs.readFile(ctx.template, 'utf-8');\n const unescapedXmlContent = unescapeHTML(xmlContent, true);\n await tailwindCache.update(unescapedXmlContent, 'xml');\n }\n } else {\n await tailwindCache.remove();\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 async 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, '&amp;')\n .replace(/'/g, '&apos;')\n .replace(/\"/g, '&quot;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;');\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 = await fs.readFile(ctx.template, 'utf8');\n const modifiedTemplateXmlContent = replaceBloggerPluginHeadComment(originalTemplateXmlContent, headContent, true);\n\n await fs.writeFile(path.resolve(ctx.viteConfig.build.outDir, TEMPLATE_OUT_FILE), 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 await fs.writeFile(path.resolve(ctx.viteConfig.build.outDir, TEMPLATE_TAGS_OUT_FILE), 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 await fs.writeFile(path.resolve(ctx.viteConfig.build.outDir, TEMPLATE_MINIFIED_OUT_FILE), minifiedTemplateXmlContent);\n }\n },\n async closeBundle() {\n const htmlDir = path.resolve(ctx.viteConfig.build.outDir, 'virtual:blogger-plugin');\n\n const exists = await fsExists(htmlDir);\n\n if (exists) {\n await fs.rm(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 tailwindCache: TailwindCache | null;\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.tailwindCache = null;\n this.input = undefined as unknown as string;\n this.headTags = [];\n this.html = undefined as unknown as string;\n }\n\n async resolve(config: UserConfig): Promise<void> {\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 (await fsExists(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_MODULE_FILES) {\n const modulePath = path.resolve(this.root, module);\n if (await fsExists(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 (await fsExists(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 (await fsExists(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_TEMPLATE_FILES) {\n const fullPath = path.resolve(this.root, file);\n if (await fsExists(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_TEMPLATE_FILES].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(\n server: ViteDevServer | PreviewServer,\n ctx: BloggerPluginContext,\n _this: MinimalPluginContextWithoutEnvironment,\n): () => void {\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 url.pathname.startsWith('/@')\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.tailwindCache && isViteDevServer(server) && secFetchDestHeader === 'document' && secFetchModeHeader === 'navigate') {\n await ctx.tailwindCache.update(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 = await fs.readFile(path.resolve(ctx.viteConfig.build.outDir, TEMPLATE_OUT_FILE), '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.12",
3
+ "version": "0.0.13",
4
4
  "description": "A plugin which allows you to use frontend frameworks in a blogger template.",
5
5
  "keywords": [
6
6
  "blogger"
@@ -11,14 +11,14 @@
11
11
  "email": "deo@fineshopdesign.com",
12
12
  "url": "https://github.com/kumardeo"
13
13
  },
14
- "homepage": "https://github.com/bloggerkit/blogger-plugin/tree/main/packages/blogger-plugin#readme",
14
+ "homepage": "https://github.com/bloggerkit/bloggerkit/tree/main/packages/blogger-plugin#readme",
15
15
  "repository": {
16
16
  "type": "git",
17
- "url": "https://github.com/bloggerkit/blogger-plugin",
17
+ "url": "https://github.com/bloggerkit/bloggerkit",
18
18
  "directory": "packages/blogger-plugin"
19
19
  },
20
20
  "bugs": {
21
- "url": "https://github.com/bloggerkit/blogger-plugin/issues"
21
+ "url": "https://github.com/bloggerkit/bloggerkit/issues"
22
22
  },
23
23
  "publishConfig": {
24
24
  "access": "public",
@@ -59,11 +59,11 @@
59
59
  },
60
60
  "dependencies": {
61
61
  "minify-xml": "^4.5.2",
62
- "tailwindcss-iso": "^1.0.6"
62
+ "tailwindcss-iso": "^1.0.7"
63
63
  },
64
64
  "devDependencies": {
65
- "@types/node": "^25.7.0",
66
- "tsdown": "^0.22.0",
65
+ "@types/node": "^25.9.1",
66
+ "tsdown": "^0.22.1",
67
67
  "vite": "^7.0.0"
68
68
  },
69
69
  "scripts": {