@bagelink/blox 1.15.504 → 1.15.506

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,6 @@
1
- import fs from "node:fs/promises";
2
- import path from "node:path";
1
+ import { execFile } from "node:child_process";
2
+ import fs, { readFile } from "node:fs/promises";
3
+ import path, { resolve } from "node:path";
3
4
  import process$1 from "node:process";
4
5
  import { pathToFileURL } from "node:url";
5
6
  import { r as resolvePageTitle, p as primaryPageContext, c as contextPageTitle } from "./pageTitle-BOTMH-D8.js";
@@ -49,8 +50,41 @@ function localizePath(slug, locale, defaultLocale) {
49
50
  const s = slug === "" || slug === "/" ? "" : slug;
50
51
  return `/${locale}${s}`;
51
52
  }
53
+ function expandLocalePaths(paths, defaultLocale, supportedLocales) {
54
+ const locales = supportedLocales.length > 0 ? supportedLocales : [defaultLocale];
55
+ const out = [];
56
+ for (const slug of paths) {
57
+ for (const loc of locales) {
58
+ out.push(localizePath(slug, loc, defaultLocale));
59
+ }
60
+ }
61
+ return [...new Set(out)];
62
+ }
52
63
  async function fetchCmsSiteData(apiBase, websiteName, requestOptions = {}) {
53
- var _a;
64
+ var _a, _b, _c;
65
+ const websiteId = typeof process !== "undefined" ? (_b = (_a = process.env) == null ? void 0 : _a.BLOX_WEBSITE_ID) == null ? void 0 : _b.trim() : void 0;
66
+ if (websiteId) {
67
+ const bundle = await bloxBuildJson(
68
+ `${apiBase}/blox-build/websites/${websiteId}/published`,
69
+ {},
70
+ requestOptions
71
+ );
72
+ const website2 = bundle.website;
73
+ const defaultLocale2 = website2.default_locale || "en";
74
+ const paths2 = await expandRoutes(apiBase, bundle.pages, requestOptions, defaultLocale2);
75
+ const localizedPaths = expandLocalePaths(
76
+ paths2,
77
+ defaultLocale2,
78
+ website2.supported_locales ?? [defaultLocale2]
79
+ );
80
+ return {
81
+ websiteId,
82
+ website: website2,
83
+ paths: localizedPaths,
84
+ redirects: bundle.redirects.filter((redirect) => redirect.from_path && redirect.to_path),
85
+ collections: extractCollectionRefs(bundle.pages)
86
+ };
87
+ }
54
88
  const sitesData = await bloxBuildJson(`${apiBase}/blox/websites`, {}, requestOptions);
55
89
  const sites = Array.isArray(sitesData) ? sitesData : sitesData.data ?? [];
56
90
  const site = sites.find((s) => s.name === websiteName);
@@ -69,12 +103,12 @@ async function fetchCmsSiteData(apiBase, websiteName, requestOptions = {}) {
69
103
  requestOptions
70
104
  );
71
105
  const pages = Array.isArray(pagesData) ? pagesData : pagesData.data ?? [];
72
- const localePaths = await expandRoutes(apiBase, pages, requestOptions);
106
+ const localePaths = await expandRoutes(apiBase, pages, requestOptions, locale);
73
107
  return { locale, pages, paths: localePaths.map((path2) => localizePath(path2, locale, defaultLocale)) };
74
108
  }));
75
109
  const paths = [...new Set(localizedPages.flatMap((result) => result.paths))];
76
110
  const pathSet = new Set(paths);
77
- const defaultPages = ((_a = localizedPages.find((result) => result.locale === defaultLocale)) == null ? void 0 : _a.pages) ?? [];
111
+ const defaultPages = ((_c = localizedPages.find((result) => result.locale === defaultLocale)) == null ? void 0 : _c.pages) ?? [];
78
112
  const canonicalSlugById = new Map(
79
113
  defaultPages.flatMap((page) => page.id && page.slug && !page.slug.includes(":") ? [[page.id, page.slug]] : [])
80
114
  );
@@ -107,7 +141,7 @@ async function fetchCmsPrerenderPaths(apiBase, websiteName, requestOptions = {})
107
141
  const { paths } = await fetchCmsSiteData(apiBase, websiteName, requestOptions);
108
142
  return paths;
109
143
  }
