zudoku 0.3.0-dev.75 → 0.3.0-dev.76

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 (66) hide show
  1. package/dist/lib/authentication/components/SignUp.js +1 -1
  2. package/dist/lib/authentication/components/SignUp.js.map +1 -1
  3. package/dist/lib/authentication/providers/openid.d.ts +4 -4
  4. package/dist/lib/authentication/providers/openid.js +12 -11
  5. package/dist/lib/authentication/providers/openid.js.map +1 -1
  6. package/dist/lib/components/DevPortal.js +4 -3
  7. package/dist/lib/components/DevPortal.js.map +1 -1
  8. package/dist/lib/core/DevPortalContext.d.ts +4 -1
  9. package/dist/lib/core/DevPortalContext.js +2 -2
  10. package/dist/lib/core/DevPortalContext.js.map +1 -1
  11. package/dist/lib/core/plugins.d.ts +4 -2
  12. package/dist/lib/core/plugins.js.map +1 -1
  13. package/dist/lib/plugins/api-keys/SettingsApiKeys.js +1 -1
  14. package/dist/lib/plugins/api-keys/SettingsApiKeys.js.map +1 -1
  15. package/lib/{AnchorLink-DwUyvkrL.js → AnchorLink-BZcpTwOs.js} +3 -3
  16. package/lib/{AnchorLink-DwUyvkrL.js.map → AnchorLink-BZcpTwOs.js.map} +1 -1
  17. package/lib/{AuthenticationPlugin-BuCQtecV.js → AuthenticationPlugin-CngUn5DP.js} +9 -9
  18. package/lib/AuthenticationPlugin-CngUn5DP.js.map +1 -0
  19. package/lib/{CategoryHeading-8saHYD9L.js → CategoryHeading-D0V23fMT.js} +3 -3
  20. package/lib/{CategoryHeading-8saHYD9L.js.map → CategoryHeading-D0V23fMT.js.map} +1 -1
  21. package/lib/{Combination-BMJg4xHo.js → Combination-CgxP9BB4.js} +4 -4
  22. package/lib/{Combination-BMJg4xHo.js.map → Combination-CgxP9BB4.js.map} +1 -1
  23. package/lib/{DevPortalProvider-DMrk4yw1.js → DevPortalProvider-BTFqdAEL.js} +2 -2
  24. package/lib/{DevPortalProvider-DMrk4yw1.js.map → DevPortalProvider-BTFqdAEL.js.map} +1 -1
  25. package/lib/{Input-98JuH9ox.js → Input-BcZoDid4.js} +5 -5
  26. package/lib/{Input-98JuH9ox.js.map → Input-BcZoDid4.js.map} +1 -1
  27. package/lib/{Markdown-CSdXDuYx.js → Markdown-IsabnbGN.js} +3 -3
  28. package/lib/{Markdown-CSdXDuYx.js.map → Markdown-IsabnbGN.js.map} +1 -1
  29. package/lib/{MdxPage-7CszsIct.js → MdxPage-B1B2Inj5.js} +7 -7
  30. package/lib/{MdxPage-7CszsIct.js.map → MdxPage-B1B2Inj5.js.map} +1 -1
  31. package/lib/{OperationList-DbFAs7j0.js → OperationList-B2nsuf1v.js} +10 -10
  32. package/lib/{OperationList-DbFAs7j0.js.map → OperationList-B2nsuf1v.js.map} +1 -1
  33. package/lib/{Route-CueiECQ0.js → Route-D0Ub80Oa.js} +2 -2
  34. package/lib/{Route-CueiECQ0.js.map → Route-D0Ub80Oa.js.map} +1 -1
  35. package/lib/{SlotletProvider-ibdqvOie.js → SlotletProvider-CJXWb2gw.js} +7 -7
  36. package/lib/{SlotletProvider-ibdqvOie.js.map → SlotletProvider-CJXWb2gw.js.map} +1 -1
  37. package/lib/{Spinner-D0EmkS4m.js → Spinner-BhtSoFka.js} +4 -4
  38. package/lib/{Spinner-D0EmkS4m.js.map → Spinner-BhtSoFka.js.map} +1 -1
  39. package/lib/{index-C5qcuxqm.js → index-BC2Ob2BR.js} +7 -7
  40. package/lib/{index-C5qcuxqm.js.map → index-BC2Ob2BR.js.map} +1 -1
  41. package/lib/{index-CjHZiWvQ.js → index-Dt-pU7Vu.js} +2 -2
  42. package/lib/{index-CjHZiWvQ.js.map → index-Dt-pU7Vu.js.map} +1 -1
  43. package/lib/{jsx-runtime-D0NHp7nI.js → jsx-runtime-CJBdjYYx.js} +3 -3
  44. package/lib/{jsx-runtime-D0NHp7nI.js.map → jsx-runtime-CJBdjYYx.js.map} +1 -1
  45. package/lib/zudoku.auth-clerk.js +1 -1
  46. package/lib/zudoku.auth-openid.js +262 -289
  47. package/lib/zudoku.auth-openid.js.map +1 -1
  48. package/lib/zudoku.components.js +449 -447
  49. package/lib/zudoku.components.js.map +1 -1
  50. package/lib/zudoku.plugin-api-keys.js +19 -18
  51. package/lib/zudoku.plugin-api-keys.js.map +1 -1
  52. package/lib/zudoku.plugin-custom-page.js +2 -2
  53. package/lib/zudoku.plugin-markdown.js +3 -3
  54. package/lib/zudoku.plugin-openapi.js +3 -3
  55. package/package.json +1 -1
  56. package/src/lib/authentication/components/SignUp.tsx +1 -1
  57. package/src/lib/authentication/providers/openid.tsx +13 -15
  58. package/src/lib/components/DevPortal.tsx +4 -3
  59. package/src/lib/core/DevPortalContext.ts +7 -2
  60. package/src/lib/core/plugins.ts +5 -2
  61. package/src/lib/plugins/api-keys/SettingsApiKeys.tsx +2 -0
  62. package/dist/lib/authentication/Callback.d.ts +0 -3
  63. package/dist/lib/authentication/Callback.js +0 -33
  64. package/dist/lib/authentication/Callback.js.map +0 -1
  65. package/lib/AuthenticationPlugin-BuCQtecV.js.map +0 -1
  66. package/src/lib/authentication/Callback.tsx +0 -58
