zudoku 0.3.0-dev.57 → 0.3.0-dev.59

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 (199) hide show
  1. package/dist/app/entry.client.js +1 -1
  2. package/dist/app/entry.client.js.map +1 -1
  3. package/dist/app/entry.server.d.ts +2 -0
  4. package/dist/app/entry.server.js +1 -0
  5. package/dist/app/entry.server.js.map +1 -1
  6. package/dist/app/main.js +8 -2
  7. package/dist/app/main.js.map +1 -1
  8. package/dist/config/validators/validate.d.ts +121 -102
  9. package/dist/config/validators/validate.js +4 -0
  10. package/dist/config/validators/validate.js.map +1 -1
  11. package/dist/lib/authentication/AuthenticationPlugin.d.ts +16 -0
  12. package/dist/lib/authentication/AuthenticationPlugin.js +31 -0
  13. package/dist/lib/authentication/AuthenticationPlugin.js.map +1 -0
  14. package/dist/lib/authentication/authentication.d.ts +3 -4
  15. package/dist/lib/authentication/components/Login.d.ts +1 -0
  16. package/dist/lib/authentication/components/Login.js +10 -0
  17. package/dist/lib/authentication/components/Login.js.map +1 -0
  18. package/dist/lib/authentication/components/Logout.d.ts +1 -0
  19. package/dist/lib/authentication/components/Logout.js +10 -0
  20. package/dist/lib/authentication/components/Logout.js.map +1 -0
  21. package/dist/lib/authentication/providers/clerk.js +43 -27
  22. package/dist/lib/authentication/providers/clerk.js.map +1 -1
  23. package/dist/lib/authentication/providers/openid.d.ts +11 -3
  24. package/dist/lib/authentication/providers/openid.js +22 -11
  25. package/dist/lib/authentication/providers/openid.js.map +1 -1
  26. package/dist/lib/authentication/routes.d.ts +5 -0
  27. package/dist/lib/authentication/routes.js +12 -0
  28. package/dist/lib/authentication/routes.js.map +1 -0
  29. package/dist/lib/components/Bootstrap.d.ts +2 -1
  30. package/dist/lib/components/Bootstrap.js +4 -1
  31. package/dist/lib/components/Bootstrap.js.map +1 -1
  32. package/dist/lib/components/DevPortal.js +14 -2
  33. package/dist/lib/components/DevPortal.js.map +1 -1
  34. package/dist/lib/components/Header.js +16 -2
  35. package/dist/lib/components/Header.js.map +1 -1
  36. package/dist/lib/components/InlineCode.js +1 -1
  37. package/dist/lib/components/InlineCode.js.map +1 -1
  38. package/dist/lib/components/TopNavigation.js +1 -1
  39. package/dist/lib/components/TopNavigation.js.map +1 -1
  40. package/dist/lib/components/context/DevPortalProvider.js +18 -1
  41. package/dist/lib/components/context/DevPortalProvider.js.map +1 -1
  42. package/dist/lib/components/index.d.ts +5 -1
  43. package/dist/lib/components/index.js +4 -0
  44. package/dist/lib/components/index.js.map +1 -1
  45. package/dist/lib/components/navigation/SideNavigationItem.js +1 -1
  46. package/dist/lib/components/navigation/SideNavigationItem.js.map +1 -1
  47. package/dist/lib/core/DevPortalContext.d.ts +1 -1
  48. package/dist/lib/core/DevPortalContext.js.map +1 -1
  49. package/dist/lib/core/plugins.d.ts +10 -1
  50. package/dist/lib/core/plugins.js +1 -0
  51. package/dist/lib/core/plugins.js.map +1 -1
  52. package/dist/lib/plugins/api-keys/CreateApiKey.js +1 -1
  53. package/dist/lib/plugins/api-keys/CreateApiKey.js.map +1 -1
  54. package/dist/lib/plugins/api-keys/SettingsApiKeys.js +2 -2
  55. package/dist/lib/plugins/api-keys/SettingsApiKeys.js.map +1 -1
  56. package/dist/lib/plugins/api-keys/index.d.ts +2 -2
  57. package/dist/lib/plugins/api-keys/index.js +6 -0
  58. package/dist/lib/plugins/api-keys/index.js.map +1 -1
  59. package/dist/lib/plugins/custom-page/index.d.ts +8 -0
  60. package/dist/lib/plugins/custom-page/index.js +12 -0
  61. package/dist/lib/plugins/custom-page/index.js.map +1 -0
  62. package/dist/lib/plugins/markdown/MdxPage.js +1 -1
  63. package/dist/lib/plugins/markdown/MdxPage.js.map +1 -1
  64. package/dist/lib/plugins/openapi/OperationListItem.js +1 -1
  65. package/dist/lib/plugins/openapi/OperationListItem.js.map +1 -1
  66. package/dist/lib/plugins/openapi/ParameterList.js +1 -1
  67. package/dist/lib/plugins/openapi/ParameterList.js.map +1 -1
  68. package/dist/lib/plugins/openapi/SchemaListViewItem.js +3 -3
  69. package/dist/lib/plugins/openapi/SchemaListViewItem.js.map +1 -1
  70. package/dist/lib/plugins/openapi/SidecarBox.js +1 -1
  71. package/dist/lib/plugins/openapi/SidecarBox.js.map +1 -1
  72. package/dist/lib/plugins/openapi/StaggeredRender.d.ts +3 -0
  73. package/dist/lib/plugins/openapi/StaggeredRender.js +10 -5
  74. package/dist/lib/plugins/openapi/StaggeredRender.js.map +1 -1
  75. package/dist/lib/plugins/openapi/playground/Playground.js +2 -2
  76. package/dist/lib/plugins/openapi/playground/Playground.js.map +1 -1
  77. package/dist/lib/ui/Card.js +1 -1
  78. package/dist/lib/ui/Card.js.map +1 -1
  79. package/dist/lib/ui/DropdownMenu.d.ts +27 -0
  80. package/dist/lib/ui/DropdownMenu.js +36 -0
  81. package/dist/lib/ui/DropdownMenu.js.map +1 -0
  82. package/dist/lib/ui/button-variants.d.ts +2 -2
  83. package/dist/lib/ui/button-variants.js +1 -0
  84. package/dist/lib/ui/button-variants.js.map +1 -1
  85. package/dist/lib/util/MdxComponents.js +1 -1
  86. package/dist/lib/util/MdxComponents.js.map +1 -1
  87. package/dist/lib/util/joinPath.js +2 -1
  88. package/dist/lib/util/joinPath.js.map +1 -1
  89. package/dist/vite/build.js +5 -2
  90. package/dist/vite/build.js.map +1 -1
  91. package/dist/vite/config.d.ts +8 -1
  92. package/dist/vite/config.js +13 -6
  93. package/dist/vite/config.js.map +1 -1
  94. package/dist/vite/plugin-component.js +1 -0
  95. package/dist/vite/plugin-component.js.map +1 -1
  96. package/dist/vite/prerender.d.ts +1 -1
  97. package/dist/vite/prerender.js +23 -3
  98. package/dist/vite/prerender.js.map +1 -1
  99. package/lib/{AnchorLink-GNsUeGSX.js → AnchorLink-Bj1hwDuD.js} +3 -3
  100. package/lib/{AnchorLink-GNsUeGSX.js.map → AnchorLink-Bj1hwDuD.js.map} +1 -1
  101. package/lib/AuthenticationPlugin-CG6Bw32B.js +46 -0
  102. package/lib/AuthenticationPlugin-CG6Bw32B.js.map +1 -0
  103. package/lib/CategoryHeading-DMkTmmBh.js +10 -0
  104. package/lib/CategoryHeading-DMkTmmBh.js.map +1 -0
  105. package/lib/Combination-lAFQBd6U.js +2774 -0
  106. package/lib/Combination-lAFQBd6U.js.map +1 -0
  107. package/lib/DevPortalProvider-BBhQ8kgI.js +1125 -0
  108. package/lib/DevPortalProvider-BBhQ8kgI.js.map +1 -0
  109. package/lib/{Markdown-DtLFdxD1.js → Markdown-BjRJKl_E.js} +1376 -1379
  110. package/lib/Markdown-BjRJKl_E.js.map +1 -0
  111. package/lib/{MdxPage-CbwYRKf5.js → MdxPage-DJTFOCbZ.js} +17 -17
  112. package/lib/{MdxPage-CbwYRKf5.js.map → MdxPage-DJTFOCbZ.js.map} +1 -1
  113. package/lib/OperationList-DDTtK3I7.js +5403 -0
  114. package/lib/OperationList-DDTtK3I7.js.map +1 -0
  115. package/lib/{Route-C1LyvITr.js → Route-Bsrd0acQ.js} +2 -2
  116. package/lib/{Route-C1LyvITr.js.map → Route-Bsrd0acQ.js.map} +1 -1
  117. package/lib/Select-CEnkyfyn.js +2223 -0
  118. package/lib/Select-CEnkyfyn.js.map +1 -0
  119. package/lib/Spinner-Ciq_pWU7.js +359 -0
  120. package/lib/Spinner-Ciq_pWU7.js.map +1 -0
  121. package/lib/{hook-Biq3zYel.js → hook-Q_gAL2NZ.js} +20 -19
  122. package/lib/{hook-Biq3zYel.js.map → hook-Q_gAL2NZ.js.map} +1 -1
  123. package/lib/{index-Bg82-bqR.js → index-BE2a6gGC.js} +24 -23
  124. package/lib/{index-Bg82-bqR.js.map → index-BE2a6gGC.js.map} +1 -1
  125. package/lib/{jsx-runtime-CJZJivg2.js → jsx-runtime-BIr0WBt_.js} +119 -119
  126. package/lib/jsx-runtime-BIr0WBt_.js.map +1 -0
  127. package/lib/{router-CBw2vqJE.js → router-BiRCp01d.js} +671 -673
  128. package/lib/router-BiRCp01d.js.map +1 -0
  129. package/lib/zudoku.auth-clerk.js +47 -32
  130. package/lib/zudoku.auth-clerk.js.map +1 -1
  131. package/lib/zudoku.auth-openid.js +170 -159
  132. package/lib/zudoku.auth-openid.js.map +1 -1
  133. package/lib/zudoku.components.js +1514 -598
  134. package/lib/zudoku.components.js.map +1 -1
  135. package/lib/zudoku.plugin-api-keys.js +30 -24
  136. package/lib/zudoku.plugin-api-keys.js.map +1 -1
  137. package/lib/zudoku.plugin-custom-page.js +13 -0
  138. package/lib/zudoku.plugin-custom-page.js.map +1 -0
  139. package/lib/zudoku.plugin-markdown.js +19 -20
  140. package/lib/zudoku.plugin-markdown.js.map +1 -1
  141. package/lib/zudoku.plugin-openapi.js +4 -4
  142. package/lib/zudoku.plugin-redirect.js +3 -3
  143. package/package.json +29 -14
  144. package/src/app/entry.client.tsx +1 -1
  145. package/src/app/entry.server.tsx +2 -0
  146. package/src/app/main.css +6 -0
  147. package/src/app/main.tsx +8 -2
  148. package/src/lib/authentication/AuthenticationPlugin.tsx +36 -0
  149. package/src/lib/authentication/authentication.ts +3 -4
  150. package/src/lib/authentication/components/Login.tsx +11 -0
  151. package/src/lib/authentication/components/Logout.tsx +11 -0
  152. package/src/lib/authentication/providers/clerk.tsx +43 -27
  153. package/src/lib/authentication/providers/openid.tsx +25 -13
  154. package/src/lib/authentication/routes.tsx +10 -0
  155. package/src/lib/components/Bootstrap.tsx +14 -7
  156. package/src/lib/components/DevPortal.tsx +29 -9
  157. package/src/lib/components/Header.tsx +80 -30
  158. package/src/lib/components/InlineCode.tsx +1 -1
  159. package/src/lib/components/TopNavigation.tsx +1 -1
  160. package/src/lib/components/context/DevPortalProvider.ts +22 -2
  161. package/src/lib/components/index.ts +4 -0
  162. package/src/lib/components/navigation/SideNavigationItem.tsx +1 -1
  163. package/src/lib/core/DevPortalContext.ts +1 -1
  164. package/src/lib/core/plugins.ts +16 -0
  165. package/src/lib/plugins/api-keys/CreateApiKey.tsx +1 -1
  166. package/src/lib/plugins/api-keys/SettingsApiKeys.tsx +4 -4
  167. package/src/lib/plugins/api-keys/index.tsx +8 -1
  168. package/src/lib/plugins/custom-page/index.tsx +22 -0
  169. package/src/lib/plugins/markdown/MdxPage.tsx +2 -2
  170. package/src/lib/plugins/openapi/OperationListItem.tsx +1 -4
  171. package/src/lib/plugins/openapi/ParameterList.tsx +1 -1
  172. package/src/lib/plugins/openapi/SchemaListViewItem.tsx +3 -3
  173. package/src/lib/plugins/openapi/SidecarBox.tsx +1 -1
  174. package/src/lib/plugins/openapi/StaggeredRender.tsx +19 -5
  175. package/src/lib/plugins/openapi/playground/Playground.tsx +2 -2
  176. package/src/lib/ui/Card.tsx +1 -1
  177. package/src/lib/ui/DropdownMenu.tsx +199 -0
  178. package/src/lib/ui/button-variants.ts +1 -0
  179. package/src/lib/util/MdxComponents.tsx +1 -1
  180. package/src/lib/util/joinPath.tsx +2 -1
  181. package/dist/app/zudoku-manifest.d.ts +0 -1
  182. package/dist/app/zudoku-manifest.js +0 -20
  183. package/dist/app/zudoku-manifest.js.map +0 -1
  184. package/lib/Button-DpHMZvVs.js +0 -4571
  185. package/lib/Button-DpHMZvVs.js.map +0 -1
  186. package/lib/DevPortalProvider-Do9oJqme.js +0 -1081
  187. package/lib/DevPortalProvider-Do9oJqme.js.map +0 -1
  188. package/lib/Markdown-DtLFdxD1.js.map +0 -1
  189. package/lib/OperationList-DypxLtSC.js +0 -5578
  190. package/lib/OperationList-DypxLtSC.js.map +0 -1
  191. package/lib/Spinner-Bhbs5aPI.js +0 -182
  192. package/lib/Spinner-Bhbs5aPI.js.map +0 -1
  193. package/lib/index-gsAuUwQh.js +0 -418
  194. package/lib/index-gsAuUwQh.js.map +0 -1
  195. package/lib/jsx-runtime-CJZJivg2.js.map +0 -1
  196. package/lib/router-CBw2vqJE.js.map +0 -1
  197. package/lib/util-_jwUlTBU.js +0 -41
  198. package/lib/util-_jwUlTBU.js.map +0 -1
  199. package/src/app/zudoku-manifest.ts +0 -22
