zudoku 0.93.0 → 0.93.1

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.
Files changed (53) hide show
  1. package/dist/cli/cli.js +1248 -766
  2. package/dist/declarations/app/env.d.ts +2 -26
  3. package/dist/declarations/app/wrapProtectedRoutes.d.ts +3 -4
  4. package/dist/declarations/lib/components/Heading.d.ts +1 -1
  5. package/dist/declarations/lib/plugins/blog/BlogComponents.d.ts +18 -0
  6. package/dist/declarations/lib/plugins/blog/BlogListPage.d.ts +8 -0
  7. package/dist/declarations/lib/plugins/blog/BlogPostPage.d.ts +9 -0
  8. package/dist/declarations/lib/plugins/blog/BlogTagsPage.d.ts +5 -0
  9. package/dist/declarations/lib/plugins/blog/index.d.ts +4 -0
  10. package/dist/declarations/lib/plugins/blog/options.d.ts +61 -0
  11. package/dist/declarations/lib/plugins/openapi/ParamInfos.d.ts +2 -1
  12. package/dist/declarations/lib/plugins/openapi/components/EnumValues.d.ts +2 -1
  13. package/dist/declarations/lib/plugins/openapi/schema/SchemaPropertyItem.d.ts +1 -1
  14. package/dist/declarations/lib/plugins/openapi/schema/SchemaView.d.ts +2 -2
  15. package/dist/declarations/lib/plugins/openapi/schema/utils.d.ts +7 -0
  16. package/dist/declarations/lib/ui/Form.d.ts +1 -1
  17. package/dist/declarations/vite/zuplo.d.ts +13 -0
  18. package/docs/configuration/api-catalog.md +16 -0
  19. package/docs/configuration/blog.md +214 -0
  20. package/package.json +48 -44
  21. package/src/app/entry.server.tsx +1 -5
  22. package/src/app/env.ts +30 -24
  23. package/src/app/main.tsx +2 -4
  24. package/src/app/wrapProtectedRoutes.ts +10 -14
  25. package/src/lib/plugins/blog/BlogComponents.tsx +138 -0
  26. package/src/lib/plugins/blog/BlogListPage.tsx +150 -0
  27. package/src/lib/plugins/blog/BlogPostPage.tsx +162 -0
  28. package/src/lib/plugins/blog/BlogTagsPage.tsx +69 -0
  29. package/src/lib/plugins/blog/index.tsx +163 -0
  30. package/src/lib/plugins/blog/options.ts +129 -0
  31. package/src/lib/plugins/blog/virtual.d.ts +7 -0
  32. package/src/lib/plugins/openapi/OperationListItem.tsx +7 -1
  33. package/src/lib/plugins/openapi/ParamInfos.tsx +26 -5
  34. package/src/lib/plugins/openapi/ParameterListItem.tsx +19 -4
  35. package/src/lib/plugins/openapi/Sidecar.tsx +13 -2
  36. package/src/lib/plugins/openapi/components/EnumValues.tsx +27 -8
  37. package/src/lib/plugins/openapi/components/ResponseContent.tsx +5 -3
  38. package/src/lib/plugins/openapi/playground/createUrl.ts +30 -13
  39. package/src/lib/plugins/openapi/schema/SchemaPropertyItem.tsx +15 -3
  40. package/src/lib/plugins/openapi/schema/SchemaView.tsx +45 -8
  41. package/src/lib/plugins/openapi/schema/utils.ts +90 -1
  42. package/src/lib/plugins/openapi/util/generateSchemaExample.ts +5 -1
  43. package/src/vite/api/SchemaManager.ts +2 -9
  44. package/src/vite/api/upgradeOpenApi.ts +104 -0
  45. package/src/vite/config.ts +5 -6
  46. package/src/vite/plugin-api-keys.ts +1 -5
  47. package/src/vite/plugin-blog.ts +648 -0
  48. package/src/vite/plugin-markdown-export.ts +2 -2
  49. package/src/vite/plugin-mdx.ts +5 -0
  50. package/src/vite/plugin.ts +2 -0
  51. package/src/vite-env.d.ts +1 -0
  52. package/dist/declarations/app/ZuploBuildConfig.d.ts +0 -47
  53. package/src/app/ZuploBuildConfig.ts +0 -36
package/dist/cli/cli.js CHANGED
@@ -136,8 +136,8 @@ __export(llms_exports, {
136
136
  generateLlmsTxtFiles: () => generateLlmsTxtFiles
137
137
  });
138
138
  import { writeFile as writeFile5 } from "node:fs/promises";
139
- import path22 from "node:path";
140
- import colors6 from "picocolors";
139
+ import path23 from "node:path";
140
+ import colors7 from "picocolors";
141
141
  async function generateLlmsTxtFiles({
142
142
  markdownFileInfos,
143
143
  outputUrls,
@@ -180,11 +180,11 @@ async function generateLlmsTxtFiles({
180
180
  ...documentationLinks.length > 0 ? ["## Documentation", documentationLinks.join("\n")] : []
181
181
  ];
182
182
  await writeFile5(
183
- path22.join(baseOutputDir, "llms.txt"),
183
+ path23.join(baseOutputDir, "llms.txt"),
184
184
  llmsTxtParts.join("\n\n"),
185
185
  "utf-8"
186
186
  );
187
- console.log(colors6.blue("\u2713 generated llms.txt"));
187
+ console.log(colors7.blue("\u2713 generated llms.txt"));
188
188
  }
189
189
  if (llmsTxtFull) {
190
190
  const llmsFullParts = [];
@@ -211,11 +211,11 @@ ${info.content}
211
211
  }
212
212
  const llmsFull = llmsFullParts.join("\n");
213
213
  await writeFile5(
214
- path22.join(baseOutputDir, "llms-full.txt"),
214
+ path23.join(baseOutputDir, "llms-full.txt"),
215
215
  llmsFull,
216
216
  "utf-8"
217
217
  );
218
- console.log(colors6.blue("\u2713 generated llms-full.txt"));
218
+ console.log(colors7.blue("\u2713 generated llms-full.txt"));
219
219
  }
220
220
  }
221
221
  var DEFAULT_TITLE, DEFAULT_DESCRIPTION, toSingleLine, escapeMarkdownLinkLabel, formatInstructions;
@@ -238,70 +238,36 @@ import { hideBin } from "yargs/helpers";
238
238
  import yargs from "yargs/yargs";
239
239
 
240
240
  // src/cli/build/handler.ts
241
- import path27 from "node:path";
241
+ import path28 from "node:path";
242
242
 
243
243
  // src/vite/build.ts
244
244
  import { existsSync as existsSync3 } from "node:fs";
245
245
  import { mkdir as mkdir6, readFile as readFile5, rename as rename2, rm as rm4, writeFile as writeFile6 } from "node:fs/promises";
246
- import path25 from "node:path";
246
+ import path26 from "node:path";
247
247
  import { build as esbuild } from "esbuild";
248
248
  import { createBuilder } from "vite";
249
249
 