@@ -1,11 +1,11 @@
1
- import { b as y, j as e, O as f } from "./jsx-runtime-D0NHp7nI.js";
2
- import { u as j, a as g, R as v } from "./SlotletProvider-ibdqvOie.js";
3
- import { u as w, a as p, I as k, S as b, b as K, c as N, d as A, e as E, f as x } from "./Input-98JuH9ox.js";
4
- import { L as u } from "./index-CjHZiWvQ.js";
5
- import { u as h, x as S, y as I } from "./DevPortalProvider-DMrk4yw1.js";
6
- import { B as o, p as P } from "./Combination-BMJg4xHo.js";
1
+ import { a as f, j as e, O as j } from "./jsx-runtime-CJBdjYYx.js";
2
+ import { u as g, a as x, R as v } from "./SlotletProvider-CJXWb2gw.js";
3
+ import { u as w, a as h, I as k, S as b, b as K, c as N, d as A, e as E, f as p } from "./Input-BcZoDid4.js";
4
+ import { L as u } from "./index-Dt-pU7Vu.js";
5
+ import { u as m, x as S, y as I } from "./DevPortalProvider-BTFqdAEL.js";
6
+ import { B as o, p as P } from "./Combination-CgxP9BB4.js";
7
7
  import { useState as C } from "react";
8
- import { c as l, a as D } from "./Markdown-CSdXDuYx.js";
8
+ import { c as l, a as D } from "./Markdown-IsabnbGN.js";
9
9
  /**
10
10
  * @license lucide-react v0.378.0 - ISC
11
11
  *
@@ -70,17 +70,17 @@ class M extends Error {
70
70
  }
71
71
  }
72
72
  const L = ({ service: t }) => {
73
- const n = h(), r = y(), a = w({
73
+ const n = m(), r = f(), a = w({
74
74
  defaultValues: {
75
75
  expiresOn: "30"
76
76
  }
77
- }), i = p({
77
+ }), i = h({
78
78
  mutationFn: ({ description: s, expiresOn: c }) => {
79
79
  if (!t.createKey)
80
80
  throw new Error("deleteKey not implemented");
81
- const m = c !== "never" ? T(Number(c)) : void 0;
81
+ const y = c !== "never" ? T(Number(c)) : void 0;
82
82
  return t.createKey(
83
- { description: s, expiresOn: m },
83
+ { description: s, expiresOn: y },
84
84
  n
85
85
  );
86
86
  },
@@ -104,11 +104,11 @@ const L = ({ service: t }) => {
104
104
  children: [
105
105
  /* @__PURE__ */ e.jsx(K, { children: /* @__PURE__ */ e.jsx(N, {}) }),