@@ -1,18 +1,18 @@
1
- import { j as e, a as j, O as v } from "./jsx-runtime-CJZJivg2.js";
2
- import { u as b, R as w } from "./hook-Biq3zYel.js";
3
- import { u as k, a as h, S as N, b as K, c as E, d as A, e as S, f as p, B as o } from "./Button-DpHMZvVs.js";
4
- import { c as l, e as m, L as x } from "./Markdown-DtLFdxD1.js";
5
- import { u as y, q as D, t as P } from "./DevPortalProvider-Do9oJqme.js";
1
+ import { j as e, b as j, O as v } from "./jsx-runtime-BIr0WBt_.js";
2
+ import { u as w, R as b } from "./hook-Q_gAL2NZ.js";
3
+ import { u as k, a as h, S as N, b as K, c as E, d as A, e as P, f as p } from "./Select-CEnkyfyn.js";
4
+ import { c, a as m, L as x } from "./Markdown-BjRJKl_E.js";
5
+ import { u as y, x as S, y as I } from "./DevPortalProvider-BBhQ8kgI.js";
6
6
  import * as C from "react";
7
- import { useState as I } from "react";
8
- import { D as R } from "./index-gsAuUwQh.js";
7
+ import { useState as D } from "react";
8
+ import { B as o, p as R } from "./Combination-lAFQBd6U.js";
9
9
  /**
10
10
  * @license lucide-react v0.378.0 - ISC
11
11
  *
12
12
  * This source code is licensed under the ISC license.
13
13
  * See the LICENSE file in the root directory of this source tree.
14
14
  */
