@lukoweb/apitogo 0.1.86 → 0.1.88

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 (75) hide show
  1. package/dist/cli/cli.js +10755 -1987
  2. package/dist/declarations/cli/platform/apply/index.d.ts +3 -0
  3. package/dist/declarations/cli/platform/client/deploy-server.d.ts +16 -0
  4. package/dist/declarations/cli/platform/client/platform-api.d.ts +397 -0
  5. package/dist/declarations/cli/platform/config.d.ts +20 -0
  6. package/dist/declarations/cli/platform/errors.d.ts +16 -0
  7. package/dist/declarations/cli/platform/helpers/backend-packaging.d.ts +11 -0
  8. package/dist/declarations/cli/platform/helpers/deploy-artifact-hash.d.ts +14 -0
  9. package/dist/declarations/cli/platform/helpers/dev-portal-backend-job.d.ts +25 -0
  10. package/dist/declarations/cli/platform/helpers/dev-portal-backend.d.ts +11 -0
  11. package/dist/declarations/cli/platform/helpers/dev-portal-landing.d.ts +99 -0
  12. package/dist/declarations/cli/platform/helpers/dev-portal-manifest.d.ts +167 -0
  13. package/dist/declarations/cli/platform/helpers/dev-portal-plan-sync.d.ts +20 -0
  14. package/dist/declarations/cli/platform/helpers/dev-portal-secrets.d.ts +61 -0
  15. package/dist/declarations/cli/platform/helpers/dev-portal-settings-kinds.d.ts +8 -0
  16. package/dist/declarations/cli/platform/helpers/dev-portal-site-api-url.d.ts +12 -0
  17. package/dist/declarations/cli/platform/helpers/dev-portal-site-validation.d.ts +22 -0
  18. package/dist/declarations/cli/platform/helpers/dev-portal-urls.d.ts +17 -0
  19. package/dist/declarations/cli/platform/helpers/fetch-retry.d.ts +17 -0
  20. package/dist/declarations/cli/platform/helpers/free-projects-quota.d.ts +14 -0
  21. package/dist/declarations/cli/platform/helpers/gateway-plan-sync.d.ts +26 -0
  22. package/dist/declarations/cli/platform/helpers/gateway-readiness.d.ts +11 -0
  23. package/dist/declarations/cli/platform/helpers/job-status.d.ts +12 -0
  24. package/dist/declarations/cli/platform/helpers/merge-dev-portal-settings.d.ts +26 -0
  25. package/dist/declarations/cli/platform/helpers/npm-build.d.ts +34 -0
  26. package/dist/declarations/cli/platform/helpers/openapi-gateway-servers.d.ts +23 -0
  27. package/dist/declarations/cli/platform/helpers/openapi.d.ts +24 -0
  28. package/dist/declarations/cli/platform/helpers/package-files.d.ts +1 -0
  29. package/dist/declarations/cli/platform/helpers/paid-gateway-platform-compat.d.ts +22 -0
  30. package/dist/declarations/cli/platform/helpers/platform-plan-catalog.d.ts +27 -0
  31. package/dist/declarations/cli/platform/helpers/platform-plan.d.ts +17 -0
  32. package/dist/declarations/cli/platform/helpers/poll.d.ts +21 -0
  33. package/dist/declarations/cli/platform/helpers/progress.d.ts +45 -0
  34. package/dist/declarations/cli/platform/helpers/project-name.d.ts +8 -0
  35. package/dist/declarations/cli/platform/helpers/public-routes.d.ts +4 -0
  36. package/dist/declarations/cli/platform/helpers/publish-ledger.d.ts +30 -0
  37. package/dist/declarations/cli/platform/helpers/publish-preflight.d.ts +60 -0
  38. package/dist/declarations/cli/platform/helpers/status.d.ts +7 -0
  39. package/dist/declarations/cli/platform/helpers/stripe-webhook.d.ts +3 -0
  40. package/dist/declarations/cli/platform/helpers/tarball.d.ts +11 -0
  41. package/dist/declarations/cli/platform/helpers/validate-dev-portal-readiness.d.ts +48 -0
  42. package/dist/declarations/cli/platform/helpers/wait-for-gateway-actions.d.ts +9 -0
  43. package/dist/declarations/cli/platform/helpers/warm-pool.d.ts +35 -0
  44. package/dist/declarations/cli/platform/helpers/zip.d.ts +6 -0
  45. package/dist/declarations/cli/platform/tools/backend.d.ts +45 -0
  46. package/dist/declarations/cli/platform/tools/dev-portal-bootstrap-shared.d.ts +25 -0
  47. package/dist/declarations/cli/platform/tools/dev-portal-publish.d.ts +45 -0
  48. package/dist/declarations/cli/platform/tools/dev-portal-site-build.d.ts +12 -0
  49. package/dist/declarations/cli/platform/tools/dev-portal.d.ts +84 -0
  50. package/dist/declarations/cli/platform/tools/gateway.d.ts +140 -0
  51. package/dist/declarations/cli/platform/tools/infrastructure.d.ts +47 -0
  52. package/dist/declarations/cli/platform/tools/lifecycle.d.ts +40 -0
  53. package/dist/declarations/cli/platform/tools/platform-plan.d.ts +43 -0
  54. package/dist/declarations/cli/platform/tools/projects.d.ts +27 -0
  55. package/dist/declarations/cli/platform/tools/subscription.d.ts +13 -0
  56. package/dist/declarations/config/landing-manifest.d.ts +5 -0
  57. package/dist/declarations/config/local-manifest.d.ts +5 -0
  58. package/dist/declarations/config/validators/ModulesSchema.d.ts +21 -0
  59. package/dist/declarations/config/validators/ZudokuConfig.d.ts +5 -0
  60. package/dist/flat-config.d.ts +2 -0
  61. package/docs/cli/commands.md +14 -9
  62. package/docs/cli/go-live.md +2 -2
  63. package/docs/cli/setup.md +1 -1
  64. package/docs/guides/environment-variables.md +1 -1
  65. package/package.json +14 -2
  66. package/src/app/apitogoBrandTheme.ts +30 -29
  67. package/src/app/defaultTheme.css +56 -56
  68. package/src/config/validators/ModulesSchema.ts +2 -0
  69. package/src/lib/authentication/providers/dev-portal-auth-pages.tsx +45 -18
  70. package/src/lib/components/Header.tsx +8 -5
  71. package/src/lib/components/HeaderAuthActions.tsx +5 -7
  72. package/src/lib/components/Layout.tsx +13 -4
  73. package/src/lib/components/Main.tsx +3 -2
  74. package/src/lib/components/MobileTopNavigation.tsx +2 -5
  75. package/src/lib/components/ThemeSwitch.tsx +41 -25
