@daz4126/swifty 3.2.0 → 4.2.0

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/src/urls.js ADDED
@@ -0,0 +1,116 @@
1
+ import path from "path";
2
+
3
+ import { defaultConfig } from "./config.js";
4
+
5
+ const normalizeBasePath = (value = defaultConfig.base_path) => {
6
+ if (!value || value === "/") return "";
7
+ if (typeof value !== "string") {
8
+ throw new TypeError("base_path must be a string");
9
+ }
10
+
11
+ const normalized = `/${value}`.replace(/\/+/g, "/").replace(/\/$/, "");
12
+ if (normalized.includes("..") || /[?#]/.test(normalized)) {
13
+ throw new Error(`Invalid base_path: ${value}`);
14
+ }
15
+ return normalized;
16
+ };
17
+
18
+ const withBasePath = (url, basePath = defaultConfig.base_path) => {
19
+ if (typeof url !== "string" || !url.startsWith("/") || url.startsWith("//")) {
20
+ return url;
21
+ }
22
+
23
+ const base = normalizeBasePath(basePath);
24
+ if (!base || url === base || url.startsWith(`${base}/`)) return url;
25
+ return url === "/" ? `${base}/` : `${base}${url}`;
26
+ };
27
+
28
+ const withoutBasePath = (url, basePath = defaultConfig.base_path) => {
29
+ const base = normalizeBasePath(basePath);
30
+ if (!base || typeof url !== "string") return url;
31
+ if (url === base || url === `${base}/`) return "/";
32
+ return url.startsWith(`${base}/`) ? url.slice(base.length) : url;
33
+ };
34
+
35
+ const normalizePermalink = (value) => {
36
+ if (typeof value !== "string" || !value.trim()) {
37
+ throw new TypeError("permalink must be a non-empty string");
38
+ }
39
+ if (/^(?:[a-z]+:)?\/\//i.test(value.trim())) {
40
+ throw new Error(`Invalid permalink: ${value}`);
41
+ }
42
+
43
+ const route = `/${value.trim()}`
44
+ .replace(/\\/g, "/")
45
+ .replace(/\/{2,}/g, "/")
46
+ .replace(/\/$/, "") || "/";
47
+ if (route.split("/").includes("..") || /[?#]/.test(route)) {
48
+ throw new Error(`Invalid permalink: ${value}`);
49
+ }
50
+ return route;
51
+ };
52
+
53
+ const routeToOutputPath = (route) => {
54
+ const normalized = normalizePermalink(route);
55
+ if (normalized === "/") return "index.html";
56
+
57
+ const relativeRoute = normalized.replace(/^\/+/, "");
58
+ return path.extname(relativeRoute)
59
+ ? relativeRoute
60
+ : path.join(relativeRoute, "index.html");
61
+ };
62
+
63
+ const applyBasePathToHtml = (html, basePath = defaultConfig.base_path) => {
64
+ const base = normalizeBasePath(basePath);
65
+ if (!base) return html;
66
+
67
+ const protectedBlocks = [];
68
+ const protectedHtml = html.replace(
69
+ /(<(script|style|pre|code)\b[^>]*>)([\s\S]*?)(<\/\2>)/gi,
70
+ (block, opening, tagName, content, closing) => {
71
+ const token = `__SWIFTY_BASE_PATH_BLOCK_${protectedBlocks.length}__`;
72
+ protectedBlocks.push(content);
73
+ return `${opening}${token}${closing}`;
74
+ },
75
+ );
76
+
77
+ const rewritten = protectedHtml
78
+ .replace(
79
+ /\b(href|src|action|poster)=(['"])(\/(?!\/)[^'"]*)\2/gi,
80
+ (attribute, name, quote, url) =>
81
+ `${name}=${quote}${withBasePath(url, base)}${quote}`,
82
+ )
83
+ .replace(/\bsrcset=(['"])(.*?)\1/gi, (attribute, quote, value) => {
84
+ if (!/(?:^|,)\s*\//.test(value)) return attribute;
85
+ const nextValue = value.replace(
86
+ /(^|,\s*)(\/(?!\/)[^\s,]+)/g,
87
+ (candidate, prefix, url) => `${prefix}${withBasePath(url, base)}`,
88
+ );
89
+ return `srcset=${quote}${nextValue}${quote}`;
90
+ });
91
+
92
+ return rewritten.replace(
93
+ /__SWIFTY_BASE_PATH_BLOCK_(\d+)__/g,
94
+ (token, index) => protectedBlocks[index],
95
+ );
96
+ };
97
+
98
+ const applyBasePathToCss = (css, basePath = defaultConfig.base_path) => {
99
+ const base = normalizeBasePath(basePath);
100
+ if (!base) return css;
101
+
102
+ return css.replace(
103
+ /url\(\s*(['"]?)(\/(?!\/)[^)'"\s]+)\1\s*\)/gi,
104
+ (value, quote, url) => `url(${quote}${withBasePath(url, base)}${quote})`,
105
+ );
106
+ };
107
+
108
+ export {
109
+ applyBasePathToCss,
110
+ applyBasePathToHtml,
111
+ normalizeBasePath,
112
+ normalizePermalink,
113
+ routeToOutputPath,
114
+ withBasePath,
115
+ withoutBasePath,
116
+ };
package/src/watcher.js CHANGED
@@ -13,6 +13,7 @@ const dirExtensions = {
13
13
  js: [".js"],
14
14
  partials: [".md", ".html"],
15
15
  data: [".json", ".yaml", ".yml"],
16
+ public: null,
16
17
  };
17
18
 
18
19
  // Build watch paths