@clarify-labs/cli 0.6.7 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -40,9 +40,9 @@ let gray_matter = require("gray-matter");
40
40
  gray_matter = __toESM(gray_matter, 1);
41
41
  let _apidevtools_swagger_parser = require("@apidevtools/swagger-parser");
42
42
  _apidevtools_swagger_parser = __toESM(_apidevtools_swagger_parser, 1);
43
+ let node_os = require("node:os");
43
44
  let node_fs_promises = require("node:fs/promises");
44
45
  let zod = require("zod");
45
- let node_os = require("node:os");
46
46
  let node_url = require("node:url");
47
47
  let vite = require("vite");
48
48
  let node_module = require("node:module");
@@ -261,8 +261,80 @@ function createContentArtifactsPlugin() {
261
261
  };
262
262
  }
263
263
  //#endregion
264
+ //#region source/core/theme.ts
265
+ var clarifyThemePresets = {
266
+ default: {
267
+ preset: "default",
268
+ tokens: {
269
+ colors: {
270
+ primary: "#047857",
271
+ accent: "#0D9488",
272
+ background: "#ffffff",
273
+ foreground: "#111827",
274
+ surface: "#ffffff",
275
+ muted: "#64748b",
276
+ border: "rgb(15 23 42 / 0.12)",
277
+ codeBackground: "#f6fbf8"
278
+ },
279
+ radius: {
280
+ sm: "6px",
281
+ md: "10px",
282
+ lg: "14px",
283
+ xl: "18px"
284
+ }
285
+ },
286
+ layout: { maxWidth: "82rem" },
287
+ editor: false
288
+ },
289
+ base: {
290
+ preset: "base",
291
+ tokens: {
292
+ colors: {
293
+ primary: "#18181b",
294
+ accent: "#52525b",
295
+ background: "#ffffff",
296
+ foreground: "#18181b",
297
+ surface: "#ffffff",
298
+ muted: "#71717a",
299
+ border: "rgb(24 24 27 / 0.12)",
300
+ codeBackground: "#f4f4f5"
301
+ },
302
+ radius: {
303
+ sm: "6px",
304
+ md: "8px",
305
+ lg: "12px",
306
+ xl: "16px"
307
+ }
308
+ },
309
+ layout: { maxWidth: "80rem" },
310
+ editor: false
311
+ }
312
+ };
313
+ function resolveThemeConfig(theme = {}) {
314
+ const preset = theme.preset ?? "default";
315
+ const presetTheme = clarifyThemePresets[preset];
316
+ return {
317
+ preset,
318
+ tokens: {
319
+ colors: {
320
+ ...presetTheme.tokens.colors,
321
+ ...theme.tokens?.colors
322
+ },
323
+ radius: {
324
+ ...presetTheme.tokens.radius,
325
+ ...theme.tokens?.radius
326
+ }
327
+ },
328
+ layout: {
329
+ ...presetTheme.layout,
330
+ ...theme.layout
331
+ },
332
+ editor: theme.editor ?? presetTheme.editor
333
+ };
334
+ }
335
+ //#endregion
264
336
  //#region source/plugins/html-shell/index.ts
