zudoku 0.79.0 → 0.80.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli/cli.js +355 -515
- package/dist/declarations/app/ssrCacheControl.d.ts +1 -0
- package/dist/declarations/config/create-plugin.d.ts +2 -1
- package/dist/declarations/config/validators/InputNavigationSchema.d.ts +13 -0
- package/dist/declarations/config/validators/NavigationSchema.d.ts +7 -1
- package/dist/declarations/config/validators/ZudokuConfig.d.ts +1 -0
- package/dist/declarations/index.d.ts +1 -0
- package/dist/declarations/lib/authentication/components/CallbackHandler.d.ts +1 -1
- package/dist/declarations/lib/authentication/cookie-sync.d.ts +1 -0
- package/dist/declarations/lib/authentication/utils/redirectAfterAuth.d.ts +4 -0
- package/dist/declarations/lib/components/Anchor.d.ts +5 -0
- package/dist/declarations/lib/components/Bootstrap.d.ts +5 -4
- package/dist/declarations/lib/components/Meta.d.ts +1 -1
- package/dist/declarations/lib/components/PluginHeads.d.ts +1 -1
- package/dist/declarations/lib/components/index.d.ts +3 -1
- package/dist/declarations/lib/components/navigation/Navigation.d.ts +2 -1
- package/dist/declarations/lib/components/navigation/NavigationFilterContext.d.ts +3 -1
- package/dist/declarations/lib/components/navigation/NavigationFrames.d.ts +6 -0
- package/dist/declarations/lib/components/navigation/StackRows.d.ts +12 -0
- package/dist/declarations/lib/components/navigation/motionFeatures.d.ts +1 -0
- package/dist/declarations/lib/components/navigation/useNavigationFrame.d.ts +15 -0
- package/dist/declarations/lib/components/navigation/utils.d.ts +16 -1
- package/dist/declarations/lib/core/plugin-config.d.ts +2 -0
- package/dist/declarations/lib/graphiql/GraphiQLViewer.d.ts +29 -0
- package/dist/declarations/lib/graphiql/index.d.ts +2 -0
- package/dist/declarations/lib/graphiql/loadGraphiQLFromCdn.d.ts +45 -0
- package/dist/declarations/lib/hooks/index.d.ts +1 -0
- package/dist/declarations/lib/plugins/openapi/ApiHeader.d.ts +1 -2
- package/dist/declarations/lib/plugins/openapi/ParameterList.d.ts +2 -1
- package/dist/declarations/lib/plugins/openapi/ParameterListItem.d.ts +1 -1
- package/dist/declarations/lib/plugins/openapi/PlaygroundDialogWrapper.d.ts +3 -2
- package/dist/declarations/lib/plugins/openapi/RequestBodySidecarBox.d.ts +2 -2
- package/dist/declarations/lib/plugins/openapi/ResponsesSidecarBox.d.ts +12 -4
- package/dist/declarations/lib/plugins/openapi/SchemaInfo.d.ts +4 -1
- package/dist/declarations/lib/plugins/openapi/Sidecar.d.ts +3 -3
- package/dist/declarations/lib/plugins/openapi/SidecarExamples.d.ts +2 -2
- package/dist/declarations/lib/plugins/openapi/components/ResponseContent.d.ts +2 -2
- package/dist/declarations/lib/plugins/openapi/graphql/gql.d.ts +1 -1
- package/dist/declarations/lib/plugins/openapi/graphql/graphql.d.ts +136 -466
- package/dist/declarations/lib/plugins/openapi/index.d.ts +3 -3
- package/dist/declarations/lib/plugins/openapi/interfaces.d.ts +2 -2
- package/dist/declarations/lib/plugins/openapi/playground/BodyPanel.d.ts +2 -2
- package/dist/declarations/lib/plugins/openapi/playground/ExamplesDropdown.d.ts +3 -3
- package/dist/declarations/lib/plugins/openapi/playground/GraphiQL.d.ts +9 -0
- package/dist/declarations/lib/plugins/openapi/playground/GraphiQLDialog.d.ts +11 -0
- package/dist/declarations/lib/plugins/openapi/playground/Playground.d.ts +5 -3
- package/dist/declarations/lib/plugins/openapi/playground/result-panel/ResponseTab.d.ts +2 -1
- package/dist/declarations/lib/plugins/openapi/playground/result-panel/ResultPanel.d.ts +2 -1
- package/dist/declarations/lib/plugins/openapi/playground/result-panel/convertToTypes.d.ts +2 -2
- package/dist/declarations/lib/plugins/openapi/util/extractOperationSecuritySchemes.d.ts +2 -1
- package/dist/declarations/lib/plugins/openapi/util/graphqlEndpoint.d.ts +6 -0
- package/dist/declarations/lib/plugins/openapi/util/shouldShowInfoPage.d.ts +1 -0
- package/dist/declarations/lib/ui/Callout.d.ts +32 -28
- package/dist/declarations/lib/util/MdxComponents.d.ts +8 -2
- package/dist/declarations/vite/index.d.ts +3 -0
- package/dist/flat-config.d.ts +7 -0
- package/docs/components/callout.mdx +126 -8
- package/docs/components/head.mdx +2 -12
- package/docs/components/sidecar-box.mdx +131 -0
- package/docs/configuration/api-catalog.md +62 -43
- package/docs/configuration/api-reference.md +5 -4
- package/docs/configuration/navigation.mdx +70 -7
- package/docs/customization/colors-theme.mdx +19 -0
- package/docs/markdown/admonitions.md +79 -0
- package/package.json +30 -24
- package/src/app/defaultTheme.css +22 -0
- package/src/app/demo.tsx +4 -1
- package/src/app/entry.client.tsx +4 -2
- package/src/app/entry.server.tsx +13 -19
- package/src/app/main.css +14 -1
- package/src/app/ssrCacheControl.ts +20 -0
- package/src/app/standalone.tsx +4 -1
- package/src/config/create-plugin.ts +47 -28
- package/src/config/loader.ts +92 -34
- package/src/config/validators/InputNavigationSchema.ts +10 -0
- package/src/config/validators/NavigationSchema.ts +16 -2
- package/src/config/validators/ZudokuConfig.ts +32 -3
- package/src/index.ts +1 -0
- package/src/lib/authentication/components/CallbackHandler.tsx +9 -2
- package/src/lib/authentication/cookie-sync.ts +39 -6
- package/src/lib/authentication/providers/supabase.tsx +7 -1
- package/src/lib/authentication/ui/EmailLinkCallbackUi.tsx +2 -1
- package/src/lib/authentication/ui/ZudokuAuthUi.tsx +5 -4
- package/src/lib/authentication/utils/redirectAfterAuth.ts +25 -0
- package/src/lib/components/Anchor.tsx +29 -0
- package/src/lib/components/Bootstrap.tsx +10 -7
- package/src/lib/components/Header.tsx +3 -3
- package/src/lib/components/Main.tsx +2 -1
- package/src/lib/components/Meta.tsx +51 -45
- package/src/lib/components/PluginHeads.tsx +16 -8
- package/src/lib/components/context/ZudokuContext.ts +3 -0
- package/src/lib/components/index.ts +3 -1
- package/src/lib/components/navigation/Navigation.tsx +33 -39
- package/src/lib/components/navigation/NavigationCategory.tsx +28 -16
- package/src/lib/components/navigation/NavigationFilterContext.tsx +15 -1
- package/src/lib/components/navigation/NavigationFrames.tsx +104 -0
- package/src/lib/components/navigation/NavigationItem.tsx +33 -21
- package/src/lib/components/navigation/NavigationWrapper.tsx +29 -2
- package/src/lib/components/navigation/StackRows.tsx +65 -0
- package/src/lib/components/navigation/motionFeatures.ts +2 -0
- package/src/lib/components/navigation/useNavigationFrame.ts +107 -0
- package/src/lib/components/navigation/utils.ts +60 -6
- package/src/lib/core/RouteGuard.tsx +3 -3
- package/src/lib/core/plugin-config.ts +25 -0
- package/src/lib/graphiql/GraphiQLViewer.tsx +247 -0
- package/src/lib/graphiql/graphiql-sri.json +11 -0
- package/src/lib/graphiql/graphiql-theme.css +83 -0
- package/src/lib/graphiql/graphiql.css +6 -0
- package/src/lib/graphiql/index.ts +7 -0
- package/src/lib/graphiql/loadGraphiQLFromCdn.ts +191 -0
- package/src/lib/hooks/index.ts +1 -0
- package/src/lib/plugins/api-catalog/Catalog.tsx +3 -3
- package/src/lib/plugins/markdown/MdxPage.tsx +3 -3
- package/src/lib/plugins/openapi/ApiHeader.tsx +1 -3
- package/src/lib/plugins/openapi/GeneratedExampleSidecarBox.tsx +1 -1
- package/src/lib/plugins/openapi/OperationList.tsx +4 -9
- package/src/lib/plugins/openapi/OperationListItem.tsx +150 -118
- package/src/lib/plugins/openapi/ParamInfos.tsx +1 -1
- package/src/lib/plugins/openapi/ParameterList.tsx +5 -1
- package/src/lib/plugins/openapi/ParameterListItem.tsx +1 -1
- package/src/lib/plugins/openapi/PlaygroundDialogWrapper.tsx +22 -5
- package/src/lib/plugins/openapi/RequestBodySidecarBox.tsx +3 -3
- package/src/lib/plugins/openapi/ResponsesSidecarBox.tsx +17 -9
- package/src/lib/plugins/openapi/SchemaInfo.tsx +27 -7
- package/src/lib/plugins/openapi/SchemaList.tsx +6 -6
- package/src/lib/plugins/openapi/Sidecar.tsx +118 -43
- package/src/lib/plugins/openapi/SidecarExamples.tsx +3 -3
- package/src/lib/plugins/openapi/components/ResponseContent.tsx +2 -2
- package/src/lib/plugins/openapi/graphql/gql.ts +3 -3
- package/src/lib/plugins/openapi/graphql/graphql.ts +146 -524
- package/src/lib/plugins/openapi/index.tsx +8 -1
- package/src/lib/plugins/openapi/interfaces.ts +2 -2
- package/src/lib/plugins/openapi/playground/BodyPanel.tsx +2 -2
- package/src/lib/plugins/openapi/playground/ExamplesDropdown.tsx +3 -3
- package/src/lib/plugins/openapi/playground/GraphiQL.tsx +24 -0
- package/src/lib/plugins/openapi/playground/GraphiQLDialog.tsx +79 -0
- package/src/lib/plugins/openapi/playground/Playground.tsx +5 -2
- package/src/lib/plugins/openapi/playground/result-panel/ResponseTab.tsx +7 -5
- package/src/lib/plugins/openapi/playground/result-panel/ResultPanel.tsx +18 -0
- package/src/lib/plugins/openapi/playground/result-panel/convertToTypes.ts +28 -9
- package/src/lib/plugins/openapi/util/extractOperationSecuritySchemes.ts +5 -4
- package/src/lib/plugins/openapi/util/getRoutes.tsx +27 -14
- package/src/lib/plugins/openapi/util/graphqlEndpoint.ts +28 -0
- package/src/lib/plugins/openapi/util/shouldShowInfoPage.ts +15 -0
- package/src/lib/shiki.ts +1 -1
- package/src/lib/testing/index.tsx +4 -3
- package/src/lib/ui/Callout.tsx +68 -68
- package/src/lib/ui/EmbeddedCodeBlock.tsx +2 -2
- package/src/lib/{plugins/openapi → ui}/SidecarBox.tsx +1 -1
- package/src/lib/util/MdxComponents.tsx +6 -0
- package/src/vite/config.ts +7 -3
- package/src/vite/dev-server.ts +11 -4
- package/src/vite/html.ts +0 -2
- package/src/vite/index.ts +9 -0
- package/src/vite/plugin-api.ts +20 -4
- package/src/vite/plugin-docs.ts +3 -2
- package/src/vite/plugin-theme.ts +6 -2
- /package/dist/declarations/lib/{plugins/openapi → ui}/SidecarBox.d.ts +0 -0
package/dist/cli/cli.js
CHANGED
|
@@ -85,9 +85,9 @@ var init_transform_config = __esm({
|
|
|
85
85
|
}
|
|
86
86
|
return result;
|
|
87
87
|
};
|
|
88
|
-
runPluginTransformConfig = async (
|
|
89
|
-
const plugins =
|
|
90
|
-
let result =
|
|
88
|
+
runPluginTransformConfig = async (config) => {
|
|
89
|
+
const plugins = config.plugins ?? [];
|
|
90
|
+
let result = config;
|
|
91
91
|
for (const plugin of plugins.filter(isTransformConfigPlugin)) {
|
|
92
92
|
const merge = (partial) => mergeConfig(result, partial);
|
|
93
93
|
const transformed = await plugin.transformConfig?.({
|
|
@@ -506,8 +506,8 @@ var init_plugin_theme = __esm({
|
|
|
506
506
|
// Handle the virtual module for dynamic theme content
|
|
507
507
|
async load(id) {
|
|
508
508
|
if (id !== resolvedVirtualModuleId) return;
|
|
509
|
-
const
|
|
510
|
-
const themeConfig =
|
|
509
|
+
const config = getCurrentConfig();
|
|
510
|
+
const themeConfig = config.theme ?? {};
|
|
511
511
|
const themeCss = [];
|
|
512
512
|
const fonts = await processFonts(themeConfig);
|
|
513
513
|
if (fonts.imports.length > 0) {
|
|
@@ -583,10 +583,18 @@ ${generateCss(themeConfig.dark)}
|
|
|
583
583
|
if (fonts.families.serif) {
|
|
584
584
|
rootVars.push(` --font-serif: ${fonts.families.serif};`);
|
|
585
585
|
}
|
|
586
|
-
const shikiThemes =
|
|
586
|
+
const shikiThemes = config.syntaxHighlighting?.themes ?? defaultHighlightOptions.themes;
|
|
587
587
|
const [lightTheme, darkTheme] = (await Promise.all([
|
|
588
|
-
import(
|
|
589
|
-
|
|
588
|
+
import(
|
|
589
|
+
/* @vite-ignore */
|
|
590
|
+
`@shikijs/themes/${shikiThemes.light}`
|
|
591
|
+
).then((m) => m.default),
|
|
592
|
+
import(
|
|
593
|
+
/* @vite-ignore */
|
|
594
|
+
`@shikijs/themes/${shikiThemes.dark}`
|
|
595
|
+
).then(
|
|
596
|
+
(m) => m.default
|
|
597
|
+
)
|
|
590
598
|
])).map(normalizeTheme);
|
|
591
599
|
rootVars.push(
|
|
592
600
|
` --shiki-light: ${lightTheme?.fg ?? "#000"};`,
|
|
@@ -603,12 +611,12 @@ ${rootVars.join("\n")}
|
|
|
603
611
|
// This goes through the normal CSS pipeline so Tailwind can process it
|
|
604
612
|
async transform(src, id) {
|
|
605
613
|
if (!id.endsWith("/src/app/main.css")) return;
|
|
606
|
-
const
|
|
614
|
+
const config = getCurrentConfig();
|
|
607
615
|
const files = new Set(
|
|
608
616
|
[
|
|
609
|
-
|
|
610
|
-
...
|
|
611
|
-
...
|
|
617
|
+
config.__meta.rootDir,
|
|
618
|
+
...config.__meta.dependencies,
|
|
619
|
+
...config.__pluginDirs ?? []
|
|
612
620
|
].map((file) => path2.relative(path2.dirname(id), file))
|
|
613
621
|
);
|
|
614
622
|
const code = [...files].map((file) => `@source "${file}";`);
|
|
@@ -660,11 +668,11 @@ ${rootVars.join("\n")}
|
|
|
660
668
|
` --font-serif: var(--font-serif);`
|
|
661
669
|
);
|
|
662
670
|
code.push("}");
|
|
663
|
-
const customCss =
|
|
671
|
+
const customCss = config.theme?.customCss;
|
|
664
672
|
if (customCss) {
|
|
665
673
|
code.push(processCustomCss(customCss));
|
|
666
674
|
}
|
|
667
|
-
const defaultThemeImport =
|
|
675
|
+
const defaultThemeImport = config.theme?.noDefaultTheme ? "" : '@import "./defaultTheme.css" layer(theme);';
|
|
668
676
|
return src.replace(DEFAULT_THEME_REPLACE, defaultThemeImport).replace(MAIN_REPLACE, code.join("\n"));
|
|
669
677
|
}
|
|
670
678
|
};
|
|
@@ -2695,6 +2703,11 @@ var init_InputNavigationSchema = __esm({
|
|
|
2695
2703
|
file: z5.string(),
|
|
2696
2704
|
label: z5.string().optional(),
|
|
2697
2705
|
path: z5.string().optional()
|
|
2706
|
+
}),
|
|
2707
|
+
z5.object({
|
|
2708
|
+
type: z5.literal("link"),
|
|
2709
|
+
to: z5.string(),
|
|
2710
|
+
label: z5.string().optional()
|
|
2698
2711
|
})
|
|
2699
2712
|
]);
|
|
2700
2713
|
DisplaySchema = z5.union([
|
|
@@ -2710,7 +2723,10 @@ var init_InputNavigationSchema = __esm({
|
|
|
2710
2723
|
badge: BadgeSchema.optional(),
|
|
2711
2724
|
collapsed: z5.boolean().optional(),
|
|
2712
2725
|
collapsible: z5.boolean().optional(),
|
|
2713
|
-
display: DisplaySchema
|
|
2726
|
+
display: DisplaySchema,
|
|
2727
|
+
// Turn a (plugin-generated) category into a stacked sub-nav
|
|
2728
|
+
// E.g. make each OpenAPI tag drill into its own panel. See `stack` above.
|
|
2729
|
+
stack: z5.boolean().optional()
|
|
2714
2730
|
})
|
|
2715
2731
|
});
|
|
2716
2732
|
NavigationInsertRuleSchema = z5.object({
|
|
@@ -2762,7 +2778,8 @@ var init_InputNavigationSchema = __esm({
|
|
|
2762
2778
|
target: z5.enum(["_self", "_blank"]).optional(),
|
|
2763
2779
|
icon: IconSchema2.optional(),
|
|
2764
2780
|
badge: BadgeSchema.optional(),
|
|
2765
|
-
display: DisplaySchema
|
|
2781
|
+
display: DisplaySchema,
|
|
2782
|
+
stack: z5.boolean().optional()
|
|
2766
2783
|
});
|
|
2767
2784
|
InputNavigationCustomPageSchema = z5.object({
|
|
2768
2785
|
type: z5.literal("custom-page"),
|
|
@@ -2795,7 +2812,8 @@ var init_InputNavigationSchema = __esm({
|
|
|
2795
2812
|
collapsible: z5.boolean().optional(),
|
|
2796
2813
|
collapsed: z5.boolean().optional(),
|
|
2797
2814
|
link: InputNavigationCategoryLinkDocSchema.optional(),
|
|
2798
|
-
display: DisplaySchema
|
|
2815
|
+
display: DisplaySchema,
|
|
2816
|
+
stack: z5.boolean().optional()
|
|
2799
2817
|
});
|
|
2800
2818
|
InputNavigationCategorySchema = BaseInputNavigationCategorySchema.extend({
|
|
2801
2819
|
items: z5.lazy(() => InputNavigationItemSchema.array())
|
|
@@ -2919,20 +2937,35 @@ __export(ZudokuConfig_exports, {
|
|
|
2919
2937
|
import colors from "picocolors";
|
|
2920
2938
|
import { isValidElement as isValidElement2 } from "react";
|
|
2921
2939
|
import { z as z7 } from "zod";
|
|
2922
|
-
function validateConfig(
|
|
2923
|
-
|
|
2940
|
+
function validateConfig(config, configPath) {
|
|
2941
|
+
warnUnsafeConfigKeys(config);
|
|
2942
|
+
const validationResult = ZudokuConfig.safeParse(config);
|
|
2924
2943
|
if (!validationResult.success) {
|
|
2944
|
+
const prettyErrors = z7.prettifyError(validationResult.error);
|
|
2945
|
+
const location = configPath ? ` at ${configPath}` : "";
|
|
2925
2946
|
if (process.env.NODE_ENV === "production") {
|
|
2926
2947
|
throw new Error(
|
|
2927
|
-
`
|
|
2928
|
-
${
|
|
2948
|
+
`Invalid Zudoku configuration${location}:
|
|
2949
|
+
${prettyErrors}`
|
|
2929
2950
|
);
|
|
2930
2951
|
}
|
|
2931
|
-
console.log(colors.yellow(
|
|
2932
|
-
console.log(colors.yellow(
|
|
2952
|
+
console.log(colors.yellow(`Invalid Zudoku configuration${location}:`));
|
|
2953
|
+
console.log(colors.yellow(prettyErrors));
|
|
2933
2954
|
}
|
|
2934
2955
|
}
|
|
2935
|
-
|
|
2956
|
+
function warnUnsafeConfigKeys(config) {
|
|
2957
|
+
if (typeof config !== "object" || config === null) return;
|
|
2958
|
+
const usedKeys = DEPRECATED_UNSAFE_KEYS.filter(
|
|
2959
|
+
(key) => Object.hasOwn(config, key)
|
|
2960
|
+
);
|
|
2961
|
+
if (usedKeys.length === 0) return;
|
|
2962
|
+
console.log(
|
|
2963
|
+
colors.yellow(
|
|
2964
|
+
`Warning: The following config ${usedKeys.length === 1 ? "option is" : "options are"} deprecated and will be removed soon: ${usedKeys.join(", ")}`
|
|
2965
|
+
)
|
|
2966
|
+
);
|
|
2967
|
+
}
|
|
2968
|
+
var ThemeSchema, ApiCatalogCategorySchema, LanguageOption, AiAssistantCustomSchema, AiAssistantPresets, AiAssistantsSchema, ApiOptionsSchema, ApiConfigSchema, VersionConfigSchema, ApiSchema, ApiKeysSchema, LogoSchema, FooterSocialIcons, FooterSocialSchema, FooterSchema, SiteMapSchema, DEFAULT_DOCS_FILES, LlmsConfigSchema, DocsConfigSchema, Redirect, SearchSchema, SignUpUrlValueSchema, SignUpUrlSchema, SignUpOpenIdSchema, AuthenticationSchema, MetadataSchema, FontConfigSchema, FontsConfigSchema, CssObject, ThemeConfigSchema, SiteSchema, PlacementPosition, HeaderConfigSchema, ApiCatalogSchema, CdnUrlSchema, BaseConfigSchema, ZudokuConfig, DEPRECATED_UNSAFE_KEYS;
|
|
2936
2969
|
var init_ZudokuConfig = __esm({
|
|
2937
2970
|
"src/config/validators/ZudokuConfig.ts"() {
|
|
2938
2971
|
init_plugin_theme();
|
|
@@ -3471,6 +3504,7 @@ var init_ZudokuConfig = __esm({
|
|
|
3471
3504
|
__pluginDirs: z7.array(z7.string())
|
|
3472
3505
|
});
|
|
3473
3506
|
ZudokuConfig = BaseConfigSchema.partial();
|
|
3507
|
+
DEPRECATED_UNSAFE_KEYS = ["UNSAFE_slotlets"];
|
|
3474
3508
|
}
|
|
3475
3509
|
});
|
|
3476
3510
|
|
|
@@ -3493,29 +3527,48 @@ async function getConfigFilePath(rootDir) {
|
|
|
3493
3527
|
}
|
|
3494
3528
|
async function loadZudokuConfigWithMeta(rootDir) {
|
|
3495
3529
|
const configPath = await getConfigFilePath(rootDir);
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
|
|
3530
|
+
let module;
|
|
3531
|
+
let dependencies;
|
|
3532
|
+
try {
|
|
3533
|
+
({ module, dependencies } = await runnerImport(configPath, {
|
|
3534
|
+
plugins: [virtualModuleStubPlugin],
|
|
3535
|
+
environments: {
|
|
3536
|
+
inline: {
|
|
3537
|
+
resolve: {
|
|
3538
|
+
// Prevent Node.js from trying to load zudoku's raw .ts source
|
|
3539
|
+
// directly, which fails with ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING
|
|
3540
|
+
// when --experimental-strip-types is enabled. Uses regex to also
|
|
3541
|
+
// catch plugins that re-export from zudoku (e.g. @zuplo/zudoku-plugin-*).
|
|
3542
|
+
noExternal: [/zudoku/]
|
|
3543
|
+
}
|
|
3506
3544
|
}
|
|
3545
|
+
},
|
|
3546
|
+
server: {
|
|
3547
|
+
// this allows us to 'load' CSS files in the config
|
|
3548
|
+
// see https://github.com/vitejs/vite/pull/19577
|
|
3549
|
+
perEnvironmentStartEndDuringDev: true
|
|
3507
3550
|
}
|
|
3508
|
-
}
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3551
|
+
}));
|
|
3552
|
+
} catch (error) {
|
|
3553
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
3554
|
+
throw new Error(
|
|
3555
|
+
`Invalid Zudoku configuration at ${colors2.dim(configPath)}:
|
|
3556
|
+
|
|
3557
|
+
${detail}`,
|
|
3558
|
+
{ cause: error }
|
|
3559
|
+
);
|
|
3560
|
+
}
|
|
3561
|
+
if (module.default === void 0) {
|
|
3562
|
+
throw new Error(
|
|
3563
|
+
`Invalid Zudoku configuration at ${colors2.dim(configPath)}:
|
|
3564
|
+
|
|
3565
|
+
Config file must have a default export.`
|
|
3566
|
+
);
|
|
3567
|
+
}
|
|
3568
|
+
const config = module.default;
|
|
3569
|
+
validateConfig(config, configPath);
|
|
3517
3570
|
const configWithMetadata = {
|
|
3518
|
-
...
|
|
3571
|
+
...config,
|
|
3519
3572
|
__meta: {
|
|
3520
3573
|
rootDir,
|
|
3521
3574
|
moduleDir: getZudokuRootDir(),
|
|
@@ -3536,8 +3589,12 @@ function loadEnv(configEnv, rootDir) {
|
|
|
3536
3589
|
return { publicEnv: publicEnv2, envPrefix: envPrefix2 };
|
|
3537
3590
|
}
|
|
3538
3591
|
async function hasConfigChanged() {
|
|
3592
|
+
const config = getConfig();
|
|
3539
3593
|
if (!config || !modifiedTimes) return true;
|
|
3540
|
-
const files = [
|
|
3594
|
+
const files = [
|
|
3595
|
+
config.__meta.configPath,
|
|
3596
|
+
...config.__meta.dependencies.filter(isFileSystemPath)
|
|
3597
|
+
];
|
|
3541
3598
|
try {
|
|
3542
3599
|
const hasChanged = await Promise.all(
|
|
3543
3600
|
files.map(async (depPath) => {
|
|
@@ -3552,8 +3609,12 @@ async function hasConfigChanged() {
|
|
|
3552
3609
|
}
|
|
3553
3610
|
}
|
|
3554
3611
|
async function updateModifiedTimes() {
|
|
3612
|
+
const config = getConfig();
|
|
3555
3613
|
if (!config) return;
|
|
3556
|
-
const files = [
|
|
3614
|
+
const files = [
|
|
3615
|
+
config.__meta.configPath,
|
|
3616
|
+
...config.__meta.dependencies.filter(isFileSystemPath)
|
|
3617
|
+
];
|
|
3557
3618
|
modifiedTimes = /* @__PURE__ */ new Map();
|
|
3558
3619
|
await Promise.all(
|
|
3559
3620
|
files.map(async (depPath) => {
|
|
@@ -3564,29 +3625,38 @@ async function updateModifiedTimes() {
|
|
|
3564
3625
|
}
|
|
3565
3626
|
async function loadZudokuConfig(configEnv, rootDir) {
|
|
3566
3627
|
const shouldReload = await hasConfigChanged();
|
|
3567
|
-
|
|
3568
|
-
|
|
3628
|
+
const existing = getConfig();
|
|
3629
|
+
if (!shouldReload && existing && envPrefix && publicEnv) {
|
|
3630
|
+
return { config: existing, envPrefix, publicEnv };
|
|
3569
3631
|
}
|
|
3570
3632
|
({ publicEnv, envPrefix } = loadEnv(configEnv, rootDir));
|
|
3571
3633
|
try {
|
|
3572
3634
|
const loadedConfig = await loadZudokuConfigWithMeta(rootDir);
|
|
3573
|
-
config = await runPluginTransformConfig(loadedConfig);
|
|
3635
|
+
const config = await runPluginTransformConfig(loadedConfig);
|
|
3636
|
+
setConfig(config);
|
|
3574
3637
|
logger.info(
|
|
3575
3638
|
colors2.cyan(`loaded config file `) + colors2.dim(config.__meta.configPath),
|
|
3576
3639
|
{ timestamp: true }
|
|
3577
3640
|
);
|
|
3578
3641
|
return { config, envPrefix, publicEnv };
|
|
3579
3642
|
} catch (error) {
|
|
3580
|
-
const
|
|
3581
|
-
if (
|
|
3582
|
-
|
|
3643
|
+
const lastValid = getConfig();
|
|
3644
|
+
if (lastValid) {
|
|
3645
|
+
logger.error(
|
|
3646
|
+
colors2.red("Failed to reload config, using last valid config."),
|
|
3647
|
+
{
|
|
3648
|
+
timestamp: true,
|
|
3649
|
+
error: error instanceof Error ? error : new Error(String(error))
|
|
3650
|
+
}
|
|
3651
|
+
);
|
|
3652
|
+
return { config: lastValid, envPrefix, publicEnv };
|
|
3583
3653
|
}
|
|
3584
|
-
throw
|
|
3654
|
+
throw error;
|
|
3585
3655
|
} finally {
|
|
3586
3656
|
await updateModifiedTimes();
|
|
3587
3657
|
}
|
|
3588
3658
|
}
|
|
3589
|
-
var
|
|
3659
|
+
var configStore, getConfig, setConfig, envPrefix, publicEnv, modifiedTimes, zudokuConfigFiles, virtualModuleStubPlugin, isFileSystemPath, getCurrentConfig;
|
|
3590
3660
|
var init_loader = __esm({
|
|
3591
3661
|
"src/config/loader.ts"() {
|
|
3592
3662
|
init_logger();
|
|
@@ -3595,6 +3665,11 @@ var init_loader = __esm({
|
|
|
3595
3665
|
init_invariant();
|
|
3596
3666
|
init_file_exists();
|
|
3597
3667
|
init_ZudokuConfig();
|
|
3668
|
+
configStore = globalThis;
|
|
3669
|
+
getConfig = () => configStore.__zudokuConfig;
|
|
3670
|
+
setConfig = (next) => {
|
|
3671
|
+
configStore.__zudokuConfig = next;
|
|
3672
|
+
};
|
|
3598
3673
|
zudokuConfigFiles = [
|
|
3599
3674
|
"zudoku.config.js",
|
|
3600
3675
|
"zudoku.config.jsx",
|
|
@@ -3611,7 +3686,9 @@ var init_loader = __esm({
|
|
|
3611
3686
|
if (id.startsWith("\0virtual:")) return "export default {}";
|
|
3612
3687
|
}
|
|
3613
3688
|
};
|
|
3689
|
+
isFileSystemPath = (p) => !p.startsWith("\0") && !p.includes("virtual:");
|
|
3614
3690
|
getCurrentConfig = () => {
|
|
3691
|
+
const config = getConfig();
|
|
3615
3692
|
invariant(config, "Config not loaded");
|
|
3616
3693
|
return config;
|
|
3617
3694
|
};
|
|
@@ -3808,25 +3885,25 @@ var getClerkFrontendApi = (publishableKey) => {
|
|
|
3808
3885
|
};
|
|
3809
3886
|
|
|
3810
3887
|
// src/lib/auth/issuer.ts
|
|
3811
|
-
var getIssuer = async (
|
|
3812
|
-
switch (
|
|
3888
|
+
var getIssuer = async (config) => {
|
|
3889
|
+
switch (config.authentication?.type) {
|
|
3813
3890
|
case "clerk": {
|
|
3814
|
-
return `https://${getClerkFrontendApi(
|
|
3891
|
+
return `https://${getClerkFrontendApi(config.authentication.clerkPubKey)}`;
|
|
3815
3892
|
}
|
|
3816
3893
|
case "auth0": {
|
|
3817
|
-
return `https://${
|
|
3894
|
+
return `https://${config.authentication.domain}/`;
|
|
3818
3895
|
}
|
|
3819
3896
|
case "openid": {
|
|
3820
|
-
return
|
|
3897
|
+
return config.authentication.issuer;
|
|
3821
3898
|
}
|
|
3822
3899
|
case "supabase": {
|
|
3823
|
-
return
|
|
3900
|
+
return config.authentication.supabaseUrl;
|
|
3824
3901
|
}
|
|
3825
3902
|
case "azureb2c": {
|
|
3826
|
-
return
|
|
3903
|
+
return config.authentication.issuer;
|
|
3827
3904
|
}
|
|
3828
3905
|
case "firebase": {
|
|
3829
|
-
return `https://securetoken.google.com/${
|
|
3906
|
+
return `https://securetoken.google.com/${config.authentication.projectId}`;
|
|
3830
3907
|
}
|
|
3831
3908
|
case void 0: {
|
|
3832
3909
|
return void 0;
|
|
@@ -3849,269 +3926,6 @@ import {
|
|
|
3849
3926
|
loadConfigFromFile,
|
|
3850
3927
|
mergeConfig as mergeConfig2
|
|
3851
3928
|
} from "vite";
|
|
3852
|
-
|
|
3853
|
-
// package.json
|
|
3854
|
-
var package_default = {
|
|
3855
|
-
name: "zudoku",
|
|
3856
|
-
version: "0.78.1",
|
|
3857
|
-
type: "module",
|
|
3858
|
-
sideEffects: [
|
|
3859
|
-
"**/*.css",
|
|
3860
|
-
"**/polyfills.ts"
|
|
3861
|
-
],
|
|
3862
|
-
homepage: "https://zudoku.dev",
|
|
3863
|
-
repository: {
|
|
3864
|
-
type: "git",
|
|
3865
|
-
url: "git+https://github.com/zuplo/zudoku.git"
|
|
3866
|
-
},
|
|
3867
|
-
bugs: {
|
|
3868
|
-
url: "https://github.com/zuplo/zudoku/issues"
|
|
3869
|
-
},
|
|
3870
|
-
description: "Framework for building high quality, interactive API documentation.",
|
|
3871
|
-
files: [
|
|
3872
|
-
"dist",
|
|
3873
|
-
"cli.js",
|
|
3874
|
-
"src",
|
|
3875
|
-
"client.d.ts",
|
|
3876
|
-
"docs"
|
|
3877
|
-
],
|
|
3878
|
-
bin: {
|
|
3879
|
-
zudoku: "./cli.js"
|
|
3880
|
-
},
|
|
3881
|
-
exports: {
|
|
3882
|
-
".": "./src/index.ts",
|
|
3883
|
-
"./package.json": "./package.json",
|
|
3884
|
-
"./ui/*": {
|
|
3885
|
-
types: "./src/lib/ui/*.tsx",
|
|
3886
|
-
default: "./src/lib/ui/*.tsx"
|
|
3887
|
-
},
|
|
3888
|
-
"./ui/*.js": {
|
|
3889
|
-
types: "./src/lib/ui/*.tsx",
|
|
3890
|
-
default: "./src/lib/ui/*.tsx"
|
|
3891
|
-
},
|
|
3892
|
-
"./client": {
|
|
3893
|
-
types: "./client.d.ts"
|
|
3894
|
-
},
|
|
3895
|
-
"./auth/clerk": "./src/lib/authentication/providers/clerk.tsx",
|
|
3896
|
-
"./auth/auth0": "./src/lib/authentication/providers/auth0.tsx",
|
|
3897
|
-
"./auth/openid": "./src/lib/authentication/providers/openid.tsx",
|
|
3898
|
-
"./auth/supabase": "./src/lib/authentication/providers/supabase.tsx",
|
|
3899
|
-
"./auth/azureb2c": "./src/lib/authentication/providers/azureb2c.tsx",
|
|
3900
|
-
"./auth/firebase": "./src/lib/authentication/providers/firebase.tsx",
|
|
3901
|
-
"./plugins": "./src/lib/core/plugins.ts",
|
|
3902
|
-
"./plugins/api-keys": "./src/lib/plugins/api-keys/index.tsx",
|
|
3903
|
-
"./plugins/markdown": "./src/lib/plugins/markdown/index.tsx",
|
|
3904
|
-
"./plugins/openapi": "./src/lib/plugins/openapi/index.tsx",
|
|
3905
|
-
"./plugins/custom-pages": "./src/lib/plugins/custom-pages/index.tsx",
|
|
3906
|
-
"./plugins/search-inkeep": "./src/lib/plugins/search-inkeep/index.tsx",
|
|
3907
|
-
"./plugins/search-pagefind": "./src/lib/plugins/search-pagefind/index.tsx",
|
|
3908
|
-
"./plugins/api-catalog": "./src/lib/plugins/api-catalog/index.tsx",
|
|
3909
|
-
"./components": "./src/lib/components/index.ts",
|
|
3910
|
-
"./mermaid": "./src/lib/components/Mermaid.tsx",
|
|
3911
|
-
"./router": "./src/lib/core/router.ts",
|
|
3912
|
-
"./react-query": "./src/lib/core/react-query.ts",
|
|
3913
|
-
"./icons": "./src/lib/icons.ts",
|
|
3914
|
-
"./vite": "./src/vite/index.ts",
|
|
3915
|
-
"./server": "./src/app/entry.server.tsx",
|
|
3916
|
-
"./server/adapters/lambda": "./src/app/adapters/lambda.ts",
|
|
3917
|
-
"./server/adapters/node": "./src/app/adapters/node.ts",
|
|
3918
|
-
"./server/adapters/vercel": "./src/app/adapters/vercel.ts",
|
|
3919
|
-
"./server/adapters/cloudflare": "./src/app/adapters/cloudflare.ts",
|
|
3920
|
-
"./app/*": "./src/app/*",
|
|
3921
|
-
"./hooks": "./src/lib/hooks/index.ts",
|
|
3922
|
-
"./processors/*": "./src/lib/plugins/openapi/processors/*.ts",
|
|
3923
|
-
"./with-zuplo": "./src/zuplo/with-zuplo.ts",
|
|
3924
|
-
"./testing": "./src/lib/testing/index.tsx"
|
|
3925
|
-
},
|
|
3926
|
-
scripts: {
|
|
3927
|
-
build: "esbuild src/cli/cli.ts src/vite/prerender/worker.ts --outdir=dist/cli --entry-names=[name] --bundle --format=esm --packages=external --target=node20 --platform=node --log-level=error",
|
|
3928
|
-
postbuild: "tsx scripts/check-external-deps.ts",
|
|
3929
|
-
typecheck: "tsc --project tsconfig.app.json --noEmit",
|
|
3930
|
-
"generate:types": "tsx scripts/generate-types.js && tsx scripts/generate-flat-config.js",
|
|
3931
|
-
"build:standalone": "vite build --mode standalone --config vite.standalone.config.ts --log-level=error",
|
|
3932
|
-
prepublishOnly: "tsx scripts/generate-publish-exports.ts && publint .",
|
|
3933
|
-
postpublish: "git checkout -- package.json",
|
|
3934
|
-
clean: "rm -rf dist",
|
|
3935
|
-
codegen: "graphql-codegen --config ./src/codegen.ts"
|
|
3936
|
-
},
|
|
3937
|
-
dependencies: {
|
|
3938
|
-
"@apidevtools/json-schema-ref-parser": "15.3.5",
|
|
3939
|
-
"@base-ui/react": "^1.4.1",
|
|
3940
|
-
"@envelop/core": "5.5.1",
|
|
3941
|
-
"@graphql-typed-document-node/core": "3.2.0",
|
|
3942
|
-
"@hono/node-server": "2.0.2",
|
|
3943
|
-
"@lekoarts/rehype-meta-as-attributes": "3.0.3",
|
|
3944
|
-
"@mdx-js/react": "3.1.1",
|
|
3945
|
-
"@mdx-js/rollup": "3.1.1",
|
|
3946
|
-
"@pothos/core": "4.12.0",
|
|
3947
|
-
"@radix-ui/react-accordion": "1.2.12",
|
|
3948
|
-
"@radix-ui/react-alert-dialog": "1.1.15",
|
|
3949
|
-
"@radix-ui/react-aspect-ratio": "1.1.8",
|
|
3950
|
-
"@radix-ui/react-checkbox": "1.3.3",
|
|
3951
|
-
"@radix-ui/react-collapsible": "1.1.12",
|
|
3952
|
-
"@radix-ui/react-dialog": "1.1.15",
|
|
3953
|
-
"@radix-ui/react-dropdown-menu": "2.1.16",
|
|
3954
|
-
"@radix-ui/react-hover-card": "1.1.15",
|
|
3955
|
-
"@radix-ui/react-label": "2.1.8",
|
|
3956
|
-
"@radix-ui/react-navigation-menu": "1.2.14",
|
|
3957
|
-
"@radix-ui/react-popover": "1.1.15",
|
|
3958
|
-
"@radix-ui/react-progress": "1.1.8",
|
|
3959
|
-
"@radix-ui/react-radio-group": "1.3.8",
|
|
3960
|
-
"@radix-ui/react-scroll-area": "1.2.10",
|
|
3961
|
-
"@radix-ui/react-select": "2.2.6",
|
|
3962
|
-
"@radix-ui/react-separator": "^1.1.8",
|
|
3963
|
-
"@radix-ui/react-slider": "1.3.6",
|
|
3964
|
-
"@radix-ui/react-slot": "1.2.4",
|
|
3965
|
-
"@radix-ui/react-switch": "1.2.6",
|
|
3966
|
-
"@radix-ui/react-tabs": "1.1.13",
|
|
3967
|
-
"@radix-ui/react-toggle": "1.1.10",
|
|
3968
|
-
"@radix-ui/react-toggle-group": "1.1.11",
|
|
3969
|
-
"@radix-ui/react-tooltip": "1.2.8",
|
|
3970
|
-
"@radix-ui/react-visually-hidden": "1.2.4",
|
|
3971
|
-
"@scalar/openapi-parser": "0.23.13",
|
|
3972
|
-
"@scalar/snippetz": "0.9.6",
|
|
3973
|
-
"@sentry/node": "10.52.0",
|
|
3974
|
-
"@shikijs/langs": "4.0.2",
|
|
3975
|
-
"@shikijs/rehype": "4.0.2",
|
|
3976
|
-
"@shikijs/themes": "4.0.2",
|
|
3977
|
-
"@shikijs/transformers": "4.0.2",
|
|
3978
|
-
"@tailwindcss/typography": "0.5.19",
|
|
3979
|
-
"@tailwindcss/vite": "4.2.2",
|
|
3980
|
-
"@tanem/react-nprogress": "6.0.3",
|
|
3981
|
-
"@tanstack/react-query": "5.97.0",
|
|
3982
|
-
"@types/react": "catalog:",
|
|
3983
|
-
"@types/react-dom": "catalog:",
|
|
3984
|
-
"@vitejs/plugin-react": "6.0.1",
|
|
3985
|
-
"@x0k/json-schema-merge": "1.0.2",
|
|
3986
|
-
"@zudoku/react-helmet-async": "2.0.5",
|
|
3987
|
-
"@zuplo/mcp": "0.0.32",
|
|
3988
|
-
bs58: "6.0.0",
|
|
3989
|
-
"class-variance-authority": "0.7.1",
|
|
3990
|
-
clsx: "2.1.1",
|
|
3991
|
-
cmdk: "1.1.1",
|
|
3992
|
-
dotenv: "17.3.1",
|
|
3993
|
-
"embla-carousel-react": "8.6.0",
|
|
3994
|
-
esbuild: "^0.28.0",
|
|
3995
|
-
"estree-util-is-identifier-name": "3.0.0",
|
|
3996
|
-
"estree-util-value-to-estree": "3.5.0",
|
|
3997
|
-
"fast-equals": "6.0.0",
|
|
3998
|
-
glob: "13.0.6",
|
|
3999
|
-
"glob-parent": "6.0.2",
|
|
4000
|
-
graphql: "16.14.0",
|
|
4001
|
-
"graphql-type-json": "0.3.2",
|
|
4002
|
-
"graphql-yoga": "5.18.0",
|
|
4003
|
-
"gray-matter": "4.0.3",
|
|
4004
|
-
"hast-util-heading-rank": "3.0.0",
|
|
4005
|
-
"hast-util-to-jsx-runtime": "2.3.6",
|
|
4006
|
-
"hast-util-to-string": "3.0.1",
|
|
4007
|
-
hono: "4.12.18",
|
|
4008
|
-
"http-terminator": "3.2.0",
|
|
4009
|
-
"javascript-stringify": "2.1.0",
|
|
4010
|
-
jose: "6.2.2",
|
|
4011
|
-
"json-schema-to-typescript-lite": "15.0.0",
|
|
4012
|
-
loglevel: "1.9.2",
|
|
4013
|
-
"lucide-react": "1.16.0",
|
|
4014
|
-
"mdast-util-from-markdown": "2.0.2",
|
|
4015
|
-
"mdast-util-mdx": "3.0.0",
|
|
4016
|
-
"mdast-util-mdx-jsx": "3.2.0",
|
|
4017
|
-
"micromark-extension-mdxjs": "3.0.0",
|
|
4018
|
-
motion: "12.38.0",
|
|
4019
|
-
nanoevents: "9.1.0",
|
|
4020
|
-
"next-themes": "0.4.6",
|
|
4021
|
-
oauth4webapi: "3.8.5",
|
|
4022
|
-
"openapi-types": "12.1.3",
|
|
4023
|
-
pagefind: "1.5.2",
|
|
4024
|
-
picocolors: "1.1.1",
|
|
4025
|
-
piscina: "5.1.4",
|
|
4026
|
-
"posthog-node": "5.33.4",
|
|
4027
|
-
"quick-lru": "7.3.0",
|
|
4028
|
-
"react-error-boundary": "6.1.1",
|
|
4029
|
-
"react-hook-form": "7.75.0",
|
|
4030
|
-
"react-is": "catalog:",
|
|
4031
|
-
"react-markdown": "10.1.0",
|
|
4032
|
-
"react-router": "7.14.1",
|
|
4033
|
-
"rehype-mdx-import-media": "1.4.0",
|
|
4034
|
-
"rehype-raw": "7.0.0",
|
|
4035
|
-
"rehype-slug": "6.0.0",
|
|
4036
|
-
"remark-comment": "1.0.0",
|
|
4037
|
-
"remark-directive": "3.0.1",
|
|
4038
|
-
"remark-directive-rehype": "1.0.0",
|
|
4039
|
-
"remark-frontmatter": "5.0.0",
|
|
4040
|
-
"remark-gfm": "4.0.1",
|
|
4041
|
-
"remark-mdx-frontmatter": "5.2.0",
|
|
4042
|
-
semver: "7.8.0",
|
|
4043
|
-
shiki: "4.0.2",
|
|
4044
|
-
sitemap: "9.0.1",
|
|
4045
|
-
"strip-ansi": "7.2.0",
|
|
4046
|
-
"tailwind-merge": "3.6.0",
|
|
4047
|
-
tailwindcss: "4.3.0",
|
|
4048
|
-
"tw-animate-css": "1.4.0",
|
|
4049
|
-
unified: "11.0.5",
|
|
4050
|
-
"unist-util-visit": "5.1.0",
|
|
4051
|
-
vaul: "1.1.2",
|
|
4052
|
-
vfile: "6.0.3",
|
|
4053
|
-
vite: "8.0.13",
|
|
4054
|
-
yaml: "2.8.4",
|
|
4055
|
-
yargs: "18.0.0",
|
|
4056
|
-
zod: "4.3.6",
|
|
4057
|
-
zustand: "5.0.13"
|
|
4058
|
-
},
|
|
4059
|
-
devDependencies: {
|
|
4060
|
-
"@graphql-codegen/cli": "7.0.0",
|
|
4061
|
-
"@inkeep/cxkit-types": "0.5.117",
|
|
4062
|
-
"@testing-library/dom": "catalog:",
|
|
4063
|
-
"@testing-library/jest-dom": "catalog:",
|
|
4064
|
-
"@testing-library/react": "catalog:",
|
|
4065
|
-
"@testing-library/user-event": "catalog:",
|
|
4066
|
-
"@types/estree": "1.0.9",
|
|
4067
|
-
"@types/glob-parent": "5.1.3",
|
|
4068
|
-
"@types/har-format": "^1.2.16",
|
|
4069
|
-
"@types/hast": "3.0.4",
|
|
4070
|
-
"@types/json-schema": "7.0.15",
|
|
4071
|
-
"@types/mdast": "4.0.4",
|
|
4072
|
-
"@types/mdx": "2.0.13",
|
|
4073
|
-
"@types/node": "catalog:",
|
|
4074
|
-
"@types/react-is": "catalog:",
|
|
4075
|
-
"@types/semver": "7.7.1",
|
|
4076
|
-
"@types/unist": "3.0.3",
|
|
4077
|
-
"@types/yargs": "17.0.35",
|
|
4078
|
-
"@vitest/coverage-v8": "4.0.18",
|
|
4079
|
-
"happy-dom": "catalog:",
|
|
4080
|
-
"oxc-parser": "^0.126.0",
|
|
4081
|
-
react: "catalog:",
|
|
4082
|
-
"react-dom": "catalog:",
|
|
4083
|
-
tsx: "4.21.0",
|
|
4084
|
-
typescript: "catalog:"
|
|
4085
|
-
},
|
|
4086
|
-
peerDependencies: {
|
|
4087
|
-
"@azure/msal-browser": "^4.13.0",
|
|
4088
|
-
"@sentry/react": "^10.0.0",
|
|
4089
|
-
"@supabase/supabase-js": "^2.49.4",
|
|
4090
|
-
firebase: "^12.6.0",
|
|
4091
|
-
mermaid: "^11.0.0",
|
|
4092
|
-
react: ">=19.2.0",
|
|
4093
|
-
"react-dom": ">=19.2.0"
|
|
4094
|
-
},
|
|
4095
|
-
peerDependenciesMeta: {
|
|
4096
|
-
"@azure/msal-browser": {
|
|
4097
|
-
optional: true
|
|
4098
|
-
},
|
|
4099
|
-
"@sentry/react": {
|
|
4100
|
-
optional: true
|
|
4101
|
-
},
|
|
4102
|
-
"@supabase/supabase-js": {
|
|
4103
|
-
optional: true
|
|
4104
|
-
},
|
|
4105
|
-
firebase: {
|
|
4106
|
-
optional: true
|
|
4107
|
-
},
|
|
4108
|
-
mermaid: {
|
|
4109
|
-
optional: true
|
|
4110
|
-
}
|
|
4111
|
-
}
|
|
4112
|
-
};
|
|
4113
|
-
|
|
4114
|
-
// src/vite/config.ts
|
|
4115
3929
|
init_logger();
|
|
4116
3930
|
init_package_json();
|
|
4117
3931
|
init_loader();
|
|
@@ -4130,22 +3944,22 @@ init_joinUrl();
|
|
|
4130
3944
|
var PROTECTED_CHUNK_DIR = "_protected";
|
|
4131
3945
|
var MANIFEST_VERSION = 1;
|
|
4132
3946
|
var MANIFEST_FILENAME = "zudoku-manifest.json";
|
|
4133
|
-
var buildManifest = (
|
|
4134
|
-
const protectedRoutes = ProtectedRoutesSchema.parse(
|
|
3947
|
+
var buildManifest = (config) => {
|
|
3948
|
+
const protectedRoutes = ProtectedRoutesSchema.parse(config.protectedRoutes);
|
|
4135
3949
|
const routePatterns = protectedRoutes ? Object.keys(protectedRoutes) : [];
|
|
4136
3950
|
return {
|
|
4137
3951
|
version: MANIFEST_VERSION,
|
|
4138
|
-
basePath:
|
|
3952
|
+
basePath: config.basePath ?? "/",
|
|
4139
3953
|
ssrEntry: "server/entry.js",
|
|
4140
3954
|
static: {
|
|
4141
|
-
prefixes: [joinUrl(
|
|
3955
|
+
prefixes: [joinUrl(config.basePath, "assets")]
|
|
4142
3956
|
},
|
|
4143
3957
|
protected: {
|
|
4144
|
-
chunkPrefix: joinUrl(
|
|
3958
|
+
chunkPrefix: joinUrl(config.basePath, PROTECTED_CHUNK_DIR),
|
|
4145
3959
|
routePatterns
|
|
4146
3960
|
},
|
|
4147
3961
|
auth: {
|
|
4148
|
-
sessionEndpoint: joinUrl(
|
|
3962
|
+
sessionEndpoint: joinUrl(config.basePath, "/__z/auth/session"),
|
|
4149
3963
|
cookies: {
|
|
4150
3964
|
access: ACCESS_TOKEN_COOKIE,
|
|
4151
3965
|
refresh: REFRESH_TOKEN_COOKIE,
|
|
@@ -4210,9 +4024,9 @@ async function collectStyleUrls(server, entries) {
|
|
|
4210
4024
|
var VIRTUAL_ENTRY = "virtual:ssr-css.css";
|
|
4211
4025
|
function vitePluginSsrCss(pluginOpts) {
|
|
4212
4026
|
let server;
|
|
4213
|
-
const
|
|
4027
|
+
const config = getCurrentConfig();
|
|
4214
4028
|
const virtualHref = path5.join(
|
|
4215
|
-
|
|
4029
|
+
config.basePath ?? "",
|
|
4216
4030
|
`/@id/__x00__${VIRTUAL_ENTRY}?direct`
|
|
4217
4031
|
);
|
|
4218
4032
|
const cssModuleMap = /* @__PURE__ */ new Map();
|
|
@@ -4320,8 +4134,8 @@ var viteApiKeysPlugin = () => {
|
|
|
4320
4134
|
},
|
|
4321
4135
|
async load(id) {
|
|
4322
4136
|
if (id === resolvedVirtualModuleId4) {
|
|
4323
|
-
const
|
|
4324
|
-
if (!
|
|
4137
|
+
const config = getCurrentConfig();
|
|
4138
|
+
if (!config.apiKeys?.enabled || config.__meta.mode === "standalone") {
|
|
4325
4139
|
return `export const configuredApiKeysPlugin = undefined;`;
|
|
4326
4140
|
}
|
|
4327
4141
|
const deploymentName = ZuploEnv.buildConfig?.deploymentName || getZuploSystemConfigurations(process.env.ZUPLO_SYSTEM_CONFIGURATIONS)?.__ZUPLO_DEPLOYMENT_NAME;
|
|
@@ -4397,8 +4211,8 @@ var getBuildConfig = async () => {
|
|
|
4397
4211
|
).then((m) => m.module.default);
|
|
4398
4212
|
return validateBuildConfig(buildModule);
|
|
4399
4213
|
};
|
|
4400
|
-
function validateBuildConfig(
|
|
4401
|
-
const validationResult = BuildConfigSchema2.safeParse(
|
|
4214
|
+
function validateBuildConfig(config) {
|
|
4215
|
+
const validationResult = BuildConfigSchema2.safeParse(config);
|
|
4402
4216
|
if (!validationResult.success) {
|
|
4403
4217
|
if (process.env.NODE_ENV === "production") {
|
|
4404
4218
|
throw new Error(z8.prettifyError(validationResult.error));
|
|
@@ -5718,11 +5532,11 @@ var SchemaManager = class {
|
|
|
5718
5532
|
config;
|
|
5719
5533
|
constructor({
|
|
5720
5534
|
storeDir,
|
|
5721
|
-
config
|
|
5535
|
+
config,
|
|
5722
5536
|
processors
|
|
5723
5537
|
}) {
|
|
5724
5538
|
this.storeDir = storeDir;
|
|
5725
|
-
this.config =
|
|
5539
|
+
this.config = config;
|
|
5726
5540
|
this.processors = [
|
|
5727
5541
|
({ schema: schema2 }) => upgrade(schema2).specification,
|
|
5728
5542
|
flattenAllOfProcessor,
|
|
@@ -5800,7 +5614,7 @@ var SchemaManager = class {
|
|
|
5800
5614
|
const existingSchema = schemas[index];
|
|
5801
5615
|
const schemaVersion = processedSchema.info.version ?? FALLBACK_VERSION;
|
|
5802
5616
|
const versionPath = existingSchema?.path && existingSchema.path.length > 0 ? existingSchema.path : paramsPath(params) || schemaVersion;
|
|
5803
|
-
const
|
|
5617
|
+
const config = ensureArray(this.config.apis ?? []).find(
|
|
5804
5618
|
(c) => c.path === configuredPath
|
|
5805
5619
|
);
|
|
5806
5620
|
const processed = {
|
|
@@ -5816,7 +5630,7 @@ var SchemaManager = class {
|
|
|
5816
5630
|
versionPath,
|
|
5817
5631
|
configuredPath,
|
|
5818
5632
|
params,
|
|
5819
|
-
|
|
5633
|
+
config?.options
|
|
5820
5634
|
),
|
|
5821
5635
|
processedJsonPath,
|
|
5822
5636
|
processedTime
|
|
@@ -5902,10 +5716,10 @@ var SchemaManager = class {
|
|
|
5902
5716
|
}
|
|
5903
5717
|
return map;
|
|
5904
5718
|
};
|
|
5905
|
-
createSchemaPath = (inputPath, versionPath, apiPath, params,
|
|
5719
|
+
createSchemaPath = (inputPath, versionPath, apiPath, params, config) => {
|
|
5906
5720
|
const suffix = paramsSuffix(params);
|
|
5907
5721
|
const extension = suffix ? ".json" : path7.extname(inputPath);
|
|
5908
|
-
const fileName =
|
|
5722
|
+
const fileName = config?.schemaDownload?.fileName ?? this.config.defaults?.apis?.schemaDownload?.fileName ?? "schema";
|
|
5909
5723
|
return joinUrl(
|
|
5910
5724
|
this.config.basePath,
|
|
5911
5725
|
apiPath,
|
|
@@ -5996,10 +5810,10 @@ var NavigationResolver = class {
|
|
|
5996
5810
|
globFiles = [];
|
|
5997
5811
|
items = [];
|
|
5998
5812
|
itemIndex = 0;
|
|
5999
|
-
constructor(
|
|
6000
|
-
this.rootDir =
|
|
6001
|
-
this.globPatterns = DocsConfigSchema.parse(
|
|
6002
|
-
this.items =
|
|
5813
|
+
constructor(config) {
|
|
5814
|
+
this.rootDir = config.__meta.rootDir;
|
|
5815
|
+
this.globPatterns = DocsConfigSchema.parse(config.docs ?? {}).files;
|
|
5816
|
+
this.items = config.navigation ?? [];
|
|
6003
5817
|
}
|
|
6004
5818
|
async initialize() {
|
|
6005
5819
|
if (this.globFiles.length > 0) return;
|
|
@@ -6066,6 +5880,9 @@ var NavigationResolver = class {
|
|
|
6066
5880
|
if (typeof item === "string") {
|
|
6067
5881
|
return this.resolveLink(item);
|
|
6068
5882
|
}
|
|
5883
|
+
if (item.type === "link") {
|
|
5884
|
+
return { type: "link", to: item.to, label: item.label };
|
|
5885
|
+
}
|
|
6069
5886
|
const doc = await this.resolveDoc(item.file);
|
|
6070
5887
|
return doc ? {
|
|
6071
5888
|
...item,
|
|
@@ -6153,11 +5970,11 @@ var viteNavigationPlugin = () => {
|
|
|
6153
5970
|
},
|
|
6154
5971
|
async load(id) {
|
|
6155
5972
|
if (id !== resolvedVirtualModuleId2) return;
|
|
6156
|
-
const
|
|
6157
|
-
const resolver = new NavigationResolver(
|
|
5973
|
+
const config = getCurrentConfig();
|
|
5974
|
+
const resolver = new NavigationResolver(config);
|
|
6158
5975
|
const resolvedNavigation = await resolver.resolve();
|
|
6159
5976
|
const resolvedRules = await resolver.resolveRules(
|
|
6160
|
-
|
|
5977
|
+
config.navigationRules ?? []
|
|
6161
5978
|
);
|
|
6162
5979
|
const collectedIcons = /* @__PURE__ */ new Set();
|
|
6163
5980
|
let hasMissingIcon = false;
|
|
@@ -6183,7 +6000,7 @@ var viteNavigationPlugin = () => {
|
|
|
6183
6000
|
2
|
|
6184
6001
|
);
|
|
6185
6002
|
const headerNavigationCode = stringifyWithIcons(
|
|
6186
|
-
|
|
6003
|
+
config.header?.navigation ?? []
|
|
6187
6004
|
);
|
|
6188
6005
|
const navigationCode = stringifyWithIcons(resolvedNavigation);
|
|
6189
6006
|
const rulesCode = stringifyWithIcons(resolvedRules);
|
|
@@ -6191,7 +6008,7 @@ var viteNavigationPlugin = () => {
|
|
|
6191
6008
|
invariant(navigationCode, "Failed to stringify navigation");
|
|
6192
6009
|
invariant(rulesCode, "Failed to stringify navigation rules");
|
|
6193
6010
|
await writePluginDebugCode(
|
|
6194
|
-
|
|
6011
|
+
config.__meta.rootDir,
|
|
6195
6012
|
"navigation-plugin",
|
|
6196
6013
|
`export const headerNavigation = ${headerNavigationCode};
|
|
6197
6014
|
export const navigation = ${navigationCode};
|
|
@@ -6294,8 +6111,24 @@ var viteApiPlugin = async () => {
|
|
|
6294
6111
|
const mainFiles = schemaManager.getFilesToReprocess(id);
|
|
6295
6112
|
if (mainFiles.length === 0) return;
|
|
6296
6113
|
console.log(`Re-processing schema ${id}`);
|
|
6297
|
-
|
|
6298
|
-
|
|
6114
|
+
try {
|
|
6115
|
+
for (const inputConfig of mainFiles) {
|
|
6116
|
+
await schemaManager.processSchema(inputConfig);
|
|
6117
|
+
}
|
|
6118
|
+
} catch (error) {
|
|
6119
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
6120
|
+
server.config.logger.error(
|
|
6121
|
+
`Failed to re-process schema ${id}. Fix the error and save again.`,
|
|
6122
|
+
{ error: err }
|
|
6123
|
+
);
|
|
6124
|
+
server.ws.send({
|
|
6125
|
+
type: "error",
|
|
6126
|
+
err: {
|
|
6127
|
+
message: `Failed to re-process schema ${id}: ${err.message}`,
|
|
6128
|
+
stack: err.stack ?? ""
|
|
6129
|
+
}
|
|
6130
|
+
});
|
|
6131
|
+
return;
|
|
6299
6132
|
}
|
|
6300
6133
|
schemaManager.getAllTrackedFiles().forEach((file) => server.watcher.add(file));
|
|
6301
6134
|
invalidate(server);
|
|
@@ -6309,13 +6142,13 @@ var viteApiPlugin = async () => {
|
|
|
6309
6142
|
},
|
|
6310
6143
|
async load(id) {
|
|
6311
6144
|
if (id !== resolvedVirtualModuleId4) return;
|
|
6312
|
-
const
|
|
6313
|
-
if (!deepEqual2(schemaManager.config.apis,
|
|
6314
|
-
schemaManager.config =
|
|
6145
|
+
const config = getCurrentConfig();
|
|
6146
|
+
if (!deepEqual2(schemaManager.config.apis, config.apis)) {
|
|
6147
|
+
schemaManager.config = config;
|
|
6315
6148
|
await schemaManager.processAllSchemas();
|
|
6316
6149
|
schemaManager.getAllTrackedFiles().forEach((file) => this.addWatchFile(file));
|
|
6317
6150
|
}
|
|
6318
|
-
if (
|
|
6151
|
+
if (config.__meta.mode === "standalone") {
|
|
6319
6152
|
return [
|
|
6320
6153
|
"export const configuredApiPlugins = [];",
|
|
6321
6154
|
"export const configuredApiCatalogPlugins = [];"
|
|
@@ -6326,12 +6159,12 @@ var viteApiPlugin = async () => {
|
|
|
6326
6159
|
`const configuredApiPlugins = [];`,
|
|
6327
6160
|
`const configuredApiCatalogPlugins = [];`
|
|
6328
6161
|
];
|
|
6329
|
-
if (
|
|
6162
|
+
if (config.apis) {
|
|
6330
6163
|
code.push('import { openApiPlugin } from "zudoku/plugins/openapi";');
|
|
6331
6164
|
code.push(
|
|
6332
6165
|
`const apis = Array.isArray(config.apis) ? config.apis : [config.apis]`
|
|
6333
6166
|
);
|
|
6334
|
-
const apis = ensureArray(
|
|
6167
|
+
const apis = ensureArray(config.apis);
|
|
6335
6168
|
const apiMetadata = [];
|
|
6336
6169
|
const httpMethods = /* @__PURE__ */ new Set([
|
|
6337
6170
|
"get",
|
|
@@ -6408,7 +6241,7 @@ var viteApiPlugin = async () => {
|
|
|
6408
6241
|
` disableSecurity: config.defaults?.apis?.disableSecurity ?? true,`,
|
|
6409
6242
|
` showVersionSelect: config.defaults?.apis?.showVersionSelect ?? "if-available",`,
|
|
6410
6243
|
` expandAllTags: config.defaults?.apis?.expandAllTags ?? true,`,
|
|
6411
|
-
` showInfoPage: config.defaults?.apis?.showInfoPage
|
|
6244
|
+
` showInfoPage: config.defaults?.apis?.showInfoPage,`,
|
|
6412
6245
|
` schemaDownload: config.defaults?.apis?.schemaDownload,`,
|
|
6413
6246
|
` transformExamples: config.defaults?.apis?.transformExamples,`,
|
|
6414
6247
|
` generateCodeSnippet: config.defaults?.apis?.generateCodeSnippet,`,
|
|
@@ -6433,7 +6266,7 @@ var viteApiPlugin = async () => {
|
|
|
6433
6266
|
` disableSecurity: config.defaults?.apis?.disableSecurity ?? true,`,
|
|
6434
6267
|
` showVersionSelect: config.defaults?.apis?.showVersionSelect ?? "if-available",`,
|
|
6435
6268
|
` expandAllTags: config.defaults?.apis?.expandAllTags ?? false,`,
|
|
6436
|
-
` showInfoPage: config.defaults?.apis?.showInfoPage
|
|
6269
|
+
` showInfoPage: config.defaults?.apis?.showInfoPage,`,
|
|
6437
6270
|
` schemaDownload: config.defaults?.apis?.schemaDownload,`,
|
|
6438
6271
|
` ...${JSON.stringify(apiConfig.options ?? {})},`,
|
|
6439
6272
|
" },",
|
|
@@ -6441,11 +6274,11 @@ var viteApiPlugin = async () => {
|
|
|
6441
6274
|
);
|
|
6442
6275
|
}
|
|
6443
6276
|
}
|
|
6444
|
-
if (
|
|
6277
|
+
if (config.catalogs) {
|
|
6445
6278
|
code.push(
|
|
6446
6279
|
'import { apiCatalogPlugin } from "zudoku/plugins/api-catalog";'
|
|
6447
6280
|
);
|
|
6448
|
-
const catalogs = ensureArray(
|
|
6281
|
+
const catalogs = ensureArray(config.catalogs);
|
|
6449
6282
|
const categories = apis.flatMap((api) => api.categories ?? []).reduce((acc, catalog) => {
|
|
6450
6283
|
if (!acc.has(catalog.label)) {
|
|
6451
6284
|
acc.set(catalog.label ?? "", new Set(catalog.tags));
|
|
@@ -6491,12 +6324,12 @@ var viteApiPlugin = async () => {
|
|
|
6491
6324
|
},
|
|
6492
6325
|
async closeBundle() {
|
|
6493
6326
|
if (this.environment.name === "ssr") return;
|
|
6494
|
-
const
|
|
6327
|
+
const config = getCurrentConfig();
|
|
6495
6328
|
const pathMap = schemaManager.getUrlToFilePathMap();
|
|
6496
6329
|
if (process.env.NODE_ENV !== "production") return;
|
|
6497
6330
|
for (const [urlPath, inputPath] of pathMap) {
|
|
6498
6331
|
const content = await fs2.readFile(inputPath, "utf-8");
|
|
6499
|
-
const outputPath = path11.join(
|
|
6332
|
+
const outputPath = path11.join(config.__meta.rootDir, "dist", urlPath);
|
|
6500
6333
|
await fs2.mkdir(path11.dirname(outputPath), { recursive: true });
|
|
6501
6334
|
await fs2.writeFile(outputPath, content, "utf-8");
|
|
6502
6335
|
}
|
|
@@ -6520,16 +6353,16 @@ var viteAuthPlugin = () => {
|
|
|
6520
6353
|
},
|
|
6521
6354
|
async load(id) {
|
|
6522
6355
|
if (id === resolvedVirtualModuleId4) {
|
|
6523
|
-
const
|
|
6524
|
-
if (!
|
|
6356
|
+
const config = getCurrentConfig();
|
|
6357
|
+
if (!config.authentication || config.__meta.mode === "standalone") {
|
|
6525
6358
|
return `export const configuredAuthProvider = undefined;`;
|
|
6526
6359
|
}
|
|
6527
6360
|
return [
|
|
6528
6361
|
`const config = {
|
|
6529
|
-
...${JSON.stringify(
|
|
6530
|
-
basePath: ${
|
|
6362
|
+
...${JSON.stringify(config.authentication, null, 2)},
|
|
6363
|
+
basePath: ${config.basePath ? JSON.stringify(config.basePath) : "undefined"},
|
|
6531
6364
|
};`,
|
|
6532
|
-
`import authProvider from "zudoku/auth/${
|
|
6365
|
+
`import authProvider from "zudoku/auth/${config.authentication.type}";`,
|
|
6533
6366
|
`export const configuredAuthProvider = authProvider(config);`
|
|
6534
6367
|
].join("\n");
|
|
6535
6368
|
}
|
|
@@ -6612,8 +6445,8 @@ var viteCustomPagesPlugin = () => {
|
|
|
6612
6445
|
},
|
|
6613
6446
|
async load(id) {
|
|
6614
6447
|
if (id === resolvedVirtualModuleId4) {
|
|
6615
|
-
const
|
|
6616
|
-
if (
|
|
6448
|
+
const config = getCurrentConfig();
|
|
6449
|
+
if (config.__meta.mode === "standalone" || !config.navigation) {
|
|
6617
6450
|
return `export const configuredCustomPagesPlugin = undefined;`;
|
|
6618
6451
|
}
|
|
6619
6452
|
const code = [
|
|
@@ -6640,9 +6473,9 @@ var viteDocMetadataPlugin = () => ({
|
|
|
6640
6473
|
enforce: "pre",
|
|
6641
6474
|
name: "zudoku-doc-metadata-plugin",
|
|
6642
6475
|
configureServer: async (server) => {
|
|
6643
|
-
const
|
|
6476
|
+
const config = getCurrentConfig();
|
|
6644
6477
|
const files = await glob2("**/*.{md,mdx}", {
|
|
6645
|
-
cwd:
|
|
6478
|
+
cwd: config.__meta.rootDir,
|
|
6646
6479
|
ignore: ["node_modules", "dist"],
|
|
6647
6480
|
absolute: true
|
|
6648
6481
|
});
|
|
@@ -6720,12 +6553,12 @@ var navigationListItem = cva(
|
|
|
6720
6553
|
// src/vite/plugin-docs.ts
|
|
6721
6554
|
init_joinUrl();
|
|
6722
6555
|
var ensureLeadingSlash = joinUrl;
|
|
6723
|
-
var globMarkdownFiles = async (
|
|
6724
|
-
const docsConfig = DocsConfigSchema.parse(
|
|
6556
|
+
var globMarkdownFiles = async (config, options = { absolute: false }) => {
|
|
6557
|
+
const docsConfig = DocsConfigSchema.parse(config.docs ?? {});
|
|
6725
6558
|
const fileMapping = {};
|
|
6726
6559
|
for (const globPattern of docsConfig.files) {
|
|
6727
6560
|
const globbedFiles = await glob3(globPattern, {
|
|
6728
|
-
root:
|
|
6561
|
+
root: config.__meta.rootDir,
|
|
6729
6562
|
ignore: ["**/node_modules/**", "**/dist/**", "**/.git/**"],
|
|
6730
6563
|
// Always glob with relative paths to avoid issues on different OS
|
|
6731
6564
|
absolute: false,
|
|
@@ -6736,7 +6569,7 @@ var globMarkdownFiles = async (config2, options = { absolute: false }) => {
|
|
|
6736
6569
|
if (process.env.NODE_ENV !== "development") {
|
|
6737
6570
|
const draftStatuses = await Promise.all(
|
|
6738
6571
|
globbedFiles.map(async (file) => {
|
|
6739
|
-
const absolutePath = path12.resolve(
|
|
6572
|
+
const absolutePath = path12.resolve(config.__meta.rootDir, file);
|
|
6740
6573
|
const { data } = await readFrontmatter(absolutePath);
|
|
6741
6574
|
return { file, isDraft: data.draft === true };
|
|
6742
6575
|
})
|
|
@@ -6751,32 +6584,32 @@ var globMarkdownFiles = async (config2, options = { absolute: false }) => {
|
|
|
6751
6584
|
}
|
|
6752
6585
|
const relativePath = path12.posix.relative(parent, file);
|
|
6753
6586
|
const routePath = ensureLeadingSlash(relativePath.replace(/\.mdx?$/, ""));
|
|
6754
|
-
const filePath = options.absolute ? path12.resolve(
|
|
6587
|
+
const filePath = options.absolute ? path12.resolve(config.__meta.rootDir, file) : file;
|
|
6755
6588
|
fileMapping[routePath] = filePath;
|
|
6756
6589
|
}
|
|
6757
6590
|
}
|
|
6758
6591
|
return fileMapping;
|
|
6759
6592
|
};
|
|
6760
|
-
var resolveCustomNavigationPaths = async (
|
|
6761
|
-
if (!
|
|
6762
|
-
const resolver = new NavigationResolver(
|
|
6593
|
+
var resolveCustomNavigationPaths = async (config, fileMapping) => {
|
|
6594
|
+
if (!config.navigation && !config.navigationRules) return fileMapping;
|
|
6595
|
+
const resolver = new NavigationResolver(config);
|
|
6763
6596
|
const mapping = { ...fileMapping };
|
|
6764
6597
|
const processItem = (item) => {
|
|
6765
|
-
const doc = item.type === "doc" ? { file: item.file, path: item.path } : item.type === "category" && item.link ? { file: item.link.file, path: item.link.path } : void 0;
|
|
6598
|
+
const doc = item.type === "doc" ? { file: item.file, path: item.path } : item.type === "category" && item.link?.type === "doc" ? { file: item.link.file, path: item.link.path } : void 0;
|
|
6766
6599
|
if (!doc || doc.path === doc.file) return;
|
|
6767
6600
|
const fileRoutePath = ensureLeadingSlash(doc.file.replace(/\.mdx?$/, ""));
|
|
6768
6601
|
const filePath = mapping[fileRoutePath];
|
|
6769
6602
|
if (!filePath) return;
|
|
6770
6603
|
const customPath = ensureLeadingSlash(doc.path);
|
|
6771
6604
|
mapping[customPath] = filePath;
|
|
6772
|
-
delete mapping[fileRoutePath];
|
|
6605
|
+
if (customPath !== fileRoutePath) delete mapping[fileRoutePath];
|
|
6773
6606
|
};
|
|
6774
|
-
if (
|
|
6607
|
+
if (config.navigation) {
|
|
6775
6608
|
const resolvedNavigation = await resolver.resolve();
|
|
6776
6609
|
traverseNavigation(resolvedNavigation, processItem);
|
|
6777
6610
|
}
|
|
6778
|
-
if (
|
|
6779
|
-
const resolvedRules = await resolver.resolveRules(
|
|
6611
|
+
if (config.navigationRules) {
|
|
6612
|
+
const resolvedRules = await resolver.resolveRules(config.navigationRules);
|
|
6780
6613
|
for (const rule of resolvedRules) {
|
|
6781
6614
|
if (rule.type === "insert") {
|
|
6782
6615
|
traverseNavigation(rule.items, processItem);
|
|
@@ -6797,17 +6630,17 @@ var viteDocsPlugin = () => {
|
|
|
6797
6630
|
},
|
|
6798
6631
|
async load(id) {
|
|
6799
6632
|
if (id !== resolvedVirtualModuleId4) return;
|
|
6800
|
-
const
|
|
6801
|
-
if (
|
|
6633
|
+
const config = getCurrentConfig();
|
|
6634
|
+
if (config.__meta.mode === "standalone") {
|
|
6802
6635
|
return `export const configuredDocsPlugin = undefined;`;
|
|
6803
6636
|
}
|
|
6804
6637
|
const code = [
|
|
6805
6638
|
'import { markdownPlugin } from "zudoku/plugins/markdown";'
|
|
6806
6639
|
];
|
|
6807
|
-
const docsConfig = DocsConfigSchema.parse(
|
|
6640
|
+
const docsConfig = DocsConfigSchema.parse(config.docs ?? {});
|
|
6808
6641
|
const fileMapping = await resolveCustomNavigationPaths(
|
|
6809
|
-
|
|
6810
|
-
await globMarkdownFiles(
|
|
6642
|
+
config,
|
|
6643
|
+
await globMarkdownFiles(config, { absolute: false })
|
|
6811
6644
|
);
|
|
6812
6645
|
const globbedDocuments = {};
|
|
6813
6646
|
for (const [routePath, file] of Object.entries(fileMapping)) {
|
|
@@ -6821,13 +6654,13 @@ var viteDocsPlugin = () => {
|
|
|
6821
6654
|
),
|
|
6822
6655
|
`};`,
|
|
6823
6656
|
`export const configuredDocsPlugin = markdownPlugin({`,
|
|
6824
|
-
` basePath: "${
|
|
6657
|
+
` basePath: "${config.basePath ?? ""}",`,
|
|
6825
6658
|
` fileImports,`,
|
|
6826
6659
|
` defaultOptions: ${JSON.stringify(docsConfig.defaultOptions)},`,
|
|
6827
6660
|
` publishMarkdown: ${JSON.stringify(docsConfig.publishMarkdown)},`,
|
|
6828
6661
|
`});`
|
|
6829
6662
|
);
|
|
6830
|
-
await writePluginDebugCode(
|
|
6663
|
+
await writePluginDebugCode(config.__meta.rootDir, "docs-plugin", code);
|
|
6831
6664
|
return code.join("\n");
|
|
6832
6665
|
}
|
|
6833
6666
|
};
|
|
@@ -6877,19 +6710,19 @@ var viteMarkdownExportPlugin = () => {
|
|
|
6877
6710
|
return env.name === "ssr";
|
|
6878
6711
|
},
|
|
6879
6712
|
async buildStart() {
|
|
6880
|
-
const
|
|
6881
|
-
const llmsConfig =
|
|
6882
|
-
const needsMdFiles =
|
|
6883
|
-
if (
|
|
6713
|
+
const config = getCurrentConfig();
|
|
6714
|
+
const llmsConfig = config.docs?.llms;
|
|
6715
|
+
const needsMdFiles = config.docs?.publishMarkdown || llmsConfig?.llmsTxt || llmsConfig?.llmsTxtFull;
|
|
6716
|
+
if (config.__meta.mode === "standalone" || !needsMdFiles) {
|
|
6884
6717
|
return;
|
|
6885
6718
|
}
|
|
6886
6719
|
markdownFiles = await resolveCustomNavigationPaths(
|
|
6887
|
-
|
|
6888
|
-
await globMarkdownFiles(
|
|
6720
|
+
config,
|
|
6721
|
+
await globMarkdownFiles(config, { absolute: true })
|
|
6889
6722
|
);
|
|
6890
6723
|
if (!llmsConfig?.includeProtected) {
|
|
6891
6724
|
const protectedRoutes = ProtectedRoutesSchema.parse(
|
|
6892
|
-
|
|
6725
|
+
config.protectedRoutes
|
|
6893
6726
|
);
|
|
6894
6727
|
if (protectedRoutes) {
|
|
6895
6728
|
const patterns = Object.keys(protectedRoutes);
|
|
@@ -6902,19 +6735,19 @@ var viteMarkdownExportPlugin = () => {
|
|
|
6902
6735
|
}
|
|
6903
6736
|
},
|
|
6904
6737
|
async configureServer(server) {
|
|
6905
|
-
const
|
|
6906
|
-
const llmsConfig =
|
|
6907
|
-
const needsMdFiles =
|
|
6738
|
+
const config = getCurrentConfig();
|
|
6739
|
+
const llmsConfig = config.docs?.llms;
|
|
6740
|
+
const needsMdFiles = config.docs?.publishMarkdown || llmsConfig?.llmsTxt || llmsConfig?.llmsTxtFull;
|
|
6908
6741
|
if (!needsMdFiles) return;
|
|
6909
6742
|
markdownFiles = await resolveCustomNavigationPaths(
|
|
6910
|
-
|
|
6911
|
-
await globMarkdownFiles(
|
|
6743
|
+
config,
|
|
6744
|
+
await globMarkdownFiles(config, { absolute: true })
|
|
6912
6745
|
);
|
|
6913
6746
|
server.middlewares.use(async (req, res, next) => {
|
|
6914
6747
|
if (req.method !== "GET" || !req.url?.endsWith(".md")) {
|
|
6915
6748
|
return next();
|
|
6916
6749
|
}
|
|
6917
|
-
const basePath = joinUrl(
|
|
6750
|
+
const basePath = joinUrl(config.basePath);
|
|
6918
6751
|
const routePath = resolveMarkdownRoutePath(req.url, basePath);
|
|
6919
6752
|
const filePath = markdownFiles[routePath];
|
|
6920
6753
|
if (!filePath) return next();
|
|
@@ -6929,16 +6762,16 @@ var viteMarkdownExportPlugin = () => {
|
|
|
6929
6762
|
});
|
|
6930
6763
|
},
|
|
6931
6764
|
async closeBundle() {
|
|
6932
|
-
const
|
|
6933
|
-
const llmsConfig =
|
|
6934
|
-
const needsMdFiles =
|
|
6765
|
+
const config = getCurrentConfig();
|
|
6766
|
+
const llmsConfig = config.docs?.llms;
|
|
6767
|
+
const needsMdFiles = config.docs?.publishMarkdown || llmsConfig?.llmsTxt || llmsConfig?.llmsTxtFull;
|
|
6935
6768
|
if (process.env.NODE_ENV !== "production" || Object.keys(markdownFiles).length === 0 || !needsMdFiles) {
|
|
6936
6769
|
return;
|
|
6937
6770
|
}
|
|
6938
6771
|
const distDir = path13.join(
|
|
6939
|
-
|
|
6772
|
+
config.__meta.rootDir,
|
|
6940
6773
|
"dist",
|
|
6941
|
-
|
|
6774
|
+
config.basePath ?? ""
|
|
6942
6775
|
);
|
|
6943
6776
|
markdownFileInfos = [];
|
|
6944
6777
|
for (const [routePath, filePath] of Object.entries(markdownFiles)) {
|
|
@@ -6962,9 +6795,9 @@ var viteMarkdownExportPlugin = () => {
|
|
|
6962
6795
|
console.warn(`Failed to export markdown for ${routePath}:`, error);
|
|
6963
6796
|
}
|
|
6964
6797
|
}
|
|
6965
|
-
if (
|
|
6798
|
+
if (config.docs?.llms?.llmsTxt || config.docs?.llms?.llmsTxtFull) {
|
|
6966
6799
|
const markdownInfoPath = path13.join(
|
|
6967
|
-
|
|
6800
|
+
config.__meta.rootDir,
|
|
6968
6801
|
"node_modules/.zudoku/markdown-info.json"
|
|
6969
6802
|
);
|
|
6970
6803
|
await writeFile2(
|
|
@@ -7382,12 +7215,12 @@ var rehypeExcerptWithMdxExport = () => (tree) => {
|
|
|
7382
7215
|
tree.children.unshift(exportMdxjsConst("excerpt", excerpt));
|
|
7383
7216
|
};
|
|
7384
7217
|
var viteMdxPlugin = async () => {
|
|
7385
|
-
const
|
|
7218
|
+
const config = getCurrentConfig();
|
|
7386
7219
|
const buildConfig = await getBuildConfig();
|
|
7387
7220
|
const highlighter = await highlighterPromise;
|
|
7388
7221
|
const defaultRemarkPlugins = [
|
|
7389
7222
|
remarkStaticGeneration,
|
|
7390
|
-
[remarkInjectFilepath,
|
|
7223
|
+
[remarkInjectFilepath, config.__meta.rootDir],
|
|
7391
7224
|
remarkComment,
|
|
7392
7225
|
remarkGfm,
|
|
7393
7226
|
remarkFrontmatter,
|
|
@@ -7399,9 +7232,9 @@ var viteMdxPlugin = async () => {
|
|
|
7399
7232
|
remarkDirective,
|
|
7400
7233
|
remarkDirectiveRehype,
|
|
7401
7234
|
remarkCodeTabs,
|
|
7402
|
-
[remarkLinkRewrite,
|
|
7403
|
-
[remarkNormalizeImageUrl,
|
|
7404
|
-
...
|
|
7235
|
+
[remarkLinkRewrite, config.basePath],
|
|
7236
|
+
[remarkNormalizeImageUrl, config.basePath],
|
|
7237
|
+
...config.build?.remarkPlugins ?? []
|
|
7405
7238
|
];
|
|
7406
7239
|
const remarkPlugins = typeof buildConfig?.remarkPlugins === "function" ? buildConfig.remarkPlugins(defaultRemarkPlugins) : [...defaultRemarkPlugins, ...buildConfig?.remarkPlugins ?? []];
|
|
7407
7240
|
const defaultRehypePlugins = [
|
|
@@ -7414,9 +7247,9 @@ var viteMdxPlugin = async () => {
|
|
|
7414
7247
|
rehypeMetaAsAttributes,
|
|
7415
7248
|
...createConfiguredShikiRehypePlugins(
|
|
7416
7249
|
highlighter,
|
|
7417
|
-
|
|
7250
|
+
config.syntaxHighlighting?.themes
|
|
7418
7251
|
),
|
|
7419
|
-
...
|
|
7252
|
+
...config.build?.rehypePlugins ?? []
|
|
7420
7253
|
];
|
|
7421
7254
|
const rehypePlugins = typeof buildConfig?.rehypePlugins === "function" ? buildConfig.rehypePlugins(defaultRehypePlugins) : [...defaultRehypePlugins, ...buildConfig?.rehypePlugins ?? []];
|
|
7422
7255
|
return {
|
|
@@ -7447,12 +7280,12 @@ var viteSearchPlugin = () => {
|
|
|
7447
7280
|
},
|
|
7448
7281
|
async load(id) {
|
|
7449
7282
|
if (id !== resolvedVirtualModuleId4) return;
|
|
7450
|
-
const
|
|
7451
|
-
if (!
|
|
7283
|
+
const config = getCurrentConfig();
|
|
7284
|
+
if (!config.search || config.__meta.mode === "standalone") {
|
|
7452
7285
|
return `export const configuredSearchPlugin = undefined;`;
|
|
7453
7286
|
}
|
|
7454
7287
|
const code = [];
|
|
7455
|
-
if (
|
|
7288
|
+
if (config.search.type === "inkeep") {
|
|
7456
7289
|
code.push(
|
|
7457
7290
|
`import config from 'virtual:zudoku-config';`,
|
|
7458
7291
|
`import { inkeepSearchPlugin } from "zudoku/plugins/search-inkeep";`,
|
|
@@ -7460,7 +7293,7 @@ var viteSearchPlugin = () => {
|
|
|
7460
7293
|
);
|
|
7461
7294
|
return code.join("\n");
|
|
7462
7295
|
}
|
|
7463
|
-
if (
|
|
7296
|
+
if (config.search.type === "pagefind") {
|
|
7464
7297
|
code.push(
|
|
7465
7298
|
`import config from 'virtual:zudoku-config';`,
|
|
7466
7299
|
`import { pagefindSearchPlugin } from "zudoku/plugins/search-pagefind";`,
|
|
@@ -7490,10 +7323,10 @@ var viteShikiPlugin = () => {
|
|
|
7490
7323
|
return {
|
|
7491
7324
|
name: "vite-plugin-shiki-register",
|
|
7492
7325
|
config() {
|
|
7493
|
-
const
|
|
7494
|
-
const languages =
|
|
7326
|
+
const config = getCurrentConfig();
|
|
7327
|
+
const languages = config.syntaxHighlighting?.languages ?? defaultLanguages;
|
|
7495
7328
|
const themes = Object.values(
|
|
7496
|
-
|
|
7329
|
+
config.syntaxHighlighting?.themes ?? defaultHighlightOptions.themes
|
|
7497
7330
|
);
|
|
7498
7331
|
const shikiIds = [
|
|
7499
7332
|
...languages.map((lang) => `@shikijs/langs/${resolveLang(lang)}`),
|
|
@@ -7516,10 +7349,10 @@ var viteShikiPlugin = () => {
|
|
|
7516
7349
|
},
|
|
7517
7350
|
async load(id) {
|
|
7518
7351
|
if (id !== resolvedVirtualModuleId4) return;
|
|
7519
|
-
const
|
|
7520
|
-
const languages =
|
|
7352
|
+
const config = getCurrentConfig();
|
|
7353
|
+
const languages = config.syntaxHighlighting?.languages ?? defaultLanguages;
|
|
7521
7354
|
const themes = Object.values(
|
|
7522
|
-
|
|
7355
|
+
config.syntaxHighlighting?.themes ?? defaultHighlightOptions.themes
|
|
7523
7356
|
);
|
|
7524
7357
|
const highlighter = await highlighterPromise;
|
|
7525
7358
|
await Promise.all([
|
|
@@ -7595,8 +7428,8 @@ var scopeMatchesPattern = (scope, pattern) => {
|
|
|
7595
7428
|
}
|
|
7596
7429
|
return matchPath2({ path: pattern, end: false }, root) != null;
|
|
7597
7430
|
};
|
|
7598
|
-
var getProtectedSourceMatcher = (
|
|
7599
|
-
const protectedRoutes = ProtectedRoutesSchema.parse(
|
|
7431
|
+
var getProtectedSourceMatcher = (config) => {
|
|
7432
|
+
const protectedRoutes = ProtectedRoutesSchema.parse(config.protectedRoutes);
|
|
7600
7433
|
const patterns = protectedRoutes ? Object.keys(protectedRoutes) : [];
|
|
7601
7434
|
if (patterns.length === 0) {
|
|
7602
7435
|
return { match: () => false, enabled: false, patterns };
|
|
@@ -7734,16 +7567,16 @@ var defineEnvVars = (vars) => Object.fromEntries(
|
|
|
7734
7567
|
])
|
|
7735
7568
|
);
|
|
7736
7569
|
async function getViteConfig(dir, configEnv, options = {}) {
|
|
7737
|
-
const { config
|
|
7570
|
+
const { config, publicEnv: publicEnv2, envPrefix: envPrefix2 } = await loadZudokuConfig(
|
|
7738
7571
|
configEnv,
|
|
7739
7572
|
dir
|
|
7740
7573
|
);
|
|
7741
|
-
const { match: isProtectedSource, enabled: hasProtectedSources } = getProtectedSourceMatcher(
|
|
7574
|
+
const { match: isProtectedSource, enabled: hasProtectedSources } = getProtectedSourceMatcher(config);
|
|
7742
7575
|
const shouldProtectChunks = hasProtectedSources && options.ssr === true;
|
|
7743
7576
|
const isProtectedChunk = (chunk) => chunk.facadeModuleId && isProtectedSource(chunk.facadeModuleId) || chunk.moduleIds.some(isProtectedSource);
|
|
7744
7577
|
const isWorker = options.adapter === "cloudflare";
|
|
7745
|
-
const cdnUrl = CdnUrlSchema.parse(
|
|
7746
|
-
const base = cdnUrl?.base ? joinUrl(cdnUrl.base,
|
|
7578
|
+
const cdnUrl = CdnUrlSchema.parse(config.cdnUrl);
|
|
7579
|
+
const base = cdnUrl?.base ? joinUrl(cdnUrl.base, config.basePath) : config.basePath;
|
|
7747
7580
|
if (cdnUrl && !hasLoggedCdnInfo) {
|
|
7748
7581
|
logger.info(colors4.blue(`Using CDN URL:`));
|
|
7749
7582
|
logger.info(colors4.blue(` base: `) + colors4.dim(cdnUrl.base));
|
|
@@ -7758,7 +7591,7 @@ async function getViteConfig(dir, configEnv, options = {}) {
|
|
|
7758
7591
|
);
|
|
7759
7592
|
if (ZuploEnv.isZuplo) {
|
|
7760
7593
|
dotenv.config({
|
|
7761
|
-
path: path16.resolve(
|
|
7594
|
+
path: path16.resolve(config.__meta.rootDir, "../.env.zuplo"),
|
|
7762
7595
|
quiet: true
|
|
7763
7596
|
});
|
|
7764
7597
|
}
|
|
@@ -7783,7 +7616,9 @@ async function getViteConfig(dir, configEnv, options = {}) {
|
|
|
7783
7616
|
}
|
|
7784
7617
|
},
|
|
7785
7618
|
define: {
|
|
7786
|
-
"process.env.ZUDOKU_VERSION": JSON.stringify(
|
|
7619
|
+
"process.env.ZUDOKU_VERSION": JSON.stringify(
|
|
7620
|
+
getZudokuPackageJson().version
|
|
7621
|
+
),
|
|
7787
7622
|
"process.env.IS_ZUPLO": ZuploEnv.isZuplo,
|
|
7788
7623
|
"import.meta.env.IS_ZUPLO": ZuploEnv.isZuplo,
|
|
7789
7624
|
"import.meta.env.ZUDOKU_HAS_SERVER": JSON.stringify(options.ssr === true),
|
|
@@ -7807,8 +7642,8 @@ async function getViteConfig(dir, configEnv, options = {}) {
|
|
|
7807
7642
|
`${dir}/dist`,
|
|
7808
7643
|
`${dir}/lib`,
|
|
7809
7644
|
`${dir}/.git`,
|
|
7810
|
-
`${
|
|
7811
|
-
`${
|
|
7645
|
+
`${config.__meta.moduleDir}/src/vite`,
|
|
7646
|
+
`${config.__meta.moduleDir}/src/cli`
|
|
7812
7647
|
]
|
|
7813
7648
|
}
|
|
7814
7649
|
},
|
|
@@ -7816,10 +7651,10 @@ async function getViteConfig(dir, configEnv, options = {}) {
|
|
|
7816
7651
|
sourcemap: true,
|
|
7817
7652
|
target: "es2022",
|
|
7818
7653
|
chunkSizeWarningLimit: 1500,
|
|
7819
|
-
outDir: path16.resolve(path16.join(dir, "dist",
|
|
7654
|
+
outDir: path16.resolve(path16.join(dir, "dist", config.basePath ?? "")),
|
|
7820
7655
|
emptyOutDir: false,
|
|
7821
7656
|
rolldownOptions: {
|
|
7822
|
-
external: [joinUrl(
|
|
7657
|
+
external: [joinUrl(config.basePath, "/pagefind/pagefind.js")],
|
|
7823
7658
|
logLevel: process.env.ZUDOKU_ENV === "internal" ? "info" : "warn",
|
|
7824
7659
|
checks: {
|
|
7825
7660
|
pluginTimings: process.env.ZUDOKU_ENV === "internal"
|
|
@@ -7847,12 +7682,12 @@ async function getViteConfig(dir, configEnv, options = {}) {
|
|
|
7847
7682
|
},
|
|
7848
7683
|
build: {
|
|
7849
7684
|
outDir: path16.resolve(
|
|
7850
|
-
path16.join(dir, "dist",
|
|
7685
|
+
path16.join(dir, "dist", config.basePath ?? "", "server")
|
|
7851
7686
|
),
|
|
7852
7687
|
copyPublicDir: false,
|
|
7853
7688
|
rolldownOptions: {
|
|
7854
7689
|
logLevel: "warn",
|
|
7855
|
-
input: ["zudoku/app/entry.server.tsx",
|
|
7690
|
+
input: ["zudoku/app/entry.server.tsx", config.__meta.configPath]
|
|
7856
7691
|
}
|
|
7857
7692
|
}
|
|
7858
7693
|
}
|
|
@@ -7860,7 +7695,7 @@ async function getViteConfig(dir, configEnv, options = {}) {
|
|
|
7860
7695
|
experimental: {
|
|
7861
7696
|
renderBuiltUrl(filename) {
|
|
7862
7697
|
if (filename.startsWith(`${PROTECTED_CHUNK_DIR}/`)) {
|
|
7863
|
-
return joinUrl(
|
|
7698
|
+
return joinUrl(config.basePath, `/${filename}`);
|
|
7864
7699
|
}
|
|
7865
7700
|
if (cdnUrl?.base && [".js", ".css"].includes(path16.extname(filename))) {
|
|
7866
7701
|
return joinUrl(cdnUrl.base, filename);
|
|
@@ -7899,7 +7734,7 @@ async function getViteConfig(dir, configEnv, options = {}) {
|
|
|
7899
7734
|
}
|
|
7900
7735
|
};
|
|
7901
7736
|
const configRoots = await Promise.all(
|
|
7902
|
-
(
|
|
7737
|
+
(config.__pluginDirs ?? []).map(findPackageRoot)
|
|
7903
7738
|
);
|
|
7904
7739
|
configRoots.push(dir);
|
|
7905
7740
|
let mergedViteConfig = viteConfig;
|
|
@@ -7935,7 +7770,6 @@ function getDevHtml({
|
|
|
7935
7770
|
<head>
|
|
7936
7771
|
<meta charset="UTF-8" />
|
|
7937
7772
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
|
|
7938
|
-
<!--app-helmet-->
|
|
7939
7773
|
<link rel="preconnect" href="https://cdn.zudoku.dev/">
|
|
7940
7774
|
</head>
|
|
7941
7775
|
<body>
|
|
@@ -7959,7 +7793,6 @@ function getBuildHtml({
|
|
|
7959
7793
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
|
|
7960
7794
|
<script type="module" crossorigin src="${jsEntry}"></script>
|
|
7961
7795
|
${cssLinks}
|
|
7962
|
-
<!--app-helmet-->
|
|
7963
7796
|
<link rel="preconnect" href="https://cdn.zudoku.dev/">
|
|
7964
7797
|
</head>
|
|
7965
7798
|
<body>
|
|
@@ -7972,10 +7805,10 @@ ${cssLinks}
|
|
|
7972
7805
|
// src/vite/manifest.ts
|
|
7973
7806
|
import { writeFile as writeFile3 } from "node:fs/promises";
|
|
7974
7807
|
import path17 from "node:path";
|
|
7975
|
-
var writeManifest = async (distDir,
|
|
7808
|
+
var writeManifest = async (distDir, config) => {
|
|
7976
7809
|
await writeFile3(
|
|
7977
7810
|
path17.join(distDir, MANIFEST_FILENAME),
|
|
7978
|
-
`${JSON.stringify(buildManifest(
|
|
7811
|
+
`${JSON.stringify(buildManifest(config), null, 2)}
|
|
7979
7812
|
`,
|
|
7980
7813
|
"utf-8"
|
|
7981
7814
|
);
|
|
@@ -7989,7 +7822,7 @@ import { cp, mkdir as mkdir3, writeFile as writeFile4 } from "node:fs/promises";
|
|
|
7989
7822
|
import path18 from "node:path";
|
|
7990
7823
|
var pkgJson = getZudokuPackageJson();
|
|
7991
7824
|
function generateOutput({
|
|
7992
|
-
config
|
|
7825
|
+
config,
|
|
7993
7826
|
redirects,
|
|
7994
7827
|
rewrites = []
|
|
7995
7828
|
}) {
|
|
@@ -8014,7 +7847,7 @@ function generateOutput({
|
|
|
8014
7847
|
}
|
|
8015
7848
|
],
|
|
8016
7849
|
headers: {
|
|
8017
|
-
"Set-Cookie": `__vdpl=${process.env.VERCEL_DEPLOYMENT_ID}; Path=${joinUrl(
|
|
7850
|
+
"Set-Cookie": `__vdpl=${process.env.VERCEL_DEPLOYMENT_ID}; Path=${joinUrl(config.basePath)}; SameSite=Strict; Secure; HttpOnly`
|
|
8018
7851
|
},
|
|
8019
7852
|
continue: true
|
|
8020
7853
|
});
|
|
@@ -8023,8 +7856,8 @@ function generateOutput({
|
|
|
8023
7856
|
routes.push({ handle: "filesystem" });
|
|
8024
7857
|
for (const rewrite of rewrites) {
|
|
8025
7858
|
routes.push({
|
|
8026
|
-
src: joinUrl(
|
|
8027
|
-
dest: joinUrl(
|
|
7859
|
+
src: joinUrl(config.basePath, rewrite.source),
|
|
7860
|
+
dest: joinUrl(config.basePath, rewrite.destination)
|
|
8028
7861
|
});
|
|
8029
7862
|
}
|
|
8030
7863
|
}
|
|
@@ -8038,11 +7871,11 @@ function generateOutput({
|
|
|
8038
7871
|
return output;
|
|
8039
7872
|
}
|
|
8040
7873
|
async function writeOutput(dir, {
|
|
8041
|
-
config
|
|
7874
|
+
config,
|
|
8042
7875
|
redirects,
|
|
8043
7876
|
rewrites
|
|
8044
7877
|
}) {
|
|
8045
|
-
const output = generateOutput({ config
|
|
7878
|
+
const output = generateOutput({ config, redirects, rewrites });
|
|
8046
7879
|
const outputDir = process.env.VERCEL ? path18.join(dir, ".vercel/output") : path18.join(dir, "dist/.output");
|
|
8047
7880
|
await mkdir3(outputDir, { recursive: true });
|
|
8048
7881
|
const outputFile = path18.join(outputDir, "config.json");
|
|
@@ -8107,14 +7940,14 @@ async function generateSitemap({
|
|
|
8107
7940
|
outputUrls,
|
|
8108
7941
|
basePath,
|
|
8109
7942
|
baseOutputDir,
|
|
8110
|
-
config
|
|
7943
|
+
config,
|
|
8111
7944
|
redirectUrls
|
|
8112
7945
|
}) {
|
|
8113
|
-
if (!
|
|
7946
|
+
if (!config) {
|
|
8114
7947
|
return;
|
|
8115
7948
|
}
|
|
8116
|
-
const sitemap = new SitemapStream({ hostname:
|
|
8117
|
-
const outputDir = path19.resolve(baseOutputDir,
|
|
7949
|
+
const sitemap = new SitemapStream({ hostname: config.siteUrl });
|
|
7950
|
+
const outputDir = path19.resolve(baseOutputDir, config.outDir ?? "");
|
|
8118
7951
|
if (!existsSync(outputDir)) {
|
|
8119
7952
|
await mkdir4(outputDir, { recursive: true });
|
|
8120
7953
|
}
|
|
@@ -8122,18 +7955,18 @@ async function generateSitemap({
|
|
|
8122
7955
|
const writeStream = createWriteStream(sitemapOutputPath);
|
|
8123
7956
|
sitemap.pipe(writeStream);
|
|
8124
7957
|
let lastmod;
|
|
8125
|
-
if (
|
|
7958
|
+
if (config.autoLastmod !== false) {
|
|
8126
7959
|
lastmod = (/* @__PURE__ */ new Date()).toISOString();
|
|
8127
7960
|
}
|
|
8128
|
-
const exclude = (typeof
|
|
7961
|
+
const exclude = (typeof config.exclude === "function" ? await config.exclude() : config.exclude) ?? [];
|
|
8129
7962
|
for (const url of outputUrls) {
|
|
8130
7963
|
const shouldExclude = exclude.includes(url) || url.includes("*") || /(400|404|500)$/.test(url) || redirectUrls.has(url);
|
|
8131
7964
|
if (shouldExclude) continue;
|
|
8132
7965
|
sitemap.write({
|
|
8133
|
-
url: new URL(joinUrl(basePath, url),
|
|
7966
|
+
url: new URL(joinUrl(basePath, url), config.siteUrl).toString(),
|
|
8134
7967
|
lastmod,
|
|
8135
|
-
changefreq:
|
|
8136
|
-
priority:
|
|
7968
|
+
changefreq: config.changefreq ?? "daily",
|
|
7969
|
+
priority: config.priority ?? 0.7
|
|
8137
7970
|
});
|
|
8138
7971
|
}
|
|
8139
7972
|
sitemap.end();
|
|
@@ -8214,15 +8047,15 @@ var prerender = async ({
|
|
|
8214
8047
|
const rawConfig = await import(serverConfigPath).then(
|
|
8215
8048
|
(m) => m.default
|
|
8216
8049
|
);
|
|
8217
|
-
const
|
|
8050
|
+
const config = await runPluginTransformConfig(rawConfig);
|
|
8218
8051
|
const buildConfig = await getBuildConfig();
|
|
8219
8052
|
const module = await import(entryServerPath);
|
|
8220
8053
|
const getRoutes = module.getRoutesByConfig;
|
|
8221
|
-
const routes = getRoutes(
|
|
8054
|
+
const routes = getRoutes(config);
|
|
8222
8055
|
const paths = routesToPaths(routes);
|
|
8223
8056
|
const rewrites = routesToRewrites(routes);
|
|
8224
|
-
if (
|
|
8225
|
-
for (const r of
|
|
8057
|
+
if (config.redirects) {
|
|
8058
|
+
for (const r of config.redirects) {
|
|
8226
8059
|
paths.push(joinUrl(r.from));
|
|
8227
8060
|
}
|
|
8228
8061
|
}
|
|
@@ -8246,7 +8079,7 @@ var prerender = async ({
|
|
|
8246
8079
|
}
|
|
8247
8080
|
let completedCount = 0;
|
|
8248
8081
|
let pagefindIndex;
|
|
8249
|
-
if (
|
|
8082
|
+
if (config.search?.type === "pagefind") {
|
|
8250
8083
|
const { index, errors } = await createIndex();
|
|
8251
8084
|
invariant(
|
|
8252
8085
|
index,
|
|
@@ -8332,18 +8165,18 @@ var prerender = async ({
|
|
|
8332
8165
|
);
|
|
8333
8166
|
}
|
|
8334
8167
|
}
|
|
8335
|
-
const redirectUrls = getRedirectUrls(workerResults,
|
|
8168
|
+
const redirectUrls = getRedirectUrls(workerResults, config.basePath);
|
|
8336
8169
|
await generateSitemap({
|
|
8337
|
-
basePath:
|
|
8170
|
+
basePath: config.basePath,
|
|
8338
8171
|
outputUrls: paths,
|
|
8339
|
-
config:
|
|
8172
|
+
config: config.sitemap,
|
|
8340
8173
|
baseOutputDir: distDir,
|
|
8341
8174
|
redirectUrls
|
|
8342
8175
|
});
|
|
8343
|
-
if (
|
|
8176
|
+
if (config.docs) {
|
|
8344
8177
|
const { DocsConfigSchema: DocsConfigSchema2 } = await Promise.resolve().then(() => (init_ZudokuConfig(), ZudokuConfig_exports));
|
|
8345
8178
|
const { generateLlmsTxtFiles: generateLlmsTxtFiles2 } = await Promise.resolve().then(() => (init_llms(), llms_exports));
|
|
8346
|
-
const docsConfig = DocsConfigSchema2.parse(
|
|
8179
|
+
const docsConfig = DocsConfigSchema2.parse(config.docs);
|
|
8347
8180
|
const llmsConfig = docsConfig.llms ?? {};
|
|
8348
8181
|
const markdownInfoPath = path21.join(
|
|
8349
8182
|
dir,
|
|
@@ -8357,10 +8190,10 @@ var prerender = async ({
|
|
|
8357
8190
|
if (llmsConfig.llmsTxt || llmsConfig.llmsTxtFull) {
|
|
8358
8191
|
await generateLlmsTxtFiles2({
|
|
8359
8192
|
markdownFileInfos,
|
|
8360
|
-
basePath:
|
|
8193
|
+
basePath: config.basePath,
|
|
8361
8194
|
outputUrls: paths,
|
|
8362
8195
|
baseOutputDir: distDir,
|
|
8363
|
-
siteName:
|
|
8196
|
+
siteName: config.site?.title,
|
|
8364
8197
|
llmsTxt: llmsConfig.llmsTxt,
|
|
8365
8198
|
llmsTxtFull: llmsConfig.llmsTxtFull,
|
|
8366
8199
|
redirectUrls
|
|
@@ -8432,8 +8265,8 @@ var getContainerMemoryLimitMb = () => {
|
|
|
8432
8265
|
import { mkdir as mkdir5, readdir, readFile as readFile3, rename, rm as rm2 } from "node:fs/promises";
|
|
8433
8266
|
import path22 from "node:path";
|
|
8434
8267
|
init_joinUrl();
|
|
8435
|
-
var assertProtectedPatternsCovered = (
|
|
8436
|
-
const { patterns } = getProtectedSourceMatcher(
|
|
8268
|
+
var assertProtectedPatternsCovered = (config) => {
|
|
8269
|
+
const { patterns } = getProtectedSourceMatcher(config);
|
|
8437
8270
|
const unmatched = findUnmatchedProtectedPatterns(patterns);
|
|
8438
8271
|
if (unmatched.length === 0) return;
|
|
8439
8272
|
throw new Error(
|
|
@@ -8509,10 +8342,10 @@ These would be served publicly. Aborting build.`
|
|
|
8509
8342
|
}
|
|
8510
8343
|
await rm2(srcDir, { recursive: true, force: true });
|
|
8511
8344
|
};
|
|
8512
|
-
var assertCloudflareWranglerGatesProtected = async (dir,
|
|
8513
|
-
const { enabled } = getProtectedSourceMatcher(
|
|
8345
|
+
var assertCloudflareWranglerGatesProtected = async (dir, config) => {
|
|
8346
|
+
const { enabled } = getProtectedSourceMatcher(config);
|
|
8514
8347
|
if (!enabled) return;
|
|
8515
|
-
const protectedPrefix = `${joinUrl(
|
|
8348
|
+
const protectedPrefix = `${joinUrl(config.basePath, PROTECTED_CHUNK_DIR)}/`;
|
|
8516
8349
|
const candidates = ["wrangler.toml", "wrangler.jsonc", "wrangler.json"];
|
|
8517
8350
|
for (const name of candidates) {
|
|
8518
8351
|
const file = await readFile3(path22.join(dir, name), "utf-8").catch(
|
|
@@ -8557,7 +8390,7 @@ async function runBuild(options) {
|
|
|
8557
8390
|
serverResult && !Array.isArray(serverResult) && "output" in serverResult,
|
|
8558
8391
|
"SSR build failed to produce valid output"
|
|
8559
8392
|
);
|
|
8560
|
-
const { config
|
|
8393
|
+
const { config } = await loadZudokuConfig(
|
|
8561
8394
|
{ mode: "production", command: "build" },
|
|
8562
8395
|
dir
|
|
8563
8396
|
);
|
|
@@ -8576,7 +8409,7 @@ async function runBuild(options) {
|
|
|
8576
8409
|
const html = getBuildHtml({
|
|
8577
8410
|
jsEntry: joinUrl(base, jsEntry),
|
|
8578
8411
|
cssEntries: cssEntries.map((css) => joinUrl(base, css)),
|
|
8579
|
-
dir:
|
|
8412
|
+
dir: config.site?.dir
|
|
8580
8413
|
});
|
|
8581
8414
|
if (ssr) {
|
|
8582
8415
|
await bundleSSREntry({
|
|
@@ -8585,12 +8418,12 @@ async function runBuild(options) {
|
|
|
8585
8418
|
serverOutDir,
|
|
8586
8419
|
html
|
|
8587
8420
|
});
|
|
8588
|
-
assertProtectedPatternsCovered(
|
|
8421
|
+
assertProtectedPatternsCovered(config);
|
|
8589
8422
|
assertNoProtectedLeaks(clientResult.output);
|
|
8590
8423
|
if (adapter !== "cloudflare") {
|
|
8591
8424
|
await moveProtectedChunks(clientOutDir, serverOutDir);
|
|
8592
8425
|
} else {
|
|
8593
|
-
await assertCloudflareWranglerGatesProtected(dir,
|
|
8426
|
+
await assertCloudflareWranglerGatesProtected(dir, config);
|
|
8594
8427
|
}
|
|
8595
8428
|
await writeFile6(
|
|
8596
8429
|
path23.join(distDir, "package.json"),
|
|
@@ -8598,12 +8431,12 @@ async function runBuild(options) {
|
|
|
8598
8431
|
`,
|
|
8599
8432
|
"utf-8"
|
|
8600
8433
|
);
|
|
8601
|
-
await writeManifest(distDir,
|
|
8434
|
+
await writeManifest(distDir, config);
|
|
8602
8435
|
await rm3(path23.join(clientOutDir, "index.html"), { force: true });
|
|
8603
8436
|
} else {
|
|
8604
8437
|
await runPrerender({
|
|
8605
8438
|
dir,
|
|
8606
|
-
config
|
|
8439
|
+
config,
|
|
8607
8440
|
html,
|
|
8608
8441
|
clientOutDir,
|
|
8609
8442
|
serverOutDir,
|
|
@@ -8619,14 +8452,14 @@ var findServerConfigFilename = (result) => {
|
|
|
8619
8452
|
return entry.fileName;
|
|
8620
8453
|
};
|
|
8621
8454
|
var runPrerender = async (options) => {
|
|
8622
|
-
const { dir, config
|
|
8623
|
-
const issuer = await getIssuer(
|
|
8455
|
+
const { dir, config, html, clientOutDir, serverOutDir, serverResult } = options;
|
|
8456
|
+
const issuer = await getIssuer(config);
|
|
8624
8457
|
const serverConfigFilename = findServerConfigFilename(serverResult);
|
|
8625
8458
|
try {
|
|
8626
8459
|
const { workerResults, rewrites } = await prerender({
|
|
8627
8460
|
html,
|
|
8628
8461
|
dir,
|
|
8629
|
-
basePath:
|
|
8462
|
+
basePath: config.basePath,
|
|
8630
8463
|
serverConfigFilename,
|
|
8631
8464
|
writeRedirects: process.env.VERCEL === void 0
|
|
8632
8465
|
});
|
|
@@ -8652,12 +8485,12 @@ var runPrerender = async (options) => {
|
|
|
8652
8485
|
);
|
|
8653
8486
|
}
|
|
8654
8487
|
await writeOutput(dir, {
|
|
8655
|
-
config
|
|
8488
|
+
config,
|
|
8656
8489
|
redirects: workerResults.flatMap((r) => r.redirect ?? []),
|
|
8657
8490
|
rewrites
|
|
8658
8491
|
});
|
|
8659
8492
|
if (ZuploEnv.isZuplo && issuer) {
|
|
8660
|
-
const provider =
|
|
8493
|
+
const provider = config.authentication?.type;
|
|
8661
8494
|
await writeFile6(
|
|
8662
8495
|
path23.join(dir, DIST_DIR, ".output/zuplo.json"),
|
|
8663
8496
|
JSON.stringify({ issuer, provider }, null, 2),
|
|
@@ -8959,6 +8792,7 @@ import fs3 from "node:fs/promises";
|
|
|
8959
8792
|
import http from "node:http";
|
|
8960
8793
|
import https from "node:https";
|
|
8961
8794
|
import path27 from "node:path";
|
|
8795
|
+
import { stripVTControlCharacters } from "node:util";
|
|
8962
8796
|
import { createHttpTerminator } from "http-terminator";
|
|
8963
8797
|
import {
|
|
8964
8798
|
createServer as createViteServer,
|
|
@@ -8995,7 +8829,7 @@ init_joinUrl();
|
|
|
8995
8829
|
import path26 from "node:path";
|
|
8996
8830
|
import { createIndex as createIndex2 } from "pagefind";
|
|
8997
8831
|
import { isRunnableDevEnvironment } from "vite";
|
|
8998
|
-
async function* buildPagefindDevIndex(vite,
|
|
8832
|
+
async function* buildPagefindDevIndex(vite, config) {
|
|
8999
8833
|
const { index, errors } = await createIndex2();
|
|
9000
8834
|
invariant(index, `Failed to create pagefind index: ${errors.join(", ")}`);
|
|
9001
8835
|
const pagefindIndex = index;
|
|
@@ -9006,12 +8840,12 @@ async function* buildPagefindDevIndex(vite, config2) {
|
|
|
9006
8840
|
const serverModule = await ssrEnvironment.runner.import(
|
|
9007
8841
|
getAppServerEntryPath()
|
|
9008
8842
|
);
|
|
9009
|
-
const routes = serverModule.getRoutesByConfig(
|
|
8843
|
+
const routes = serverModule.getRoutesByConfig(config);
|
|
9010
8844
|
const paths = routesToPaths(routes);
|
|
9011
|
-
const { basePath } =
|
|
8845
|
+
const { basePath } = config;
|
|
9012
8846
|
const template = getDevHtml({
|
|
9013
8847
|
jsEntry: "/__z/entry.client.tsx",
|
|
9014
|
-
dir:
|
|
8848
|
+
dir: config.site?.dir
|
|
9015
8849
|
});
|
|
9016
8850
|
const transformedTemplate = await vite.transformIndexHtml("/", template);
|
|
9017
8851
|
let indexed = 0;
|
|
@@ -9060,14 +8894,14 @@ var DevServer = class {
|
|
|
9060
8894
|
constructor(options) {
|
|
9061
8895
|
this.#options = options;
|
|
9062
8896
|
}
|
|
9063
|
-
async createNodeServer(
|
|
9064
|
-
if (!
|
|
8897
|
+
async createNodeServer(config) {
|
|
8898
|
+
if (!config.https) return http.createServer();
|
|
9065
8899
|
this.protocol = "https";
|
|
9066
8900
|
const { dir } = this.#options;
|
|
9067
8901
|
const [key, cert, ca] = await Promise.all([
|
|
9068
|
-
fs3.readFile(path27.resolve(dir,
|
|
9069
|
-
fs3.readFile(path27.resolve(dir,
|
|
9070
|
-
|
|
8902
|
+
fs3.readFile(path27.resolve(dir, config.https.key)),
|
|
8903
|
+
fs3.readFile(path27.resolve(dir, config.https.cert)),
|
|
8904
|
+
config.https.ca ? fs3.readFile(path27.resolve(dir, config.https.ca)) : void 0
|
|
9071
8905
|
]);
|
|
9072
8906
|
return https.createServer({ key, cert, ca });
|
|
9073
8907
|
}
|
|
@@ -9076,12 +8910,14 @@ var DevServer = class {
|
|
|
9076
8910
|
mode: "development",
|
|
9077
8911
|
command: "serve"
|
|
9078
8912
|
};
|
|
9079
|
-
const viteConfig = await getViteConfig(this.#options.dir, configEnv
|
|
9080
|
-
|
|
8913
|
+
const viteConfig = await getViteConfig(this.#options.dir, configEnv, {
|
|
8914
|
+
ssr: this.#options.ssr
|
|
8915
|
+
});
|
|
8916
|
+
const { config } = await loadZudokuConfig(configEnv, this.#options.dir);
|
|
9081
8917
|
this.resolvedPort = await findAvailablePort(
|
|
9082
|
-
this.#options.argPort ??
|
|
8918
|
+
this.#options.argPort ?? config.port ?? DEFAULT_DEV_PORT
|
|
9083
8919
|
);
|
|
9084
|
-
const server = await this.createNodeServer(
|
|
8920
|
+
const server = await this.createNodeServer(config);
|
|
9085
8921
|
const mergedViteConfig = mergeConfig3(viteConfig, {
|
|
9086
8922
|
server: {
|
|
9087
8923
|
hmr: { server }
|
|
@@ -9116,15 +8952,15 @@ var DevServer = class {
|
|
|
9116
8952
|
const vite = await createViteServer(mergedViteConfig);
|
|
9117
8953
|
const graphql = createGraphQLServer({ graphqlEndpoint: "/__z/graphql" });
|
|
9118
8954
|
vite.middlewares.use((req, res, next) => {
|
|
9119
|
-
if (req.method === "GET" && req.originalUrl === "/" &&
|
|
9120
|
-
res.writeHead(307, { Location:
|
|
8955
|
+
if (req.method === "GET" && req.originalUrl === "/" && config.basePath && config.basePath !== "/") {
|
|
8956
|
+
res.writeHead(307, { Location: config.basePath });
|
|
9121
8957
|
res.end();
|
|
9122
8958
|
return;
|
|
9123
8959
|
}
|
|
9124
8960
|
next();
|
|
9125
8961
|
});
|
|
9126
8962
|
vite.middlewares.use(graphql.graphqlEndpoint, graphql);
|
|
9127
|
-
const sessionEndpoint = joinUrl(
|
|
8963
|
+
const sessionEndpoint = joinUrl(config.basePath, "/__z/auth/session");
|
|
9128
8964
|
vite.middlewares.use(sessionEndpoint, async (req, res) => {
|
|
9129
8965
|
if (req.method !== "POST" && req.method !== "DELETE") {
|
|
9130
8966
|
res.writeHead(405, { Allow: "POST, DELETE" });
|
|
@@ -9205,7 +9041,7 @@ var DevServer = class {
|
|
|
9205
9041
|
printDiagnosticsToConsole(
|
|
9206
9042
|
`Server-side rendering ${this.#options.ssr ? "enabled" : "disabled"}`
|
|
9207
9043
|
);
|
|
9208
|
-
if (
|
|
9044
|
+
if (config.search?.type === "pagefind") {
|
|
9209
9045
|
const pagefindPath = path27.join(
|
|
9210
9046
|
vite.config.publicDir,
|
|
9211
9047
|
"pagefind/pagefind.js"
|
|
@@ -9278,11 +9114,15 @@ var DevServer = class {
|
|
|
9278
9114
|
const html = `<!DOCTYPE html><html><body><script type="module">
|
|
9279
9115
|
import { ErrorOverlay } from '/@vite/client';
|
|
9280
9116
|
document.body.appendChild(new ErrorOverlay(${JSON.stringify({
|
|
9281
|
-
message:
|
|
9282
|
-
|
|
9117
|
+
message: stripVTControlCharacters(
|
|
9118
|
+
e instanceof Error ? e.message : String(e)
|
|
9119
|
+
),
|
|
9120
|
+
stack: stripVTControlCharacters(
|
|
9121
|
+
e instanceof Error ? e.stack ?? "" : ""
|
|
9122
|
+
)
|
|
9283
9123
|
})}));
|
|
9284
9124
|
</script></body></html>`;
|
|
9285
|
-
res.writeHead(500, { "Content-Type": "text/html" });
|
|
9125
|
+
res.writeHead(500, { "Content-Type": "text/html; charset=utf-8" });
|
|
9286
9126
|
res.end(html);
|
|
9287
9127
|
}
|
|
9288
9128
|
});
|