blogger-plugin 0.0.7 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/vite.cjs CHANGED
@@ -1,568 +1,80 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } }// src/vite.ts
2
- var _fs = require('fs'); var fs2 = _interopRequireWildcard(_fs); var fs = _interopRequireWildcard(_fs);
3
- var _path = require('path'); var path2 = _interopRequireWildcard(_path); var path = _interopRequireWildcard(_path);
4
-
5
-
6
- var _vite = require('vite');
1
+ const require_runtime = require("./_virtual/_rolldown/runtime.cjs");
2
+ const require_constants = require("./constants.cjs");
3
+ const require_tailwind = require("./tailwind.cjs");
4
+ const require_utils = require("./utils.cjs");
5
+ let node_fs = require("node:fs");
6
+ node_fs = require_runtime.__toESM(node_fs, 1);
7
+ let node_path = require("node:path");
8
+ node_path = require_runtime.__toESM(node_path, 1);
9
+ //#region src/vite.ts
10
+ function blogger(userOptions) {
11
+ const ctx = new BloggerPluginContext(userOptions);
12
+ return {
13
+ name: "@blogger-plugin/vite",
14
+ config(config) {
15
+ var _config$build;
16
+ ctx.resolve(config);
17
+ config.build || (config.build = {});
18
+ (_config$build = config.build)[require_constants.VITE_BUNDLER_KEY] || (_config$build[require_constants.VITE_BUNDLER_KEY] = {});
19
+ const bundlerOptions = config.build[require_constants.VITE_BUNDLER_KEY];
20
+ if (Array.isArray(bundlerOptions.input)) bundlerOptions.input = [...bundlerOptions.input, ctx.input];
21
+ else if (typeof bundlerOptions.input === "object" && bundlerOptions.input !== null) bundlerOptions.input[ctx.input] = ctx.input;
22
+ else bundlerOptions.input = ctx.input;
23
+ const modifiedTemplateXmlContent = require_utils.replaceBloggerPluginHeadComment(require_utils.replaceBloggerPluginHeadComment(node_fs.readFileSync(ctx.template, "utf8"), ""), "", true);
24
+ node_fs.writeFileSync(ctx.template, modifiedTemplateXmlContent, "utf-8");
25
+ },
26
+ configResolved(config) {
27
+ ctx.viteConfig = config;
28
+ ctx.tailwind = config.plugins.flat(Number.POSITIVE_INFINITY).some((plugin) => require_utils.isTailwindPlugin(plugin));
29
+ if (ctx.tailwind) {
30
+ require_tailwind.clearTailwindCache(ctx.root);
31
+ if (config.command === "build") require_tailwind.updateTailwindCache(ctx.root, node_fs.readFileSync(ctx.template, "utf-8"));
32
+ } else require_tailwind.removeTailwindCache(ctx.root);
33
+ },
34
+ resolveId(source) {
35
+ if (source === ctx.input) return ctx.input;
36
+ },
37
+ load(id) {
38
+ if (id === ctx.input) return ctx.html;
39
+ },
40
+ buildStart() {
41
+ if (ctx.viteConfig.command === "build" && !/^https?:\/\//.test(ctx.viteConfig.base)) this.warn(`"base" should be a CDN URL in production
42
+ ----------------------
43
+ Blogger cannot serve static assets (JS, CSS, etc.), so you must use
44
+ an absolute URL (http:// or https://).
7
45
 
8
- // src/cache.ts
46
+ Current value:
47
+ base: "${ctx.viteConfig.base}"
9
48
 
49
+ Quick fix:
50
+ VITE_BASE=https://cdn.jsdelivr.net/gh/<username>/<repository>@latest/dist/ npm run build
10
51
 
11
- var _tailwindcssiso = require('tailwindcss-iso');
12
- var TAILWIND_CACHE_FILE = ".tailwind-classes.json";
13
- function readFileContent(file) {
14
- if (!fs.existsSync(file)) {
15
- return null;
16
- }
17
- return fs.readFileSync(file, "utf-8");
18
- }
19
- function writeFileContent(file, content) {
20
- const dirname2 = path.dirname(file);
21
- if (!fs.existsSync(dirname2)) {
22
- fs.mkdirSync(dirname2, { recursive: true });
23
- }
24
- const current = readFileContent(file);
25
- if (current === null || content !== current) {
26
- fs.writeFileSync(file, content, "utf8");
27
- return true;
28
- }
29
- return false;
30
- }
31
- function removeFile(file) {
32
- if (!fs.existsSync(file)) {
33
- return false;
34
- }
35
- fs.rmSync(file);
36
- return true;
37
- }
38
- function getTailwindCacheFile(root) {
39
- return path.resolve(root, TAILWIND_CACHE_FILE);
40
- }
41
- function readTailwindCache(root) {
42
- const content = readFileContent(getTailwindCacheFile(root));
43
- if (!content) {
44
- return null;
45
- }
46
- try {
47
- return JSON.parse(content);
48
- } catch (e) {
49
- return null;
50
- }
51
- }
52
- function writeTailwindCache(root, classes) {
53
- const file = getTailwindCacheFile(root);
54
- const content = JSON.stringify(classes, null, 2);
55
- const updated = writeFileContent(file, content);
56
- return { updated, content };
57
- }
58
- function clearTailwindCache(root) {
59
- writeTailwindCache(root, []);
60
- }
61
- function removeTailwindCache(root) {
62
- removeFile(getTailwindCacheFile(root));
63
- }
64
- async function updateTailwindCache(root, content) {
65
- var _a;
66
- const classes = await _tailwindcssiso.getTailwindClasses.call(void 0, {
67
- content
52
+ Vite config (recommended):
53
+ export default defineConfig({
54
+ base: process.env.VITE_BASE ?? "/"
68
55
  });
69
- writeTailwindCache(root, [.../* @__PURE__ */ new Set([...(_a = readTailwindCache(root)) != null ? _a : [], ...classes])]);
70
- }
71
56
 
72
- // src/constants.ts
73
- var DEFAULT_MODULES = [
74
- "src/index.tsx",
75
- "src/index.ts",
76
- "src/index.jsx",
77
- "src/index.js",
78
- "src/main.tsx",
79
- "src/main.ts",
80
- "src/main.jsx",
81
- "src/main.js"
82
- ];
83
- var DEFAULT_TEMPLATES = ["index.xml", "template.xml", "theme.xml", "src/index.xml", "src/template.xml", "src/theme.xml"];
84
-
85
- // src/utils.ts
86
- function escapeHtml(str) {
87
- if (str === "") return "";
88
- return str.replace(/[&<>"'`]/g, (ch) => {
89
- switch (ch) {
90
- case "&":
91
- return "&amp;";
92
- case "<":
93
- return "&lt;";
94
- case ">":
95
- return "&gt;";
96
- case '"':
97
- return "&quot;";
98
- case "'":
99
- return "&#39;";
100
- case "`":
101
- return "&#96;";
102
- default:
103
- return ch;
104
- }
105
- });
106
- }
107
- function escapeRegex(str) {
108
- return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
109
- }
110
- function toWebHeaders(httpHeaders) {
111
- const headers = new Headers();
112
- for (const [name, value] of Object.entries(httpHeaders)) {
113
- if (Array.isArray(value)) {
114
- for (const item of value) {
115
- headers.append(name, item);
116
- }
117
- } else {
118
- headers.set(name, String(value != null ? value : ""));
119
- }
120
- }
121
- return headers;
122
- }
123
- var BLOGGER_PLUGIN_HEAD_COMMENT_REGEX = /(<!--blogger-plugin:head:begin-->)([\s\S]*?)(<!--blogger-plugin:head:end-->)/;
124
- var BLOGGER_PLUGIN_HEAD_BCOMMENT_REGEX = /(<b:comment><!--blogger-plugin:head:begin--><\/b:comment>)([\s\S]*?)(<b:comment><!--blogger-plugin:head:end--><\/b:comment>)/;
125
- function replaceBloggerPluginHeadComment(input, replacement, bcomment = false) {
126
- if (bcomment) {
127
- return input.replace(BLOGGER_PLUGIN_HEAD_BCOMMENT_REGEX, (_, start, _content, end) => `${start}${replacement}${end}`);
128
- }
129
- return input.replace(BLOGGER_PLUGIN_HEAD_COMMENT_REGEX, (_, start, _content, end) => `${start}${replacement}${end}`);
130
- }
131
- function getBloggerPluginHeadComment(input, bcomment = false) {
132
- var _a, _b, _c, _d;
133
- if (bcomment) {
134
- return (_b = (_a = input.match(BLOGGER_PLUGIN_HEAD_BCOMMENT_REGEX)) == null ? void 0 : _a[2]) != null ? _b : null;
135
- }
136
- return (_d = (_c = input.match(BLOGGER_PLUGIN_HEAD_COMMENT_REGEX)) == null ? void 0 : _c[2]) != null ? _d : null;
137
- }
138
- function replaceHost(input, oldHost, newHost, newProtocol) {
139
- return input.replace(
140
- new RegExp(`(https?:)?(\\/\\/|\\\\/\\\\/)${escapeRegex(oldHost)}`, "g"),
141
- (_, protocol, slash) => `${protocol ? newProtocol != null ? newProtocol : protocol : ""}${slash != null ? slash : ""}${newHost}`
142
- );
143
- }
144
- function getRequestUrl(req) {
145
- const xForwardedProtoHeader = req.headers["x-forwarded-proto"];
146
- const xForwardedHostHeader = req.headers["x-forwarded-host"];
147
- const hostHeader = req.headers.host;
148
- const protocol = Array.isArray(xForwardedProtoHeader) ? xForwardedProtoHeader[0] : xForwardedProtoHeader != null ? xForwardedProtoHeader : req.socket && "encrypted" in req.socket && req.socket.encrypted ? "https" : "http";
149
- const host = Array.isArray(xForwardedHostHeader) ? xForwardedHostHeader[0] : xForwardedHostHeader != null ? xForwardedHostHeader : hostHeader;
150
- if (host && req.originalUrl) {
151
- return new URL(`${protocol}://${host}${req.originalUrl}`);
152
- }
153
- return null;
154
- }
155
- var TAILWIND_PLUGIN_NAMES = /* @__PURE__ */ new Set(["@tailwindcss/vite:scan"]);
156
- function isTailwindPlugin(plugin) {
157
- return TAILWIND_PLUGIN_NAMES.has(plugin.name);
158
- }
159
- function errorHtml(reqUrl) {
160
- return `<!DOCTYPE html>
161
- <html>
162
-
163
- <head>
164
- <meta charset='UTF-8'/>
165
- <meta content='width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=5, user-scalable=yes' name='viewport'/>
166
- <title>500 Internal Server Error</title>
167
- <link rel='icon' href='data:,' />
168
- <style>
169
- *, ::before, ::after {
170
- box-sizing: border-box;
171
- }
172
- body {
173
- min-height: 100svh;
174
- display: flex;
175
- flex-direction: column;
176
- align-items: center;
177
- justify-content: center;
178
- margin: 0;
179
- padding: 20px;
180
- background-color: #f5f5f5;
181
- 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";
182
- }
183
- .card {
184
- padding: 24px;
185
- background-color: #ffffff;
186
- border: 1px solid #e5e5e5;
187
- max-width: 448px;
188
- border-radius: 14px;
189
- box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);
190
- display: flex;
191
- flex-direction: column;
192
- gap: 24px;
193
- }
194
- .card-content {
195
- display: flex;
196
- flex-direction: column;
197
- gap: 6px;
198
- }
199
- .card-title {
200
- font-weight: 600;
201
- }
202
- .card-description {
203
- font-size: 14px;
204
- opacity: 0.85;
205
- }
206
- .card-footer {
207
- display: flex;
208
- align-items: center;
209
- }
210
- .button {
211
- display: inline-flex;
212
- white-space: nowrap;
213
- align-items: center;
214
- justify-content: center;
215
- gap: 8px;
216
- padding: 8px 16px;
217
- font-weight: 500;
218
- background-color: #171717;
219
- outline: none;
220
- border: none;
221
- color: #ffffff;
222
- border-radius: 8px;
223
- min-height: 36px;
224
- }
225
- .button:hover {
226
- opacity: 0.9;
227
- }
228
- .button svg {
229
- wiheadersdth: 16px;
230
- height: 16px;
231
- flex-shrink: 0;
232
- }
233
- .card-footer .button {
234
- flex-grow: 1;
235
- }
236
- </style>
237
- </head>
238
-
239
- <body>
240
- <div class='card'>
241
- <div class='card-content'>
242
- <div class='card-title'>500 Internal Server Error</div>
243
- <div class='card-description'>Failed to fetch: ${escapeHtml(reqUrl)}</div>
244
- </div>
245
- <div class='card-footer'>
246
- <button class='button' type='button'>
247
- <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>
248
- Reload
249
- </button>
250
- </div>
251
- </div>
252
- <script>
253
- const button = document.getElementsByTagName('button')[0];
254
- button.addEventListener('click', () => {
255
- window.location.reload();
256
- });
257
- </script>
258
- </body>
259
-
260
- </html>`;
261
- }
262
-
263
- // src/vite.ts
264
- var viteMajor = Number(_vite.version.split(".")[0]);
265
- var bundlerKey = viteMajor >= 8 ? "rolldownOptions" : "rollupOptions";
266
- var BloggerPluginContext = class {
267
- constructor(options) {
268
- if (typeof options.template !== "undefined" && typeof options.template !== "string") {
269
- throw new Error("Option 'template' must be a string");
270
- }
271
- if (typeof options.modules !== "undefined" && !Array.isArray(options.modules)) {
272
- throw new Error("Option 'modules' must be an array");
273
- }
274
- if (typeof options.styles !== "undefined" && !Array.isArray(options.styles)) {
275
- throw new Error("Option 'styles' must be an array");
276
- }
277
- if (typeof options.proxyBlog !== "string") {
278
- throw new Error("Option 'proxyBlog' must be a string");
279
- }
280
- let proxyBlog;
281
- try {
282
- proxyBlog = new URL(options.proxyBlog);
283
- } catch (e) {
284
- throw new Error("Option 'proxyBlog' must be a valid url");
285
- }
286
- this.options = options;
287
- this.root = process.cwd();
288
- this.modules = [];
289
- this.styles = [];
290
- this.template = void 0;
291
- this.name = void 0;
292
- this.proxyBlog = proxyBlog;
293
- this.viteConfig = void 0;
294
- this.tailwind = false;
295
- this.input = void 0;
296
- this.headTags = [];
297
- this.html = void 0;
298
- }
299
- resolve(config) {
300
- this.root = config.root ? path2.resolve(config.root) : this.root;
301
- if (this.options.modules) {
302
- for (let i = 0; i < this.options.modules.length; i++) {
303
- const module = this.options.modules[i];
304
- const modulePath = path2.resolve(this.root, module);
305
- if (this.modules.includes(modulePath)) {
306
- continue;
307
- }
308
- if (fs2.existsSync(modulePath)) {
309
- this.modules.push(modulePath);
310
- } else {
311
- throw new Error(`The path provided at modules[${i}] does not exist: ${modulePath}`);
312
- }
313
- }
314
- } else {
315
- for (const module of DEFAULT_MODULES) {
316
- const modulePath = path2.resolve(this.root, module);
317
- if (fs2.existsSync(modulePath)) {
318
- this.modules.push(modulePath);
319
- break;
320
- }
321
- }
322
- }
323
- if (this.options.styles) {
324
- for (let i = 0; i < this.options.styles.length; i++) {
325
- const style = this.options.styles[i];
326
- const stylePath = path2.resolve(this.root, style);
327
- if (this.styles.includes(stylePath)) {
328
- continue;
329
- }
330
- if (fs2.existsSync(stylePath)) {
331
- this.styles.push(stylePath);
332
- } else {
333
- throw new Error(`The path provided at styles[${i}] does not exist: ${stylePath}`);
334
- }
335
- }
336
- }
337
- if (this.options.template) {
338
- const templatePath = path2.resolve(this.root, this.options.template);
339
- if (fs2.existsSync(templatePath)) {
340
- this.template = templatePath;
341
- } else {
342
- throw new Error(`Provided template file does not exist: ${templatePath}`);
343
- }
344
- } else {
345
- for (const file of DEFAULT_TEMPLATES) {
346
- const fullPath = path2.resolve(this.root, file);
347
- if (fs2.existsSync(fullPath)) {
348
- this.template = fullPath;
349
- break;
350
- }
351
- }
352
- if (!this.template) {
353
- throw new Error(
354
- `No template file found.
355
- Tried: ${DEFAULT_TEMPLATES.join(", ")}
356
- \u{1F449} Tip: You can pass a custom template as shown:
357
- blogger({ template: "src/my-template.xml" })`
358
- );
359
- }
360
- }
361
- this.name = path2.basename(this.template, path2.extname(this.template));
362
- for (const modulePath of this.modules) {
363
- this.headTags.push(`<script type="module" src="/${path2.relative(this.root, modulePath).replaceAll("\\", "/")}"></script>`);
364
- }
365
- for (const stylePath of this.styles) {
366
- this.headTags.push(`<link rel="stylesheet" href="/${path2.relative(this.root, stylePath).replaceAll("\\", "/")}">`);
367
- }
368
- this.input = `virtual:blogger-plugin/${this.name}.html`;
369
- this.html = `<!DOCTYPE html>
370
- <html>
371
- <head>
372
- <!--head-->${this.headTags.length > 0 ? `
373
- ${this.headTags.join("\n ")}` : ""}
374
- </head>
375
- <body>
376
- <!--body-->
377
- </body>
378
- </html>`;
379
- }
380
- };
381
- function isViteDevServer(server) {
382
- return "hot" in server && "transformRequest" in server && "transformIndexHtml" in server;
383
- }
384
- function useServerMiddleware(server, ctx, _this) {
385
- const input = ctx.viteConfig.build[bundlerKey].input;
386
- const htmlPathnames = [];
387
- for (const entry of Array.isArray(input) ? input : typeof input === "object" ? Object.values(input) : typeof input === "string" ? [input] : []) {
388
- if (entry === ctx.input) {
389
- continue;
390
- }
391
- const entryPath = path2.resolve(ctx.root, entry);
392
- if (!entryPath.endsWith(".html")) {
393
- continue;
394
- }
395
- const relativePath = path2.relative(ctx.root, entry).replaceAll("\\", "/");
396
- htmlPathnames.push(`/${relativePath}`);
397
- if (relativePath.endsWith("index.html")) {
398
- htmlPathnames.push(`/${relativePath.replace(/index\.html$/, "")}`);
399
- }
400
- }
401
- return () => {
402
- var _a;
403
- (_a = server.httpServer) == null ? void 0 : _a.once("listening", () => {
404
- setTimeout(() => {
405
- _this.info(`Unhandled requests will be proxied to ${ctx.proxyBlog.origin}`);
406
- }, 0);
407
- });
408
- server.middlewares.use(async (req, res, next) => {
409
- const url = getRequestUrl(req);
410
- if (!req.url || !req.originalUrl || !url || !req.method || !["GET", "HEAD"].includes(req.method.toUpperCase()) || htmlPathnames.includes(url.pathname.replace(/\/+/g, "/"))) {
411
- next();
412
- return;
413
- }
414
- const start = Date.now();
415
- const proxyUrl = new URL(`${ctx.proxyBlog.origin}${req.originalUrl}`);
416
- const viewParam = proxyUrl.searchParams.get("view");
417
- proxyUrl.searchParams.set("view", `${isViteDevServer(server) ? "-DevServer" : "-PreviewServer"}${(viewParam == null ? void 0 : viewParam.startsWith("-")) ? viewParam : ""}`);
418
- const proxyRequest = new Request(proxyUrl, {
419
- method: req.method,
420
- headers: toWebHeaders(req.headers),
421
- redirect: "manual"
422
- });
423
- const proxyResponse = await fetch(proxyRequest).catch((error) => {
424
- if (error instanceof Error) {
425
- _this.warn({
426
- message: `${error.name}: ${error.message}`,
427
- cause: error.cause,
428
- stack: error.stack
429
- });
430
- } else {
431
- _this.warn("Fetch failed");
432
- }
433
- return null;
434
- });
435
- if (proxyResponse) {
436
- res.statusCode = proxyResponse.status;
437
- res.statusMessage = proxyResponse.statusText;
438
- proxyResponse.headers.forEach((value, key) => {
439
- var _a2;
440
- if (key === "location") {
441
- const redirectUrl = new URL(value, proxyUrl);
442
- if (redirectUrl.host === url.host || redirectUrl.host === proxyUrl.host) {
443
- redirectUrl.host = url.host;
444
- redirectUrl.protocol = url.protocol;
445
- const viewParam2 = (_a2 = redirectUrl.searchParams.get("view")) == null ? void 0 : _a2.replaceAll("-DevServer", "").replaceAll("-PreviewServer", "");
446
- if (viewParam2) {
447
- redirectUrl.searchParams.set("view", viewParam2);
448
- } else {
449
- redirectUrl.searchParams.delete("view");
450
- }
451
- res.setHeader("location", redirectUrl.pathname + redirectUrl.search + redirectUrl.hash);
452
- } else {
453
- res.setHeader("location", redirectUrl.href);
454
- }
455
- } else if (["content-type", "x-robots-tag", "date", "location"].includes(key)) {
456
- res.setHeader(key, value);
457
- }
458
- });
459
- const contentType = proxyResponse.headers.get("content-type");
460
- if (contentType == null ? void 0 : contentType.startsWith("text/html")) {
461
- let htmlTemplateContent = await proxyResponse.text();
462
- const secFetchDestHeader = req.headers["sec-fetch-dest"];
463
- const secFetchModeHeader = req.headers["sec-fetch-mode"];
464
- if (ctx.tailwind && isViteDevServer(server) && secFetchDestHeader === "document" && secFetchModeHeader === "navigate") {
465
- await updateTailwindCache(ctx.root, htmlTemplateContent);
466
- }
467
- htmlTemplateContent = replaceHost(htmlTemplateContent, proxyUrl.host, url.host, url.protocol);
468
- if (isViteDevServer(server)) {
469
- const template = await server.transformIndexHtml(
470
- req.url,
471
- replaceBloggerPluginHeadComment(htmlTemplateContent, ctx.headTags.join("")),
472
- req.originalUrl
473
- );
474
- res.end(template);
475
- } else {
476
- const xmlTemplateContent = fs2.readFileSync(path2.resolve(ctx.viteConfig.build.outDir, "template.xml"), "utf8");
477
- const htmlTagsStr = getBloggerPluginHeadComment(xmlTemplateContent, true);
478
- const template = replaceBloggerPluginHeadComment(htmlTemplateContent, htmlTagsStr != null ? htmlTagsStr : "");
479
- res.end(template);
480
- }
481
- } else if (contentType && /^(text\/)|(application\/(.*\+)?(xml|json))/.test(contentType)) {
482
- const content = await proxyResponse.text();
483
- res.end(replaceHost(content, proxyUrl.host, url.host, url.protocol));
484
- } else {
485
- res.end(new Uint8Array(await proxyResponse.arrayBuffer()));
486
- }
487
- } else {
488
- res.statusCode = 500;
489
- res.statusMessage = "Internal Server Error";
490
- res.setHeader("Content-Type", "text/html");
491
- res.end(errorHtml(proxyUrl.href));
492
- }
493
- const duration = Date.now() - start;
494
- _this.info(`${req.method} ${req.originalUrl} -> ${res.statusCode} ${res.statusMessage} (${duration}ms)`);
495
- });
496
- };
497
- }
498
- function blogger(userOptions) {
499
- const ctx = new BloggerPluginContext(userOptions);
500
- return {
501
- name: "vite-plugin-blogger",
502
- config(config) {
503
- var _a;
504
- ctx.resolve(config);
505
- config.build || (config.build = {});
506
- (_a = config.build)[bundlerKey] || (_a[bundlerKey] = {});
507
- const bundlerOptions = config.build[bundlerKey];
508
- if (Array.isArray(bundlerOptions.input)) {
509
- bundlerOptions.input = [...bundlerOptions.input, ctx.input];
510
- } else if (typeof bundlerOptions.input === "object" && bundlerOptions.input !== null) {
511
- bundlerOptions.input[ctx.input] = ctx.input;
512
- } else {
513
- bundlerOptions.input = ctx.input;
514
- }
515
- const originalTemplateXmlContent = fs2.readFileSync(ctx.template, "utf8");
516
- const modifiedTemplateXmlContent = replaceBloggerPluginHeadComment(replaceBloggerPluginHeadComment(originalTemplateXmlContent, ""), "", true);
517
- fs2.writeFileSync(ctx.template, modifiedTemplateXmlContent, "utf-8");
518
- },
519
- configResolved(config) {
520
- ctx.viteConfig = config;
521
- ctx.tailwind = config.plugins.flat(Number.POSITIVE_INFINITY).some((plugin) => isTailwindPlugin(plugin));
522
- if (ctx.tailwind) {
523
- clearTailwindCache(ctx.root);
524
- if (config.command === "build") {
525
- updateTailwindCache(ctx.root, fs2.readFileSync(ctx.template, "utf-8"));
526
- }
527
- } else {
528
- removeTailwindCache(ctx.root);
529
- }
530
- },
531
- resolveId(source) {
532
- if (source === ctx.input) {
533
- return ctx.input;
534
- }
535
- },
536
- load(id) {
537
- if (id === ctx.input) {
538
- return ctx.html;
539
- }
540
- },
541
- writeBundle(_, bundle) {
542
- if (!(ctx.input in bundle)) {
543
- return;
544
- }
545
- const asset = bundle[ctx.input];
546
- delete bundle[ctx.input];
547
- if (asset.type !== "asset" || typeof asset.source !== "string") {
548
- return;
549
- }
550
- const regex = /<!DOCTYPE html>\s*<html[^>]*>\s*<head>([\s\S]*?)<!--head-->([\s\S]*?)<\/head>\s*<body>([\s\S]*?)<!--body-->([\s\S]*?)<\/body>\s*<\/html>/i;
551
- const match = asset.source.match(regex);
552
- if (!match) {
553
- return;
554
- }
555
- const afterHeadBegin = match[1];
556
- const beforeHeadEnd = match[2];
557
- const afterBodyBegin = match[3];
558
- const beforeBodyEnd = match[4];
559
- const headContent = (afterHeadBegin + beforeHeadEnd).replace(/\b(crossorigin|defer|async|disabled|checked)\b(?!=)/g, (_2, $1) => `${$1}=""`).replace(/(\w+)=(".*?"|'.*?')/g, (_2, $1, $2) => {
560
- const v = $2.slice(1, -1).replace(/&/g, "&amp;").replace(/'/g, "&apos;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
561
- return `${$1}='${v}'`;
562
- }).replace(/<(link|meta|img|br|hr|input)([^>]*?)>/gi, (_2, $1, $2) => `<${$1}${$2} />`).replace(/>\s+</g, "><").trim();
563
- const originalTemplateXmlContent = fs2.readFileSync(ctx.template, "utf8");
564
- const modifiedTemplateXmlContent = replaceBloggerPluginHeadComment(originalTemplateXmlContent, headContent, true);
565
- const templateTagsXmlContent = `<?xml version="1.0" encoding="UTF-8" ?>
57
+ Without this, your assets may fail to load in Blogger.
58
+ ----------------------`);
59
+ },
60
+ writeBundle(_, bundle) {
61
+ if (!(ctx.input in bundle)) return;
62
+ const asset = bundle[ctx.input];
63
+ delete bundle[ctx.input];
64
+ if (asset.type !== "asset" || typeof asset.source !== "string") return;
65
+ const match = asset.source.match(/<!DOCTYPE html>\s*<html[^>]*>\s*<head>([\s\S]*?)<!--head-->([\s\S]*?)<\/head>\s*<body>([\s\S]*?)<!--body-->([\s\S]*?)<\/body>\s*<\/html>/i);
66
+ if (!match) return;
67
+ const afterHeadBegin = match[1];
68
+ const beforeHeadEnd = match[2];
69
+ const afterBodyBegin = match[3];
70
+ const beforeBodyEnd = match[4];
71
+ const headContent = (afterHeadBegin + beforeHeadEnd).replace(/<[^>]+>/g, (openingTag) => {
72
+ return openingTag.replace(/\b(crossorigin|defer|async|disabled|checked)\b(?!\s*=)/g, (_, $1) => $1 === "crossorigin" ? "crossorigin=\"anonymous\"" : `${$1}=""`).replace(/(\w+)=(".*?"|'.*?')/g, (_, $1, $2) => {
73
+ return `${$1}='${$2.slice(1, -1).replace(/&/g, "&amp;").replace(/'/g, "&apos;").replace(/"/g, "&quot;").replace(/</g, "&lt;").replace(/>/g, "&gt;")}'`;
74
+ });
75
+ }).replace(/<(link|meta|img|br|hr|input)([^>]*?)>/gi, (_, $1, $2) => `<${$1}${$2}/>`).replace(/>\s+</g, "><").trim();
76
+ const modifiedTemplateXmlContent = require_utils.replaceBloggerPluginHeadComment(node_fs.readFileSync(ctx.template, "utf8"), headContent, true);
77
+ const templateTagsXmlContent = `<?xml version="1.0" encoding="UTF-8" ?>
566
78
  <!DOCTYPE html>
567
79
  <html>
568
80
  <head>
@@ -584,24 +96,197 @@ function blogger(userOptions) {
584
96
  <!--body:beforeend:end-->
585
97
  </body>
586
98
  </html>`;
587
- fs2.writeFileSync(path2.resolve(ctx.viteConfig.build.outDir, "template.xml"), modifiedTemplateXmlContent);
588
- fs2.writeFileSync(path2.resolve(ctx.viteConfig.build.outDir, "template-tags.xml"), templateTagsXmlContent);
589
- },
590
- closeBundle() {
591
- const htmlDir = path2.resolve(ctx.viteConfig.build.outDir, "virtual:blogger-plugin");
592
- if (fs2.existsSync(htmlDir)) {
593
- fs2.rmSync(htmlDir, { recursive: true });
594
- }
595
- },
596
- configureServer(server) {
597
- return useServerMiddleware(server, ctx, this);
598
- },
599
- configurePreviewServer(server) {
600
- return useServerMiddleware(server, ctx, this);
601
- }
602
- };
99
+ node_fs.writeFileSync(node_path.resolve(ctx.viteConfig.build.outDir, "template.xml"), modifiedTemplateXmlContent);
100
+ node_fs.writeFileSync(node_path.resolve(ctx.viteConfig.build.outDir, "template-tags.xml"), templateTagsXmlContent);
101
+ },
102
+ closeBundle() {
103
+ const htmlDir = node_path.resolve(ctx.viteConfig.build.outDir, "virtual:blogger-plugin");
104
+ if (node_fs.existsSync(htmlDir)) node_fs.rmSync(htmlDir, { recursive: true });
105
+ },
106
+ configureServer(server) {
107
+ return useServerMiddleware(server, ctx, this);
108
+ },
109
+ configurePreviewServer(server) {
110
+ return useServerMiddleware(server, ctx, this);
111
+ }
112
+ };
603
113
  }
114
+ var BloggerPluginContext = class {
115
+ constructor(options) {
116
+ if (typeof options.template !== "undefined" && typeof options.template !== "string") throw new Error("Option 'template' must be a string");
117
+ if (typeof options.modules !== "undefined" && !Array.isArray(options.modules)) throw new Error("Option 'modules' must be an array");
118
+ if (typeof options.styles !== "undefined" && !Array.isArray(options.styles)) throw new Error("Option 'styles' must be an array");
119
+ if (typeof options.proxyBlog !== "string") throw new Error("Option 'proxyBlog' must be a string");
120
+ let proxyBlog;
121
+ try {
122
+ proxyBlog = new URL(options.proxyBlog);
123
+ } catch (_unused) {
124
+ throw new Error("Option 'proxyBlog' must be a valid url");
125
+ }
126
+ this.options = options;
127
+ this.root = process.cwd();
128
+ this.modules = [];
129
+ this.styles = [];
130
+ this.template = void 0;
131
+ this.name = void 0;
132
+ this.proxyBlog = proxyBlog;
133
+ this.viteConfig = void 0;
134
+ this.tailwind = false;
135
+ this.input = void 0;
136
+ this.headTags = [];
137
+ this.html = void 0;
138
+ }
139
+ resolve(config) {
140
+ this.root = config.root ? node_path.resolve(config.root) : this.root;
141
+ if (this.options.modules) for (let i = 0; i < this.options.modules.length; i++) {
142
+ const module = this.options.modules[i];
143
+ const modulePath = node_path.resolve(this.root, module);
144
+ if (this.modules.includes(modulePath)) continue;
145
+ if (node_fs.existsSync(modulePath)) this.modules.push(modulePath);
146
+ else throw new Error(`The path provided at modules[${i}] does not exist: ${modulePath}`);
147
+ }
148
+ else for (const module of require_constants.DEFAULT_MODULES) {
149
+ const modulePath = node_path.resolve(this.root, module);
150
+ if (node_fs.existsSync(modulePath)) {
151
+ this.modules.push(modulePath);
152
+ break;
153
+ }
154
+ }
155
+ if (this.options.styles) for (let i = 0; i < this.options.styles.length; i++) {
156
+ const style = this.options.styles[i];
157
+ const stylePath = node_path.resolve(this.root, style);
158
+ if (this.styles.includes(stylePath)) continue;
159
+ if (node_fs.existsSync(stylePath)) this.styles.push(stylePath);
160
+ else throw new Error(`The path provided at styles[${i}] does not exist: ${stylePath}`);
161
+ }
162
+ if (this.options.template) {
163
+ const templatePath = node_path.resolve(this.root, this.options.template);
164
+ if (node_fs.existsSync(templatePath)) this.template = templatePath;
165
+ else throw new Error(`Provided template file does not exist: ${templatePath}`);
166
+ } else {
167
+ for (const file of require_constants.DEFAULT_TEMPLATES) {
168
+ const fullPath = node_path.resolve(this.root, file);
169
+ if (node_fs.existsSync(fullPath)) {
170
+ this.template = fullPath;
171
+ break;
172
+ }
173
+ }
174
+ if (!this.template) throw new Error(`No template file found.
175
+ Tried: ${require_constants.DEFAULT_TEMPLATES.join(", ")}\nšŸ‘‰ Tip: You can pass a custom template as shown:
176
+ blogger({ template: "src/my-template.xml" })`);
177
+ }
178
+ this.name = node_path.basename(this.template, node_path.extname(this.template));
179
+ for (const modulePath of this.modules) this.headTags.push(`<script type="module" src="/${node_path.relative(this.root, modulePath).replaceAll("\\", "/")}"><\/script>`);
180
+ for (const stylePath of this.styles) this.headTags.push(`<link rel="stylesheet" href="/${node_path.relative(this.root, stylePath).replaceAll("\\", "/")}">`);
181
+ this.input = `virtual:blogger-plugin/${this.name}.html`;
182
+ this.html = `<!DOCTYPE html>
183
+ <html>
184
+ <head>
185
+ <!--head-->${this.headTags.length > 0 ? `\n ${this.headTags.join("\n ")}` : ""}
186
+ </head>
187
+ <body>
188
+ <!--body-->
189
+ </body>
190
+ </html>`;
191
+ }
192
+ };
193
+ function useServerMiddleware(server, ctx, _this) {
194
+ const input = ctx.viteConfig.build[require_constants.VITE_BUNDLER_KEY].input;
195
+ const htmlPathnames = [];
196
+ for (const entry of Array.isArray(input) ? input : typeof input === "object" ? Object.values(input) : typeof input === "string" ? [input] : []) {
197
+ if (entry === ctx.input) continue;
198
+ if (!node_path.resolve(ctx.root, entry).endsWith(".html")) continue;
199
+ const relativePath = node_path.relative(ctx.root, entry).replaceAll("\\", "/");
200
+ htmlPathnames.push(`/${relativePath}`);
201
+ if (relativePath.endsWith("index.html")) htmlPathnames.push(`/${relativePath.replace(/index\.html$/, "")}`);
202
+ }
203
+ return () => {
204
+ var _server$httpServer;
205
+ (_server$httpServer = server.httpServer) === null || _server$httpServer === void 0 || _server$httpServer.once("listening", () => {
206
+ setTimeout(() => {
207
+ _this.info(`Unhandled requests will be proxied to ${ctx.proxyBlog.origin}`);
208
+ }, 0);
209
+ });
210
+ server.middlewares.use(async (req, res, next) => {
211
+ const url = require_utils.getRequestUrl(req);
212
+ if (!req.url || !req.originalUrl || !url || !req.method || !["GET", "HEAD"].includes(req.method.toUpperCase()) || htmlPathnames.includes(url.pathname.replace(/\/+/g, "/"))) {
213
+ next();
214
+ return;
215
+ }
216
+ const start = Date.now();
217
+ const proxyUrl = new URL(`${ctx.proxyBlog.origin}${req.originalUrl}`);
218
+ const viewParam = proxyUrl.searchParams.get("view");
219
+ proxyUrl.searchParams.set("view", `${isViteDevServer(server) ? "-DevServer" : "-PreviewServer"}${(viewParam === null || viewParam === void 0 ? void 0 : viewParam.startsWith("-")) ? viewParam : ""}`);
220
+ const proxyRequest = new Request(proxyUrl, {
221
+ method: req.method,
222
+ headers: require_utils.toWebHeaders(req.headers),
223
+ redirect: "manual"
224
+ });
225
+ const proxyResponse = await fetch(proxyRequest).catch((error) => {
226
+ if (error instanceof Error) _this.warn({
227
+ message: `${error.name}: ${error.message}`,
228
+ cause: error.cause,
229
+ stack: error.stack
230
+ });
231
+ else _this.warn("Fetch failed");
232
+ return null;
233
+ });
234
+ if (proxyResponse) {
235
+ res.statusCode = proxyResponse.status;
236
+ res.statusMessage = proxyResponse.statusText;
237
+ proxyResponse.headers.forEach((value, key) => {
238
+ if (key === "location") {
239
+ const redirectUrl = new URL(value, proxyUrl);
240
+ if (redirectUrl.host === url.host || redirectUrl.host === proxyUrl.host) {
241
+ var _redirectUrl$searchPa;
242
+ redirectUrl.host = url.host;
243
+ redirectUrl.protocol = url.protocol;
244
+ const viewParam = (_redirectUrl$searchPa = redirectUrl.searchParams.get("view")) === null || _redirectUrl$searchPa === void 0 ? void 0 : _redirectUrl$searchPa.replaceAll("-DevServer", "").replaceAll("-PreviewServer", "");
245
+ if (viewParam) redirectUrl.searchParams.set("view", viewParam);
246
+ else redirectUrl.searchParams.delete("view");
247
+ res.setHeader("location", redirectUrl.pathname + redirectUrl.search + redirectUrl.hash);
248
+ } else res.setHeader("location", redirectUrl.href);
249
+ } else if ([
250
+ "content-type",
251
+ "x-robots-tag",
252
+ "date",
253
+ "location"
254
+ ].includes(key)) res.setHeader(key, value);
255
+ });
256
+ const contentType = proxyResponse.headers.get("content-type");
257
+ if (contentType === null || contentType === void 0 ? void 0 : contentType.startsWith("text/html")) {
258
+ let htmlTemplateContent = await proxyResponse.text();
259
+ const secFetchDestHeader = req.headers["sec-fetch-dest"];
260
+ const secFetchModeHeader = req.headers["sec-fetch-mode"];
261
+ if (ctx.tailwind && isViteDevServer(server) && secFetchDestHeader === "document" && secFetchModeHeader === "navigate") await require_tailwind.updateTailwindCache(ctx.root, htmlTemplateContent);
262
+ htmlTemplateContent = require_utils.replaceHost(htmlTemplateContent, proxyUrl.host, url.host, url.protocol);
263
+ if (isViteDevServer(server)) {
264
+ const template = await server.transformIndexHtml(req.url, require_utils.replaceBloggerPluginHeadComment(htmlTemplateContent, ctx.headTags.join("")), req.originalUrl);
265
+ res.end(template);
266
+ } else {
267
+ const htmlTagsStr = require_utils.getBloggerPluginHeadComment(node_fs.readFileSync(node_path.resolve(ctx.viteConfig.build.outDir, "template.xml"), "utf8"), true);
268
+ const template = require_utils.replaceBloggerPluginHeadComment(htmlTemplateContent, htmlTagsStr !== null && htmlTagsStr !== void 0 ? htmlTagsStr : "");
269
+ res.end(template);
270
+ }
271
+ } else if (contentType && /^(text\/)|(application\/(.*\+)?(xml|json))/.test(contentType)) {
272
+ const content = await proxyResponse.text();
273
+ res.end(require_utils.replaceHost(content, proxyUrl.host, url.host, url.protocol));
274
+ } else res.end(new Uint8Array(await proxyResponse.arrayBuffer()));
275
+ } else {
276
+ res.statusCode = 500;
277
+ res.statusMessage = "Internal Server Error";
278
+ res.setHeader("Content-Type", "text/html");
279
+ res.end(require_utils.errorHtml(proxyUrl.href));
280
+ }
281
+ const duration = Date.now() - start;
282
+ _this.info(`${req.method} ${req.originalUrl} -> ${res.statusCode} ${res.statusMessage} (${duration}ms)`);
283
+ });
284
+ };
285
+ }
286
+ function isViteDevServer(server) {
287
+ return "hot" in server && "transformRequest" in server && "transformIndexHtml" in server;
288
+ }
289
+ //#endregion
290
+ module.exports = blogger;
604
291
 
605
-
606
- exports.default = blogger;
607
292
  //# sourceMappingURL=vite.cjs.map