106
106
  /* @__PURE__ */ e.jsx(A, { children: /* @__PURE__ */ e.jsxs(E, { children: [
107
- [7, 30, 60, 90].map((s) => /* @__PURE__ */ e.jsxs(x, { value: String(s), children: [
107
+ [7, 30, 60, 90].map((s) => /* @__PURE__ */ e.jsxs(p, { value: String(s), children: [
108
108
  s,
109
109
  " days"
110
110
  ] }, s)),
111
- /* @__PURE__ */ e.jsx(x, { value: "never", children: "Never" })
111
+ /* @__PURE__ */ e.jsx(p, { value: "never", children: "Never" })
112
112
  ] }) })
113
113
  ]
114
114
  }
@@ -125,8 +125,8 @@ const L = ({ service: t }) => {
125
125
  const n = /* @__PURE__ */ new Date();
126
126
  return n.setDate(n.getDate() + t), n.toISOString();
127
127
  }, F = () => {
128
- const t = j();
129
- return t.isAuthEnabled && t.isPending ? null : t.isAuthenticated ? /* @__PURE__ */ e.jsx(f, {}) : t.isAuthEnabled ? /* @__PURE__ */ e.jsxs("div", { className: "flex flex-col justify-center gap-2 items-center h-1/2", children: [
128
+ const t = g();
129
+ return t.isAuthEnabled && t.isPending ? null : t.isAuthenticated ? /* @__PURE__ */ e.jsx(j, {}) : t.isAuthEnabled ? /* @__PURE__ */ e.jsxs("div", { className: "flex flex-col justify-center gap-2 items-center h-1/2", children: [
130
130
  "Please login first to view this page",
131
131
  /* @__PURE__ */ e.jsx(o, { onClick: () => t.login(), children: "Login" })
132
132
  ] }) : /* @__PURE__ */ e.jsx("div", { className: "flex flex-col justify-center gap-2 items-center h-1/2", children: /* @__PURE__ */ e.jsxs(P, { className: "max-w-[600px]", children: [
@@ -135,11 +135,11 @@ const L = ({ service: t }) => {
135
135
  "."
136
136
  ] }) });
137
137
  }, V = ({ service: t }) => {
138
- const n = h(), r = S(), { data: a } = I({
138
+ const n = m(), r = S(), { data: a } = I({
139
139
  queryFn: () => t.getKeys(n),
140
140
  queryKey: ["api-keys"],
141
141
  retry: !1
142
- }), i = p({
142
+ }), i = h({
143
143
  mutationFn: (s) => {
144
144
  if (!t.deleteKey)
145
145
  throw new Error("deleteKey not implemented");
@@ -150,11 +150,12 @@ const L = ({ service: t }) => {
150
150
  }
151
151
  });
152
152
  return /* @__PURE__ */ e.jsxs("div", { className: "max-w-screen-lg h-full pt-[--padding-content-top] pb-[--padding-content-bottom]", children: [
153
+ /* @__PURE__ */ e.jsx(x, { name: "api-keys-list-page" }),
153
154
  /* @__PURE__ */ e.jsxs("div", { className: "flex justify-between mb-4 border-b pb-3", children: [
154
155
  /* @__PURE__ */ e.jsx("h1", { className: "font-medium text-2xl", children: "API Keys" }),
155
156
  t.createKey && /* @__PURE__ */ e.jsx(o, { asChild: !0, children: /* @__PURE__ */ e.jsx(u, { to: "/settings/api-keys/new", children: "Create API Key" }) })
156
157
  ] }),
157
- /* @__PURE__ */ e.jsx(g, { name: "api-keys-list-page-before-keys" }),
158
+ /* @__PURE__ */ e.jsx(x, { name: "api-keys-list-page-before-keys" }),
158
159
  a.length === 0 ? /* @__PURE__ */ e.jsxs("div", { className: "flex flex-col justify-center gap-4 items-center h-1/2 my-8", children: [
159
160
  /* @__PURE__ */ e.jsxs("div", { className: "text-center", children: [
160
161
  "No API keys created yet.",
@@ -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","../src/lib/util/invariant.ts","../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","export default function invariant(\n condition: any,\n // Not providing an inline default argument for message as the result is smaller\n /**\n * Can provide a string, or a function that returns a string for cases where\n * the message takes a fair amount of effort to compute\n */\n message?: string | (() => string),\n): asserts condition {\n if (condition) {\n return;\n }\n // Condition not passed\n\n const provided: string | undefined =\n typeof message === \"function\" ? message() : message;\n\n throw new ZudokuError(provided ?? \"Invariant failed\");\n}\n\nclass ZudokuError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ZudokuError\";\n }\n}\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 {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../../components/Select.js\";\nimport { Button } from \"../../ui/Button.js\";\nimport { Input } from \"../../ui/Input.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 { Slotlet } from \"../../components/SlotletProvider.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 <Slotlet name=\"api-keys-list-page-before-keys\" />\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 { 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 invariant from \"../../util/invariant.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","invariant","condition","message","provided","ZudokuError","CreateApiKey","service","context","useDevPortal","navigate","useNavigate","form","useForm","createKeyMutation","useMutation","description","expiresOn","expiresOnDate","addDaysToDate","jsxs","jsx","data","Input","Select","value","SelectTrigger","SelectValue","SelectContent","SelectGroup","option","SelectItem","Button","Link","days","date","ProtectedRoute","auth","useAuth","Outlet","DeveloperHint","SettingsApiKeys","queryClient","useQueryClient","useSuspenseQuery","deleteKeyMutation","id","Slotlet","cn","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]}
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","../src/lib/util/invariant.ts","../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","export default function invariant(\n condition: any,\n // Not providing an inline default argument for message as the result is smaller\n /**\n * Can provide a string, or a function that returns a string for cases where\n * the message takes a fair amount of effort to compute\n */\n message?: string | (() => string),\n): asserts condition {\n if (condition) {\n return;\n }\n // Condition not passed\n\n const provided: string | undefined =\n typeof message === \"function\" ? message() : message;\n\n throw new ZudokuError(provided ?? \"Invariant failed\");\n}\n\nclass ZudokuError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ZudokuError\";\n }\n}\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 {\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from \"../../components/Select.js\";\nimport { Button } from \"../../ui/Button.js\";\nimport { Input } from \"../../ui/Input.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 { Slotlet } from \"../../components/SlotletProvider.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 <Slotlet name=\"api-keys-list-page\" />\n\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 <Slotlet name=\"api-keys-list-page-before-keys\" />\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 { 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 invariant from \"../../util/invariant.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","invariant","condition","message","provided","ZudokuError","CreateApiKey","service","context","useDevPortal","navigate","useNavigate","form","useForm","createKeyMutation","useMutation","description","expiresOn","expiresOnDate","addDaysToDate","jsxs","jsx","data","Input","Select","value","SelectTrigger","SelectValue","SelectContent","SelectGroup","option","SelectItem","Button","Link","days","date","ProtectedRoute","auth","useAuth","Outlet","DeveloperHint","SettingsApiKeys","queryClient","useQueryClient","useSuspenseQuery","deleteKeyMutation","id","Slotlet","cn","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]}
@@ -1,5 +1,5 @@
1
- import { j as m } from "./jsx-runtime-D0NHp7nI.js";
2
- import { P as o } from "./Markdown-CSdXDuYx.js";
1
+ import { j as m } from "./jsx-runtime-CJBdjYYx.js";
2
+ import { P as o } from "./Markdown-IsabnbGN.js";
3
3
  const l = (s) => ({
4
4
  getRoutes: () => s.map(({ path: e, element: t }) => ({
5
5
  path: e,
@@ -1,5 +1,5 @@
1
- import { j as o, N as x } from "./jsx-runtime-D0NHp7nI.js";
2
- import { v as d, z as g, l as h } from "./DevPortalProvider-DMrk4yw1.js";
1
+ import { j as o, N as x } from "./jsx-runtime-CJBdjYYx.js";
2
+ import { v as d, z as g, l as h } from "./DevPortalProvider-BTFqdAEL.js";
3
3
  const f = (t, e) => {
4
4
  const a = Object.entries(t).flatMap(
5
5
  ([n, m]) => {
@@ -9,7 +9,7 @@ const f = (t, e) => {
9
9
  return {
10
10
  path: i.at(-1) === "index" ? i.slice(0, -1).join("/") : s,
11
11
  lazy: async () => {
12
- const { MdxPage: u } = await import("./MdxPage-7CszsIct.js"), { default: c, ...l } = await m();
12
+ const { MdxPage: u } = await import("./MdxPage-B1B2Inj5.js"), { default: c, ...l } = await m();
13
13
  return {
14
14
  element: /* @__PURE__ */ o.jsx(
15
15
  u,
@@ -1,8 +1,8 @@
1
- import "./jsx-runtime-D0NHp7nI.js";
2
- import { o as n } from "./index-C5qcuxqm.js";
1
+ import "./jsx-runtime-CJBdjYYx.js";
2
+ import { o as n } from "./index-BC2Ob2BR.js";
3
3
  import "./urql-DMlBWUKL.js";
4
4
  import "zudoku/openapi-worker";
5
- import "./Markdown-CSdXDuYx.js";
5
+ import "./Markdown-IsabnbGN.js";
6
6
  import "./router-BiRCp01d.js";
7
7
  export {
8
8
  n as openApiPlugin
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zudoku",
3
- "version": "0.3.0-dev.75",
3
+ "version": "0.3.0-dev.76",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist",
@@ -4,7 +4,7 @@ import { useDevPortal } from "../../components/context/DevPortalProvider.js";
4
4
  export const SignUp = () => {
5
5
  const context = useDevPortal();
6
6
  useEffect(() => {
7
- void context.authentication?.signUp();
7
+ void (context.authentication?.signUp() ?? context.authentication?.signIn());
8
8
  }, [context.authentication]);
9
9
 
10
10
  return null;
@@ -1,12 +1,13 @@
1
1
  import logger from "loglevel";
2
2
  import * as oauth from "oauth4webapi";
3
+ import { NavigateFunction } from "react-router-dom";
3
4
  import { OpenIDAuthenticationConfig } from "../../../config/config.js";
5
+ import { CommonPlugin } from "../../core/plugins.js";
4
6
  import {
5
7
  AuthenticationProvider,
6
8
  AuthenticationProviderInitializer,
7
9
  } from "../authentication.js";
8
10
  import { AuthenticationPlugin } from "../AuthenticationPlugin.js";
9
- import { Callback } from "../Callback.js";
10
11
  import { AuthorizationError, OAuthAuthorizationError } from "../errors.js";
11
12
  import { useAuthState, UserProfile } from "../state.js";
12
13
 
@@ -22,8 +23,7 @@ interface TokenState {
22
23
  class OpenIdAuthPlugin extends AuthenticationPlugin {
23
24
  constructor(
24
25
  private callbackUrlPath: string,
25
- private handleCallback: () => Promise<string>,
26
- public initialize?: () => Promise<void>,
26
+ public initialize?: CommonPlugin["initialize"],
27
27
  ) {
28
28
  super();
29
29
  }
@@ -32,7 +32,7 @@ class OpenIdAuthPlugin extends AuthenticationPlugin {
32
32
  ...super.getRoutes(),
33
33
  {
34
34
  path: this.callbackUrlPath,
35
- element: <Callback handleCallback={this.handleCallback} />,
35
+ element: <div />,
36
36
  },
37
37
  ];
38
38
  }
@@ -204,10 +204,8 @@ export class OpenIDAuthenticationProvider implements AuthenticationProvider {
204
204
  }
205
205
  if (this.tokens.expiresOn < new Date()) {
206
206
  if (!this.tokens.refreshToken) {
207
- // TODO: Log user bac in
208
- throw new AuthorizationError(
209
- "Token expired and no refresh token available",
210
- );
207
+ await this.signIn();
208
+ return "";
211
209
  }
212
210
 
213
211
  const request = await oauth.refreshTokenGrantRequest(
@@ -271,9 +269,7 @@ export class OpenIDAuthenticationProvider implements AuthenticationProvider {
271
269
  sessionStorage.removeItem(CODE_VERIFIER_KEY);
272
270
 
273
271
  if (!codeVerifier) {
274
- throw new AuthorizationError(
275
- "Code verifier not found. Invalid auth state.",
276
- );
272
+ return;
277
273
  }
278
274
 
279
275
  const authServer = await this.getAuthServer();
@@ -351,10 +347,7 @@ export class OpenIDAuthenticationProvider implements AuthenticationProvider {
351
347
  getAuthenticationPlugin() {
352
348
  return new OpenIdAuthPlugin(
353
349
  this.callbackUrlPath,
354
- async () => {
355
- return this.handleCallback();
356
- },
357
- async () => {
350
+ async (_, options: { navigate: NavigateFunction }) => {
358
351
  if (
359
352
  typeof localStorage !== "undefined" &&
360
353
  localStorage.getItem("auto-login")
@@ -362,6 +355,11 @@ export class OpenIDAuthenticationProvider implements AuthenticationProvider {
362
355
  localStorage.removeItem("auto-login");
363
356
 
364
357
  await this.authorize({ redirectTo: window.location.pathname });
358
+ } else if (window.location.pathname === "/oauth/callback") {
359
+ const redirect = await this.handleCallback();
360
+ if (redirect) {
361
+ options.navigate(redirect);
362
+ }
365
363
  }
366
364
  },
367
365
  );
@@ -12,7 +12,7 @@ import {
12
12
  useState,
13
13
  } from "react";
14
14
  import { ErrorBoundary } from "react-error-boundary";
15
- import { Outlet, useNavigation } from "react-router-dom";
15
+ import { Outlet, useNavigate, useNavigation } from "react-router-dom";
16
16
  import {
17
17
  DevPortalContext,
18
18
  queryClient,
@@ -56,6 +56,7 @@ const DevPortalInner = ({
56
56
  const [isInitialized, setIsInitialized] = useState(false);
57
57
  const { stagger } = useContext(StaggeredRenderContext);
58
58
  const [didNavigate, setDidNavigate] = useState(false);
59
+ const navigate = useNavigate();
59
60
  const initRef = useRef<"idle" | "pending" | "done">("idle");
60
61
  const staggeredValue = useMemo(
61
62
  () => (didNavigate ? { stagger: true } : { stagger }),
@@ -76,11 +77,11 @@ const DevPortalInner = ({
76
77
  useEffect(() => {
77
78
  if (initRef.current === "pending") return;
78
79
  initRef.current = "pending";
79
- void devPortalContext.initialize().then(() => {
80
+ void devPortalContext.initialize({ navigate }).then(() => {
80
81
  initRef.current = "done";
81
82
  setIsInitialized(true);
82
83
  });
83
- }, [devPortalContext]);
84
+ }, [devPortalContext, navigate]);
84
85
 
85
86
  const heads = props.plugins
86
87
  ?.filter(hasHead)
@@ -1,5 +1,6 @@
1
1
  import { QueryClient } from "@tanstack/react-query";
2
2
  import { type ReactNode } from "react";
3
+ import { NavigateFunction } from "react-router-dom";
3
4
  import { type AuthenticationProvider } from "../authentication/authentication.js";
4
5
  import type { ComponentsContextType } from "../components/context/ComponentsContext.js";
5
6
  import { type DevPortalPath } from "../components/DevPortal.js";
@@ -115,11 +116,15 @@ export class DevPortalContext {
115
116
  this.page = config.page;
116
117
  }
117
118
 
118
- initialize = async () => {
119
+ initialize = async ({
120
+ navigate,
121
+ }: {
122
+ navigate: NavigateFunction;
123
+ }): Promise<void> => {
119
124
  await Promise.all(
120
125
  this.plugins
121
126
  .filter(needsInitialization)
122
- .map((plugin) => plugin.initialize?.(this)),
127
+ .map((plugin) => plugin.initialize?.(this, { navigate })),
123
128
  );
124
129
  };
125
130
 
@@ -1,5 +1,5 @@
1
1
  import { type ReactElement } from "react";
2
- import { type RouteObject } from "react-router-dom";
2
+ import { NavigateFunction, type RouteObject } from "react-router-dom";
3
3
  import {
4
4
  DevPortalContext,
5
5
  type ApiIdentity,
@@ -36,7 +36,10 @@ export type NavigationItem = {
36
36
  };
37
37
 
38
38
  export interface CommonPlugin {
39
- initialize?: (context: DevPortalContext) => Promise<void> | void;
39
+ initialize?: (
40
+ context: DevPortalContext,
41
+ options: { navigate: NavigateFunction },
42
+ ) => Promise<void | boolean> | void | boolean;
40
43
  getHead?: () => ReactElement | undefined;
41
44
  }
42
45
 
@@ -36,6 +36,8 @@ export const SettingsApiKeys = ({ service }: { service: ApiKeyService }) => {
36
36
 
37
37
  return (
38
38
  <div className="max-w-screen-lg h-full pt-[--padding-content-top] pb-[--padding-content-bottom]">
39
+ <Slotlet name="api-keys-list-page" />
40
+
39
41
  <div className="flex justify-between mb-4 border-b pb-3">
40
42
  <h1 className="font-medium text-2xl">API Keys</h1>
41
43
  {service.createKey && (
@@ -1,3 +0,0 @@
1
- export declare function Callback({ handleCallback, }: {
2
- handleCallback: () => Promise<string>;
3
- }): import("react/jsx-runtime").JSX.Element | undefined;
@@ -1,33 +0,0 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useEffect, useRef, useState } from "react";
3
- import { useNavigate } from "react-router-dom";
4
- import { OAuthAuthorizationError } from "./errors.js";
5
- export function Callback({ handleCallback, }) {
6
- const didInitialize = useRef(false);
7
- const [error, setError] = useState(undefined);
8
- const navigate = useNavigate();
9
- // This should not use react query, etc. It is important that it
10
- // only ever runs once. The didInitialize ref keeps it from double
11
- // initializing in dev mode with ReactStrict enabled.
12
- useEffect(() => {
13
- if (didInitialize.current) {
14
- return;
15
- }
16
- didInitialize.current = true;
17
- handleCallback()
18
- .then((redirect) => {
19
- // TODO: Handle return url, state, etc
20
- navigate(redirect);
21
- })
22
- .catch((err) => {
23
- setError(err);
24
- });
25
- }, []);
26
- if (error) {
27
- if (error instanceof OAuthAuthorizationError) {
28
- return (_jsxs("div", { children: [_jsx("h2", { children: "Error" }), _jsxs("pre", { children: [error.error.error, error.error.error_description, error.error.error_uri] })] }));
29
- }
30
- return (_jsxs("div", { children: [_jsx("h2", { children: "Error" }), _jsxs("pre", { children: [error.message, error.stack] })] }));
31
- }
32
- }
33
- //# sourceMappingURL=Callback.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"Callback.js","sourceRoot":"","sources":["../../../src/lib/authentication/Callback.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAEtD,MAAM,UAAU,QAAQ,CAAC,EACvB,cAAc,GAGf;IACC,MAAM,aAAa,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC;IACpC,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAoB,SAAS,CAAC,CAAC;IACjE,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAC;IAE/B,gEAAgE;IAChE,kEAAkE;IAClE,qDAAqD;IACrD,SAAS,CAAC,GAAG,EAAE;QACb,IAAI,aAAa,CAAC,OAAO,EAAE,CAAC;YAC1B,OAAO;QACT,CAAC;QACD,aAAa,CAAC,OAAO,GAAG,IAAI,CAAC;QAC7B,cAAc,EAAE;aACb,IAAI,CAAC,CAAC,QAAQ,EAAE,EAAE;YACjB,sCAAsC;YACtC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACrB,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YACb,QAAQ,CAAC,GAAG,CAAC,CAAC;QAChB,CAAC,CAAC,CAAC;IACP,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,IAAI,KAAK,EAAE,CAAC;QACV,IAAI,KAAK,YAAY,uBAAuB,EAAE,CAAC;YAC7C,OAAO,CACL,0BACE,iCAAc,EACd,0BACG,KAAK,CAAC,KAAK,CAAC,KAAK,EAEjB,KAAK,CAAC,KAAK,CAAC,iBAAiB,EAE7B,KAAK,CAAC,KAAK,CAAC,SAAS,IAClB,IACF,CACP,CAAC;QACJ,CAAC;QACD,OAAO,CACL,0BACE,iCAAc,EACd,0BACG,KAAK,CAAC,OAAO,EAEb,KAAK,CAAC,KAAK,IACR,IACF,CACP,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"AuthenticationPlugin-BuCQtecV.js","sources":["../src/lib/authentication/components/SignIn.tsx","../src/lib/authentication/components/SignOut.tsx","../src/lib/authentication/components/SignUp.tsx","../src/lib/authentication/AuthenticationPlugin.tsx"],"sourcesContent":["import { useEffect } from \"react\";\nimport { useSearchParams } from \"react-router-dom\";\nimport { useDevPortal } from \"../../components/context/DevPortalProvider.js\";\n\nexport const SignIn = () => {\n const context = useDevPortal();\n const [search] = useSearchParams();\n useEffect(() => {\n void context.authentication?.signIn({\n redirectTo: search.get(\"redirect\") ?? undefined,\n });\n }, [context.authentication, search]);\n\n return null;\n};\n","import { useEffect } from \"react\";\nimport { useNavigate } from \"react-router-dom\";\nimport { useDevPortal } from \"../../components/context/DevPortalProvider.js\";\n\nexport const SignOut = () => {\n const context = useDevPortal();\n const navigate = useNavigate();\n useEffect(() => {\n void context.authentication?.signOut().then(() => navigate(\"/\"));\n }, [navigate, context.authentication]);\n\n return null;\n};\n","import { useEffect } from \"react\";\nimport { useDevPortal } from \"../../components/context/DevPortalProvider.js\";\n\nexport const SignUp = () => {\n const context = useDevPortal();\n useEffect(() => {\n void context.authentication?.signUp();\n }, [context.authentication]);\n\n return null;\n};\n","import {\n CommonPlugin,\n NavigationPlugin,\n ProfileMenuPlugin,\n} from \"../core/plugins.js\";\nimport { SignIn } from \"./components/SignIn.js\";\nimport { SignOut } from \"./components/SignOut.js\";\nimport { SignUp } from \"./components/SignUp.js\";\n\ntype PluginInterface = NavigationPlugin & CommonPlugin & ProfileMenuPlugin;\n\nexport class AuthenticationPlugin implements PluginInterface {\n getRoutes() {\n return [\n {\n path: \"/signout\",\n element: <SignOut />,\n },\n {\n path: \"/signin\",\n element: <SignIn />,\n },\n {\n path: \"/signup\",\n element: <SignUp />,\n },\n ];\n }\n\n getProfileMenuItems() {\n return [\n {\n label: \"Logout\",\n path: \"/signout\",\n },\n ];\n }\n}\n"],"names":["SignIn","context","useDevPortal","search","useSearchParams","useEffect","_a","SignOut","navigate","useNavigate","SignUp","AuthenticationPlugin"],"mappings":";;;;AAIO,MAAMA,IAAS,MAAM;AAC1B,QAAMC,IAAUC,KACV,CAACC,CAAM,IAAIC;AACjB,SAAAC,EAAU,MAAM;;AACT,KAAAC,IAAAL,EAAQ,mBAAR,QAAAK,EAAwB,OAAO;AAAA,MAClC,YAAYH,EAAO,IAAI,UAAU,KAAK;AAAA,IAAA;AAAA,EAEvC,GAAA,CAACF,EAAQ,gBAAgBE,CAAM,CAAC,GAE5B;AACT,GCVaI,IAAU,MAAM;AAC3B,QAAMN,IAAUC,KACVM,IAAWC;AACjB,SAAAJ,EAAU,MAAM;;AACT,KAAAC,IAAAL,EAAQ,mBAAR,QAAAK,EAAwB,UAAU,KAAK,MAAME,EAAS,GAAG;AAAA,EAC7D,GAAA,CAACA,GAAUP,EAAQ,cAAc,CAAC,GAE9B;AACT,GCTaS,IAAS,MAAM;AAC1B,QAAMT,IAAUC;AAChB,SAAAG,EAAU,MAAM;;AACT,KAAAC,IAAAL,EAAQ,mBAAR,QAAAK,EAAwB;AAAA,EAAO,GACnC,CAACL,EAAQ,cAAc,CAAC,GAEpB;AACT;ACCO,MAAMU,EAAgD;AAAA,EAC3D,YAAY;AACH,WAAA;AAAA,MACL;AAAA,QACE,MAAM;AAAA,QACN,+BAAUJ,GAAQ,EAAA;AAAA,MACpB;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,+BAAUP,GAAO,EAAA;AAAA,MACnB;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,+BAAUU,GAAO,EAAA;AAAA,MACnB;AAAA,IAAA;AAAA,EAEJ;AAAA,EAEA,sBAAsB;AACb,WAAA;AAAA,MACL;AAAA,QACE,OAAO;AAAA,QACP,MAAM;AAAA,MACR;AAAA,IAAA;AAAA,EAEJ;AACF;"}
@@ -1,58 +0,0 @@
1
- import { useEffect, useRef, useState } from "react";
2
- import { useNavigate } from "react-router-dom";
3
- import { OAuthAuthorizationError } from "./errors.js";
4
-
5
- export function Callback({
6
- handleCallback,
7
- }: {
8
- handleCallback: () => Promise<string>;
9
- }) {
10
- const didInitialize = useRef(false);
11
- const [error, setError] = useState<Error | undefined>(undefined);
12
- const navigate = useNavigate();
13
-
14
- // This should not use react query, etc. It is important that it
15
- // only ever runs once. The didInitialize ref keeps it from double
16
- // initializing in dev mode with ReactStrict enabled.
17
- useEffect(() => {
18
- if (didInitialize.current) {
19
- return;
20
- }
21
- didInitialize.current = true;
22
- handleCallback()
23
- .then((redirect) => {
24
- // TODO: Handle return url, state, etc
25
- navigate(redirect);
26
- })
27
- .catch((err) => {
28
- setError(err);
29
- });
30
- }, []);
31
-
32
- if (error) {
33
- if (error instanceof OAuthAuthorizationError) {
34
- return (
35
- <div>
36
- <h2>Error</h2>
37
- <pre>
38
- {error.error.error}
39
-
40
- {error.error.error_description}
41
-
42
- {error.error.error_uri}
43
- </pre>
44
- </div>
45
- );
46
- }
47
- return (
48
- <div>
49
- <h2>Error</h2>
50
- <pre>
51
- {error.message}
52
-
53
- {error.stack}
54
- </pre>
55
- </div>
56
- );
57
- }
58
- }