zudoku 0.6.2-dev.5 → 0.6.2-dev.7
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.
- package/dist/config/validators/validate.d.ts +115 -0
- package/dist/config/validators/validate.js +43 -0
- package/dist/config/validators/validate.js.map +1 -1
- package/dist/vite/prerender.js +7 -0
- package/dist/vite/prerender.js.map +1 -1
- package/dist/vite/sitemap.d.ts +19 -0
- package/dist/vite/sitemap.js +40 -0
- package/dist/vite/sitemap.js.map +1 -0
- package/lib/AuthenticationPlugin-BMjOjKqE.js +54 -0
- package/lib/{AuthenticationPlugin-Bx9FK124.js.map → AuthenticationPlugin-BMjOjKqE.js.map} +1 -1
- package/lib/CategoryHeading-BE8e6QdS.js +9 -0
- package/lib/{CategoryHeading-XnFqN2lJ.js.map → CategoryHeading-BE8e6QdS.js.map} +1 -1
- package/lib/DeveloperHint-Bl9gIdNI.js +12 -0
- package/lib/{DeveloperHint-FBb2uXJe.js.map → DeveloperHint-Bl9gIdNI.js.map} +1 -1
- package/lib/ErrorPage-CPR1XVKW.js +12 -0
- package/lib/{ErrorPage-knunPbKI.js.map → ErrorPage-CPR1XVKW.js.map} +1 -1
- package/lib/Input-BBlyeDuG.js +2192 -0
- package/lib/{Input-BEDZAKw0.js.map → Input-BBlyeDuG.js.map} +1 -1
- package/lib/{Markdown-B4aR03g6.js → Markdown-CCNihH_N.js} +2641 -2650
- package/lib/{Markdown-B4aR03g6.js.map → Markdown-CCNihH_N.js.map} +1 -1
- package/lib/MdxPage-BavkYqzi.js +140 -0
- package/lib/{MdxPage-BZyQsH8Z.js.map → MdxPage-BavkYqzi.js.map} +1 -1
- package/lib/OperationList-C6Ps2keZ.js +460 -0
- package/lib/{OperationList-2NeWEM0u.js.map → OperationList-C6Ps2keZ.js.map} +1 -1
- package/lib/Route-xRJ9mJgH.js +13 -0
- package/lib/{Route-BZPewmrN.js.map → Route-xRJ9mJgH.js.map} +1 -1
- package/lib/{SidebarBadge-COz0hgfa.js → SidebarBadge-2JcxswKF.js} +41 -41
- package/lib/{SidebarBadge-COz0hgfa.js.map → SidebarBadge-2JcxswKF.js.map} +1 -1
- package/lib/SlotletProvider-CuB3Ts8r.js +213 -0
- package/lib/{SlotletProvider-DJMaOUDs.js.map → SlotletProvider-CuB3Ts8r.js.map} +1 -1
- package/lib/Spinner-BlxzaFFF.js +6 -0
- package/lib/Spinner-BlxzaFFF.js.map +1 -0
- package/lib/{ZudokuContext-cr-pTRY1.js → ZudokuContext-JoyeA9dT.js} +65 -66
- package/lib/{ZudokuContext-cr-pTRY1.js.map → ZudokuContext-JoyeA9dT.js.map} +1 -1
- package/lib/{index-Dv2KZuEw.js → index-BF4cn28H.js} +1804 -1991
- package/lib/{index-Dv2KZuEw.js.map → index-BF4cn28H.js.map} +1 -1
- package/lib/{index-Zezcv0xb.js → index-BLvMkqjO.js} +5 -5
- package/lib/{index-Zezcv0xb.js.map → index-BLvMkqjO.js.map} +1 -1
- package/lib/{index-1EDgIO6b.js → index-G1-TGLO1.js} +4 -4
- package/lib/{index-1EDgIO6b.js.map → index-G1-TGLO1.js.map} +1 -1
- package/lib/jsx-runtime-lNnQYwFN.js +2403 -0
- package/lib/jsx-runtime-lNnQYwFN.js.map +1 -0
- package/lib/{utils-ByIc_KIM.js → utils-B8R4grFM.js} +97 -98
- package/lib/{utils-ByIc_KIM.js.map → utils-B8R4grFM.js.map} +1 -1
- package/lib/zudoku.auth-auth0.js +16 -21
- package/lib/zudoku.auth-auth0.js.map +1 -1
- package/lib/zudoku.auth-clerk.js +32 -37
- package/lib/zudoku.auth-clerk.js.map +1 -1
- package/lib/zudoku.auth-openid.js +485 -505
- package/lib/zudoku.auth-openid.js.map +1 -1
- package/lib/zudoku.components.js +1531 -1659
- package/lib/zudoku.components.js.map +1 -1
- package/lib/zudoku.plugin-api-keys.js +150 -214
- package/lib/zudoku.plugin-api-keys.js.map +1 -1
- package/lib/zudoku.plugin-custom-page.js +5 -6
- package/lib/zudoku.plugin-custom-page.js.map +1 -1
- package/lib/zudoku.plugin-markdown.js +12 -13
- package/lib/zudoku.plugin-markdown.js.map +1 -1
- package/lib/zudoku.plugin-openapi.js +7 -8
- package/lib/zudoku.plugin-openapi.js.map +1 -1
- package/lib/zudoku.plugin-search-inkeep.js +20 -21
- package/lib/zudoku.plugin-search-inkeep.js.map +1 -1
- package/package.json +3 -2
- package/lib/AuthenticationPlugin-Bx9FK124.js +0 -55
- package/lib/CategoryHeading-XnFqN2lJ.js +0 -10
- package/lib/DeveloperHint-FBb2uXJe.js +0 -16
- package/lib/ErrorPage-knunPbKI.js +0 -18
- package/lib/Input-BEDZAKw0.js +0 -2198
- package/lib/MdxPage-BZyQsH8Z.js +0 -172
- package/lib/OperationList-2NeWEM0u.js +0 -560
- package/lib/Route-BZPewmrN.js +0 -14
- package/lib/SlotletProvider-DJMaOUDs.js +0 -238
- package/lib/Spinner-3cQDBVGr.js +0 -7
- package/lib/Spinner-3cQDBVGr.js.map +0 -1
- package/lib/index-BG0g4WW0.js +0 -1771
- package/lib/index-BG0g4WW0.js.map +0 -1
- package/lib/jsx-runtime-B6kdoens.js +0 -635
- package/lib/jsx-runtime-B6kdoens.js.map +0 -1
|
@@ -1,250 +1,186 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { S as x,
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { RotateCwIcon as P, TrashIcon as D, EyeOffIcon as R, EyeIcon as q, CheckIcon as O, CopyIcon as z } from "lucide-react";
|
|
1
|
+
import { S as u, R as f } from "./SlotletProvider-CuB3Ts8r.js";
|
|
2
|
+
import { u as R, a as o, I as g, S as h, b as x, c as v, d as k, e as w, f as d } from "./Input-BBlyeDuG.js";
|
|
3
|
+
import { a as b, L as m, O as K } from "./jsx-runtime-lNnQYwFN.js";
|
|
4
|
+
import { u as y, a as N, b as I } from "./ZudokuContext-JoyeA9dT.js";
|
|
5
|
+
import { B as l, m as S } from "./index-BLvMkqjO.js";
|
|
6
|
+
import { D as A } from "./DeveloperHint-Bl9gIdNI.js";
|
|
7
|
+
import { RotateCwIcon as C, TrashIcon as P, EyeOffIcon as D, EyeIcon as q, CheckIcon as O, CopyIcon as z } from "lucide-react";
|
|
9
8
|
import { useState as p } from "react";
|
|
10
|
-
import { a as T } from "./Markdown-
|
|
11
|
-
function
|
|
12
|
-
if (
|
|
9
|
+
import { a as T } from "./Markdown-CCNihH_N.js";
|
|
10
|
+
function i(e, t) {
|
|
11
|
+
if (e)
|
|
13
12
|
return;
|
|
14
|
-
const
|
|
15
|
-
throw new F(
|
|
13
|
+
const n = typeof t == "function" ? t() : t;
|
|
14
|
+
throw new F(n ?? "Invariant failed");
|
|
16
15
|
}
|
|
17
16
|
class F extends Error {
|
|
18
|
-
constructor(
|
|
19
|
-
super(
|
|
17
|
+
constructor(t) {
|
|
18
|
+
super(t), this.name = "ZudokuError";
|
|
20
19
|
}
|
|
21
20
|
}
|
|
22
|
-
const
|
|
23
|
-
const
|
|
21
|
+
const j = ({ service: e }) => {
|
|
22
|
+
const t = y(), n = b(), a = R({
|
|
24
23
|
defaultValues: {
|
|
25
24
|
expiresOn: "30"
|
|
26
25
|
}
|
|
27
|
-
}),
|
|
28
|
-
mutationFn: ({ description:
|
|
29
|
-
if (!
|
|
26
|
+
}), s = o({
|
|
27
|
+
mutationFn: ({ description: c, expiresOn: r }) => {
|
|
28
|
+
if (!e.createKey)
|
|
30
29
|
throw new Error("deleteKey not implemented");
|
|
31
|
-
const
|
|
32
|
-
return
|
|
33
|
-
{ description:
|
|
34
|
-
|
|
30
|
+
const E = r !== "never" ? L(Number(r)) : void 0;
|
|
31
|
+
return e.createKey(
|
|
32
|
+
{ description: c, expiresOn: E },
|
|
33
|
+
t
|
|
35
34
|
);
|
|
36
35
|
},
|
|
37
|
-
onSuccess: () =>
|
|
36
|
+
onSuccess: () => n("/settings/api-keys/")
|
|
38
37
|
});
|
|
39
|
-
return
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
return e.createKey ? /* @__PURE__ */ React.createElement("div", { className: "max-w-screen-lg pt-[--padding-content-top] pb-[--padding-content-bottom]" }, /* @__PURE__ */ React.createElement("div", { className: "flex justify-between mb-4 border-b pb-1" }, /* @__PURE__ */ React.createElement("h1", { className: "font-medium text-2xl" }, "New API Key")), /* @__PURE__ */ React.createElement(
|
|
39
|
+
"form",
|
|
40
|
+
{
|
|
41
|
+
onSubmit: a.handleSubmit((c) => s.mutate(c))
|
|
42
|
+
},
|
|
43
|
+
/* @__PURE__ */ React.createElement("div", { className: "flex gap-2 flex-col" }, "Note", /* @__PURE__ */ React.createElement(g, { ...a.register("description") }), "Expiration", /* @__PURE__ */ React.createElement(
|
|
44
|
+
h,
|
|
43
45
|
{
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
] }, a)),
|
|
61
|
-
/* @__PURE__ */ e.jsx(m, { value: "never", children: "Never" })
|
|
62
|
-
] }) })
|
|
63
|
-
]
|
|
64
|
-
}
|
|
65
|
-
),
|
|
66
|
-
/* @__PURE__ */ e.jsxs("div", { className: "flex gap-2", children: [
|
|
67
|
-
/* @__PURE__ */ e.jsx(l, { children: "Generate Key" }),
|
|
68
|
-
/* @__PURE__ */ e.jsx(l, { variant: "outline", asChild: !0, children: /* @__PURE__ */ e.jsx(u, { to: "/settings/api-keys/", children: "Cancel" }) })
|
|
69
|
-
] })
|
|
70
|
-
] })
|
|
71
|
-
}
|
|
72
|
-
)
|
|
73
|
-
] }) : null;
|
|
74
|
-
}, V = (t) => {
|
|
75
|
-
const s = /* @__PURE__ */ new Date();
|
|
76
|
-
return s.setDate(s.getDate() + t), s.toISOString();
|
|
77
|
-
}, M = () => {
|
|
78
|
-
const t = A();
|
|
79
|
-
return t.isAuthEnabled && t.isPending ? null : t.isAuthenticated ? /* @__PURE__ */ e.jsx(I, {}) : t.isAuthEnabled ? /* @__PURE__ */ e.jsxs("div", { className: "flex flex-col justify-center gap-2 items-center h-1/2", children: [
|
|
80
|
-
"Please login first to view this page",
|
|
81
|
-
/* @__PURE__ */ e.jsx(l, { onClick: () => t.login(), children: "Login" })
|
|
82
|
-
] }) : /* @__PURE__ */ e.jsx("div", { className: "flex flex-col justify-center gap-2 items-center h-1/2", children: /* @__PURE__ */ e.jsxs(C, { className: "max-w-[600px]", children: [
|
|
83
|
-
"Authentication needs to be enabled for API keys to work. Enable it in your Zudoku configuration under ",
|
|
84
|
-
/* @__PURE__ */ e.jsx("code", { children: "authentication" }),
|
|
85
|
-
"."
|
|
86
|
-
] }) });
|
|
87
|
-
}, _ = ({ service: t }) => {
|
|
88
|
-
const s = h(), i = E(), { data: n } = S({
|
|
89
|
-
queryFn: () => t.getKeys(s),
|
|
46
|
+
onValueChange: (c) => a.setValue("expiresOn", c),
|
|
47
|
+
defaultValue: a.getValues("expiresOn")
|
|
48
|
+
},
|
|
49
|
+
/* @__PURE__ */ React.createElement(x, null, /* @__PURE__ */ React.createElement(v, null)),
|
|
50
|
+
/* @__PURE__ */ React.createElement(k, null, /* @__PURE__ */ React.createElement(w, null, [7, 30, 60, 90].map((c) => /* @__PURE__ */ React.createElement(d, { value: String(c), key: c }, c, " days")), /* @__PURE__ */ React.createElement(d, { value: "never" }, "Never")))
|
|
51
|
+
), /* @__PURE__ */ React.createElement("div", { className: "flex gap-2" }, /* @__PURE__ */ React.createElement(l, null, "Generate Key"), /* @__PURE__ */ React.createElement(l, { variant: "outline", asChild: !0 }, /* @__PURE__ */ React.createElement(m, { to: "/settings/api-keys/" }, "Cancel"))))
|
|
52
|
+
)) : null;
|
|
53
|
+
}, L = (e) => {
|
|
54
|
+
const t = /* @__PURE__ */ new Date();
|
|
55
|
+
return t.setDate(t.getDate() + e), t.toISOString();
|
|
56
|
+
}, V = () => {
|
|
57
|
+
const e = S();
|
|
58
|
+
return e.isAuthEnabled && e.isPending ? null : e.isAuthenticated ? /* @__PURE__ */ React.createElement(K, null) : e.isAuthEnabled ? /* @__PURE__ */ React.createElement("div", { className: "flex flex-col justify-center gap-2 items-center h-1/2" }, "Please login first to view this page", /* @__PURE__ */ React.createElement(l, { onClick: () => e.login() }, "Login")) : /* @__PURE__ */ React.createElement("div", { className: "flex flex-col justify-center gap-2 items-center h-1/2" }, /* @__PURE__ */ React.createElement(A, { className: "max-w-[600px]" }, "Authentication needs to be enabled for API keys to work. Enable it in your Zudoku configuration under ", /* @__PURE__ */ React.createElement("code", null, "authentication"), "."));
|
|
59
|
+
}, M = ({ service: e }) => {
|
|
60
|
+
const t = y(), n = N(), { data: a } = I({
|
|
61
|
+
queryFn: () => e.getKeys(t),
|
|
90
62
|
queryKey: ["api-keys"],
|
|
91
63
|
retry: !1
|
|
92
|
-
}),
|
|
64
|
+
}), s = o({
|
|
93
65
|
mutationFn: (r) => {
|
|
94
|
-
if (!
|
|
66
|
+
if (!e.deleteKey)
|
|
95
67
|
throw new Error("deleteKey not implemented");
|
|
96
|
-
return
|
|
68
|
+
return e.deleteKey(r, t);
|
|
97
69
|
},
|
|
98
70
|
onSuccess: () => {
|
|
99
|
-
|
|
71
|
+
n.invalidateQueries({ queryKey: ["api-keys"] });
|
|
100
72
|
}
|
|
101
|
-
}),
|
|
73
|
+
}), c = o({
|
|
102
74
|
mutationFn: (r) => {
|
|
103
|
-
if (!
|
|
75
|
+
if (!e.rollKey)
|
|
104
76
|
throw new Error("rollKey not implemented");
|
|
105
|
-
return
|
|
77
|
+
return e.rollKey(r, t);
|
|
106
78
|
},
|
|
107
|
-
onSuccess: () =>
|
|
79
|
+
onSuccess: () => n.invalidateQueries({ queryKey: ["api-keys"] })
|
|
108
80
|
});
|
|
109
|
-
return /* @__PURE__ */
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
/* @__PURE__ */ e.jsx("br", {}),
|
|
120
|
-
"Get started and create your first key."
|
|
121
|
-
] }),
|
|
122
|
-
t.createKey && /* @__PURE__ */ e.jsx(l, { asChild: !0, variant: "outline", children: /* @__PURE__ */ e.jsx(u, { to: "/settings/api-keys/new", children: "Create API Key" }) })
|
|
123
|
-
] }) : /* @__PURE__ */ e.jsx(
|
|
124
|
-
"ul",
|
|
81
|
+
return /* @__PURE__ */ React.createElement("div", { className: "max-w-screen-lg h-full pt-[--padding-content-top] pb-[--padding-content-bottom]" }, /* @__PURE__ */ React.createElement(u, { name: "api-keys-list-page" }), /* @__PURE__ */ React.createElement("div", { className: "flex justify-between mb-4 border-b pb-3" }, /* @__PURE__ */ React.createElement("h1", { className: "font-medium text-2xl" }, "API Keys"), e.createKey && /* @__PURE__ */ React.createElement(l, { asChild: !0 }, /* @__PURE__ */ React.createElement(m, { to: "/settings/api-keys/new" }, "Create API Key"))), /* @__PURE__ */ React.createElement(u, { name: "api-keys-list-page-before-keys" }), a.length === 0 ? /* @__PURE__ */ React.createElement("div", { className: "flex flex-col justify-center gap-4 items-center p-8 border rounded bg-muted/30 text-muted-foreground" }, /* @__PURE__ */ React.createElement("p", { className: "text-center" }, "No API keys created yet.", /* @__PURE__ */ React.createElement("br", null), "Get started and create your first key."), e.createKey && /* @__PURE__ */ React.createElement(l, { asChild: !0, variant: "outline" }, /* @__PURE__ */ React.createElement(m, { to: "/settings/api-keys/new" }, "Create API Key"))) : /* @__PURE__ */ React.createElement(
|
|
82
|
+
"ul",
|
|
83
|
+
{
|
|
84
|
+
className: T(
|
|
85
|
+
"grid grid-cols-1 rounded border divide-y divide-border",
|
|
86
|
+
"lg:grid-cols-[minmax(250px,min-content)_1fr_min-content]"
|
|
87
|
+
)
|
|
88
|
+
},
|
|
89
|
+
a.map((r) => /* @__PURE__ */ React.createElement(
|
|
90
|
+
"li",
|
|
125
91
|
{
|
|
126
|
-
className:
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
/* @__PURE__ */ e.jsxs("div", { className: "flex gap-2", children: [
|
|
150
|
-
t.rollKey && /* @__PURE__ */ e.jsx(
|
|
151
|
-
l,
|
|
152
|
-
{
|
|
153
|
-
size: "icon",
|
|
154
|
-
title: "Roll this key",
|
|
155
|
-
variant: "ghost",
|
|
156
|
-
onClick: () => {
|
|
157
|
-
confirm("Do you want to roll this key?") && a.mutate(r.id);
|
|
158
|
-
},
|
|
159
|
-
children: /* @__PURE__ */ e.jsx(P, { size: 16 })
|
|
160
|
-
}
|
|
161
|
-
),
|
|
162
|
-
t.deleteKey && /* @__PURE__ */ e.jsx(
|
|
163
|
-
l,
|
|
164
|
-
{
|
|
165
|
-
variant: "ghost",
|
|
166
|
-
size: "icon",
|
|
167
|
-
onClick: () => {
|
|
168
|
-
confirm("Do you want to delete this key?") && o.mutate(r.id);
|
|
169
|
-
},
|
|
170
|
-
disabled: o.isPending,
|
|
171
|
-
children: /* @__PURE__ */ e.jsx(D, { size: 16 })
|
|
172
|
-
}
|
|
173
|
-
)
|
|
174
|
-
] })
|
|
175
|
-
]
|
|
92
|
+
className: "p-5 grid grid-cols-subgrid col-span-full gap-2 items-center",
|
|
93
|
+
key: r.id
|
|
94
|
+
},
|
|
95
|
+
/* @__PURE__ */ React.createElement("div", { className: "flex flex-col gap-1 text-sm" }, r.description ?? r.id, /* @__PURE__ */ React.createElement("div", { className: "text-muted-foreground text-xs" }, r.createdOn && /* @__PURE__ */ React.createElement("div", null, "Created on ", new Date(r.createdOn).toLocaleDateString()), r.expiresOn && /* @__PURE__ */ React.createElement("div", null, "Expires on ", new Date(r.expiresOn).toLocaleDateString()))),
|
|
96
|
+
/* @__PURE__ */ React.createElement("div", { className: "items-center flex lg:justify-center" }, /* @__PURE__ */ React.createElement(_, { apiKey: r.key })),
|
|
97
|
+
/* @__PURE__ */ React.createElement("div", { className: "flex gap-2" }, e.rollKey && /* @__PURE__ */ React.createElement(
|
|
98
|
+
l,
|
|
99
|
+
{
|
|
100
|
+
size: "icon",
|
|
101
|
+
title: "Roll this key",
|
|
102
|
+
variant: "ghost",
|
|
103
|
+
onClick: () => {
|
|
104
|
+
confirm("Do you want to roll this key?") && c.mutate(r.id);
|
|
105
|
+
}
|
|
106
|
+
},
|
|
107
|
+
/* @__PURE__ */ React.createElement(C, { size: 16 })
|
|
108
|
+
), e.deleteKey && /* @__PURE__ */ React.createElement(
|
|
109
|
+
l,
|
|
110
|
+
{
|
|
111
|
+
variant: "ghost",
|
|
112
|
+
size: "icon",
|
|
113
|
+
onClick: () => {
|
|
114
|
+
confirm("Do you want to delete this key?") && s.mutate(r.id);
|
|
176
115
|
},
|
|
177
|
-
|
|
178
|
-
))
|
|
179
|
-
}
|
|
180
|
-
)
|
|
181
|
-
] });
|
|
182
|
-
}, Q = ({ apiKey: t }) => {
|
|
183
|
-
const [s, i] = p(!1), [n, o] = p(!1);
|
|
184
|
-
return /* @__PURE__ */ e.jsxs("div", { className: "flex gap-2 items-center text-sm", children: [
|
|
185
|
-
/* @__PURE__ */ e.jsx("div", { className: "border rounded bg-gray-100 dark:bg-gray-950 p-1 font-mono truncate h-9 items-center flex px-2", children: s ? t : "•".repeat(t.length) }),
|
|
186
|
-
/* @__PURE__ */ e.jsx(
|
|
187
|
-
l,
|
|
188
|
-
{
|
|
189
|
-
variant: "outline",
|
|
190
|
-
onClick: () => i((a) => !a),
|
|
191
|
-
size: "icon",
|
|
192
|
-
children: s ? /* @__PURE__ */ e.jsx(R, { size: 16 }) : /* @__PURE__ */ e.jsx(q, { size: 16 })
|
|
193
|
-
}
|
|
194
|
-
),
|
|
195
|
-
/* @__PURE__ */ e.jsx(
|
|
196
|
-
l,
|
|
197
|
-
{
|
|
198
|
-
variant: "outline",
|
|
199
|
-
onClick: () => {
|
|
200
|
-
navigator.clipboard.writeText(t).then(() => {
|
|
201
|
-
o(!0), setTimeout(() => o(!1), 2e3);
|
|
202
|
-
});
|
|
116
|
+
disabled: s.isPending
|
|
203
117
|
},
|
|
204
|
-
size:
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
118
|
+
/* @__PURE__ */ React.createElement(P, { size: 16 })
|
|
119
|
+
))
|
|
120
|
+
))
|
|
121
|
+
));
|
|
122
|
+
}, _ = ({ apiKey: e }) => {
|
|
123
|
+
const [t, n] = p(!1), [a, s] = p(!1);
|
|
124
|
+
return /* @__PURE__ */ React.createElement("div", { className: "flex gap-2 items-center text-sm" }, /* @__PURE__ */ React.createElement("div", { className: "border rounded bg-gray-100 dark:bg-gray-950 p-1 font-mono truncate h-9 items-center flex px-2" }, t ? e : "•".repeat(e.length)), /* @__PURE__ */ React.createElement(
|
|
125
|
+
l,
|
|
126
|
+
{
|
|
127
|
+
variant: "outline",
|
|
128
|
+
onClick: () => n((c) => !c),
|
|
129
|
+
size: "icon"
|
|
130
|
+
},
|
|
131
|
+
t ? /* @__PURE__ */ React.createElement(D, { size: 16 }) : /* @__PURE__ */ React.createElement(q, { size: 16 })
|
|
132
|
+
), /* @__PURE__ */ React.createElement(
|
|
133
|
+
l,
|
|
134
|
+
{
|
|
135
|
+
variant: "outline",
|
|
136
|
+
onClick: () => {
|
|
137
|
+
navigator.clipboard.writeText(e).then(() => {
|
|
138
|
+
s(!0), setTimeout(() => s(!1), 2e3);
|
|
139
|
+
});
|
|
140
|
+
},
|
|
141
|
+
size: "icon"
|
|
142
|
+
},
|
|
143
|
+
a ? /* @__PURE__ */ React.createElement(O, { size: 16 }) : /* @__PURE__ */ React.createElement(z, { size: 16 })
|
|
144
|
+
));
|
|
145
|
+
}, Q = "https://zudoku-rewiringamerica-main-ef9c9c0.d2.zuplo.dev", Z = (e) => ({
|
|
146
|
+
deleteKey: async (t, n) => {
|
|
147
|
+
const a = new Request(e + `/v1/developer/api-keys/${t}`, {
|
|
212
148
|
method: "DELETE"
|
|
213
149
|
});
|
|
214
|
-
await
|
|
215
|
-
const
|
|
216
|
-
|
|
150
|
+
await n.signRequest(a);
|
|
151
|
+
const s = await fetch(a);
|
|
152
|
+
i(s.ok, "Failed to delete API key");
|
|
217
153
|
},
|
|
218
|
-
rollKey: async (
|
|
219
|
-
const
|
|
220
|
-
await
|
|
221
|
-
new Request(
|
|
154
|
+
rollKey: async (t, n) => {
|
|
155
|
+
const a = await fetch(
|
|
156
|
+
await n.signRequest(
|
|
157
|
+
new Request(e + `/v1/developer/api-keys/${t}/key`, {
|
|
222
158
|
method: "DELETE"
|
|
223
159
|
})
|
|
224
160
|
)
|
|
225
161
|
);
|
|
226
|
-
|
|
162
|
+
i(a.ok, "Failed to delete API key");
|
|
227
163
|
},
|
|
228
|
-
createKey: async (
|
|
229
|
-
const
|
|
164
|
+
createKey: async (t, n) => {
|
|
165
|
+
const a = new Request(e + "/v1/developer/api-keys", {
|
|
230
166
|
method: "POST",
|
|
231
167
|
headers: {
|
|
232
168
|
"Content-Type": "application/json"
|
|
233
169
|
},
|
|
234
|
-
body: JSON.stringify(
|
|
170
|
+
body: JSON.stringify(t)
|
|
235
171
|
});
|
|
236
|
-
await
|
|
237
|
-
const
|
|
238
|
-
|
|
172
|
+
await n.signRequest(a);
|
|
173
|
+
const s = await fetch(a);
|
|
174
|
+
i(s.ok, "Failed to create API key");
|
|
239
175
|
},
|
|
240
|
-
getKeys: async (
|
|
241
|
-
const
|
|
242
|
-
await
|
|
243
|
-
const
|
|
244
|
-
return
|
|
176
|
+
getKeys: async (t) => {
|
|
177
|
+
const n = new Request(e + "/v1/developer/api-keys");
|
|
178
|
+
await t.signRequest(n);
|
|
179
|
+
const a = await fetch(n);
|
|
180
|
+
return i(a.ok, "Failed to fetch API keys"), await a.json();
|
|
245
181
|
}
|
|
246
|
-
}),
|
|
247
|
-
const
|
|
182
|
+
}), ee = (e) => {
|
|
183
|
+
const t = "endpoint" in e ? e.endpoint : Q, n = "getKeys" in e ? e : Z(t);
|
|
248
184
|
return {
|
|
249
185
|
getProfileMenuItems: () => [
|
|
250
186
|
{
|
|
@@ -252,12 +188,12 @@ const L = ({ service: t }) => {
|
|
|
252
188
|
path: "/settings/api-keys"
|
|
253
189
|
}
|
|
254
190
|
],
|
|
255
|
-
getIdentities: async (
|
|
191
|
+
getIdentities: async (a) => {
|
|
256
192
|
try {
|
|
257
|
-
return (await
|
|
258
|
-
authorizeRequest: (r) => (r.headers.set("Authorization", `Bearer ${
|
|
259
|
-
id:
|
|
260
|
-
label:
|
|
193
|
+
return (await n.getKeys(a)).map((c) => ({
|
|
194
|
+
authorizeRequest: (r) => (r.headers.set("Authorization", `Bearer ${c.key}`), r),
|
|
195
|
+
id: c.id,
|
|
196
|
+
label: c.description ?? c.id
|
|
261
197
|
}));
|
|
262
198
|
} catch {
|
|
263
199
|
return [];
|
|
@@ -265,16 +201,16 @@ const L = ({ service: t }) => {
|
|
|
265
201
|
},
|
|
266
202
|
getRoutes: () => [
|
|
267
203
|
{
|
|
268
|
-
element: /* @__PURE__ */
|
|
269
|
-
errorElement: /* @__PURE__ */
|
|
204
|
+
element: /* @__PURE__ */ React.createElement(V, null),
|
|
205
|
+
errorElement: /* @__PURE__ */ React.createElement(f, null),
|
|
270
206
|
children: [
|
|
271
207
|
{
|
|
272
208
|
path: "/settings/api-keys",
|
|
273
|
-
element: /* @__PURE__ */
|
|
209
|
+
element: /* @__PURE__ */ React.createElement(M, { service: n })
|
|
274
210
|
},
|
|
275
211
|
{
|
|
276
212
|
path: "/settings/api-keys/new",
|
|
277
|
-
element: /* @__PURE__ */
|
|
213
|
+
element: /* @__PURE__ */ React.createElement(j, { service: n })
|
|
278
214
|
}
|
|
279
215
|
]
|
|
280
216
|
}
|
|
@@ -282,6 +218,6 @@ const L = ({ service: t }) => {
|
|
|
282
218
|
};
|
|
283
219
|
};
|
|
284
220
|
export {
|
|
285
|
-
|
|
221
|
+
ee as apiKeyPlugin
|
|
286
222
|
};
|
|
287
223
|
//# sourceMappingURL=zudoku.plugin-api-keys.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"zudoku.plugin-api-keys.js","sources":["../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":["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 { useZudoku } from \"../../components/context/ZudokuContext.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 = useZudoku();\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 {\n CheckIcon,\n CopyIcon,\n EyeIcon,\n EyeOffIcon,\n RotateCwIcon,\n TrashIcon,\n} from \"lucide-react\";\nimport { useState } from \"react\";\nimport { Link } from \"react-router-dom\";\nimport { useZudoku } from \"../../components/context/ZudokuContext.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 = useZudoku();\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 const rollKeyMutation = useMutation({\n mutationFn: (id: string) => {\n if (!service.rollKey) {\n throw new Error(\"rollKey not implemented\");\n }\n\n return service.rollKey(id, context);\n },\n onSuccess: () => queryClient.invalidateQueries({ queryKey: [\"api-keys\"] }),\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 p-8 border rounded bg-muted/30 text-muted-foreground\">\n <p className=\"text-center\">\n No API keys created yet.\n <br />\n Get started and create your first key.\n </p>\n {service.createKey && (\n <Button asChild variant=\"outline\">\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 divide-y divide-border\",\n \"lg:grid-cols-[minmax(250px,min-content)_1fr_min-content]\",\n )}\n >\n {data.map((key) => (\n <li\n className=\"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\n size=\"icon\"\n title=\"Roll this key\"\n variant=\"ghost\"\n onClick={() => {\n if (!confirm(\"Do you want to roll this key?\")) {\n return;\n }\n\n rollKeyMutation.mutate(key.id);\n }}\n >\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 const [copied, setCopied] = useState(false);\n\n return (\n <div className=\"flex gap-2 items-center text-sm\">\n <div className=\"border rounded bg-gray-100 dark:bg-gray-950 p-1 font-mono truncate h-9 items-center flex px-2\">\n {revealed ? apiKey : \"•\".repeat(apiKey.length)}\n </div>\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 <Button\n variant=\"outline\"\n onClick={() => {\n void navigator.clipboard.writeText(apiKey).then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n });\n }}\n size=\"icon\"\n >\n {copied ? <CheckIcon size={16} /> : <CopyIcon 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 rollKey: async (id, context) => {\n const response = await fetch(\n await context.signRequest(\n new Request(endpoint + `/v1/developer/api-keys/${id}/key`, {\n method: \"DELETE\",\n }),\n ),\n );\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":["invariant","condition","message","provided","ZudokuError","CreateApiKey","service","context","useZudoku","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","rollKeyMutation","Slotlet","cn","key","RevealApiKey","RotateCwIcon","TrashIcon","apiKey","revealed","setRevealed","useState","copied","setCopied","prev","EyeOffIcon","EyeIcon","CheckIcon","CopyIcon","DEFAULT_API_KEY_ENDPOINT","createDefaultHandler","endpoint","request","response","keys","apiKeyPlugin","options","RouterError"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"zudoku.plugin-api-keys.js","sources":["../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":["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 { useZudoku } from \"../../components/context/ZudokuContext.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 = useZudoku();\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 {\n CheckIcon,\n CopyIcon,\n EyeIcon,\n EyeOffIcon,\n RotateCwIcon,\n TrashIcon,\n} from \"lucide-react\";\nimport { useState } from \"react\";\nimport { Link } from \"react-router-dom\";\nimport { useZudoku } from \"../../components/context/ZudokuContext.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 = useZudoku();\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 const rollKeyMutation = useMutation({\n mutationFn: (id: string) => {\n if (!service.rollKey) {\n throw new Error(\"rollKey not implemented\");\n }\n\n return service.rollKey(id, context);\n },\n onSuccess: () => queryClient.invalidateQueries({ queryKey: [\"api-keys\"] }),\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 p-8 border rounded bg-muted/30 text-muted-foreground\">\n <p className=\"text-center\">\n No API keys created yet.\n <br />\n Get started and create your first key.\n </p>\n {service.createKey && (\n <Button asChild variant=\"outline\">\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 divide-y divide-border\",\n \"lg:grid-cols-[minmax(250px,min-content)_1fr_min-content]\",\n )}\n >\n {data.map((key) => (\n <li\n className=\"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\n size=\"icon\"\n title=\"Roll this key\"\n variant=\"ghost\"\n onClick={() => {\n if (!confirm(\"Do you want to roll this key?\")) {\n return;\n }\n\n rollKeyMutation.mutate(key.id);\n }}\n >\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 const [copied, setCopied] = useState(false);\n\n return (\n <div className=\"flex gap-2 items-center text-sm\">\n <div className=\"border rounded bg-gray-100 dark:bg-gray-950 p-1 font-mono truncate h-9 items-center flex px-2\">\n {revealed ? apiKey : \"•\".repeat(apiKey.length)}\n </div>\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 <Button\n variant=\"outline\"\n onClick={() => {\n void navigator.clipboard.writeText(apiKey).then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n });\n }}\n size=\"icon\"\n >\n {copied ? <CheckIcon size={16} /> : <CopyIcon 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 rollKey: async (id, context) => {\n const response = await fetch(\n await context.signRequest(\n new Request(endpoint + `/v1/developer/api-keys/${id}/key`, {\n method: \"DELETE\",\n }),\n ),\n );\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":["invariant","condition","message","provided","ZudokuError","CreateApiKey","service","context","useZudoku","navigate","useNavigate","form","useForm","createKeyMutation","useMutation","description","expiresOn","expiresOnDate","addDaysToDate","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","rollKeyMutation","Slotlet","cn","key","RevealApiKey","RotateCwIcon","TrashIcon","apiKey","revealed","setRevealed","useState","copied","setCopied","prev","EyeOffIcon","EyeIcon","CheckIcon","CopyIcon","DEFAULT_API_KEY_ENDPOINT","createDefaultHandler","endpoint","request","response","keys","apiKeyPlugin","options","RouterError"],"mappings":"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"}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
path: e,
|
|
1
|
+
import { P as a } from "./Markdown-CCNihH_N.js";
|
|
2
|
+
const l = (e) => ({
|
|
3
|
+
getRoutes: () => e.map(({ path: t, element: s }) => ({
|
|
4
|
+
path: t,
|
|
6
5
|
// TODO: we should componentize prose pages
|
|
7
|
-
element: /* @__PURE__ */
|
|
6
|
+
element: /* @__PURE__ */ React.createElement("div", { className: a + " max-w-full" }, s)
|
|
8
7
|
}))
|
|
9
8
|
});
|
|
10
9
|
export {
|
|
@@ -1 +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","
|
|
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","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,SAAU,sBAAA,cAAA,OAAA,EAAI,WAAWE,IAAe,iBAAgBD,CAAQ;AAAA,EAAA,EAChE;AAAA;"}
|