@lukoweb/apitogo 0.1.50 → 0.1.53

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/dist/cli/cli.js +1339 -922
  2. package/dist/declarations/config/apitogo-config-core.d.ts +25 -0
  3. package/dist/declarations/config/apitogo-config-loader.d.ts +2 -0
  4. package/dist/declarations/config/apitogo-config-loader.node.d.ts +4 -0
  5. package/dist/declarations/config/build-apitogo-config.d.ts +8 -0
  6. package/dist/declarations/config/loader.d.ts +4 -0
  7. package/dist/declarations/config/local-manifest.d.ts +16 -9
  8. package/dist/declarations/config/validators/HeaderNavigationSchema.d.ts +24 -24
  9. package/dist/declarations/config/validators/ModulesSchema.d.ts +38 -0
  10. package/dist/declarations/config/validators/ZudokuConfig.d.ts +18 -9
  11. package/dist/declarations/index.d.ts +2 -1
  12. package/dist/declarations/lib/authentication/auth-header-nav.d.ts +10 -0
  13. package/dist/declarations/lib/core/plugins.d.ts +1 -0
  14. package/dist/declarations/lib/ui/Button.d.ts +1 -1
  15. package/dist/declarations/lib/ui/Item.d.ts +1 -1
  16. package/dist/flat-config.d.ts +36 -23
  17. package/docs/configuration/authentication.md +11 -8
  18. package/docs/configuration/manifest.md +83 -93
  19. package/package.json +17 -1
  20. package/src/config/apitogo-config-core.ts +485 -0
  21. package/src/config/apitogo-config-loader.node.ts +68 -0
  22. package/src/config/apitogo-config-loader.ts +6 -0
  23. package/src/config/build-apitogo-config.ts +52 -0
  24. package/src/config/loader.ts +61 -1
  25. package/src/config/local-manifest.ts +72 -52
  26. package/src/config/resolve-modules.ts +16 -13
  27. package/src/config/validators/ModulesSchema.ts +17 -0
  28. package/src/index.ts +9 -1
  29. package/src/lib/authentication/auth-header-nav.ts +56 -0
  30. package/src/lib/authentication/providers/dev-portal-utils.ts +7 -2
  31. package/src/lib/components/Header.tsx +48 -60
  32. package/src/lib/components/MobileTopNavigation.tsx +29 -40
  33. package/src/lib/core/plugins.ts +1 -0
  34. package/src/vite/dev-portal-env.ts +12 -4
  35. package/src/vite/plugin-config.ts +20 -3
  36. package/src/vite/plugin-local-manifest.ts +15 -0
@@ -1,6 +1,5 @@
1
1
  import { Button } from "@lukoweb/apitogo/ui/Button.js";
2
2
  import { Separator } from "@lukoweb/apitogo/ui/Separator.js";
3
- import { Skeleton } from "@lukoweb/apitogo/ui/Skeleton.js";
4
3
  import { VisuallyHidden } from "@radix-ui/react-visually-hidden";
5
4
  import { deepEqual } from "fast-equals";
6
5
  import {
@@ -28,7 +27,6 @@ import {
28
27
  DrawerTitle,
29
28
  DrawerTrigger,
30
29
  } from "../ui/Drawer.js";
31
- import { ClientOnly } from "./ClientOnly.js";
32
30
  import { useCurrentNavigation, useZudoku } from "./context/ZudokuContext.js";
33
31
  import { PoweredByZudoku } from "./navigation/PoweredByZudoku.js";
34
32
  import { getFirstMatchingPath, shouldShowItem } from "./navigation/utils.js";
@@ -130,7 +128,7 @@ export const MobileTopNavigation = () => {
130
128
  getProfileMenuItems,
131
129
  } = context;
132
130
  const headerNavigation = header?.navigation ?? [];
133
- const { isAuthenticated, profile, isAuthEnabled, isPending } = authState;
131
+ const { isAuthenticated, profile, isAuthEnabled } = authState;
134
132
  const [drawerOpen, setDrawerOpen] = useState(false);
135
133
 
136
134
  const accountItems = getProfileMenuItems();
@@ -195,9 +193,7 @@ export const MobileTopNavigation = () => {
195
193
  );
196
194
  })}
