zudoku 0.3.0-dev.5 → 0.3.0-dev.6

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 (54) hide show
  1. package/dist/app/App.js +2 -1
  2. package/dist/app/App.js.map +1 -1
  3. package/dist/lib/authentication/hook.d.ts +1 -0
  4. package/dist/lib/authentication/hook.js +1 -0
  5. package/dist/lib/authentication/hook.js.map +1 -1
  6. package/dist/lib/authentication/providers/auth0.js +1 -0
  7. package/dist/lib/authentication/providers/auth0.js.map +1 -1
  8. package/dist/lib/authentication/providers/clerk.js +2 -0
  9. package/dist/lib/authentication/providers/clerk.js.map +1 -1
  10. package/dist/lib/authentication/providers/openid.js +2 -0
  11. package/dist/lib/authentication/providers/openid.js.map +1 -1
  12. package/dist/lib/authentication/state.d.ts +1 -0
  13. package/dist/lib/authentication/state.js +1 -0
  14. package/dist/lib/authentication/state.js.map +1 -1
  15. package/dist/lib/components/DevPortal.js +0 -1
  16. package/dist/lib/components/DevPortal.js.map +1 -1
  17. package/dist/lib/components/SyntaxHighlight.js +1 -1
  18. package/dist/lib/components/SyntaxHighlight.js.map +1 -1
  19. package/dist/lib/core/DevPortalContext.js +5 -4
  20. package/dist/lib/core/DevPortalContext.js.map +1 -1
  21. package/dist/lib/plugins/api-key/CreateApiKey.d.ts +2 -3
  22. package/dist/lib/plugins/api-key/CreateApiKey.js +1 -1
  23. package/dist/lib/plugins/api-key/CreateApiKey.js.map +1 -1
  24. package/dist/lib/plugins/api-key/SettingsApiKeys.d.ts +2 -3
  25. package/dist/lib/plugins/api-key/SettingsApiKeys.js +2 -1
  26. package/dist/lib/plugins/api-key/SettingsApiKeys.js.map +1 -1
  27. package/dist/lib/plugins/api-key/index.js +20 -5
  28. package/dist/lib/plugins/api-key/index.js.map +1 -1
  29. package/dist/vite/config.test.js +1 -1
  30. package/dist/vite/config.test.js.map +1 -1
  31. package/dist/vite/plugin-docs.test.js +1 -1
  32. package/dist/vite/plugin-docs.test.js.map +1 -1
  33. package/lib/{Spinner-DWHrSHMP.js → Spinner-BINYpvLB.js} +3 -2
  34. package/lib/{index-DNx3xWa2.js → index-PyGcnQFX.js} +13 -12
  35. package/lib/loglevel-CoH7VSwE.js +152 -0
  36. package/lib/{state-DfftBQ9X.js → state-2Hu1renZ.js} +6 -5
  37. package/lib/zudoku.auth-auth0.js +2 -1
  38. package/lib/zudoku.auth-clerk.js +9 -7
  39. package/lib/zudoku.auth-openid.js +442 -587
  40. package/lib/zudoku.components.js +7 -6
  41. package/lib/zudoku.plugins.js +2567 -2548
  42. package/package.json +2 -1
  43. package/src/app/App.tsx +2 -1
  44. package/src/lib/authentication/hook.ts +1 -0
  45. package/src/lib/authentication/providers/auth0.tsx +1 -0
  46. package/src/lib/authentication/providers/clerk.tsx +2 -0
  47. package/src/lib/authentication/providers/openid.tsx +2 -0
  48. package/src/lib/authentication/state.ts +2 -0
  49. package/src/lib/components/DevPortal.tsx +0 -1
  50. package/src/lib/components/SyntaxHighlight.tsx +1 -1
  51. package/src/lib/core/DevPortalContext.ts +5 -4
  52. package/src/lib/plugins/api-key/CreateApiKey.tsx +2 -8
  53. package/src/lib/plugins/api-key/SettingsApiKeys.tsx +3 -8
  54. package/src/lib/plugins/api-key/index.tsx +30 -5
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zudoku",
3
- "version": "0.3.0-dev.5",
3
+ "version": "0.3.0-dev.6",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",
@@ -100,6 +100,7 @@
100
100
  "slugify": "1.6.6",
101
101
  "strip-ansi": "7.1.0",
102
102
  "tailwindcss": "3.4.4",
103
+ "tiny-invariant": "1.3.3",
103
104
  "ulidx": "^2.3.0",
104
105
  "unist-util-visit": "5.0.0",
105
106
  "urql": "4.1.0",
