@bagelink/blox 1.15.627 → 1.15.631
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/{PreviewApp-DcD_Cjzn.js → PreviewApp-DQ5p-pJu.js} +1 -1
- package/dist/{PreviewApp-5XGQVrnd.cjs → PreviewApp-j062gN6d.cjs} +1 -1
- package/dist/{PreviewApp.vue_vue_type_style_index_0_lang-OZtgkMXq.cjs → PreviewApp.vue_vue_type_style_index_0_lang-B9_7wgnw.cjs} +1 -1
- package/dist/{PreviewApp.vue_vue_type_style_index_0_lang-m2TIr6Wk.js → PreviewApp.vue_vue_type_style_index_0_lang-DCYf0VuH.js} +1 -1
- package/dist/api/index.d.ts +2 -0
- package/dist/api/index.d.ts.map +1 -1
- package/dist/{appRuntime-BqvP0NaP.cjs → appRuntime-BWlOTcQo.cjs} +13 -210
- package/dist/{appRuntime-FphnGcV2.js → appRuntime-DEeCouh7.js} +38 -235
- package/dist/{client-XQnL-B6N.js → client-Ce9fRCGH.js} +2 -2
- package/dist/index.cjs +23 -19
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.mjs +52 -47
- package/dist/pageTitle-DyJ9r6xJ.cjs +268 -0
- package/dist/pageTitle-tOzMNilm.js +269 -0
- package/dist/{shard-runner-CinJMC5z.cjs → shard-runner-BJ7J4qF3.cjs} +2 -2
- package/dist/{shard-runner-C7_xAkA1.js → shard-runner-BSUEe9p3.js} +2 -2
- package/dist/ssg/cli.cjs +8 -2
- package/dist/ssg/cli.mjs +8 -2
- package/dist/ssg/client.mjs +2 -2
- package/dist/ssg/cms-routes.d.ts +19 -0
- package/dist/ssg/cms-routes.d.ts.map +1 -1
- package/dist/ssg/createSSREntry.d.ts +2 -0
- package/dist/ssg/createSSREntry.d.ts.map +1 -1
- package/dist/ssg/index.cjs +10 -5
- package/dist/ssg/index.mjs +25 -20
- package/dist/{validate-output-e0E998g_.js → validate-output-CRv_cnji.js} +44 -24
- package/dist/{validate-output-DQTw64Rc.cjs → validate-output-oVFDwKIA.cjs} +24 -4
- package/package.json +1 -1
- package/dist/pageTitle-BOTMH-D8.js +0 -56
- package/dist/pageTitle-nIl1cDfD.cjs +0 -55
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
const vue = require("vue");
|
|
3
|
+
const ssg_client = require("./client-AoDTJJXJ.cjs");
|
|
4
|
+
let BASE = "/api";
|
|
5
|
+
let _websiteName = "";
|
|
6
|
+
let _store = "";
|
|
7
|
+
let _websiteId = null;
|
|
8
|
+
let _origin = "";
|
|
9
|
+
let _collectionResolver = null;
|
|
10
|
+
const BLOX_API_KEY = Symbol("blox:api");
|
|
11
|
+
function configureApi(websiteName, store) {
|
|
12
|
+
_websiteName = websiteName;
|
|
13
|
+
_store = store;
|
|
14
|
+
_websiteId = null;
|
|
15
|
+
}
|
|
16
|
+
function setApiOrigin(base) {
|
|
17
|
+
if (!base) return;
|
|
18
|
+
try {
|
|
19
|
+
const u = new URL(base);
|
|
20
|
+
_origin = u.origin;
|
|
21
|
+
BASE = u.pathname && u.pathname !== "/" ? u.pathname.replace(/\/$/, "") : "";
|
|
22
|
+
} catch {
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function setCollectionResolver(resolver) {
|
|
26
|
+
_collectionResolver = resolver;
|
|
27
|
+
}
|
|
28
|
+
function getCollectionResolver() {
|
|
29
|
+
return _collectionResolver;
|
|
30
|
+
}
|
|
31
|
+
function apiBase(base = "/api", origin = "") {
|
|
32
|
+
if (!origin) return { base, origin };
|
|
33
|
+
try {
|
|
34
|
+
const url = new URL(origin);
|
|
35
|
+
return {
|
|
36
|
+
origin: url.origin,
|
|
37
|
+
base: url.pathname && url.pathname !== "/" ? url.pathname.replace(/\/$/, "") : ""
|
|
38
|
+
};
|
|
39
|
+
} catch {
|
|
40
|
+
return { base, origin: "" };
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function createBloxApi(options) {
|
|
44
|
+
const configured = apiBase("/api", options.origin);
|
|
45
|
+
let websiteId = null;
|
|
46
|
+
async function scopedRequest(path, { locale, params, ...opts } = {}) {
|
|
47
|
+
const origin = configured.origin || (typeof window !== "undefined" ? window.location.origin : "");
|
|
48
|
+
const url = new URL(`${configured.base}${path}`, origin || void 0);
|
|
49
|
+
if (locale) url.searchParams.set("locale", locale);
|
|
50
|
+
if (params) {
|
|
51
|
+
for (const [key, value] of Object.entries(params)) url.searchParams.set(key, String(value));
|
|
52
|
+
}
|
|
53
|
+
const response = await fetch(url.toString(), opts);
|
|
54
|
+
if (!response.ok) throw new Error(`API ${response.status}: ${path}`);
|
|
55
|
+
if (response.status === 204) return null;
|
|
56
|
+
return response.json();
|
|
57
|
+
}
|
|
58
|
+
function getWebsiteIdSync2() {
|
|
59
|
+
var _a;
|
|
60
|
+
if (websiteId) return websiteId;
|
|
61
|
+
return ((_a = ssg_client.readBloxHydration()) == null ? void 0 : _a.websiteId) ?? null;
|
|
62
|
+
}
|
|
63
|
+
async function getWebsiteId2() {
|
|
64
|
+
const existing = getWebsiteIdSync2();
|
|
65
|
+
if (existing) {
|
|
66
|
+
websiteId = existing;
|
|
67
|
+
return existing;
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
const website = await scopedRequest(
|
|
71
|
+
`/blox/sites/${encodeURIComponent(options.websiteName)}`
|
|
72
|
+
);
|
|
73
|
+
websiteId = website.id;
|
|
74
|
+
return website.id;
|
|
75
|
+
} catch {
|
|
76
|
+
throw new Error(`Website "${options.websiteName}" not found. Run: npm run seed`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
async function listItems2(collection, { locale, q, offset = 0, limit = 100 } = {}) {
|
|
80
|
+
const resolver = options.collectionResolver ?? _collectionResolver;
|
|
81
|
+
if (resolver) {
|
|
82
|
+
return await resolver(collection, {
|
|
83
|
+
locale,
|
|
84
|
+
q,
|
|
85
|
+
offset,
|
|
86
|
+
limit
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
return scopedRequest(`/datastore/${options.store}/collections/${collection}`, {
|
|
90
|
+
locale,
|
|
91
|
+
params: { ...q ? { q } : {}, offset, limit }
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
getWebsiteIdSync: getWebsiteIdSync2,
|
|
96
|
+
getWebsiteId: getWebsiteId2,
|
|
97
|
+
resolvePath: async (path, locale) => {
|
|
98
|
+
const id = await getWebsiteId2();
|
|
99
|
+
return scopedRequest(`/blox/websites/${id}/resolve-path`, {
|
|
100
|
+
locale,
|
|
101
|
+
params: { path }
|
|
102
|
+
});
|
|
103
|
+
},
|
|
104
|
+
listItems: listItems2,
|
|
105
|
+
getItemBySlug: async (collection, slug, locale) => {
|
|
106
|
+
const result = await listItems2(collection, { locale, limit: 1e3 });
|
|
107
|
+
const items = Array.isArray(result) ? result : (result == null ? void 0 : result.items) ?? [];
|
|
108
|
+
return items.find((item) => String((item == null ? void 0 : item.slug) ?? "") === slug) ?? null;
|
|
109
|
+
},
|
|
110
|
+
getItemById: async (collection, id, locale) => {
|
|
111
|
+
const result = await listItems2(collection, { locale, limit: 1e3 });
|
|
112
|
+
const items = Array.isArray(result) ? result : (result == null ? void 0 : result.items) ?? [];
|
|
113
|
+
return items.find((item) => {
|
|
114
|
+
const record = item;
|
|
115
|
+
return String((record == null ? void 0 : record.id) ?? (record == null ? void 0 : record._id) ?? "") === id;
|
|
116
|
+
}) ?? null;
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
function provideBloxApi(app, options) {
|
|
121
|
+
const client = createBloxApi(options);
|
|
122
|
+
app.provide(BLOX_API_KEY, client);
|
|
123
|
+
return client;
|
|
124
|
+
}
|
|
125
|
+
function useBloxApi() {
|
|
126
|
+
return vue.getCurrentInstance() ? vue.inject(BLOX_API_KEY, null) : null;
|
|
127
|
+
}
|
|
128
|
+
async function request(path, { locale, params, ...opts } = {}) {
|
|
129
|
+
const origin = _origin || (typeof window !== "undefined" ? window.location.origin : "");
|
|
130
|
+
const url = new URL(`${BASE}${path}`, origin || void 0);
|
|
131
|
+
if (locale) url.searchParams.set("locale", locale);
|
|
132
|
+
if (params) {
|
|
133
|
+
for (const [k, v] of Object.entries(params)) url.searchParams.set(k, String(v));
|
|
134
|
+
}
|
|
135
|
+
const res = await fetch(url.toString(), opts);
|
|
136
|
+
if (!res.ok) throw new Error(`API ${res.status}: ${path}`);
|
|
137
|
+
if (res.status === 204) return null;
|
|
138
|
+
return res.json();
|
|
139
|
+
}
|
|
140
|
+
function getWebsiteIdSync() {
|
|
141
|
+
if (_websiteId) return _websiteId;
|
|
142
|
+
if (typeof window !== "undefined") {
|
|
143
|
+
const embedded = window[ssg_client.BLOX_WEBSITE_ID_WINDOW_KEY];
|
|
144
|
+
if (typeof embedded === "string" && embedded !== "") return embedded;
|
|
145
|
+
}
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
async function getWebsiteId() {
|
|
149
|
+
if (_websiteId) return _websiteId;
|
|
150
|
+
if (typeof window !== "undefined") {
|
|
151
|
+
const embedded = window[ssg_client.BLOX_WEBSITE_ID_WINDOW_KEY];
|
|
152
|
+
if (typeof embedded === "string" && embedded !== "") {
|
|
153
|
+
_websiteId = embedded;
|
|
154
|
+
return _websiteId;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
let website;
|
|
158
|
+
try {
|
|
159
|
+
website = await request(
|
|
160
|
+
`/blox/sites/${encodeURIComponent(_websiteName)}`
|
|
161
|
+
);
|
|
162
|
+
} catch {
|
|
163
|
+
throw new Error(`Website "${_websiteName}" not found. Run: npm run seed`);
|
|
164
|
+
}
|
|
165
|
+
_websiteId = website.id;
|
|
166
|
+
return website.id;
|
|
167
|
+
}
|
|
168
|
+
async function resolvePath(path, locale) {
|
|
169
|
+
const websiteId = await getWebsiteId();
|
|
170
|
+
return request(`/blox/websites/${websiteId}/resolve-path`, {
|
|
171
|
+
locale,
|
|
172
|
+
params: { path }
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
async function listItems(collection, { locale, q, offset = 0, limit = 100 } = {}) {
|
|
176
|
+
if (_collectionResolver) {
|
|
177
|
+
return await _collectionResolver(collection, { locale, q, offset, limit });
|
|
178
|
+
}
|
|
179
|
+
return request(`/datastore/${_store}/collections/${collection}`, {
|
|
180
|
+
locale,
|
|
181
|
+
params: { ...q ? { q } : {}, offset, limit }
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
async function getItemBySlug(collection, slug, locale) {
|
|
185
|
+
const res = await listItemsFromActiveApi(collection, { locale, limit: 1e3 });
|
|
186
|
+
const items = Array.isArray(res) ? res : (res == null ? void 0 : res.items) ?? [];
|
|
187
|
+
return items.find((item) => String((item == null ? void 0 : item.slug) ?? "") === slug) ?? null;
|
|
188
|
+
}
|
|
189
|
+
async function getItemById(collection, id, locale) {
|
|
190
|
+
const res = await listItemsFromActiveApi(collection, { locale, limit: 1e3 });
|
|
191
|
+
const items = Array.isArray(res) ? res : (res == null ? void 0 : res.items) ?? [];
|
|
192
|
+
return items.find((item) => {
|
|
193
|
+
const record = item;
|
|
194
|
+
return String((record == null ? void 0 : record.id) ?? (record == null ? void 0 : record._id) ?? "") === id;
|
|
195
|
+
}) ?? null;
|
|
196
|
+
}
|
|
197
|
+
function listItemsFromActiveApi(collection, options = {}) {
|
|
198
|
+
var _a;
|
|
199
|
+
return ((_a = useBloxApi()) == null ? void 0 : _a.listItems(collection, options)) ?? listItems(collection, options);
|
|
200
|
+
}
|
|
201
|
+
const PREFERRED_CONTEXT_KEYS = ["$page", "$post", "$item", "$article", "$product", "$event", "$author"];
|
|
202
|
+
const TITLE_FIELDS = ["meta_title", "metaTitle", "title", "name", "productName", "displayName"];
|
|
203
|
+
function primaryPageContext(contexts) {
|
|
204
|
+
if (!contexts) return null;
|
|
205
|
+
const keys = [
|
|
206
|
+
...PREFERRED_CONTEXT_KEYS.filter((key) => key in contexts),
|
|
207
|
+
...Object.keys(contexts).filter((key) => key !== "$website" && !PREFERRED_CONTEXT_KEYS.includes(key)).sort()
|
|
208
|
+
];
|
|
209
|
+
for (const key of keys) {
|
|
210
|
+
const ctx = contexts[key];
|
|
211
|
+
if (ctx != null && typeof ctx === "object") return { key, ctx };
|
|
212
|
+
}
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
function contextPageTitle(context) {
|
|
216
|
+
if (!context) return null;
|
|
217
|
+
for (const field of TITLE_FIELDS) {
|
|
218
|
+
const value = context[field];
|
|
219
|
+
if (typeof value === "string" && value.trim()) return value.trim();
|
|
220
|
+
}
|
|
221
|
+
return null;
|
|
222
|
+
}
|
|
223
|
+
function siteNameFromContexts(contexts) {
|
|
224
|
+
const website = contexts == null ? void 0 : contexts.$website;
|
|
225
|
+
const seo = website == null ? void 0 : website.seo;
|
|
226
|
+
const siteName = seo && typeof seo === "object" ? seo.site_name : website == null ? void 0 : website.site_name;
|
|
227
|
+
return typeof siteName === "string" && siteName.trim() ? siteName.trim() : null;
|
|
228
|
+
}
|
|
229
|
+
function withSiteName(title, siteName) {
|
|
230
|
+
if (!siteName || title.includes(siteName)) return title;
|
|
231
|
+
return `${title} · ${siteName}`;
|
|
232
|
+
}
|
|
233
|
+
function resolvePageTitle(resolved, options = {}) {
|
|
234
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
235
|
+
const hasBinding = !!((_a = resolved.page) == null ? void 0 : _a.data_bindings) && Object.keys(resolved.page.data_bindings).length > 0;
|
|
236
|
+
const contextTitle = hasBinding ? contextPageTitle((_b = primaryPageContext(resolved.contexts)) == null ? void 0 : _b.ctx) : null;
|
|
237
|
+
const dynamicTitle = ((_c = options.override) == null ? void 0 : _c.trim()) || contextTitle;
|
|
238
|
+
if (dynamicTitle) return withSiteName(dynamicTitle, options.siteName);
|
|
239
|
+
if ((_e = (_d = resolved.page) == null ? void 0 : _d.meta_title) == null ? void 0 : _e.trim()) return resolved.page.meta_title.trim();
|
|
240
|
+
if ((_g = (_f = resolved.page) == null ? void 0 : _f.title) == null ? void 0 : _g.trim()) return withSiteName(resolved.page.title.trim(), options.siteName);
|
|
241
|
+
return null;
|
|
242
|
+
}
|
|
243
|
+
function preserveCurrentSiteSuffix(title, currentTitle) {
|
|
244
|
+
const separator = " · ";
|
|
245
|
+
const suffixIndex = currentTitle.lastIndexOf(separator);
|
|
246
|
+
if (suffixIndex < 0) return title;
|
|
247
|
+
const siteName = currentTitle.slice(suffixIndex + separator.length).trim();
|
|
248
|
+
return withSiteName(title, siteName);
|
|
249
|
+
}
|
|
250
|
+
exports.configureApi = configureApi;
|
|
251
|
+
exports.contextPageTitle = contextPageTitle;
|
|
252
|
+
exports.createBloxApi = createBloxApi;
|
|
253
|
+
exports.getCollectionResolver = getCollectionResolver;
|
|
254
|
+
exports.getItemById = getItemById;
|
|
255
|
+
exports.getItemBySlug = getItemBySlug;
|
|
256
|
+
exports.getWebsiteId = getWebsiteId;
|
|
257
|
+
exports.getWebsiteIdSync = getWebsiteIdSync;
|
|
258
|
+
exports.listItems = listItems;
|
|
259
|
+
exports.listItemsFromActiveApi = listItemsFromActiveApi;
|
|
260
|
+
exports.preserveCurrentSiteSuffix = preserveCurrentSiteSuffix;
|
|
261
|
+
exports.primaryPageContext = primaryPageContext;
|
|
262
|
+
exports.provideBloxApi = provideBloxApi;
|
|
263
|
+
exports.resolvePageTitle = resolvePageTitle;
|
|
264
|
+
exports.resolvePath = resolvePath;
|
|
265
|
+
exports.setApiOrigin = setApiOrigin;
|
|
266
|
+
exports.setCollectionResolver = setCollectionResolver;
|
|
267
|
+
exports.siteNameFromContexts = siteNameFromContexts;
|
|
268
|
+
exports.useBloxApi = useBloxApi;
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import { getCurrentInstance, inject } from "vue";
|
|
2
|
+
import { B as BLOX_WEBSITE_ID_WINDOW_KEY, r as readBloxHydration } from "./client-Ce9fRCGH.js";
|
|
3
|
+
let BASE = "/api";
|
|
4
|
+
let _websiteName = "";
|
|
5
|
+
let _store = "";
|
|
6
|
+
let _websiteId = null;
|
|
7
|
+
let _origin = "";
|
|
8
|
+
let _collectionResolver = null;
|
|
9
|
+
const BLOX_API_KEY = Symbol("blox:api");
|
|
10
|
+
function configureApi(websiteName, store) {
|
|
11
|
+
_websiteName = websiteName;
|
|
12
|
+
_store = store;
|
|
13
|
+
_websiteId = null;
|
|
14
|
+
}
|
|
15
|
+
function setApiOrigin(base) {
|
|
16
|
+
if (!base) return;
|
|
17
|
+
try {
|
|
18
|
+
const u = new URL(base);
|
|
19
|
+
_origin = u.origin;
|
|
20
|
+
BASE = u.pathname && u.pathname !== "/" ? u.pathname.replace(/\/$/, "") : "";
|
|
21
|
+
} catch {
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function setCollectionResolver(resolver) {
|
|
25
|
+
_collectionResolver = resolver;
|
|
26
|
+
}
|
|
27
|
+
function getCollectionResolver() {
|
|
28
|
+
return _collectionResolver;
|
|
29
|
+
}
|
|
30
|
+
function apiBase(base = "/api", origin = "") {
|
|
31
|
+
if (!origin) return { base, origin };
|
|
32
|
+
try {
|
|
33
|
+
const url = new URL(origin);
|
|
34
|
+
return {
|
|
35
|
+
origin: url.origin,
|
|
36
|
+
base: url.pathname && url.pathname !== "/" ? url.pathname.replace(/\/$/, "") : ""
|
|
37
|
+
};
|
|
38
|
+
} catch {
|
|
39
|
+
return { base, origin: "" };
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function createBloxApi(options) {
|
|
43
|
+
const configured = apiBase("/api", options.origin);
|
|
44
|
+
let websiteId = null;
|
|
45
|
+
async function scopedRequest(path, { locale, params, ...opts } = {}) {
|
|
46
|
+
const origin = configured.origin || (typeof window !== "undefined" ? window.location.origin : "");
|
|
47
|
+
const url = new URL(`${configured.base}${path}`, origin || void 0);
|
|
48
|
+
if (locale) url.searchParams.set("locale", locale);
|
|
49
|
+
if (params) {
|
|
50
|
+
for (const [key, value] of Object.entries(params)) url.searchParams.set(key, String(value));
|
|
51
|
+
}
|
|
52
|
+
const response = await fetch(url.toString(), opts);
|
|
53
|
+
if (!response.ok) throw new Error(`API ${response.status}: ${path}`);
|
|
54
|
+
if (response.status === 204) return null;
|
|
55
|
+
return response.json();
|
|
56
|
+
}
|
|
57
|
+
function getWebsiteIdSync2() {
|
|
58
|
+
var _a;
|
|
59
|
+
if (websiteId) return websiteId;
|
|
60
|
+
return ((_a = readBloxHydration()) == null ? void 0 : _a.websiteId) ?? null;
|
|
61
|
+
}
|
|
62
|
+
async function getWebsiteId2() {
|
|
63
|
+
const existing = getWebsiteIdSync2();
|
|
64
|
+
if (existing) {
|
|
65
|
+
websiteId = existing;
|
|
66
|
+
return existing;
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
const website = await scopedRequest(
|
|
70
|
+
`/blox/sites/${encodeURIComponent(options.websiteName)}`
|
|
71
|
+
);
|
|
72
|
+
websiteId = website.id;
|
|
73
|
+
return website.id;
|
|
74
|
+
} catch {
|
|
75
|
+
throw new Error(`Website "${options.websiteName}" not found. Run: npm run seed`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
async function listItems2(collection, { locale, q, offset = 0, limit = 100 } = {}) {
|
|
79
|
+
const resolver = options.collectionResolver ?? _collectionResolver;
|
|
80
|
+
if (resolver) {
|
|
81
|
+
return await resolver(collection, {
|
|
82
|
+
locale,
|
|
83
|
+
q,
|
|
84
|
+
offset,
|
|
85
|
+
limit
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
return scopedRequest(`/datastore/${options.store}/collections/${collection}`, {
|
|
89
|
+
locale,
|
|
90
|
+
params: { ...q ? { q } : {}, offset, limit }
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
return {
|
|
94
|
+
getWebsiteIdSync: getWebsiteIdSync2,
|
|
95
|
+
getWebsiteId: getWebsiteId2,
|
|
96
|
+
resolvePath: async (path, locale) => {
|
|
97
|
+
const id = await getWebsiteId2();
|
|
98
|
+
return scopedRequest(`/blox/websites/${id}/resolve-path`, {
|
|
99
|
+
locale,
|
|
100
|
+
params: { path }
|
|
101
|
+
});
|
|
102
|
+
},
|
|
103
|
+
listItems: listItems2,
|
|
104
|
+
getItemBySlug: async (collection, slug, locale) => {
|
|
105
|
+
const result = await listItems2(collection, { locale, limit: 1e3 });
|
|
106
|
+
const items = Array.isArray(result) ? result : (result == null ? void 0 : result.items) ?? [];
|
|
107
|
+
return items.find((item) => String((item == null ? void 0 : item.slug) ?? "") === slug) ?? null;
|
|
108
|
+
},
|
|
109
|
+
getItemById: async (collection, id, locale) => {
|
|
110
|
+
const result = await listItems2(collection, { locale, limit: 1e3 });
|
|
111
|
+
const items = Array.isArray(result) ? result : (result == null ? void 0 : result.items) ?? [];
|
|
112
|
+
return items.find((item) => {
|
|
113
|
+
const record = item;
|
|
114
|
+
return String((record == null ? void 0 : record.id) ?? (record == null ? void 0 : record._id) ?? "") === id;
|
|
115
|
+
}) ?? null;
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
function provideBloxApi(app, options) {
|
|
120
|
+
const client = createBloxApi(options);
|
|
121
|
+
app.provide(BLOX_API_KEY, client);
|
|
122
|
+
return client;
|
|
123
|
+
}
|
|
124
|
+
function useBloxApi() {
|
|
125
|
+
return getCurrentInstance() ? inject(BLOX_API_KEY, null) : null;
|
|
126
|
+
}
|
|
127
|
+
async function request(path, { locale, params, ...opts } = {}) {
|
|
128
|
+
const origin = _origin || (typeof window !== "undefined" ? window.location.origin : "");
|
|
129
|
+
const url = new URL(`${BASE}${path}`, origin || void 0);
|
|
130
|
+
if (locale) url.searchParams.set("locale", locale);
|
|
131
|
+
if (params) {
|
|
132
|
+
for (const [k, v] of Object.entries(params)) url.searchParams.set(k, String(v));
|
|
133
|
+
}
|
|
134
|
+
const res = await fetch(url.toString(), opts);
|
|
135
|
+
if (!res.ok) throw new Error(`API ${res.status}: ${path}`);
|
|
136
|
+
if (res.status === 204) return null;
|
|
137
|
+
return res.json();
|
|
138
|
+
}
|
|
139
|
+
function getWebsiteIdSync() {
|
|
140
|
+
if (_websiteId) return _websiteId;
|
|
141
|
+
if (typeof window !== "undefined") {
|
|
142
|
+
const embedded = window[BLOX_WEBSITE_ID_WINDOW_KEY];
|
|
143
|
+
if (typeof embedded === "string" && embedded !== "") return embedded;
|
|
144
|
+
}
|
|
145
|
+
return null;
|
|
146
|
+
}
|
|
147
|
+
async function getWebsiteId() {
|
|
148
|
+
if (_websiteId) return _websiteId;
|
|
149
|
+
if (typeof window !== "undefined") {
|
|
150
|
+
const embedded = window[BLOX_WEBSITE_ID_WINDOW_KEY];
|
|
151
|
+
if (typeof embedded === "string" && embedded !== "") {
|
|
152
|
+
_websiteId = embedded;
|
|
153
|
+
return _websiteId;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
let website;
|
|
157
|
+
try {
|
|
158
|
+
website = await request(
|
|
159
|
+
`/blox/sites/${encodeURIComponent(_websiteName)}`
|
|
160
|
+
);
|
|
161
|
+
} catch {
|
|
162
|
+
throw new Error(`Website "${_websiteName}" not found. Run: npm run seed`);
|
|
163
|
+
}
|
|
164
|
+
_websiteId = website.id;
|
|
165
|
+
return website.id;
|
|
166
|
+
}
|
|
167
|
+
async function resolvePath(path, locale) {
|
|
168
|
+
const websiteId = await getWebsiteId();
|
|
169
|
+
return request(`/blox/websites/${websiteId}/resolve-path`, {
|
|
170
|
+
locale,
|
|
171
|
+
params: { path }
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
async function listItems(collection, { locale, q, offset = 0, limit = 100 } = {}) {
|
|
175
|
+
if (_collectionResolver) {
|
|
176
|
+
return await _collectionResolver(collection, { locale, q, offset, limit });
|
|
177
|
+
}
|
|
178
|
+
return request(`/datastore/${_store}/collections/${collection}`, {
|
|
179
|
+
locale,
|
|
180
|
+
params: { ...q ? { q } : {}, offset, limit }
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
async function getItemBySlug(collection, slug, locale) {
|
|
184
|
+
const res = await listItemsFromActiveApi(collection, { locale, limit: 1e3 });
|
|
185
|
+
const items = Array.isArray(res) ? res : (res == null ? void 0 : res.items) ?? [];
|
|
186
|
+
return items.find((item) => String((item == null ? void 0 : item.slug) ?? "") === slug) ?? null;
|
|
187
|
+
}
|
|
188
|
+
async function getItemById(collection, id, locale) {
|
|
189
|
+
const res = await listItemsFromActiveApi(collection, { locale, limit: 1e3 });
|
|
190
|
+
const items = Array.isArray(res) ? res : (res == null ? void 0 : res.items) ?? [];
|
|
191
|
+
return items.find((item) => {
|
|
192
|
+
const record = item;
|
|
193
|
+
return String((record == null ? void 0 : record.id) ?? (record == null ? void 0 : record._id) ?? "") === id;
|
|
194
|
+
}) ?? null;
|
|
195
|
+
}
|
|
196
|
+
function listItemsFromActiveApi(collection, options = {}) {
|
|
197
|
+
var _a;
|
|
198
|
+
return ((_a = useBloxApi()) == null ? void 0 : _a.listItems(collection, options)) ?? listItems(collection, options);
|
|
199
|
+
}
|
|
200
|
+
const PREFERRED_CONTEXT_KEYS = ["$page", "$post", "$item", "$article", "$product", "$event", "$author"];
|
|
201
|
+
const TITLE_FIELDS = ["meta_title", "metaTitle", "title", "name", "productName", "displayName"];
|
|
202
|
+
function primaryPageContext(contexts) {
|
|
203
|
+
if (!contexts) return null;
|
|
204
|
+
const keys = [
|
|
205
|
+
...PREFERRED_CONTEXT_KEYS.filter((key) => key in contexts),
|
|
206
|
+
...Object.keys(contexts).filter((key) => key !== "$website" && !PREFERRED_CONTEXT_KEYS.includes(key)).sort()
|
|
207
|
+
];
|
|
208
|
+
for (const key of keys) {
|
|
209
|
+
const ctx = contexts[key];
|
|
210
|
+
if (ctx != null && typeof ctx === "object") return { key, ctx };
|
|
211
|
+
}
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
function contextPageTitle(context) {
|
|
215
|
+
if (!context) return null;
|
|
216
|
+
for (const field of TITLE_FIELDS) {
|
|
217
|
+
const value = context[field];
|
|
218
|
+
if (typeof value === "string" && value.trim()) return value.trim();
|
|
219
|
+
}
|
|
220
|
+
return null;
|
|
221
|
+
}
|
|
222
|
+
function siteNameFromContexts(contexts) {
|
|
223
|
+
const website = contexts == null ? void 0 : contexts.$website;
|
|
224
|
+
const seo = website == null ? void 0 : website.seo;
|
|
225
|
+
const siteName = seo && typeof seo === "object" ? seo.site_name : website == null ? void 0 : website.site_name;
|
|
226
|
+
return typeof siteName === "string" && siteName.trim() ? siteName.trim() : null;
|
|
227
|
+
}
|
|
228
|
+
function withSiteName(title, siteName) {
|
|
229
|
+
if (!siteName || title.includes(siteName)) return title;
|
|
230
|
+
return `${title} · ${siteName}`;
|
|
231
|
+
}
|
|
232
|
+
function resolvePageTitle(resolved, options = {}) {
|
|
233
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
234
|
+
const hasBinding = !!((_a = resolved.page) == null ? void 0 : _a.data_bindings) && Object.keys(resolved.page.data_bindings).length > 0;
|
|
235
|
+
const contextTitle = hasBinding ? contextPageTitle((_b = primaryPageContext(resolved.contexts)) == null ? void 0 : _b.ctx) : null;
|
|
236
|
+
const dynamicTitle = ((_c = options.override) == null ? void 0 : _c.trim()) || contextTitle;
|
|
237
|
+
if (dynamicTitle) return withSiteName(dynamicTitle, options.siteName);
|
|
238
|
+
if ((_e = (_d = resolved.page) == null ? void 0 : _d.meta_title) == null ? void 0 : _e.trim()) return resolved.page.meta_title.trim();
|
|
239
|
+
if ((_g = (_f = resolved.page) == null ? void 0 : _f.title) == null ? void 0 : _g.trim()) return withSiteName(resolved.page.title.trim(), options.siteName);
|
|
240
|
+
return null;
|
|
241
|
+
}
|
|
242
|
+
function preserveCurrentSiteSuffix(title, currentTitle) {
|
|
243
|
+
const separator = " · ";
|
|
244
|
+
const suffixIndex = currentTitle.lastIndexOf(separator);
|
|
245
|
+
if (suffixIndex < 0) return title;
|
|
246
|
+
const siteName = currentTitle.slice(suffixIndex + separator.length).trim();
|
|
247
|
+
return withSiteName(title, siteName);
|
|
248
|
+
}
|
|
249
|
+
export {
|
|
250
|
+
primaryPageContext as a,
|
|
251
|
+
getItemBySlug as b,
|
|
252
|
+
contextPageTitle as c,
|
|
253
|
+
getItemById as d,
|
|
254
|
+
configureApi as e,
|
|
255
|
+
createBloxApi as f,
|
|
256
|
+
getCollectionResolver as g,
|
|
257
|
+
getWebsiteId as h,
|
|
258
|
+
getWebsiteIdSync as i,
|
|
259
|
+
resolvePath as j,
|
|
260
|
+
setApiOrigin as k,
|
|
261
|
+
listItems as l,
|
|
262
|
+
siteNameFromContexts as m,
|
|
263
|
+
preserveCurrentSiteSuffix as n,
|
|
264
|
+
listItemsFromActiveApi as o,
|
|
265
|
+
provideBloxApi as p,
|
|
266
|
+
resolvePageTitle as r,
|
|
267
|
+
setCollectionResolver as s,
|
|
268
|
+
useBloxApi as u
|
|
269
|
+
};
|
|
@@ -26,7 +26,7 @@ const node_child_process = require("node:child_process");
|
|
|
26
26
|
const os = require("node:os");
|
|
27
27
|
const path = require("node:path");
|
|
28
28
|
const process = require("node:process");
|
|
29
|
-
const llmArtifacts = require("./validate-output-
|
|
29
|
+
const llmArtifacts = require("./validate-output-oVFDwKIA.cjs");
|
|
30
30
|
const AUTO_SHARD_CAP = Number(process.env.BLOX_SSG_SHARD_CAP) || 6;
|
|
31
31
|
const PREFETCH_BUDGET = Number(process.env.BLOX_SSG_PREFETCH_BUDGET) || 24;
|
|
32
32
|
const SEQUENTIAL_SHARDS = process.env.BLOX_SSG_SEQUENTIAL === "1";
|
|
@@ -166,7 +166,7 @@ async function runSharded(opts) {
|
|
|
166
166
|
}
|
|
167
167
|
if (process.env.BLOX_SSG_LLM !== "0") {
|
|
168
168
|
try {
|
|
169
|
-
const { mergeLlmParts } = await Promise.resolve().then(() => require("./validate-output-
|
|
169
|
+
const { mergeLlmParts } = await Promise.resolve().then(() => require("./validate-output-oVFDwKIA.cjs")).then((n) => n.llmArtifacts);
|
|
170
170
|
const mergeWebsite = website;
|
|
171
171
|
const partFiles = Array.from({ length: total }, (_, i) => path.join(llmPartsDir, `part.${i}.json`));
|
|
172
172
|
const { pages } = await mergeLlmParts({
|
|
@@ -2,7 +2,7 @@ import { spawn } from "node:child_process";
|
|
|
2
2
|
import os from "node:os";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import process from "node:process";
|
|
5
|
-
import { f as fetchCmsSiteData, g as generateSitemapArtifacts } from "./validate-output-
|
|
5
|
+
import { f as fetchCmsSiteData, g as generateSitemapArtifacts } from "./validate-output-CRv_cnji.js";
|
|
6
6
|
const AUTO_SHARD_CAP = Number(process.env.BLOX_SSG_SHARD_CAP) || 6;
|
|
7
7
|
const PREFETCH_BUDGET = Number(process.env.BLOX_SSG_PREFETCH_BUDGET) || 24;
|
|
8
8
|
const SEQUENTIAL_SHARDS = process.env.BLOX_SSG_SEQUENTIAL === "1";
|
|
@@ -142,7 +142,7 @@ async function runSharded(opts) {
|
|
|
142
142
|
}
|
|
143
143
|
if (process.env.BLOX_SSG_LLM !== "0") {
|
|
144
144
|
try {
|
|
145
|
-
const { mergeLlmParts } = await import("./validate-output-
|
|
145
|
+
const { mergeLlmParts } = await import("./validate-output-CRv_cnji.js").then((n) => n.A);
|
|
146
146
|
const mergeWebsite = website;
|
|
147
147
|
const partFiles = Array.from({ length: total }, (_, i) => path.join(llmPartsDir, `part.${i}.json`));
|
|
148
148
|
const { pages } = await mergeLlmParts({
|
package/dist/ssg/cli.cjs
CHANGED
|
@@ -3,7 +3,8 @@
|
|
|
3
3
|
const process = require("node:process");
|
|
4
4
|
const fs = require("node:fs/promises");
|
|
5
5
|
const ssg_buildGrant = require("./build-grant.cjs");
|
|
6
|
-
const llmArtifacts = require("../validate-output-
|
|
6
|
+
const llmArtifacts = require("../validate-output-oVFDwKIA.cjs");
|
|
7
|
+
const pageTitle = require("../pageTitle-DyJ9r6xJ.cjs");
|
|
7
8
|
function installFetchTimeout() {
|
|
8
9
|
const ms = Number(process.env.BLOX_SSG_FETCH_TIMEOUT_MS) || 2e4;
|
|
9
10
|
const original = globalThis.fetch;
|
|
@@ -141,7 +142,7 @@ Environment:
|
|
|
141
142
|
if (shardsOpt !== null || routesCmd) {
|
|
142
143
|
const { apiBase: apiBase2, websiteName: configWebsiteName2 } = await resolveApiBase(mode);
|
|
143
144
|
const websiteName2 = process.env.WEBSITE_NAME ?? configWebsiteName2 ?? "default";
|
|
144
|
-
const { runSharded } = await Promise.resolve().then(() => require("../shard-runner-
|
|
145
|
+
const { runSharded } = await Promise.resolve().then(() => require("../shard-runner-BJ7J4qF3.cjs"));
|
|
145
146
|
const code = await runSharded({
|
|
146
147
|
shards: shardsOpt ?? "auto",
|
|
147
148
|
mode,
|
|
@@ -175,6 +176,7 @@ Environment:
|
|
|
175
176
|
let redirects = [];
|
|
176
177
|
let cmsPathSet = /* @__PURE__ */ new Set();
|
|
177
178
|
let cachedAppPaths = [];
|
|
179
|
+
let collectionItems;
|
|
178
180
|
const productionBuild = process.env.NODE_ENV === "production" || mode === "production";
|
|
179
181
|
try {
|
|
180
182
|
const siteData = siteDataFile ? JSON.parse(await fs.readFile(siteDataFile, "utf8")) : await llmArtifacts.fetchCmsSiteData(apiBase, websiteName, buildRequest);
|
|
@@ -184,6 +186,7 @@ Environment:
|
|
|
184
186
|
website = siteData.website;
|
|
185
187
|
websiteId = siteData.websiteId;
|
|
186
188
|
redirects = siteData.redirects;
|
|
189
|
+
collectionItems = siteData.collectionItems;
|
|
187
190
|
if (!siteDataFile) {
|
|
188
191
|
console.log(` Found ${paths.length} CMS routes`);
|
|
189
192
|
if (redirects.length > 0) console.log(` Found ${redirects.length} redirects`);
|
|
@@ -193,6 +196,9 @@ Environment:
|
|
|
193
196
|
if (productionBuild) throw err;
|
|
194
197
|
paths = ["/"];
|
|
195
198
|
}
|
|
199
|
+
if (collectionItems && Object.keys(collectionItems).length > 0) {
|
|
200
|
+
pageTitle.setCollectionResolver(llmArtifacts.buildCollectionResolver(collectionItems));
|
|
201
|
+
}
|
|
196
202
|
for (const p of extraPaths) {
|
|
197
203
|
if (!paths.includes(p)) paths.push(p);
|
|
198
204
|
}
|
package/dist/ssg/cli.mjs
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
import process from "node:process";
|
|
3
3
|
import fs from "node:fs/promises";
|
|
4
4
|
import { resolveBloxBuildGrant } from "./build-grant.mjs";
|
|
5
|
-
import { v as validateSsgOutput, u as uploadBloxManifest, p as polyfillBloxSsgGlobals, f as fetchCmsSiteData, a as prerender } from "../validate-output-
|
|
5
|
+
import { v as validateSsgOutput, u as uploadBloxManifest, p as polyfillBloxSsgGlobals, f as fetchCmsSiteData, a as prerender, b as buildCollectionResolver } from "../validate-output-CRv_cnji.js";
|
|
6
|
+
import { s as setCollectionResolver } from "../pageTitle-tOzMNilm.js";
|
|
6
7
|
function installFetchTimeout() {
|
|
7
8
|
const ms = Number(process.env.BLOX_SSG_FETCH_TIMEOUT_MS) || 2e4;
|
|
8
9
|
const original = globalThis.fetch;
|
|
@@ -140,7 +141,7 @@ Environment:
|
|
|
140
141
|
if (shardsOpt !== null || routesCmd) {
|
|
141
142
|
const { apiBase: apiBase2, websiteName: configWebsiteName2 } = await resolveApiBase(mode);
|
|
142
143
|
const websiteName2 = process.env.WEBSITE_NAME ?? configWebsiteName2 ?? "default";
|
|
143
|
-
const { runSharded } = await import("../shard-runner-
|
|
144
|
+
const { runSharded } = await import("../shard-runner-BSUEe9p3.js");
|
|
144
145
|
const code = await runSharded({
|
|
145
146
|
shards: shardsOpt ?? "auto",
|
|
146
147
|
mode,
|
|
@@ -174,6 +175,7 @@ Environment:
|
|
|
174
175
|
let redirects = [];
|
|
175
176
|
let cmsPathSet = /* @__PURE__ */ new Set();
|
|
176
177
|
let cachedAppPaths = [];
|
|
178
|
+
let collectionItems;
|
|
177
179
|
const productionBuild = process.env.NODE_ENV === "production" || mode === "production";
|
|
178
180
|
try {
|
|
179
181
|
const siteData = siteDataFile ? JSON.parse(await fs.readFile(siteDataFile, "utf8")) : await fetchCmsSiteData(apiBase, websiteName, buildRequest);
|
|
@@ -183,6 +185,7 @@ Environment:
|
|
|
183
185
|
website = siteData.website;
|
|
184
186
|
websiteId = siteData.websiteId;
|
|
185
187
|
redirects = siteData.redirects;
|
|
188
|
+
collectionItems = siteData.collectionItems;
|
|
186
189
|
if (!siteDataFile) {
|
|
187
190
|
console.log(` Found ${paths.length} CMS routes`);
|
|
188
191
|
if (redirects.length > 0) console.log(` Found ${redirects.length} redirects`);
|
|
@@ -192,6 +195,9 @@ Environment:
|
|
|
192
195
|
if (productionBuild) throw err;
|
|
193
196
|
paths = ["/"];
|
|
194
197
|
}
|
|
198
|
+
if (collectionItems && Object.keys(collectionItems).length > 0) {
|
|
199
|
+
setCollectionResolver(buildCollectionResolver(collectionItems));
|
|
200
|
+
}
|
|
195
201
|
for (const p of extraPaths) {
|
|
196
202
|
if (!paths.includes(p)) paths.push(p);
|
|
197
203
|
}
|
package/dist/ssg/client.mjs
CHANGED