197
195
  {isAuthEnabled && isAuthenticated && (
198
- <ClientOnly
199
- fallback={<Skeleton className="rounded-sm h-5 w-24" />}
200
- >
196
+ <>
201
197
  <Separator className="my-2" />
202
198
  <li className="py-2">
203
199
  <div className="text-base font-medium">
@@ -226,45 +222,38 @@ export const MobileTopNavigation = () => {
226
222
  </Link>
227
223
  </li>
228
224
  ))}
229
- </ClientOnly>
225
+ </>
230
226
  )}
231
227
  </ul>
232
228
  </div>
233
229
  <div className="border-t shadow-[0_-4px_6px_-1px_rgba(0,0,0,0.05)] px-4 pt-3 flex flex-col gap-2">
234
230
  <div className="flex items-center justify-between">
235
- {isAuthEnabled && (
236
- <ClientOnly
237
- fallback={<Skeleton className="rounded-sm h-8 w-16" />}
238
- >
239
- {isPending ? (
240
- <Skeleton className="rounded-sm h-8 w-16" />
241
- ) : isAuthenticated ? (
242
- <Button asChild variant="outline">
243
- <Link
244
- to="/signout"
245
- onClick={() => setDrawerOpen(false)}
246
- className="flex items-center gap-2"
247
- >
248
- <LogOutIcon
249
- size={16}
250
- strokeWidth={1}
251
- absoluteStrokeWidth
252
- />
253
- Logout
254
- </Link>
255
- </Button>
256
- ) : (
257
- <Button asChild variant="outline">
258
- <Link
259
- to={`/signin?redirect=${encodeURIComponent(location.pathname)}`}
260
- onClick={() => setDrawerOpen(false)}
261
- >
262
- Login
263
- </Link>
264
- </Button>
265
- )}
266
- </ClientOnly>
267
- )}
231
+ {isAuthEnabled &&
232
+ (isAuthenticated ? (
233
+ <Button asChild variant="outline">
234
+ <Link
235
+ to="/signout"
236
+ onClick={() => setDrawerOpen(false)}
237
+ className="flex items-center gap-2"
238
+ >
239
+ <LogOutIcon
240
+ size={16}
241
+ strokeWidth={1}
242
+ absoluteStrokeWidth
243
+ />
244
+ Logout
245
+ </Link>
246
+ </Button>
247
+ ) : (
248
+ <Button asChild variant="outline">
249
+ <Link
250
+ to={`/signin?redirect=${encodeURIComponent(location.pathname)}`}
251
+ onClick={() => setDrawerOpen(false)}
252
+ >
253
+ Login
254
+ </Link>
255
+ </Button>
256
+ ))}
268
257
  <ThemeSwitch />
269
258
  </div>