package/src/app/App.tsx CHANGED
@@ -32,8 +32,9 @@ export default function App() {
32
32
  plugins={[
33
33
  ...configuredDocsPlugins,
34
34
  ...configuredApiPlugins,
35
- configuredApiKeysPlugin,
36
35
  configuredRedirectPlugin,
36
+ ...(configuredApiKeysPlugin ? [configuredApiKeysPlugin] : []),
37
+ ...(configuredAuthProvider ? [configuredAuthProvider] : []),
37
38
  ]}
38
39
  />
39
40
  );
@@ -8,6 +8,7 @@ export const useAuth = () => {
8
8
 
9
9
  return {
10
10
  isAuthEnabled,
11
+ isPending: authState.isPending,
11
12
  profile: authState.profile,
12
13
  isAuthenticated: authState.profile,
13
14
 
@@ -7,6 +7,7 @@ class Auth0AuthenticationProvider extends OpenIDAuthenticationProvider {
7
7
  override async logout(): Promise<void> {
8
8
  useAuthState.setState({
9
9
  isAuthenticated: false,
10
+ isPending: false,
10
11
  profile: undefined,
11
12
  });
12
13
  const as = await this.getAuthServer();
@@ -34,6 +34,7 @@ const clerkAuth: AuthenticationProviderInitializer<
34
34
  if (clerkApi.session) {
35
35
  useAuthState.setState({
36
36
  isAuthenticated: true,
37
+ isPending: false,
37
38
  profile: {
38
39
  sub: clerkApi.session.user.id,
39
40
  name: clerkApi.session.user.fullName ?? undefined,
@@ -46,6 +47,7 @@ const clerkAuth: AuthenticationProviderInitializer<
46
47
  } else {
47
48
  useAuthState.setState({
48
49
  isAuthenticated: false,
50
+ isPending: false,
49
51
  profile: undefined,
50
52
  });
51
53
  }
@@ -180,6 +180,7 @@ export class OpenIDAuthenticationProvider implements AuthenticationProvider {
180
180
  async logout(): Promise<void> {
181
181
  useAuthState.setState({
182
182
  isAuthenticated: false,
183
+ isPending: false,
183
184
  profile: undefined,
184
185
  });
185
186
 
@@ -293,6 +294,7 @@ export class OpenIDAuthenticationProvider implements AuthenticationProvider {
293
294
 
294
295
  useAuthState.setState({
295
296
  isAuthenticated: true,
297
+ isPending: false,
296
298
  profile,
297
299
  });
298
300
 
@@ -1,11 +1,13 @@
1
1
  import { create } from "zustand";
2
2
 
3
3
  export const useAuthState = create<AuthState>(() => ({
4
+ isPending: true,
4
5
  isAuthenticated: false,
5
6
  }));
6
7
 
7
8
  export interface AuthState {
8
9
  isAuthenticated: boolean;
10
+ isPending: boolean;
9
11
  profile?: UserProfile;
10
12
  }
11
13
 
@@ -1,4 +1,3 @@
1
- /* eslint-disable react/destructuring-assignment */
2
1
  import { MDXProvider } from "@mdx-js/react";
3
2
  import { QueryClientProvider } from "@tanstack/react-query";
4
3
  import { memo, Suspense, useEffect, useMemo } from "react";
@@ -67,7 +67,7 @@ export const SyntaxHighlight = ({
67
67
  disabled={isCopied}
68
68
  onClick={() => {
69
69
  setIsCopied(true);
70
- navigator.clipboard.writeText(
70
+ void navigator.clipboard.writeText(
71
71
  tokens
72
72
  .map((line) => line.map(({ content }) => content).join(""))
73
73
  .join("\n"),
@@ -85,10 +85,11 @@ export class DevPortalContext {
85
85
  }
86
86
 
87
87
  initialize = async () => {
88
- this.plugins
89
- .filter(needsInitialization)
90
- .forEach((plugin) => plugin.initialize(this));
91
- this.authentication?.initialize(this);
88
+ await Promise.all([
89
+ this.plugins
90
+ .filter(needsInitialization)
91
+ .map((plugin) => plugin.initialize(this)),
92
+ ]);
92
93
  };
93
94
 
94
95
  invalidateCache = async (key: DevPortalCacheKey[]) => {
@@ -12,17 +12,11 @@ import {
12
12
  SelectValue,
13
13
  } from "../../components/Select.js";
14
14
  import { Button } from "../../ui/Button.js";
15
- import { type ApiKeyPluginOptions, ApiKeyService } from "./index.js";
15
+ import { ApiKeyService } from "./index.js";
16
16
 
17
17
  type CreateApiKey = { description: string; expiresOn?: string };
18
18
 
19
- export const CreateApiKey = ({
20
- options,
21
- service,
22
- }: {
23
- options: ApiKeyPluginOptions;
24
- service: ApiKeyService;
25
- }) => {
19
+ export const CreateApiKey = ({ service }: { service: ApiKeyService }) => {
26
20
  const context = useDevPortal();
27
21
  const navigate = useNavigate();
28
22
  const form = useForm<CreateApiKey>({
@@ -8,20 +8,15 @@ import { useState } from "react";
8
8
  import { Link } from "react-router-dom";
9
9
  import { useDevPortal } from "../../components/context/DevPortalProvider.js";
10
10
  import { Button } from "../../ui/Button.js";
11
- import { type ApiKeyPluginOptions, ApiKeyService } from "./index.js";
11
+ import { ApiKeyService } from "./index.js";
12
12
 
13
- export const SettingsApiKeys = ({
14
- options,
15
- service,
16
- }: {
17
- options: ApiKeyPluginOptions;
18
- service: ApiKeyService;
19
- }) => {
13
+ export const SettingsApiKeys = ({ service }: { service: ApiKeyService }) => {
20
14
  const context = useDevPortal();
21
15
  const queryClient = useQueryClient();
22
16
  const { data } = useSuspenseQuery({
23
17
  queryFn: () => service.getKeys(context),
24
18
  queryKey: ["api-keys"],
19
+ retry: false,
25
20
  });
26
21
 
27
22
  const deleteKeyMutation = useMutation({
@@ -1,4 +1,6 @@
1
- import { Outlet } from "react-router-dom";
1
+ import logger from "loglevel";
2
+ import { Outlet, useRouteError } from "react-router-dom";
3
+ import invariant from "tiny-invariant";
2
4
  import { useAuth } from "../../authentication/hook.js";
3
5
  import { DevPortalContext } from "../../core/DevPortalContext.js";
4
6
  import {
@@ -50,7 +52,8 @@ const createDefaultHandler = (endpoint: string): ApiKeyService => {
50
52
 
51
53
  await context.signRequest(request);
52
54
 
53
- await fetch(request);
55
+ const response = await fetch(request);
56
+ invariant(response.ok, "Failed to delete API key");
54
57
  },
55
58
  createKey: async (apiKey, context) => {
56
59
  const request = new Request(endpoint + `/v1/developer/api-keys`, {
@@ -62,7 +65,9 @@ const createDefaultHandler = (endpoint: string): ApiKeyService => {
62
65
  });
63
66
 
64
67
  await context.signRequest(request);
65
- await fetch(request);
68
+
69
+ const response = await fetch(request);
70
+ invariant(response.ok, "Failed to create API key");
66
71
  },
67
72
  getKeys: async (context) => {
68
73
  const request = new Request(endpoint + `/v1/developer/api-keys`);
@@ -70,6 +75,7 @@ const createDefaultHandler = (endpoint: string): ApiKeyService => {
70
75
  await context.signRequest(request);
71
76
 
72
77
  const keys = await fetch(request);
78
+ invariant(keys.ok, "Failed to fetch API keys");
73
79
 
74
80
  return await keys.json();
75
81
  },
@@ -78,6 +84,12 @@ const createDefaultHandler = (endpoint: string): ApiKeyService => {
78
84
 
79
85
  const ProtectedRoute = () => {
80
86
  const auth = useAuth();
87
+
88
+ // TODO: should we suspend here somehow?
89
+ if (auth.isPending) {
90
+ return null;
91
+ }
92
+
81
93
  return auth.isAuthenticated ? (
82
94
  <Outlet />
83
95
  ) : (
@@ -88,6 +100,18 @@ const ProtectedRoute = () => {
88
100
  );
89
101
  };
90
102
 
103
+ const SettingsErrorBoundary = () => {
104
+ const error = useRouteError();
105
+ logger.error(String(error));
106
+
107
+ return (
108
+ <div className="flex flex-col justify-center gap-2 items-center h-1/2 my-12">
109
+ <h1>Something went wrong</h1>
110
+ {error instanceof Error && <p>{error.message}</p>}
111
+ </div>
112
+ );
113
+ };
114
+
91
115
  export const apiKeyPlugin = (
92
116
  options: ApiKeyPluginOptions,
93
117
  ): DevPortalPlugin & ApiIdentityPlugin => {
@@ -118,14 +142,15 @@ export const apiKeyPlugin = (
118
142
  return [
119
143
  {
120
144
  element: <ProtectedRoute />,
145
+ errorElement: <SettingsErrorBoundary />,
121
146
  children: [
122
147
  {
123
148
  path: "/settings/api-keys",
124
- element: <SettingsApiKeys options={options} service={service} />,
149
+ element: <SettingsApiKeys service={service} />,
125
150
  },
126
151
  {
127
152
  path: "/settings/api-keys/new",
128
- element: <CreateApiKey options={options} service={service} />,
153
+ element: <CreateApiKey service={service} />,
129
154
  },
130
155
  ],
131
156
  },