@lukoweb/apitogo 0.1.54 → 0.1.55
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 +604 -376
- package/dist/declarations/config/landing-manifest.d.ts +76 -0
- package/dist/declarations/config/local-manifest.d.ts +76 -0
- package/dist/declarations/config/validators/ModulesSchema.d.ts +227 -0
- package/dist/declarations/config/validators/ZudokuConfig.d.ts +50 -0
- package/dist/declarations/lib/authentication/header-nav-filter.d.ts +4 -0
- package/dist/declarations/lib/authentication/providers/dev-portal-auth-pages.d.ts +5 -5
- package/dist/declarations/lib/components/HeaderAuthActions.d.ts +3 -0
- package/dist/declarations/lib/components/SiteTitle.d.ts +6 -0
- package/dist/declarations/lib/components/ThemeSwitch.d.ts +3 -1
- package/dist/declarations/lib/components/TopNavigation.d.ts +1 -1
- package/dist/declarations/lib/core/ZudokuContext.d.ts +1 -0
- package/dist/flat-config.d.ts +44 -0
- package/package.json +1 -1
- package/src/app/main.css +2 -2
- package/src/config/apitogo-config-core.ts +13 -0
- package/src/config/apitogo-config-loader.browser.ts +17 -0
- package/src/config/build-apitogo-config.ts +13 -4
- package/src/config/landing-manifest.ts +11 -0
- package/src/config/landing-openapi-showcase.ts +115 -0
- package/src/config/loader.ts +17 -3
- package/src/config/local-manifest.ts +114 -10
- package/src/config/resolve-modules.ts +22 -1
- package/src/config/validators/ModulesSchema.ts +84 -0
- package/src/config/validators/ZudokuConfig.ts +1 -0
- package/src/lib/authentication/auth-header-nav.ts +5 -15
- package/src/lib/authentication/header-nav-filter.ts +36 -0
- package/src/lib/authentication/providers/dev-portal-auth-pages.tsx +95 -35
- package/src/lib/authentication/providers/dev-portal-utils.ts +17 -7
- package/src/lib/authentication/providers/dev-portal.tsx +18 -8
- package/src/lib/components/Header.tsx +49 -39
- package/src/lib/components/HeaderAuthActions.tsx +36 -0
- package/src/lib/components/HeaderNavigation.tsx +11 -9
- package/src/lib/components/MobileTopNavigation.tsx +43 -24
- package/src/lib/components/SiteTitle.tsx +20 -0
- package/src/lib/components/ThemeSwitch.tsx +36 -2
- package/src/lib/components/TopNavigation.tsx +20 -33
- package/src/lib/core/ZudokuContext.ts +1 -0
- package/src/vite/config.ts +21 -0
- package/src/vite/plugin-auth.ts +4 -1
- package/src/vite/plugin-config.ts +39 -4
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
type HeaderNavItem,
|
|
7
7
|
type HeaderNavLinkItem,
|
|
8
8
|
} from "../../config/validators/HeaderNavigationSchema.js";
|
|
9
|
+
import { withoutMarketingCtaHeaderNavigation } from "../authentication/header-nav-filter.js";
|
|
9
10
|
import { useAuth } from "../authentication/hook.js";
|
|
10
11
|
import type { ZudokuContext } from "../core/ZudokuContext.js";
|
|
11
12
|
import {
|
|
@@ -15,12 +16,14 @@ import {
|
|
|
15
16
|
NavigationMenuLink,
|
|
16
17
|
NavigationMenuList,
|
|
17
18
|
NavigationMenuTrigger,
|
|
18
|
-
navigationMenuTriggerStyle,
|
|
19
19
|
} from "../ui/NavigationMenu.js";
|
|
20
20
|
import { cn } from "../util/cn.js";
|
|
21
21
|
import { useZudoku } from "./context/ZudokuContext.js";
|
|
22
22
|
import { shouldShowItem } from "./navigation/utils.js";
|
|
23
23
|
|
|
24
|
+
const marketingNavLinkClassName =
|
|
25
|
+
"inline-flex items-center gap-2 rounded-lg px-3 py-2 text-sm font-medium text-muted-foreground transition-colors hover:bg-muted hover:text-foreground";
|
|
26
|
+
|
|
24
27
|
const NavLinkItem = ({ item }: { item: HeaderNavLinkItem }) => {
|
|
25
28
|
const Icon = item.icon as LucideIcon | undefined;
|
|
26
29
|
return (
|
|
@@ -118,10 +121,7 @@ const HeaderNavItemComponent = ({
|
|
|
118
121
|
to={item.to}
|
|
119
122
|
target={item.target}
|
|
120
123
|
rel={item.target === "_blank" ? "noopener noreferrer" : undefined}
|
|
121
|
-
className={
|
|
122
|
-
navigationMenuTriggerStyle(),
|
|
123
|
-
"flex items-center gap-2",
|
|
124
|
-
)}
|
|
124
|
+
className={marketingNavLinkClassName}
|
|
125
125
|
>
|
|
126
126
|
{Icon && <Icon size={16} />}
|
|
127
127
|
{item.label}
|
|
@@ -146,8 +146,10 @@ const HeaderNavItemComponent = ({
|
|
|
146
146
|
export const HeaderNavigation = () => {
|
|
147
147
|
const context = useZudoku();
|
|
148
148
|
const auth = useAuth();
|
|
149
|
-
const items =
|
|
150
|
-
|
|
149
|
+
const items = withoutMarketingCtaHeaderNavigation(
|
|
150
|
+
context.options.header?.navigation ?? [],
|
|
151
|
+
);
|
|
152
|
+
const navPosition = context.options.header?.placements?.navigation ?? "start";
|
|
151
153
|
if (!items || items.length === 0) return null;
|
|
152
154
|
|
|
153
155
|
const viewportAlign =
|
|
@@ -158,8 +160,8 @@ export const HeaderNavigation = () => {
|
|
|
158
160
|
: undefined;
|
|
159
161
|
|
|
160
162
|
return (
|
|
161
|
-
<NavigationMenu className={viewportAlign}>
|
|
162
|
-
<NavigationMenuList>
|
|
163
|
+
<NavigationMenu className={cn("max-w-none", viewportAlign)}>
|
|
164
|
+
<NavigationMenuList className="gap-1">
|
|
163
165
|
{items.map((item) => (
|
|
164
166
|
<HeaderNavItemComponent
|
|
165
167
|
key={"to" in item ? item.to : item.label}
|
|
@@ -3,6 +3,7 @@ import { Separator } from "@lukoweb/apitogo/ui/Separator.js";
|
|
|
3
3
|
import { VisuallyHidden } from "@radix-ui/react-visually-hidden";
|
|
4
4
|
import { deepEqual } from "fast-equals";
|
|
5
5
|
import {
|
|
6
|
+
ArrowRightIcon,
|
|
6
7
|
ChevronDownIcon,
|
|
7
8
|
LogOutIcon,
|
|
8
9
|
MenuIcon,
|
|
@@ -15,6 +16,7 @@ import {
|
|
|
15
16
|
type HeaderNavItem,
|
|
16
17
|
type HeaderNavLinkItem,
|
|
17
18
|
} from "../../config/validators/HeaderNavigationSchema.js";
|
|
19
|
+
import { withoutMarketingCtaHeaderNavigation } from "../authentication/header-nav-filter.js";
|
|
18
20
|
import { useAuth } from "../authentication/hook.js";
|
|
19
21
|
import {
|
|
20
22
|
Collapsible,
|
|
@@ -127,8 +129,10 @@ export const MobileTopNavigation = () => {
|
|
|
127
129
|
options: { header, navigation = [], site },
|
|
128
130
|
getProfileMenuItems,
|
|
129
131
|
} = context;
|
|
130
|
-
const headerNavigation =
|
|
131
|
-
|
|
132
|
+
const headerNavigation = withoutMarketingCtaHeaderNavigation(
|
|
133
|
+
header?.navigation ?? [],
|
|
134
|
+
);
|
|
135
|
+
const { isAuthenticated, profile, isAuthEnabled, login, signup } = authState;
|
|
132
136
|
const [drawerOpen, setDrawerOpen] = useState(false);
|
|
133
137
|
|
|
134
138
|
const accountItems = getProfileMenuItems();
|
|
@@ -158,18 +162,6 @@ export const MobileTopNavigation = () => {
|
|
|
158
162
|
<DrawerTitle>Navigation</DrawerTitle>
|
|
159
163
|
</VisuallyHidden>
|
|
160
164
|
<ul className="flex flex-col gap-1 px-4">
|
|
161
|
-
{headerNavigation.map((item) => (
|
|
162
|
-
<MobileHeaderNavItem
|
|
163
|
-
key={item.label}
|
|
164
|
-
item={item}
|
|
165
|
-
onNavigate={() => setDrawerOpen(false)}
|
|
166
|
-
/>
|
|
167
|
-
))}
|
|
168
|
-
{headerNavigation.length > 0 && <Separator className="my-2" />}
|
|
169
|
-
<li className="empty:hidden">
|
|
170
|
-
<Slot.Target name="top-navigation-side" />
|
|
171
|
-
</li>
|
|
172
|
-
|
|
173
165
|
{filteredItems.map((item) => {
|
|
174
166
|
if (item.type === "separator") {
|
|
175
167
|
return <Separator className="my-2" key={item.label} />;
|
|
@@ -192,6 +184,19 @@ export const MobileTopNavigation = () => {
|
|
|
192
184
|
</li>
|
|
193
185
|
);
|
|
194
186
|
})}
|
|
187
|
+
{filteredItems.length > 0 && headerNavigation.length > 0 && (
|
|
188
|
+
<Separator className="my-2" />
|
|
189
|
+
)}
|
|
190
|
+
<li className="empty:hidden">
|
|
191
|
+
<Slot.Target name="top-navigation-side" />
|
|
192
|
+
</li>
|
|
193
|
+
{headerNavigation.map((item) => (
|
|
194
|
+
<MobileHeaderNavItem
|
|
195
|
+
key={item.label}
|
|
196
|
+
item={item}
|
|
197
|
+
onNavigate={() => setDrawerOpen(false)}
|
|
198
|
+
/>
|
|
199
|
+
))}
|
|
195
200
|
{isAuthEnabled && isAuthenticated && (
|
|
196
201
|
<>
|
|
197
202
|
<Separator className="my-2" />
|
|
@@ -227,7 +232,7 @@ export const MobileTopNavigation = () => {
|
|
|
227
232
|
</ul>
|
|
228
233
|
</div>
|
|
229
234
|
<div className="border-t shadow-[0_-4px_6px_-1px_rgba(0,0,0,0.05)] px-4 pt-3 flex flex-col gap-2">
|
|
230
|
-
<div className="flex items-center justify-between">
|
|
235
|
+
<div className="flex items-center justify-between gap-2">
|
|
231
236
|
{isAuthEnabled &&
|
|
232
237
|
(isAuthenticated ? (
|
|
233
238
|
<Button asChild variant="outline">
|
|
@@ -241,20 +246,34 @@ export const MobileTopNavigation = () => {
|
|
|
241
246
|
strokeWidth={1}
|
|
242
247
|
absoluteStrokeWidth
|
|
243
248
|
/>
|
|
244
|
-
|
|
249
|
+
Log out
|
|
245
250
|
</Link>
|
|
246
251
|
</Button>
|
|
247
252
|
) : (
|
|
248
|
-
<
|
|
249
|
-
<
|
|
250
|
-
|
|
251
|
-
|
|
253
|
+
<div className="flex flex-1 items-center gap-2">
|
|
254
|
+
<Button
|
|
255
|
+
variant="ghost"
|
|
256
|
+
className="font-semibold"
|
|
257
|
+
onClick={() => {
|
|
258
|
+
setDrawerOpen(false);
|
|
259
|
+
void login({ redirectTo: location.pathname });
|
|
260
|
+
}}
|
|
252
261
|
>
|
|
253
|
-
|
|
254
|
-
</
|
|
255
|
-
|
|
262
|
+
Sign in
|
|
263
|
+
</Button>
|
|
264
|
+
<Button
|
|
265
|
+
className="gap-1.5"
|
|
266
|
+
onClick={() => {
|
|
267
|
+
setDrawerOpen(false);
|
|
268
|
+
void signup({ redirectTo: location.pathname });
|
|
269
|
+
}}
|
|
270
|
+
>
|
|
271
|
+
Start free
|
|
272
|
+
<ArrowRightIcon size={15} strokeWidth={2} />
|
|
273
|
+
</Button>
|
|
274
|
+
</div>
|
|
256
275
|
))}
|
|
257
|
-
<ThemeSwitch />
|
|
276
|
+
<ThemeSwitch variant="compact" />
|
|
258
277
|
</div>
|
|
259
278
|
{site?.showPoweredBy !== false && (
|
|
260
279
|
<PoweredByZudoku className="grow-0 justify-center gap-1" />
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { cn } from "../util/cn.js";
|
|
2
|
+
|
|
3
|
+
type SiteTitleProps = {
|
|
4
|
+
title: string;
|
|
5
|
+
className?: string;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export const SiteTitle = ({ title, className }: SiteTitleProps) => {
|
|
9
|
+
return (
|
|
10
|
+
<div
|
|
11
|
+
className={cn(
|
|
12
|
+
"shrink-0 font-bold text-[19px] tracking-[-0.02em] text-foreground",
|
|
13
|
+
className,
|
|
14
|
+
)}
|
|
15
|
+
style={{ fontFamily: '"Space Grotesk", var(--font-sans, sans-serif)' }}
|
|
16
|
+
>
|
|
17
|
+
{title}
|
|
18
|
+
</div>
|
|
19
|
+
);
|
|
20
|
+
};
|
|
@@ -4,17 +4,51 @@ import { focusRing } from "../ui/util.js";
|
|
|
4
4
|
import { cn } from "../util/cn.js";
|
|
5
5
|
import { useIsClient } from "./ClientOnly.js";
|
|
6
6
|
|
|
7
|
-
export const ThemeSwitch = (
|
|
7
|
+
export const ThemeSwitch = ({
|
|
8
|
+
variant = "default",
|
|
9
|
+
}: {
|
|
10
|
+
variant?: "default" | "compact";
|
|
11
|
+
}) => {
|
|
8
12
|
const { resolvedTheme, setTheme } = useTheme();
|
|
9
13
|
const isClient = useIsClient();
|
|
10
14
|
|
|
11
15
|
const theme = isClient ? resolvedTheme : undefined;
|
|
12
16
|
|
|
17
|
+
const handleThemeToggle = () => {
|
|
18
|
+
setTheme(resolvedTheme === "dark" ? "light" : "dark");
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
if (variant === "compact") {
|
|
22
|
+
return (
|
|
23
|
+
<button
|
|
24
|
+
type="button"
|
|
25
|
+
className={cn(
|
|
26
|
+
"grid size-[38px] place-items-center rounded-[9px] border border-border text-muted-foreground transition-colors hover:border-border hover:text-foreground",
|
|
27
|
+
focusRing,
|
|
28
|
+
)}
|
|
29
|
+
onClick={handleThemeToggle}
|
|
30
|
+
aria-label={
|
|
31
|
+
!isClient
|
|
32
|
+
? "Toggle theme"
|
|
33
|
+
: theme === "dark"
|
|
34
|
+
? "Switch to light mode"
|
|
35
|
+
: "Switch to dark mode"
|
|
36
|
+
}
|
|
37
|
+
>
|
|
38
|
+
{!isClient || theme === "dark" ? (
|
|
39
|
+
<SunIcon size={17} strokeWidth={1.8} />
|
|
40
|
+
) : (
|
|
41
|
+
<MoonIcon size={17} strokeWidth={1.8} />
|
|
42
|
+
)}
|
|
43
|
+
</button>
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
|
|
13
47
|
return (
|
|
14
48
|
<button
|
|
15
49
|
type="button"
|
|
16
50
|
className={cn("flex rounded-full border p-0.5 gap-0.5 group", focusRing)}
|
|
17
|
-
onClick={
|
|
51
|
+
onClick={handleThemeToggle}
|
|
18
52
|
aria-label={
|
|
19
53
|
!isClient
|
|
20
54
|
? "Toggle theme"
|
|
@@ -7,8 +7,6 @@ import type { NavigationItem } from "../../config/validators/NavigationSchema.js
|
|
|
7
7
|
import { useAuth } from "../authentication/hook.js";
|
|
8
8
|
import { useCurrentNavigation, useZudoku } from "./context/ZudokuContext.js";
|
|
9
9
|
import { getFirstMatchingPath, shouldShowItem } from "./navigation/utils.js";
|
|
10
|
-
import { Slot } from "./Slot.js";
|
|
11
|
-
|
|
12
10
|
export const TopNavigation = () => {
|
|
13
11
|
const context = useZudoku();
|
|
14
12
|
const {
|
|
@@ -18,30 +16,26 @@ export const TopNavigation = () => {
|
|
|
18
16
|
const filteredItems = navigation.filter(shouldShowItem({ auth, context }));
|
|
19
17
|
|
|
20
18
|
if (filteredItems.length === 0 || import.meta.env.MODE === "standalone") {
|
|
21
|
-
return
|
|
19
|
+
return null;
|
|
22
20
|
}
|
|
23
21
|
|
|
24
22
|
return (
|
|
25
23
|
<Suspense>
|
|
26
|
-
<
|
|
27
|
-
<
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
item.
|
|
31
|
-
<
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
<
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
</nav>
|
|
42
|
-
<Slot.Target name="top-navigation-side" />
|
|
43
|
-
</div>
|
|
44
|
-
{/* <PageProgress /> */}
|
|
24
|
+
<nav className="min-w-0 text-sm">
|
|
25
|
+
<ul className="flex flex-row items-center gap-1">
|
|
26
|
+
{filteredItems.map((item) =>
|
|
27
|
+
item.type === "separator" ? (
|
|
28
|
+
<li key={item.label} className="mx-1 h-5">
|
|
29
|
+
<Separator orientation="vertical" />
|
|
30
|
+
</li>
|
|
31
|
+
) : item.type !== "section" && item.type !== "filter" ? (
|
|
32
|
+
<li key={item.label + item.type}>
|
|
33
|
+
<TopNavItem {...item} />
|
|
34
|
+
</li>
|
|
35
|
+
) : null,
|
|
36
|
+
)}
|
|
37
|
+
</ul>
|
|
38
|
+
</nav>
|
|
45
39
|
</Suspense>
|
|
46
40
|
);
|
|
47
41
|
};
|
|
@@ -60,18 +54,11 @@ export const TopNavLink = ({
|
|
|
60
54
|
className={({ isActive: isActiveNavLink, isPending }) => {
|
|
61
55
|
const isActiveReal = isActiveNavLink || isActive;
|
|
62
56
|
return cx(
|
|
63
|
-
"flex items-center gap-2 lg
|
|
57
|
+
"inline-flex items-center gap-2 rounded-lg px-3 py-2 text-sm font-medium transition-colors",
|
|
64
58
|
isActiveReal || isPending
|
|
65
|
-
?
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
"after:content-[''] after:absolute after:bottom-0 after:left-0 after:right-0",
|
|
69
|
-
"after:h-0.5 after:bg-primary",
|
|
70
|
-
isActiveReal &&
|
|
71
|
-
"after:[view-transition-name:top-nav-underline]",
|
|
72
|
-
isPending && "after:bg-primary/25",
|
|
73
|
-
]
|
|
74
|
-
: "text-foreground/75 hover:text-foreground",
|
|
59
|
+
? "bg-muted text-foreground"
|
|
60
|
+
: "text-muted-foreground hover:bg-muted hover:text-foreground",
|
|
61
|
+
isPending && "opacity-75",
|
|
75
62
|
);
|
|
76
63
|
}}
|
|
77
64
|
{...props}
|
package/src/vite/config.ts
CHANGED
|
@@ -21,6 +21,11 @@ import { ensurePagefindDevStub } from "./pagefind-dev-stub.js";
|
|
|
21
21
|
import vitePlugin from "./plugin.js";
|
|
22
22
|
import { getZuploSystemConfigurations } from "./zuplo.js";
|
|
23
23
|
|
|
24
|
+
const browserConfigLoaderPath = path.join(
|
|
25
|
+
getZudokuRootDir(),
|
|
26
|
+
"src/config/apitogo-config-loader.browser.ts",
|
|
27
|
+
);
|
|
28
|
+
|
|
24
29
|
/** Resolved absolute public directory (Vite default: `<root>/public`). */
|
|
25
30
|
const resolveMergedPublicDir = (
|
|
26
31
|
rootDir: string,
|
|
@@ -114,6 +119,22 @@ export async function getViteConfig(
|
|
|
114
119
|
"@mdx-js/react": import.meta.resolve("@mdx-js/react"),
|
|
115
120
|
},
|
|
116
121
|
},
|
|
122
|
+
environments: {
|
|
123
|
+
client: {
|
|
124
|
+
resolve: {
|
|
125
|
+
alias: {
|
|
126
|
+
[path.join(
|
|
127
|
+
getZudokuRootDir(),
|
|
128
|
+
"src/config/apitogo-config-loader.node.ts",
|
|
129
|
+
)]: browserConfigLoaderPath,
|
|
130
|
+
[path.join(
|
|
131
|
+
getZudokuRootDir(),
|
|
132
|
+
"src/config/apitogo-config-loader.node.js",
|
|
133
|
+
)]: browserConfigLoaderPath,
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
},
|
|
117
138
|
define: {
|
|
118
139
|
"process.env.ZUDOKU_VERSION": JSON.stringify(packageJson.version),
|
|
119
140
|
"process.env.IS_ZUPLO": ZuploEnv.isZuplo,
|
package/src/vite/plugin-auth.ts
CHANGED
|
@@ -16,7 +16,10 @@ const viteAuthPlugin = (): Plugin => {
|
|
|
16
16
|
if (id === resolvedVirtualModuleId) {
|
|
17
17
|
const config = getCurrentConfig();
|
|
18
18
|
|
|
19
|
-
if (
|
|
19
|
+
if (
|
|
20
|
+
!config.authentication?.type ||
|
|
21
|
+
config.__meta.mode === "standalone"
|
|
22
|
+
) {
|
|
20
23
|
return `export const configuredAuthProvider = undefined;`;
|
|
21
24
|
}
|
|
22
25
|
// TODO: Validate that the authConfig.type is a valid authentication provider
|
|
@@ -1,18 +1,50 @@
|
|
|
1
|
+
import path from "node:path";
|
|
1
2
|
import { normalizePath, type Plugin, type ResolvedConfig } from "vite";
|
|
3
|
+
import { getZudokuRootDir } from "../cli/common/package-json.js";
|
|
2
4
|
import { getCurrentConfig, loadZudokuConfig } from "../config/loader.js";
|
|
5
|
+
import type { ConfigWithMeta } from "../config/loader.js";
|
|
3
6
|
|
|
4
7
|
const virtualModuleId = "virtual:zudoku-config";
|
|
5
8
|
const resolvedVirtualModuleId = `\0${virtualModuleId}`;
|
|
9
|
+
const browserConfigLoaderPath = path.join(
|
|
10
|
+
getZudokuRootDir(),
|
|
11
|
+
"src/config/apitogo-config-loader.browser.ts",
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
function serializeClientConfig(config: ConfigWithMeta): string {
|
|
15
|
+
const {
|
|
16
|
+
plugins: _plugins,
|
|
17
|
+
__meta: _meta,
|
|
18
|
+
__resolvedModules,
|
|
19
|
+
...rest
|
|
20
|
+
} = config;
|
|
21
|
+
|
|
22
|
+
return JSON.stringify({ ...rest, __resolvedModules }, (_key, value) =>
|
|
23
|
+
typeof value === "function" ? undefined : value,
|
|
24
|
+
);
|
|
25
|
+
}
|
|
6
26
|
|
|
7
27
|
const viteConfigPlugin = (): Plugin => {
|
|
8
28
|
let viteConfig: ResolvedConfig;
|
|
9
29
|
|
|
10
30
|
return {
|
|
11
31
|
name: "zudoku-config-plugin",
|
|
12
|
-
resolveId(
|
|
13
|
-
if (
|
|
32
|
+
resolveId(source, _importer, options) {
|
|
33
|
+
if (source === virtualModuleId) {
|
|
34
|
+
return resolvedVirtualModuleId;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (!source.includes("apitogo-config-loader.node")) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const isServerEnvironment =
|
|
42
|
+
options?.ssr === true ||
|
|
43
|
+
this.environment?.config?.consumer === "server";
|
|
14
44
|
|
|
15
|
-
|
|
45
|
+
if (!isServerEnvironment) {
|
|
46
|
+
return browserConfigLoaderPath;
|
|
47
|
+
}
|
|
16
48
|
},
|
|
17
49
|
configResolved(resolvedConfig) {
|
|
18
50
|
viteConfig = resolvedConfig;
|
|
@@ -43,8 +75,11 @@ const viteConfigPlugin = (): Plugin => {
|
|
|
43
75
|
import rawConfig from "${normalizePath(configPath)}";
|
|
44
76
|
import { runPluginTransformConfig } from "@lukoweb/apitogo/plugins";
|
|
45
77
|
|
|
78
|
+
const embeddedConfig = ${serializeClientConfig(loadedConfig)};
|
|
79
|
+
|
|
46
80
|
const config = await runPluginTransformConfig({
|
|
47
|
-
...
|
|
81
|
+
...embeddedConfig,
|
|
82
|
+
plugins: rawConfig?.plugins ?? embeddedConfig.plugins ?? [],
|
|
48
83
|
__meta: ${JSON.stringify(clientMeta)},
|
|
49
84
|
});
|
|
50
85
|
export default config;
|