110
- async function expandRoutes(apiBase, pages, requestOptions) {
144
+ async function expandRoutes(apiBase, pages, requestOptions, locale) {
111
145
  const routes = [];
112
146
  for (const page of pages) {
113
147
  const slug = page.slug ?? "/";
@@ -117,8 +151,9 @@ async function expandRoutes(apiBase, pages, requestOptions) {
117
151
  const b = binding;
118
152
  if (b.adapter === "datastore" && b.collection != null && b.collection !== "" && b.store != null && b.store !== "" && b.bind_by != null && b.bind_by !== "") {
119
153
  const q = b.filter ? `&q=${encodeURIComponent(b.filter)}` : "";
154
+ const localeParam = locale ? `&locale=${encodeURIComponent(locale)}` : "";
120
155
  const itemsData = await bloxBuildJson(
121
- `${apiBase}/datastore/${b.store}/collections/${b.collection}?limit=200${q}`,
156
+ `${apiBase}/datastore/${b.store}/collections/${b.collection}?limit=200${localeParam}${q}`,
122
157
  {},
123
158
  requestOptions
124
159
  );
@@ -162,6 +197,52 @@ function extractCollectionRefs(pages) {
162
197
  }
163
198
  return refs;
164
199
  }
200
+ function environment(name) {
201
+ var _a;
202
+ return ((_a = process$1.env[name]) == null ? void 0 : _a.trim()) || void 0;
203
+ }
204
+ async function gitValue(args) {
205
+ const stdout = await new Promise((resolvePromise, reject) => {
206
+ execFile("git", args, { cwd: process$1.cwd(), encoding: "utf8" }, (error, result) => {
207
+ if (error) reject(error);
208
+ else resolvePromise(result);
209
+ });
210
+ });
211
+ return stdout.trim();
212
+ }
213
+ function normalizeRepository(repository) {
214
+ return repository.replace(/^git@github\.com:/, "https://github.com/").replace(/\.git$/, "");
215
+ }
216
+ async function resolveManifestProvenance() {
217
+ const repository = environment("BLOX_REPOSITORY") ?? environment("REPOSITORY_URL") ?? await gitValue(["config", "--get", "remote.origin.url"]);
218
+ const branch = environment("BLOX_BRANCH") ?? environment("BRANCH") ?? await gitValue(["rev-parse", "--abbrev-ref", "HEAD"]);
219
+ const commit = environment("BLOX_COMMIT") ?? environment("COMMIT_REF") ?? await gitValue(["rev-parse", "HEAD"]);
220
+ return {
221
+ repository: normalizeRepository(repository),
222
+ branch,
223
+ commit
224
+ };
225
+ }
226
+ async function uploadBloxManifest(apiBase, websiteId) {
227
+ if (!environment("BLOX_BUILD_TOKEN")) {
228
+ throw new Error("BLOX_BUILD_TOKEN is required to upload the Blox manifest");
229
+ }
230
+ const distDirectory = resolve(process$1.cwd(), "dist");
231
+ const resolvedManifestPath = resolve(distDirectory, ".blox-manifest.json");
232
+ const manifest = JSON.parse(await readFile(resolvedManifestPath, "utf8"));
233
+ const payload = {
234
+ manifest,
235
+ provenance: await resolveManifestProvenance()
236
+ };
237
+ await bloxBuildJson(
238
+ `${apiBase.replace(/\/$/, "")}/blox-build/websites/${websiteId}/manifest`,
239
+ {
240
+ method: "PUT",
241
+ headers: { "Content-Type": "application/json" },
242
+ body: JSON.stringify(payload)
243
+ }
244
+ );
245
+ }
165
246
  async function polyfillBloxSsgGlobals(options) {
166
247
  const { env: env2 } = await import("node:process");
167
248
  const pageUrl = (options == null ? void 0 : options.pageUrl) ?? env2.BAGELINK_API_URL ?? "https://example.com/";
@@ -719,7 +800,7 @@ async function prerender({
719
800
  console.warn(
720
801
  `[prerender] resolve prefetch retry ${attempt}/${prefetchAttempts} for ${url} in ${delay}ms: ${error.message}`
721
802
  );
722
- if (delay) await new Promise((resolve) => setTimeout(resolve, delay));
803
+ if (delay) await new Promise((resolve2) => setTimeout(resolve2, delay));
723
804
  }
724
805
  }
725
806
  throw new Error(`CMS route "${url}" resolve prefetch exhausted retries`);
@@ -1018,5 +1099,7 @@ export {
1018
1099
  getBloxBuildRequestOptions as q,
1019
1100
  getSiteIconFlags as r,
1020
1101
  mergeLlmParts as s,
1021
- llmArtifacts as t
1102
+ resolveManifestProvenance as t,
1103
+ uploadBloxManifest as u,
1104
+ llmArtifacts as v
1022
1105
  };
@@ -21,6 +21,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
21
21
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
22
22
  mod
23
23
  ));
24
+ const node_child_process = require("node:child_process");
24
25
  const fs = require("node:fs/promises");
25
26
  const path = require("node:path");
26
27
  const process$1 = require("node:process");
@@ -72,8 +73,41 @@ function localizePath(slug, locale, defaultLocale) {
72
73
  const s = slug === "" || slug === "/" ? "" : slug;
73
74
  return `/${locale}${s}`;
74
75
  }
76
+ function expandLocalePaths(paths, defaultLocale, supportedLocales) {
77
+ const locales = supportedLocales.length > 0 ? supportedLocales : [defaultLocale];
78
+ const out = [];
79
+ for (const slug of paths) {
80
+ for (const loc of locales) {
81
+ out.push(localizePath(slug, loc, defaultLocale));
82
+ }
83
+ }
84
+ return [...new Set(out)];
85
+ }
75
86
  async function fetchCmsSiteData(apiBase, websiteName, requestOptions = {}) {
76
- var _a;
87
+ var _a, _b, _c;
88
+ const websiteId = typeof process !== "undefined" ? (_b = (_a = process.env) == null ? void 0 : _a.BLOX_WEBSITE_ID) == null ? void 0 : _b.trim() : void 0;
89
+ if (websiteId) {
90
+ const bundle = await bloxBuildJson(
91
+ `${apiBase}/blox-build/websites/${websiteId}/published`,
92
+ {},
93
+ requestOptions
94
+ );
95
+ const website2 = bundle.website;
96
+ const defaultLocale2 = website2.default_locale || "en";
97
+ const paths2 = await expandRoutes(apiBase, bundle.pages, requestOptions, defaultLocale2);
98
+ const localizedPaths = expandLocalePaths(
99
+ paths2,
100
+ defaultLocale2,
101
+ website2.supported_locales ?? [defaultLocale2]
102
+ );
103
+ return {
104
+ websiteId,
105
+ website: website2,
106
+ paths: localizedPaths,
107
+ redirects: bundle.redirects.filter((redirect) => redirect.from_path && redirect.to_path),
108
+ collections: extractCollectionRefs(bundle.pages)
109
+ };
110
+ }
77
111
  const sitesData = await bloxBuildJson(`${apiBase}/blox/websites`, {}, requestOptions);
78
112
  const sites = Array.isArray(sitesData) ? sitesData : sitesData.data ?? [];
79
113
  const site = sites.find((s) => s.name === websiteName);
@@ -92,12 +126,12 @@ async function fetchCmsSiteData(apiBase, websiteName, requestOptions = {}) {
92
126
  requestOptions
93
127
  );
94
128
  const pages = Array.isArray(pagesData) ? pagesData : pagesData.data ?? [];
95
- const localePaths = await expandRoutes(apiBase, pages, requestOptions);
129
+ const localePaths = await expandRoutes(apiBase, pages, requestOptions, locale);
96
130
  return { locale, pages, paths: localePaths.map((path2) => localizePath(path2, locale, defaultLocale)) };
97
131
  }));
98
132
  const paths = [...new Set(localizedPages.flatMap((result) => result.paths))];
99
133
  const pathSet = new Set(paths);
100
- const defaultPages = ((_a = localizedPages.find((result) => result.locale === defaultLocale)) == null ? void 0 : _a.pages) ?? [];
134
+ const defaultPages = ((_c = localizedPages.find((result) => result.locale === defaultLocale)) == null ? void 0 : _c.pages) ?? [];
101
135
  const canonicalSlugById = new Map(
102
136
  defaultPages.flatMap((page) => page.id && page.slug && !page.slug.includes(":") ? [[page.id, page.slug]] : [])
103
137
  );
@@ -130,7 +164,7 @@ async function fetchCmsPrerenderPaths(apiBase, websiteName, requestOptions = {})
130
164
  const { paths } = await fetchCmsSiteData(apiBase, websiteName, requestOptions);
131
165
  return paths;
132
166
  }
