zudoku 0.1.1-dev.13 → 0.1.1-dev.14

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 (108) hide show
  1. package/dist/config/config.d.ts +0 -1
  2. package/dist/vite/build.js +2 -8
  3. package/dist/vite/build.js.map +1 -1
  4. package/dist/vite/config.d.ts +7 -3
  5. package/dist/vite/config.js +13 -17
  6. package/dist/vite/config.js.map +1 -1
  7. package/dist/vite/dev-server.js +7 -4
  8. package/dist/vite/dev-server.js.map +1 -1
  9. package/dist/vite/plugin-api.js +1 -1
  10. package/dist/vite/plugin-api.js.map +1 -1
  11. package/dist/vite/plugin-auth.js +1 -2
  12. package/dist/vite/plugin-auth.js.map +1 -1
  13. package/dist/vite/plugin-docs.js +1 -1
  14. package/dist/vite/plugin-docs.js.map +1 -1
  15. package/dist/vite/plugin-docs.test.js +0 -1
  16. package/dist/vite/plugin-docs.test.js.map +1 -1
  17. package/package.json +7 -2
  18. package/src/app/App.tsx +30 -0
  19. package/src/app/DevPortal.tsx +93 -0
  20. package/src/app/Heading.tsx +60 -0
  21. package/src/app/Router.tsx +28 -0
  22. package/src/app/authentication/authentication.ts +18 -0
  23. package/src/app/authentication/clerk.ts +47 -0
  24. package/src/app/authentication/openid.ts +192 -0
  25. package/src/app/components/AnchorLink.tsx +19 -0
  26. package/src/app/components/CategoryHeading.tsx +16 -0
  27. package/src/app/components/Dialog.tsx +119 -0
  28. package/src/app/components/DynamicIcon.tsx +60 -0
  29. package/src/app/components/Header.tsx +69 -0
  30. package/src/app/components/Input.tsx +24 -0
  31. package/src/app/components/Layout.tsx +56 -0
  32. package/src/app/components/Markdown.tsx +37 -0
  33. package/src/app/components/SyntaxHighlight.tsx +94 -0
  34. package/src/app/components/TopNavigation.tsx +32 -0
  35. package/src/app/components/context/ComponentsContext.tsx +24 -0
  36. package/src/app/components/context/DevPortalProvider.ts +54 -0
  37. package/src/app/components/context/PluginSystem.ts +0 -0
  38. package/src/app/components/context/ThemeContext.tsx +46 -0
  39. package/src/app/components/context/ViewportAnchorContext.tsx +139 -0
  40. package/src/app/components/navigation/SideNavigation.tsx +18 -0
  41. package/src/app/components/navigation/SideNavigationCategory.tsx +74 -0
  42. package/src/app/components/navigation/SideNavigationItem.tsx +143 -0
  43. package/src/app/components/navigation/SideNavigationWrapper.tsx +15 -0
  44. package/src/app/components/navigation/useNavigationCollapsibleState.ts +27 -0
  45. package/src/app/components/navigation/util.ts +38 -0
  46. package/src/app/core/DevPortalContext.ts +164 -0
  47. package/src/app/core/helmet.ts +5 -0
  48. package/src/app/core/icons.tsx +1 -0
  49. package/src/app/core/plugins.ts +43 -0
  50. package/src/app/core/router.tsx +1 -0
  51. package/src/app/core/types/combine.ts +16 -0
  52. package/src/app/main.css +137 -0
  53. package/src/app/main.tsx +9 -0
  54. package/src/app/oas/graphql/index.ts +422 -0
  55. package/src/app/oas/graphql/server.ts +10 -0
  56. package/src/app/oas/parser/dereference/index.ts +59 -0
  57. package/src/app/oas/parser/dereference/resolveRef.ts +32 -0
  58. package/src/app/oas/parser/index.ts +94 -0
  59. package/src/app/oas/parser/schemas/v3.0.json +1489 -0
  60. package/src/app/oas/parser/schemas/v3.1.json +1298 -0
  61. package/src/app/oas/parser/upgrade/index.ts +108 -0
  62. package/src/app/plugins/api-key/SettingsApiKeys.tsx +22 -0
  63. package/src/app/plugins/api-key/index.tsx +123 -0
  64. package/src/app/plugins/markdown/MdxPage.tsx +128 -0
  65. package/src/app/plugins/markdown/Toc.tsx +122 -0
  66. package/src/app/plugins/markdown/generateRoutes.tsx +72 -0
  67. package/src/app/plugins/markdown/index.tsx +31 -0
  68. package/src/app/plugins/openapi/ColorizedParam.tsx +82 -0
  69. package/src/app/plugins/openapi/MakeRequest.tsx +49 -0
  70. package/src/app/plugins/openapi/MethodBadge.tsx +36 -0
  71. package/src/app/plugins/openapi/OperationList.tsx +117 -0
  72. package/src/app/plugins/openapi/OperationListItem.tsx +55 -0
  73. package/src/app/plugins/openapi/ParameterList.tsx +32 -0
  74. package/src/app/plugins/openapi/ParameterListItem.tsx +60 -0
  75. package/src/app/plugins/openapi/RequestBodySidecarBox.tsx +51 -0
  76. package/src/app/plugins/openapi/ResponsesSidecarBox.tsx +60 -0
  77. package/src/app/plugins/openapi/Select.tsx +35 -0
  78. package/src/app/plugins/openapi/Sidecar.tsx +160 -0
  79. package/src/app/plugins/openapi/SidecarBox.tsx +36 -0
  80. package/src/app/plugins/openapi/graphql/fragment-masking.ts +111 -0
  81. package/src/app/plugins/openapi/graphql/gql.ts +70 -0
  82. package/src/app/plugins/openapi/graphql/graphql.ts +795 -0
  83. package/src/app/plugins/openapi/graphql/index.ts +2 -0
  84. package/src/app/plugins/openapi/index.tsx +142 -0
  85. package/src/app/plugins/openapi/playground/Playground.tsx +309 -0
  86. package/src/app/plugins/openapi/queries.graphql +6 -0
  87. package/src/app/plugins/openapi/util/generateSchemaExample.ts +59 -0
  88. package/src/app/plugins/openapi/util/urql.ts +8 -0
  89. package/src/app/plugins/openapi/worker/createSharedWorkerClient.ts +60 -0
  90. package/src/app/plugins/openapi/worker/worker.ts +30 -0
  91. package/src/app/plugins/redirect/index.tsx +20 -0
  92. package/src/app/tailwind.ts +72 -0
  93. package/src/app/ui/Button.tsx +56 -0
  94. package/src/app/ui/Callout.tsx +87 -0
  95. package/src/app/ui/Card.tsx +82 -0
  96. package/src/app/ui/Note.tsx +58 -0
  97. package/src/app/ui/Tabs.tsx +52 -0
  98. package/src/app/util/MdxComponents.tsx +70 -0
  99. package/src/app/util/cn.ts +6 -0
  100. package/src/app/util/createVariantComponent.tsx +30 -0
  101. package/src/app/util/createWaitForNotify.ts +18 -0
  102. package/src/app/util/groupBy.ts +24 -0
  103. package/src/app/util/joinPath.tsx +10 -0
  104. package/src/app/util/pastellize.ts +25 -0
  105. package/src/app/util/slugify.ts +3 -0
  106. package/src/app/util/traverseNavigation.ts +55 -0
  107. package/src/app/util/useScrollToAnchor.ts +38 -0
  108. package/src/app/util/useScrollToTop.ts +13 -0
