@bagelink/blox 1.12.22 → 1.12.23
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/CmsPageView.vue.d.ts.map +1 -1
- package/dist/PreviewApp-C2T03Jm9.cjs +4 -0
- package/dist/PreviewApp-CmThrLvv.js +4 -0
- package/dist/PreviewApp.vue.d.ts.map +1 -1
- package/dist/PreviewApp.vue_vue_type_style_index_0_lang-B0N5QbfS.js +157 -0
- package/dist/PreviewApp.vue_vue_type_style_index_0_lang-BTuE4GmT.cjs +156 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/bridge.d.ts +1 -0
- package/dist/bridge.d.ts.map +1 -1
- package/dist/core-C3Iu5qa2.js +460 -0
- package/dist/core-_fnHoEZN.cjs +459 -0
- package/dist/core.d.ts.map +1 -1
- package/dist/createBloxApp.d.ts +107 -0
- package/dist/createBloxApp.d.ts.map +1 -0
- package/dist/defineBlock.d.ts +2 -0
- package/dist/defineBlock.d.ts.map +1 -1
- package/dist/index.cjs +79 -585
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +78 -583
- package/dist/{prerender-6jE_obPj.cjs → prerender-Bi7YtzSp.cjs} +246 -6
- package/dist/prerender-D3Q4jKXm.js +522 -0
- package/dist/schema.d.ts +2 -0
- package/dist/schema.d.ts.map +1 -1
- package/dist/ssg/cli.cjs +48 -5
- package/dist/ssg/cli.mjs +48 -5
- package/dist/ssg/client.cjs +50 -3
- package/dist/ssg/client.d.ts +2 -1
- package/dist/ssg/client.d.ts.map +1 -1
- package/dist/ssg/client.mjs +49 -2
- package/dist/ssg/cms-routes.d.ts +21 -4
- package/dist/ssg/cms-routes.d.ts.map +1 -1
- package/dist/ssg/collection-cache.d.ts +53 -0
- package/dist/ssg/collection-cache.d.ts.map +1 -0
- package/dist/ssg/constants.d.ts +4 -0
- package/dist/ssg/constants.d.ts.map +1 -1
- package/dist/ssg/createSSREntry.d.ts +73 -0
- package/dist/ssg/createSSREntry.d.ts.map +1 -0
- package/dist/ssg/index.cjs +138 -6
- package/dist/ssg/index.d.ts +10 -3
- package/dist/ssg/index.d.ts.map +1 -1
- package/dist/ssg/index.mjs +124 -12
- package/dist/ssg/prerender.d.ts +19 -1
- package/dist/ssg/prerender.d.ts.map +1 -1
- package/dist/ssg/render-resolved-page.d.ts +13 -3
- package/dist/ssg/render-resolved-page.d.ts.map +1 -1
- package/dist/ssg/seo.d.ts +66 -0
- package/dist/ssg/seo.d.ts.map +1 -0
- package/dist/style.css +20 -0
- package/dist/vite-plugin.cjs +142 -3
- package/dist/vite-plugin.d.ts +22 -21
- package/dist/vite-plugin.d.ts.map +1 -1
- package/dist/vite-plugin.mjs +142 -3
- package/package.json +4 -1
- package/dist/PreviewApp-BZNzZkit.js +0 -4
- package/dist/PreviewApp-C1WvJWI4.cjs +0 -4
- package/dist/constants-BIbQhd3z.js +0 -4
- package/dist/constants-fZvybj0k.cjs +0 -3
- package/dist/prerender-DYmDaqcz.js +0 -282
package/dist/vite-plugin.mjs
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { join, dirname } from "node:path";
|
|
3
|
+
import process from "node:process";
|
|
1
4
|
var comma = ",".charCodeAt(0);
|
|
2
5
|
var semicolon = ";".charCodeAt(0);
|
|
3
6
|
var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
|
@@ -1067,8 +1070,143 @@ class MagicString {
|
|
|
1067
1070
|
return this._replaceRegexp(searchValue, replacement);
|
|
1068
1071
|
}
|
|
1069
1072
|
}
|
|
1070
|
-
function bloxPlugin() {
|
|
1071
|
-
|
|
1073
|
+
function bloxPlugin(options = {}) {
|
|
1074
|
+
const enableSSR = options.ssr ?? false;
|
|
1075
|
+
const plugins = [];
|
|
1076
|
+
if (enableSSR) {
|
|
1077
|
+
plugins.push({
|
|
1078
|
+
name: "vite-plugin-blox-ssr",
|
|
1079
|
+
enforce: "pre",
|
|
1080
|
+
config(_config, { command }) {
|
|
1081
|
+
const cwd = process.cwd();
|
|
1082
|
+
function resolveVuePaths() {
|
|
1083
|
+
const bases = [join(cwd, "..", "package.json"), join(cwd, "package.json")];
|
|
1084
|
+
for (const base of bases) {
|
|
1085
|
+
try {
|
|
1086
|
+
const req = createRequire(base);
|
|
1087
|
+
const vueEntry = req.resolve("vue");
|
|
1088
|
+
const vueDir = dirname(dirname(vueEntry));
|
|
1089
|
+
return {
|
|
1090
|
+
"vue": vueEntry,
|
|
1091
|
+
"vue/server-renderer": join(vueDir, "server-renderer", "index.mjs"),
|
|
1092
|
+
"@vue/server-renderer": req.resolve("@vue/server-renderer")
|
|
1093
|
+
};
|
|
1094
|
+
} catch {
|
|
1095
|
+
continue;
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
return {};
|
|
1099
|
+
}
|
|
1100
|
+
const dedupe = [
|
|
1101
|
+
"vue",
|
|
1102
|
+
"vue-router",
|
|
1103
|
+
"@vue/runtime-core",
|
|
1104
|
+
"@vue/runtime-dom",
|
|
1105
|
+
"@vue/reactivity",
|
|
1106
|
+
"pinia"
|
|
1107
|
+
];
|
|
1108
|
+
const alias = resolveVuePaths();
|
|
1109
|
+
const ssrConfig = {
|
|
1110
|
+
resolve: {
|
|
1111
|
+
dedupe,
|
|
1112
|
+
alias
|
|
1113
|
+
}
|
|
1114
|
+
};
|
|
1115
|
+
return ssrConfig;
|
|
1116
|
+
}
|
|
1117
|
+
});
|
|
1118
|
+
plugins.push({
|
|
1119
|
+
name: "vite-plugin-blox-ssr-build",
|
|
1120
|
+
enforce: "pre",
|
|
1121
|
+
config(config) {
|
|
1122
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
1123
|
+
if ((_a = config.build) == null ? void 0 : _a.ssr) {
|
|
1124
|
+
return {
|
|
1125
|
+
build: {
|
|
1126
|
+
rollupOptions: {
|
|
1127
|
+
input: ((_c = (_b = config.build) == null ? void 0 : _b.rollupOptions) == null ? void 0 : _c.input) ?? "src/main.server.ts",
|
|
1128
|
+
output: ((_e = (_d = config.build) == null ? void 0 : _d.rollupOptions) == null ? void 0 : _e.output) ?? {
|
|
1129
|
+
dir: "dist/server",
|
|
1130
|
+
format: "esm"
|
|
1131
|
+
},
|
|
1132
|
+
external: [
|
|
1133
|
+
"vue",
|
|
1134
|
+
"vue-router",
|
|
1135
|
+
"vue/server-renderer",
|
|
1136
|
+
"@vue/server-renderer",
|
|
1137
|
+
...Array.isArray((_g = (_f = config.build) == null ? void 0 : _f.rollupOptions) == null ? void 0 : _g.external) ? config.build.rollupOptions.external : []
|
|
1138
|
+
]
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
};
|
|
1142
|
+
}
|
|
1143
|
+
return {};
|
|
1144
|
+
}
|
|
1145
|
+
});
|
|
1146
|
+
}
|
|
1147
|
+
if (options.autoCollections ?? false) {
|
|
1148
|
+
const discoveredCollections = /* @__PURE__ */ new Map();
|
|
1149
|
+
const VIRTUAL_ID = "virtual:blox-collections";
|
|
1150
|
+
const RESOLVED_VIRTUAL_ID = `\0${VIRTUAL_ID}`;
|
|
1151
|
+
plugins.push({
|
|
1152
|
+
name: "vite-plugin-blox-collections",
|
|
1153
|
+
enforce: "pre",
|
|
1154
|
+
resolveId(id) {
|
|
1155
|
+
if (id === VIRTUAL_ID) return RESOLVED_VIRTUAL_ID;
|
|
1156
|
+
},
|
|
1157
|
+
load(id) {
|
|
1158
|
+
if (id === RESOLVED_VIRTUAL_ID) {
|
|
1159
|
+
const entries = [...discoveredCollections.values()];
|
|
1160
|
+
return `export default ${JSON.stringify(entries)}`;
|
|
1161
|
+
}
|
|
1162
|
+
},
|
|
1163
|
+
transform(code, id) {
|
|
1164
|
+
if (!id.endsWith(".vue")) return;
|
|
1165
|
+
const namePatterns = [
|
|
1166
|
+
/collectionName\s*:\s*['"]([^'"]+)['"]/g,
|
|
1167
|
+
/collection_name\s*:\s*['"]([^'"]+)['"]/g,
|
|
1168
|
+
/collection\s*:\s*['"]([^'"]+)['"]/g
|
|
1169
|
+
];
|
|
1170
|
+
const storeRe = /store\s*:\s*['"]([^'"]+)['"]/g;
|
|
1171
|
+
const stores = [];
|
|
1172
|
+
let storeMatch;
|
|
1173
|
+
while ((storeMatch = storeRe.exec(code)) !== null) {
|
|
1174
|
+
stores.push(storeMatch[1]);
|
|
1175
|
+
}
|
|
1176
|
+
const listItemsRe = /listItems\s*\(\s*['"]([^'"]+)['"]/g;
|
|
1177
|
+
let listMatch;
|
|
1178
|
+
while ((listMatch = listItemsRe.exec(code)) !== null) {
|
|
1179
|
+
const collectionName = listMatch[1];
|
|
1180
|
+
const key = `*/${collectionName}`;
|
|
1181
|
+
if (!discoveredCollections.has(key)) {
|
|
1182
|
+
discoveredCollections.set(key, { store: "*", collection: collectionName });
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1185
|
+
for (const pattern of namePatterns) {
|
|
1186
|
+
let match;
|
|
1187
|
+
while ((match = pattern.exec(code)) !== null) {
|
|
1188
|
+
const collection = match[1];
|
|
1189
|
+
if (["name", "label", "icon", "description", "type"].includes(collection)) continue;
|
|
1190
|
+
const store = stores[0] ?? "*";
|
|
1191
|
+
const key = `${store}/${collection}`;
|
|
1192
|
+
if (!discoveredCollections.has(key)) {
|
|
1193
|
+
discoveredCollections.set(key, { store, collection });
|
|
1194
|
+
}
|
|
1195
|
+
}
|
|
1196
|
+
}
|
|
1197
|
+
},
|
|
1198
|
+
generateBundle() {
|
|
1199
|
+
if (discoveredCollections.size === 0) return;
|
|
1200
|
+
const entries = [...discoveredCollections.values()];
|
|
1201
|
+
this.emitFile({
|
|
1202
|
+
type: "asset",
|
|
1203
|
+
fileName: ".blox-collections.json",
|
|
1204
|
+
source: JSON.stringify(entries, null, 2)
|
|
1205
|
+
});
|
|
1206
|
+
}
|
|
1207
|
+
});
|
|
1208
|
+
}
|
|
1209
|
+
plugins.push({
|
|
1072
1210
|
name: "vite-plugin-blox",
|
|
1073
1211
|
enforce: "pre",
|
|
1074
1212
|
transform(code, id) {
|
|
@@ -1161,7 +1299,8 @@ ${openTag}${remaining}${closeTag}`;
|
|
|
1161
1299
|
map: s.generateMap({ hires: true })
|
|
1162
1300
|
};
|
|
1163
1301
|
}
|
|
1164
|
-
};
|
|
1302
|
+
});
|
|
1303
|
+
return plugins;
|
|
1165
1304
|
}
|
|
1166
1305
|
export {
|
|
1167
1306
|
bloxPlugin
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bagelink/blox",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "1.12.
|
|
4
|
+
"version": "1.12.23",
|
|
5
5
|
"description": "Blox page builder library for drag-and-drop page building and static data management",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Bagel Studio",
|
|
@@ -118,6 +118,9 @@
|
|
|
118
118
|
"vue-router": "^4.6.3",
|
|
119
119
|
"vue-tsc": "^2.0.0"
|
|
120
120
|
},
|
|
121
|
+
"dependencies": {
|
|
122
|
+
"pinia": "^3.0.4"
|
|
123
|
+
},
|
|
121
124
|
"scripts": {
|
|
122
125
|
"dev": "vite build --watch",
|
|
123
126
|
"build": "vite build",
|
|
@@ -1,282 +0,0 @@
|
|
|
1
|
-
import fs from "node:fs/promises";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import process from "node:process";
|
|
4
|
-
import { pathToFileURL } from "node:url";
|
|
5
|
-
async function fetchCmsPrerenderPaths(apiBase, websiteName) {
|
|
6
|
-
const sitesRes = await fetch(`${apiBase}/cms/websites`);
|
|
7
|
-
const sitesData = await sitesRes.json();
|
|
8
|
-
const sites = Array.isArray(sitesData) ? sitesData : sitesData.data ?? [];
|
|
9
|
-
const site = sites.find((s) => s.name === websiteName);
|
|
10
|
-
if ((site == null ? void 0 : site.id) == null || site.id === "") throw new Error(`Website "${websiteName}" not found at ${apiBase}`);
|
|
11
|
-
const pagesRes = await fetch(`${apiBase}/cms/websites/${site.id}/pages?locale=en`);
|
|
12
|
-
const pagesData = await pagesRes.json();
|
|
13
|
-
const pages = Array.isArray(pagesData) ? pagesData : pagesData.data ?? [];
|
|
14
|
-
const routes = [];
|
|
15
|
-
for (const page of pages) {
|
|
16
|
-
const slug = page.slug ?? "/";
|
|
17
|
-
if (slug.includes(":") && page.data_bindings) {
|
|
18
|
-
for (const [, binding] of Object.entries(page.data_bindings)) {
|
|
19
|
-
const b = binding;
|
|
20
|
-
if (b.adapter === "datastore" && b.collection != null && b.collection !== "" && b.store != null && b.store !== "" && b.bind_by != null && b.bind_by !== "") {
|
|
21
|
-
try {
|
|
22
|
-
const itemsRes = await fetch(
|
|
23
|
-
`${apiBase}/datastore/${b.store}/collections/${b.collection}?limit=200`
|
|
24
|
-
);
|
|
25
|
-
const itemsData = await itemsRes.json();
|
|
26
|
-
const items = Array.isArray(itemsData) ? itemsData : itemsData.data ?? [];
|
|
27
|
-
for (const item of items) {
|
|
28
|
-
const bindValue = item[b.bind_by];
|
|
29
|
-
if (bindValue != null && bindValue !== "") {
|
|
30
|
-
const concrete = slug.replace(/:([a-z_]+)/g, (_m, p) => p === b.bind_by ? String(bindValue) : String(item[p] ?? ""));
|
|
31
|
-
routes.push(concrete);
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
} catch (e) {
|
|
35
|
-
console.warn(` [blox-ssg] Could not expand ${slug}: ${e.message}`);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
} else if (!slug.includes(":")) {
|
|
40
|
-
routes.push(slug === "" ? "/" : slug);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
return [...new Set(routes)];
|
|
44
|
-
}
|
|
45
|
-
async function polyfillBloxSsgGlobals(options) {
|
|
46
|
-
const { env } = await import("node:process");
|
|
47
|
-
const pageUrl = (options == null ? void 0 : options.pageUrl) ?? env.BAGELINK_API_URL ?? "https://example.com/";
|
|
48
|
-
const { Window: HappyWindow } = await import("happy-dom");
|
|
49
|
-
const _win = new HappyWindow({ url: pageUrl });
|
|
50
|
-
const g = globalThis;
|
|
51
|
-
if (g.window == null) g.window = g;
|
|
52
|
-
for (const key of Object.getOwnPropertyNames(_win)) {
|
|
53
|
-
if (key === "window" || key === "global" || key === "globalThis") continue;
|
|
54
|
-
try {
|
|
55
|
-
if (!(key in g)) g[key] = _win[key];
|
|
56
|
-
} catch {
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
for (const key of [
|
|
60
|
-
"document",
|
|
61
|
-
"location",
|
|
62
|
-
"localStorage",
|
|
63
|
-
"sessionStorage",
|
|
64
|
-
"navigator",
|
|
65
|
-
"Element",
|
|
66
|
-
"Document",
|
|
67
|
-
"HTMLElement",
|
|
68
|
-
"Event",
|
|
69
|
-
"CustomEvent",
|
|
70
|
-
"MouseEvent",
|
|
71
|
-
"KeyboardEvent",
|
|
72
|
-
"MutationObserver",
|
|
73
|
-
"IntersectionObserver",
|
|
74
|
-
"ResizeObserver",
|
|
75
|
-
"getComputedStyle",
|
|
76
|
-
"matchMedia",
|
|
77
|
-
"requestAnimationFrame",
|
|
78
|
-
"cancelAnimationFrame"
|
|
79
|
-
]) {
|
|
80
|
-
try {
|
|
81
|
-
g[key] = _win[key];
|
|
82
|
-
} catch {
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
g.window = g;
|
|
86
|
-
g.window.location = _win.location;
|
|
87
|
-
g.window.document = _win.document;
|
|
88
|
-
}
|
|
89
|
-
async function prerender({
|
|
90
|
-
root = process.cwd(),
|
|
91
|
-
clientOutDir = "dist/client",
|
|
92
|
-
serverEntry = "dist/server/main.server.js",
|
|
93
|
-
paths = [],
|
|
94
|
-
crawl = true,
|
|
95
|
-
excludePaths = [],
|
|
96
|
-
failFast = false,
|
|
97
|
-
maxPages = 5e3,
|
|
98
|
-
mode = "dir"
|
|
99
|
-
} = {}) {
|
|
100
|
-
const absRoot = path.resolve(root);
|
|
101
|
-
const absClient = path.resolve(absRoot, clientOutDir);
|
|
102
|
-
const absServerEntry = path.resolve(absRoot, serverEntry);
|
|
103
|
-
const templatePath = path.join(absClient, "index.html");
|
|
104
|
-
const template = await fs.readFile(templatePath, "utf8");
|
|
105
|
-
const serverMod = await import(pathToFileURL(absServerEntry).href);
|
|
106
|
-
if (typeof serverMod.render !== "function") {
|
|
107
|
-
throw new TypeError(
|
|
108
|
-
`SSR entry must export async function render(url, ctx). Missing "render" in: ${absServerEntry}`
|
|
109
|
-
);
|
|
110
|
-
}
|
|
111
|
-
let manifest = null;
|
|
112
|
-
try {
|
|
113
|
-
const manifestPath = path.join(absClient, "ssr-manifest.json");
|
|
114
|
-
manifest = JSON.parse(await fs.readFile(manifestPath, "utf8"));
|
|
115
|
-
} catch {
|
|
116
|
-
}
|
|
117
|
-
const isExcluded = makeExcludeChecker(excludePaths);
|
|
118
|
-
const queue = [];
|
|
119
|
-
const seen = /* @__PURE__ */ new Set();
|
|
120
|
-
enqueue("/", queue, seen, isExcluded);
|
|
121
|
-
for (const p of paths) enqueue(p, queue, seen, isExcluded);
|
|
122
|
-
const fontPreloads = await discoverFontPreloads(absClient);
|
|
123
|
-
const rendered = [];
|
|
124
|
-
const failures = [];
|
|
125
|
-
while (queue.length) {
|
|
126
|
-
if (rendered.length >= maxPages) break;
|
|
127
|
-
const urlPath = queue.shift();
|
|
128
|
-
if (urlPath == null || urlPath === "") continue;
|
|
129
|
-
if (isExcluded(urlPath)) continue;
|
|
130
|
-
try {
|
|
131
|
-
const { html, head = "", htmlAttrs = "" } = await serverMod.render(urlPath, {
|
|
132
|
-
manifest,
|
|
133
|
-
template
|
|
134
|
-
});
|
|
135
|
-
const outHtml = injectIntoTemplate(template, head, html, fontPreloads, htmlAttrs);
|
|
136
|
-
const outfile = outFilePath(absClient, urlPath, mode);
|
|
137
|
-
await fs.mkdir(path.dirname(outfile), { recursive: true });
|
|
138
|
-
await fs.writeFile(outfile, outHtml, "utf8");
|
|
139
|
-
rendered.push(urlPath);
|
|
140
|
-
if (crawl) {
|
|
141
|
-
const discovered = discoverInternalLinks(outHtml);
|
|
142
|
-
for (const p of discovered) enqueue(p, queue, seen, isExcluded);
|
|
143
|
-
}
|
|
144
|
-
} catch (err) {
|
|
145
|
-
failures.push({ path: urlPath, error: err });
|
|
146
|
-
if (failFast) throw err;
|
|
147
|
-
console.warn(`[prerender] failed: ${urlPath}
|
|
148
|
-
`, err.stack ?? err);
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
return {
|
|
152
|
-
rendered,
|
|
153
|
-
failures,
|
|
154
|
-
queuedRemaining: queue.length,
|
|
155
|
-
totalDiscovered: seen.size
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
function normalizePath(p) {
|
|
159
|
-
if (!p) return "/";
|
|
160
|
-
try {
|
|
161
|
-
if (p.startsWith("http://") || p.startsWith("https://")) {
|
|
162
|
-
const u = new URL(p);
|
|
163
|
-
p = u.pathname + (u.search || "");
|
|
164
|
-
}
|
|
165
|
-
} catch {
|
|
166
|
-
}
|
|
167
|
-
if (!p.startsWith("/")) p = `/${p}`;
|
|
168
|
-
const hashIdx = p.indexOf("#");
|
|
169
|
-
if (hashIdx !== -1) p = p.slice(0, hashIdx);
|
|
170
|
-
p = p.replace(/\/{2,}/g, "/");
|
|
171
|
-
if (p.length > 1 && p.endsWith("/")) p = p.slice(0, -1);
|
|
172
|
-
return p || "/";
|
|
173
|
-
}
|
|
174
|
-
function enqueue(p, queue, seen, isExcluded) {
|
|
175
|
-
const np = normalizePath(p);
|
|
176
|
-
if (seen.has(np)) return;
|
|
177
|
-
if (isExcluded(np)) return;
|
|
178
|
-
seen.add(np);
|
|
179
|
-
queue.push(np);
|
|
180
|
-
}
|
|
181
|
-
function makeExcludeChecker(excludePaths) {
|
|
182
|
-
const rules = Array.isArray(excludePaths) ? excludePaths : [excludePaths];
|
|
183
|
-
return (p) => {
|
|
184
|
-
const np = normalizePath(p);
|
|
185
|
-
for (const r of rules) {
|
|
186
|
-
if (typeof r === "string" && r === "") continue;
|
|
187
|
-
if (typeof r === "function") {
|
|
188
|
-
if (r(np)) return true;
|
|
189
|
-
} else if (r instanceof RegExp) {
|
|
190
|
-
if (r.test(np)) return true;
|
|
191
|
-
} else if (typeof r === "string") {
|
|
192
|
-
const prefix = normalizePath(r);
|
|
193
|
-
if (np === prefix || np.startsWith(`${prefix}/`)) return true;
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
return false;
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
async function discoverFontPreloads(clientOutDir) {
|
|
200
|
-
const assetsDir = path.join(clientOutDir, "assets");
|
|
201
|
-
let cssFiles = [];
|
|
202
|
-
try {
|
|
203
|
-
const entries = await fs.readdir(assetsDir);
|
|
204
|
-
cssFiles = entries.filter((f) => f.endsWith(".css")).map((f) => path.join(assetsDir, f));
|
|
205
|
-
} catch {
|
|
206
|
-
return "";
|
|
207
|
-
}
|
|
208
|
-
const seen = /* @__PURE__ */ new Set();
|
|
209
|
-
const woff2Re = /url\((["']?)(https?:\/\/[^"')]+\.woff2)\1\)/g;
|
|
210
|
-
for (const file of cssFiles) {
|
|
211
|
-
const css = await fs.readFile(file, "utf8");
|
|
212
|
-
for (const [, , url] of css.matchAll(woff2Re)) {
|
|
213
|
-
if (url !== "") seen.add(url);
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
return [...seen].map((href) => `<link rel="preload" as="font" type="font/woff2" crossorigin href="${href}">`).join("\n");
|
|
217
|
-
}
|
|
218
|
-
function injectIntoTemplate(template, head, appHtml, fontPreloads, htmlAttrs = "") {
|
|
219
|
-
let out = template;
|
|
220
|
-
if (template.includes("<!--app-html-->")) {
|
|
221
|
-
out = template.replace("<!--app-html-->", appHtml);
|
|
222
|
-
} else if (template.includes('<div id="app"></div>')) {
|
|
223
|
-
out = template.replace('<div id="app"></div>', `<div id="app">${appHtml}</div>`);
|
|
224
|
-
}
|
|
225
|
-
if (htmlAttrs) {
|
|
226
|
-
const langMatch = htmlAttrs.match(/lang="([^"]*)"/);
|
|
227
|
-
if (langMatch) {
|
|
228
|
-
out = out.replace(/(<html[^>]*\s)lang="[^"]*"/, `$1lang="${langMatch[1]}"`);
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
if (fontPreloads) {
|
|
232
|
-
out = out.replace("</head>", `${fontPreloads}
|
|
233
|
-
</head>`);
|
|
234
|
-
}
|
|
235
|
-
if (head) {
|
|
236
|
-
const descTagRe = /<meta\s[^>]*name\s*=\s*["']description["'][^>]*>/gi;
|
|
237
|
-
const descMatches = [...head.matchAll(descTagRe)];
|
|
238
|
-
if (descMatches.length > 1) {
|
|
239
|
-
for (let i = 0; i < descMatches.length - 1; i++) {
|
|
240
|
-
head = head.replace(descMatches[i][0], "");
|
|
241
|
-
}
|
|
242
|
-
}
|
|
243
|
-
if (/<meta\s[^>]*name\s*=\s*["']description["']/i.test(head)) {
|
|
244
|
-
out = out.replace(/<meta\s[^>]*name\s*=\s*["']description["'][^>]*>/gi, "");
|
|
245
|
-
}
|
|
246
|
-
out = out.replace("</head>", `${head}
|
|
247
|
-
</head>`);
|
|
248
|
-
}
|
|
249
|
-
return out;
|
|
250
|
-
}
|
|
251
|
-
function outFilePath(absClientDir, urlPath, mode) {
|
|
252
|
-
const [pathname] = urlPath.split("?");
|
|
253
|
-
const safe = pathname === "/" ? "/" : pathname;
|
|
254
|
-
if (mode === "file") {
|
|
255
|
-
if (safe === "/") return path.join(absClientDir, "index.html");
|
|
256
|
-
return path.join(absClientDir, `${safe.slice(1)}.html`);
|
|
257
|
-
}
|
|
258
|
-
if (safe === "/") return path.join(absClientDir, "index.html");
|
|
259
|
-
return path.join(absClientDir, safe.slice(1), "index.html");
|
|
260
|
-
}
|
|
261
|
-
function discoverInternalLinks(html) {
|
|
262
|
-
const out = /* @__PURE__ */ new Set();
|
|
263
|
-
const hrefRe = /\bhref\s*=\s*(?:"([^"]*)"|'([^']*)')/gi;
|
|
264
|
-
let m;
|
|
265
|
-
while ((m = hrefRe.exec(html)) !== null) {
|
|
266
|
-
const raw = (m[1] ?? m[2] ?? "").trim();
|
|
267
|
-
if (!raw) continue;
|
|
268
|
-
if (raw.startsWith("mailto:") || raw.startsWith("tel:") || raw.startsWith("javascript:") || raw.startsWith("#")) {
|
|
269
|
-
continue;
|
|
270
|
-
}
|
|
271
|
-
if (raw.startsWith("http://") || raw.startsWith("https://")) continue;
|
|
272
|
-
if (/\.(?:pdf|png|jpe?g|gif|svg|webp|css|js|map|ico)(?:\?|$)/i.test(raw)) continue;
|
|
273
|
-
const candidate = raw.startsWith("/") ? raw : `/${raw}`;
|
|
274
|
-
out.add(candidate);
|
|
275
|
-
}
|
|
276
|
-
return [...out];
|
|
277
|
-
}
|
|
278
|
-
export {
|
|
279
|
-
prerender as a,
|
|
280
|
-
fetchCmsPrerenderPaths as f,
|
|
281
|
-
polyfillBloxSsgGlobals as p
|
|
282
|
-
};
|