133
- async function expandRoutes(apiBase, pages, requestOptions) {
167
+ async function expandRoutes(apiBase, pages, requestOptions, locale) {
134
168
  const routes = [];
135
169
  for (const page of pages) {
136
170
  const slug = page.slug ?? "/";
@@ -140,8 +174,9 @@ async function expandRoutes(apiBase, pages, requestOptions) {
140
174
  const b = binding;
141
175
  if (b.adapter === "datastore" && b.collection != null && b.collection !== "" && b.store != null && b.store !== "" && b.bind_by != null && b.bind_by !== "") {
142
176
  const q = b.filter ? `&q=${encodeURIComponent(b.filter)}` : "";
177
+ const localeParam = locale ? `&locale=${encodeURIComponent(locale)}` : "";
143
178
  const itemsData = await bloxBuildJson(
144
- `${apiBase}/datastore/${b.store}/collections/${b.collection}?limit=200${q}`,
179
+ `${apiBase}/datastore/${b.store}/collections/${b.collection}?limit=200${localeParam}${q}`,
145
180
  {},
146
181
  requestOptions
147
182
  );
@@ -185,6 +220,52 @@ function extractCollectionRefs(pages) {
185
220
  }
186
221
  return refs;
187
222
  }
223
+ function environment(name) {
224
+ var _a;
225
+ return ((_a = process$1.env[name]) == null ? void 0 : _a.trim()) || void 0;
226
+ }
227
+ async function gitValue(args) {
228
+ const stdout = await new Promise((resolvePromise, reject) => {
229
+ node_child_process.execFile("git", args, { cwd: process$1.cwd(), encoding: "utf8" }, (error, result) => {
230
+ if (error) reject(error);
231
+ else resolvePromise(result);
232
+ });
233
+ });
234
+ return stdout.trim();
235
+ }
236
+ function normalizeRepository(repository) {
237
+ return repository.replace(/^git@github\.com:/, "https://github.com/").replace(/\.git$/, "");
238
+ }
239
+ async function resolveManifestProvenance() {
240
+ const repository = environment("BLOX_REPOSITORY") ?? environment("REPOSITORY_URL") ?? await gitValue(["config", "--get", "remote.origin.url"]);
241
+ const branch = environment("BLOX_BRANCH") ?? environment("BRANCH") ?? await gitValue(["rev-parse", "--abbrev-ref", "HEAD"]);
242
+ const commit = environment("BLOX_COMMIT") ?? environment("COMMIT_REF") ?? await gitValue(["rev-parse", "HEAD"]);
243
+ return {
244
+ repository: normalizeRepository(repository),
245
+ branch,
246
+ commit
247
+ };
248
+ }
249
+ async function uploadBloxManifest(apiBase, websiteId) {
250
+ if (!environment("BLOX_BUILD_TOKEN")) {
251
+ throw new Error("BLOX_BUILD_TOKEN is required to upload the Blox manifest");
252
+ }
253
+ const distDirectory = path.resolve(process$1.cwd(), "dist");
254
+ const resolvedManifestPath = path.resolve(distDirectory, ".blox-manifest.json");
255
+ const manifest = JSON.parse(await fs.readFile(resolvedManifestPath, "utf8"));
256
+ const payload = {
257
+ manifest,
258
+ provenance: await resolveManifestProvenance()
259
+ };
260
+ await bloxBuildJson(
261
+ `${apiBase.replace(/\/$/, "")}/blox-build/websites/${websiteId}/manifest`,
262
+ {
263
+ method: "PUT",
264
+ headers: { "Content-Type": "application/json" },
265
+ body: JSON.stringify(payload)
266
+ }
267
+ );
268
+ }
188
269
  async function polyfillBloxSsgGlobals(options) {
189
270
  const { env: env2 } = await import("node:process");
190
271
  const pageUrl = (options == null ? void 0 : options.pageUrl) ?? env2.BAGELINK_API_URL ?? "https://example.com/";
@@ -1041,3 +1122,5 @@ exports.mergeLlmParts = mergeLlmParts;
1041
1122
  exports.polyfillBloxSsgGlobals = polyfillBloxSsgGlobals;
1042
1123
  exports.prerender = prerender;
1043
1124
  exports.primaryContextEntry = primaryContextEntry;
1125
+ exports.resolveManifestProvenance = resolveManifestProvenance;
1126
+ exports.uploadBloxManifest = uploadBloxManifest;
@@ -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 generateSitemapXml } from "./prerender-DcWClubo.js";
5
+ import { f as fetchCmsSiteData, g as generateSitemapXml } from "./prerender-BsxH6wHP.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
  function resolveShardCount(shards) {
@@ -109,7 +109,7 @@ async function runSharded(opts) {
109
109
  }
110
110
  if (process.env.BLOX_SSG_LLM !== "0") {
111
111
  try {
112
- const { mergeLlmParts } = await import("./prerender-DcWClubo.js").then((n) => n.t);
112
+ const { mergeLlmParts } = await import("./prerender-BsxH6wHP.js").then((n) => n.v);
113
113
  const mergeWebsite = website;
114
114
  const partFiles = Array.from({ length: total }, (_, i) => path.join(llmPartsDir, `part.${i}.json`));
115
115
  const { pages } = await mergeLlmParts({
@@ -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("./prerender-JdRKimQ5.cjs");
29
+ const llmArtifacts = require("./prerender-_ap-rfba.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
  function resolveShardCount(shards) {
@@ -133,7 +133,7 @@ async function runSharded(opts) {
133
133
  }
134
134
  if (process.env.BLOX_SSG_LLM !== "0") {
135
135
  try {
136
- const { mergeLlmParts } = await Promise.resolve().then(() => require("./prerender-JdRKimQ5.cjs")).then((n) => n.llmArtifacts);
136
+ const { mergeLlmParts } = await Promise.resolve().then(() => require("./prerender-_ap-rfba.cjs")).then((n) => n.llmArtifacts);
137
137
  const mergeWebsite = website;
138
138
  const partFiles = Array.from({ length: total }, (_, i) => path.join(llmPartsDir, `part.${i}.json`));
139
139
  const { pages } = await mergeLlmParts({
package/dist/ssg/cli.cjs CHANGED
@@ -2,7 +2,7 @@
2
2
  "use strict";
3
3
  const process = require("node:process");
4
4
  const fs = require("node:fs/promises");
5
- const llmArtifacts = require("../prerender-JdRKimQ5.cjs");
5
+ const llmArtifacts = require("../prerender-_ap-rfba.cjs");
6
6
  function installFetchTimeout() {
7
7
  const ms = Number(process.env.BLOX_SSG_FETCH_TIMEOUT_MS) || 2e4;
8
8
  const original = globalThis.fetch;
@@ -13,6 +13,9 @@ function installFetchTimeout() {
13
13
  globalThis.fetch = Object.assign(wrapped, original);
14
14
  }
15
15
  async function resolveApiBase(mode) {
16
+ if (process.env.BLOX_API_URL != null && process.env.BLOX_API_URL !== "") {
17
+ return { apiBase: process.env.BLOX_API_URL };
18
+ }
16
19
  if (process.env.BAGELINK_API_URL != null && process.env.BAGELINK_API_URL !== "") {
17
20
  return { apiBase: process.env.BAGELINK_API_URL };
18
21
  }
@@ -40,6 +43,7 @@ async function resolveApiBase(mode) {
40
43
  return { apiBase: "https://localhost:8000" };
41
44
  }
42
45
  async function main() {
46
+ var _a, _b;
43
47
  installFetchTimeout();
44
48
  const argv = process.argv.slice(2);
45
49
  const extraPaths = [];
@@ -94,6 +98,9 @@ Options:
94
98
  --help, -h Show this help
95
99
 
96
100
  Environment:
101
+ BLOX_API_URL Build API base URL
102
+ BLOX_WEBSITE_ID Website ID for manifest upload
103
+ BLOX_BUILD_TOKEN Server-only build credential
97
104
  BAGELINK_API_URL Override API base URL
98
105
  WEBSITE_NAME Override CMS website name
99
106
  BLOX_SSG_SHARD_CAP Cap for --shards=auto (default 6)
@@ -116,7 +123,7 @@ Environment:
116
123
  if (shardsOpt !== null || routesCmd) {
117
124
  const { apiBase: apiBase2, websiteName: configWebsiteName2 } = await resolveApiBase(mode);
118
125
  const websiteName2 = process.env.WEBSITE_NAME ?? configWebsiteName2 ?? "default";
119
- const { runSharded } = await Promise.resolve().then(() => require("../shard-runner-DLCODqJs.cjs"));
126
+ const { runSharded } = await Promise.resolve().then(() => require("../shard-runner-DT0wvI1a.cjs"));
120
127
  const code = await runSharded({
121
128
  shards: shardsOpt ?? "auto",
122
129
  mode,
@@ -126,6 +133,12 @@ Environment:
126
133
  passthroughArgs,
127
134
  routesCmd: routesCmd || void 0
128
135
  });
136
+ if (code === 0 && (process.env.NODE_ENV === "production" || mode === "production")) {
137
+ const uploadWebsiteId = (_a = process.env.BLOX_WEBSITE_ID) == null ? void 0 : _a.trim();
138
+ if (!uploadWebsiteId) throw new Error("BLOX_WEBSITE_ID is required to upload the Blox manifest");
139
+ await llmArtifacts.uploadBloxManifest(apiBase2, uploadWebsiteId);
140
+ console.log("Uploaded .blox-manifest.json with Git provenance");
141
+ }
129
142
  process.exitCode = code;
130
143
  return;
131
144
  }
@@ -240,6 +253,12 @@ ${"=".repeat(60)}`);
240
253
  process.exitCode = 1;
241
254
  }
242
255
  }
256
+ if (productionBuild && shardTotal === 1) {
257
+ const uploadWebsiteId = ((_b = process.env.BLOX_WEBSITE_ID) == null ? void 0 : _b.trim()) || websiteId;
258
+ if (!uploadWebsiteId) throw new Error("BLOX_WEBSITE_ID is required to upload the Blox manifest");
259
+ await llmArtifacts.uploadBloxManifest(apiBase, uploadWebsiteId);
260
+ console.log("Uploaded .blox-manifest.json with Git provenance");
261
+ }
243
262
  } catch (err) {
244
263
  console.error("Fatal error:", err);
245
264
  process.exitCode = 1;
package/dist/ssg/cli.d.ts CHANGED
@@ -14,7 +14,8 @@
14
14
  * WEBSITE_NAME env var overrides the website name (defaults from config or 'default').
15
15
  *
16
16
  * Env overrides:
17
- * BAGELINK_API_URL — skip config, use this host directly
17
+ * BLOX_API_URL — build API base URL
18
+ * BAGELINK_API_URL — legacy build API base URL
18
19
  * WEBSITE_NAME — CMS website name
19
20
  */
20
21
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/ssg/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;GAiBG"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/ssg/cli.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;GAkBG"}
package/dist/ssg/cli.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env bun
2
2
  import process from "node:process";
3
3
  import fs from "node:fs/promises";
4
- import { p as polyfillBloxSsgGlobals, f as fetchCmsSiteData, a as prerender } from "../prerender-DcWClubo.js";
4
+ import { u as uploadBloxManifest, p as polyfillBloxSsgGlobals, f as fetchCmsSiteData, a as prerender } from "../prerender-BsxH6wHP.js";
5
5
  function installFetchTimeout() {
6
6
  const ms = Number(process.env.BLOX_SSG_FETCH_TIMEOUT_MS) || 2e4;
7
7
  const original = globalThis.fetch;
@@ -12,6 +12,9 @@ function installFetchTimeout() {
12
12
  globalThis.fetch = Object.assign(wrapped, original);
13
13
  }
14
14
  async function resolveApiBase(mode) {
15
+ if (process.env.BLOX_API_URL != null && process.env.BLOX_API_URL !== "") {
16
+ return { apiBase: process.env.BLOX_API_URL };
17
+ }
15
18
  if (process.env.BAGELINK_API_URL != null && process.env.BAGELINK_API_URL !== "") {
16
19
  return { apiBase: process.env.BAGELINK_API_URL };
17
20
  }
@@ -39,6 +42,7 @@ async function resolveApiBase(mode) {
39
42
  return { apiBase: "https://localhost:8000" };
40
43
  }
41
44
  async function main() {
45
+ var _a, _b;
42
46
  installFetchTimeout();
43
47
  const argv = process.argv.slice(2);
44
48
  const extraPaths = [];
@@ -93,6 +97,9 @@ Options:
93
97
  --help, -h Show this help
94
98
 
95
99
  Environment:
100
+ BLOX_API_URL Build API base URL
101
+ BLOX_WEBSITE_ID Website ID for manifest upload
102
+ BLOX_BUILD_TOKEN Server-only build credential
96
103
  BAGELINK_API_URL Override API base URL
97
104
  WEBSITE_NAME Override CMS website name
98
105
  BLOX_SSG_SHARD_CAP Cap for --shards=auto (default 6)
@@ -115,7 +122,7 @@ Environment:
115
122
  if (shardsOpt !== null || routesCmd) {
116
123
  const { apiBase: apiBase2, websiteName: configWebsiteName2 } = await resolveApiBase(mode);
117
124
  const websiteName2 = process.env.WEBSITE_NAME ?? configWebsiteName2 ?? "default";
118
- const { runSharded } = await import("../shard-runner-BfoWrtHB.js");
125
+ const { runSharded } = await import("../shard-runner-BkVwCHM_.js");
119
126
  const code = await runSharded({
120
127
  shards: shardsOpt ?? "auto",
121
128
  mode,
@@ -125,6 +132,12 @@ Environment:
125
132
  passthroughArgs,
126
133
  routesCmd: routesCmd || void 0
127
134
  });
135
+ if (code === 0 && (process.env.NODE_ENV === "production" || mode === "production")) {
136
+ const uploadWebsiteId = (_a = process.env.BLOX_WEBSITE_ID) == null ? void 0 : _a.trim();
137
+ if (!uploadWebsiteId) throw new Error("BLOX_WEBSITE_ID is required to upload the Blox manifest");
138
+ await uploadBloxManifest(apiBase2, uploadWebsiteId);
139
+ console.log("Uploaded .blox-manifest.json with Git provenance");
140
+ }
128
141
  process.exitCode = code;
129
142
  return;
130
143
  }
@@ -239,6 +252,12 @@ ${"=".repeat(60)}`);
239
252
  process.exitCode = 1;
240
253
  }
241
254
  }
255
+ if (productionBuild && shardTotal === 1) {
256
+ const uploadWebsiteId = ((_b = process.env.BLOX_WEBSITE_ID) == null ? void 0 : _b.trim()) || websiteId;
257
+ if (!uploadWebsiteId) throw new Error("BLOX_WEBSITE_ID is required to upload the Blox manifest");
258
+ await uploadBloxManifest(apiBase, uploadWebsiteId);
259
+ console.log("Uploaded .blox-manifest.json with Git provenance");
260
+ }
242
261
  } catch (err) {
243
262
  console.error("Fatal error:", err);
244
263
  process.exitCode = 1;
@@ -1 +1 @@
1
- {"version":3,"file":"cms-routes.d.ts","sourceRoot":"","sources":["../../src/ssg/cms-routes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAC1C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAA;AAc9D,2EAA2E;AAC3E,MAAM,WAAW,aAAa;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,WAAW;IAC3B,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,WAAW,CAAA;IACpB,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,SAAS,EAAE,aAAa,EAAE,CAAA;IAC1B,oEAAoE;IACpE,WAAW,EAAE,aAAa,EAAE,CAAA;CAC5B;AAYD;;;GAGG;AACH,wBAAgB,iBAAiB,CAChC,KAAK,EAAE,MAAM,EAAE,EACf,aAAa,EAAE,MAAM,EACrB,gBAAgB,EAAE,MAAM,EAAE,GACxB,MAAM,EAAE,CASV;AAMD;;;GAGG;AACH,wBAAsB,gBAAgB,CACrC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,cAAc,GAAE,uBAA4B,GAC1C,OAAO,CAAC,WAAW,CAAC,CAgFtB;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC3C,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,cAAc,GAAE,uBAA4B,GAC1C,OAAO,CAAC,MAAM,EAAE,CAAC,CAGnB"}
1
+ {"version":3,"file":"cms-routes.d.ts","sourceRoot":"","sources":["../../src/ssg/cms-routes.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,OAAO,CAAA;AAC1C,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAA;AAoB9D,2EAA2E;AAC3E,MAAM,WAAW,aAAa;IAC7B,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,WAAW;IAC3B,SAAS,EAAE,MAAM,CAAA;IACjB,OAAO,EAAE,WAAW,CAAA;IACpB,KAAK,EAAE,MAAM,EAAE,CAAA;IACf,SAAS,EAAE,aAAa,EAAE,CAAA;IAC1B,oEAAoE;IACpE,WAAW,EAAE,aAAa,EAAE,CAAA;CAC5B;AAYD;;;GAGG;AACH,wBAAgB,iBAAiB,CAChC,KAAK,EAAE,MAAM,EAAE,EACf,aAAa,EAAE,MAAM,EACrB,gBAAgB,EAAE,MAAM,EAAE,GACxB,MAAM,EAAE,CASV;AAMD;;;GAGG;AACH,wBAAsB,gBAAgB,CACrC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,cAAc,GAAE,uBAA4B,GAC1C,OAAO,CAAC,WAAW,CAAC,CAwGtB;AAED;;GAEG;AACH,wBAAsB,sBAAsB,CAC3C,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,cAAc,GAAE,uBAA4B,GAC1C,OAAO,CAAC,MAAM,EAAE,CAAC,CAGnB"}
@@ -22,7 +22,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
22
22
  mod
23
23
  ));
24
24
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
25
- const llmArtifacts = require("../prerender-JdRKimQ5.cjs");
25
+ const llmArtifacts = require("../prerender-_ap-rfba.cjs");
26
26
  const ssg_client = require("./client.cjs");
27
27
  const pinia = require("pinia");
28
28
  const vue = require("vue");
@@ -254,6 +254,8 @@ exports.getSiteIconFlags = llmArtifacts.getSiteIconFlags;
254
254
  exports.mergeLlmParts = llmArtifacts.mergeLlmParts;
255
255
  exports.polyfillBloxSsgGlobals = llmArtifacts.polyfillBloxSsgGlobals;
256
256
  exports.prerender = llmArtifacts.prerender;
257
+ exports.resolveManifestProvenance = llmArtifacts.resolveManifestProvenance;
258
+ exports.uploadBloxManifest = llmArtifacts.uploadBloxManifest;
257
259
  exports.BLOX_COLLECTIONS_WINDOW_KEY = ssg_client.BLOX_COLLECTIONS_WINDOW_KEY;
258
260
  exports.BLOX_DATA_WINDOW_KEY = ssg_client.BLOX_DATA_WINDOW_KEY;
259
261
  exports.BLOX_PAGE_SEO_WINDOW_KEY = ssg_client.BLOX_PAGE_SEO_WINDOW_KEY;
@@ -27,4 +27,6 @@ export type { RedirectEntry, SeoPageData } from './seo';
27
27
  export { buildJsonLd, extractPageText, generateLlmsFullTxt, generateLlmsTxt, mergeLlmParts } from './llm-artifacts';
28
28
  export type { LlmArtifactsConfig, LlmPageEntry } from './llm-artifacts';
29
29
  export { installBloxStateCache } from './state-cache';
30
+ export { resolveManifestProvenance, uploadBloxManifest } from './manifest-upload';
31
+ export type { ManifestProvenance, ManifestUpload } from './manifest-upload';
30
32
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ssg/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AACvE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAC9D,OAAO,EAAE,sBAAsB,EAAE,aAAa,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAA;AACrH,YAAY,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAA;AAC9D,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AACrG;;;;;;;;;;GAUG;AACH,OAAO,EAAE,2BAA2B,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAA;AAC5J,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AACrD,YAAY,EAAE,YAAY,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAA;AAC/E,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAA;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AACjG,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC1D,YAAY,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC/D,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAA;AACvI,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AACvD,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,mBAAmB,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AACnH,YAAY,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ssg/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AACvE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAC9D,OAAO,EAAE,sBAAsB,EAAE,aAAa,EAAE,gBAAgB,EAAE,0BAA0B,EAAE,MAAM,iBAAiB,CAAA;AACrH,YAAY,EAAE,uBAAuB,EAAE,MAAM,iBAAiB,CAAA;AAC9D,OAAO,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAA;AACrG;;;;;;;;;;GAUG;AACH,OAAO,EAAE,2BAA2B,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAA;AAC5J,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA;AACrD,YAAY,EAAE,YAAY,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAA;AAC/E,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAA;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AACvC,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AACjG,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC1D,YAAY,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC/D,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,wBAAwB,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAA;AACvI,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,OAAO,CAAA;AACvD,OAAO,EAAE,WAAW,EAAE,eAAe,EAAE,mBAAmB,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AACnH,YAAY,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAA;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAA;AACrD,OAAO,EAAE,yBAAyB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAA;AACjF,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA"}
@@ -1,5 +1,5 @@
1
- import { b as buildPageHead, c as primaryContextEntry, d as buildJsonLd, e as extractPageText, B as BloxBuildResponseError, h as bloxBuildJson } from "../prerender-DcWClubo.js";
2
- import { i, j, k, f, l, m, n, o, g, q, r, s, p, a } from "../prerender-DcWClubo.js";
1
+ import { b as buildPageHead, c as primaryContextEntry, d as buildJsonLd, e as extractPageText, B as BloxBuildResponseError, h as bloxBuildJson } from "../prerender-BsxH6wHP.js";
2
+ import { i, j, k, f, l, m, n, o, g, q, r, s, p, a, t, u } from "../prerender-BsxH6wHP.js";
3
3
  import { BLOX_STATE_WINDOW_KEY, BLOX_WEBSITE_ID_WINDOW_KEY } from "./client.mjs";
4
4
  import { BLOX_COLLECTIONS_WINDOW_KEY, BLOX_DATA_WINDOW_KEY, BLOX_PAGE_SEO_WINDOW_KEY, getCollectionCache, getEmbeddedWebsiteId, installBloxStateCache, installCollectionCache } from "./client.mjs";
5
5
  import { createPinia } from "pinia";
@@ -243,5 +243,7 @@ export {
243
243
  s as mergeLlmParts,
244
244
  p as polyfillBloxSsgGlobals,
245
245
  a as prerender,
246
- renderBloxSsgPage
246
+ renderBloxSsgPage,
247
+ t as resolveManifestProvenance,
248
+ u as uploadBloxManifest
247
249
  };
@@ -0,0 +1,13 @@
1
+ import { BloxManifest } from '../manifest';
2
+ export interface ManifestProvenance {
3
+ repository: string;
4
+ branch: string;
5
+ commit: string;
6
+ }
7
+ export interface ManifestUpload {
8
+ manifest: BloxManifest;
9
+ provenance: ManifestProvenance;
10
+ }
11
+ export declare function resolveManifestProvenance(): Promise<ManifestProvenance>;
12
+ export declare function uploadBloxManifest(apiBase: string, websiteId: string): Promise<void>;
13
+ //# sourceMappingURL=manifest-upload.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest-upload.d.ts","sourceRoot":"","sources":["../../src/ssg/manifest-upload.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAO/C,MAAM,WAAW,kBAAkB;IAClC,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,EAAE,MAAM,CAAA;CACd;AAED,MAAM,WAAW,cAAc;IAC9B,QAAQ,EAAE,YAAY,CAAA;IACtB,UAAU,EAAE,kBAAkB,CAAA;CAC9B;AAsBD,wBAAsB,yBAAyB,IAAI,OAAO,CAAC,kBAAkB,CAAC,CAgB7E;AAED,wBAAsB,kBAAkB,CACvC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,CAAC,CAmBf"}
@@ -165,12 +165,17 @@ function bloxPlugin(options = {}) {
165
165
  }
166
166
  if (options.emitManifest ?? false) {
167
167
  const glob = options.manifestGlob ?? "./src/components/blocks/*.vue";
168
+ const manifestGlob = glob.startsWith("/") ? glob : `/${glob.replace(/^\.\//, "")}`;
168
169
  const fileName = options.manifestFileName ?? ".blox-manifest.json";
170
+ if (fileName.startsWith("/") || fileName.split(/[\\/]/).includes("..")) {
171
+ throw new Error("manifestFileName must stay within the Vite output directory");
172
+ }
169
173
  const VIRTUAL_ENTRY = "virtual:blox-manifest-entry";
170
174
  const RESOLVED_ENTRY = `\0${VIRTUAL_ENTRY}`;
171
175
  let root = process.cwd();
172
176
  let outDir = "dist";
173
177
  let isSsrBuild = false;
178
+ let vuePlugin;
174
179
  plugins.push({
175
180
  name: "vite-plugin-blox-manifest",
176
181
  apply: "build",
@@ -178,6 +183,7 @@ function bloxPlugin(options = {}) {
178
183
  root = resolved.root;
179
184
  outDir = resolved.build.outDir;
180
185
  isSsrBuild = !!resolved.build.ssr;
186
+ vuePlugin = resolved.plugins.find((plugin) => plugin.name === "vite:vue");
181
187
  },
182
188
  resolveId(id) {
183
189
  if (id === VIRTUAL_ENTRY) return RESOLVED_ENTRY;
@@ -190,7 +196,7 @@ function bloxPlugin(options = {}) {
190
196
  return [
191
197
  `import { createBlox } from '@bagelink/blox'`,
192
198
  `import { serializeRegistry } from '@bagelink/blox'`,
193
- `const mods = import.meta.glob(${JSON.stringify(glob)}, { eager: true })`,
199
+ `const mods = import.meta.glob(${JSON.stringify(manifestGlob)}, { eager: true })`,
194
200
  `export function build() {`,
195
201
  ` const blox = createBlox({ modules: mods })`,
196
202
  ` return serializeRegistry(blox.getRegistry())`,
@@ -206,7 +212,28 @@ function bloxPlugin(options = {}) {
206
212
  configFile: false,
207
213
  logLevel: "silent",
208
214
  server: { middlewareMode: true, hmr: false },
209
- plugins: bloxPlugin()
215
+ plugins: [
216
+ {
217
+ name: "vite-plugin-blox-manifest-entry",
218
+ resolveId(id) {
219
+ if (id === VIRTUAL_ENTRY) return RESOLVED_ENTRY;
220
+ },
221
+ load(id) {
222
+ if (id !== RESOLVED_ENTRY) return;
223
+ return [
224
+ `import { createBlox } from '@bagelink/blox'`,
225
+ `import { serializeRegistry } from '@bagelink/blox'`,
226
+ `const mods = import.meta.glob(${JSON.stringify(manifestGlob)}, { eager: true })`,
227
+ `export function build() {`,
228
+ ` const blox = createBlox({ modules: mods })`,
229
+ ` return serializeRegistry(blox.getRegistry())`,
230
+ `}`
231
+ ].join("\n");
232
+ }
233
+ },
234
+ ...vuePlugin ? [vuePlugin] : [],
235
+ ...bloxPlugin()
236
+ ]
210
237
  });
211
238
  try {
212
239
  const mod = await server.ssrLoadModule(VIRTUAL_ENTRY);
@@ -1 +1 @@
1
- {"version":3,"file":"vite-plugin.d.ts","sourceRoot":"","sources":["../src/vite-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAc,MAAM,MAAM,CAAA;AAM9C,MAAM,WAAW,iBAAiB;IACjC;;;;;OAKG;IACH,GAAG,CAAC,EAAE,OAAO,CAAA;IACb;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB;;;;;;;;;;;;;OAaG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;CACzB;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,OAAO,GAAE,iBAAsB,GAAG,MAAM,EAAE,CAyepE"}
1
+ {"version":3,"file":"vite-plugin.d.ts","sourceRoot":"","sources":["../src/vite-plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAc,MAAM,MAAM,CAAA;AAM9C,MAAM,WAAW,iBAAiB;IACjC;;;;;OAKG;IACH,GAAG,CAAC,EAAE,OAAO,CAAA;IACb;;;;;;OAMG;IACH,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB;;;;;;;;;;;;;OAaG;IACH,YAAY,CAAC,EAAE,OAAO,CAAA;IACtB;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAA;CACzB;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,OAAO,GAAE,iBAAsB,GAAG,MAAM,EAAE,CAogBpE"}
@@ -141,12 +141,17 @@ function bloxPlugin(options = {}) {
141
141
  }
142
142
  if (options.emitManifest ?? false) {
143
143
  const glob = options.manifestGlob ?? "./src/components/blocks/*.vue";
144
+ const manifestGlob = glob.startsWith("/") ? glob : `/${glob.replace(/^\.\//, "")}`;
144
145
  const fileName = options.manifestFileName ?? ".blox-manifest.json";
146
+ if (fileName.startsWith("/") || fileName.split(/[\\/]/).includes("..")) {
147
+ throw new Error("manifestFileName must stay within the Vite output directory");
148
+ }
145
149
  const VIRTUAL_ENTRY = "virtual:blox-manifest-entry";
146
150
  const RESOLVED_ENTRY = `\0${VIRTUAL_ENTRY}`;
147
151
  let root = process.cwd();
148
152
  let outDir = "dist";
149
153
  let isSsrBuild = false;
154
+ let vuePlugin;
150
155
  plugins.push({
151
156
  name: "vite-plugin-blox-manifest",
152
157
  apply: "build",
@@ -154,6 +159,7 @@ function bloxPlugin(options = {}) {
154
159
  root = resolved.root;
155
160
  outDir = resolved.build.outDir;
156
161
  isSsrBuild = !!resolved.build.ssr;
162
+ vuePlugin = resolved.plugins.find((plugin) => plugin.name === "vite:vue");
157
163
  },
158
164
  resolveId(id) {
159
165
  if (id === VIRTUAL_ENTRY) return RESOLVED_ENTRY;
@@ -166,7 +172,7 @@ function bloxPlugin(options = {}) {
166
172
  return [
167
173
  `import { createBlox } from '@bagelink/blox'`,
168
174
  `import { serializeRegistry } from '@bagelink/blox'`,
169
- `const mods = import.meta.glob(${JSON.stringify(glob)}, { eager: true })`,
175
+ `const mods = import.meta.glob(${JSON.stringify(manifestGlob)}, { eager: true })`,
170
176
  `export function build() {`,
171
177
  ` const blox = createBlox({ modules: mods })`,
172
178
  ` return serializeRegistry(blox.getRegistry())`,
@@ -182,7 +188,28 @@ function bloxPlugin(options = {}) {
182
188
  configFile: false,
183
189
  logLevel: "silent",
184
190
  server: { middlewareMode: true, hmr: false },
185
- plugins: bloxPlugin()
191
+ plugins: [
192
+ {
193
+ name: "vite-plugin-blox-manifest-entry",
194
+ resolveId(id) {
195
+ if (id === VIRTUAL_ENTRY) return RESOLVED_ENTRY;
196
+ },
197
+ load(id) {
198
+ if (id !== RESOLVED_ENTRY) return;
199
+ return [
200
+ `import { createBlox } from '@bagelink/blox'`,
201
+ `import { serializeRegistry } from '@bagelink/blox'`,
202
+ `const mods = import.meta.glob(${JSON.stringify(manifestGlob)}, { eager: true })`,
203
+ `export function build() {`,
204
+ ` const blox = createBlox({ modules: mods })`,
205
+ ` return serializeRegistry(blox.getRegistry())`,
206
+ `}`
207
+ ].join("\n");
208
+ }
209
+ },
210
+ ...vuePlugin ? [vuePlugin] : [],
211
+ ...bloxPlugin()
212
+ ]
186
213
  });
187
214
  try {
188
215
  const mod = await server.ssrLoadModule(VIRTUAL_ENTRY);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bagelink/blox",
3
3
  "type": "module",
4
- "version": "1.15.504",
4
+ "version": "1.15.506",
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",