@@ -0,0 +1,164 @@
1
+ import { QueryClient } from "@tanstack/react-query";
2
+ import { type ReactNode } from "react";
3
+ import { create } from "zustand";
4
+ import { type DevPortalPath, type DevPortalProps } from "../DevPortal.js";
5
+ import { type AuthProvider } from "../authentication/authentication.js";
6
+ import {
7
+ isApiKeyPlugin,
8
+ isNavigationPlugin,
9
+ needsInitialization,
10
+ type DevPortalPlugin,
11
+ type NavigationPlugin,
12
+ } from "./plugins.js";
13
+
14
+ import type { LucideIcon } from "lucide-react";
15
+ import type { IconName } from "../components/DynamicIcon.js";
16
+
17
+ export interface ApiIdentity {
18
+ authorizeRequest: (request: Request) => Request;
19
+ name: string;
20
+ id: string;
21
+ }
22
+
23
+ type BaseNavigationCategoryItem = {
24
+ label: ReactNode;
25
+ title?: string;
26
+ icon?: ReactNode | IconName;
27
+ };
28
+
29
+ export type PathNavigationCategoryItem = BaseNavigationCategoryItem & {
30
+ path: string;
31
+ children?: NavigationCategoryItem[];
32
+ };
33
+
34
+ export type HrefNavigationCategoryItem = BaseNavigationCategoryItem & {
35
+ href: string;
36
+ };
37
+
38
+ export type NavigationCategoryItem =
39
+ | PathNavigationCategoryItem
40
+ | HrefNavigationCategoryItem;
41
+
42
+ export type NavigationCategory = {
43
+ label: string;
44
+ path?: string;
45
+ expanded?: boolean;
46
+ collapsible?: boolean;
47
+ icon?: LucideIcon;
48
+ children: NavigationCategoryItem[];
49
+ };
50
+
51
+ export type NavigationItem = {
52
+ label: string;
53
+ path: DevPortalPath;
54
+ categories?: NavigationCategory[];
55
+ };
56
+
57
+ export type SessionProfileState = {
58
+ isLoggedIn: boolean;
59
+ sub?: string;
60
+ email?: string;
61
+ name?: string;
62
+ email_verified?: string;
63
+ picture?: string;
64
+ };
65
+
66
+ export type RoutingState = {
67
+ path?: string;
68
+ };
69
+
70
+ export const queryClient = new QueryClient();
71
+
72
+ export const useDevPortalState = create<SessionProfileState & RoutingState>(
73
+ () => ({
74
+ isLoggedIn: false,
75
+ }),
76
+ );
77
+
78
+ export type ApiKeyCache = "api-keys";
79
+ export type DevPortalCacheKey = ApiKeyCache | string;
80
+
81
+ export class DevPortalContext {
82
+ private plugins: DevPortalPlugin[] = [];
83
+ private navigationPlugins: NavigationPlugin[];
84
+
85
+ public navigation: NavigationItem[];
86
+ public meta: DevPortalProps["meta"];
87
+ public authentication?: AuthProvider;
88
+ public state: typeof useDevPortalState;
89
+
90
+ constructor(private config: DevPortalProps) {
91
+ this.plugins = config.plugins ?? [];
92
+ this.navigation = config.navigation;
93
+ this.navigationPlugins = this.plugins.filter(isNavigationPlugin);
94
+ this.authentication = config.authentication;
95
+ this.meta = config.meta;
96
+ this.state = useDevPortalState;
97
+ }
98
+
99
+ initialize = async () => {
100
+ this.plugins
101
+ .filter(needsInitialization)
102
+ .forEach((plugin) => plugin.initialize(this));
103
+ this.authentication?.initialize(this);
104
+ };
105
+
106
+ setUserProfile = async (profile: Partial<SessionProfileState>) => {
107
+ return useDevPortalState.setState(profile);
108
+ };
109
+
110
+ invalidateCache = async (key: DevPortalCacheKey[]) => {
111
+ queryClient.invalidateQueries({ queryKey: key });
112
+ };
113
+
114
+ getApiIdentities = async () => {
115
+ const keys = await Promise.all(
116
+ this.plugins
117
+ .filter(isApiKeyPlugin)
118
+ .map((plugin) => plugin.getIdentities(this)),
119
+ );
120
+
121
+ return keys.flat();
122
+ };
123
+
124
+ login = async () => {
125
+ if (!this.authentication) {
126
+ throw new Error("No authentication configured");
127
+ }
128
+
129
+ return this.authentication.login(this);
130
+ };
131
+
132
+ logout = async () => {
133
+ if (!this.authentication) {
134
+ throw new Error("No authentication configured");
135
+ }
136
+
137
+ return this.authentication.signOut(this);
138
+ };
139
+
140
+ handleAuthenticationResponse = async (path: {
141
+ pathname: string;
142
+ search: string;
143
+ hash: string;
144
+ }) => {
145
+ this.config.authentication?.handleAuthenticationResponse?.(path, this);
146
+ };
147
+
148
+ getNavigation = async (path: string) => {
149
+ const navigations = await Promise.all(
150
+ this.navigationPlugins.map(async (plugin) =>
151
+ plugin.getNavigation?.(path),
152
+ ),
153
+ );
154
+
155
+ return navigations.flatMap((nav) => nav ?? []);
156
+ };
157
+
158
+ sessionStorage = {
159
+ get: async (key: string) => localStorage.getItem(`session-${key}`) ?? "",
160
+ setProfile: async () => {},
161
+ set: async (key: string, value: string) =>
162
+ localStorage.setItem(`session-${key}`, value),
163
+ };
164
+ }
@@ -0,0 +1,5 @@
1
+ import * as helmet from "react-helmet-async";
2
+
3
+ export const Helmet = helmet.Helmet;
4
+ export const HelmetData = helmet.HelmetData;
5
+ export const HelmetProvider = helmet.HelmetProvider;
@@ -0,0 +1 @@
1
+ export * from "lucide-react";
@@ -0,0 +1,43 @@
1
+ import { type RouteObject } from "react-router-dom";
2
+ import {
3
+ DevPortalContext,
4
+ type ApiIdentity,
5
+ type NavigationCategory,
6
+ } from "./DevPortalContext.js";
7
+ import { type Combine } from "./types/combine.js";
8
+
9
+ export type PluginNavigationCategory = {
10
+ path: string;
11
+ } & NavigationCategory;
12
+
13
+ export type DevPortalPlugin = Combine<
14
+ [NavigationPlugin, ApiIdentityPlugin, InitializationPlugin]
15
+ >;
16
+
17
+ export interface NavigationPlugin {
18
+ getRoutes: () => RouteObject[];
19
+ getNavigation?: (path: string) => Promise<PluginNavigationCategory[]>;
20
+ }
21
+
22
+ export interface ApiIdentityPlugin {
23
+ getIdentities: (context: DevPortalContext) => Promise<ApiIdentity[]>;
24
+ }
25
+
26
+ export interface InitializationPlugin {
27
+ initialize: (context: DevPortalContext) => Promise<void> | void;
28
+ }
29
+
30
+ export const isNavigationPlugin = (
31
+ obj: DevPortalPlugin,
32
+ ): obj is NavigationPlugin =>
33
+ "getRoutes" in obj && typeof obj.getRoutes === "function";
34
+
35
+ export const needsInitialization = (
36
+ obj: DevPortalPlugin,
37
+ ): obj is InitializationPlugin =>
38
+ "initialize" in obj && typeof obj.initialize === "function";
39
+
40
+ export const isApiKeyPlugin = (
41
+ obj: DevPortalPlugin,
42
+ ): obj is ApiIdentityPlugin =>
43
+ "getIdentities" in obj && typeof obj.getIdentities === "function";
@@ -0,0 +1 @@
1
+ export * from "react-router-dom";
@@ -0,0 +1,16 @@
1
+ /* eslint-disable @typescript-eslint/no-explicit-any */
2
+ type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (
3
+ k: infer I,
4
+ ) => void
5
+ ? I
6
+ : never;
7
+
8
+ type AnyCombination<T, U = T> = T extends any
9
+ ? U extends any
10
+ ? T | (T & U)
11
+ : never
12
+ : never;
13
+
14
+ export type Combine<T extends any[]> =
15
+ | UnionToIntersection<T[number]>
16
+ | AnyCombination<T[number]>;
@@ -0,0 +1,137 @@
1
+ @tailwind base;
2
+ @tailwind components;
3
+ @tailwind utilities;
4
+
5
+ @layer base {
6
+ :root {
7
+ --top-header-height: 65px;
8
+ --top-nav-height: 50px;
9
+ --side-nav-width: theme("spacing.72");
10
+ --header-height: calc(var(--top-header-height) + var(--top-nav-height));
11
+ --scroll-padding: calc(var(--header-height) + 10px);
12
+ --padding-content-top: theme("spacing.12");
13
+ --padding-content-bottom: theme("spacing.12");
14
+ --padding-nav-item: theme("spacing[2.5]");
15
+ --sidecar-grid-cols: 1fr minmax(200px, 260px);
16
+ }
17
+
18
+ html,
19
+ body,
20
+ #root {
21
+ @apply h-full min-h-screen;
22
+ }
23
+
24
+ html {
25
+ scroll-padding-block: var(--scroll-padding);
26
+ }
27
+
28
+ body {
29
+ @apply antialiased bg-background text-foreground;
30
+ }
31
+
32
+ .dark {
33
+ color-scheme: dark;
34
+ }
35
+
36
+ .prose.prose {
37
+ @apply prose-a:decoration-primary/60 hover:prose-a:decoration-primary prose-a:underline-offset-4 hover:prose-a:decoration-2;
38
+ @apply prose-blockquote:not-italic prose-blockquote:text-neutral-500/75 prose-blockquote:dark:text-neutral-400;
39
+ @apply prose-headings:prose-code:mx-2;
40
+ @apply prose-code:before:content-none prose-code:after:content-none;
41
+
42
+ ul.contains-task-list {
43
+ @apply list-none px-0;
44
+ li {
45
+ @apply flex items-center gap-2;
46
+ }
47
+ }
48
+ }
49
+
50
+ select {
51
+ @apply focus-visible:ring-primary focus-visible:ring-[1.5px] focus:outline-none;
52
+ }
53
+
54
+ .CollapsibleContent {
55
+ --easing: cubic-bezier(0.4, 0, 0.2, 1);
56
+ --slide-offset: -0.75rem;
57
+ @apply overflow-hidden;
58
+ }
59
+ .CollapsibleContent[data-state="open"] {
60
+ animation: slideDown 300ms var(--easing);
61
+ }
62
+ .CollapsibleContent[data-state="closed"] {
63
+ animation: slideUp 300ms var(--easing);
64
+ }
65
+
66
+ @keyframes slideDown {
67
+ from {
68
+ height: 0;
69
+ opacity: 0;
70
+ transform: translateY(var(--slide-offset));
71
+ }
72
+ to {
73
+ height: var(--radix-collapsible-content-height);
74
+ opacity: 1;
75
+ transform: translateY(0);
76
+ }
77
+ }
78
+
79
+ @keyframes slideUp {
80
+ from {
81
+ height: var(--radix-collapsible-content-height);
82
+ opacity: 1;
83
+ transform: translateY(0);
84
+ }
85
+ to {
86
+ height: 0;
87
+ opacity: 0;
88
+ transform: translateY(var(--slide-offset));
89
+ }
90
+ }
91
+
92
+ /* Theme */
93
+ :root {
94
+ --background: 0 0% 100%;
95
+ --foreground: 222.2 84% 4.9%;
96
+ --card: 0 0% 100%;
97
+ --card-foreground: 222.2 84% 4.9%;
98
+ --popover: 0 0% 100%;
99
+ --popover-foreground: 222.2 84% 4.9%;
100
+ --primary: 221.2 83.2% 53.3%;
101
+ --primary-foreground: 210 40% 98%;
102
+ --secondary: 210 40% 96.1%;
103
+ --secondary-foreground: 222.2 47.4% 11.2%;
104
+ --muted: 210 40% 96.1%;
105
+ --muted-foreground: 215.4 16.3% 46.9%;
106
+ --accent: 210 40% 96.1%;
107
+ --accent-foreground: 222.2 47.4% 11.2%;
108
+ --destructive: 0 72.22% 50.59%;
109
+ --destructive-foreground: 210 40% 98%;
110
+ --border: 214.3 31.8% 91.4%;
111
+ --input: 214.3 31.8% 91.4%;
112
+ --ring: 221.2 83.2% 53.3%;
113
+ --radius: 0.5rem;
114
+ }
115
+
116
+ .dark {
117
+ --background: 222.2 84% 4.9%;
118
+ --foreground: 210 40% 98%;
119
+ --card: 222.2 84% 4.9%;
120
+ --card-foreground: 210 40% 98%;
121
+ --popover: 222.2 84% 4.9%;
122
+ --popover-foreground: 210 40% 98%;
123
+ --primary: 217.2 91.2% 59.8%;
124
+ --primary-foreground: 222.2 47.4% 11.2%;
125
+ --secondary: 217.2 32.6% 17.5%;
126
+ --secondary-foreground: 210 40% 98%;
127
+ --muted: 217.2 32.6% 17.5%;
128
+ --muted-foreground: 215 20.2% 65.1%;
129
+ --accent: 217.2 32.6% 17.5%;
130
+ --accent-foreground: 210 40% 98%;
131
+ --destructive: 0 62.8% 30.6%;
132
+ --destructive-foreground: 210 40% 98%;
133
+ --border: 217.2 32.6% 17.5%;
134
+ --input: 217.2 32.6% 17.5%;
135
+ --ring: 224.3 76.3% 48%;
136
+ }
137
+ }
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import { createRoot } from "react-dom/client";
3
+ import App from "./App.js";
4
+
5
+ createRoot(document.getElementById("root")!).render(
6
+ <React.StrictMode>
7
+ <App />
8
+ </React.StrictMode>,
9
+ );