265
- var THEME_BOOTSTRAP_SCRIPT = `(function(){try{var e=localStorage.getItem('clarify:theme');var t=e==='dark'||e==='light'||e==='system'?e:'system';var r=t==='system'?window.matchMedia('(prefers-color-scheme: dark)').matches:t==='dark';document.documentElement.classList.toggle('dark',r);document.documentElement.style.colorScheme=r?'dark':'light'}catch(e){}})();`;
337
+ var THEME_STORAGE_KEY = "clarify:theme";
266
338
  var REL_ICON_RE = /<link\s+[^>]*rel=["'][^"']*\bicon\b[^"']*["'][^>]*>/i;
267
339
  function inferIconType(href) {
268
340
  const path = href.split(/[?#]/, 1)[0]?.toLowerCase() ?? href.toLowerCase();
@@ -292,6 +364,62 @@ function createIconTags(icon) {
292
364
  if (lightIcon === darkIcon) return [createIconTag(lightIcon)];
293
365
  return [createIconTag(lightIcon, "(prefers-color-scheme: light)"), createIconTag(darkIcon, "(prefers-color-scheme: dark)")];
294
366
  }
367
+ function matchesPresetTheme(theme) {
368
+ const preset = clarifyThemePresets[theme.preset];
369
+ return JSON.stringify({
370
+ tokens: theme.tokens,
371
+ layout: theme.layout
372
+ }) === JSON.stringify({
373
+ tokens: preset.tokens,
374
+ layout: preset.layout
375
+ });
376
+ }
377
+ function effectiveTheme(theme, resolvedTheme) {
378
+ if (resolvedTheme !== "dark" || !matchesPresetTheme(theme)) return theme;
379
+ return {
380
+ ...theme,
381
+ tokens: {
382
+ ...theme.tokens,
383
+ colors: {
384
+ ...theme.tokens.colors,
385
+ background: "#09090b",
386
+ foreground: "#ffffff",
387
+ surface: "#18181b",
388
+ muted: "#a1a1aa",
389
+ border: "rgb(255 255 255 / 0.1)",
390
+ codeBackground: "#18181b"
391
+ }
392
+ }
393
+ };
394
+ }
395
+ function resolveThemeColorValue(value, resolvedTheme) {
396
+ return typeof value === "string" ? value : value[resolvedTheme] ?? value.light ?? value.dark ?? "";
397
+ }
398
+ function themeToCssVariables(theme, resolvedTheme) {
399
+ const resolved = effectiveTheme(theme, resolvedTheme);
400
+ const { colors } = resolved.tokens;
401
+ const { radius } = resolved.tokens;
402
+ return {
403
+ "--clarify-theme-tokens-colors-primary": resolveThemeColorValue(colors.primary, resolvedTheme),
404
+ "--clarify-theme-tokens-colors-accent": resolveThemeColorValue(colors.accent, resolvedTheme),
405
+ "--clarify-theme-tokens-colors-background": resolveThemeColorValue(colors.background, resolvedTheme),
406
+ "--clarify-theme-tokens-colors-foreground": resolveThemeColorValue(colors.foreground, resolvedTheme),
407
+ "--clarify-theme-tokens-colors-surface": resolveThemeColorValue(colors.surface, resolvedTheme),
408
+ "--clarify-theme-tokens-colors-muted": resolveThemeColorValue(colors.muted, resolvedTheme),
409
+ "--clarify-theme-tokens-colors-border": resolveThemeColorValue(colors.border, resolvedTheme),
410
+ "--clarify-theme-tokens-colors-code-background": resolveThemeColorValue(colors.codeBackground, resolvedTheme),
411
+ "--clarify-theme-tokens-radius-sm": radius.sm,
412
+ "--clarify-theme-tokens-radius-md": radius.md,
413
+ "--clarify-theme-tokens-radius-lg": radius.lg,
414
+ "--clarify-theme-tokens-radius-xl": radius.xl,
415
+ "--clarify-theme-layout-max-width": resolved.layout.maxWidth
416
+ };
417
+ }
418
+ function themeBootstrapScript(theme) {
419
+ const darkVariables = themeToCssVariables(theme, "dark");
420
+ const lightVariables = themeToCssVariables(theme, "light");
421
+ return `(function(){try{var e=localStorage.getItem(${JSON.stringify(THEME_STORAGE_KEY)});var t=e==='dark'||e==='light'||e==='system'?e:'system';var r=t==='system'?window.matchMedia('(prefers-color-scheme: dark)').matches:t==='dark';var v=r?${JSON.stringify(darkVariables)}:${JSON.stringify(lightVariables)};var s=document.documentElement.style;for(var k in v)s.setProperty(k,v[k]);document.documentElement.classList.toggle('dark',r);document.documentElement.style.colorScheme=r?'dark':'light'}catch(e){}})();`;
422
+ }
295
423
  function createHtmlShellPlugin() {
296
424
  return {
297
425
  name: "clarify:html-shell",
@@ -302,7 +430,7 @@ function createHtmlShellPlugin() {
302
430
  ...REL_ICON_RE.test(input.html) ? [] : createIconTags(ctx.projectConfig.favicon ?? ctx.projectConfig.logo),
303
431
  {
304
432
  tag: "script",
305
- children: THEME_BOOTSTRAP_SCRIPT,
433
+ children: themeBootstrapScript(ctx.projectConfig.theme),
306
434
  injectTo: "head-prepend"
307
435
  },
308
436
  {
@@ -779,8 +907,10 @@ function generateRoutesModule(routes, resolvedNavigation, projectConfig, mode =
779
907
  const navigation = resolvedNavigation ?? (projectConfig?.tabs ? projectConfig.i18n ? buildLocalizedNavigationFromTabsConfig(routes, projectConfig.tabs, projectConfig.i18n) ?? {} : buildNavigationFromTabsConfig(routes, projectConfig.tabs) : buildNavigation(routes));
780
908
  return `${imports}\n\nexport const routes = [\n${routesArray}\n];\n\nexport const navigation = ${JSON.stringify(navigation, null, 2)};\n`;
781
909
  }
782
- function createRuntimeModule() {
783
- return "export const openApis = {};";
910
+ function createRuntimeModule(options = {}) {
911
+ return `${options.footerComponentSource === "path" && options.imports?.footerComponent ? `import FooterComponent from ${moduleSpecifier(options.imports.footerComponent)};` : ""}
912
+ export const openApis = {};
913
+ export const footerComponent = ${options.footerComponentSource === "path" ? "FooterComponent" : "undefined"};`;
784
914
  }
785
915
  function createClientEntryModule(options = {}) {
786
916
  return `
@@ -788,16 +918,22 @@ import '@clarify-labs/renderer/style.css';
788
918
  import { render } from '@clarify-labs/renderer/client';
789
919
  import { routes, navigation } from '${VIRTUAL_ROUTES}';
790
920
  import { config } from '${VIRTUAL_CONFIG}';
791
- import { openApis } from '${VIRTUAL_RUNTIME}';
792
- render({ config, routes, navigation, openApis, themeEditor: ${JSON.stringify(options.themeEditor ?? false)} });`;
921
+ import { openApis, footerComponent } from '${VIRTUAL_RUNTIME}';
922
+ render({ config, routes, navigation, openApis, footerComponent, themeEditor: ${JSON.stringify(options.themeEditor ?? false)} });`;
793
923
  }
794
924
  function buildVirtualModules(args) {
795
925
  const modules = /* @__PURE__ */ new Map();
796
926
  const clientEntryModule = createClientEntryModule({ themeEditor: args.themeEditor });
927
+ const footerComponent = args.projectConfig.footer;
928
+ const footerComponentSource = typeof footerComponent === "string" ? "path" : void 0;
929
+ const footerComponentImport = typeof footerComponent === "string" ? footerComponent : void 0;
797
930
  modules.set(VIRTUAL_CONFIG, generateConfigModule(args.projectConfig, args.generateOptions));
798
931
  modules.set(VIRTUAL_ROUTES, generateRoutesModule(args.routes, args.navigation, args.projectConfig, "client"));
799
932
  modules.set(VIRTUAL_SERVER_ROUTES, generateRoutesModule(args.routes, args.navigation, args.projectConfig, "server"));
800
- modules.set(VIRTUAL_RUNTIME, createRuntimeModule());
933
+ modules.set(VIRTUAL_RUNTIME, createRuntimeModule({
934
+ footerComponentSource,
935
+ imports: { footerComponent: footerComponentImport }
936
+ }));
801
937
  modules.set(VIRTUAL_CLIENT_ENTRY, clientEntryModule);
802
938
  modules.set(RESOLVED_CLIENT_ENTRY, clientEntryModule);
803
939
  for (const route of args.routes) modules.set(route.virtualModuleId, `export { default } from ${moduleSpecifier(route.filePath)};`);
@@ -806,8 +942,12 @@ function buildVirtualModules(args) {
806
942
  //#endregion
807
943
  //#region source/plugins/openapi/virtual-modules.ts
808
944
  var openApiRegistryModuleId = VIRTUAL_RUNTIME;
809
- function generateOpenAPIRegistryModule(openApis) {
810
- return `export const openApis = ${JSON.stringify(openApis)};`;
945
+ function generateOpenAPIRegistryModule(openApis, runtimeModule = "") {
946
+ const openApisExport = `export const openApis = ${JSON.stringify(openApis)};`;
947
+ const openApisPlaceholder = /export const openApis = \{\};?/;
948
+ if (!runtimeModule) return openApisExport;
949
+ if (openApisPlaceholder.test(runtimeModule)) return runtimeModule.replace(openApisPlaceholder, openApisExport);
950
+ return runtimeModule;
811
951
  }
812
952
  function generateOpenAPIModule(spec, tagFilter) {
813
953
  return `import { createElement } from 'react';
@@ -935,7 +1075,7 @@ function createOpenAPIPlugin() {
935
1075
  return nextRoutes;
936
1076
  },
937
1077
  "modules:before": (modules, ctx) => {
938
- modules.set(openApiRegistryModuleId, generateOpenAPIRegistryModule(Object.fromEntries(Object.entries(specs).map(([moduleId, entry]) => [moduleId, entry.spec]))));
1078
+ modules.set(openApiRegistryModuleId, generateOpenAPIRegistryModule(Object.fromEntries(Object.entries(specs).map(([moduleId, entry]) => [moduleId, entry.spec])), modules.get(openApiRegistryModuleId)));
939
1079
  for (const [moduleId, entry] of Object.entries(specs)) modules.set(moduleId, generateOpenAPIModule(entry.spec, entry.tagFilter));
940
1080
  for (const route of ctx.routes.filter((route) => route.kind === "openapi" && route.diagnostic)) if (route.diagnostic) modules.set(route.virtualModuleId, generateOpenAPIErrorModule(route.diagnostic));
941
1081
  return modules;
@@ -944,6 +1084,180 @@ function createOpenAPIPlugin() {
944
1084
  };
945
1085
  }
946
1086
  //#endregion
1087
+ //#region source/core/search-language.ts
1088
+ function toPagefindLanguage(locale) {
1089
+ return locale?.trim().replace(/_/g, "-").split("-").filter(Boolean).join("-").toLowerCase() || "en";
1090
+ }
1091
+ //#endregion
1092
+ //#region source/core/temp-dir.ts
1093
+ function createClarifyTempDir(name) {
1094
+ return (0, node_fs.mkdtempSync)((0, node_path.join)((0, node_os.tmpdir)(), `clarify-${name}-`));
1095
+ }
1096
+ function removeClarifyTempDir(path) {
1097
+ if (!path) return;
1098
+ (0, node_fs.rmSync)(path, {
1099
+ recursive: true,
1100
+ force: true
1101
+ });
1102
+ }
1103
+ //#endregion
1104
+ //#region source/plugins/search-index/index.ts
1105
+ var pagefindContentTypes = {
1106
+ ".css": "text/css; charset=utf-8",
1107
+ ".js": "text/javascript; charset=utf-8",
1108
+ ".json": "application/json; charset=utf-8",
1109
+ ".wasm": "application/wasm"
1110
+ };
1111
+ function assertNoPagefindErrors(action, errors) {
1112
+ if (!errors?.length) return;
1113
+ throw new Error(`[clarify] Pagefind ${action} failed:\n${errors.join("\n")}`);
1114
+ }
1115
+ async function generatePagefindIndex(options) {
1116
+ const pagefind = await import("pagefind");
1117
+ const { errors, index } = await pagefind.createIndex({
1118
+ excludeSelectors: [
1119
+ "[data-pagefind-ignore]",
1120
+ "script",
1121
+ "style",
1122
+ "svg"
1123
+ ],
1124
+ includeCharacters: "._-/#:@",
1125
+ keepIndexUrl: false,
1126
+ verbose: false,
1127
+ writePlayground: false
1128
+ });
1129
+ assertNoPagefindErrors("createIndex", errors);
1130
+ if (!index) throw new Error("[clarify] Pagefind did not create an index.");
1131
+ try {
1132
+ const addResult = await index.addDirectory({
1133
+ path: options.sourceRoot ?? options.outputRoot,
1134
+ glob: "**/*.html"
1135
+ });
1136
+ assertNoPagefindErrors("addDirectory", addResult.errors);
1137
+ assertNoPagefindErrors("writeFiles", (await index.writeFiles({ outputPath: (0, node_path.join)(options.outputRoot, "pagefind") })).errors);
1138
+ return addResult.page_count;
1139
+ } finally {
1140
+ await index.deleteIndex();
1141
+ await pagefind.close();
1142
+ }
1143
+ }
1144
+ function routeSearchContent(route) {
1145
+ return [
1146
+ route.title,
1147
+ route.description,
1148
+ route.keywords?.join(" "),
1149
+ route.sections?.map((section) => section.title).join(" "),
1150
+ route.content
1151
+ ].filter(Boolean).join("\n\n");
1152
+ }
1153
+ async function generateDevSearchIndex(ctx, root) {
1154
+ const pagefind = await import("pagefind");
1155
+ const { errors, index } = await pagefind.createIndex({
1156
+ includeCharacters: "._-/#:@",
1157
+ keepIndexUrl: false,
1158
+ verbose: false,
1159
+ writePlayground: false
1160
+ });
1161
+ assertNoPagefindErrors("createIndex", errors);
1162
+ if (!index) throw new Error("[clarify] Pagefind did not create an index.");
1163
+ try {
1164
+ let pageCount = 0;
1165
+ for (const route of ctx.routes) {
1166
+ const content = routeSearchContent(route);
1167
+ if (!content.trim()) continue;
1168
+ const result = await index.addCustomRecord({
1169
+ url: route.path,
1170
+ content,
1171
+ language: toPagefindLanguage(route.locale ?? ctx.projectConfig.i18n?.defaultLocale),
1172
+ meta: { title: route.title }
1173
+ });
1174
+ assertNoPagefindErrors(`addCustomRecord ${route.path}`, result.errors);
1175
+ pageCount += 1;
1176
+ }
1177
+ assertNoPagefindErrors("writeFiles", (await index.writeFiles({ outputPath: (0, node_path.join)(root, "pagefind") })).errors);
1178
+ console.log(`[clarify] Dev search index generated for ${pageCount} pages.`);
1179
+ } finally {
1180
+ await index.deleteIndex();
1181
+ await pagefind.close();
1182
+ }
1183
+ }
1184
+ function normalizeDevPagefindPath(rawUrl, routePrefix) {
1185
+ const pathname = rawUrl?.split("?")[0];
1186
+ if (!pathname) return void 0;
1187
+ const normalizedPrefix = routePrefix && routePrefix !== "/" ? `/${routePrefix.replace(/^\/+|\/+$/g, "")}` : "";
1188
+ const pagefindPath = normalizedPrefix && pathname.startsWith(`${normalizedPrefix}/pagefind/`) ? pathname.slice(normalizedPrefix.length) : pathname;
1189
+ return pagefindPath.startsWith("/pagefind/") ? pagefindPath : void 0;
1190
+ }
1191
+ function serveDevPagefind(server, getRoot, ctx) {
1192
+ server.middlewares.use((req, res, next) => {
1193
+ const root = getRoot();
1194
+ const pagefindPath = normalizeDevPagefindPath(req.url, ctx.projectConfig.routePrefix);
1195
+ if (!root || !pagefindPath) {
1196
+ next();
1197
+ return;
1198
+ }
1199
+ const filePath = (0, node_path.join)(root, pagefindPath);
1200
+ const relativePath = (0, node_path.relative)(root, filePath);
1201
+ if (relativePath.startsWith("..") || relativePath === "" || !(0, node_fs.existsSync)(filePath)) {
1202
+ next();
1203
+ return;
1204
+ }
1205
+ const contentType = pagefindContentTypes[(0, node_path.extname)(filePath)] ?? "application/octet-stream";
1206
+ res.setHeader("Content-Type", contentType);
1207
+ (0, node_fs.createReadStream)(filePath).pipe(res);
1208
+ });
1209
+ }
1210
+ function createSearchIndexPlugin() {
1211
+ return {
1212
+ name: "clarify:search-index",
1213
+ hooks: {
1214
+ async "dev:configureServer"(server, ctx) {
1215
+ let currentRoot;
1216
+ const staleRoots = /* @__PURE__ */ new Set();
1217
+ const replaceDevIndex = async () => {
1218
+ const nextRoot = createClarifyTempDir("pagefind");
1219
+ await generateDevSearchIndex(ctx, nextRoot);
1220
+ const previousRoot = currentRoot;
1221
+ currentRoot = nextRoot;
1222
+ if (previousRoot) {
1223
+ staleRoots.add(previousRoot);
1224
+ setTimeout(() => {
1225
+ staleRoots.delete(previousRoot);
1226
+ removeClarifyTempDir(previousRoot);
1227
+ }, 3e4).unref?.();
1228
+ }
1229
+ };
1230
+ serveDevPagefind(server, () => currentRoot, ctx);
1231
+ await replaceDevIndex();
1232
+ let regenerateTimer;
1233
+ const regenerate = (filePath) => {
1234
+ if (!/\.(md|mdx|json|ya?ml)$/i.test(filePath)) return;
1235
+ if (regenerateTimer) clearTimeout(regenerateTimer);
1236
+ regenerateTimer = setTimeout(() => {
1237
+ replaceDevIndex().catch((err) => {
1238
+ console.error("[clarify] Failed to regenerate dev search index:", err);
1239
+ });
1240
+ }, 100);
1241
+ };
1242
+ server.watcher.on("add", regenerate);
1243
+ server.watcher.on("change", regenerate);
1244
+ server.watcher.on("unlink", regenerate);
1245
+ server.httpServer?.once("close", () => {
1246
+ if (regenerateTimer) clearTimeout(regenerateTimer);
1247
+ removeClarifyTempDir(currentRoot);
1248
+ for (const staleRoot of staleRoots) removeClarifyTempDir(staleRoot);
1249
+ });
1250
+ },
1251
+ async "build:done"(ctx) {
1252
+ const outputDirectory = ctx.generateOptions.outputDirectory;
1253
+ if (!outputDirectory) return;
1254
+ const pageCount = await generatePagefindIndex({ outputRoot: (0, node_path.resolve)(ctx.generateOptions.projectRoot, outputDirectory) });
1255
+ console.log(`[clarify] Search index generated for ${pageCount} pages.`);
1256
+ }
1257
+ }
1258
+ };
1259
+ }
1260
+ //#endregion
947
1261
  //#region source/plugins/seo/artifacts.ts
948
1262
  function trimTrailingSlash(value) {
949
1263
  return value.replace(/\/+$/, "");
@@ -1039,7 +1353,8 @@ function createBuiltinPlugins(options = {}) {
1039
1353
  createOpenAPIPlugin(),
1040
1354
  createSourceLinksPlugin(),
1041
1355
  createContentArtifactsPlugin(),
1042
- createSeoPlugin()
1356
+ createSeoPlugin(),
1357
+ createSearchIndexPlugin()
1043
1358
  ];
1044
1359
  if (options.htmlShell ?? true) plugins.push(createHtmlShellPlugin());
1045
1360
  return plugins;
@@ -1097,11 +1412,12 @@ var clarifyBannerConfigSchema = zod.z.object({
1097
1412
  content: clarifyLocalizedTextSchema,
1098
1413
  dismissible: zod.z.boolean().optional()
1099
1414
  });
1100
- var clarifyFooterConfigSchema = zod.z.object({
1415
+ var clarifyFooterLinksConfigSchema = zod.z.object({
1101
1416
  links: zod.z.array(clarifyNavbarLinkSchema).optional(),
1102
1417
  socials: zod.z.record(zod.z.string(), zod.z.string()).optional(),
1103
1418
  copyright: clarifyLocalizedTextSchema.optional()
1104
- });
1419
+ }).strict();
1420
+ var clarifyFooterConfigSchema = zod.z.union([clarifyFooterLinksConfigSchema, zod.z.string()]);
1105
1421
  var clarifySourceConfigSchema = zod.z.object({
1106
1422
  repository: zod.z.string(),
1107
1423
  branch: zod.z.string().optional(),
@@ -1185,78 +1501,6 @@ var clarifyProjectConfigSchema = zod.z.object({
1185
1501
  tabs: clarifyTabsConfigSchema.optional()
1186
1502
  });
1187
1503
  //#endregion
1188
- //#region source/core/theme.ts
1189
- var clarifyThemePresets = {
1190
- default: {
1191
- preset: "default",
1192
- tokens: {
1193
- colors: {
1194
- primary: "#047857",
1195
- accent: "#0D9488",
1196
- background: "#ffffff",
1197
- foreground: "#111827",
1198
- surface: "#ffffff",
1199
- muted: "#64748b",
1200
- border: "rgb(15 23 42 / 0.12)",
1201
- codeBackground: "#f6fbf8"
1202
- },
1203
- radius: {
1204
- sm: "6px",
1205
- md: "10px",
1206
- lg: "14px",
1207
- xl: "18px"
1208
- }
1209
- },
1210
- layout: { maxWidth: "82rem" },
1211
- editor: false
1212
- },
1213
- base: {
1214
- preset: "base",
1215
- tokens: {
1216
- colors: {
1217
- primary: "#18181b",
1218
- accent: "#52525b",
1219
- background: "#ffffff",
1220
- foreground: "#18181b",
1221
- surface: "#ffffff",
1222
- muted: "#71717a",
1223
- border: "rgb(24 24 27 / 0.12)",
1224
- codeBackground: "#f4f4f5"
1225
- },
1226
- radius: {
1227
- sm: "6px",
1228
- md: "8px",
1229
- lg: "12px",
1230
- xl: "16px"
1231
- }
1232
- },
1233
- layout: { maxWidth: "80rem" },
1234
- editor: false
1235
- }
1236
- };
1237
- function resolveThemeConfig(theme = {}) {
1238
- const preset = theme.preset ?? "default";
1239
- const presetTheme = clarifyThemePresets[preset];
1240
- return {
1241
- preset,
1242
- tokens: {
1243
- colors: {
1244
- ...presetTheme.tokens.colors,
1245
- ...theme.tokens?.colors
1246
- },
1247
- radius: {
1248
- ...presetTheme.tokens.radius,
1249
- ...theme.tokens?.radius
1250
- }
1251
- },
1252
- layout: {
1253
- ...presetTheme.layout,
1254
- ...theme.layout
1255
- },
1256
- editor: theme.editor ?? presetTheme.editor
1257
- };
1258
- }
1259
- //#endregion
1260
1504
  //#region source/core/config.ts
1261
1505
  function formatIssuePath(path) {
1262
1506
  return path.reduce((result, segment) => {
@@ -1550,13 +1794,13 @@ function routeOutputFiles(outputDirectory, route) {
1550
1794
  var SSR_ENTRY_CODE = `import { renderToHTML } from '@clarify-labs/renderer/server';
1551
1795
  import { routes, navigation } from 'virtual:clarify-routes/server';
1552
1796
  import { config } from 'virtual:clarify-config';
1553
- import { openApis } from 'virtual:clarify-runtime';
1797
+ import { openApis, footerComponent } from 'virtual:clarify-runtime';
1554
1798
 
1555
1799
  export function render(url) {
1556
- return renderToHTML({ config, routes, navigation, openApis, url, themeEditor: config.theme.editor });
1800
+ return renderToHTML({ config, routes, navigation, openApis, footerComponent, url, themeEditor: config.theme.editor });
1557
1801
  }`;
1558
1802
  function createTempEntryFile(content) {
1559
- const entryPath = (0, node_path.join)((0, node_fs.mkdtempSync)((0, node_path.join)((0, node_os.tmpdir)(), "clarify-ssr-")), "entry-server.ts");
1803
+ const entryPath = (0, node_path.join)(createClarifyTempDir("ssr"), "entry-server.ts");
1560
1804
  (0, node_fs.writeFileSync)(entryPath, content, "utf-8");
1561
1805
  return entryPath;
1562
1806
  }
@@ -1596,6 +1840,7 @@ async function renderSSGRoutes(routes, projectConfig, outputDirectory, ssrBundle
1596
1840
  //#endregion
1597
1841
  //#region source/core/user-config.ts
1598
1842
  function defineConfig(config) {
1843
+ validateProjectConfig(config);
1599
1844
  return config;
1600
1845
  }
1601
1846
  var CONFIG_FILENAMES = [
@@ -1858,6 +2103,12 @@ Object.defineProperty(exports, "createClarifyRuntimeAliases", {
1858
2103
  return createClarifyRuntimeAliases;
1859
2104
  }
1860
2105
  });
2106
+ Object.defineProperty(exports, "createClarifyTempDir", {
2107
+ enumerable: true,
2108
+ get: function() {
2109
+ return createClarifyTempDir;
2110
+ }
2111
+ });
1861
2112
  Object.defineProperty(exports, "defineConfig", {
1862
2113
  enumerable: true,
1863
2114
  get: function() {
@@ -1877,4 +2128,4 @@ Object.defineProperty(exports, "resolveClarifySite", {
1877
2128
  }
1878
2129
  });
1879
2130
 
1880
- //# sourceMappingURL=plugin-hJcy-YdO.cjs.map
2131
+ //# sourceMappingURL=plugin-dzXRzjdX.cjs.map