270
259
  {site?.showPoweredBy !== false && (
@@ -11,6 +11,7 @@ import type {
11
11
  ApitogoEvents,
12
12
  ZudokuContext,
13
13
  } from "./ZudokuContext.js";
14
+ export { createPlugin } from "../../config/create-plugin.js";
14
15
  export { runPluginTransformConfig } from "./transform-config.js";
15
16
 
16
17
  export type ApitogoPlugin =
@@ -1,8 +1,14 @@
1
-
2
1
  import { loadEnv } from "vite";
3
2
 
3
+ export const AUTHENTICATION_API_BASE_URL_ENV =
4
+ "VITE_APITOGO_AUTHENTICATION_API_BASE_URL";
5
+
6
+ /** @deprecated Use {@link AUTHENTICATION_API_BASE_URL_ENV}. */
7
+ export const LEGACY_DEV_PORTAL_API_URL_ENV = "VITE_APITOGO_DEV_PORTAL_API_URL";
8
+
4
9
  export const DEV_PORTAL_VITE_ENV_KEYS = [
5
- "VITE_APITOGO_DEV_PORTAL_API_URL",
10
+ AUTHENTICATION_API_BASE_URL_ENV,
11
+ LEGACY_DEV_PORTAL_API_URL_ENV,
6
12
  ] as const;
7
13
 
8
14
  export async function loadDevPortalViteDefines(
@@ -12,9 +18,11 @@ export async function loadDevPortalViteDefines(
12
18
  const env = loadEnv(mode, rootDir, "VITE_");
13
19
  const defines: Record<string, string> = {};
14
20
 
15
- const apiUrl = env.VITE_APITOGO_DEV_PORTAL_API_URL?.trim();
21
+ const apiUrl =
22
+ env[AUTHENTICATION_API_BASE_URL_ENV]?.trim() ||
23
+ env[LEGACY_DEV_PORTAL_API_URL_ENV]?.trim();
16
24
  if (apiUrl) {
17
- defines.VITE_APITOGO_DEV_PORTAL_API_URL = JSON.stringify(apiUrl);
25
+ defines[AUTHENTICATION_API_BASE_URL_ENV] = JSON.stringify(apiUrl);
18
26
  }
19
27
 
20
28
  return defines;
@@ -1,5 +1,5 @@
1
1
  import { normalizePath, type Plugin, type ResolvedConfig } from "vite";
2
- import { getCurrentConfig } from "../config/loader.js";
2
+ import { getCurrentConfig, loadZudokuConfig } from "../config/loader.js";
3
3
 
4
4
  const virtualModuleId = "virtual:zudoku-config";
5
5
  const resolvedVirtualModuleId = `\0${virtualModuleId}`;
@@ -17,7 +17,7 @@ const viteConfigPlugin = (): Plugin => {
17
17
  configResolved(resolvedConfig) {
18
18
  viteConfig = resolvedConfig;
19
19
  },
20
- load(id) {
20
+ async load(id) {
21
21
  if (id !== resolvedVirtualModuleId) return;
22
22
 
23
23
  const configPath = getCurrentConfig().__meta.configPath;
@@ -25,11 +25,28 @@ const viteConfigPlugin = (): Plugin => {
25
25
  return `export default {};`;
26
26
  }
27
27
 
28
+ const { config: loadedConfig } = await loadZudokuConfig(
29
+ {
30
+ mode: viteConfig.mode,
31
+ command: viteConfig.command,
32
+ },
33
+ viteConfig.root,
34
+ );
35
+ const clientMeta = {
36
+ rootDir: loadedConfig.__meta.rootDir,
37
+ pricingEnabled: loadedConfig.__meta.pricingEnabled,
38
+ authenticationEnabled: loadedConfig.__meta.authenticationEnabled,
39
+ previewPlans: loadedConfig.__meta.previewPlans,
40
+ };
41
+
28
42
  return `
29
43
  import rawConfig from "${normalizePath(configPath)}";
30
44
  import { runPluginTransformConfig } from "@lukoweb/apitogo/plugins";
31
45
 
32
- const config = await runPluginTransformConfig(rawConfig);
46
+ const config = await runPluginTransformConfig({
47
+ ...rawConfig,
48
+ __meta: ${JSON.stringify(clientMeta)},
49
+ });
33
50
  export default config;
34
51
  `;
35
52
  },
@@ -1,10 +1,16 @@
1
1
  import path from "node:path";
2
2
  import type { Plugin, ResolvedConfig } from "vite";
3
+ import {
4
+ loadApitogoConfig,
5
+ readPlanCatalogItems,
6
+ } from "../config/apitogo-config-loader.js";
3
7
  import {
4
8
  manifestPathsForEnv,
5
9
  manifestToPreviewCatalog,
10
+ plansToPreviewCatalog,
6
11
  readEffectiveManifest,
7
12
  resolveManifestEnv,
13
+ type ManifestPlanInput,
8
14
  } from "../config/local-manifest.js";
9
15
 
10
16
  export const APITOGO_LOCAL_MANIFEST_VIRTUAL_ID =
@@ -24,6 +30,15 @@ const viteLocalManifestPlugin = (): Plugin => {
24
30
  try {
25
31
  const manifest = await readEffectiveManifest(rootDir, env);
26
32
  catalog = manifestToPreviewCatalog(manifest);
33
+ if (!catalog.plans.length) {
34
+ const config = loadApitogoConfig(rootDir);
35
+ catalog = {
36
+ ...catalog,
37
+ ...plansToPreviewCatalog(
38
+ readPlanCatalogItems(config) as ManifestPlanInput[],
39
+ ),
40
+ };
41
+ }
27
42
  } catch {
28
43
  // Missing or invalid manifest — empty catalog for preview.
29
44
  }