250
- // src/app/env.ts
251
- import { z as z2 } from "zod/mini";
252
-
253
- // src/app/ZuploBuildConfig.ts
254
- import { z } from "zod/mini";
255
- var EntitlementsSchema = z.object({
256
- devPortalZuploBranding: z.boolean(),
257
- numberOfProjects: z.number(),
258
- numberOfUsers: z.number(),
259
- egressGbPerMonth: z.number(),
260
- requestsPerMonth: z.number(),
261
- numberOfApiKeys: z.number(),
262
- customDomains: z.number(),
263
- advancedAnalyticsEnabled: z.boolean(),
264
- devPortalAnalyticsEnabled: z.boolean(),
265
- premiumSupport: z.boolean(),
266
- emergencyPhoneSupport: z.boolean(),
267
- rbacEnabled: z.boolean(),
268
- onPremEnabled: z.boolean(),
269
- largeBuildRunners: z.boolean()
270
- });
271
- var BuildConfigSchema = z.object({
272
- entitlements: EntitlementsSchema,
273
- environmentType: z.optional(z.string()),
274
- deploymentName: z.string(),
275
- deploymentUrl: z.optional(z.string()),
276
- projectId: z.optional(z.string()),
277
- projectType: z.optional(z.string()),
278
- sourceType: z.optional(z.string()),
279
- accountName: z.optional(z.string()),
280
- projectName: z.optional(z.string())
281
- });
282
- var parseBuildConfig = (value) => BuildConfigSchema.parse(value);
283
-
284
- // src/app/env.ts
285
- var formatError = (error) => {
286
- if (error instanceof SyntaxError) {
287
- return "ZUPLO_BUILD_CONFIG contains invalid JSON";
288
- }
289
- if (error instanceof z2.core.$ZodError) {
290
- return `ZUPLO_BUILD_CONFIG is invalid:
291
- ${z2.prettifyError(error)}`;
292
- }
293
- return `ZUPLO_BUILD_CONFIG is invalid: ${error}`;
294
- };
295
- var getZuploBuildConfig = () => {
296
- if (!process.env.ZUPLO_BUILD_CONFIG) return void 0;
250
+ // src/vite/zuplo.ts
251
+ import bs58 from "bs58";
252
+ var getZuploSystemConfigurations = (string) => {
253
+ if (!string) return void 0;
297
254
  try {
298
- const parsed = JSON.parse(process.env.ZUPLO_BUILD_CONFIG);
299
- return parseBuildConfig(parsed);
255
+ const zuploSystemConfigurations = JSON.parse(
256
+ Buffer.from(bs58.decode(string)).toString("utf8")
257
+ );
258
+ return zuploSystemConfigurations;
300
259
  } catch (error) {
301
- console.error(formatError(error));
260
+ console.error(error);
302
261
  return void 0;
303
262
  }
304
263
  };
264
+
265
+ // src/app/env.ts
266
+ var parseBoolean = (value) => {
267
+ if (value === "true") return true;
268
+ if (value === "false") return false;
269
+ return void 0;
270
+ };
305
271
  var ZuploEnv = {
306
272
  /**
307
273
  * Indicates that the build is running in Zuplo "mode"
@@ -312,7 +278,21 @@ var ZuploEnv = {
312
278
  get serverUrl() {
313
279
  return process.env.ZUPLO_SERVER_URL;
314
280
  },
315
- buildConfig: getZuploBuildConfig()
281
+ /**
282
+ * The Zuplo deployment name, from `ZUPLO_DEPLOYMENT_NAME`, falling back to
283
+ * the deployment name in `ZUPLO_SYSTEM_CONFIGURATIONS`.
284
+ */
285
+ get deploymentName() {
286
+ return process.env.ZUPLO_DEPLOYMENT_NAME || getZuploSystemConfigurations(process.env.ZUPLO_SYSTEM_CONFIGURATIONS)?.__ZUPLO_DEPLOYMENT_NAME;
287
+ },
288
+ /**
289
+ * Whether Zuplo branding is shown in the dev portal, from
290
+ * `ZUPLO_DEV_PORTAL_ZUPLO_BRANDING` (`"true"` or `"false"`). Any other value
291
+ * means it isn't set.
292
+ */
293
+ get devPortalZuploBranding() {
294
+ return parseBoolean(process.env.ZUPLO_DEV_PORTAL_ZUPLO_BRANDING);
295
+ }
316
296
  };
317
297
 
318
298
  // src/cli/common/package-json.ts
@@ -420,7 +400,7 @@ var ZudokuError = class extends Error {
420
400
 
421
401
  // src/config/file-exists.ts
422
402
  import { stat } from "node:fs/promises";
423
- var fileExists = (path32) => stat(path32).then(() => true).catch(() => false);
403
+ var fileExists = (path33) => stat(path33).then(() => true).catch(() => false);
424
404
 
425
405
  // src/config/plugin-versions.ts
426
406
  import { readFile } from "node:fs/promises";
@@ -465,7 +445,7 @@ var getPluginVersions = async (pluginDirs) => {
465
445
  // src/config/validators/ZudokuConfig.ts
466
446
  import colors from "picocolors";
467
447
  import { isValidElement as isValidElement2 } from "react";
468
- import { z as z7 } from "zod";
448
+ import { z as z5 } from "zod";
469
449
 
470
450
  // src/vite/plugin-theme.ts
471
451
  import path4 from "node:path";
@@ -630,27 +610,27 @@ var createConfiguredShikiRehypePlugins = (highlighterInstance, themes = defaultH
630
610
  var objectEntries = (obj) => Object.entries(obj);
631
611
 
632
612
  // src/vite/shadcn-registry.ts
633
- import { z as z3 } from "zod";
634
- var registryItemCssSchema = z3.record(
635
- z3.string(),
636
- z3.lazy(
637
- () => z3.union([
638
- z3.string(),
639
- z3.record(
640
- z3.string(),
641
- z3.union([z3.string(), z3.record(z3.string(), z3.string())])
613
+ import { z } from "zod";
614
+ var registryItemCssSchema = z.record(
615
+ z.string(),
616
+ z.lazy(
617
+ () => z.union([
618
+ z.string(),
619
+ z.record(
620
+ z.string(),
621
+ z.union([z.string(), z.record(z.string(), z.string())])
642
622
  )
643
623
  ])
644
624
  )
645
625
  );
646
- var registryItemSchema = z3.object({
647
- $schema: z3.literal("https://ui.shadcn.com/schema/registry-item.json"),
648
- name: z3.string(),
649
- type: z3.enum(["registry:theme", "registry:style"]),
650
- cssVars: z3.object({
651
- theme: z3.record(z3.string(), z3.string()).optional(),
652
- light: z3.record(z3.string(), z3.string()).optional(),
653
- dark: z3.record(z3.string(), z3.string()).optional()
626
+ var registryItemSchema = z.object({
627
+ $schema: z.literal("https://ui.shadcn.com/schema/registry-item.json"),
628
+ name: z.string(),
629
+ type: z.enum(["registry:theme", "registry:style"]),
630
+ cssVars: z.object({
631
+ theme: z.record(z.string(), z.string()).optional(),
632
+ light: z.record(z.string(), z.string()).optional(),
633
+ dark: z.record(z.string(), z.string()).optional()
654
634
  }).optional(),
655
635
  css: registryItemCssSchema.optional()
656
636
  });
@@ -1005,7 +985,7 @@ ${rootVars.join("\n")}
1005
985
  };
1006
986
 
1007
987
  // src/config/validators/HeaderNavigationSchema.ts
1008
- import { z as z4 } from "zod";
988
+ import { z as z2 } from "zod";
1009
989
 
1010
990
  // src/config/validators/icon-types.ts
1011
991
  var IconNames = [
@@ -3142,122 +3122,122 @@ var IconNames = [
3142
3122
  ];
3143
3123
 
3144
3124
  // src/config/validators/HeaderNavigationSchema.ts
3145
- var IconSchema = z4.enum(IconNames);
3146
- var HeaderNavLinkItemSchema = z4.object({
3147
- label: z4.string(),
3125
+ var IconSchema = z2.enum(IconNames);
3126
+ var HeaderNavLinkItemSchema = z2.object({
3127
+ label: z2.string(),
3148
3128
  icon: IconSchema.optional(),
3149
- description: z4.string().optional(),
3150
- to: z4.string(),
3151
- target: z4.enum(["_self", "_blank"]).optional()
3129
+ description: z2.string().optional(),
3130
+ to: z2.string(),
3131
+ target: z2.enum(["_self", "_blank"]).optional()
3152
3132
  });
3153
- var HeaderNavGroupSchema = z4.object({
3154
- label: z4.string(),
3155
- items: z4.array(HeaderNavLinkItemSchema)
3133
+ var HeaderNavGroupSchema = z2.object({
3134
+ label: z2.string(),
3135
+ items: z2.array(HeaderNavLinkItemSchema)
3156
3136
  });
3157
- var HeaderNavItemSchema = z4.union([
3158
- z4.object({
3159
- label: z4.string(),
3137
+ var HeaderNavItemSchema = z2.union([
3138
+ z2.object({
3139
+ label: z2.string(),
3160
3140
  icon: IconSchema.optional(),
3161
- to: z4.string(),
3162
- target: z4.enum(["_self", "_blank"]).optional()
3141
+ to: z2.string(),
3142
+ target: z2.enum(["_self", "_blank"]).optional()
3163
3143
  }),
3164
- z4.object({
3165
- label: z4.string(),
3166
- items: z4.array(z4.union([HeaderNavLinkItemSchema, HeaderNavGroupSchema]))
3144
+ z2.object({
3145
+ label: z2.string(),
3146
+ items: z2.array(z2.union([HeaderNavLinkItemSchema, HeaderNavGroupSchema]))
3167
3147
  })
3168
3148
  ]);
3169
- var HeaderNavigationSchema = z4.array(HeaderNavItemSchema);
3149
+ var HeaderNavigationSchema = z2.array(HeaderNavItemSchema);
3170
3150
 
3171
3151
  // src/config/validators/InputNavigationSchema.ts
3172
- import { z as z5 } from "zod";
3173
- var IconSchema2 = z5.custom((f) => typeof f === "string");
3174
- var BadgeSchema = z5.object({
3175
- label: z5.string(),
3152
+ import { z as z3 } from "zod";
3153
+ var IconSchema2 = z3.custom((f) => typeof f === "string");
3154
+ var BadgeSchema = z3.object({
3155
+ label: z3.string(),
3176
3156
  // prettier-ignore
3177
- color: z5.enum(["green", "blue", "yellow", "red", "purple", "indigo", "gray", "outline"]),
3178
- invert: z5.boolean().optional(),
3179
- className: z5.string().optional()
3157
+ color: z3.enum(["green", "blue", "yellow", "red", "purple", "indigo", "gray", "outline"]),
3158
+ invert: z3.boolean().optional(),
3159
+ className: z3.string().optional()
3180
3160
  });
3181
- var InputNavigationCategoryLinkDocSchema = z5.union([
3182
- z5.string(),
3183
- z5.object({
3184
- type: z5.literal("doc"),
3185
- file: z5.string(),
3186
- label: z5.string().optional(),
3187
- path: z5.string().optional()
3161
+ var InputNavigationCategoryLinkDocSchema = z3.union([
3162
+ z3.string(),
3163
+ z3.object({
3164
+ type: z3.literal("doc"),
3165
+ file: z3.string(),
3166
+ label: z3.string().optional(),
3167
+ path: z3.string().optional()
3188
3168
  }),
3189
- z5.object({
3190
- type: z5.literal("link"),
3191
- to: z5.string(),
3192
- label: z5.string().optional()
3169
+ z3.object({
3170
+ type: z3.literal("link"),
3171
+ to: z3.string(),
3172
+ label: z3.string().optional()
3193
3173
  })
3194
3174
  ]);
3195
- var DisplaySchema = z5.union([
3196
- z5.enum(["auth", "anon", "always", "hide"]),
3197
- z5.custom((val) => typeof val === "function")
3175
+ var DisplaySchema = z3.union([
3176
+ z3.enum(["auth", "anon", "always", "hide"]),
3177
+ z3.custom((val) => typeof val === "function")
3198
3178
  ]).optional();
3199
3179
  var CommonItemFields = {
3200
3180
  icon: IconSchema2.optional(),
3201
3181
  badge: BadgeSchema.optional(),
3202
3182
  display: DisplaySchema
3203
3183
  };
3204
- var InputNavigationDocObjectSchema = z5.object({
3205
- type: z5.literal("doc"),
3206
- file: z5.string(),
3184
+ var InputNavigationDocObjectSchema = z3.object({
3185
+ type: z3.literal("doc"),
3186
+ file: z3.string(),
3207
3187
  // Custom URL path for this document (overrides file-based path)
3208
- path: z5.string().optional(),
3209
- label: z5.string().optional(),
3188
+ path: z3.string().optional(),
3189
+ label: z3.string().optional(),
3210
3190
  ...CommonItemFields
3211
3191
  });
3212
- var InputNavigationLinkSchema = z5.object({
3213
- type: z5.literal("link"),
3214
- to: z5.string(),
3215
- label: z5.string(),
3216
- target: z5.enum(["_self", "_blank"]).optional(),
3217
- stack: z5.boolean().optional(),
3192
+ var InputNavigationLinkSchema = z3.object({
3193
+ type: z3.literal("link"),
3194
+ to: z3.string(),
3195
+ label: z3.string(),
3196
+ target: z3.enum(["_self", "_blank"]).optional(),
3197
+ stack: z3.boolean().optional(),
3218
3198
  ...CommonItemFields
3219
3199
  });
3220
- var InputNavigationCustomPageSchema = z5.object({
3221
- type: z5.literal("custom-page"),
3222
- path: z5.string(),
3223
- label: z5.string().optional(),
3224
- element: z5.any(),
3225
- layout: z5.enum(["default", "none"]).optional(),
3200
+ var InputNavigationCustomPageSchema = z3.object({
3201
+ type: z3.literal("custom-page"),
3202
+ path: z3.string(),
3203
+ label: z3.string().optional(),
3204
+ element: z3.any(),
3205
+ layout: z3.enum(["default", "none"]).optional(),
3226
3206
  ...CommonItemFields
3227
3207
  });
3228
- var InputNavigationSeparatorSchema = z5.object({
3229
- type: z5.literal("separator"),
3208
+ var InputNavigationSeparatorSchema = z3.object({
3209
+ type: z3.literal("separator"),
3230
3210
  display: DisplaySchema
3231
3211
  });
3232
- var InputNavigationSectionSchema = z5.object({
3233
- type: z5.literal("section"),
3234
- label: z5.string(),
3212
+ var InputNavigationSectionSchema = z3.object({
3213
+ type: z3.literal("section"),
3214
+ label: z3.string(),
3235
3215
  display: DisplaySchema
3236
3216
  });
3237
- var InputNavigationFilterSchema = z5.object({
3238
- type: z5.literal("filter"),
3239
- placeholder: z5.string().optional(),
3217
+ var InputNavigationFilterSchema = z3.object({
3218
+ type: z3.literal("filter"),
3219
+ placeholder: z3.string().optional(),
3240
3220
  display: DisplaySchema
3241
3221
  });
3242
- var BaseInputNavigationCategorySchema = z5.object({
3243
- type: z5.literal("category"),
3222
+ var BaseInputNavigationCategorySchema = z3.object({
3223
+ type: z3.literal("category"),
3244
3224
  icon: IconSchema2.optional(),
3245
- label: z5.string(),
3246
- collapsible: z5.boolean().optional(),
3247
- collapsed: z5.boolean().optional(),
3225
+ label: z3.string(),
3226
+ collapsible: z3.boolean().optional(),
3227
+ collapsed: z3.boolean().optional(),
3248
3228
  link: InputNavigationCategoryLinkDocSchema.optional(),
3249
3229
  display: DisplaySchema,
3250
- stack: z5.boolean().optional()
3230
+ stack: z3.boolean().optional()
3251
3231
  });
3252
- var InputNavigationCategorySchema = z5.object({
3232
+ var InputNavigationCategorySchema = z3.object({
3253
3233
  ...BaseInputNavigationCategorySchema.shape,
3254
3234
  get items() {
3255
3235
  return InputNavigationItemSchema.array();
3256
3236
  }
3257
3237
  });
3258
- var InputNavigationItemSchema = z5.union([
3259
- z5.string(),
3260
- z5.discriminatedUnion("type", [
3238
+ var InputNavigationItemSchema = z3.union([
3239
+ z3.string(),
3240
+ z3.discriminatedUnion("type", [
3261
3241
  InputNavigationDocObjectSchema,
3262
3242
  InputNavigationLinkSchema,
3263
3243
  InputNavigationCustomPageSchema,
@@ -3268,43 +3248,43 @@ var InputNavigationItemSchema = z5.union([
3268
3248
  ])
3269
3249
  ]);
3270
3250
  var InputNavigationSchema = InputNavigationItemSchema.array();
3271
- var NavigationModifyRuleSchema = z5.object({
3272
- type: z5.literal("modify"),
3273
- match: z5.string(),
3274
- set: z5.object({
3275
- label: z5.string().optional(),
3251
+ var NavigationModifyRuleSchema = z3.object({
3252
+ type: z3.literal("modify"),
3253
+ match: z3.string(),
3254
+ set: z3.object({
3255
+ label: z3.string().optional(),
3276
3256
  icon: IconSchema2.optional(),
3277
3257
  badge: BadgeSchema.optional(),
3278
- collapsed: z5.boolean().optional(),
3279
- collapsible: z5.boolean().optional(),
3258
+ collapsed: z3.boolean().optional(),
3259
+ collapsible: z3.boolean().optional(),
3280
3260
  display: DisplaySchema,
3281
3261
  // Turn a (plugin-generated) category into a stacked sub-nav
3282
3262
  // E.g. make each OpenAPI tag drill into its own panel. See `stack` above.
3283
- stack: z5.boolean().optional()
3263
+ stack: z3.boolean().optional()
3284
3264
  })
3285
3265
  });
3286
- var NavigationInsertRuleSchema = z5.object({
3287
- type: z5.literal("insert"),
3288
- match: z5.string(),
3289
- position: z5.enum(["before", "after"]),
3266
+ var NavigationInsertRuleSchema = z3.object({
3267
+ type: z3.literal("insert"),
3268
+ match: z3.string(),
3269
+ position: z3.enum(["before", "after"]),
3290
3270
  items: InputNavigationItemSchema.array()
3291
3271
  });
3292
- var NavigationRemoveRuleSchema = z5.object({
3293
- type: z5.literal("remove"),
3294
- match: z5.string()
3272
+ var NavigationRemoveRuleSchema = z3.object({
3273
+ type: z3.literal("remove"),
3274
+ match: z3.string()
3295
3275
  });
3296
- var NavigationSortRuleSchema = z5.object({
3297
- type: z5.literal("sort"),
3298
- match: z5.string(),
3299
- by: z5.custom((val) => typeof val === "function")
3276
+ var NavigationSortRuleSchema = z3.object({
3277
+ type: z3.literal("sort"),
3278
+ match: z3.string(),
3279
+ by: z3.custom((val) => typeof val === "function")
3300
3280
  });
3301
- var NavigationMoveRuleSchema = z5.object({
3302
- type: z5.literal("move"),
3303
- match: z5.string(),
3304
- to: z5.string(),
3305
- position: z5.enum(["before", "after"])
3281
+ var NavigationMoveRuleSchema = z3.object({
3282
+ type: z3.literal("move"),
3283
+ match: z3.string(),
3284
+ to: z3.string(),
3285
+ position: z3.enum(["before", "after"])
3306
3286
  });
3307
- var NavigationRuleSchema = z5.discriminatedUnion("type", [
3287
+ var NavigationRuleSchema = z3.discriminatedUnion("type", [
3308
3288
  NavigationModifyRuleSchema,
3309
3289
  NavigationInsertRuleSchema,
3310
3290
  NavigationRemoveRuleSchema,
@@ -3314,15 +3294,15 @@ var NavigationRuleSchema = z5.discriminatedUnion("type", [
3314
3294
  var NavigationRulesSchema = NavigationRuleSchema.array();
3315
3295
 
3316
3296
  // src/config/validators/ProtectedRoutesSchema.ts
3317
- import { z as z6 } from "zod/mini";
3297
+ import { z as z4 } from "zod/mini";
3318
3298
 
3319
3299
  // src/lib/core/ZudokuContext.ts
3320
3300
  import { createNanoEvents } from "nanoevents";
3321
3301
 
3322
3302
  // src/lib/util/url.ts
3323
3303
  import { matchPath } from "react-router";
3324
- var matchesProtectedPattern = (pattern, path32) => matchPath({ path: pattern, end: true }, path32) != null;
3325
- var matchesAnyProtectedPattern = (patterns, path32) => patterns.some((p) => matchesProtectedPattern(p, path32));
3304
+ var matchesProtectedPattern = (pattern, path33) => matchPath({ path: pattern, end: true }, path33) != null;
3305
+ var matchesAnyProtectedPattern = (patterns, path33) => patterns.some((p) => matchesProtectedPattern(p, path33));
3326
3306
 
3327
3307
  // src/lib/core/ZudokuContext.ts
3328
3308
  var normalizeProtectedRoutes = (val) => {
@@ -3339,147 +3319,147 @@ var normalizeProtectedRoutes = (val) => {
3339
3319
  };
3340
3320
 
3341
3321
  // src/config/validators/ProtectedRoutesSchema.ts
3342
- var ProtectedRoutesInputSchema = z6.optional(
3343
- z6.union([
3344
- z6.array(z6.string()),
3345
- z6.record(
3346
- z6.string(),
3347
- z6.custom((val) => typeof val === "function")
3322
+ var ProtectedRoutesInputSchema = z4.optional(
3323
+ z4.union([
3324
+ z4.array(z4.string()),
3325
+ z4.record(
3326
+ z4.string(),
3327
+ z4.custom((val) => typeof val === "function")
3348
3328
  )
3349
3329
  ])
3350
3330
  );
3351
- var ProtectedRoutesSchema = z6.pipe(
3331
+ var ProtectedRoutesSchema = z4.pipe(
3352
3332
  ProtectedRoutesInputSchema,
3353
- z6.transform(normalizeProtectedRoutes)
3333
+ z4.transform(normalizeProtectedRoutes)
3354
3334
  );
3355
3335
 
3356
3336
  // src/config/validators/ZudokuConfig.ts
3357
- var ThemeSchema = z7.object({
3358
- background: z7.string(),
3359
- foreground: z7.string(),
3360
- card: z7.string(),
3361
- cardForeground: z7.string(),
3362
- popover: z7.string(),
3363
- popoverForeground: z7.string(),
3364
- primary: z7.string(),
3365
- primaryForeground: z7.string(),
3366
- secondary: z7.string(),
3367
- secondaryForeground: z7.string(),
3368
- muted: z7.string(),
3369
- mutedForeground: z7.string(),
3370
- accent: z7.string(),
3371
- accentForeground: z7.string(),
3372
- destructive: z7.string(),
3373
- destructiveForeground: z7.string(),
3374
- border: z7.string(),
3375
- input: z7.string(),
3376
- ring: z7.string(),
3377
- radius: z7.string()
3337
+ var ThemeSchema = z5.object({
3338
+ background: z5.string(),
3339
+ foreground: z5.string(),
3340
+ card: z5.string(),
3341
+ cardForeground: z5.string(),
3342
+ popover: z5.string(),
3343
+ popoverForeground: z5.string(),
3344
+ primary: z5.string(),
3345
+ primaryForeground: z5.string(),
3346
+ secondary: z5.string(),
3347
+ secondaryForeground: z5.string(),
3348
+ muted: z5.string(),
3349
+ mutedForeground: z5.string(),
3350
+ accent: z5.string(),
3351
+ accentForeground: z5.string(),
3352
+ destructive: z5.string(),
3353
+ destructiveForeground: z5.string(),
3354
+ border: z5.string(),
3355
+ input: z5.string(),
3356
+ ring: z5.string(),
3357
+ radius: z5.string()
3378
3358
  }).partial();
3379
- var ApiCatalogCategorySchema = z7.object({
3380
- label: z7.string(),
3381
- tags: z7.array(z7.string())
3359
+ var ApiCatalogCategorySchema = z5.object({
3360
+ label: z5.string(),
3361
+ tags: z5.array(z5.string())
3382
3362
  });
3383
- var LanguageOption = z7.object({
3384
- value: z7.string().min(1),
3385
- label: z7.string().min(1)
3363
+ var LanguageOption = z5.object({
3364
+ value: z5.string().min(1),
3365
+ label: z5.string().min(1)
3386
3366
  });
3387
- var AiAssistantCustomSchema = z7.object({
3388
- label: z7.string(),
3389
- icon: z7.custom().optional(),
3390
- url: z7.union([
3391
- z7.string(),
3392
- z7.custom((val) => typeof val === "function")
3367
+ var AiAssistantCustomSchema = z5.object({
3368
+ label: z5.string(),
3369
+ icon: z5.custom().optional(),
3370
+ url: z5.union([
3371
+ z5.string(),
3372
+ z5.custom((val) => typeof val === "function")
3393
3373
  ])
3394
3374
  });
3395
3375
  var AiAssistantPresets = ["claude", "chatgpt"];
3396
- var AiAssistantsSchema = z7.union([
3397
- z7.literal(false),
3398
- z7.array(z7.union([z7.enum(AiAssistantPresets), AiAssistantCustomSchema]))
3376
+ var AiAssistantsSchema = z5.union([
3377
+ z5.literal(false),
3378
+ z5.array(z5.union([z5.enum(AiAssistantPresets), AiAssistantCustomSchema]))
3399
3379
  ]).optional();
3400
- var ApiOptionsSchema = z7.object({
3401
- examplesLanguage: z7.string(),
3402
- supportedLanguages: z7.array(LanguageOption),
3403
- disablePlayground: z7.boolean(),
3404
- disableSidecar: z7.boolean(),
3405
- disableRequestBox: z7.boolean(),
3406
- showVersionSelect: z7.enum(["always", "if-available", "hide"]),
3407
- expandAllTags: z7.boolean(),
3408
- showInfoPage: z7.boolean(),
3409
- disableSecurity: z7.boolean(),
3410
- disableMcpAuthInstructions: z7.boolean(),
3411
- schemaDownload: z7.object({
3412
- enabled: z7.boolean(),
3413
- fileName: z7.string().regex(/^[A-Za-z0-9_-]+$/).optional()
3380
+ var ApiOptionsSchema = z5.object({
3381
+ examplesLanguage: z5.string(),
3382
+ supportedLanguages: z5.array(LanguageOption),
3383
+ disablePlayground: z5.boolean(),
3384
+ disableSidecar: z5.boolean(),
3385
+ disableRequestBox: z5.boolean(),
3386
+ showVersionSelect: z5.enum(["always", "if-available", "hide"]),
3387
+ expandAllTags: z5.boolean(),
3388
+ showInfoPage: z5.boolean(),
3389
+ disableSecurity: z5.boolean(),
3390
+ disableMcpAuthInstructions: z5.boolean(),
3391
+ schemaDownload: z5.object({
3392
+ enabled: z5.boolean(),
3393
+ fileName: z5.string().regex(/^[A-Za-z0-9_-]+$/).optional()
3414
3394
  }).partial(),
3415
- transformExamples: z7.custom(
3395
+ transformExamples: z5.custom(
3416
3396
  (val) => typeof val === "function"
3417
3397
  ),
3418
- generateCodeSnippet: z7.custom(
3398
+ generateCodeSnippet: z5.custom(
3419
3399
  (val) => typeof val === "function"
3420
3400
  )
3421
3401
  }).partial();
3422
- var ApiConfigSchema = z7.object({
3423
- server: z7.string(),
3424
- path: z7.string(),
3425
- categories: z7.array(ApiCatalogCategorySchema),
3402
+ var ApiConfigSchema = z5.object({
3403
+ server: z5.string(),
3404
+ path: z5.string(),
3405
+ categories: z5.array(ApiCatalogCategorySchema),
3426
3406
  options: ApiOptionsSchema
3427
3407
  }).partial();
3428
- var OpenApiPublicationSchema = z7.object({
3429
- path: z7.string().regex(
3408
+ var OpenApiPublicationSchema = z5.object({
3409
+ path: z5.string().regex(
3430
3410
  /^\/(?!\/)(?:[A-Za-z0-9._~-]+\/)*[A-Za-z0-9._~-]+\.(?:json|ya?ml)$/i,
3431
3411
  "OpenAPI publication path must be a root-relative .json, .yaml, or .yml path without traversal, query, or fragment components"
3432
3412
  ).refine(
3433
3413
  (value) => value.split("/").every((segment) => segment !== "." && segment !== ".."),
3434
3414
  "OpenAPI publication path must not contain traversal segments"
3435
3415
  ),
3436
- agentQuality: z7.boolean().optional()
3416
+ agentQuality: z5.boolean().optional()
3437
3417
  });
3438
- var VersionConfigSchema = z7.object({
3439
- path: z7.string(),
3440
- input: z7.string(),
3441
- label: z7.string().optional()
3418
+ var VersionConfigSchema = z5.object({
3419
+ path: z5.string(),
3420
+ input: z5.string(),
3421
+ label: z5.string().optional()
3442
3422
  });
3443
- var ApiSchema = z7.discriminatedUnion("type", [
3444
- z7.object({
3445
- type: z7.literal("url"),
3446
- input: z7.union([z7.string(), z7.array(VersionConfigSchema)]),
3423
+ var ApiSchema = z5.discriminatedUnion("type", [
3424
+ z5.object({
3425
+ type: z5.literal("url"),
3426
+ input: z5.union([z5.string(), z5.array(VersionConfigSchema)]),
3447
3427
  ...ApiConfigSchema.shape
3448
3428
  }),
3449
- z7.object({
3450
- type: z7.literal("file"),
3451
- input: z7.union([
3452
- z7.string(),
3453
- z7.array(z7.union([z7.string(), VersionConfigSchema]))
3429
+ z5.object({
3430
+ type: z5.literal("file"),
3431
+ input: z5.union([
3432
+ z5.string(),
3433
+ z5.array(z5.union([z5.string(), VersionConfigSchema]))
3454
3434
  ]),
3455
3435
  publish: OpenApiPublicationSchema.optional(),
3456
3436
  ...ApiConfigSchema.shape
3457
3437
  }),
3458
- z7.object({
3459
- type: z7.literal("raw"),
3460
- input: z7.string(),
3438
+ z5.object({
3439
+ type: z5.literal("raw"),
3440
+ input: z5.string(),
3461
3441
  ...ApiConfigSchema.shape
3462
3442
  })
3463
3443
  ]);
3464
- var ApiKeysSchema = z7.object({
3465
- enabled: z7.boolean(),
3466
- getConsumers: z7.custom(
3444
+ var ApiKeysSchema = z5.object({
3445
+ enabled: z5.boolean(),
3446
+ getConsumers: z5.custom(
3467
3447
  (val) => typeof val === "function"
3468
3448
  ).optional(),
3469
- rollKey: z7.custom(
3449
+ rollKey: z5.custom(
3470
3450
  (val) => typeof val === "function"
3471
3451
  ).optional(),
3472
- deleteKey: z7.custom((val) => typeof val === "function").optional(),
3473
- updateKeyDescription: z7.custom((val) => typeof val === "function").optional(),
3474
- createKey: z7.custom((val) => typeof val === "function").optional()
3452
+ deleteKey: z5.custom((val) => typeof val === "function").optional(),
3453
+ updateKeyDescription: z5.custom((val) => typeof val === "function").optional(),
3454
+ createKey: z5.custom((val) => typeof val === "function").optional()
3475
3455
  });
3476
- var LogoSchema = z7.object({
3477
- src: z7.object({ light: z7.string(), dark: z7.string() }),
3478
- alt: z7.string().optional(),
3479
- width: z7.string().or(z7.number()).optional(),
3480
- height: z7.string().or(z7.number()).optional(),
3481
- href: z7.string().optional(),
3482
- reloadDocument: z7.boolean().optional()
3456
+ var LogoSchema = z5.object({
3457
+ src: z5.object({ light: z5.string(), dark: z5.string() }),
3458
+ alt: z5.string().optional(),
3459
+ width: z5.string().or(z5.number()).optional(),
3460
+ height: z5.string().or(z5.number()).optional(),
3461
+ href: z5.string().optional(),
3462
+ reloadDocument: z5.boolean().optional()
3483
3463
  });
3484
3464
  var FooterSocialIcons = [
3485
3465
  "reddit",
@@ -3497,38 +3477,38 @@ var FooterSocialIcons = [
3497
3477
  "whatsapp",
3498
3478
  "telegram"
3499
3479
  ];
3500
- var FooterSocialSchema = z7.object({
3501
- label: z7.string().optional(),
3502
- href: z7.string(),
3503
- icon: z7.union([
3504
- z7.enum(FooterSocialIcons),
3505
- z7.custom((val) => isValidElement2(val))
3480
+ var FooterSocialSchema = z5.object({
3481
+ label: z5.string().optional(),
3482
+ href: z5.string(),
3483
+ icon: z5.union([
3484
+ z5.enum(FooterSocialIcons),
3485
+ z5.custom((val) => isValidElement2(val))
3506
3486
  ]).optional()
3507
3487
  });
3508
- var FooterSchema = z7.object({
3509
- columns: z7.array(
3510
- z7.object({
3511
- position: z7.enum(["start", "center", "end"]).optional(),
3512
- title: z7.string(),
3513
- links: z7.array(z7.object({ label: z7.string(), href: z7.string() }))
3488
+ var FooterSchema = z5.object({
3489
+ columns: z5.array(
3490
+ z5.object({
3491
+ position: z5.enum(["start", "center", "end"]).optional(),
3492
+ title: z5.string(),
3493
+ links: z5.array(z5.object({ label: z5.string(), href: z5.string() }))
3514
3494
  })
3515
3495
  ).optional(),
3516
- social: z7.array(FooterSocialSchema).optional(),
3517
- copyright: z7.string().optional(),
3496
+ social: z5.array(FooterSocialSchema).optional(),
3497
+ copyright: z5.string().optional(),
3518
3498
  logo: LogoSchema.optional(),
3519
- position: z7.enum(["start", "center", "end"]).optional()
3499
+ position: z5.enum(["start", "center", "end"]).optional()
3520
3500
  }).optional();
3521
- var SiteMapSchema = z7.object({
3501
+ var SiteMapSchema = z5.object({
3522
3502
  /**
3523
3503
  * Base url of your website
3524
3504
  */
3525
- siteUrl: z7.string(),
3505
+ siteUrl: z5.string(),
3526
3506
  /**
3527
3507
  * Change frequency.
3528
3508
  * @default 'daily'
3529
3509
  */
3530
- changefreq: z7.optional(
3531
- z7.enum([
3510
+ changefreq: z5.optional(
3511
+ z5.enum([
3532
3512
  "always",
3533
3513
  "hourly",
3534
3514
  "daily",
@@ -3542,59 +3522,59 @@ var SiteMapSchema = z7.object({
3542
3522
  * Priority
3543
3523
  * @default 0.7
3544
3524
  */
3545
- priority: z7.optional(z7.number()),
3546
- outDir: z7.string().optional(),
3525
+ priority: z5.optional(z5.number()),
3526
+ outDir: z5.string().optional(),
3547
3527
  /**
3548
3528
  * Add <lastmod/> property.
3549
3529
  * @default true
3550
3530
  */
3551
- autoLastmod: z7.boolean().optional(),
3531
+ autoLastmod: z5.boolean().optional(),
3552
3532
  /**
3553
3533
  * Array of relative paths to exclude from listing on sitemap.xml or sitemap-*.xml.
3554
3534
  * @example ['/page-0', '/page/example']
3555
3535
  */
3556
- exclude: z7.union([
3557
- z7.custom((val) => typeof val === "function"),
3558
- z7.array(z7.string())
3536
+ exclude: z5.union([
3537
+ z5.custom((val) => typeof val === "function"),
3538
+ z5.array(z5.string())
3559
3539
  ]).optional()
3560
3540
  }).optional();
3561
3541
  var DEFAULT_DOCS_FILES = "/pages/**/*.{md,mdx}";
3562
- var LlmsConfigSchema = z7.object({
3563
- llmsTxt: z7.boolean().default(false).describe(
3542
+ var LlmsConfigSchema = z5.object({
3543
+ llmsTxt: z5.boolean().default(false).describe(
3564
3544
  "When enabled, generates an llms.txt file following the spec at https://llmstxt.org/. This file provides a summary with links to all documentation."
3565
3545
  ),
3566
- llmsTxtFull: z7.boolean().default(false).describe(
3546
+ llmsTxtFull: z5.boolean().default(false).describe(
3567
3547
  "When enabled, generates an llms-full.txt file with the complete content of all markdown documents for LLM consumption."
3568
3548
  ),
3569
- includeProtected: z7.boolean().default(false).describe(
3549
+ includeProtected: z5.boolean().default(false).describe(
3570
3550
  "When enabled, includes content from protected routes in the generated .md files and llms.txt files. By default, protected routes are excluded."
3571
3551
  ),
3572
- title: z7.string().trim().min(1).optional().describe(
3552
+ title: z5.string().trim().min(1).optional().describe(
3573
3553
  "The project or site name rendered as the llms.txt H1. Defaults to the configured site title."
3574
3554
  ),
3575
- description: z7.string().trim().min(1).optional().describe("A short project summary rendered as the llms.txt blockquote."),
3576
- instructions: z7.string().trim().min(1).optional().describe(
3555
+ description: z5.string().trim().min(1).optional().describe("A short project summary rendered as the llms.txt blockquote."),
3556
+ instructions: z5.string().trim().min(1).optional().describe(
3577
3557
  "Guidance for agents, such as when to use the documentation and how to interpret it. Rendered as introductory prose before the link sections."
3578
3558
  )
3579
3559
  }).partial().prefault({});
3580
- var DocsConfigSchema = z7.object({
3581
- files: z7.union([z7.string(), z7.array(z7.string())]).transform((val) => typeof val === "string" ? [val] : val).default([DEFAULT_DOCS_FILES]),
3582
- publishMarkdown: z7.boolean().default(true).describe(
3560
+ var DocsConfigSchema = z5.object({
3561
+ files: z5.union([z5.string(), z5.array(z5.string())]).transform((val) => typeof val === "string" ? [val] : val).default([DEFAULT_DOCS_FILES]),
3562
+ publishMarkdown: z5.boolean().default(true).describe(
3583
3563
  "When enabled, generates .md files for each document during build. Access documents at their URL path with .md extension (e.g., /foo/hello.md). Markdown files are generated without frontmatter."
3584
3564
  ),
3585
- contentNegotiation: z7.boolean().optional().describe(
3565
+ contentNegotiation: z5.boolean().optional().describe(
3586
3566
  "When enabled, serves generated Markdown at canonical document URLs when Accept prefers text/markdown and adds Vary: Accept. Defaults to the value of publishMarkdown."
3587
3567
  ),
3588
- defaultOptions: z7.object({
3589
- toc: z7.boolean(),
3590
- copyPage: z7.boolean().optional(),
3591
- disablePager: z7.boolean(),
3592
- showLastModified: z7.boolean(),
3593
- fullWidth: z7.boolean().optional(),
3594
- centered: z7.boolean().optional(),
3595
- suggestEdit: z7.object({
3596
- url: z7.string(),
3597
- text: z7.string().optional()
3568
+ defaultOptions: z5.object({
3569
+ toc: z5.boolean(),
3570
+ copyPage: z5.boolean().optional(),
3571
+ disablePager: z5.boolean(),
3572
+ showLastModified: z5.boolean(),
3573
+ fullWidth: z5.boolean().optional(),
3574
+ centered: z5.boolean().optional(),
3575
+ suggestEdit: z5.object({
3576
+ url: z5.string(),
3577
+ text: z5.string().optional()
3598
3578
  }).optional()
3599
3579
  }).partial().optional(),
3600
3580
  llms: LlmsConfigSchema
@@ -3602,73 +3582,73 @@ var DocsConfigSchema = z7.object({
3602
3582
  ...docs,
3603
3583
  contentNegotiation: docs.publishMarkdown && (docs.contentNegotiation ?? true)
3604
3584
  })).prefault({});
3605
- var Redirect = z7.object({
3606
- from: z7.string(),
3607
- to: z7.string()
3585
+ var Redirect = z5.object({
3586
+ from: z5.string(),
3587
+ to: z5.string()
3608
3588
  });
3609
- var SearchSchema = z7.discriminatedUnion("type", [
3589
+ var SearchSchema = z5.discriminatedUnion("type", [
3610
3590
  // looseObject to allow additional properties so the
3611
3591
  // user can set other inkeep settings
3612
- z7.looseObject({
3613
- type: z7.literal("inkeep"),
3614
- apiKey: z7.string(),
3615
- integrationId: z7.string(),
3616
- organizationId: z7.string(),
3617
- primaryBrandColor: z7.string(),
3618
- organizationDisplayName: z7.string(),
3619
- searchSettings: z7.custom().optional(),
3620
- aiChatSettings: z7.custom().optional(),
3621
- modalSettings: z7.custom().optional()
3592
+ z5.looseObject({
3593
+ type: z5.literal("inkeep"),
3594
+ apiKey: z5.string(),
3595
+ integrationId: z5.string(),
3596
+ organizationId: z5.string(),
3597
+ primaryBrandColor: z5.string(),
3598
+ organizationDisplayName: z5.string(),
3599
+ searchSettings: z5.custom().optional(),
3600
+ aiChatSettings: z5.custom().optional(),
3601
+ modalSettings: z5.custom().optional()
3622
3602
  }),
3623
- z7.object({
3624
- type: z7.literal("pagefind"),
3625
- ranking: z7.object({
3626
- termFrequency: z7.number(),
3627
- pageLength: z7.number(),
3628
- termSimilarity: z7.number(),
3629
- termSaturation: z7.number()
3603
+ z5.object({
3604
+ type: z5.literal("pagefind"),
3605
+ ranking: z5.object({
3606
+ termFrequency: z5.number(),
3607
+ pageLength: z5.number(),
3608
+ termSimilarity: z5.number(),
3609
+ termSaturation: z5.number()
3630
3610
  }).optional(),
3631
- maxResults: z7.number().optional(),
3632
- maxSubResults: z7.number().optional(),
3633
- transformResults: z7.custom((val) => typeof val === "function").optional()
3611
+ maxResults: z5.number().optional(),
3612
+ maxSubResults: z5.number().optional(),
3613
+ transformResults: z5.custom((val) => typeof val === "function").optional()
3634
3614
  })
3635
3615
  ]).optional();
3636
- var SignUpUrlValueSchema = z7.string().min(1).refine((v) => v.startsWith("/") || URL.canParse(v), {
3616
+ var SignUpUrlValueSchema = z5.string().min(1).refine((v) => v.startsWith("/") || URL.canParse(v), {
3637
3617
  message: "signUp.url must be an absolute URL or a path starting with '/'"
3638
3618
  });
3639
- var SignUpUrlSchema = z7.object({ url: SignUpUrlValueSchema }).strict();
3640
- var SignUpOpenIdSchema = z7.union([
3619
+ var SignUpUrlSchema = z5.object({ url: SignUpUrlValueSchema }).strict();
3620
+ var SignUpOpenIdSchema = z5.union([
3641
3621
  SignUpUrlSchema,
3642
- z7.object({
3643
- authorizationParams: z7.record(z7.string(), z7.string())
3622
+ z5.object({
3623
+ authorizationParams: z5.record(z5.string(), z5.string())
3644
3624
  }).strict()
3645
3625
  ]);
3646
- var AuthenticationSchema = z7.discriminatedUnion("type", [
3647
- z7.object({
3648
- type: z7.literal("clerk"),
3649
- clerkPubKey: z7.custom().refine((val) => /^pk_(test|live)_\w+$/.test(val), {
3626
+ var AuthenticationSchema = z5.discriminatedUnion("type", [
3627
+ z5.object({
3628
+ type: z5.literal("clerk"),
3629
+ clerkPubKey: z5.custom().refine((val) => /^pk_(test|live)_\w+$/.test(val), {
3650
3630
  message: "Clerk public key invalid, must start with pk_test or pk_live"
3651
3631
  }),
3652
3632
  // No default: an absent template must stay absent so Clerk issues its
3653
3633
  // standard session token instead of requesting a non-existent template.
3654
- jwtTemplateName: z7.string().optional(),
3655
- redirectToAfterSignUp: z7.string().optional(),
3656
- redirectToAfterSignIn: z7.string().optional(),
3657
- redirectToAfterSignOut: z7.string().optional(),
3634
+ jwtTemplateName: z5.string().optional(),
3635
+ redirectToAfterSignUp: z5.string().optional(),
3636
+ redirectToAfterSignIn: z5.string().optional(),
3637
+ redirectToAfterSignOut: z5.string().optional(),
3658
3638
  signUp: SignUpUrlSchema.optional(),
3659
- disableSignUp: z7.boolean().optional()
3639
+ disableSignUp: z5.boolean().optional()
3660
3640
  }),
3661
- z7.object({
3662
- type: z7.literal("firebase"),
3663
- apiKey: z7.string(),
3664
- authDomain: z7.string(),
3665
- projectId: z7.string(),
3666
- storageBucket: z7.string().optional(),
3667
- messagingSenderId: z7.string().optional(),
3668
- appId: z7.string(),
3669
- measurementId: z7.string().optional(),
3670
- providers: z7.array(
3671
- z7.enum([
3641
+ z5.object({
3642
+ type: z5.literal("firebase"),
3643
+ apiKey: z5.string(),
3644
+ authDomain: z5.string(),
3645
+ projectId: z5.string(),
3646
+ storageBucket: z5.string().optional(),
3647
+ messagingSenderId: z5.string().optional(),
3648
+ appId: z5.string(),
3649
+ measurementId: z5.string().optional(),
3650
+ providers: z5.array(
3651
+ z5.enum([
3672
3652
  "google",
3673
3653
  "facebook",
3674
3654
  "twitter",
@@ -3680,65 +3660,65 @@ var AuthenticationSchema = z7.discriminatedUnion("type", [
3680
3660
  "emailLink"
3681
3661
  ])
3682
3662
  ).optional(),
3683
- disableSignUp: z7.boolean().optional(),
3684
- redirectToAfterSignUp: z7.string().optional(),
3685
- redirectToAfterSignIn: z7.string().optional(),
3686
- redirectToAfterSignOut: z7.string().optional(),
3663
+ disableSignUp: z5.boolean().optional(),
3664
+ redirectToAfterSignUp: z5.string().optional(),
3665
+ redirectToAfterSignIn: z5.string().optional(),
3666
+ redirectToAfterSignOut: z5.string().optional(),
3687
3667
  signUp: SignUpUrlSchema.optional()
3688
3668
  }),
3689
- z7.object({
3690
- type: z7.literal("openid"),
3691
- basePath: z7.string().optional(),
3692
- clientId: z7.string(),
3693
- issuer: z7.string(),
3694
- audience: z7.string().optional(),
3695
- scopes: z7.array(z7.string()).optional(),
3696
- allowInsecureRequests: z7.boolean().optional(),
3697
- redirectToAfterSignUp: z7.string().optional(),
3698
- redirectToAfterSignIn: z7.string().optional(),
3699
- redirectToAfterSignOut: z7.string().optional(),
3669
+ z5.object({
3670
+ type: z5.literal("openid"),
3671
+ basePath: z5.string().optional(),
3672
+ clientId: z5.string(),
3673
+ issuer: z5.string(),
3674
+ audience: z5.string().optional(),
3675
+ scopes: z5.array(z5.string()).optional(),
3676
+ allowInsecureRequests: z5.boolean().optional(),
3677
+ redirectToAfterSignUp: z5.string().optional(),
3678
+ redirectToAfterSignIn: z5.string().optional(),
3679
+ redirectToAfterSignOut: z5.string().optional(),
3700
3680
  signUp: SignUpOpenIdSchema.optional(),
3701
- disableSignUp: z7.boolean().optional(),
3702
- authorizationParams: z7.record(z7.string(), z7.string()).optional(),
3703
- forwardAuthorizationParams: z7.array(z7.string()).optional()
3681
+ disableSignUp: z5.boolean().optional(),
3682
+ authorizationParams: z5.record(z5.string(), z5.string()).optional(),
3683
+ forwardAuthorizationParams: z5.array(z5.string()).optional()
3704
3684
  }),
3705
- z7.object({
3706
- type: z7.literal("entra"),
3707
- basePath: z7.string().optional(),
3708
- clientId: z7.string(),
3685
+ z5.object({
3686
+ type: z5.literal("entra"),
3687
+ basePath: z5.string().optional(),
3688
+ clientId: z5.string(),
3709
3689
  // Tenant id or one of Entra's multi-tenant authorities
3710
3690
  // (common/organizations/consumers). Defaults to "common".
3711
- tenantId: z7.string().optional(),
3691
+ tenantId: z5.string().optional(),
3712
3692
  // Full issuer override, e.g. for CIAM tenants on *.ciamlogin.com.
3713
- issuer: z7.string().optional(),
3714
- audience: z7.string().optional(),
3715
- scopes: z7.array(z7.string()).optional(),
3716
- redirectToAfterSignUp: z7.string().optional(),
3717
- redirectToAfterSignIn: z7.string().optional(),
3718
- redirectToAfterSignOut: z7.string().optional(),
3693
+ issuer: z5.string().optional(),
3694
+ audience: z5.string().optional(),
3695
+ scopes: z5.array(z5.string()).optional(),
3696
+ redirectToAfterSignUp: z5.string().optional(),
3697
+ redirectToAfterSignIn: z5.string().optional(),
3698
+ redirectToAfterSignOut: z5.string().optional(),
3719
3699
  signUp: SignUpOpenIdSchema.optional(),
3720
- disableSignUp: z7.boolean().optional(),
3721
- authorizationParams: z7.record(z7.string(), z7.string()).optional(),
3722
- forwardAuthorizationParams: z7.array(z7.string()).optional()
3700
+ disableSignUp: z5.boolean().optional(),
3701
+ authorizationParams: z5.record(z5.string(), z5.string()).optional(),
3702
+ forwardAuthorizationParams: z5.array(z5.string()).optional()
3723
3703
  }),
3724
- z7.object({
3725
- type: z7.literal("azureb2c"),
3726
- basePath: z7.string().optional(),
3727
- clientId: z7.string(),
3728
- tenantName: z7.string(),
3729
- policyName: z7.string(),
3730
- scopes: z7.array(z7.string()).optional(),
3731
- issuer: z7.string(),
3732
- redirectToAfterSignUp: z7.string().optional(),
3733
- redirectToAfterSignIn: z7.string().optional(),
3734
- redirectToAfterSignOut: z7.string().optional(),
3704
+ z5.object({
3705
+ type: z5.literal("azureb2c"),
3706
+ basePath: z5.string().optional(),
3707
+ clientId: z5.string(),
3708
+ tenantName: z5.string(),
3709
+ policyName: z5.string(),
3710
+ scopes: z5.array(z5.string()).optional(),
3711
+ issuer: z5.string(),
3712
+ redirectToAfterSignUp: z5.string().optional(),
3713
+ redirectToAfterSignIn: z5.string().optional(),
3714
+ redirectToAfterSignOut: z5.string().optional(),
3735
3715
  signUp: SignUpUrlSchema.optional(),
3736
- disableSignUp: z7.boolean().optional()
3716
+ disableSignUp: z5.boolean().optional()
3737
3717
  }),
3738
- z7.object({
3739
- type: z7.literal("auth0"),
3740
- clientId: z7.string(),
3741
- domain: z7.string().refine(
3718
+ z5.object({
3719
+ type: z5.literal("auth0"),
3720
+ clientId: z5.string(),
3721
+ domain: z5.string().refine(
3742
3722
  (val) => {
3743
3723
  if (val.startsWith("http://") || val.startsWith("https://")) {
3744
3724
  return false;
@@ -3752,133 +3732,133 @@ var AuthenticationSchema = z7.discriminatedUnion("type", [
3752
3732
  message: "Domain must be a host only (e.g., 'example.com') without protocol or slashes"
3753
3733
  }
3754
3734
  ),
3755
- audience: z7.string().optional(),
3756
- scopes: z7.array(z7.string()).optional(),
3757
- redirectToAfterSignUp: z7.string().optional(),
3758
- redirectToAfterSignIn: z7.string().optional(),
3759
- redirectToAfterSignOut: z7.string().optional(),
3760
- authorizationParams: z7.record(z7.string(), z7.string()).optional(),
3761
- forwardAuthorizationParams: z7.array(z7.string()).optional(),
3762
- options: z7.object({
3763
- alwaysPromptLogin: z7.boolean().optional(),
3764
- prompt: z7.string().optional()
3735
+ audience: z5.string().optional(),
3736
+ scopes: z5.array(z5.string()).optional(),
3737
+ redirectToAfterSignUp: z5.string().optional(),
3738
+ redirectToAfterSignIn: z5.string().optional(),
3739
+ redirectToAfterSignOut: z5.string().optional(),
3740
+ authorizationParams: z5.record(z5.string(), z5.string()).optional(),
3741
+ forwardAuthorizationParams: z5.array(z5.string()).optional(),
3742
+ options: z5.object({
3743
+ alwaysPromptLogin: z5.boolean().optional(),
3744
+ prompt: z5.string().optional()
3765
3745
  }).optional(),
3766
3746
  signUp: SignUpOpenIdSchema.optional(),
3767
- disableSignUp: z7.boolean().optional()
3747
+ disableSignUp: z5.boolean().optional()
3768
3748
  }),
3769
- z7.object({
3770
- type: z7.literal("supabase"),
3771
- basePath: z7.string().optional(),
3772
- supabaseUrl: z7.string(),
3773
- supabaseKey: z7.string(),
3774
- provider: z7.string().optional(),
3775
- providers: z7.array(z7.string()).optional(),
3776
- onlyThirdPartyProviders: z7.boolean().optional(),
3777
- disableSignUp: z7.boolean().optional(),
3778
- redirectToAfterSignUp: z7.string().optional(),
3779
- redirectToAfterSignIn: z7.string().optional(),
3780
- redirectToAfterSignOut: z7.string().optional(),
3749
+ z5.object({
3750
+ type: z5.literal("supabase"),
3751
+ basePath: z5.string().optional(),
3752
+ supabaseUrl: z5.string(),
3753
+ supabaseKey: z5.string(),
3754
+ provider: z5.string().optional(),
3755
+ providers: z5.array(z5.string()).optional(),
3756
+ onlyThirdPartyProviders: z5.boolean().optional(),
3757
+ disableSignUp: z5.boolean().optional(),
3758
+ redirectToAfterSignUp: z5.string().optional(),
3759
+ redirectToAfterSignIn: z5.string().optional(),
3760
+ redirectToAfterSignOut: z5.string().optional(),
3781
3761
  signUp: SignUpUrlSchema.optional()
3782
3762
  })
3783
3763
  ]);
3784
- var MetadataSchema = z7.object({
3785
- title: z7.string(),
3786
- defaultTitle: z7.string().optional(),
3787
- description: z7.string(),
3788
- logo: z7.string(),
3789
- favicon: z7.string(),
3790
- generator: z7.string(),
3791
- applicationName: z7.string(),
3792
- referrer: z7.string(),
3793
- keywords: z7.array(z7.string()),
3794
- authors: z7.array(z7.string()),
3795
- creator: z7.string(),
3796
- publisher: z7.string(),
3797
- robots: z7.string().describe(
3764
+ var MetadataSchema = z5.object({
3765
+ title: z5.string(),
3766
+ defaultTitle: z5.string().optional(),
3767
+ description: z5.string(),
3768
+ logo: z5.string(),
3769
+ favicon: z5.string(),
3770
+ generator: z5.string(),
3771
+ applicationName: z5.string(),
3772
+ referrer: z5.string(),
3773
+ keywords: z5.array(z5.string()),
3774
+ authors: z5.array(z5.string()),
3775
+ creator: z5.string(),
3776
+ publisher: z5.string(),
3777
+ robots: z5.string().describe(
3798
3778
  'Sets the contents of the `meta[name="robots"]` tag. For example: `noindex, nofollow`.'
3799
3779
  )
3800
3780
  }).partial();
3801
- var FontConfigSchema = z7.union([
3802
- z7.enum(GOOGLE_FONTS),
3803
- z7.object({
3804
- url: z7.string(),
3805
- fontFamily: z7.string().optional()
3781
+ var FontConfigSchema = z5.union([
3782
+ z5.enum(GOOGLE_FONTS),
3783
+ z5.object({
3784
+ url: z5.string(),
3785
+ fontFamily: z5.string().optional()
3806
3786
  })
3807
3787
  ]);
3808
- var FontsConfigSchema = z7.object({
3788
+ var FontsConfigSchema = z5.object({
3809
3789
  sans: FontConfigSchema.optional(),
3810
3790
  serif: FontConfigSchema.optional(),
3811
3791
  mono: FontConfigSchema.optional()
3812
3792
  });
3813
- var CssObject = z7.record(
3814
- z7.string(),
3815
- z7.lazy(
3816
- () => z7.union([
3817
- z7.string(),
3818
- z7.record(
3819
- z7.string(),
3820
- z7.union([z7.string(), z7.record(z7.string(), z7.string())])
3793
+ var CssObject = z5.record(
3794
+ z5.string(),
3795
+ z5.lazy(
3796
+ () => z5.union([
3797
+ z5.string(),
3798
+ z5.record(
3799
+ z5.string(),
3800
+ z5.union([z5.string(), z5.record(z5.string(), z5.string())])
3821
3801
  )
3822
3802
  ])
3823
3803
  )
3824
3804
  );
3825
- var ThemeConfigSchema = z7.object({
3826
- registryUrl: z7.url().optional(),
3805
+ var ThemeConfigSchema = z5.object({
3806
+ registryUrl: z5.url().optional(),
3827
3807
  /**
3828
3808
  * @deprecated Import a `.css` file from your `zudoku.config.ts` instead.
3829
3809
  * Inline CSS via this option still works but requires a dev server restart
3830
3810
  * on every change and provides no editor tooling.
3831
3811
  */
3832
- customCss: z7.union([z7.string(), CssObject]).optional(),
3812
+ customCss: z5.union([z5.string(), CssObject]).optional(),
3833
3813
  light: ThemeSchema.optional(),
3834
3814
  dark: ThemeSchema.optional(),
3835
3815
  fonts: FontsConfigSchema.optional(),
3836
- noDefaultTheme: z7.boolean().optional()
3816
+ noDefaultTheme: z5.boolean().optional()
3837
3817
  });
3838
- var SiteSchema = z7.object({
3839
- title: z7.string(),
3840
- logoUrl: z7.string(),
3841
- dir: z7.enum(["ltr", "rtl"]).optional(),
3818
+ var SiteSchema = z5.object({
3819
+ title: z5.string(),
3820
+ logoUrl: z5.string(),
3821
+ dir: z5.enum(["ltr", "rtl"]).optional(),
3842
3822
  logo: LogoSchema,
3843
- showPoweredBy: z7.boolean().optional(),
3844
- sidebar: z7.object({
3845
- collapsible: z7.boolean().optional(),
3846
- toggleVisibility: z7.enum(["always", "hover"]).optional(),
3847
- togglePosition: z7.enum(["top", "center", "bottom"]).optional()
3823
+ showPoweredBy: z5.boolean().optional(),
3824
+ sidebar: z5.object({
3825
+ collapsible: z5.boolean().optional(),
3826
+ toggleVisibility: z5.enum(["always", "hover"]).optional(),
3827
+ togglePosition: z5.enum(["top", "center", "bottom"]).optional()
3848
3828
  }).optional(),
3849
- notFoundPage: z7.custom(),
3850
- banner: z7.object({
3851
- message: z7.custom(),
3852
- color: z7.custom(
3829
+ notFoundPage: z5.custom(),
3830
+ banner: z5.object({
3831
+ message: z5.custom(),
3832
+ color: z5.custom(
3853
3833
  (val) => typeof val === "string"
3854
3834
  ).optional(),
3855
- dismissible: z7.boolean().optional()
3835
+ dismissible: z5.boolean().optional()
3856
3836
  }),
3857
3837
  footer: FooterSchema
3858
3838
  }).partial();
3859
- var PlacementPosition = z7.enum(["start", "center", "end"]);
3860
- var HeaderConfigSchema = z7.object({
3839
+ var PlacementPosition = z5.enum(["start", "center", "end"]);
3840
+ var HeaderConfigSchema = z5.object({
3861
3841
  navigation: HeaderNavigationSchema,
3862
- themeSwitcher: z7.object({
3863
- enabled: z7.boolean()
3842
+ themeSwitcher: z5.object({
3843
+ enabled: z5.boolean()
3864
3844
  }).partial().optional(),
3865
- placements: z7.object({
3845
+ placements: z5.object({
3866
3846
  navigation: PlacementPosition,
3867
3847
  search: PlacementPosition,
3868
- auth: z7.enum(["start", "center", "end", "navigation"])
3848
+ auth: z5.enum(["start", "center", "end", "navigation"])
3869
3849
  }).partial().optional()
3870
3850
  }).partial();
3871
- var ApiCatalogSchema = z7.object({
3872
- path: z7.string(),
3873
- label: z7.string(),
3874
- items: z7.array(z7.string()).optional(),
3875
- filterItems: z7.custom((val) => typeof val === "function").optional()
3851
+ var ApiCatalogSchema = z5.object({
3852
+ path: z5.string(),
3853
+ label: z5.string(),
3854
+ items: z5.array(z5.string()).optional(),
3855
+ filterItems: z5.custom((val) => typeof val === "function").optional()
3876
3856
  });
3877
- var CdnUrlSchema = z7.union([
3878
- z7.string(),
3879
- z7.object({
3880
- base: z7.string().optional(),
3881
- media: z7.string().optional()
3857
+ var CdnUrlSchema = z5.union([
3858
+ z5.string(),
3859
+ z5.object({
3860
+ base: z5.string().optional(),
3861
+ media: z5.string().optional()
3882
3862
  })
3883
3863
  ]).transform((val) => {
3884
3864
  if (typeof val === "string") {
@@ -3886,66 +3866,66 @@ var CdnUrlSchema = z7.union([
3886
3866
  }
3887
3867
  return { base: val.base, media: val.media };
3888
3868
  });
3889
- var BaseConfigSchema = z7.object({
3890
- slots: z7.record(z7.string(), z7.custom()),
3869
+ var BaseConfigSchema = z5.object({
3870
+ slots: z5.record(z5.string(), z5.custom()),
3891
3871
  /**
3892
3872
  * @deprecated Use `slots` instead
3893
3873
  */
3894
- UNSAFE_slotlets: z7.record(z7.string(), z7.custom()),
3895
- mdx: z7.object({
3896
- components: z7.custom()
3874
+ UNSAFE_slotlets: z5.record(z5.string(), z5.custom()),
3875
+ mdx: z5.object({
3876
+ components: z5.custom()
3897
3877
  }).partial(),
3898
- customPages: z7.array(
3899
- z7.object({
3900
- path: z7.string(),
3901
- element: z7.custom().optional(),
3902
- render: z7.custom().optional(),
3903
- prose: z7.boolean().optional()
3878
+ customPages: z5.array(
3879
+ z5.object({
3880
+ path: z5.string(),
3881
+ element: z5.custom().optional(),
3882
+ render: z5.custom().optional(),
3883
+ prose: z5.boolean().optional()
3904
3884
  })
3905
3885
  ),
3906
- plugins: z7.array(z7.custom()),
3907
- build: z7.custom(),
3886
+ plugins: z5.array(z5.custom()),
3887
+ build: z5.custom(),
3908
3888
  protectedRoutes: ProtectedRoutesSchema,
3909
- basePath: z7.string().optional(),
3910
- canonicalUrlOrigin: z7.string().optional(),
3889
+ basePath: z5.string().optional(),
3890
+ canonicalUrlOrigin: z5.string().optional(),
3911
3891
  cdnUrl: CdnUrlSchema.optional(),
3912
- port: z7.number().optional(),
3913
- https: z7.object({
3914
- key: z7.string(),
3915
- cert: z7.string(),
3916
- ca: z7.string().optional()
3892
+ port: z5.number().optional(),
3893
+ https: z5.object({
3894
+ key: z5.string(),
3895
+ cert: z5.string(),
3896
+ ca: z5.string().optional()
3917
3897
  }).optional(),
3918
3898
  site: SiteSchema,
3919
3899
  header: HeaderConfigSchema.optional(),
3920
3900
  navigation: InputNavigationSchema,
3921
3901
  navigationRules: NavigationRulesSchema.optional(),
3922
3902
  theme: ThemeConfigSchema,
3923
- syntaxHighlighting: z7.object({
3924
- languages: z7.array(z7.custom()),
3925
- themes: z7.object({
3926
- light: z7.custom(),
3927
- dark: z7.custom()
3903
+ syntaxHighlighting: z5.object({
3904
+ languages: z5.array(z5.custom()),
3905
+ themes: z5.object({
3906
+ light: z5.custom(),
3907
+ dark: z5.custom()
3928
3908
  })
3929
3909
  }).partial().optional(),
3930
3910
  metadata: MetadataSchema,
3931
3911
  authentication: AuthenticationSchema,
3932
3912
  search: SearchSchema,
3933
- apis: z7.union([ApiSchema, z7.array(ApiSchema)]),
3934
- catalogs: z7.union([ApiCatalogSchema, z7.array(ApiCatalogSchema)]),
3913
+ apis: z5.union([ApiSchema, z5.array(ApiSchema)]),
3914
+ catalogs: z5.union([ApiCatalogSchema, z5.array(ApiCatalogSchema)]),
3935
3915
  apiKeys: ApiKeysSchema,
3936
3916
  aiAssistants: AiAssistantsSchema,
3937
- redirects: z7.array(Redirect),
3917
+ redirects: z5.array(Redirect),
3938
3918
  sitemap: SiteMapSchema,
3939
- enableStatusPages: z7.boolean().optional(),
3940
- defaults: z7.object({
3919
+ enableStatusPages: z5.boolean().optional(),
3920
+ defaults: z5.object({
3941
3921
  apis: ApiOptionsSchema,
3942
3922
  /**
3943
3923
  * @deprecated Use `apis.examplesLanguage` or `defaults.apis.examplesLanguage` instead
3944
3924
  */
3945
- examplesLanguage: z7.string().optional()
3925
+ examplesLanguage: z5.string().optional()
3946
3926
  }),
3947
3927
  // Internal: populated by plugins via `transformConfig` to track plugin directories
3948
- __pluginDirs: z7.array(z7.string())
3928
+ __pluginDirs: z5.array(z5.string())
3949
3929
  });
3950
3930
  var ZudokuConfig = BaseConfigSchema.partial().extend({
3951
3931
  docs: DocsConfigSchema
@@ -3956,7 +3936,7 @@ function validateConfig(config, configPath) {
3956
3936
  if (validationResult.success) {
3957
3937
  return validationResult.data;
3958
3938
  }
3959
- const prettyErrors = z7.prettifyError(validationResult.error);
3939
+ const prettyErrors = z5.prettifyError(validationResult.error);
3960
3940
  const location = configPath ? ` at ${configPath}` : "";
3961
3941
  if (process.env.NODE_ENV === "production") {
3962
3942
  throw new Error(
@@ -4236,9 +4216,9 @@ var getIssuer = async (config) => {
4236
4216
  init_joinUrl();
4237
4217
 
4238
4218
  // src/vite/config.ts
4239
- import path18 from "node:path";
4219
+ import path19 from "node:path";
4240
4220
  import dotenv from "dotenv";
4241
- import colors4 from "picocolors";
4221
+ import colors5 from "picocolors";
4242
4222
  import {
4243
4223
  loadConfigFromFile,
4244
4224
  mergeConfig as mergeConfig2
@@ -4402,21 +4382,6 @@ function invalidateModule(server, id) {
4402
4382
  }
4403
4383
  }
4404
4384
 
4405
- // src/vite/zuplo.ts
4406
- import bs58 from "bs58";
4407
- var getZuploSystemConfigurations = (string) => {
4408
- if (!string) return void 0;
4409
- try {
4410
- const zuploSystemConfigurations = JSON.parse(
4411
- Buffer.from(bs58.decode(string)).toString("utf8")
4412
- );
4413
- return zuploSystemConfigurations;
4414
- } catch (error) {
4415
- console.error(error);
4416
- return void 0;
4417
- }
4418
- };
4419
-
4420
4385
  // src/vite/plugin-api-keys.ts
4421
4386
  var viteApiKeysPlugin = () => {
4422
4387
  const virtualModuleId4 = "virtual:zudoku-api-keys-plugin";
@@ -4434,7 +4399,7 @@ var viteApiKeysPlugin = () => {
4434
4399
  if (!config.apiKeys?.enabled || config.__meta.mode === "standalone") {
4435
4400
  return `export const configuredApiKeysPlugin = undefined;`;
4436
4401
  }
4437
- const deploymentName = ZuploEnv.buildConfig?.deploymentName || getZuploSystemConfigurations(process.env.ZUPLO_SYSTEM_CONFIGURATIONS)?.__ZUPLO_DEPLOYMENT_NAME;
4402
+ const deploymentName = ZuploEnv.deploymentName;
4438
4403
  const code = [
4439
4404
  `import config from "virtual:zudoku-config";`,
4440
4405
  `import { apiKeyPlugin } from "zudoku/plugins/api-keys";`,
@@ -4464,18 +4429,18 @@ import { parse as parseYaml } from "yaml";
4464
4429
  // src/config/validators/BuildSchema.ts
4465
4430
  import path7 from "node:path";
4466
4431
  import { runnerImport as runnerImport2 } from "vite";
4467
- import { z as z8 } from "zod";
4468
- var BuildProcessorSchema = z8.custom((val) => typeof val === "function");
4469
- var PluginConfigSchema = z8.custom().or(
4470
- z8.custom(
4432
+ import { z as z6 } from "zod";
4433
+ var BuildProcessorSchema = z6.custom((val) => typeof val === "function");
4434
+ var PluginConfigSchema = z6.custom().or(
4435
+ z6.custom(
4471
4436
  (val) => typeof val === "function"
4472
4437
  )
4473
4438
  );
4474
- var BuildConfigSchema2 = z8.object({
4475
- processors: z8.array(BuildProcessorSchema).optional(),
4439
+ var BuildConfigSchema = z6.object({
4440
+ processors: z6.array(BuildProcessorSchema).optional(),
4476
4441
  remarkPlugins: PluginConfigSchema.optional(),
4477
4442
  rehypePlugins: PluginConfigSchema.optional(),
4478
- prerender: z8.object({ workers: z8.number().optional() }).optional()
4443
+ prerender: z6.object({ workers: z6.number().optional() }).optional()
4479
4444
  });
4480
4445
  var zudokuBuildConfigFiles = [
4481
4446
  "zudoku.build.js",
@@ -4505,13 +4470,13 @@ var getBuildConfig = async () => {
4505
4470
  return validateBuildConfig(buildModule);
4506
4471
  };
4507
4472
  function validateBuildConfig(config) {
4508
- const validationResult = BuildConfigSchema2.safeParse(config);
4473
+ const validationResult = BuildConfigSchema.safeParse(config);
4509
4474
  if (!validationResult.success) {
4510
4475
  if (process.env.NODE_ENV === "production") {
4511
- throw new Error(z8.prettifyError(validationResult.error));
4476
+ throw new Error(z6.prettifyError(validationResult.error));
4512
4477
  }
4513
4478
  console.warn("Build config validation errors:");
4514
- console.warn(z8.prettifyError(validationResult.error));
4479
+ console.warn(z6.prettifyError(validationResult.error));
4515
4480
  return;
4516
4481
  }
4517
4482
  return validationResult.data;
@@ -4608,14 +4573,14 @@ var flattenAllOf = (schema2) => {
4608
4573
  };
4609
4574
 
4610
4575
  // src/lib/util/traverse.ts
4611
- var traverse = (specification, transform, path32 = []) => {
4612
- const transformed = transform(specification, path32);
4576
+ var traverse = (specification, transform, path33 = []) => {
4577
+ const transformed = transform(specification, path33);
4613
4578
  if (typeof transformed !== "object" || transformed === null) {
4614
4579
  return transformed;
4615
4580
  }
4616
4581
  const result = Array.isArray(transformed) ? [] : {};
4617
4582
  for (const [key, value] of Object.entries(transformed)) {
4618
- const currentPath = [...path32, key];
4583
+ const currentPath = [...path33, key];
4619
4584
  if (Array.isArray(value)) {
4620
4585
  result[key] = value.map(
4621
4586
  (item, index) => typeof item === "object" && item != null ? traverse(item, transform, [...currentPath, index.toString()]) : item
@@ -4643,9 +4608,9 @@ var resolveLocalRef = (schema2, ref) => {
4643
4608
  if (schemaCache?.has(ref)) {
4644
4609
  return schemaCache.get(ref);
4645
4610
  }
4646
- const path32 = ref.split("/").slice(1);
4611
+ const path33 = ref.split("/").slice(1);
4647
4612
  let current = schema2;
4648
- for (const segment of path32) {
4613
+ for (const segment of path33) {
4649
4614
  if (!current || typeof current !== "object") {
4650
4615
  current = null;
4651
4616
  }
@@ -4664,7 +4629,7 @@ var dereference = async (schema2, resolvers = []) => {
4664
4629
  }
4665
4630
  const cloned = structuredClone(schema2);
4666
4631
  const visited = /* @__PURE__ */ new Set();
4667
- const resolve = async (current, path32) => {
4632
+ const resolve = async (current, path33) => {
4668
4633
  if (isIndexableObject(current)) {
4669
4634
  if (visited.has(current)) {
4670
4635
  return CIRCULAR_REF;
@@ -4672,7 +4637,7 @@ var dereference = async (schema2, resolvers = []) => {
4672
4637
  visited.add(current);
4673
4638
  if (Array.isArray(current)) {
4674
4639
  for (let index = 0; index < current.length; index++) {
4675
- current[index] = await resolve(current[index], `${path32}/${index}`);
4640
+ current[index] = await resolve(current[index], `${path33}/${index}`);
4676
4641
  }
4677
4642
  } else {
4678
4643
  if ("$ref" in current && typeof current.$ref === "string") {
@@ -4683,13 +4648,13 @@ var dereference = async (schema2, resolvers = []) => {
4683
4648
  for (const resolver of resolvers) {
4684
4649
  const resolved = await resolver($ref);
4685
4650
  if (resolved) {
4686
- result2 = await resolve(resolved, path32);
4651
+ result2 = await resolve(resolved, path33);
4687
4652
  break;
4688
4653
  }
4689
4654
  }
4690
4655
  if (result2 === void 0) {
4691
4656
  const resolved = await resolveLocalRef(cloned, $ref);
4692
- result2 = await resolve(resolved, path32);
4657
+ result2 = await resolve(resolved, path33);
4693
4658
  }
4694
4659
  if (hasSiblings) {
4695
4660
  if (result2 === CIRCULAR_REF) {
@@ -4702,7 +4667,7 @@ var dereference = async (schema2, resolvers = []) => {
4702
4667
  return result2;
4703
4668
  }
4704
4669
  for (const key in current) {
4705
- current[key] = await resolve(current[key], `${path32}/${key}`);
4670
+ current[key] = await resolve(current[key], `${path33}/${key}`);
4706
4671
  }
4707
4672
  }
4708
4673
  visited.delete(current);
@@ -4741,9 +4706,9 @@ var upgradeSchema = (schema2) => {
4741
4706
  }
4742
4707
  return sub;
4743
4708
  });
4744
- schema2 = traverse(schema2, (sub, path32) => {
4709
+ schema2 = traverse(schema2, (sub, path33) => {
4745
4710
  if (sub.example !== void 0) {
4746
- if (isSchemaPath(path32 ?? [])) {
4711
+ if (isSchemaPath(path33 ?? [])) {
4747
4712
  sub.examples = [sub.example];
4748
4713
  } else {
4749
4714
  sub.examples = {
@@ -4756,11 +4721,11 @@ var upgradeSchema = (schema2) => {
4756
4721
  }
4757
4722
  return sub;
4758
4723
  });
4759
- schema2 = traverse(schema2, (schema3, path32) => {
4724
+ schema2 = traverse(schema2, (schema3, path33) => {
4760
4725
  if (schema3.type === "object" && schema3.properties !== void 0) {
4761
- const parentPath = path32?.slice(0, -1);
4726
+ const parentPath = path33?.slice(0, -1);
4762
4727
  const isMultipart = parentPath?.some((segment, index) => {
4763
- return segment === "content" && path32?.[index + 1] === "multipart/form-data";
4728
+ return segment === "content" && path33?.[index + 1] === "multipart/form-data";
4764
4729
  });
4765
4730
  if (isMultipart) {
4766
4731
  const entries = Object.entries(schema3.properties);
@@ -4774,8 +4739,8 @@ var upgradeSchema = (schema2) => {
4774
4739
  }
4775
4740
  return schema3;
4776
4741
  });
4777
- schema2 = traverse(schema2, (schema3, path32) => {
4778
- if (path32?.includes("content") && path32.includes("application/octet-stream")) {
4742
+ schema2 = traverse(schema2, (schema3, path33) => {
4743
+ if (path33?.includes("content") && path33.includes("application/octet-stream")) {
4779
4744
  return {};
4780
4745
  }
4781
4746
  if (schema3.type === "string" && schema3.format === "binary") {
@@ -4801,11 +4766,11 @@ var upgradeSchema = (schema2) => {
4801
4766
  }
4802
4767
  return sub;
4803
4768
  });
4804
- schema2 = traverse(schema2, (schema3, path32) => {
4769
+ schema2 = traverse(schema2, (schema3, path33) => {
4805
4770
  if (schema3.type === "string" && schema3.format === "byte") {
4806
- const parentPath = path32?.slice(0, -1);
4771
+ const parentPath = path33?.slice(0, -1);
4807
4772
  const contentMediaType = parentPath?.find(
4808
- (_, index) => path32?.[index - 1] === "content"
4773
+ (_, index) => path33?.[index - 1] === "content"
4809
4774
  );
4810
4775
  return {
4811
4776
  type: "string",
@@ -4817,7 +4782,7 @@ var upgradeSchema = (schema2) => {
4817
4782
  });
4818
4783
  return schema2;
4819
4784
  };
4820
- function isSchemaPath(path32) {
4785
+ function isSchemaPath(path33) {
4821
4786
  const schemaLocations = [
4822
4787
  ["components", "schemas"],
4823
4788
  "properties",
@@ -4830,10 +4795,10 @@ function isSchemaPath(path32) {
4830
4795
  ];
4831
4796
  return schemaLocations.some((location) => {
4832
4797
  if (Array.isArray(location)) {
4833
- return location.every((segment, index) => path32[index] === segment);
4798
+ return location.every((segment, index) => path33[index] === segment);
4834
4799
  }
4835
- return path32.includes(location);
4836
- }) || path32.includes("schema") || path32.some((segment) => segment.endsWith("Schema"));
4800
+ return path33.includes(location);
4801
+ }) || path33.includes("schema") || path33.some((segment) => segment.endsWith("Schema"));
4837
4802
  }
4838
4803
 
4839
4804
  // src/lib/oas/parser/index.ts
@@ -4925,13 +4890,13 @@ var OPENAPI_PROPS = /* @__PURE__ */ new Set([
4925
4890
  "anyOf",
4926
4891
  "oneOf"
4927
4892
  ]);
4928
- var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs = /* @__PURE__ */ new WeakMap(), path32 = [], currentRefPaths = /* @__PURE__ */ new Set()) => {
4893
+ var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs = /* @__PURE__ */ new WeakMap(), path33 = [], currentRefPaths = /* @__PURE__ */ new Set()) => {
4929
4894
  if (obj === null || typeof obj !== "object") return obj;
4930
4895
  const refPath = obj.__$ref;
4931
4896
  const isCircular = currentPath.has(obj) || typeof refPath === "string" && currentRefPaths.has(refPath);
4932
4897
  if (isCircular) {
4933
4898
  if (typeof refPath === "string") return SCHEMA_REF_PREFIX + refPath;
4934
- const circularProp = path32.find((p) => !OPENAPI_PROPS.has(p)) || path32[0];
4899
+ const circularProp = path33.find((p) => !OPENAPI_PROPS.has(p)) || path33[0];
4935
4900
  return [CIRCULAR_REF, circularProp].filter(Boolean).join(":");
4936
4901
  }
4937
4902
  if (refs.has(obj)) return refs.get(obj);
@@ -4941,7 +4906,7 @@ var handleCircularRefs = (obj, currentPath = /* @__PURE__ */ new WeakSet(), refs
4941
4906
  value,
4942
4907
  currentPath,
4943
4908
  refs,
4944
- [...path32, key],
4909
+ [...path33, key],
4945
4910
  currentRefPaths
4946
4911
  );
4947
4912
  const result = Array.isArray(obj) ? obj.map((item, i) => recurse(item, i.toString())) : Object.fromEntries(
@@ -4979,7 +4944,7 @@ var resolveExtensions = (obj) => Object.fromEntries(
4979
4944
  var getAllTags = (schema2) => {
4980
4945
  const rootTags = schema2.tags ?? [];
4981
4946
  const operations = Object.values(schema2.paths ?? {}).flatMap(
4982
- (path32) => HttpMethods.map((k) => path32?.[k]).filter((op) => op != null)
4947
+ (path33) => HttpMethods.map((k) => path33?.[k]).filter((op) => op != null)
4983
4948
  );
4984
4949
  const operationTags = new Set(operations.flatMap((op) => op.tags ?? []));
4985
4950
  const hasUntaggedOperations = operations.some(
@@ -5034,7 +4999,7 @@ var getAllSlugs = (ops, schemaTags = []) => {
5034
4999
  var getOperationSlugKey = (op) => [op.path, op.method, op.operationId, op.summary].filter(Boolean).join("-");
5035
5000
  var getAllOperations = (paths) => {
5036
5001
  const operations = Object.entries(paths ?? {}).flatMap(
5037
- ([path32, value]) => HttpMethods.flatMap((method) => {
5002
+ ([path33, value]) => HttpMethods.flatMap((method) => {
5038
5003
  if (!value?.[method]) return [];
5039
5004
  const operation = value[method];
5040
5005
  const pathParameters = value.parameters ?? [];
@@ -5054,7 +5019,7 @@ var getAllOperations = (paths) => {
5054
5019
  return {
5055
5020
  ...operation,
5056
5021
  method,
5057
- path: path32,
5022
+ path: path33,
5058
5023
  parameters,
5059
5024
  servers,
5060
5025
  tags: operation.tags ?? []
@@ -5583,8 +5548,8 @@ var Schema = builder.objectRef("Schema").implement({
5583
5548
  }),
5584
5549
  paths: t.field({
5585
5550
  type: [PathItem],
5586
- resolve: (root) => Object.entries(root.paths ?? {}).map(([path32, value]) => ({
5587
- path: path32,
5551
+ resolve: (root) => Object.entries(root.paths ?? {}).map(([path33, value]) => ({
5552
+ path: path33,
5588
5553
  // biome-ignore lint/style/noNonNullAssertion: value is guaranteed to be defined
5589
5554
  methods: Object.keys(value)
5590
5555
  }))
@@ -5714,9 +5679,9 @@ var removeParameters = ({ names, in: locations, shouldRemove } = {}) => ({ schem
5714
5679
  }
5715
5680
  if (spec.paths) {
5716
5681
  const updatedPaths = {};
5717
- for (const [path32, pathItem] of Object.entries(spec.paths)) {
5682
+ for (const [path33, pathItem] of Object.entries(spec.paths)) {
5718
5683
  if (typeof pathItem !== "object" || pathItem === null) {
5719
- updatedPaths[path32] = pathItem;
5684
+ updatedPaths[path33] = pathItem;
5720
5685
  continue;
5721
5686
  }
5722
5687
  let updatedPathItem = { ...pathItem };
@@ -5739,7 +5704,7 @@ var removeParameters = ({ names, in: locations, shouldRemove } = {}) => ({ schem
5739
5704
  updatedPathItem = pathItemWithMethods;
5740
5705
  }
5741
5706
  }
5742
- updatedPaths[path32] = updatedPathItem;
5707
+ updatedPaths[path33] = updatedPathItem;
5743
5708
  }
5744
5709
  spec = { ...spec, paths: updatedPaths };
5745
5710
  }
@@ -5750,27 +5715,27 @@ var removeParameters = ({ names, in: locations, shouldRemove } = {}) => ({ schem
5750
5715
  var removePaths = ({ paths = {}, shouldRemove }) => ({ schema: schema2 }) => traverse(schema2, (spec) => {
5751
5716
  if (!spec.paths) return spec;
5752
5717
  const updatedPaths = {};
5753
- for (const [path32, methods] of Object.entries(spec.paths)) {
5754
- const operations = spec.paths[path32];
5755
- if (paths[path32] === true) continue;
5756
- if (shouldRemove?.({ path: path32, method: true, operation: operations }))
5718
+ for (const [path33, methods] of Object.entries(spec.paths)) {
5719
+ const operations = spec.paths[path33];
5720
+ if (paths[path33] === true) continue;
5721
+ if (shouldRemove?.({ path: path33, method: true, operation: operations }))
5757
5722
  continue;
5758
5723
  if (typeof methods === "object" && methods !== null) {
5759
5724
  const filteredPath = Object.fromEntries(
5760
5725
  Object.entries(methods).filter(([method]) => {
5761
- const operations2 = spec.paths[path32][method];
5762
- const isMethodToRemove = Array.isArray(paths[path32]) && paths[path32].includes(method);
5726
+ const operations2 = spec.paths[path33][method];
5727
+ const isMethodToRemove = Array.isArray(paths[path33]) && paths[path33].includes(method);
5763
5728
  const isMethodFiltered = shouldRemove?.({
5764
- path: path32,
5729
+ path: path33,
5765
5730
  method,
5766
5731
  operation: operations2
5767
5732
  });
5768
5733
  return !isMethodToRemove && !isMethodFiltered;
5769
5734
  })
5770
5735
  );
5771
- updatedPaths[path32] = filteredPath;
5736
+ updatedPaths[path33] = filteredPath;
5772
5737
  } else {
5773
- updatedPaths[path32] = methods;
5738
+ updatedPaths[path33] = methods;
5774
5739
  }
5775
5740
  }
5776
5741
  return { ...spec, paths: updatedPaths };
@@ -5905,7 +5870,6 @@ var writeOpenApiPublications = async (outputDir, publications) => {
5905
5870
  import fs2 from "node:fs/promises";
5906
5871
  import path9 from "node:path";
5907
5872
  import { $RefParser as $RefParser2 } from "@apidevtools/json-schema-ref-parser";
5908
- import { upgrade } from "@scalar/openapi-parser";
5909
5873
  import { deepEqual } from "fast-equals";
5910
5874
 
5911
5875
  // src/lib/util/flattenAllOfProcessor.ts
@@ -6123,7 +6087,7 @@ var formatAgentQualityReport = (apiPath, issues) => [
6123
6087
 
6124
6088
  // src/vite/api/schema-codegen.ts
6125
6089
  var unescapeJsonPointer = (uri) => decodeURIComponent(uri.replace(/~1/g, "/").replace(/~0/g, "~"));
6126
- var getSegmentsFromPath = (path32) => path32.split("/").slice(1).map(unescapeJsonPointer);
6090
+ var getSegmentsFromPath = (path33) => path33.split("/").slice(1).map(unescapeJsonPointer);
6127
6091
  var createLocalRefMap = (obj) => {
6128
6092
  const refMap = /* @__PURE__ */ new Map();
6129
6093
  const siblingsMap = /* @__PURE__ */ new Map();
@@ -6154,16 +6118,16 @@ var replaceMarkers = (code, mergedRefs) => code.replace(/"__refMap:(.*?)"/g, '__
6154
6118
  /"__refMap\+Siblings:(.*?)"/g,
6155
6119
  (_, key) => mergedRefs.get(key) ?? `__refMap["${key}"]`
6156
6120
  );
6157
- var lookup = (schema2, path32, filePath) => {
6158
- const parts = getSegmentsFromPath(path32);
6121
+ var lookup = (schema2, path33, filePath) => {
6122
+ const parts = getSegmentsFromPath(path33);
6159
6123
  let val = schema2;
6160
6124
  for (const part of parts) {
6161
6125
  while (val.$ref?.startsWith("#/")) {
6162
- val = val.$ref === path32 ? val : lookup(schema2, val.$ref, filePath);
6126
+ val = val.$ref === path33 ? val : lookup(schema2, val.$ref, filePath);
6163
6127
  }
6164
6128
  if (val[part] === void 0) {
6165
6129
  throw new Error(
6166
- `Error in ${filePath ?? "code generation"}: Could not find path segment ${part} in path: ${path32}`
6130
+ `Error in ${filePath ?? "code generation"}: Could not find path segment ${part} in path: ${path33}`
6167
6131
  );
6168
6132
  }
6169
6133
  val = val[part];
@@ -6216,6 +6180,72 @@ var generateCode = (schema2, filePath) => {
6216
6180
  return lines.join("\n");
6217
6181
  };
6218
6182
 
6183
+ // src/vite/api/upgradeOpenApi.ts
6184
+ import { upgrade } from "@scalar/openapi-parser";
6185
+ var httpMethods2 = new Set(HttpMethods);
6186
+ var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
6187
+ var mapValues = (record, fn) => Object.fromEntries(
6188
+ Object.entries(record).map(([key, value]) => [key, fn(value)])
6189
+ );
6190
+ var upgradeResponse = (response) => upgrade({
6191
+ openapi: "3.0.3",
6192
+ info: { title: "", version: "" },
6193
+ paths: { "/": { get: { responses: { "200": response } } } }
6194
+ }).specification?.paths?.["/"]?.get?.responses?.["200"] ?? response;
6195
+ var upgradeDefaultResponse = (responses) => isRecord(responses) && isRecord(responses.default) ? { ...responses, default: upgradeResponse(responses.default) } : responses;
6196
+ var upgradePathItem = (pathItem) => {
6197
+ if (!isRecord(pathItem)) return pathItem;
6198
+ return Object.fromEntries(
6199
+ Object.entries(pathItem).map(([method, operation]) => {
6200
+ if (!httpMethods2.has(method) || !isRecord(operation)) {
6201
+ return [method, operation];
6202
+ }
6203
+ return [
6204
+ method,
6205
+ {
6206
+ ...operation,
6207
+ ...operation.responses && {
6208
+ responses: upgradeDefaultResponse(operation.responses)
6209
+ },
6210
+ ...isRecord(operation.callbacks) && {
6211
+ callbacks: mapValues(operation.callbacks, upgradeCallback)
6212
+ }
6213
+ }
6214
+ ];
6215
+ })
6216
+ );
6217
+ };
6218
+ var upgradeCallback = (callback) => isRecord(callback) ? mapValues(callback, upgradePathItem) : callback;
6219
+ var upgradeDefaultResponses = (document) => ({
6220
+ ...document,
6221
+ ...isRecord(document.paths) && {
6222
+ paths: mapValues(document.paths, upgradePathItem)
6223
+ },
6224
+ ...isRecord(document.webhooks) && {
6225
+ webhooks: mapValues(document.webhooks, upgradePathItem)
6226
+ },
6227
+ ...isRecord(document.components) && {
6228
+ components: {
6229
+ ...document.components,
6230
+ ...isRecord(document.components.responses) && {
6231
+ responses: upgradeDefaultResponse(document.components.responses)
6232
+ },
6233
+ ...isRecord(document.components.callbacks) && {
6234
+ callbacks: mapValues(document.components.callbacks, upgradeCallback)
6235
+ }
6236
+ }
6237
+ }
6238
+ });
6239
+ var upgradeOpenApi = (schema2) => {
6240
+ const isUpgraded = typeof schema2.swagger === "string" || typeof schema2.openapi === "string" && schema2.openapi.startsWith("3.0");
6241
+ const upgraded = upgrade(schema2).specification;
6242
+ const document = isUpgraded && isRecord(upgraded) ? upgradeDefaultResponses(upgraded) : upgraded;
6243
+ if (document?.info && typeof document.info.version !== "string") {
6244
+ document.info.version = "0.0.1";
6245
+ }
6246
+ return document;
6247
+ };
6248
+
6219
6249
  // src/vite/api/SchemaManager.ts
6220
6250
  var FALLBACK_VERSION = "default";
6221
6251
  var parseInputString = (input) => {
@@ -6256,13 +6286,7 @@ var SchemaManager = class {
6256
6286
  this.storeDir = storeDir;
6257
6287
  this.config = config;
6258
6288
  this.processors = [
6259
- ({ schema: schema2 }) => {
6260
- const upgraded = upgrade(schema2).specification;
6261
- if (upgraded?.info && typeof upgraded.info.version !== "string") {
6262
- upgraded.info.version = "0.0.1";
6263
- }
6264
- return upgraded;
6265
- },
6289
+ ({ schema: schema2 }) => upgradeOpenApi(schema2),
6266
6290
  flattenAllOfProcessor,
6267
6291
  ...processors
6268
6292
  ];
@@ -6429,8 +6453,8 @@ var SchemaManager = class {
6429
6453
  }
6430
6454
  this.getPublishedSchemas();
6431
6455
  };
6432
- getLatestSchema = (path32) => this.processedSchemas[path32]?.at(0);
6433
- getSchemasForPath = (path32) => this.processedSchemas[path32];
6456
+ getLatestSchema = (path33) => this.processedSchemas[path33]?.at(0);
6457
+ getSchemasForPath = (path33) => this.processedSchemas[path33];
6434
6458
  getSchemaImports = () => Object.values(this.processedSchemas).flat().filter((s) => s.importKey);
6435
6459
  getPublishedSchemas = () => {
6436
6460
  if (this.publishedSchemas) return this.publishedSchemas;
@@ -7148,6 +7172,457 @@ var viteAuthPlugin = () => {
7148
7172
  };
7149
7173
  var plugin_auth_default = viteAuthPlugin;
7150
7174
 
7175
+ // src/vite/plugin-blog.ts
7176
+ import { spawnSync } from "node:child_process";
7177
+ import { stat as stat3 } from "node:fs/promises";
7178
+ import path14 from "node:path";
7179
+ import { glob as glob2 } from "glob";
7180
+ import globParent from "glob-parent";
7181
+ import { fromMarkdown as fromMarkdown2 } from "mdast-util-from-markdown";
7182
+ import { mdxFromMarkdown as mdxFromMarkdown2 } from "mdast-util-mdx";
7183
+ import { mdxjs as mdxjs2 } from "micromark-extension-mdxjs";
7184
+ import colors4 from "picocolors";
7185
+
7186
+ // src/lib/core/plugin-config.ts
7187
+ var PLUGIN_CONFIG = /* @__PURE__ */ Symbol.for("zudoku.pluginConfig");
7188
+ var selectPluginConfigs = (plugins, name) => plugins.flatMap((plugin) => {
7189
+ const tag = plugin && typeof plugin === "object" ? plugin[PLUGIN_CONFIG] : void 0;
7190
+ return tag?.name === name ? [tag.config] : [];
7191
+ });
7192
+
7193
+ // src/lib/plugins/blog/options.ts
7194
+ init_joinUrl();
7195
+ var BLOG_PLUGIN_NAME = "zudoku-blog";
7196
+ var resolveBlogOptions = (options = {}) => ({
7197
+ files: typeof options.files === "string" ? [options.files] : options.files ?? ["/blog/**/*.{md,mdx}"],
7198
+ path: joinUrl(options.path ?? "/blog"),
7199
+ title: options.title ?? "Blog",
7200
+ description: options.description,
7201
+ postsPerPage: Math.max(1, Math.floor(options.postsPerPage ?? 10)),
7202
+ showReadingTime: options.showReadingTime ?? true,
7203
+ authors: options.authors ?? {},
7204
+ sidebar: options.sidebar === false ? false : {
7205
+ title: options.sidebar?.title ?? "Recent posts",
7206
+ count: options.sidebar?.count ?? 5
7207
+ },
7208
+ feed: options.feed
7209
+ });
7210
+
7211
+ // src/vite/plugin-blog.ts
7212
+ init_joinUrl();
7213
+ var WORDS_PER_MINUTE = 200;
7214
+ var DATE_PREFIX = /^(\d{4}-\d{2}-\d{2})(?:[-_]|$)/;
7215
+ var warn2 = (message) => logger.warn(colors4.yellow(`[blog] ${message}`), { timestamp: true });
7216
+ var parsePostPath = (relativePath) => {
7217
+ const segments = relativePath.replace(/\.mdx?$/, "").split("/");
7218
+ if (segments.length > 1 && segments.at(-1) === "index") segments.pop();
7219
+ const name = segments.pop() ?? "";
7220
+ const date = name.match(DATE_PREFIX)?.[1];
7221
+ const slugName = date ? name.slice(date.length).replace(/^[-_]/, "") : name;
7222
+ return { slug: [...segments, slugName || name].join("/"), date };
7223
+ };
7224
+ var toArray = (value) => value === void 0 || value === null ? [] : Array.isArray(value) ? value : [value];
7225
+ var nonEmptyString = (value) => typeof value === "string" && value.trim() ? value.trim() : void 0;
7226
+ var parseDate = (value) => {
7227
+ if (!(value instanceof Date) && typeof value !== "string") return;
7228
+ const date = new Date(value);
7229
+ return Number.isNaN(date.getTime()) ? void 0 : date;
7230
+ };
7231
+ var PHRASING_PARENTS = /* @__PURE__ */ new Set([
7232
+ "paragraph",
7233
+ "heading",
7234
+ "emphasis",
7235
+ "strong",
7236
+ "delete",
7237
+ "link",
7238
+ "linkReference",
7239
+ "tableCell",
7240
+ "mdxJsxTextElement"
7241
+ ]);
7242
+ var toText = (node) => {
7243
+ if ("children" in node) {
7244
+ const separator = PHRASING_PARENTS.has(node.type) ? "" : " ";
7245
+ return node.children.map(toText).join(separator);
7246
+ }
7247
+ if (node.type === "html" || node.type.startsWith("mdx")) return "";
7248
+ return "value" in node ? node.value : "";
7249
+ };
7250
+ var collapseWhitespace = (text) => text.replace(/\s+/g, " ").trim();
7251
+ var parseMarkdown = (content, isMdx) => {
7252
+ let withoutComments = content;
7253
+ for (let previous = ""; previous !== withoutComments; ) {
7254
+ previous = withoutComments;
7255
+ withoutComments = withoutComments.replace(/<!--[\s\S]*?-->/g, "");
7256
+ }
7257
+ try {
7258
+ return isMdx ? fromMarkdown2(withoutComments, {
7259
+ extensions: [mdxjs2()],
7260
+ mdastExtensions: [mdxFromMarkdown2()]
7261
+ // biome-ignore lint/suspicious/noExplicitAny: mdast-util-from-markdown has type incompatibilities between versions
7262
+ }) : fromMarkdown2(withoutComments);
7263
+ } catch {
7264
+ return void 0;
7265
+ }
7266
+ };
7267
+ var isAbsoluteUrl = (url) => /^([a-z][a-z\d+.-]*:|\/\/)/i.test(url);
7268
+ var withBasePath = (config, url) => url && !isAbsoluteUrl(url) ? joinUrl(config.basePath, url) : url;
7269
+ var resolveAuthor = (config, blog, entry, file) => {
7270
+ if (typeof entry === "string") {
7271
+ const author = blog.authors[entry];
7272
+ if (author) {
7273
+ return { ...author, imageUrl: withBasePath(config, author.imageUrl) };
7274
+ }
7275
+ warn2(
7276
+ `Unknown author "${entry}" in ${file}. Add it to the \`authors\` of \`blogPlugin()\`.`
7277
+ );
7278
+ return { name: entry };
7279
+ }
7280
+ if (typeof entry !== "object" || entry === null) return;
7281
+ const record = entry;
7282
+ const name = nonEmptyString(record.name);
7283
+ if (!name) return;
7284
+ return {
7285
+ name,
7286
+ title: nonEmptyString(record.title),
7287
+ url: nonEmptyString(record.url),
7288
+ imageUrl: withBasePath(config, nonEmptyString(record.imageUrl))
7289
+ };
7290
+ };
7291
+ var resolveTags = (value) => {
7292
+ const tags = /* @__PURE__ */ new Map();
7293
+ for (const entry of toArray(value)) {
7294
+ const label = nonEmptyString(
7295
+ typeof entry === "number" ? `${entry}` : entry
7296
+ );
7297
+ if (!label) continue;
7298
+ const slug = slugify(label);
7299
+ if (slug && !tags.has(slug)) tags.set(slug, { label, slug });
7300
+ }
7301
+ return [...tags.values()];
7302
+ };
7303
+ var getGitCreatedDate = (absolutePath) => {
7304
+ const result = spawnSync(
7305
+ "git",
7306
+ ["log", "--diff-filter=A", "--follow", "--format=%cI", "--", absolutePath],
7307
+ {
7308
+ cwd: path14.dirname(absolutePath),
7309
+ encoding: "utf-8",
7310
+ stdio: ["ignore", "pipe", "ignore"]
7311
+ }
7312
+ );
7313
+ if (result.status !== 0) return;
7314
+ return parseDate(result.stdout.trim().split("\n").at(-1));
7315
+ };
7316
+ var readPost = async (config, blog, file, globRoot) => {
7317
+ const absolutePath = path14.resolve(config.__meta.rootDir, file);
7318
+ const { data, content } = await readFrontmatter(absolutePath);
7319
+ const draft = data.draft === true;
7320
+ if (draft && process.env.NODE_ENV !== "development") return;
7321
+ const fromPath = parsePostPath(path14.posix.relative(globRoot, file));
7322
+ const slug = nonEmptyString(data.slug)?.replace(/^\/+|\/+$/g, "");
7323
+ const tree = parseMarkdown(content, file.endsWith(".mdx"));
7324
+ const contentTitle = tree?.children.find(
7325
+ (node) => node.type === "heading" && node.depth === 1
7326
+ );
7327
+ const firstParagraph = tree?.children.filter((node) => node.type === "paragraph").map((node) => collapseWhitespace(toText(node))).find(Boolean);
7328
+ const words = collapseWhitespace(tree ? toText(tree) : content).split(" ").filter(Boolean).length;
7329
+ let date = parseDate(data.date);
7330
+ if (data.date !== void 0 && !date) {
7331
+ warn2(`Invalid date "${data.date}" in ${file}.`);
7332
+ }
7333
+ date ??= parseDate(fromPath.date) ?? getGitCreatedDate(absolutePath) ?? (await stat3(absolutePath)).mtime;
7334
+ return {
7335
+ file,
7336
+ path: joinUrl(blog.path, slug ?? fromPath.slug),
7337
+ title: nonEmptyString(data.title) ?? (contentTitle ? collapseWhitespace(toText(contentTitle)) : void 0) ?? fromPath.slug,
7338
+ description: nonEmptyString(data.description) ?? firstParagraph,
7339
+ date: date.toISOString(),
7340
+ authors: toArray(data.authors).flatMap(
7341
+ (entry) => resolveAuthor(config, blog, entry, file) ?? []
7342
+ ),
7343
+ tags: resolveTags(data.tags),
7344
+ readingTime: Math.max(1, Math.round(words / WORDS_PER_MINUTE)),
7345
+ image: resolveImage(config, nonEmptyString(data.image)),
7346
+ ...draft ? { draft } : {}
7347
+ };
7348
+ };
7349
+ var isIndexFile = (file) => /(^|\/)index\.mdx?$/.test(file);
7350
+ var filterPostFiles = (files) => {
7351
+ const postFolders = new Set(
7352
+ files.filter((file) => isIndexFile(file) && file.includes("/")).map((file) => path14.posix.dirname(file))
7353
+ );
7354
+ return files.filter((file) => {
7355
+ const segments = file.split("/");
7356
+ if (segments.some((segment) => segment.startsWith("_"))) return false;
7357
+ if (isIndexFile(file)) return true;
7358
+ return !segments.slice(0, -1).some((_, i) => postFolders.has(segments.slice(0, i + 1).join("/")));
7359
+ });
7360
+ };
7361
+ var isReservedPath = (blog, postPath) => {
7362
+ const subPath = postPath.slice(blog.path.length).replace(/^\//, "");
7363
+ return subPath === "" || subPath === "tags" || subPath === "rss.xml" || subPath.startsWith("tags/") || subPath.startsWith("page/");
7364
+ };
7365
+ var loadBlogPosts = async (config, blog) => {
7366
+ const posts = await Promise.all(
7367
+ blog.files.map(async (pattern) => {
7368
+ const files = await glob2(pattern, {
7369
+ root: config.__meta.rootDir,
7370
+ cwd: config.__meta.rootDir,
7371
+ ignore: ["**/node_modules/**", "**/dist/**", "**/.git/**"],
7372
+ absolute: false,
7373
+ posix: true
7374
+ });
7375
+ const globRoot = globParent(pattern).replace(/^\.?\//, "");
7376
+ const postFiles = filterPostFiles(
7377
+ files.map((file) => path14.posix.relative(globRoot, file))
7378
+ );
7379
+ return Promise.all(
7380
+ postFiles.map(
7381
+ (file) => readPost(config, blog, path14.posix.join(globRoot, file), globRoot)
7382
+ )
7383
+ );
7384
+ })
7385
+ );
7386
+ const sorted = posts.flat().filter((post) => post !== void 0).sort(
7387
+ (a, b) => b.date.localeCompare(a.date) || a.title.localeCompare(b.title)
7388
+ );
7389
+ const byPath = /* @__PURE__ */ new Map();
7390
+ for (const post of sorted) {
7391
+ if (isReservedPath(blog, post.path)) {
7392
+ warn2(
7393
+ `${post.file} resolves to ${post.path}, which is used by the blog's own pages. Rename it or set a different \`slug\`.`
7394
+ );
7395
+ continue;
7396
+ }
7397
+ const existing = byPath.get(post.path);
7398
+ if (!existing) {
7399
+ byPath.set(post.path, post);
7400
+ } else if (existing.file !== post.file) {
7401
+ warn2(
7402
+ `${post.file} and ${existing.file} both resolve to ${post.path}. Only ${existing.file} is used.`
7403
+ );
7404
+ }
7405
+ }
7406
+ return [...byPath.values()];
7407
+ };
7408
+ var getBlogSiteUrl = (config) => config.canonicalUrlOrigin ?? config.sitemap?.siteUrl;
7409
+ var resolveImage = (config, image) => {
7410
+ const siteUrl = getBlogSiteUrl(config);
7411
+ if (!image || isAbsoluteUrl(image) || !siteUrl) {
7412
+ return withBasePath(config, image);
7413
+ }
7414
+ return joinUrl(siteUrl, config.basePath, image);
7415
+ };
7416
+ var isFeedEnabled = (config, blog) => Boolean((blog.feed ?? true) && getBlogSiteUrl(config));
7417
+ var getFeedPath = (blog) => joinUrl(blog.path, "rss.xml");
7418
+ var escapeXml = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;").replaceAll("'", "&apos;");
7419
+ var generateRssFeed = ({
7420
+ siteUrl,
7421
+ basePath,
7422
+ blog,
7423
+ posts
7424
+ }) => {
7425
+ const url = (routePath) => joinUrl(siteUrl, basePath, routePath);
7426
+ const tag = (name, value) => value ? `<${name}>${escapeXml(value)}</${name}>` : "";
7427
+ const items = posts.map(
7428
+ (post) => [
7429
+ " <item>",
7430
+ ` ${tag("title", post.title)}`,
7431
+ ` ${tag("link", url(post.path))}`,
7432
+ ` <guid isPermaLink="true">${escapeXml(url(post.path))}</guid>`,
7433
+ ` ${tag("pubDate", new Date(post.date).toUTCString())}`,
7434
+ post.description && ` ${tag("description", post.description)}`,
7435
+ ...post.authors.map((a) => ` ${tag("dc:creator", a.name)}`),
7436
+ ...post.tags.map((t) => ` ${tag("category", t.label)}`),
7437
+ " </item>"
7438
+ ].filter(Boolean).join("\n")
7439
+ );
7440
+ return [
7441
+ '<?xml version="1.0" encoding="UTF-8"?>',
7442
+ '<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">',
7443
+ " <channel>",
7444
+ ` ${tag("title", blog.title)}`,
7445
+ ` ${tag("link", url(blog.path))}`,
7446
+ ` ${tag("description", blog.description ?? blog.title)}`,
7447
+ ` <atom:link href="${escapeXml(url(getFeedPath(blog)))}" rel="self" type="application/rss+xml"/>`,
7448
+ ...items,
7449
+ " </channel>",
7450
+ "</rss>",
7451
+ ""
7452
+ ].join("\n");
7453
+ };
7454
+ var getBlogs = (config) => {
7455
+ if (config.__meta.mode === "standalone") return [];
7456
+ const blogs = selectPluginConfigs(
7457
+ config.plugins ?? [],
7458
+ BLOG_PLUGIN_NAME
7459
+ ).map((options) => resolveBlogOptions(options));
7460
+ const duplicate = blogs.find(
7461
+ (blog, index) => blogs.findIndex((b) => b.path === blog.path) !== index
7462
+ );
7463
+ if (duplicate) {
7464
+ throw new ZudokuError(
7465
+ `Multiple blogs are configured with the path "${duplicate.path}".`,
7466
+ {
7467
+ title: "Conflicting blog paths",
7468
+ developerHint: "Give each `blogPlugin()` in `plugins` its own `path`, e.g. `/blog` and `/changelog`."
7469
+ }
7470
+ );
7471
+ }
7472
+ return blogs;
7473
+ };
7474
+ var postsCache = /* @__PURE__ */ new Map();
7475
+ var getBlogPosts = (config, blog) => {
7476
+ const key = JSON.stringify([
7477
+ config.__meta.rootDir,
7478
+ config.basePath,
7479
+ getBlogSiteUrl(config),
7480
+ blog
7481
+ ]);
7482
+ const cached = postsCache.get(key);
7483
+ if (cached) return cached;
7484
+ const posts = loadBlogPosts(config, blog);
7485
+ postsCache.set(key, posts);
7486
+ posts.catch(() => postsCache.delete(key));
7487
+ return posts;
7488
+ };
7489
+ var getBlogRoutesByFile = async (config) => {
7490
+ const posts = await Promise.all(
7491
+ getBlogs(config).map((blog) => getBlogPosts(config, blog))
7492
+ );
7493
+ return new Map(
7494
+ posts.flat().map((post) => [
7495
+ path14.resolve(config.__meta.rootDir, post.file).replace(/\.mdx?$/, ""),
7496
+ post.path
7497
+ ])
7498
+ );
7499
+ };
7500
+ var isInBlogFolder = (config, filePath) => getBlogs(config).flatMap((blog) => blog.files).map((pattern) => globParent(pattern).replace(/^\.?\//, "")).some((folder) => {
7501
+ const relative = path14.relative(
7502
+ path14.resolve(config.__meta.rootDir, folder),
7503
+ filePath
7504
+ );
7505
+ return relative !== ".." && !relative.startsWith(`..${path14.sep}`) && !path14.isAbsolute(relative);
7506
+ });
7507
+ var manifestModuleId = "virtual:zudoku-blog";
7508
+ var postsModulePrefix = "virtual:zudoku-blog/posts";
7509
+ var generateManifest = async (config) => {
7510
+ const entries = await Promise.all(
7511
+ getBlogs(config).map(async (blog) => {
7512
+ const posts = await getBlogPosts(config, blog);
7513
+ const tags = /* @__PURE__ */ new Map();
7514
+ for (const tag of posts.flatMap((post) => post.tags)) {
7515
+ if (!tags.has(tag.slug)) tags.set(tag.slug, tag);
7516
+ }
7517
+ const data = {
7518
+ tags: [...tags.values()].sort((a, b) => a.label.localeCompare(b.label)),
7519
+ feedUrl: isFeedEnabled(config, blog) ? joinUrl(config.basePath, getFeedPath(blog)) : void 0
7520
+ };
7521
+ return [
7522
+ ` ${JSON.stringify(blog.path)}: {`,
7523
+ ` ...${JSON.stringify(data)},`,
7524
+ ` postImports: {`,
7525
+ ...posts.map(
7526
+ (post) => ` ${JSON.stringify(post.path)}: () => import(${JSON.stringify(joinUrl(post.file))}),`
7527
+ ),
7528
+ ` },`,
7529
+ ` loadPosts: () => import(${JSON.stringify(postsModulePrefix + blog.path)}).then((m) => m.posts),`,
7530
+ ` },`
7531
+ ];
7532
+ })
7533
+ );
7534
+ return [`export const blogs = {`, ...entries.flat(), `};`];
7535
+ };
7536
+ var viteBlogPlugin = () => {
7537
+ const resolvedManifestId = `\0${manifestModuleId}`;
7538
+ const resolvedPostsPrefix = `\0${postsModulePrefix}`;
7539
+ return {
7540
+ name: "zudoku-blog-plugin",
7541
+ resolveId(id) {
7542
+ if (id === manifestModuleId || id.startsWith(`${postsModulePrefix}/`)) {
7543
+ return `\0${id}`;
7544
+ }
7545
+ },
7546
+ async load(id) {
7547
+ if (id === resolvedManifestId) {
7548
+ const config = getCurrentConfig();
7549
+ const code = await generateManifest(config);
7550
+ await writePluginDebugCode(config.__meta.rootDir, "blog-plugin", code);
7551
+ return code.join("\n");
7552
+ }
7553
+ if (id.startsWith(`${resolvedPostsPrefix}/`)) {
7554
+ const config = getCurrentConfig();
7555
+ const blogPath = id.slice(resolvedPostsPrefix.length);
7556
+ const blog = getBlogs(config).find((b) => b.path === blogPath);
7557
+ const posts = blog ? await getBlogPosts(config, blog) : [];
7558
+ return `export const posts = ${JSON.stringify(
7559
+ posts.map(({ file: _file, ...post }) => post)
7560
+ )};`;
7561
+ }
7562
+ },
7563
+ async generateBundle() {
7564
+ if (this.environment.name !== "client") return;
7565
+ const config = getCurrentConfig();
7566
+ const siteUrl = getBlogSiteUrl(config);
7567
+ for (const blog of getBlogs(config)) {
7568
+ if (!siteUrl || !isFeedEnabled(config, blog)) {
7569
+ if (blog.feed) {
7570
+ warn2(
7571
+ `Skipping the RSS feed of ${blog.path}: set \`canonicalUrlOrigin\` or \`sitemap.siteUrl\` so the feed can link to posts.`
7572
+ );
7573
+ }
7574
+ continue;
7575
+ }
7576
+ this.emitFile({
7577
+ type: "asset",
7578
+ fileName: getFeedPath(blog).slice(1),
7579
+ source: generateRssFeed({
7580
+ siteUrl,
7581
+ basePath: config.basePath,
7582
+ blog,
7583
+ posts: await getBlogPosts(config, blog)
7584
+ })
7585
+ });
7586
+ }
7587
+ },
7588
+ async configureServer(server) {
7589
+ const loadAll = (config) => Promise.all(
7590
+ getBlogs(config).map((blog) => getBlogPosts(config, blog))
7591
+ ).then((posts) => JSON.stringify(posts));
7592
+ let snapshot = await loadAll(getCurrentConfig());
7593
+ server.middlewares.use(async (req, res, next) => {
7594
+ const config = getCurrentConfig();
7595
+ const siteUrl = getBlogSiteUrl(config);
7596
+ const pathname = req.url?.split(/[?#]/)[0];
7597
+ const blog = getBlogs(config).find(
7598
+ (b) => joinUrl(config.basePath, getFeedPath(b)) === pathname
7599
+ );
7600
+ if (!blog || !siteUrl || !isFeedEnabled(config, blog)) return next();
7601
+ res.setHeader("Content-Type", "application/rss+xml; charset=utf-8");
7602
+ res.end(
7603
+ generateRssFeed({
7604
+ siteUrl,
7605
+ basePath: config.basePath,
7606
+ blog,
7607
+ posts: await getBlogPosts(config, blog)
7608
+ })
7609
+ );
7610
+ });
7611
+ server.watcher.on("all", async (event, filePath) => {
7612
+ if (!["add", "change", "unlink"].includes(event)) return;
7613
+ if (!/\.mdx?$/.test(filePath)) return;
7614
+ const config = getCurrentConfig();
7615
+ if (!isInBlogFolder(config, filePath)) return;
7616
+ postsCache.clear();
7617
+ const previous = snapshot;
7618
+ snapshot = await loadAll(config);
7619
+ if (previous !== snapshot) reload(server);
7620
+ });
7621
+ }
7622
+ };
7623
+ };
7624
+ var plugin_blog_default = viteBlogPlugin;
7625
+
7151
7626
  // src/vite/plugin-config.ts
7152
7627
  import { normalizePath } from "vite";
7153
7628
  var virtualModuleId3 = "virtual:zudoku-config";
@@ -7237,7 +7712,7 @@ var viteCustomPagesPlugin = () => {
7237
7712
  var plugin_custom_pages_default = viteCustomPagesPlugin;
7238
7713
 
7239
7714
  // src/vite/plugin-doc-metadata.ts
7240
- import { glob as glob2 } from "glob";
7715
+ import { glob as glob3 } from "glob";
7241
7716
  var serializeMetadata = async (filePath) => {
7242
7717
  const fm = await readFrontmatter(filePath);
7243
7718
  const h1 = fm.content.match(/^#\s+(.*)$/m)?.[1];
@@ -7248,7 +7723,7 @@ var viteDocMetadataPlugin = () => ({
7248
7723
  name: "zudoku-doc-metadata-plugin",
7249
7724
  configureServer: async (server) => {
7250
7725
  const config = getCurrentConfig();
7251
- const files = await glob2("**/*.{md,mdx}", {
7726
+ const files = await glob3("**/*.{md,mdx}", {
7252
7727
  cwd: config.__meta.rootDir,
7253
7728
  ignore: ["node_modules", "dist"],
7254
7729
  absolute: true
@@ -7273,9 +7748,9 @@ var viteDocMetadataPlugin = () => ({
7273
7748
  });
7274
7749
 
7275
7750
  // src/vite/plugin-docs.ts
7276
- import path14 from "node:path";
7277
- import { glob as glob3 } from "glob";
7278
- import globParent from "glob-parent";
7751
+ import path15 from "node:path";
7752
+ import { glob as glob4 } from "glob";
7753
+ import globParent2 from "glob-parent";
7279
7754
 
7280
7755
  // src/lib/components/navigation/utils.ts
7281
7756
  import { cva } from "class-variance-authority";
@@ -7328,19 +7803,19 @@ var ensureLeadingSlash = joinUrl;
7328
7803
  var globMarkdownFiles = async (config, options = { absolute: false }) => {
7329
7804
  const fileMapping = {};
7330
7805
  for (const globPattern of config.docs.files) {
7331
- const globbedFiles = await glob3(globPattern, {
7806
+ const globbedFiles = await glob4(globPattern, {
7332
7807
  root: config.__meta.rootDir,
7333
7808
  ignore: ["**/node_modules/**", "**/dist/**", "**/.git/**"],
7334
7809
  // Always glob with relative paths to avoid issues on different OS
7335
7810
  absolute: false,
7336
7811
  posix: true
7337
7812
  });
7338
- const parent = globParent(globPattern).replace(/^\.?\//, "");
7813
+ const parent = globParent2(globPattern).replace(/^\.?\//, "");
7339
7814
  let draftFiles = /* @__PURE__ */ new Set();
7340
7815
  if (process.env.NODE_ENV !== "development") {
7341
7816
  const draftStatuses = await Promise.all(
7342
7817
  globbedFiles.map(async (file) => {
7343
- const absolutePath = path14.resolve(config.__meta.rootDir, file);
7818
+ const absolutePath = path15.resolve(config.__meta.rootDir, file);
7344
7819
  const { data } = await readFrontmatter(absolutePath);
7345
7820
  return { file, isDraft: data.draft === true };
7346
7821
  })
@@ -7353,9 +7828,9 @@ var globMarkdownFiles = async (config, options = { absolute: false }) => {
7353
7828
  if (draftFiles.has(file)) {
7354
7829
  continue;
7355
7830
  }
7356
- const relativePath = path14.posix.relative(parent, file);
7831
+ const relativePath = path15.posix.relative(parent, file);
7357
7832
  const routePath = ensureLeadingSlash(relativePath.replace(/\.mdx?$/, ""));
7358
- const filePath = options.absolute ? path14.resolve(config.__meta.rootDir, file) : file;
7833
+ const filePath = options.absolute ? path15.resolve(config.__meta.rootDir, file) : file;
7359
7834
  fileMapping[routePath] = filePath;
7360
7835
  }
7361
7836
  }
@@ -7439,7 +7914,7 @@ var plugin_docs_default = viteDocsPlugin;
7439
7914
 
7440
7915
  // src/vite/plugin-markdown-export.ts
7441
7916
  import { mkdir as mkdir2, writeFile as writeFile2 } from "node:fs/promises";
7442
- import path15 from "node:path";
7917
+ import path16 from "node:path";
7443
7918
 
7444
7919
  // src/lib/util/contentNegotiation.ts
7445
7920
  var representations = [
@@ -7611,15 +8086,15 @@ ${markdownContent}`;
7611
8086
  return {
7612
8087
  content: finalMarkdown,
7613
8088
  title: frontmatter.title,
7614
- description: frontmatter.description
8089
+ description: frontmatter.seo?.description ?? frontmatter.description
7615
8090
  };
7616
8091
  };
7617
8092
  var getMarkdownOutputPath = (distDir, routePath) => {
7618
8093
  const segments = routePath === "/" ? ["index"] : routePath.split("/").filter(Boolean);
7619
- return `${path15.join(distDir, ...segments)}.md`;
8094
+ return `${path16.join(distDir, ...segments)}.md`;
7620
8095
  };
7621
8096
  var writeMarkdownInfo = async (markdownInfoPath, markdownFileInfos) => {
7622
- await mkdir2(path15.dirname(markdownInfoPath), { recursive: true });
8097
+ await mkdir2(path16.dirname(markdownInfoPath), { recursive: true });
7623
8098
  await writeFile2(
7624
8099
  markdownInfoPath,
7625
8100
  JSON.stringify(markdownFileInfos, null, 2),
@@ -7748,7 +8223,7 @@ var viteMarkdownExportPlugin = () => {
7748
8223
  if (process.env.NODE_ENV !== "production" || !needsMdFiles(config)) {
7749
8224
  return;
7750
8225
  }
7751
- const distDir = path15.join(
8226
+ const distDir = path16.join(
7752
8227
  config.__meta.rootDir,
7753
8228
  "dist",
7754
8229
  config.basePath ?? ""
@@ -7769,14 +8244,14 @@ var viteMarkdownExportPlugin = () => {
7769
8244
  content: finalMarkdown
7770
8245
  });
7771
8246
  const outputPath = getMarkdownOutputPath(distDir, routePath);
7772
- await mkdir2(path15.dirname(outputPath), { recursive: true });
8247
+ await mkdir2(path16.dirname(outputPath), { recursive: true });
7773
8248
  await writeFile2(outputPath, finalMarkdown, "utf-8");
7774
8249
  } catch (error) {
7775
8250
  console.warn(`Failed to export markdown for ${routePath}:`, error);
7776
8251
  }
7777
8252
  }
7778
8253
  if (config.docs.llms.llmsTxt || config.docs.llms.llmsTxtFull || isContentNegotiationEnabled(config)) {
7779
- const markdownInfoPath = path15.join(
8254
+ const markdownInfoPath = path16.join(
7780
8255
  config.__meta.rootDir,
7781
8256
  "node_modules/.zudoku/markdown-info.json"
7782
8257
  );
@@ -8079,28 +8554,28 @@ var remarkCodeTabs = () => (tree) => {
8079
8554
  };
8080
8555
 
8081
8556
  // src/vite/mdx/remark-inject-filepath.ts
8082
- import path16 from "node:path";
8557
+ import path17 from "node:path";
8083
8558
  var remarkInjectFilepath = (rootDir) => (tree, vfile) => {
8084
- const relativePath = path16.relative(rootDir, vfile.path).split(path16.sep).join(path16.posix.sep);
8559
+ const relativePath = path17.relative(rootDir, vfile.path).split(path17.sep).join(path17.posix.sep);
8085
8560
  tree.children.unshift(exportMdxjsConst("__filepath", relativePath));
8086
8561
  };
8087
8562
 
8088
8563
  // src/vite/mdx/remark-last-modified.ts
8089
- import { spawnSync } from "node:child_process";
8090
- import { stat as stat3 } from "node:fs/promises";
8564
+ import { spawnSync as spawnSync2 } from "node:child_process";
8565
+ import { stat as stat4 } from "node:fs/promises";
8091
8566
  import { visit as visit4 } from "unist-util-visit";
8092
8567
  import { parse as parse2, stringify as stringify4 } from "yaml";
8093
8568
  var isGitAvailable;
8094
8569
  var hasWarnedShallowClone = false;
8095
8570
  var checkGitAvailable = () => {
8096
8571
  if (isGitAvailable !== void 0) return isGitAvailable;
8097
- const result = spawnSync("git", ["--version"], { stdio: "ignore" });
8572
+ const result = spawnSync2("git", ["--version"], { stdio: "ignore" });
8098
8573
  isGitAvailable = result.status === 0;
8099
8574
  return isGitAvailable;
8100
8575
  };
8101
8576
  var isShallowRepository = () => {
8102
8577
  if (!checkGitAvailable()) return false;
8103
- const result = spawnSync("git", ["rev-parse", "--is-shallow-repository"], {
8578
+ const result = spawnSync2("git", ["rev-parse", "--is-shallow-repository"], {
8104
8579
  encoding: "utf-8",
8105
8580
  stdio: ["pipe", "pipe", "ignore"]
8106
8581
  });
@@ -8125,7 +8600,7 @@ var warnShallowClone = () => {
8125
8600
  };
8126
8601
  var getLastModifiedDate = async (filePath) => {
8127
8602
  if (checkGitAvailable()) {
8128
- const result = spawnSync(
8603
+ const result = spawnSync2(
8129
8604
  "git",
8130
8605
  ["log", "-1", "--format=%cI", "--", filePath],
8131
8606
  { encoding: "utf-8", stdio: ["pipe", "pipe", "ignore"] }
@@ -8136,7 +8611,7 @@ var getLastModifiedDate = async (filePath) => {
8136
8611
  }
8137
8612
  }
8138
8613
  try {
8139
- const stats = await stat3(filePath);
8614
+ const stats = await stat4(filePath);
8140
8615
  return stats.mtime;
8141
8616
  } catch {
8142
8617
  }
@@ -8168,7 +8643,7 @@ var remarkLastModified = () => {
8168
8643
  };
8169
8644
 
8170
8645
  // src/vite/mdx/remark-link-rewrite.ts
8171
- import path17 from "node:path";
8646
+ import path18 from "node:path";
8172
8647
  import { visit as visit5 } from "unist-util-visit";
8173
8648
  var markdownExtension = /\.mdx?$/;
8174
8649
  var resolveToRoute = (url, filePath, routesByFile) => {
@@ -8176,7 +8651,7 @@ var resolveToRoute = (url, filePath, routesByFile) => {
8176
8651
  if (!markdownExtension.test(pathname) || pathname.startsWith("/")) {
8177
8652
  return void 0;
8178
8653
  }
8179
- const targetFile = path17.resolve(path17.dirname(filePath), pathname).replace(markdownExtension, "");
8654
+ const targetFile = path18.resolve(path18.dirname(filePath), pathname).replace(markdownExtension, "");
8180
8655
  const route = routesByFile.get(targetFile);
8181
8656
  if (route === void 0) return void 0;
8182
8657
  return `${route}${suffix}`;
@@ -8191,11 +8666,11 @@ var remarkLinkRewrite = (basePath = "", routesByFile = /* @__PURE__ */ new Map()
8191
8666
  node.url = resolved;
8192
8667
  return;
8193
8668
  }
8194
- const base = path17.posix.join(basePath);
8669
+ const base = path18.posix.join(basePath);
8195
8670
  if (basePath && node.url.startsWith(base)) {
8196
8671
  node.url = node.url.slice(base.length);
8197
8672
  } else if (!node.url.startsWith("/") && !node.url.startsWith("#")) {
8198
- node.url = path17.posix.join("..", node.url);
8673
+ node.url = path18.posix.join("..", node.url);
8199
8674
  }
8200
8675
  node.url = node.url.replace(/\.mdx?(#.*)?$/, "$1");
8201
8676
  });
@@ -8408,6 +8883,9 @@ var viteMdxPlugin = async () => {
8408
8883
  for (const [route, filePath] of Object.entries(fileMapping)) {
8409
8884
  routesByFile.set(filePath.replace(/\.mdx?$/, ""), route);
8410
8885
  }
8886
+ for (const [filePath, route] of await getBlogRoutesByFile(config)) {
8887
+ routesByFile.set(filePath, route);
8888
+ }
8411
8889
  const defaultRemarkPlugins = [
8412
8890
  remarkStaticGeneration,
8413
8891
  [remarkInjectFilepath, config.__meta.rootDir],
@@ -8567,6 +9045,7 @@ function vitePlugin() {
8567
9045
  plugin_custom_pages_default(),
8568
9046
  plugin_auth_default(),
8569
9047
  plugin_docs_default(),
9048
+ plugin_blog_default(),
8570
9049
  viteDocMetadataPlugin(),
8571
9050
  viteNavigationPlugin(),
8572
9051
  plugin_api_default(),
@@ -8829,12 +9308,12 @@ var protectedAnnotatorPlugin = () => ({
8829
9308
  });
8830
9309
 
8831
9310
  // src/vite/config.ts
8832
- var getAppClientEntryPath = () => path18.posix.join(getZudokuRootDir(), "src/app/entry.client.tsx");
8833
- var getAppServerEntryPath = () => path18.posix.join(getZudokuRootDir(), "src/app/entry.server.tsx");
9311
+ var getAppClientEntryPath = () => path19.posix.join(getZudokuRootDir(), "src/app/entry.client.tsx");
9312
+ var getAppServerEntryPath = () => path19.posix.join(getZudokuRootDir(), "src/app/entry.server.tsx");
8834
9313
  var hasLoggedCdnInfo = false;
8835
9314
  var MEDIA_REGEX = /\.(a?png|jpe?g|gif|bmp|svg|webp|tiff|ico|webm|ogg|mp3|wav|m4a|avif|mp4)/i;
8836
9315
  var getDepScanEntries = () => {
8837
- const src = path18.posix.join(getZudokuRootDir(), "src");
9316
+ const src = path19.posix.join(getZudokuRootDir(), "src");
8838
9317
  return [
8839
9318
  `${src}/{app,lib}/**/*.{ts,tsx}`,
8840
9319
  // Client-environment scan: `entry.server.tsx` imports
@@ -8864,9 +9343,9 @@ async function getViteConfig(dir, configEnv, options = {}) {
8864
9343
  const cdnUrl = config.cdnUrl;
8865
9344
  const base = cdnUrl?.base ? joinUrl(cdnUrl.base, config.basePath) : config.basePath;
8866
9345
  if (cdnUrl && !hasLoggedCdnInfo) {
8867
- logger.info(colors4.blue(`Using CDN URL:`));
8868
- logger.info(colors4.blue(` base: `) + colors4.dim(cdnUrl.base));
8869
- logger.info(colors4.blue(` media: `) + colors4.dim(cdnUrl.media));
9346
+ logger.info(colors5.blue(`Using CDN URL:`));
9347
+ logger.info(colors5.blue(` base: `) + colors5.dim(cdnUrl.base));
9348
+ logger.info(colors5.blue(` media: `) + colors5.dim(cdnUrl.media));
8870
9349
  hasLoggedCdnInfo = true;
8871
9350
  }
8872
9351
  const publicVarsProcessEnvDefine = Object.fromEntries(
@@ -8877,11 +9356,11 @@ async function getViteConfig(dir, configEnv, options = {}) {
8877
9356
  );
8878
9357
  if (ZuploEnv.isZuplo) {
8879
9358
  dotenv.config({
8880
- path: path18.resolve(config.__meta.rootDir, "../.env.zuplo"),
9359
+ path: path19.resolve(config.__meta.rootDir, "../.env.zuplo"),
8881
9360
  quiet: true
8882
9361
  });
8883
9362
  }
8884
- const deploymentName = ZuploEnv.buildConfig?.deploymentName || getZuploSystemConfigurations(process.env.ZUPLO_SYSTEM_CONFIGURATIONS)?.__ZUPLO_DEPLOYMENT_NAME;
9363
+ const deploymentName = ZuploEnv.deploymentName;
8885
9364
  const viteConfig = {
8886
9365
  root: dir,
8887
9366
  base,
@@ -8909,10 +9388,13 @@ async function getViteConfig(dir, configEnv, options = {}) {
8909
9388
  "import.meta.env.IS_ZUPLO": ZuploEnv.isZuplo,
8910
9389
  "import.meta.env.ZUDOKU_HAS_SERVER": JSON.stringify(options.ssr === true),
8911
9390
  "import.meta.env.ZUPLO_PUBLIC_DEPLOYMENT_NAME": JSON.stringify(deploymentName),
9391
+ // Derived value only; the raw env var is read at build time.
9392
+ "import.meta.env.ZUPLO_DEV_PORTAL_ZUPLO_BRANDING": JSON.stringify(
9393
+ ZuploEnv.devPortalZuploBranding
9394
+ ),
8912
9395
  ...defineEnvVars([
8913
9396
  "SENTRY_DSN",
8914
9397
  "ZUPLO_BUILD_ID",
8915
- "ZUPLO_BUILD_CONFIG",
8916
9398
  "ZUPLO_ENVIRONMENT_TYPE",
8917
9399
  "ZUPLO_SERVER_URL",
8918
9400
  "ZUPLO_GATEWAY_SERVICE_URL"
@@ -8937,7 +9419,7 @@ async function getViteConfig(dir, configEnv, options = {}) {
8937
9419
  sourcemap: true,
8938
9420
  target: "es2022",
8939
9421
  chunkSizeWarningLimit: 1500,
8940
- outDir: path18.resolve(path18.join(dir, "dist", config.basePath ?? "")),
9422
+ outDir: path19.resolve(path19.join(dir, "dist", config.basePath ?? "")),
8941
9423
  emptyOutDir: false,
8942
9424
  rolldownOptions: {
8943
9425
  external: [joinUrl(config.basePath, "/pagefind/pagefind.js")],
@@ -8967,8 +9449,8 @@ async function getViteConfig(dir, configEnv, options = {}) {
8967
9449
  external: ["@shikijs/themes", "@shikijs/langs"]
8968
9450
  },
8969
9451
  build: {
8970
- outDir: path18.resolve(
8971
- path18.join(dir, "dist", config.basePath ?? "", "server")
9452
+ outDir: path19.resolve(
9453
+ path19.join(dir, "dist", config.basePath ?? "", "server")
8972
9454
  ),
8973
9455
  copyPublicDir: false,
8974
9456
  rolldownOptions: {
@@ -8983,7 +9465,7 @@ async function getViteConfig(dir, configEnv, options = {}) {
8983
9465
  if (filename.startsWith(`${PROTECTED_CHUNK_DIR}/`)) {
8984
9466
  return joinUrl(config.basePath, `/${filename}`);
8985
9467
  }
8986
- if (cdnUrl?.base && [".js", ".css"].includes(path18.extname(filename))) {
9468
+ if (cdnUrl?.base && [".js", ".css"].includes(path19.extname(filename))) {
8987
9469
  return joinUrl(cdnUrl.base, filename);
8988
9470
  }
8989
9471
  if (cdnUrl?.media && MEDIA_REGEX.test(filename)) {
@@ -9037,7 +9519,7 @@ async function getViteConfig(dir, configEnv, options = {}) {
9037
9519
  if (!loaded) continue;
9038
9520
  mergedViteConfig = mergeConfig2(mergedViteConfig, loaded.config, true);
9039
9521
  if (root === dir) {
9040
- logger.info(colors4.blue(`merged with custom user Vite config`), {
9522
+ logger.info(colors5.blue(`merged with custom user Vite config`), {
9041
9523
  timestamp: true
9042
9524
  });
9043
9525
  }
@@ -9090,10 +9572,10 @@ ${cssLinks}
9090
9572
 
9091
9573
  // src/vite/manifest.ts
9092
9574
  import { writeFile as writeFile3 } from "node:fs/promises";
9093
- import path19 from "node:path";
9575
+ import path20 from "node:path";
9094
9576
  var writeManifest = async (distDir, config) => {
9095
9577
  await writeFile3(
9096
- path19.join(distDir, MANIFEST_FILENAME),
9578
+ path20.join(distDir, MANIFEST_FILENAME),
9097
9579
  `${JSON.stringify(buildManifest(config), null, 2)}
9098
9580
  `,
9099
9581
  "utf-8"
@@ -9104,7 +9586,7 @@ var writeManifest = async (distDir, config) => {
9104
9586
  import assert from "node:assert";
9105
9587
  import { existsSync } from "node:fs";
9106
9588
  import { cp, mkdir as mkdir3, readdir, rm, writeFile as writeFile4 } from "node:fs/promises";
9107
- import path20 from "node:path";
9589
+ import path21 from "node:path";
9108
9590
  init_joinUrl();
9109
9591
 
9110
9592
  // src/lib/util/redirectPattern.ts
@@ -9112,8 +9594,8 @@ init_joinUrl();
9112
9594
  var SPLAT = "*";
9113
9595
  var ABSOLUTE_URL_REGEX = /^(?:[a-z][a-z0-9+.-]*:|[\\/]{2})/i;
9114
9596
  var TOKEN_REGEX = /\/(?::([\w-]+)|\*)(?=[/?#]|$)/g;
9115
- var parseSegments = (path32) => {
9116
- const parts = path32.split("/").filter(Boolean);
9597
+ var parseSegments = (path33) => {
9598
+ const parts = path33.split("/").filter(Boolean);
9117
9599
  return parts.map((part, index) => {
9118
9600
  if (part === SPLAT && index === parts.length - 1) return { type: "splat" };
9119
9601
  const match = part.match(/^:([\w-]+)(\?)?$/);
@@ -9135,8 +9617,8 @@ var replaceTokens = (to, names, replace) => {
9135
9617
  const lostPath = target === "" || /^[?#]/.test(target);
9136
9618
  return target !== to && lostPath ? `/${target}` : target;
9137
9619
  };
9138
- var rankPath = (path32) => {
9139
- const segments = joinUrl(path32).split("/");
9620
+ var rankPath = (path33) => {
9621
+ const segments = joinUrl(path33).split("/");
9140
9622
  return segments.reduce(
9141
9623
  (score, segment) => {
9142
9624
  if (segment === SPLAT) return score;
@@ -9570,12 +10052,12 @@ var listStaticFiles = async (rootDir, currentDir = rootDir) => {
9570
10052
  const entries = await readdir(currentDir, { withFileTypes: true });
9571
10053
  const files = await Promise.all(
9572
10054
  entries.map(async (entry) => {
9573
- const entryPath = path20.join(currentDir, entry.name);
10055
+ const entryPath = path21.join(currentDir, entry.name);
9574
10056
  if (entry.isDirectory()) {
9575
10057
  return listStaticFiles(rootDir, entryPath);
9576
10058
  }
9577
10059
  if (!entry.isFile()) return [];
9578
- return [path20.relative(rootDir, entryPath).split(path20.sep).join("/")];
10060
+ return [path21.relative(rootDir, entryPath).split(path21.sep).join("/")];
9579
10061
  })
9580
10062
  );
9581
10063
  return files.flat().sort();
@@ -9605,7 +10087,7 @@ var getCleanUrlOverrides = (staticHtmlFiles) => {
9605
10087
  };
9606
10088
  var cleanVercelOutput = async (dir) => {
9607
10089
  if (!process.env.VERCEL) return;
9608
- await rm(path20.join(dir, ".vercel/output"), {
10090
+ await rm(path21.join(dir, ".vercel/output"), {
9609
10091
  recursive: true,
9610
10092
  force: true
9611
10093
  });
@@ -9706,12 +10188,12 @@ async function writeOutput(dir, {
9706
10188
  markdownNegotiation
9707
10189
  }) {
9708
10190
  const vercelMarkdownNegotiation = process.env.VERCEL ? markdownNegotiation : void 0;
9709
- const staticFiles = process.env.VERCEL ? await listStaticFiles(path20.join(dir, ".vercel/output/static")) : [];
10191
+ const staticFiles = process.env.VERCEL ? await listStaticFiles(path21.join(dir, ".vercel/output/static")) : [];
9710
10192
  const staticHtmlFiles = staticFiles.filter(
9711
10193
  (filename) => filename.endsWith(HTML_EXTENSION)
9712
10194
  );
9713
10195
  const staticPassthroughPaths = staticFiles.filter((filename) => {
9714
- const basename = path20.posix.basename(filename);
10196
+ const basename = path21.posix.basename(filename);
9715
10197
  return !basename.includes(".") || basename.endsWith(".md") || basename.endsWith(".mdx");
9716
10198
  }).map((filename) => `/${filename}`);
9717
10199
  const output = generateOutput({
@@ -9721,13 +10203,13 @@ async function writeOutput(dir, {
9721
10203
  markdownNegotiation: vercelMarkdownNegotiation,
9722
10204
  staticHtmlFiles
9723
10205
  });
9724
- const outputDir = process.env.VERCEL ? path20.join(dir, ".vercel/output") : path20.join(dir, "dist/.output");
10206
+ const outputDir = process.env.VERCEL ? path21.join(dir, ".vercel/output") : path21.join(dir, "dist/.output");
9725
10207
  await mkdir3(outputDir, { recursive: true });
9726
- const outputFile = path20.join(outputDir, "config.json");
10208
+ const outputFile = path21.join(outputDir, "config.json");
9727
10209
  await writeFile4(outputFile, JSON.stringify(output, null, 2), "utf-8");
9728
10210
  if (process.env.VERCEL) {
9729
10211
  if (vercelMarkdownNegotiation) {
9730
- const functionDir = path20.join(
10212
+ const functionDir = path21.join(
9731
10213
  outputDir,
9732
10214
  "functions",
9733
10215
  `${MARKDOWN_MIDDLEWARE_PATH}.func`
@@ -9735,7 +10217,7 @@ async function writeOutput(dir, {
9735
10217
  await mkdir3(functionDir, { recursive: true });
9736
10218
  await Promise.all([
9737
10219
  writeFile4(
9738
- path20.join(functionDir, "index.js"),
10220
+ path21.join(functionDir, "index.js"),
9739
10221
  generateVercelMarkdownMiddleware({
9740
10222
  basePath: config.basePath,
9741
10223
  ...vercelMarkdownNegotiation,
@@ -9744,7 +10226,7 @@ async function writeOutput(dir, {
9744
10226
  "utf-8"
9745
10227
  ),
9746
10228
  writeFile4(
9747
- path20.join(functionDir, ".vc-config.json"),
10229
+ path21.join(functionDir, ".vc-config.json"),
9748
10230
  JSON.stringify({ runtime: "edge", entrypoint: "index.js" }, null, 2),
9749
10231
  "utf-8"
9750
10232
  )
@@ -9758,10 +10240,10 @@ async function writeOutput(dir, {
9758
10240
  import { readFileSync as readFileSync2 } from "node:fs";
9759
10241
  import { readFile as readFile3, rm as rm2 } from "node:fs/promises";
9760
10242
  import os from "node:os";
9761
- import path23 from "node:path";
10243
+ import path24 from "node:path";
9762
10244
  import { pathToFileURL } from "node:url";
9763
10245
  import { createIndex } from "pagefind";
9764
- import colors7 from "picocolors";
10246
+ import colors8 from "picocolors";
9765
10247
  import PiscinaImport from "piscina";
9766
10248
  init_markdown_representation();
9767
10249
 
@@ -9798,8 +10280,8 @@ function throttle(fn) {
9798
10280
  init_joinUrl();
9799
10281
  import { createWriteStream, existsSync as existsSync2 } from "node:fs";
9800
10282
  import { mkdir as mkdir4 } from "node:fs/promises";
9801
- import path21 from "node:path";
9802
- import colors5 from "picocolors";
10283
+ import path22 from "node:path";
10284
+ import colors6 from "picocolors";
9803
10285
  import { SitemapStream } from "sitemap";
9804
10286
  async function generateSitemap({
9805
10287
  outputUrls,
@@ -9812,11 +10294,11 @@ async function generateSitemap({
9812
10294
  return;
9813
10295
  }
9814
10296
  const sitemap = new SitemapStream({ hostname: config.siteUrl });
9815
- const outputDir = path21.resolve(baseOutputDir, config.outDir ?? "");
10297
+ const outputDir = path22.resolve(baseOutputDir, config.outDir ?? "");
9816
10298
  if (!existsSync2(outputDir)) {
9817
10299
  await mkdir4(outputDir, { recursive: true });
9818
10300
  }
9819
- const sitemapOutputPath = path21.join(outputDir, "sitemap.xml");
10301
+ const sitemapOutputPath = path22.join(outputDir, "sitemap.xml");
9820
10302
  const writeStream = createWriteStream(sitemapOutputPath);
9821
10303
  sitemap.pipe(writeStream);
9822
10304
  let lastmod;
@@ -9840,20 +10322,20 @@ async function generateSitemap({
9840
10322
  writeStream.on("error", reject);
9841
10323
  });
9842
10324
  console.debug(
9843
- colors5.blue(`\u2713 wrote sitemap to ${colors5.bold(sitemapOutputPath)}`)
10325
+ colors6.blue(`\u2713 wrote sitemap to ${colors6.bold(sitemapOutputPath)}`)
9844
10326
  );
9845
10327
  }
9846
10328
 
9847
10329
  // src/vite/prerender/utils.ts
9848
10330
  init_joinUrl();
9849
- var resolveRoutePath2 = (path32) => {
9850
- const segments = path32.split("/");
10331
+ var resolveRoutePath2 = (path33) => {
10332
+ const segments = path33.split("/");
9851
10333
  if (segments.some((s) => s.startsWith(":") && !s.endsWith("?"))) {
9852
10334
  return void 0;
9853
10335
  }
9854
10336
  return segments.filter((s) => !s.startsWith(":")).join("/") || void 0;
9855
10337
  };
9856
- var isSkipped = (path32) => path32.includes("*") || /^\d+$/.test(path32);
10338
+ var isSkipped = (path33) => path33.includes("*") || /^\d+$/.test(path33);
9857
10339
  var resolveRoutes = (routes, parentPath = "") => routes.flatMap((route) => {
9858
10340
  if (route.path && isSkipped(route.path)) return [];
9859
10341
  const routePath = route.path ? resolveRoutePath2(route.path) : void 0;
@@ -9924,12 +10406,12 @@ var prerender = async ({
9924
10406
  serverConfigFilename,
9925
10407
  writeRedirects = true
9926
10408
  }) => {
9927
- const distDir = path23.join(dir, "dist", basePath);
10409
+ const distDir = path24.join(dir, "dist", basePath);
9928
10410
  const serverConfigPath = pathToFileURL(
9929
- path23.join(distDir, "server", serverConfigFilename)
10411
+ path24.join(distDir, "server", serverConfigFilename)
9930
10412
  ).href;
9931
10413
  const entryServerPath = pathToFileURL(
9932
- path23.join(distDir, "server/entry.server.js")
10414
+ path24.join(distDir, "server/entry.server.js")
9933
10415
  ).href;
9934
10416
  const rawConfig = await import(serverConfigPath).then((m) => m.default);
9935
10417
  const config = validateConfig(await runPluginTransformConfig(rawConfig));
@@ -9950,12 +10432,12 @@ var prerender = async ({
9950
10432
  let lastLogTime = start;
9951
10433
  const writeProgress = throttle(
9952
10434
  (count, total, urlPath) => {
9953
- writeLine(`prerendering (${count}/${total}) ${colors7.dim(urlPath)}`);
10435
+ writeLine(`prerendering (${count}/${total}) ${colors8.dim(urlPath)}`);
9954
10436
  }
9955
10437
  );
9956
10438
  if (!isTTY()) {
9957
10439
  logger.info(
9958
- colors7.dim(
10440
+ colors8.dim(
9959
10441
  `prerendering ${paths.length} routes using ${maxThreads} workers...`
9960
10442
  )
9961
10443
  );
@@ -9997,7 +10479,7 @@ var prerender = async ({
9997
10479
  const now = performance.now();
9998
10480
  if (now - lastLogTime >= LOG_INTERVAL_MS) {
9999
10481
  logger.info(
10000
- colors7.blue(
10482
+ colors8.blue(
10001
10483
  `prerendered ${completedCount}/${paths.length} routes using ${maxThreads} workers`
10002
10484
  )
10003
10485
  );
@@ -10010,10 +10492,10 @@ var prerender = async ({
10010
10492
  const seconds = ((performance.now() - start) / 1e3).toFixed(1);
10011
10493
  const message = `\u2713 finished prerendering ${paths.length} routes in ${seconds} seconds using ${maxThreads} workers`;
10012
10494
  if (isTTY()) {
10013
- writeLine(colors7.blue(`${message}
10495
+ writeLine(colors8.blue(`${message}
10014
10496
  `));
10015
10497
  } else {
10016
- logger.info(colors7.blue(message));
10498
+ logger.info(colors8.blue(message));
10017
10499
  }
10018
10500
  if (pagefindIndex) {
10019
10501
  const { include: pagesToIndex, exclude } = selectPagesToIndex(
@@ -10023,7 +10505,7 @@ var prerender = async ({
10023
10505
  if (exclude.length > 0) {
10024
10506
  const details = exclude.map(({ url, status }) => `${url} (${status})`).join(", ");
10025
10507
  logger.warn(
10026
- colors7.yellow(
10508
+ colors8.yellow(
10027
10509
  `\u26A0 ${exclude.length} route(s) excluded from the search index (render status >= 400): ${details}`
10028
10510
  )
10029
10511
  );
@@ -10040,18 +10522,18 @@ var prerender = async ({
10040
10522
  if (isTTY()) {
10041
10523
  const done = offset + batch.length;
10042
10524
  writeLine(
10043
- `pagefind indexing (${done}/${pagesToIndex.length}) ${colors7.dim(batch.at(-1)?.url ?? "")}`
10525
+ `pagefind indexing (${done}/${pagesToIndex.length}) ${colors8.dim(batch.at(-1)?.url ?? "")}`
10044
10526
  );
10045
10527
  }
10046
10528
  }
10047
10529
  if (isTTY()) writeLine("");
10048
10530
  const { outputPath } = await pagefindIndex.writeFiles({
10049
- outputPath: path23.join(distDir, "pagefind")
10531
+ outputPath: path24.join(distDir, "pagefind")
10050
10532
  });
10051
10533
  if (outputPath) {
10052
10534
  const duration = (performance.now() - pagefindStart) / 1e3;
10053
10535
  logger.info(
10054
- colors7.blue(
10536
+ colors8.blue(
10055
10537
  `\u2713 pagefind index built in ${duration.toFixed(1)} seconds: ${outputPath}`
10056
10538
  )
10057
10539
  );
@@ -10066,7 +10548,7 @@ var prerender = async ({
10066
10548
  redirectUrls
10067
10549
  });
10068
10550
  const llmsConfig = config.docs.llms;
10069
- const markdownInfoPath = path23.join(
10551
+ const markdownInfoPath = path24.join(
10070
10552
  dir,
10071
10553
  "node_modules/.zudoku/markdown-info.json"
10072
10554
  );
@@ -10102,7 +10584,7 @@ var prerender = async ({
10102
10584
  await Promise.all(
10103
10585
  markdownFileInfos.map((info) => {
10104
10586
  const outputPath = getMarkdownOutputPath(distDir, info.routePath);
10105
- if (!path23.resolve(outputPath).startsWith(path23.resolve(distDir))) {
10587
+ if (!path24.resolve(outputPath).startsWith(path24.resolve(distDir))) {
10106
10588
  return;
10107
10589
  }
10108
10590
  return rm2(outputPath).catch(() => {
@@ -10167,7 +10649,7 @@ var getContainerMemoryLimitMb = () => {
10167
10649
 
10168
10650
  // src/vite/protected/build.ts
10169
10651
  import { mkdir as mkdir5, readdir as readdir2, readFile as readFile4, rename, rm as rm3 } from "node:fs/promises";
10170
- import path24 from "node:path";
10652
+ import path25 from "node:path";
10171
10653
  init_joinUrl();
10172
10654
  var assertProtectedPatternsCovered = (config) => {
10173
10655
  const { patterns } = getProtectedSourceMatcher(config);
@@ -10189,11 +10671,11 @@ var findProtectedLeaks = (output) => {
10189
10671
  const visited = /* @__PURE__ */ new Set();
10190
10672
  const stack = [{ fileName: entry.fileName, path: [entry.fileName] }];
10191
10673
  while (stack.length > 0) {
10192
- const { fileName, path: path32 } = stack.pop();
10674
+ const { fileName, path: path33 } = stack.pop();
10193
10675
  if (visited.has(fileName)) continue;
10194
10676
  visited.add(fileName);
10195
10677
  for (const imp of byFileName.get(fileName)?.imports ?? []) {
10196
- const next = [...path32, imp];
10678
+ const next = [...path33, imp];
10197
10679
  if (isProtected(imp)) {
10198
10680
  leaks.push(next.join(" -> "));
10199
10681
  continue;
@@ -10224,17 +10706,17 @@ This eagerly pulls gated content into the public bundle. Check that nothing in n
10224
10706
  );
10225
10707
  };
10226
10708
  var moveProtectedChunks = async (clientOutDir, serverOutDir) => {
10227
- const srcDir = path24.join(clientOutDir, PROTECTED_CHUNK_DIR);
10709
+ const srcDir = path25.join(clientOutDir, PROTECTED_CHUNK_DIR);
10228
10710
  const files = await readdir2(srcDir).catch((err) => {
10229
10711
  if (err.code === "ENOENT") return null;
10230
10712
  throw err;
10231
10713
  });
10232
10714
  if (!files) return;
10233
- const destDir = path24.join(serverOutDir, PROTECTED_CHUNK_DIR);
10715
+ const destDir = path25.join(serverOutDir, PROTECTED_CHUNK_DIR);
10234
10716
  await mkdir5(destDir, { recursive: true });
10235
10717
  await Promise.all(
10236
10718
  files.map(
10237
- (file) => rename(path24.join(srcDir, file), path24.join(destDir, file))
10719
+ (file) => rename(path25.join(srcDir, file), path25.join(destDir, file))
10238
10720
  )
10239
10721
  );
10240
10722
  const leftover = await readdir2(srcDir).catch(() => []);
@@ -10252,7 +10734,7 @@ var assertCloudflareWranglerGatesProtected = async (dir, config) => {
10252
10734
  const protectedPrefix = `${joinUrl(config.basePath, PROTECTED_CHUNK_DIR)}/`;
10253
10735
  const candidates = ["wrangler.toml", "wrangler.jsonc", "wrangler.json"];
10254
10736
  for (const name of candidates) {
10255
- const file = await readFile4(path24.join(dir, name), "utf-8").catch(
10737
+ const file = await readFile4(path25.join(dir, name), "utf-8").catch(
10256
10738
  () => void 0
10257
10739
  );
10258
10740
  if (file === void 0) continue;
@@ -10308,7 +10790,7 @@ async function runBuild(options) {
10308
10790
  const builder2 = await createBuilder(viteConfig);
10309
10791
  invariant(builder2.environments.client, "Client environment is missing");
10310
10792
  invariant(builder2.environments.ssr, "SSR environment is missing");
10311
- const distDir = path25.resolve(path25.join(dir, "dist"));
10793
+ const distDir = path26.resolve(path26.join(dir, "dist"));
10312
10794
  await Promise.all([
10313
10795
  rm4(distDir, { recursive: true, force: true }),
10314
10796
  cleanVercelOutput(dir)
@@ -10367,13 +10849,13 @@ async function runBuild(options) {
10367
10849
  await assertCloudflareWranglerGatesProtected(dir, config);
10368
10850
  }
10369
10851
  await writeFile6(
10370
- path25.join(distDir, "package.json"),
10852
+ path26.join(distDir, "package.json"),
10371
10853
  `${JSON.stringify({ type: "module" }, null, 2)}
10372
10854
  `,
10373
10855
  "utf-8"
10374
10856
  );
10375
10857
  await writeManifest(distDir, config);
10376
- await rm4(path25.join(clientOutDir, "index.html"), { force: true });
10858
+ await rm4(path26.join(clientOutDir, "index.html"), { force: true });
10377
10859
  } else {
10378
10860
  await runPrerender({
10379
10861
  dir,
@@ -10410,25 +10892,25 @@ var runPrerender = async (options) => {
10410
10892
  serverConfigFilename,
10411
10893
  writeRedirects: process.env.VERCEL === void 0
10412
10894
  });
10413
- const indexHtml = path25.join(clientOutDir, "index.html");
10895
+ const indexHtml = path26.join(clientOutDir, "index.html");
10414
10896
  if (!workerResults.find((r) => r.outputPath === indexHtml)) {
10415
10897
  await writeFile6(indexHtml, html, "utf-8");
10416
10898
  }
10417
10899
  const statusPages = workerResults.flatMap(
10418
- (r) => /^(400|404|500)\.html$/.test(path25.basename(r.outputPath)) ? r.outputPath : []
10900
+ (r) => /^(400|404|500)\.html$/.test(path26.basename(r.outputPath)) ? r.outputPath : []
10419
10901
  );
10420
10902
  for (const statusPage of statusPages) {
10421
10903
  await rename2(
10422
10904
  statusPage,
10423
- path25.join(dir, DIST_DIR, path25.basename(statusPage))
10905
+ path26.join(dir, DIST_DIR, path26.basename(statusPage))
10424
10906
  );
10425
10907
  }
10426
10908
  await rm4(serverOutDir, { recursive: true, force: true });
10427
10909
  if (process.env.VERCEL) {
10428
- await mkdir6(path25.join(dir, ".vercel/output/static"), { recursive: true });
10910
+ await mkdir6(path26.join(dir, ".vercel/output/static"), { recursive: true });
10429
10911
  await rename2(
10430
- path25.join(dir, DIST_DIR),
10431
- path25.join(dir, ".vercel/output/static")
10912
+ path26.join(dir, DIST_DIR),
10913
+ path26.join(dir, ".vercel/output/static")
10432
10914
  );
10433
10915
  }
10434
10916
  await writeOutput(dir, {
@@ -10444,7 +10926,7 @@ var runPrerender = async (options) => {
10444
10926
  if (ZuploEnv.isZuplo && issuer) {
10445
10927
  const provider = config.authentication?.type;
10446
10928
  await writeFile6(
10447
- path25.join(dir, DIST_DIR, ".output/zuplo.json"),
10929
+ path26.join(dir, DIST_DIR, ".output/zuplo.json"),
10448
10930
  JSON.stringify({ issuer, provider }, null, 2),
10449
10931
  "utf-8"
10450
10932
  );
@@ -10456,7 +10938,7 @@ var runPrerender = async (options) => {
10456
10938
  };
10457
10939
  var findUserEntry = (dir) => {
10458
10940
  for (const ext of ["ts", "tsx", "js", "mjs"]) {
10459
- const candidate = path25.join(dir, `zudoku.server.${ext}`);
10941
+ const candidate = path26.join(dir, `zudoku.server.${ext}`);
10460
10942
  if (existsSync3(candidate)) return candidate;
10461
10943
  }
10462
10944
  };
@@ -10467,15 +10949,15 @@ var bundleSSREntry = async (options) => {
10467
10949
  let entryPoint = userEntry;
10468
10950
  let tempEntryPath;
10469
10951
  if (!entryPoint) {
10470
- tempEntryPath = path25.join(dir, "__ssr-entry.ts");
10952
+ tempEntryPath = path26.join(dir, "__ssr-entry.ts");
10471
10953
  const templateContent = await readFile5(
10472
- path25.join(packageRoot, "src/vite/ssr-templates", `${adapter}.ts`),
10954
+ path26.join(packageRoot, "src/vite/ssr-templates", `${adapter}.ts`),
10473
10955
  "utf-8"
10474
10956
  );
10475
10957
  await writeFile6(tempEntryPath, templateContent, "utf-8");
10476
10958
  entryPoint = tempEntryPath;
10477
10959
  }
10478
- const frameworkPath = path25.join(serverOutDir, "entry.server.js");
10960
+ const frameworkPath = path26.join(serverOutDir, "entry.server.js");
10479
10961
  try {
10480
10962
  await esbuild({
10481
10963
  entryPoints: [entryPoint],
@@ -10483,9 +10965,9 @@ var bundleSSREntry = async (options) => {
10483
10965
  platform: ["node", "lambda"].includes(adapter) ? "node" : "neutral",
10484
10966
  target: "es2022",
10485
10967
  format: "esm",
10486
- outfile: path25.join(serverOutDir, "entry.js"),
10968
+ outfile: path26.join(serverOutDir, "entry.js"),
10487
10969
  external: ["./zudoku.config.js"],
10488
- nodePaths: [path25.join(packageRoot, "node_modules")],
10970
+ nodePaths: [path26.join(packageRoot, "node_modules")],
10489
10971
  banner: { js: "// Bundled SSR entry" },
10490
10972
  define: {
10491
10973
  __ZUDOKU_TEMPLATE__: JSON.stringify(html)
@@ -10504,7 +10986,7 @@ var bundleSSREntry = async (options) => {
10504
10986
  await Promise.all([
10505
10987
  rm4(frameworkPath, { force: true }),
10506
10988
  rm4(`${frameworkPath}.map`, { force: true }),
10507
- rm4(path25.join(serverOutDir, "assets"), {
10989
+ rm4(path26.join(serverOutDir, "assets"), {
10508
10990
  recursive: true,
10509
10991
  force: true
10510
10992
  })
@@ -10515,20 +10997,20 @@ var bundleSSREntry = async (options) => {
10515
10997
  };
10516
10998
 
10517
10999
  // src/cli/common/output.ts
10518
- import colors8 from "picocolors";
11000
+ import colors9 from "picocolors";
10519
11001
  function printDiagnosticsToConsole(message) {
10520
- console.error(colors8.bold(colors8.blue(message)));
11002
+ console.error(colors9.bold(colors9.blue(message)));
10521
11003
  }
10522
11004
  function printWarningToConsole(message) {
10523
11005
  console.error(message);
10524
11006
  }
10525
11007
 
10526
11008
  // src/cli/preview/handler.ts
10527
- import path26 from "node:path";
11009
+ import path27 from "node:path";
10528
11010
  import { preview as vitePreview } from "vite";
10529
11011
  var DEFAULT_PREVIEW_PORT = 4e3;
10530
11012
  async function preview(argv) {
10531
- const dir = path26.resolve(process.cwd(), argv.dir);
11013
+ const dir = path27.resolve(process.cwd(), argv.dir);
10532
11014
  const viteConfig = await getViteConfig(dir, {
10533
11015
  command: "serve",
10534
11016
  mode: "production",
@@ -10566,7 +11048,7 @@ async function build(argv) {
10566
11048
  printDiagnosticsToConsole(`Starting Zudoku build v${packageJson2.version}`);
10567
11049
  printDiagnosticsToConsole("");
10568
11050
  printDiagnosticsToConsole("");
10569
- const dir = path27.resolve(process.cwd(), argv.dir);
11051
+ const dir = path28.resolve(process.cwd(), argv.dir);
10570
11052
  try {
10571
11053
  await runBuild({
10572
11054
  dir,
@@ -10725,13 +11207,13 @@ var build_default = {
10725
11207
 
10726
11208
  // src/cli/dev/handler.ts
10727
11209
  init_joinUrl();
10728
- import path30 from "node:path";
11210
+ import path31 from "node:path";
10729
11211
 
10730
11212
  // src/vite/dev-server.ts
10731
11213
  import fs4 from "node:fs/promises";
10732
11214
  import http from "node:http";
10733
11215
  import https from "node:https";
10734
- import path29 from "node:path";
11216
+ import path30 from "node:path";
10735
11217
  import { stripVTControlCharacters } from "node:util";
10736
11218
  import { createHttpTerminator } from "http-terminator";
10737
11219
  import {
@@ -10763,7 +11245,7 @@ async function findAvailablePort(startPort) {
10763
11245
  init_joinUrl();
10764
11246
 
10765
11247
  // src/vite/pagefind-dev-index.ts
10766
- import path28 from "node:path";
11248
+ import path29 from "node:path";
10767
11249
  import { createIndex as createIndex2 } from "pagefind";
10768
11250
  import { isRunnableDevEnvironment } from "vite";
10769
11251
  init_joinUrl();
@@ -10817,7 +11299,7 @@ async function* buildPagefindDevIndex(vite, config) {
10817
11299
  path: urlPath
10818
11300
  };
10819
11301
  }
10820
- const outputPath = path28.join(vite.config.publicDir, "pagefind");
11302
+ const outputPath = path29.join(vite.config.publicDir, "pagefind");
10821
11303
  await pagefindIndex.writeFiles({ outputPath });
10822
11304
  yield { type: "complete", success: true, indexed };
10823
11305
  }
@@ -10837,9 +11319,9 @@ var DevServer = class {
10837
11319
  this.protocol = "https";
10838
11320
  const { dir } = this.#options;
10839
11321
  const [key, cert, ca] = await Promise.all([
10840
- fs4.readFile(path29.resolve(dir, config.https.key)),
10841
- fs4.readFile(path29.resolve(dir, config.https.cert)),
10842
- config.https.ca ? fs4.readFile(path29.resolve(dir, config.https.ca)) : void 0
11322
+ fs4.readFile(path30.resolve(dir, config.https.key)),
11323
+ fs4.readFile(path30.resolve(dir, config.https.cert)),
11324
+ config.https.ca ? fs4.readFile(path30.resolve(dir, config.https.ca)) : void 0
10843
11325
  ]);
10844
11326
  return https.createServer({ key, cert, ca });
10845
11327
  }
@@ -10867,7 +11349,7 @@ var DevServer = class {
10867
11349
  // built-in transform middleware which would treat the path as a static asset.
10868
11350
  name: "zudoku:entry-client",
10869
11351
  configureServer(server2) {
10870
- const entryPath = path29.posix.join(
11352
+ const entryPath = path30.posix.join(
10871
11353
  server2.config.base,
10872
11354
  "/__z/entry.client.tsx"
10873
11355
  );
@@ -10979,13 +11461,13 @@ var DevServer = class {
10979
11461
  `Server-side rendering ${this.#options.ssr ? "enabled" : "disabled"}`
10980
11462
  );
10981
11463
  if (config.search?.type === "pagefind") {
10982
- const pagefindPath = path29.join(
11464
+ const pagefindPath = path30.join(
10983
11465
  vite.config.publicDir,
10984
11466
  "pagefind/pagefind.js"
10985
11467
  );
10986
11468
  const exists = await fs4.stat(pagefindPath).catch(() => false);
10987
11469
  if (!exists) {
10988
- await fs4.mkdir(path29.dirname(pagefindPath), { recursive: true });
11470
+ await fs4.mkdir(path30.dirname(pagefindPath), { recursive: true });
10989
11471
  await fs4.writeFile(pagefindPath, 'throw new Error("NOT_BUILT_YET");');
10990
11472
  }
10991
11473
  }
@@ -11087,7 +11569,7 @@ var DevServer = class {
11087
11569
  async function dev(argv) {
11088
11570
  const packageJson2 = getZudokuPackageJson();
11089
11571
  process.env.NODE_ENV = "development";
11090
- const dir = path30.resolve(process.cwd(), argv.dir);
11572
+ const dir = path31.resolve(process.cwd(), argv.dir);
11091
11573
  const server = new DevServer({
11092
11574
  dir,
11093
11575
  argPort: argv.port,
@@ -11195,11 +11677,11 @@ var preview_default = previewCommand;
11195
11677
  import { existsSync as existsSync4, mkdirSync } from "node:fs";
11196
11678
  import { readFile as readFile6, writeFile as writeFile7 } from "node:fs/promises";
11197
11679
  import { join } from "node:path";
11198
- import colors10 from "picocolors";
11680
+ import colors11 from "picocolors";
11199
11681
  import { gt } from "semver";
11200
11682
 
11201
11683
  // src/cli/common/utils/box.ts
11202
- import colors9 from "picocolors";
11684
+ import colors10 from "picocolors";
11203
11685
  import stripAnsi from "strip-ansi";
11204
11686
  var border = ["\u2500", "\u256D", "\u256E", "\u2502", "\u2502", "\u2570", "\u256F"];
11205
11687
  var nothing = ["\u2500", "", "", "", "", "", ""];
@@ -11211,7 +11693,7 @@ function box(message, {
11211
11693
  } = {}) {
11212
11694
  const lines = message.split(/\r?\n/).map((line) => [line, stripAnsi(line).length]);
11213
11695
  const maxLine = lines.reduce((p, [, len]) => Math.max(p, len), 0);
11214
- const borderColorFn = borderColor && colors9[borderColor] || colors9.yellow;
11696
+ const borderColorFn = borderColor && colors10[borderColor] || colors10.yellow;
11215
11697
  const clampedSidePadding = Math.max(1, padding * 3);
11216
11698
  const narrowMode = maxLine + 2 + clampedSidePadding * 2 > cols;
11217
11699
  const sidePadding = narrowMode ? 0 : clampedSidePadding;
@@ -11243,12 +11725,12 @@ function box(message, {
11243
11725
 
11244
11726
  // src/cli/common/xdg/lib.ts
11245
11727
  import { homedir } from "node:os";
11246
- import path31 from "node:path";
11728
+ import path32 from "node:path";
11247
11729
  function defineDirectoryWithFallback(xdgName, fallback) {
11248
11730
  if (process.env[xdgName]) {
11249
11731
  return process.env[xdgName];
11250
11732
  } else {
11251
- return path31.join(homedir(), fallback);
11733
+ return path32.join(homedir(), fallback);
11252
11734
  }
11253
11735
  }
11254
11736
  var XDG_CONFIG_HOME = defineDirectoryWithFallback(
@@ -11263,15 +11745,15 @@ var XDG_STATE_HOME = defineDirectoryWithFallback(
11263
11745
  "XDG_DATA_HOME",
11264
11746
  ".local/state"
11265
11747
  );
11266
- var ZUDOKU_XDG_CONFIG_HOME = path31.join(
11748
+ var ZUDOKU_XDG_CONFIG_HOME = path32.join(
11267
11749
  XDG_CONFIG_HOME,
11268
11750
  CLI_XDG_FOLDER_NAME
11269
11751
  );
11270
- var ZUDOKU_XDG_DATA_HOME = path31.join(
11752
+ var ZUDOKU_XDG_DATA_HOME = path32.join(
11271
11753
  XDG_DATA_HOME,
11272
11754
  CLI_XDG_FOLDER_NAME
11273
11755
  );
11274
- var ZUDOKU_XDG_STATE_HOME = path31.join(
11756
+ var ZUDOKU_XDG_STATE_HOME = path32.join(
11275
11757
  XDG_STATE_HOME,
11276
11758
  CLI_XDG_FOLDER_NAME
11277
11759
  );
@@ -11289,12 +11771,12 @@ async function warnIfOutdatedVersion(currentVersion) {
11289
11771
  if (shouldWarn) {
11290
11772
  printWarningToConsole(
11291
11773
  box(
11292
- `Update available! ${colors10.gray(`v${currentVersion}`)} \u226B ${colors10.green(
11774
+ `Update available! ${colors11.gray(`v${currentVersion}`)} \u226B ${colors11.green(
11293
11775
  `v${versionCheckInfo.latestVersion}`
11294
11776
  )}
11295
- Run ${colors10.cyan("npm install zudoku@latest")} to update.
11777
+ Run ${colors11.cyan("npm install zudoku@latest")} to update.
11296
11778
 
11297
- ${colors10.gray("Upgrade to receive the latest features and fixes.")}`
11779
+ ${colors11.gray("Upgrade to receive the latest features and fixes.")}`
11298
11780
  )
11299
11781
  );
11300
11782
  }
@@ -11355,7 +11837,7 @@ async function getVersionCheckInfo() {
11355
11837
  }
11356
11838
 
11357
11839
  // src/cli/common/version-check.ts
11358
- import colors11 from "picocolors";
11840
+ import colors12 from "picocolors";
11359
11841
  import { minVersion, satisfies } from "semver";
11360
11842
  var getPkgManager = () => {
11361
11843
  const userAgent = process.env.npm_config_user_agent ?? "";
@@ -11389,16 +11871,16 @@ var warnPackageVersionMismatch = () => {
11389
11871
  return;
11390
11872
  }
11391
11873
  const pkgManager = getPkgManager();
11392
- const message = `${colors11.yellow("React version mismatch detected!")}
11874
+ const message = `${colors12.yellow("React version mismatch detected!")}
11393
11875
 
11394
11876
  Zudoku requires specific versions of React
11395
11877
  and React DOM to function correctly.
11396
11878
 
11397
- Installed: ${colors11.bold(`react@${installed.react}, react-dom@${installed["react-dom"]}`)}
11398
- Required: ${colors11.green(`react@${required.react}, react-dom@${required["react-dom"]}`)}
11879
+ Installed: ${colors12.bold(`react@${installed.react}, react-dom@${installed["react-dom"]}`)}
11880
+ Required: ${colors12.green(`react@${required.react}, react-dom@${required["react-dom"]}`)}
11399
11881
 
11400
11882
  To fix, run:
11401
- ${colors11.cyan(`${pkgManager} install react@${minVersion(required.react)} react-dom@${minVersion(required["react-dom"])}`)}`;
11883
+ ${colors12.cyan(`${pkgManager} install react@${minVersion(required.react)} react-dom@${minVersion(required["react-dom"])}`)}`;
11402
11884
  printWarningToConsole(box(message));
11403
11885
  process.exit(1);
11404
11886
  };