@@ -94,6 +94,7 @@ export const LandingApiShowcaseItemSchema = z.object({
94
94
  icon: z.string().optional(),
95
95
  latency: z.string().optional(),
96
96
  summary: z.string().optional(),
97
+ method: z.string().optional(),
97
98
  });
98
99
 
99
100
  export const LandingApiShowcaseSchema = z
@@ -104,6 +105,7 @@ export const LandingApiShowcaseSchema = z
104
105
  browseAllHref: z.string().optional(),
105
106
  browseAllLabel: z.string().optional(),
106
107
  autoFromOpenApi: z.boolean().optional(),
108
+ layout: z.enum(["grid", "list"]).optional(),
107
109
  items: z.array(LandingApiShowcaseItemSchema).optional(),
108
110
  })
109
111
  .optional();
@@ -1,4 +1,5 @@
1
1
  import { Spinner } from "@lukoweb/apitogo/components";
2
+ import { Badge } from "@lukoweb/apitogo/ui/Badge.js";
2
3
  import { Button } from "@lukoweb/apitogo/ui/Button.js";
3
4
  import {
4
5
  Card,
@@ -9,7 +10,7 @@ import {
9
10
  } from "@lukoweb/apitogo/ui/Card.js";
10
11
  import { Input } from "@lukoweb/apitogo/ui/Input.js";
11
12
  import { Label } from "@lukoweb/apitogo/ui/Label.js";
12
- import { useCallback, useEffect, useState } from "react";
13
+ import { useCallback, useEffect, useState, type ReactNode } from "react";
13
14
  import { Link, useSearchParams } from "react-router";
14
15
  import type { DevPortalAuthConfigResponse } from "./dev-portal-constants.js";
15
16
  import {
@@ -31,20 +32,31 @@ import {
31
32
  type AuthPageShellProps = {
32
33
  title: string;
33
34
  description?: string;
34
- children: React.ReactNode;
35
+ badge?: ReactNode;
36
+ children: ReactNode;
35
37
  };
36
38
 
37
- function AuthPageShell({ title, description, children }: AuthPageShellProps) {
39
+ function AuthPageShell({
40
+ title,
41
+ description,
42
+ badge,
43
+ children,
44
+ }: AuthPageShellProps) {
38
45
  return (
39
- <div className="flex items-center justify-center mt-8 px-4">
40
- <Card className="max-w-md w-full">
41
- <CardHeader>
42
- <CardTitle className="text-lg">{title}</CardTitle>
46
+ <div className="flex items-center justify-center bg-muted px-5 py-10">
47
+ <Card className="w-full max-w-md gap-0 bg-card py-8">
48
+ <CardHeader className="gap-0 px-8 pb-0">
49
+ {badge ? <div className="mb-3.5">{badge}</div> : null}
50
+ <CardTitle className="text-2xl font-bold tracking-tight">
51
+ {title}
52
+ </CardTitle>
43
53
  {description ? (
44
- <CardDescription>{description}</CardDescription>
54
+ <CardDescription className="mt-1 mb-[22px] text-sm">
55
+ {description}
56
+ </CardDescription>
45
57
  ) : null}
46
58
  </CardHeader>
47
- <CardContent className="space-y-4">{children}</CardContent>
59
+ <CardContent className="space-y-4 px-8">{children}</CardContent>
48
60
  </Card>
49
61
  </div>
50
62
  );
@@ -349,7 +361,7 @@ export function DevPortalRegisterPage({
349
361
  if (!baseUrl) {
350
362
  return (
351
363
  <AuthPageShell
352
- title="Create account"
364
+ title="Create your account"
353
365
  description="Dev portal API is not configured."
354
366
  >
355
367
  <p className="text-sm text-muted-foreground">
@@ -361,16 +373,17 @@ export function DevPortalRegisterPage({
361
373
 
362
374
  return (
363
375
  <AuthPageShell
364
- title="Create account"
365
- description="Register for API access."
376
+ title="Create your account"
366
377
  >
367
- <form className="space-y-4" onSubmit={onSubmit}>
378
+ <form className="flex flex-col gap-4" onSubmit={onSubmit}>
368
379
  <div className="space-y-2">
369
- <Label htmlFor="displayName">Name</Label>
380
+ <Label htmlFor="displayName">Full name</Label>
370
381
  <Input
371
382
  id="displayName"
383
+ placeholder="Priya Shah"
372
384
  value={displayName}
373
385
  onChange={(event) => setDisplayName(event.target.value)}
386
+ className="h-10"
374
387
  />
375
388
  </div>
376
389
  <div className="space-y-2">
@@ -379,9 +392,11 @@ export function DevPortalRegisterPage({
379
392
  id="email"
380
393
  type="email"
381
394
  autoComplete="email"
395
+ placeholder="you@company.com"
382
396
  value={email}
383
397
  onChange={(event) => setEmail(event.target.value)}
384
398
  required
399
+ className="h-10"
385
400
  />
386
401
  </div>
387
402
  <div className="space-y-2">
@@ -390,24 +405,36 @@ export function DevPortalRegisterPage({
390
405
  id="password"
391
406
  type="password"
392
407
  autoComplete="new-password"
408
+ placeholder="••••••••"
393
409
  value={password}
394
410
  onChange={(event) => setPassword(event.target.value)}
395
411
  required
412
+ className="h-10"
396
413
  />
414
+ <p className="text-xs text-muted-foreground">At least 8 characters</p>
397
415
  </div>
398
416
  <AuthError message={error} />
399
417
  {message ? (
400
418
  <p className="text-sm text-muted-foreground">{message}</p>
401
419
  ) : null}
402
- <Button type="submit" className="w-full" disabled={pending}>
420
+ <Button
421
+ type="submit"
422
+ size="lg"
423
+ className="h-12 w-full text-base"
424
+ disabled={pending}
425
+ >
403
426
  {pending ? <Spinner /> : "Create account"}
404
427
  </Button>
405
- <p className="text-sm text-center">
428
+ <p className="text-xs leading-relaxed text-muted-foreground">
429
+ By creating an account you agree to our Terms and Privacy Policy.
430
+ </p>
431
+ <p className="text-sm text-muted-foreground">
432
+ Already have an account?{" "}
406
433
  <Link
407
- className="text-primary hover:underline"
434
+ className="font-semibold text-primary no-underline hover:underline"
408
435
  to={`/login?redirect=${encodeURIComponent(returnUrl)}`}
409
436
  >
410
- Back to sign in
437
+ Log in
411
438
  </Link>
412
439
  </p>
413
440
  </form>
@@ -148,6 +148,7 @@ export const Header = memo(function HeaderInner() {
148
148
  const authPlacement = header?.placements?.auth ?? "end";
149
149
  const authPosition =
150
150
  authPlacement === "navigation" ? navPosition : authPlacement;
151
+ const hasMarketingHeaderNav = (header?.navigation?.length ?? 0) > 0;
151
152
 
152
153
  const logoLightSrc = site?.logo
153
154
  ? /https?:\/\//.test(site.logo.src.light)
@@ -206,11 +207,13 @@ export const Header = memo(function HeaderInner() {
206
207
  </div>
207
208
  </Link>
208
209
  <Slot.Target name="head-navigation-start" />
209
- <div className="hidden lg:flex min-w-0 items-center ml-2">
210
- <Slot.Target name="top-navigation-before" />
211
- <TopNavigation />
212
- <Slot.Target name="top-navigation-after" />
213
- </div>
210
+ {!hasMarketingHeaderNav ? (
211
+ <div className="hidden lg:flex min-w-0 items-center ml-2">
212
+ <Slot.Target name="top-navigation-before" />
213
+ <TopNavigation />
214
+ <Slot.Target name="top-navigation-after" />
215
+ </div>
216
+ ) : null}
214
217
  {searchPosition === "start" && (
215
218
  <Search className="hidden lg:flex" />
216
219
  )}
@@ -1,5 +1,4 @@
1
1
  import { Button } from "@lukoweb/apitogo/ui/Button.js";
2
- import { ArrowRightIcon } from "lucide-react";
3
2
  import { useAuth } from "../authentication/hook.js";
4
3
  import { cn } from "../util/cn.js";
5
4
 
@@ -15,19 +14,18 @@ export const HeaderAuthActions = ({ className }: { className?: string }) => {
15
14
  <div className={cn("hidden lg:flex items-center gap-2.5", className)}>
16
15
  <Button
17
16
  variant="ghost"
18
- size="lg"
17
+ size="sm"
19
18
  className="font-semibold text-foreground hover:text-primary px-3"
20
19
  onClick={() => void auth.login()}
21
20
  >
22
- Sign in
21
+ Log in
23
22
  </Button>
24
23
  <Button
25
- size="lg"
26
- className="gap-1.5 rounded-[9px] px-4 font-semibold shadow-[0_4px_14px_-4px] shadow-primary/30"
24
+ size="sm"
25
+ className="rounded-[9px] px-4 font-semibold shadow-[0_4px_14px_-4px] shadow-primary/30"
27
26
  onClick={() => void auth.signup()}
28
27
  >
29
- Start free
30
- <ArrowRightIcon size={15} strokeWidth={2} />
28
+ Get started
31
29
  </Button>
32
30
  </div>
33
31
  );
@@ -4,7 +4,10 @@ import { Outlet } from "react-router";
4
4
  import { cn } from "../util/cn.js";
5
5
  import { useScrollToAnchor } from "../util/useScrollToAnchor.js";
6
6
  import { useScrollToTop } from "../util/useScrollToTop.js";
7
- import { useZudoku } from "./context/ZudokuContext.js";
7
+ import {
8
+ useCurrentNavigation,
9
+ useZudoku,
10
+ } from "./context/ZudokuContext.js";
8
11
  import { Footer } from "./Footer.js";
9
12
  import { Header } from "./Header.js";
10
13
  import { Main } from "./Main.js";
@@ -19,6 +22,8 @@ const LoadingFallback = () => (
19
22
 
20
23
  export const Layout = ({ children }: { children?: ReactNode }) => {
21
24
  const { authentication } = useZudoku();
25
+ const { navigation } = useCurrentNavigation();
26
+ const hasSideNav = navigation.length > 0;
22
27
 
23
28
  useScrollToAnchor();
24
29
  useScrollToTop();
@@ -38,9 +43,13 @@ export const Layout = ({ children }: { children?: ReactNode }) => {
38
43
 
39
44
  <div
40
45
  className={cn(
41
- "grid max-w-screen-2xl w-full lg:mx-auto",
42
- "[&:has(>:only-child)]:grid-rows-1 grid-rows-[0_min-content_1fr] lg:grid-rows-[min-content_1fr]",
43
- "grid-cols-1 lg:grid-cols-[var(--side-nav-width)_1fr]",
46
+ "grid w-full",
47
+ // Docs shell: cap width + reserve side-nav column.
48
+ // Marketing pages (no side nav): full-bleed so section backgrounds
49
+ // and compare/FAQ bands can span the viewport.
50
+ hasSideNav
51
+ ? "max-w-screen-2xl lg:mx-auto grid-rows-[0_min-content_1fr] lg:grid-rows-[min-content_1fr] grid-cols-1 lg:grid-cols-[var(--side-nav-width)_1fr]"
52
+ : "grid-cols-1 grid-rows-1",
44
53
  )}
45
54
  >
46
55
  <Suspense fallback={<LoadingFallback />}>
@@ -37,8 +37,9 @@ export const Main = ({ children }: PropsWithChildren) => {
37
37
  <main
38
38
  data-pagefind-body
39
39
  className={cn(
40
- "px-4 lg:pe-8 lg:px-8",
41
- !hasNavigation && "col-span-full",
40
+ // Docs: gutter so content clears the side nav.
41
+ // Marketing: no shell padding — pages own section px / full-bleed bands.
42
+ hasNavigation ? "px-4 lg:pe-8 lg:px-8" : "col-span-full px-0",
42
43
  isNavigating && "animate-pulse",
43
44
  )}
44
45
  >
@@ -3,7 +3,6 @@ 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,
7
6
  ChevronDownIcon,
8
7
  LogOutIcon,
9
8
  MenuIcon,
@@ -258,17 +257,15 @@ export const MobileTopNavigation = () => {
258
257
  void login();
259
258
  }}
260
259
  >
261
- Sign in
260
+ Log in
262
261
  </Button>
263
262
  <Button
264
- className="gap-1.5"
265
263
  onClick={() => {
266
264
  setDrawerOpen(false);
267
265
  void signup();
268
266
  }}
269
267
  >
270
- Start free
271
- <ArrowRightIcon size={15} strokeWidth={2} />
268
+ Get started
272
269
  </Button>
273
270
  </div>
274
271
  ))}
@@ -1,18 +1,25 @@
1
- import { MoonIcon, SunIcon } from "lucide-react";
1
+ import { MoonIcon, MonitorIcon, SunIcon } from "lucide-react";
2
2
  import { useTheme } from "next-themes";
3
3
  import { focusRing } from "../ui/util.js";
4
4
  import { cn } from "../util/cn.js";
5
5
  import { useIsClient } from "./ClientOnly.js";
6
6
 
7
+ const COMPACT_OPTIONS = [
8
+ { value: "light", label: "Light", Icon: SunIcon },
9
+ { value: "dark", label: "Dark", Icon: MoonIcon },
10
+ { value: "system", label: "System", Icon: MonitorIcon },
11
+ ] as const;
12
+
7
13
  export const ThemeSwitch = ({
8
14
  variant = "default",
9
15
  }: {
10
16
  variant?: "default" | "compact";
11
17
  }) => {
12
- const { resolvedTheme, setTheme } = useTheme();
18
+ const { theme, resolvedTheme, setTheme } = useTheme();
13
19
  const isClient = useIsClient();
14
20
 
15
- const theme = isClient ? resolvedTheme : undefined;
21
+ const activeTheme = isClient ? resolvedTheme : undefined;
22
+ const selectedMode = isClient ? (theme ?? "system") : "system";
16
23
 
17
24
  const handleThemeToggle = () => {
18
25
  setTheme(resolvedTheme === "dark" ? "light" : "dark");
@@ -20,27 +27,36 @@ export const ThemeSwitch = ({
20
27
 
21
28
  if (variant === "compact") {
22
29
  return (
23
- <button
24
- type="button"
30
+ <div
31
+ role="group"
32
+ aria-label="Theme"
25
33
  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",
34
+ "inline-flex h-8 items-center gap-0.5 rounded-[9px] border border-border bg-muted/40 p-0.5",
27
35
  focusRing,
28
36
  )}
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
37
  >
38
- {!isClient || theme === "dark" ? (
39
- <SunIcon size={17} strokeWidth={1.8} />
40
- ) : (
41
- <MoonIcon size={17} strokeWidth={1.8} />
42
- )}
43
- </button>
38
+ {COMPACT_OPTIONS.map(({ value, label, Icon }) => {
39
+ const selected = selectedMode === value;
40
+ return (
41
+ <button
42
+ key={value}
43
+ type="button"
44
+ className={cn(
45
+ "grid size-7 place-items-center rounded-[7px] text-muted-foreground transition-colors",
46
+ selected
47
+ ? "bg-card text-foreground shadow-xs"
48
+ : "hover:text-foreground",
49
+ )}
50
+ onClick={() => setTheme(value)}
51
+ aria-label={label}
52
+ aria-pressed={selected}
53
+ title={label}
54
+ >
55
+ <Icon size={14} strokeWidth={1.8} />
56
+ </button>
57
+ );
58
+ })}
59
+ </div>
44
60
  );
45
61
  }
46
62
 
@@ -52,7 +68,7 @@ export const ThemeSwitch = ({
52
68
  aria-label={
53
69
  !isClient
54
70
  ? "Toggle theme"
55
- : theme === "dark"
71
+ : activeTheme === "dark"
56
72
  ? "Switch to light mode"
57
73
  : "Switch to dark mode"
58
74
  }
@@ -60,8 +76,8 @@ export const ThemeSwitch = ({
60
76
  <div
61
77
  className={cn(
62
78
  "rounded-full p-0.5 border border-transparent [&>svg>circle]:transition-colors [&>svg>path]:transition-transform transition-all [&>svg>path]:duration-200 [&>svg>circle]:duration-500 [&>svg>circle]:fill-transparent",
63
- theme === "light" && "border-border bg-muted",
64
- theme === "dark" &&
79
+ activeTheme === "light" && "border-border bg-muted",
80
+ activeTheme === "dark" &&
65
81
  "group-hover:[&>svg>path]:scale-110 group-hover:[&>svg>path]:-translate-x-px group-hover:[&>svg>path]:-translate-y-px group-hover:rotate-15",
66
82
  )}
67
83
  >
@@ -70,9 +86,9 @@ export const ThemeSwitch = ({
70
86
  <div
71
87
  className={cn(
72
88
  "rounded-full p-0.5 border border-transparent transition-transform transform-gpu duration-500",
73
- theme === "dark" &&
89
+ activeTheme === "dark" &&
74
90
  "border-border bg-muted [&>svg>path]:fill-white [&>svg>path]:stroke-transparent",
75
- theme === "light" &&
91
+ activeTheme === "light" &&
76
92
  "group-hover:rotate-[-10deg] [&>svg>path]:stroke-currentColor",
77
93
  )}
78
94
  >