blogger-plugin 0.0.11 → 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":"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"}