15
- const O = l("EyeOff", [
15
+ const O = c("EyeOff", [
16
16
  ["path", { d: "M9.88 9.88a3 3 0 1 0 4.24 4.24", key: "1jxqfv" }],
17
17
  [
18
18
  "path",
@@ -33,7 +33,7 @@ const O = l("EyeOff", [
33
33
  * This source code is licensed under the ISC license.
34
34
  * See the LICENSE file in the root directory of this source tree.
35
35
  */
36
- const q = l("Eye", [
36
+ const q = c("Eye", [
37
37
  ["path", { d: "M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z", key: "rwhkz3" }],
38
38
  ["circle", { cx: "12", cy: "12", r: "3", key: "1v7zrd" }]
39
39
  ]);
@@ -43,7 +43,7 @@ const q = l("Eye", [
43
43
  * This source code is licensed under the ISC license.
44
44
  * See the LICENSE file in the root directory of this source tree.
45
45
  */
46
- const z = l("RotateCw", [
46
+ const z = c("RotateCw", [
47
47
  ["path", { d: "M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8", key: "1p45f6" }],
48
48
  ["path", { d: "M21 3v5h-5", key: "1q7to0" }]
49
49
  ]);
@@ -53,7 +53,7 @@ const z = l("RotateCw", [
53
53
  * This source code is licensed under the ISC license.
54
54
  * See the LICENSE file in the root directory of this source tree.
55
55
  */
56
- const M = l("Trash", [
56
+ const M = c("Trash", [
57
57
  ["path", { d: "M3 6h18", key: "d0wm0j" }],
58
58
  ["path", { d: "M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6", key: "4alrt4" }],
59
59
  ["path", { d: "M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2", key: "v07s0e" }]
@@ -88,10 +88,10 @@ const T = ({ service: t }) => {
88
88
  expiresOn: "30"
89
89
  }
90
90
  }), i = h({
91
- mutationFn: ({ description: s, expiresOn: c }) => {
91
+ mutationFn: ({ description: s, expiresOn: l }) => {
92
92
  if (!t.createKey)
93
93
  throw new Error("deleteKey not implemented");
94
- const g = c !== "never" ? V(Number(c)) : void 0;
94
+ const g = l !== "never" ? V(Number(l)) : void 0;
95
95
  return t.createKey(
96
96
  { description: s, expiresOn: g },
97
97
  n
@@ -100,7 +100,7 @@ const T = ({ service: t }) => {
100
100
  onSuccess: () => a("/settings/api-keys/")
101
101
  });
102
102
  return t.createKey ? /* @__PURE__ */ e.jsxs("div", { className: "max-w-screen-lg pt-[--padding-content-top] pb-[--padding-content-bottom]", children: [
103
- /* @__PURE__ */ e.jsx("div", { className: "flex justify-between mb-4 border-b border-border pb-1", children: /* @__PURE__ */ e.jsx("h1", { className: "font-medium text-2xl", children: "New API Key" }) }),
103
+ /* @__PURE__ */ e.jsx("div", { className: "flex justify-between mb-4 border-b pb-1", children: /* @__PURE__ */ e.jsx("h1", { className: "font-medium text-2xl", children: "New API Key" }) }),
104
104
  /* @__PURE__ */ e.jsx(
105
105
  "form",
106
106
  {
@@ -116,7 +116,7 @@ const T = ({ service: t }) => {
116
116
  defaultValue: r.getValues("expiresOn"),
117
117
  children: [
118
118
  /* @__PURE__ */ e.jsx(K, { children: /* @__PURE__ */ e.jsx(E, {}) }),
119
- /* @__PURE__ */ e.jsx(A, { children: /* @__PURE__ */ e.jsxs(S, { children: [
119
+ /* @__PURE__ */ e.jsx(A, { children: /* @__PURE__ */ e.jsxs(P, { children: [
120
120
  [7, 30, 60, 90].map((s) => /* @__PURE__ */ e.jsxs(p, { value: String(s), children: [
121
121
  s,
122
122
  " days"
@@ -138,7 +138,7 @@ const T = ({ service: t }) => {
138
138
  const n = /* @__PURE__ */ new Date();
139
139
  return n.setDate(n.getDate() + t), n.toISOString();
140
140
  }, F = () => {
141
- const t = b();
141
+ const t = w();
142
142
  return t.isAuthEnabled && t.isPending ? null : t.isAuthenticated ? /* @__PURE__ */ e.jsx(v, {}) : t.isAuthEnabled ? /* @__PURE__ */ e.jsxs("div", { className: "flex flex-col justify-center gap-2 items-center h-1/2", children: [
143
143
  "Please login first to view this page",
144
144
  /* @__PURE__ */ e.jsx(o, { onClick: () => t.login(), children: "Login" })
@@ -148,7 +148,7 @@ const T = ({ service: t }) => {
148
148
  "."
149
149
  ] }) });
150
150
  }, _ = ({ service: t }) => {
151
- const n = y(), a = D(), { data: r } = P({
151
+ const n = y(), a = S(), { data: r } = I({
152
152
  queryFn: () => t.getKeys(n),
153
153
  queryKey: ["api-keys"],
154
154
  retry: !1
@@ -163,7 +163,7 @@ const T = ({ service: t }) => {
163
163
  }
164
164
  });
165
165
  return /* @__PURE__ */ e.jsxs("div", { className: "max-w-screen-lg h-full pt-[--padding-content-top] pb-[--padding-content-bottom]", children: [
166
- /* @__PURE__ */ e.jsxs("div", { className: "flex justify-between mb-4 border-b border-border pb-3", children: [
166
+ /* @__PURE__ */ e.jsxs("div", { className: "flex justify-between mb-4 border-b pb-3", children: [
167
167
  /* @__PURE__ */ e.jsx("h1", { className: "font-medium text-2xl", children: "API Keys" }),
168
168
  t.createKey && /* @__PURE__ */ e.jsx(o, { asChild: !0, children: /* @__PURE__ */ e.jsx(x, { to: "/settings/api-keys/new", children: "Create API Key" }) })
169
169
  ] }),
@@ -178,13 +178,13 @@ const T = ({ service: t }) => {
178
178
  "ul",
179
179
  {
180
180
  className: m(
181
- "grid grid-cols-1 rounded border-border border",
181
+ "grid grid-cols-1 rounded border",
182
182
  "lg:grid-cols-[minmax(250px,min-content)_1fr_min-content]"
183
183
  ),
184
184
  children: r.map((s) => /* @__PURE__ */ e.jsxs(
185
185
  "li",
186
186
  {
187
- className: "border-b border-border p-5 grid grid-cols-subgrid col-span-full gap-2 items-center",
187
+ className: "border-b p-5 grid grid-cols-subgrid col-span-full gap-2 items-center",
188
188
  children: [
189
189
  /* @__PURE__ */ e.jsxs("div", { className: "flex flex-col gap-1 text-sm", children: [
190
190
  s.description ?? s.id,
@@ -223,12 +223,12 @@ const T = ({ service: t }) => {
223
223
  )
224
224
  ] });
225
225
  }, B = ({ apiKey: t }) => {
226
- const [n, a] = I(!1);
226
+ const [n, a] = D(!1);
227
227
  return /* @__PURE__ */ e.jsxs("div", { className: "flex gap-2 items-center text-sm w-full", children: [
228
228
  /* @__PURE__ */ e.jsx(
229
229
  "input",
230
230
  {
231
- className: "border border-border rounded bg-gray-100 dark:bg-gray-950 p-1 font-mono max-w-min",
231
+ className: "border rounded bg-gray-100 dark:bg-gray-950 p-1 font-mono max-w-min",
232
232
  value: n ? t : "•".repeat(t.length)
233
233
  }
234
234
  ),
@@ -272,10 +272,16 @@ const T = ({ service: t }) => {
272
272
  }), X = (t) => {
273
273
  const n = "endpoint" in t ? t.endpoint : G, a = "getKeys" in t ? t : H(n);
274
274
  return {
275
+ getProfileMenuItems: () => [
276
+ {
277
+ label: "API Keys",
278
+ path: "/settings/api-keys"
279
+ }
280
+ ],
275
281
  getIdentities: async (r) => {
276
282
  try {
277
283
  return (await a.getKeys(r)).map((s) => ({
278
- authorizeRequest: (c) => (c.headers.set("Authorization", `Bearer ${s.key}`), c),
284
+ authorizeRequest: (l) => (l.headers.set("Authorization", `Bearer ${s.key}`), l),
279
285
  id: s.id,
280
286
  label: s.description ?? s.id
281
287
  }));
@@ -286,7 +292,7 @@ const T = ({ service: t }) => {
286
292
  getRoutes: () => [
287
293
  {
288
294
  element: /* @__PURE__ */ e.jsx(F, {}),
289
- errorElement: /* @__PURE__ */ e.jsx(w, {}),
295
+ errorElement: /* @__PURE__ */ e.jsx(b, {}),
290
296
  children: [
291
297
  {
292
298
  path: "/settings/api-keys",
@@ -1 +1 @@
1
- {"version":3,"file":"zudoku.plugin-api-keys.js","sources":["../../../node_modules/.pnpm/lucide-react@0.378.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/eye-off.js","../../../node_modules/.pnpm/lucide-react@0.378.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/eye.js","../../../node_modules/.pnpm/lucide-react@0.378.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/rotate-cw.js","../../../node_modules/.pnpm/lucide-react@0.378.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/trash.js","../../../node_modules/.pnpm/tiny-invariant@1.3.3/node_modules/tiny-invariant/dist/esm/tiny-invariant.js","../src/lib/components/Input.tsx","../src/lib/plugins/api-keys/CreateApiKey.tsx","../src/lib/plugins/api-keys/ProtectedRoute.tsx","../src/lib/plugins/api-keys/SettingsApiKeys.tsx","../src/lib/plugins/api-keys/index.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.378.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst EyeOff = createLucideIcon(\"EyeOff\", [\n [\"path\", { d: \"M9.88 9.88a3 3 0 1 0 4.24 4.24\", key: \"1jxqfv\" }],\n [\n \"path\",\n {\n d: \"M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68\",\n key: \"9wicm4\"\n }\n ],\n [\n \"path\",\n { d: \"M6.61 6.61A13.526 13.526 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61\", key: \"1jreej\" }\n ],\n [\"line\", { x1: \"2\", x2: \"22\", y1: \"2\", y2: \"22\", key: \"a6p6uj\" }]\n]);\n\nexport { EyeOff as default };\n//# sourceMappingURL=eye-off.js.map\n","/**\n * @license lucide-react v0.378.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Eye = createLucideIcon(\"Eye\", [\n [\"path\", { d: \"M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z\", key: \"rwhkz3\" }],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"3\", key: \"1v7zrd\" }]\n]);\n\nexport { Eye as default };\n//# sourceMappingURL=eye.js.map\n","/**\n * @license lucide-react v0.378.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst RotateCw = createLucideIcon(\"RotateCw\", [\n [\"path\", { d: \"M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8\", key: \"1p45f6\" }],\n [\"path\", { d: \"M21 3v5h-5\", key: \"1q7to0\" }]\n]);\n\nexport { RotateCw as default };\n//# sourceMappingURL=rotate-cw.js.map\n","/**\n * @license lucide-react v0.378.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Trash = createLucideIcon(\"Trash\", [\n [\"path\", { d: \"M3 6h18\", key: \"d0wm0j\" }],\n [\"path\", { d: \"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6\", key: \"4alrt4\" }],\n [\"path\", { d: \"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2\", key: \"v07s0e\" }]\n]);\n\nexport { Trash as default };\n//# sourceMappingURL=trash.js.map\n","var isProduction = process.env.NODE_ENV === 'production';\nvar prefix = 'Invariant failed';\nfunction invariant(condition, message) {\n if (condition) {\n return;\n }\n if (isProduction) {\n throw new Error(prefix);\n }\n var provided = typeof message === 'function' ? message() : message;\n var value = provided ? \"\".concat(prefix, \": \").concat(provided) : prefix;\n throw new Error(value);\n}\n\nexport { invariant as default };\n","import * as React from \"react\";\nimport { cn } from \"../util/cn.js\";\n\nexport interface InputProps\n extends React.InputHTMLAttributes<HTMLInputElement> {}\n\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(\n ({ className, type, ...props }, ref) => {\n return (\n <input\n type={type}\n className={cn(\n \"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\",\n className,\n )}\n ref={ref}\n {...props}\n />\n );\n },\n);\nInput.displayName = \"Input\";\n\nexport { Input };\n","import { useMutation } from \"@tanstack/react-query\";\nimport { useForm } from \"react-hook-form\";\nimport { Link, useNavigate } from \"react-router-dom\";\nimport { useDevPortal } from \"../../components/context/DevPortalProvider.js\";\nimport { Input } from \"../../components/Input.js\";\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../../components/Select.js\";\nimport { Button } from \"../../ui/Button.js\";\nimport { ApiKeyService } from \"./index.js\";\n\ntype CreateApiKey = { description: string; expiresOn?: string };\n\nexport const CreateApiKey = ({ service }: { service: ApiKeyService }) => {\n const context = useDevPortal();\n const navigate = useNavigate();\n const form = useForm<CreateApiKey>({\n defaultValues: {\n expiresOn: \"30\",\n },\n });\n const createKeyMutation = useMutation({\n mutationFn: ({ description, expiresOn }: CreateApiKey) => {\n if (!service.createKey) {\n throw new Error(\"deleteKey not implemented\");\n }\n\n const expiresOnDate =\n expiresOn !== \"never\" ? addDaysToDate(Number(expiresOn)) : undefined;\n\n return service.createKey(\n { description: description, expiresOn: expiresOnDate },\n context,\n );\n },\n onSuccess: () => navigate(\"/settings/api-keys/\"),\n });\n\n if (!service.createKey) {\n return null;\n }\n\n return (\n <div className=\"max-w-screen-lg pt-[--padding-content-top] pb-[--padding-content-bottom]\">\n <div className=\"flex justify-between mb-4 border-b border-border pb-1\">\n <h1 className=\"font-medium text-2xl\">New API Key</h1>\n </div>\n <form\n onSubmit={form.handleSubmit((data) => createKeyMutation.mutate(data))}\n >\n <div className=\"flex gap-2 flex-col\">\n Note\n <Input {...form.register(\"description\")} />\n Expiration\n <Select\n onValueChange={(value) => form.setValue(\"expiresOn\", value)}\n defaultValue={form.getValues(\"expiresOn\")}\n >\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectGroup>\n {[7, 30, 60, 90].map((option) => (\n <SelectItem value={String(option)} key={option}>\n {option} days\n </SelectItem>\n ))}\n <SelectItem value=\"never\">Never</SelectItem>\n </SelectGroup>\n </SelectContent>\n </Select>\n <div className=\"flex gap-2\">\n <Button>Generate Key</Button>\n <Button variant=\"outline\" asChild>\n <Link to=\"/settings/api-keys/\">Cancel</Link>\n </Button>\n </div>\n </div>\n </form>\n </div>\n );\n};\n\nconst addDaysToDate = (days: number): string => {\n const date = new Date();\n date.setDate(date.getDate() + days);\n return date.toISOString();\n};\n","import { Outlet } from \"react-router-dom\";\nimport { useAuth } from \"../../authentication/hook.js\";\nimport { DeveloperHint } from \"../../components/DeveloperHint.js\";\nimport { Button } from \"../../ui/Button.js\";\n\nexport const ProtectedRoute = () => {\n const auth = useAuth();\n\n // TODO: should we suspend here somehow?\n if (auth.isAuthEnabled && auth.isPending) {\n return null;\n }\n\n return auth.isAuthenticated ? (\n <Outlet />\n ) : !auth.isAuthEnabled ? (\n <div className=\"flex flex-col justify-center gap-2 items-center h-1/2\">\n <DeveloperHint className=\"max-w-[600px]\">\n Authentication needs to be enabled for API keys to work. Enable it in\n your Zudoku configuration under <code>authentication</code>.\n </DeveloperHint>\n </div>\n ) : (\n <div className=\"flex flex-col justify-center gap-2 items-center h-1/2\">\n Please login first to view this page\n <Button onClick={() => auth.login()}>Login</Button>\n </div>\n );\n};\n","import {\n useMutation,\n useQueryClient,\n useSuspenseQuery,\n} from \"@tanstack/react-query\";\nimport { EyeIcon, EyeOffIcon, RotateCwIcon, TrashIcon } from \"lucide-react\";\nimport { useState } from \"react\";\nimport { Link } from \"react-router-dom\";\nimport { useDevPortal } from \"../../components/context/DevPortalProvider.js\";\nimport { Button } from \"../../ui/Button.js\";\nimport { cn } from \"../../util/cn.js\";\nimport { ApiKeyService } from \"./index.js\";\n\nexport const SettingsApiKeys = ({ service }: { service: ApiKeyService }) => {\n const context = useDevPortal();\n const queryClient = useQueryClient();\n const { data } = useSuspenseQuery({\n queryFn: () => service.getKeys(context),\n queryKey: [\"api-keys\"],\n retry: false,\n });\n\n const deleteKeyMutation = useMutation({\n mutationFn: (id: string) => {\n if (!service.deleteKey) {\n throw new Error(\"deleteKey not implemented\");\n }\n\n return service.deleteKey(id, context);\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [\"api-keys\"] });\n },\n });\n\n return (\n <div className=\"max-w-screen-lg h-full pt-[--padding-content-top] pb-[--padding-content-bottom]\">\n <div className=\"flex justify-between mb-4 border-b border-border pb-3\">\n <h1 className=\"font-medium text-2xl\">API Keys</h1>\n {service.createKey && (\n <Button asChild>\n <Link to=\"/settings/api-keys/new\">Create API Key</Link>\n </Button>\n )}\n </div>\n\n {data.length === 0 ? (\n <div className=\"flex flex-col justify-center gap-4 items-center h-1/2 my-8\">\n <div className=\"text-center\">\n No API keys created yet.\n <br />\n Get started and create the first one now\n </div>\n {service.createKey && (\n <Button asChild>\n <Link to=\"/settings/api-keys/new\">Create API Key</Link>\n </Button>\n )}\n </div>\n ) : (\n <ul\n className={cn(\n \"grid grid-cols-1 rounded border-border border\",\n \"lg:grid-cols-[minmax(250px,min-content)_1fr_min-content]\",\n )}\n >\n {data.map((key) => (\n <li\n className=\"border-b border-border p-5 grid grid-cols-subgrid col-span-full gap-2 items-center\"\n key={key.id}\n >\n <div className=\"flex flex-col gap-1 text-sm\">\n {key.description ?? key.id}\n <div className=\"text-muted-foreground text-xs\">\n {key.createdOn && (\n <div>\n Created on {new Date(key.createdOn).toLocaleDateString()}\n </div>\n )}\n {key.expiresOn && (\n <div>\n Expires on {new Date(key.expiresOn).toLocaleDateString()}\n </div>\n )}\n </div>\n </div>\n <div className=\"items-center flex lg:justify-center\">\n <RevealApiKey apiKey={key.key} />\n </div>\n <div className=\"flex gap-2\">\n {service.rollKey && (\n <Button size=\"icon\">\n <RotateCwIcon size={16} />\n </Button>\n )}\n {service.deleteKey && (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => {\n if (!confirm(\"Do you want to delete this key?\")) {\n return;\n }\n\n deleteKeyMutation.mutate(key.id);\n }}\n disabled={deleteKeyMutation.isPending}\n >\n <TrashIcon size={16} />\n </Button>\n )}\n </div>\n </li>\n ))}\n </ul>\n )}\n </div>\n );\n};\n\nconst RevealApiKey = ({ apiKey }: { apiKey: string }) => {\n const [revealed, setRevealed] = useState(false);\n\n return (\n <div className=\"flex gap-2 items-center text-sm w-full\">\n <input\n className=\"border border-border rounded bg-gray-100 dark:bg-gray-950 p-1 font-mono max-w-min\"\n value={revealed ? apiKey : \"•\".repeat(apiKey.length)}\n />\n <Button\n variant=\"outline\"\n onClick={() => setRevealed((prev) => !prev)}\n size=\"icon\"\n >\n {revealed ? <EyeOffIcon size={16} /> : <EyeIcon size={16} />}\n </Button>\n </div>\n );\n};\n","import { type RouteObject } from \"react-router-dom\";\nimport invariant from \"tiny-invariant\";\nimport { DevPortalContext } from \"../../core/DevPortalContext.js\";\nimport {\n type ApiIdentityPlugin,\n type DevPortalPlugin,\n} from \"../../core/plugins.js\";\nimport { RouterError } from \"../../errors/RouterError.js\";\nimport { CreateApiKey } from \"./CreateApiKey.js\";\nimport { ProtectedRoute } from \"./ProtectedRoute.js\";\nimport { SettingsApiKeys } from \"./SettingsApiKeys.js\";\n\nconst DEFAULT_API_KEY_ENDPOINT =\n \"https://zudoku-rewiringamerica-main-ef9c9c0.d2.zuplo.dev\";\n\nexport type ApiKeyService = {\n getKeys: (context: DevPortalContext) => Promise<ApiKey[]>;\n rollKey?: (id: string, context: DevPortalContext) => Promise<void>;\n deleteKey?: (id: string, context: DevPortalContext) => Promise<void>;\n updateKeyDescription?: (\n apiKey: { id: string; description: string },\n context: DevPortalContext,\n ) => Promise<void>;\n getUsage?: (apiKeys: string[], context: DevPortalContext) => Promise<void>;\n createKey?: (\n apiKey: { description: string; expiresOn?: string },\n context: DevPortalContext,\n ) => Promise<void>;\n};\n\nexport type GetApiKeysOptions = ApiKeyService | { endpoint: string } | object;\n\nexport type ApiKeyPluginOptions = object & GetApiKeysOptions;\n\nexport interface ApiKey {\n id: string;\n description?: string;\n createdOn?: string;\n updatedOn?: string;\n expiresOn?: string;\n key: string;\n}\n\nconst createDefaultHandler = (endpoint: string): ApiKeyService => {\n return {\n deleteKey: async (id, context) => {\n const request = new Request(endpoint + `/v1/developer/api-keys/${id}`, {\n method: \"DELETE\",\n });\n\n await context.signRequest(request);\n\n const response = await fetch(request);\n invariant(response.ok, \"Failed to delete API key\");\n },\n createKey: async (apiKey, context) => {\n const request = new Request(endpoint + `/v1/developer/api-keys`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(apiKey),\n });\n\n await context.signRequest(request);\n\n const response = await fetch(request);\n invariant(response.ok, \"Failed to create API key\");\n },\n getKeys: async (context) => {\n const request = new Request(endpoint + `/v1/developer/api-keys`);\n\n await context.signRequest(request);\n\n const keys = await fetch(request);\n invariant(keys.ok, \"Failed to fetch API keys\");\n\n return await keys.json();\n },\n };\n};\n\nexport const apiKeyPlugin = (\n options: ApiKeyPluginOptions,\n): DevPortalPlugin & ApiIdentityPlugin => {\n const endpoint =\n \"endpoint\" in options ? options.endpoint : DEFAULT_API_KEY_ENDPOINT;\n\n const service =\n \"getKeys\" in options ? options : createDefaultHandler(endpoint);\n\n return {\n getIdentities: async (context) => {\n try {\n const keys = await service.getKeys(context);\n\n return keys.map((key) => ({\n authorizeRequest: (request) => {\n request.headers.set(\"Authorization\", `Bearer ${key.key}`);\n return request;\n },\n id: key.id,\n label: key.description ?? key.id,\n }));\n } catch {\n return [];\n }\n },\n getRoutes: (): RouteObject[] => {\n // TODO: Make lazy\n return [\n {\n element: <ProtectedRoute />,\n errorElement: <RouterError />,\n children: [\n {\n path: \"/settings/api-keys\",\n element: <SettingsApiKeys service={service} />,\n },\n {\n path: \"/settings/api-keys/new\",\n element: <CreateApiKey service={service} />,\n },\n ],\n },\n ];\n },\n };\n};\n"],"names":["EyeOff","createLucideIcon","Eye","RotateCw","Trash","isProduction","prefix","invariant","condition","message","provided","value","Input","React","className","type","props","ref","jsx","cn","CreateApiKey","service","context","useDevPortal","navigate","useNavigate","form","useForm","createKeyMutation","useMutation","description","expiresOn","expiresOnDate","addDaysToDate","jsxs","data","Select","SelectTrigger","SelectValue","SelectContent","SelectGroup","option","SelectItem","Button","Link","days","date","ProtectedRoute","auth","useAuth","Outlet","DeveloperHint","SettingsApiKeys","queryClient","useQueryClient","useSuspenseQuery","deleteKeyMutation","id","key","RevealApiKey","RotateCwIcon","TrashIcon","apiKey","revealed","setRevealed","useState","prev","EyeOffIcon","EyeIcon","DEFAULT_API_KEY_ENDPOINT","createDefaultHandler","endpoint","request","response","keys","apiKeyPlugin","options","RouterError"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4]}
1
+ {"version":3,"file":"zudoku.plugin-api-keys.js","sources":["../../../node_modules/.pnpm/lucide-react@0.378.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/eye-off.js","../../../node_modules/.pnpm/lucide-react@0.378.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/eye.js","../../../node_modules/.pnpm/lucide-react@0.378.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/rotate-cw.js","../../../node_modules/.pnpm/lucide-react@0.378.0_react@18.3.1/node_modules/lucide-react/dist/esm/icons/trash.js","../../../node_modules/.pnpm/tiny-invariant@1.3.3/node_modules/tiny-invariant/dist/esm/tiny-invariant.js","../src/lib/components/Input.tsx","../src/lib/plugins/api-keys/CreateApiKey.tsx","../src/lib/plugins/api-keys/ProtectedRoute.tsx","../src/lib/plugins/api-keys/SettingsApiKeys.tsx","../src/lib/plugins/api-keys/index.tsx"],"sourcesContent":["/**\n * @license lucide-react v0.378.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst EyeOff = createLucideIcon(\"EyeOff\", [\n [\"path\", { d: \"M9.88 9.88a3 3 0 1 0 4.24 4.24\", key: \"1jxqfv\" }],\n [\n \"path\",\n {\n d: \"M10.73 5.08A10.43 10.43 0 0 1 12 5c7 0 10 7 10 7a13.16 13.16 0 0 1-1.67 2.68\",\n key: \"9wicm4\"\n }\n ],\n [\n \"path\",\n { d: \"M6.61 6.61A13.526 13.526 0 0 0 2 12s3 7 10 7a9.74 9.74 0 0 0 5.39-1.61\", key: \"1jreej\" }\n ],\n [\"line\", { x1: \"2\", x2: \"22\", y1: \"2\", y2: \"22\", key: \"a6p6uj\" }]\n]);\n\nexport { EyeOff as default };\n//# sourceMappingURL=eye-off.js.map\n","/**\n * @license lucide-react v0.378.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Eye = createLucideIcon(\"Eye\", [\n [\"path\", { d: \"M2 12s3-7 10-7 10 7 10 7-3 7-10 7-10-7-10-7Z\", key: \"rwhkz3\" }],\n [\"circle\", { cx: \"12\", cy: \"12\", r: \"3\", key: \"1v7zrd\" }]\n]);\n\nexport { Eye as default };\n//# sourceMappingURL=eye.js.map\n","/**\n * @license lucide-react v0.378.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst RotateCw = createLucideIcon(\"RotateCw\", [\n [\"path\", { d: \"M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8\", key: \"1p45f6\" }],\n [\"path\", { d: \"M21 3v5h-5\", key: \"1q7to0\" }]\n]);\n\nexport { RotateCw as default };\n//# sourceMappingURL=rotate-cw.js.map\n","/**\n * @license lucide-react v0.378.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst Trash = createLucideIcon(\"Trash\", [\n [\"path\", { d: \"M3 6h18\", key: \"d0wm0j\" }],\n [\"path\", { d: \"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6\", key: \"4alrt4\" }],\n [\"path\", { d: \"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2\", key: \"v07s0e\" }]\n]);\n\nexport { Trash as default };\n//# sourceMappingURL=trash.js.map\n","var isProduction = process.env.NODE_ENV === 'production';\nvar prefix = 'Invariant failed';\nfunction invariant(condition, message) {\n if (condition) {\n return;\n }\n if (isProduction) {\n throw new Error(prefix);\n }\n var provided = typeof message === 'function' ? message() : message;\n var value = provided ? \"\".concat(prefix, \": \").concat(provided) : prefix;\n throw new Error(value);\n}\n\nexport { invariant as default };\n","import * as React from \"react\";\nimport { cn } from \"../util/cn.js\";\n\nexport interface InputProps\n extends React.InputHTMLAttributes<HTMLInputElement> {}\n\nconst Input = React.forwardRef<HTMLInputElement, InputProps>(\n ({ className, type, ...props }, ref) => {\n return (\n <input\n type={type}\n className={cn(\n \"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\",\n className,\n )}\n ref={ref}\n {...props}\n />\n );\n },\n);\nInput.displayName = \"Input\";\n\nexport { Input };\n","import { useMutation } from \"@tanstack/react-query\";\nimport { useForm } from \"react-hook-form\";\nimport { Link, useNavigate } from \"react-router-dom\";\nimport { useDevPortal } from \"../../components/context/DevPortalProvider.js\";\nimport { Input } from \"../../components/Input.js\";\nimport {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../../components/Select.js\";\nimport { Button } from \"../../ui/Button.js\";\nimport { ApiKeyService } from \"./index.js\";\n\ntype CreateApiKey = { description: string; expiresOn?: string };\n\nexport const CreateApiKey = ({ service }: { service: ApiKeyService }) => {\n const context = useDevPortal();\n const navigate = useNavigate();\n const form = useForm<CreateApiKey>({\n defaultValues: {\n expiresOn: \"30\",\n },\n });\n const createKeyMutation = useMutation({\n mutationFn: ({ description, expiresOn }: CreateApiKey) => {\n if (!service.createKey) {\n throw new Error(\"deleteKey not implemented\");\n }\n\n const expiresOnDate =\n expiresOn !== \"never\" ? addDaysToDate(Number(expiresOn)) : undefined;\n\n return service.createKey(\n { description: description, expiresOn: expiresOnDate },\n context,\n );\n },\n onSuccess: () => navigate(\"/settings/api-keys/\"),\n });\n\n if (!service.createKey) {\n return null;\n }\n\n return (\n <div className=\"max-w-screen-lg pt-[--padding-content-top] pb-[--padding-content-bottom]\">\n <div className=\"flex justify-between mb-4 border-b pb-1\">\n <h1 className=\"font-medium text-2xl\">New API Key</h1>\n </div>\n <form\n onSubmit={form.handleSubmit((data) => createKeyMutation.mutate(data))}\n >\n <div className=\"flex gap-2 flex-col\">\n Note\n <Input {...form.register(\"description\")} />\n Expiration\n <Select\n onValueChange={(value) => form.setValue(\"expiresOn\", value)}\n defaultValue={form.getValues(\"expiresOn\")}\n >\n <SelectTrigger>\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectGroup>\n {[7, 30, 60, 90].map((option) => (\n <SelectItem value={String(option)} key={option}>\n {option} days\n </SelectItem>\n ))}\n <SelectItem value=\"never\">Never</SelectItem>\n </SelectGroup>\n </SelectContent>\n </Select>\n <div className=\"flex gap-2\">\n <Button>Generate Key</Button>\n <Button variant=\"outline\" asChild>\n <Link to=\"/settings/api-keys/\">Cancel</Link>\n </Button>\n </div>\n </div>\n </form>\n </div>\n );\n};\n\nconst addDaysToDate = (days: number): string => {\n const date = new Date();\n date.setDate(date.getDate() + days);\n return date.toISOString();\n};\n","import { Outlet } from \"react-router-dom\";\nimport { useAuth } from \"../../authentication/hook.js\";\nimport { DeveloperHint } from \"../../components/DeveloperHint.js\";\nimport { Button } from \"../../ui/Button.js\";\n\nexport const ProtectedRoute = () => {\n const auth = useAuth();\n\n // TODO: should we suspend here somehow?\n if (auth.isAuthEnabled && auth.isPending) {\n return null;\n }\n\n return auth.isAuthenticated ? (\n <Outlet />\n ) : !auth.isAuthEnabled ? (\n <div className=\"flex flex-col justify-center gap-2 items-center h-1/2\">\n <DeveloperHint className=\"max-w-[600px]\">\n Authentication needs to be enabled for API keys to work. Enable it in\n your Zudoku configuration under <code>authentication</code>.\n </DeveloperHint>\n </div>\n ) : (\n <div className=\"flex flex-col justify-center gap-2 items-center h-1/2\">\n Please login first to view this page\n <Button onClick={() => auth.login()}>Login</Button>\n </div>\n );\n};\n","import {\n useMutation,\n useQueryClient,\n useSuspenseQuery,\n} from \"@tanstack/react-query\";\nimport { EyeIcon, EyeOffIcon, RotateCwIcon, TrashIcon } from \"lucide-react\";\nimport { useState } from \"react\";\nimport { Link } from \"react-router-dom\";\nimport { useDevPortal } from \"../../components/context/DevPortalProvider.js\";\nimport { Button } from \"../../ui/Button.js\";\nimport { cn } from \"../../util/cn.js\";\nimport { ApiKeyService } from \"./index.js\";\n\nexport const SettingsApiKeys = ({ service }: { service: ApiKeyService }) => {\n const context = useDevPortal();\n const queryClient = useQueryClient();\n const { data } = useSuspenseQuery({\n queryFn: () => service.getKeys(context),\n queryKey: [\"api-keys\"],\n retry: false,\n });\n\n const deleteKeyMutation = useMutation({\n mutationFn: (id: string) => {\n if (!service.deleteKey) {\n throw new Error(\"deleteKey not implemented\");\n }\n\n return service.deleteKey(id, context);\n },\n onSuccess: () => {\n void queryClient.invalidateQueries({ queryKey: [\"api-keys\"] });\n },\n });\n\n return (\n <div className=\"max-w-screen-lg h-full pt-[--padding-content-top] pb-[--padding-content-bottom]\">\n <div className=\"flex justify-between mb-4 border-b pb-3\">\n <h1 className=\"font-medium text-2xl\">API Keys</h1>\n {service.createKey && (\n <Button asChild>\n <Link to=\"/settings/api-keys/new\">Create API Key</Link>\n </Button>\n )}\n </div>\n\n {data.length === 0 ? (\n <div className=\"flex flex-col justify-center gap-4 items-center h-1/2 my-8\">\n <div className=\"text-center\">\n No API keys created yet.\n <br />\n Get started and create the first one now\n </div>\n {service.createKey && (\n <Button asChild>\n <Link to=\"/settings/api-keys/new\">Create API Key</Link>\n </Button>\n )}\n </div>\n ) : (\n <ul\n className={cn(\n \"grid grid-cols-1 rounded border\",\n \"lg:grid-cols-[minmax(250px,min-content)_1fr_min-content]\",\n )}\n >\n {data.map((key) => (\n <li\n className=\"border-b p-5 grid grid-cols-subgrid col-span-full gap-2 items-center\"\n key={key.id}\n >\n <div className=\"flex flex-col gap-1 text-sm\">\n {key.description ?? key.id}\n <div className=\"text-muted-foreground text-xs\">\n {key.createdOn && (\n <div>\n Created on {new Date(key.createdOn).toLocaleDateString()}\n </div>\n )}\n {key.expiresOn && (\n <div>\n Expires on {new Date(key.expiresOn).toLocaleDateString()}\n </div>\n )}\n </div>\n </div>\n <div className=\"items-center flex lg:justify-center\">\n <RevealApiKey apiKey={key.key} />\n </div>\n <div className=\"flex gap-2\">\n {service.rollKey && (\n <Button size=\"icon\">\n <RotateCwIcon size={16} />\n </Button>\n )}\n {service.deleteKey && (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n onClick={() => {\n if (!confirm(\"Do you want to delete this key?\")) {\n return;\n }\n\n deleteKeyMutation.mutate(key.id);\n }}\n disabled={deleteKeyMutation.isPending}\n >\n <TrashIcon size={16} />\n </Button>\n )}\n </div>\n </li>\n ))}\n </ul>\n )}\n </div>\n );\n};\n\nconst RevealApiKey = ({ apiKey }: { apiKey: string }) => {\n const [revealed, setRevealed] = useState(false);\n\n return (\n <div className=\"flex gap-2 items-center text-sm w-full\">\n <input\n className=\"border rounded bg-gray-100 dark:bg-gray-950 p-1 font-mono max-w-min\"\n value={revealed ? apiKey : \"•\".repeat(apiKey.length)}\n />\n <Button\n variant=\"outline\"\n onClick={() => setRevealed((prev) => !prev)}\n size=\"icon\"\n >\n {revealed ? <EyeOffIcon size={16} /> : <EyeIcon size={16} />}\n </Button>\n </div>\n );\n};\n","import { type RouteObject } from \"react-router-dom\";\nimport invariant from \"tiny-invariant\";\nimport { DevPortalContext } from \"../../core/DevPortalContext.js\";\nimport {\n type ApiIdentityPlugin,\n type DevPortalPlugin,\n ProfileMenuPlugin,\n} from \"../../core/plugins.js\";\nimport { RouterError } from \"../../errors/RouterError.js\";\nimport { CreateApiKey } from \"./CreateApiKey.js\";\nimport { ProtectedRoute } from \"./ProtectedRoute.js\";\nimport { SettingsApiKeys } from \"./SettingsApiKeys.js\";\n\nconst DEFAULT_API_KEY_ENDPOINT =\n \"https://zudoku-rewiringamerica-main-ef9c9c0.d2.zuplo.dev\";\n\nexport type ApiKeyService = {\n getKeys: (context: DevPortalContext) => Promise<ApiKey[]>;\n rollKey?: (id: string, context: DevPortalContext) => Promise<void>;\n deleteKey?: (id: string, context: DevPortalContext) => Promise<void>;\n updateKeyDescription?: (\n apiKey: { id: string; description: string },\n context: DevPortalContext,\n ) => Promise<void>;\n getUsage?: (apiKeys: string[], context: DevPortalContext) => Promise<void>;\n createKey?: (\n apiKey: { description: string; expiresOn?: string },\n context: DevPortalContext,\n ) => Promise<void>;\n};\n\nexport type GetApiKeysOptions = ApiKeyService | { endpoint: string } | object;\n\nexport type ApiKeyPluginOptions = object & GetApiKeysOptions;\n\nexport interface ApiKey {\n id: string;\n description?: string;\n createdOn?: string;\n updatedOn?: string;\n expiresOn?: string;\n key: string;\n}\n\nconst createDefaultHandler = (endpoint: string): ApiKeyService => {\n return {\n deleteKey: async (id, context) => {\n const request = new Request(endpoint + `/v1/developer/api-keys/${id}`, {\n method: \"DELETE\",\n });\n\n await context.signRequest(request);\n\n const response = await fetch(request);\n invariant(response.ok, \"Failed to delete API key\");\n },\n createKey: async (apiKey, context) => {\n const request = new Request(endpoint + `/v1/developer/api-keys`, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(apiKey),\n });\n\n await context.signRequest(request);\n\n const response = await fetch(request);\n invariant(response.ok, \"Failed to create API key\");\n },\n getKeys: async (context) => {\n const request = new Request(endpoint + `/v1/developer/api-keys`);\n\n await context.signRequest(request);\n\n const keys = await fetch(request);\n invariant(keys.ok, \"Failed to fetch API keys\");\n\n return await keys.json();\n },\n };\n};\n\nexport const apiKeyPlugin = (\n options: ApiKeyPluginOptions,\n): DevPortalPlugin & ApiIdentityPlugin & ProfileMenuPlugin => {\n const endpoint =\n \"endpoint\" in options ? options.endpoint : DEFAULT_API_KEY_ENDPOINT;\n\n const service =\n \"getKeys\" in options ? options : createDefaultHandler(endpoint);\n\n return {\n getProfileMenuItems: () => [\n {\n label: \"API Keys\",\n path: \"/settings/api-keys\",\n },\n ],\n getIdentities: async (context) => {\n try {\n const keys = await service.getKeys(context);\n\n return keys.map((key) => ({\n authorizeRequest: (request) => {\n request.headers.set(\"Authorization\", `Bearer ${key.key}`);\n return request;\n },\n id: key.id,\n label: key.description ?? key.id,\n }));\n } catch {\n return [];\n }\n },\n getRoutes: (): RouteObject[] => {\n // TODO: Make lazy\n return [\n {\n element: <ProtectedRoute />,\n errorElement: <RouterError />,\n children: [\n {\n path: \"/settings/api-keys\",\n element: <SettingsApiKeys service={service} />,\n },\n {\n path: \"/settings/api-keys/new\",\n element: <CreateApiKey service={service} />,\n },\n ],\n },\n ];\n },\n };\n};\n"],"names":["EyeOff","createLucideIcon","Eye","RotateCw","Trash","isProduction","prefix","invariant","condition","message","provided","value","Input","React","className","type","props","ref","jsx","cn","CreateApiKey","service","context","useDevPortal","navigate","useNavigate","form","useForm","createKeyMutation","useMutation","description","expiresOn","expiresOnDate","addDaysToDate","jsxs","data","Select","SelectTrigger","SelectValue","SelectContent","SelectGroup","option","SelectItem","Button","Link","days","date","ProtectedRoute","auth","useAuth","Outlet","DeveloperHint","SettingsApiKeys","queryClient","useQueryClient","useSuspenseQuery","deleteKeyMutation","id","key","RevealApiKey","RotateCwIcon","TrashIcon","apiKey","revealed","setRevealed","useState","prev","EyeOffIcon","EyeIcon","DEFAULT_API_KEY_ENDPOINT","createDefaultHandler","endpoint","request","response","keys","apiKeyPlugin","options","RouterError"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4]}
@@ -0,0 +1,13 @@
1
+ import { j as m } from "./jsx-runtime-BIr0WBt_.js";
2
+ import { P as o } from "./Markdown-BjRJKl_E.js";
3
+ const l = (s) => ({
4
+ getRoutes: () => s.map(({ path: e, element: t }) => ({
5
+ path: e,
6
+ // TODO: we should componentize prose pages
7
+ element: /* @__PURE__ */ m.jsx("div", { className: o + " max-w-full", children: t })
8
+ }))
9
+ });
10
+ export {
11
+ l as customPagePlugin
12
+ };
13
+ //# sourceMappingURL=zudoku.plugin-custom-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zudoku.plugin-custom-page.js","sources":["../src/lib/plugins/custom-page/index.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport type { RouteObject } from \"react-router-dom\";\nimport { ProseClasses } from \"../../components/Markdown.js\";\nimport type { DevPortalPlugin, NavigationPlugin } from \"../../core/plugins.js\";\n\ntype CustomPageConfig = Array<{\n path: string;\n element: ReactNode;\n}>;\n\nexport const customPagePlugin = (\n config: CustomPageConfig,\n): DevPortalPlugin & NavigationPlugin => {\n return {\n getRoutes: (): RouteObject[] =>\n config.map(({ path, element }) => ({\n path,\n // TODO: we should componentize prose pages\n element: <div className={ProseClasses + \" max-w-full\"}>{element}</div>,\n })),\n };\n};\n"],"names":["customPagePlugin","config","path","element","jsx","ProseClasses"],"mappings":";;AAUa,MAAAA,IAAmB,CAC9BC,OAEO;AAAA,EACL,WAAW,MACTA,EAAO,IAAI,CAAC,EAAE,MAAAC,GAAM,SAAAC,SAAe;AAAA,IACjC,MAAAD;AAAA;AAAA,IAEA,SAAUE,gBAAAA,EAAAA,IAAA,OAAA,EAAI,WAAWC,IAAe,eAAgB,UAAQF,GAAA;AAAA,EAAA,EAChE;AAAA;"}
@@ -1,18 +1,17 @@
1
- import { j as s, N as x } from "./jsx-runtime-CJZJivg2.js";
2
- import { k as d } from "./DevPortalProvider-Do9oJqme.js";
3
- import { t as f, i as g } from "./util-_jwUlTBU.js";
4
- const h = (t, e) => {
5
- const r = Object.entries(t).flatMap(
1
+ import { j as o, N as x } from "./jsx-runtime-BIr0WBt_.js";
2
+ import { v as d, z as g, l as h } from "./DevPortalProvider-BBhQ8kgI.js";
3
+ const f = (t, e) => {
4
+ const a = Object.entries(t).flatMap(
6
5
  ([n, m]) => {
7
- const a = n.match(/pages\/(.*).mdx?$/), o = a == null ? void 0 : a.at(1);
8
- if (!o) return [];
9
- const i = o.split("/");
6
+ const r = n.match(/pages\/(.*).mdx?$/), s = r == null ? void 0 : r.at(1);
7
+ if (!s) return [];
8
+ const i = s.split("/");
10
9
  return {
11
- path: i.at(-1) === "index" ? i.slice(0, -1).join("/") : o,
10
+ path: i.at(-1) === "index" ? i.slice(0, -1).join("/") : s,
12
11
  lazy: async () => {
13
- const { MdxPage: u } = await import("./MdxPage-CbwYRKf5.js"), { default: c, ...l } = await m();
12
+ const { MdxPage: u } = await import("./MdxPage-DJTFOCbZ.js"), { default: c, ...l } = await m();
14
13
  return {
15
- element: /* @__PURE__ */ s.jsx(
14
+ element: /* @__PURE__ */ o.jsx(
16
15
  u,
17
16
  {
18
17
  mdxComponent: c,
@@ -25,25 +24,25 @@ const h = (t, e) => {
25
24
  };
26
25
  }
27
26
  ), p = Array.from(
28
- new Set(r.map((n) => n.path.split("/").at(0)))
27
+ new Set(a.map((n) => n.path.split("/").at(0)))
29
28
  ).map((n) => ({
30
29
  path: `/${n}`,
31
- element: /* @__PURE__ */ s.jsx(j, {})
30
+ element: /* @__PURE__ */ o.jsx(j, {})
32
31
  }));
33
- return [...r, ...p];
32
+ return [...a, ...p];
34
33
  }, j = () => {
35
34
  const t = d();
36
- return t ? f(t, (e, r) => {
37
- if (!("children" in e || !g(e)))
38
- return /* @__PURE__ */ s.jsx(x, { to: r, replace: !0 });
35
+ return t ? g(t, (e, a) => {
36
+ if (!("children" in e || !h(e)))
37
+ return /* @__PURE__ */ o.jsx(x, { to: a, replace: !0 });
39
38
  }) : null;
40
- }, N = ({
39
+ }, w = ({
41
40
  markdownFiles: t,
42
41
  defaultOptions: e
43
42
  }) => ({
44
- getRoutes: () => h(t, e)
43
+ getRoutes: () => f(t, e)
45
44
  });
46
45
  export {
47
- N as markdownPlugin
46
+ w as markdownPlugin
48
47
  };
49
48
  //# sourceMappingURL=zudoku.plugin-markdown.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"zudoku.plugin-markdown.js","sources":["../src/lib/plugins/markdown/generateRoutes.tsx","../src/lib/plugins/markdown/index.tsx"],"sourcesContent":["import { Navigate, type RouteObject } from \"react-router-dom\";\nimport { useTopNavigationItem } from \"../../components/context/DevPortalProvider.js\";\nimport { isPathItem } from \"../../components/navigation/util.js\";\nimport { traverseNavigation } from \"../../util/traverseNavigation.js\";\n\nimport {\n MarkdownPluginDefaultOptions,\n MarkdownPluginOptions,\n} from \"./index.js\";\n\nexport const generateRoutes = (\n markdownFiles: MarkdownPluginOptions[\"markdownFiles\"],\n defaultOptions?: MarkdownPluginDefaultOptions,\n): RouteObject[] => {\n const routes = Object.entries(markdownFiles).flatMap(\n ([file, importPromise]) => {\n // @todo we can pass in the folder name and then filter the markdown files based on that path\n const match = file.match(/pages\\/(.*).mdx?$/);\n const path = match?.at(1);\n\n if (!path) return [];\n\n const pathSegments = path.split(\"/\");\n const isIndexFile = pathSegments.at(-1) === \"index\";\n const routePath = isIndexFile\n ? pathSegments.slice(0, -1).join(\"/\")\n : path;\n\n return {\n path: routePath,\n lazy: async () => {\n const { MdxPage } = await import(\"./MdxPage.js\");\n const { default: Component, ...props } = await importPromise();\n return {\n element: (\n <MdxPage\n mdxComponent={Component}\n {...props}\n defaultOptions={defaultOptions}\n />\n ),\n };\n },\n } satisfies RouteObject;\n },\n );\n\n const rootRoutes: RouteObject[] = Array.from(\n new Set(routes.map((route) => route.path.split(\"/\").at(0))),\n ).map((dir) => ({\n path: `/${dir}`,\n element: <Redirect />,\n }));\n\n return [...routes, ...rootRoutes];\n};\n\nconst Redirect = () => {\n const navItem = useTopNavigationItem();\n\n if (!navItem) return null;\n\n return traverseNavigation(navItem, (node, fullPath) => {\n if (\"children\" in node || !isPathItem(node)) return;\n return <Navigate to={fullPath} replace />;\n });\n};\n","import type { Toc } from \"@stefanprobst/rehype-extract-toc\";\nimport type { MDXProps } from \"mdx/types.js\";\nimport type { DevPortalPlugin } from \"../../core/plugins.js\";\nimport { generateRoutes } from \"./generateRoutes.js\";\n\nexport type MarkdownPluginOptions = {\n markdownFiles: Record<string, () => Promise<MDXImport>>;\n defaultOptions?: MarkdownPluginDefaultOptions;\n};\nexport type MarkdownPluginDefaultOptions = Pick<\n Frontmatter,\n \"toc\" | \"disablePager\"\n>;\n\nexport type Frontmatter = {\n title?: string;\n description?: string;\n category?: string;\n toc?: boolean;\n disablePager?: boolean;\n};\n\nexport type MDXImport = {\n tableOfContents: Toc;\n frontmatter: Frontmatter;\n default: (props: MDXProps) => JSX.Element;\n};\n\nexport const markdownPlugin = ({\n markdownFiles,\n defaultOptions,\n}: MarkdownPluginOptions): DevPortalPlugin => ({\n getRoutes: () => generateRoutes(markdownFiles, defaultOptions),\n});\n"],"names":["generateRoutes","markdownFiles","defaultOptions","routes","file","importPromise","match","path","pathSegments","MdxPage","Component","props","jsx","rootRoutes","route","dir","Redirect","navItem","useTopNavigationItem","traverseNavigation","node","fullPath","isPathItem","Navigate","markdownPlugin"],"mappings":";;;AAUa,MAAAA,IAAiB,CAC5BC,GACAC,MACkB;AAClB,QAAMC,IAAS,OAAO,QAAQF,CAAa,EAAE;AAAA,IAC3C,CAAC,CAACG,GAAMC,CAAa,MAAM;AAEnB,YAAAC,IAAQF,EAAK,MAAM,mBAAmB,GACtCG,IAAOD,KAAA,gBAAAA,EAAO,GAAG;AAEnB,UAAA,CAACC,EAAM,QAAO;AAEZ,YAAAC,IAAeD,EAAK,MAAM,GAAG;AAM5B,aAAA;AAAA,QACL,MANkBC,EAAa,GAAG,EAAE,MAAM,UAExCA,EAAa,MAAM,GAAG,EAAE,EAAE,KAAK,GAAG,IAClCD;AAAA,QAIF,MAAM,YAAY;AAChB,gBAAM,EAAE,SAAAE,EAAA,IAAY,MAAM,OAAO,uBAAc,GACzC,EAAE,SAASC,GAAW,GAAGC,EAAM,IAAI,MAAMN;AACxC,iBAAA;AAAA,YACL,SACEO,gBAAAA,EAAA;AAAA,cAACH;AAAA,cAAA;AAAA,gBACC,cAAcC;AAAA,gBACb,GAAGC;AAAA,gBACJ,gBAAAT;AAAA,cAAA;AAAA,YACF;AAAA,UAAA;AAAA,QAGN;AAAA,MAAA;AAAA,IAEJ;AAAA,EAAA,GAGIW,IAA4B,MAAM;AAAA,IACtC,IAAI,IAAIV,EAAO,IAAI,CAACW,MAAUA,EAAM,KAAK,MAAM,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;AAAA,EAAA,EAC1D,IAAI,CAACC,OAAS;AAAA,IACd,MAAM,IAAIA,CAAG;AAAA,IACb,+BAAUC,GAAS,EAAA;AAAA,EACnB,EAAA;AAEF,SAAO,CAAC,GAAGb,GAAQ,GAAGU,CAAU;AAClC,GAEMG,IAAW,MAAM;AACrB,QAAMC,IAAUC;AAEZ,SAACD,IAEEE,EAAmBF,GAAS,CAACG,GAAMC,MAAa;AACrD,QAAI,gBAAcD,KAAQ,CAACE,EAAWF,CAAI;AAC1C,aAAQR,gBAAAA,EAAAA,IAAAW,GAAA,EAAS,IAAIF,GAAU,SAAO,GAAC,CAAA;AAAA,EAAA,CACxC,IALoB;AAMvB,GCtCaG,IAAiB,CAAC;AAAA,EAC7B,eAAAvB;AAAA,EACA,gBAAAC;AACF,OAA+C;AAAA,EAC7C,WAAW,MAAMF,EAAeC,GAAeC,CAAc;AAC/D;"}
1
+ {"version":3,"file":"zudoku.plugin-markdown.js","sources":["../src/lib/plugins/markdown/generateRoutes.tsx","../src/lib/plugins/markdown/index.tsx"],"sourcesContent":["import { Navigate, type RouteObject } from \"react-router-dom\";\nimport { useTopNavigationItem } from \"../../components/context/DevPortalProvider.js\";\nimport { isPathItem } from \"../../components/navigation/util.js\";\nimport { traverseNavigation } from \"../../util/traverseNavigation.js\";\n\nimport {\n MarkdownPluginDefaultOptions,\n MarkdownPluginOptions,\n} from \"./index.js\";\n\nexport const generateRoutes = (\n markdownFiles: MarkdownPluginOptions[\"markdownFiles\"],\n defaultOptions?: MarkdownPluginDefaultOptions,\n): RouteObject[] => {\n const routes = Object.entries(markdownFiles).flatMap(\n ([file, importPromise]) => {\n // @todo we can pass in the folder name and then filter the markdown files based on that path\n const match = file.match(/pages\\/(.*).mdx?$/);\n const path = match?.at(1);\n\n if (!path) return [];\n\n const pathSegments = path.split(\"/\");\n const isIndexFile = pathSegments.at(-1) === \"index\";\n const routePath = isIndexFile\n ? pathSegments.slice(0, -1).join(\"/\")\n : path;\n\n return {\n path: routePath,\n lazy: async () => {\n const { MdxPage } = await import(\"./MdxPage.js\");\n const { default: Component, ...props } = await importPromise();\n return {\n element: (\n <MdxPage\n mdxComponent={Component}\n {...props}\n defaultOptions={defaultOptions}\n />\n ),\n };\n },\n } satisfies RouteObject;\n },\n );\n\n const rootRoutes: RouteObject[] = Array.from(\n new Set(routes.map((route) => route.path.split(\"/\").at(0))),\n ).map((dir) => ({\n path: `/${dir}`,\n element: <Redirect />,\n }));\n\n return [...routes, ...rootRoutes];\n};\n\nconst Redirect = () => {\n const navItem = useTopNavigationItem();\n\n if (!navItem) return null;\n\n return traverseNavigation(navItem, (node, fullPath) => {\n if (\"children\" in node || !isPathItem(node)) return;\n return <Navigate to={fullPath} replace />;\n });\n};\n","import type { Toc } from \"@stefanprobst/rehype-extract-toc\";\nimport type { MDXProps } from \"mdx/types.js\";\nimport type { DevPortalPlugin } from \"../../core/plugins.js\";\nimport { generateRoutes } from \"./generateRoutes.js\";\n\nexport type MarkdownPluginOptions = {\n markdownFiles: Record<string, () => Promise<MDXImport>>;\n defaultOptions?: MarkdownPluginDefaultOptions;\n};\nexport type MarkdownPluginDefaultOptions = Pick<\n Frontmatter,\n \"toc\" | \"disablePager\"\n>;\n\nexport type Frontmatter = {\n title?: string;\n description?: string;\n category?: string;\n toc?: boolean;\n disablePager?: boolean;\n};\n\nexport type MDXImport = {\n tableOfContents: Toc;\n frontmatter: Frontmatter;\n default: (props: MDXProps) => JSX.Element;\n};\n\nexport const markdownPlugin = ({\n markdownFiles,\n defaultOptions,\n}: MarkdownPluginOptions): DevPortalPlugin => ({\n getRoutes: () => generateRoutes(markdownFiles, defaultOptions),\n});\n"],"names":["generateRoutes","markdownFiles","defaultOptions","routes","file","importPromise","match","path","pathSegments","MdxPage","Component","props","jsx","rootRoutes","route","dir","Redirect","navItem","useTopNavigationItem","traverseNavigation","node","fullPath","isPathItem","Navigate","markdownPlugin"],"mappings":";;AAUa,MAAAA,IAAiB,CAC5BC,GACAC,MACkB;AAClB,QAAMC,IAAS,OAAO,QAAQF,CAAa,EAAE;AAAA,IAC3C,CAAC,CAACG,GAAMC,CAAa,MAAM;AAEnB,YAAAC,IAAQF,EAAK,MAAM,mBAAmB,GACtCG,IAAOD,KAAA,gBAAAA,EAAO,GAAG;AAEnB,UAAA,CAACC,EAAM,QAAO;AAEZ,YAAAC,IAAeD,EAAK,MAAM,GAAG;AAM5B,aAAA;AAAA,QACL,MANkBC,EAAa,GAAG,EAAE,MAAM,UAExCA,EAAa,MAAM,GAAG,EAAE,EAAE,KAAK,GAAG,IAClCD;AAAA,QAIF,MAAM,YAAY;AAChB,gBAAM,EAAE,SAAAE,EAAA,IAAY,MAAM,OAAO,uBAAc,GACzC,EAAE,SAASC,GAAW,GAAGC,EAAM,IAAI,MAAMN;AACxC,iBAAA;AAAA,YACL,SACEO,gBAAAA,EAAA;AAAA,cAACH;AAAA,cAAA;AAAA,gBACC,cAAcC;AAAA,gBACb,GAAGC;AAAA,gBACJ,gBAAAT;AAAA,cAAA;AAAA,YACF;AAAA,UAAA;AAAA,QAGN;AAAA,MAAA;AAAA,IAEJ;AAAA,EAAA,GAGIW,IAA4B,MAAM;AAAA,IACtC,IAAI,IAAIV,EAAO,IAAI,CAACW,MAAUA,EAAM,KAAK,MAAM,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC;AAAA,EAAA,EAC1D,IAAI,CAACC,OAAS;AAAA,IACd,MAAM,IAAIA,CAAG;AAAA,IACb,+BAAUC,GAAS,EAAA;AAAA,EACnB,EAAA;AAEF,SAAO,CAAC,GAAGb,GAAQ,GAAGU,CAAU;AAClC,GAEMG,IAAW,MAAM;AACrB,QAAMC,IAAUC;AAEZ,SAACD,IAEEE,EAAmBF,GAAS,CAACG,GAAMC,MAAa;AACrD,QAAI,gBAAcD,KAAQ,CAACE,EAAWF,CAAI;AAC1C,aAAQR,gBAAAA,EAAAA,IAAAW,GAAA,EAAS,IAAIF,GAAU,SAAO,GAAC,CAAA;AAAA,EAAA,CACxC,IALoB;AAMvB,GCtCaG,IAAiB,CAAC;AAAA,EAC7B,eAAAvB;AAAA,EACA,gBAAAC;AACF,OAA+C;AAAA,EAC7C,WAAW,MAAMF,EAAeC,GAAeC,CAAc;AAC/D;"}
@@ -1,9 +1,9 @@
1
- import "./jsx-runtime-CJZJivg2.js";
2
- import { o as n } from "./index-Bg82-bqR.js";
1
+ import "./jsx-runtime-BIr0WBt_.js";
2
+ import { o as n } from "./index-BE2a6gGC.js";
3
3
  import "./urql-DMlBWUKL.js";
4
4
  import "zudoku/openapi-worker";
5
- import "./Markdown-DtLFdxD1.js";
6
- import "./router-CBw2vqJE.js";
5
+ import "./Markdown-BjRJKl_E.js";
6
+ import "./router-BiRCp01d.js";
7
7
  export {
8
8
  n as openApiPlugin
9
9
  };
@@ -1,11 +1,11 @@
1
- import { q as o } from "./router-CBw2vqJE.js";
2
- const a = (r) => ({
1
+ import { a as o } from "./router-BiRCp01d.js";
2
+ const i = (r) => ({
3
3
  getRoutes: () => r.redirects.map(({ from: e, to: t }) => ({
4
4
  path: e,
5
5
  loader: () => o(t)
6
6
  }))
7
7
  });
8
8
  export {
9
- a as redirectPlugin
9
+ i as redirectPlugin
10
10
  };
11
11
  //# sourceMappingURL=zudoku.plugin-redirect.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zudoku",
3
- "version": "0.3.0-dev.57",
3
+ "version": "0.3.0-dev.59",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",
@@ -16,37 +16,51 @@
16
16
  },
17
17
  "exports": {
18
18
  ".": {
19
- "import": "./dist/index.js"
19
+ "import": "./dist/index.js",
20
+ "types": "./dist/index.d.ts"
20
21
  },
21
22
  "./internal": {
22
23
  "import": "./dist/internal.js"
23
24
  },
24
25
  "./auth/clerk": {
25
- "import": "./lib/zudoku.auth-clerk.js"
26
+ "import": "./lib/zudoku.auth-clerk.js",
27
+ "types": "./dist/lib/authentication/providers/clerk.d.ts"
26
28
  },
27
29
  "./auth/auth0": {
28
- "import": "./lib/zudoku.auth-auth0.js"
30
+ "import": "./lib/zudoku.auth-auth0.js",
31
+ "types": "./dist/lib/authentication/providers/auth0.d.ts"
29
32
  },
30
33
  "./auth/openid": {
31
- "import": "./lib/zudoku.auth-openid.js"
34
+ "import": "./lib/zudoku.auth-openid.js",
35
+ "types": "./dist/lib/authentication/providers/openid.d.ts"
32
36
  },
33
37
  "./plugins/api-keys": {
34
- "import": "./lib/zudoku.plugin-api-keys.js"
38
+ "import": "./lib/zudoku.plugin-api-keys.js",
39
+ "types": "./dist/lib/plugins/api-keys/index.d.ts"
35
40
  },
36
41
  "./plugins/markdown": {
37
- "import": "./lib/zudoku.plugin-markdown.js"
42
+ "import": "./lib/zudoku.plugin-markdown.js",
43
+ "types": "./dist/lib/plugins/markdown/index.d.ts"
38
44
  },
39
45
  "./plugins/openapi": {
40
- "import": "./lib/zudoku.plugin-openapi.js"
46
+ "import": "./lib/zudoku.plugin-openapi.js",
47
+ "types": "./dist/lib/plugins/openapi/index.d.ts"
41
48
  },
42
49
  "./plugins/redirect": {
43
- "import": "./lib/zudoku.plugin-redirect.js"
50
+ "import": "./lib/zudoku.plugin-redirect.js",
51
+ "types": "./dist/lib/plugins/redirect/index.d.ts"
52
+ },
53
+ "./plugins/custom-page": {
54
+ "import": "./lib/zudoku.plugin-custom-page.js",
55
+ "types": "./dist/lib/plugins/custom-page/index.d.ts"
44
56
  },
45
57
  "./openapi-worker": {
46
- "import": "./lib/zudoku.openapi-worker.js"
58
+ "import": "./lib/zudoku.openapi-worker.js",
59
+ "types": "./dist/lib/plugins/openapi-worker.d.ts"
47
60
  },
48
61
  "./components": {
49
- "import": "./lib/zudoku.components.js"
62
+ "import": "./lib/zudoku.components.js",
63
+ "types": "./dist/lib/components/index.d.ts"
50
64
  },
51
65
  "./vite": {
52
66
  "require": "./dist/vite/plugin.js",
@@ -74,6 +88,7 @@
74
88
  "@monaco-editor/react": "^4.6.0",
75
89
  "@pothos/core": "3.41.0",
76
90
  "@radix-ui/react-collapsible": "1.1.0",
91
+ "@radix-ui/react-dropdown-menu": "^2.1.1",
77
92
  "@radix-ui/react-select": "2.1.1",
78
93
  "@radix-ui/react-visually-hidden": "1.1.0",
79
94
  "@sentry/node": "8.11.0",
@@ -106,7 +121,7 @@
106
121
  "react-hook-form": "^7.52.1",
107
122
  "react-is": "18.3.1",
108
123
  "react-markdown": "9.0.1",
109
- "react-router-dom": "6.24.1",
124
+ "react-router-dom": "6.25.1",
110
125
  "rehype-slug": "6.0.0",
111
126
  "remark-comment": "1.0.0",
112
127
  "remark-directive": "3.0.0",
@@ -154,7 +169,7 @@
154
169
  "prism-react-renderer": "2.3.1",
155
170
  "prismjs": "1.29.0",
156
171
  "react-markdown": "9.0.1",
157
- "react-router-dom": "6.24.1",
172
+ "react-router-dom": "6.25.1",
158
173
  "rollup-plugin-visualizer": "^5.12.0",
159
174
  "typescript": "5.5.3"
160
175
  },
@@ -163,7 +178,7 @@
163
178
  "react-dom": ">18.0.0"
164
179
  },
165
180
  "optionalDependencies": {
166
- "@clerk/clerk-js": "5.2.2"
181
+ "@clerk/clerk-js": "5.11.0"
167
182
  },
168
183
  "scripts": {
169
184
  "build": "tsc --project tsconfig.json",
@@ -43,5 +43,5 @@ async function hydrate(routes: RouteObject[]) {
43
43
  await hydrateLazyRoutes(routes);
44
44
  const router = createBrowserRouter(routes);
45
45
 
46
- hydrateRoot(root, <Bootstrap router={router} />);
46
+ hydrateRoot(root, <Bootstrap hydrate router={router} />);
47
47
  }
@@ -15,6 +15,8 @@ import type { FileWritingResponse } from "../vite/prerender.js";
15
15
  import "./main.css";
16
16
  import { getRoutesByConfig } from "./main.js";
17
17
 
18
+ export { getRoutesByConfig };
19
+
18
20
  export const render = async ({
19
21
  template,
20
22
  request: baseRequest,
package/src/app/main.css CHANGED
@@ -94,6 +94,9 @@
94
94
  #root {
95
95
  @apply h-full min-h-screen;
96
96
  }
97
+ * {
98
+ @apply border-border;
99
+ }
97
100
 
98
101
  html {
99
102
  scroll-padding-block: var(--scroll-padding);
@@ -102,6 +105,9 @@
102
105
 
103
106
  body {
104
107
  @apply antialiased bg-background text-foreground;
108
+ font-feature-settings:
109
+ "rlig" 1,
110
+ "calt" 1;
105
111
  }
106
112
 
107
113
  .dark {
package/src/app/main.tsx CHANGED
@@ -7,6 +7,7 @@ import { configuredRedirectPlugin } from "virtual:zudoku-redirect-plugin";
7
7
  import "virtual:zudoku-theme.css";
8
8
  import { DevPortal, Layout, RouterError } from "zudoku/components";
9
9
  import { isNavigationPlugin } from "zudoku/internal";
10
+ import { customPagePlugin } from "zudoku/plugins/custom-page";
10
11
  import type { ZudokuConfig } from "../config/config.js";
11
12
  import type { ZudokuContextOptions } from "../lib/core/DevPortalContext.js";
12
13
 
@@ -41,7 +42,10 @@ export const convertZudokuConfigToOptions = (
41
42
  ...configuredApiPlugins,
42
43
  ...(configuredRedirectPlugin ? [configuredRedirectPlugin] : []),
43
44
  ...(configuredApiKeysPlugin ? [configuredApiKeysPlugin] : []),
44
- ...(configuredAuthProvider ? [configuredAuthProvider] : []),
45
+ ...(config.customPages ? [customPagePlugin(config.customPages)] : []),
46
+ ...(configuredAuthProvider?.getAuthenticationPlugin
47
+ ? [configuredAuthProvider.getAuthenticationPlugin()]
48
+ : []),
45
49
  ],
46
50
  };
47
51
  };
@@ -51,7 +55,9 @@ export const getRoutesByConfig = (config: ZudokuConfig): RouteObject[] => {
51
55
 
52
56
  const allPlugins = [
53
57
  ...(options.plugins ? options.plugins : []),
54
- ...(options.authentication ? [options.authentication] : []),
58
+ ...(options.authentication?.getAuthenticationPlugin
59
+ ? [options.authentication.getAuthenticationPlugin()]
60
+ : []),
55
61
  ];
56
62
 
57
63
  const routes = allPlugins