@raketa-cloud/admin 0.0.3 → 0.0.5
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/babel.config.js +6 -0
- package/bin/tailwind +2 -0
- package/package.json +22 -30
- package/src/Adapter.js +160 -0
- package/src/HonoAdapter.js +248 -0
- package/src/RaketaContext.js +46 -0
- package/src/helpers/AuthHelper.js +44 -0
- package/src/helpers/FormBuilder.js +226 -0
- package/src/helpers/HTMLBuilder.js +38 -0
- package/src/helpers/Pagination.js +92 -0
- package/src/helpers/SortButton.js +102 -0
- package/src/helpers/form_for.js +6 -0
- package/src/helpers/pagination_helper.js +5 -0
- package/src/helpers/sort_button.js +5 -0
- package/src/index.js +7 -0
- package/src/routeCollection.js +90 -0
- package/src/routeMember.js +40 -0
- package/src/routeNestedCollection.js +90 -0
- package/src/routeNestedMember.js +40 -0
- package/src/setGlobalConfig.js +5 -0
- package/src/setGlobalContext.js +5 -0
- package/src/setupAuthentication.js +99 -0
- package/src/styles/application.css +479 -0
- package/src/tests/Adapter.test.js +39 -0
- package/src/tests/HonoAdapter.test.js +34 -0
- package/src/tests/helpers/Pagination.test.js +65 -0
- package/src/tests/helpers/SortButton.test.js +85 -0
- package/src/tests/routeCollection.test.js +150 -0
- package/src/tests/routeMember.test.js +91 -0
- package/src/tests/routeNestedCollection.test.js +176 -0
- package/src/tests/routeNestedMember.test.js +96 -0
- package/src/views/_auth/login.ejs +92 -0
- package/src/views/layouts/application.ejs +147 -0
- package/src/views/layouts/header.ejs +49 -0
- package/src/views/redirects/index.ejs +1 -0
- package/tailwind.config.js +39 -0
- package/tsconfig.json +15 -0
- package/tsconfig.lint.json +8 -0
- package/dist/index.js +0 -670
package/dist/index.js
DELETED
|
@@ -1,670 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
7
|
-
var __export = (target, all) => {
|
|
8
|
-
for (var name in all)
|
|
9
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
-
};
|
|
11
|
-
var __copyProps = (to, from, except, desc) => {
|
|
12
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
-
for (let key of __getOwnPropNames(from))
|
|
14
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
-
}
|
|
17
|
-
return to;
|
|
18
|
-
};
|
|
19
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
-
var __publicField = (obj, key, value) => {
|
|
21
|
-
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
|
|
22
|
-
return value;
|
|
23
|
-
};
|
|
24
|
-
|
|
25
|
-
// src/index.ts
|
|
26
|
-
var src_exports = {};
|
|
27
|
-
__export(src_exports, {
|
|
28
|
-
adminApp: () => app_default
|
|
29
|
-
});
|
|
30
|
-
module.exports = __toCommonJS(src_exports);
|
|
31
|
-
|
|
32
|
-
// src/app.tsx
|
|
33
|
-
var import_hono4 = require("hono");
|
|
34
|
-
|
|
35
|
-
// src/middleware/logger.ts
|
|
36
|
-
var import_crypto = require("crypto");
|
|
37
|
-
|
|
38
|
-
// src/lib/logger.tsx
|
|
39
|
-
var _Fancy = class {
|
|
40
|
-
static formatDate(date) {
|
|
41
|
-
return date.toISOString().replace("T", " ").split(".")[0];
|
|
42
|
-
}
|
|
43
|
-
static formatSeverity(severity) {
|
|
44
|
-
return _Fancy.SEVERITY[severity];
|
|
45
|
-
}
|
|
46
|
-
static formatStatus(status) {
|
|
47
|
-
const out = {
|
|
48
|
-
5: `\x1B[31m${status}\x1B[0m`,
|
|
49
|
-
4: `\x1B[31m${status}\x1B[0m`,
|
|
50
|
-
3: `\x1B[33m${status}\x1B[0m`,
|
|
51
|
-
2: `\x1B[32m${status}\x1B[0m`,
|
|
52
|
-
1: `\x1B[32m${status}\x1B[0m`,
|
|
53
|
-
0: `${status}`
|
|
54
|
-
};
|
|
55
|
-
const calculateStatus = status / 100 | 0;
|
|
56
|
-
return out[calculateStatus];
|
|
57
|
-
}
|
|
58
|
-
static formatMessage(message) {
|
|
59
|
-
if (message.startsWith("-> ")) {
|
|
60
|
-
const { verb, path } = message.match(
|
|
61
|
-
/(?<verb>GET|POST|DELETE|PUT|PATCH|OPTIONS)\s(?<path>.*)$/i
|
|
62
|
-
).groups;
|
|
63
|
-
return `-> ${verb} \x1B[36m${path}\x1B[0m`;
|
|
64
|
-
}
|
|
65
|
-
if (message.startsWith("<- ")) {
|
|
66
|
-
const { status } = message.match(/<-\s(?<status>\d{3})\s/i).groups;
|
|
67
|
-
return `${message.replace(
|
|
68
|
-
status,
|
|
69
|
-
_Fancy.formatStatus(parseInt(status))
|
|
70
|
-
)}
|
|
71
|
-
`;
|
|
72
|
-
}
|
|
73
|
-
return message;
|
|
74
|
-
}
|
|
75
|
-
static format({ date, identifier, severity, message }) {
|
|
76
|
-
return [
|
|
77
|
-
`[${_Fancy.formatDate(date)}]`,
|
|
78
|
-
`(${identifier})`,
|
|
79
|
-
`${_Fancy.formatSeverity(severity)}:`,
|
|
80
|
-
_Fancy.formatMessage(message)
|
|
81
|
-
].join(" ");
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
var Fancy = _Fancy;
|
|
85
|
-
__publicField(Fancy, "SEVERITY", {
|
|
86
|
-
[1 /* Info */]: "I",
|
|
87
|
-
[2 /* Warn */]: "W",
|
|
88
|
-
[3 /* Error */]: "E",
|
|
89
|
-
[4 /* Debug */]: "D"
|
|
90
|
-
});
|
|
91
|
-
var Logger = class {
|
|
92
|
-
requestID;
|
|
93
|
-
formatter;
|
|
94
|
-
constructor(requestID, formatter = Fancy) {
|
|
95
|
-
this.requestID = requestID;
|
|
96
|
-
this.formatter = formatter;
|
|
97
|
-
}
|
|
98
|
-
log(severity, message, meta) {
|
|
99
|
-
const date = new Date();
|
|
100
|
-
console.log(
|
|
101
|
-
this.formatter.format({
|
|
102
|
-
date,
|
|
103
|
-
identifier: this.requestID,
|
|
104
|
-
severity,
|
|
105
|
-
message,
|
|
106
|
-
meta
|
|
107
|
-
})
|
|
108
|
-
);
|
|
109
|
-
}
|
|
110
|
-
info(message, meta) {
|
|
111
|
-
this.log(1 /* Info */, message, meta);
|
|
112
|
-
}
|
|
113
|
-
warn(message, meta) {
|
|
114
|
-
this.log(2 /* Warn */, message, meta);
|
|
115
|
-
}
|
|
116
|
-
error(message, meta) {
|
|
117
|
-
this.log(3 /* Error */, message, meta);
|
|
118
|
-
}
|
|
119
|
-
debug(message, meta) {
|
|
120
|
-
this.log(4 /* Debug */, message, meta);
|
|
121
|
-
}
|
|
122
|
-
};
|
|
123
|
-
|
|
124
|
-
// src/middleware/logger.ts
|
|
125
|
-
var logger_default = async (c, next) => {
|
|
126
|
-
c.set("logger", new Logger((0, import_crypto.randomBytes)(8).toString("hex")));
|
|
127
|
-
await next();
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
// src/middleware/http_logger.ts
|
|
131
|
-
var humanize = (times) => {
|
|
132
|
-
const [delimiter, separator] = [",", "."];
|
|
133
|
-
const orderTimes = times.map(
|
|
134
|
-
(v) => v.replace(/(\d)(?=(\d\d\d)+(?!\d))/g, `$1${delimiter}`)
|
|
135
|
-
);
|
|
136
|
-
return orderTimes.join(separator);
|
|
137
|
-
};
|
|
138
|
-
var time = (start) => {
|
|
139
|
-
const delta = Date.now() - start;
|
|
140
|
-
return humanize([
|
|
141
|
-
delta < 1e3 ? `${delta}ms` : `${Math.round(delta / 1e3)}s`
|
|
142
|
-
]);
|
|
143
|
-
};
|
|
144
|
-
var http_logger_default = async (c, next) => {
|
|
145
|
-
const logger = c.get("logger");
|
|
146
|
-
const { method } = c.req;
|
|
147
|
-
const start = Date.now();
|
|
148
|
-
const url = new URL(c.req.url);
|
|
149
|
-
const path = url.href.replace(url.origin, "");
|
|
150
|
-
logger.info(`-> ${method} ${path}`, {
|
|
151
|
-
method,
|
|
152
|
-
path
|
|
153
|
-
});
|
|
154
|
-
await next();
|
|
155
|
-
const elapsed = time(start);
|
|
156
|
-
logger.info(`<- ${c.res.status} in ${elapsed}`, {
|
|
157
|
-
method,
|
|
158
|
-
elapsed
|
|
159
|
-
});
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
// src/middleware/authentication.ts
|
|
163
|
-
var import_cookie = require("hono/cookie");
|
|
164
|
-
var import_jwt = require("hono/jwt");
|
|
165
|
-
var import_adapter = require("hono/adapter");
|
|
166
|
-
var EXCLUDED_PATHS = ["/login", "/logout", "/serviceworker.js"];
|
|
167
|
-
function shouldAuthenticate(c) {
|
|
168
|
-
return !EXCLUDED_PATHS.includes(c.req.path);
|
|
169
|
-
}
|
|
170
|
-
function redirect(location) {
|
|
171
|
-
return new Response("Not Authorized", {
|
|
172
|
-
status: 301,
|
|
173
|
-
headers: {
|
|
174
|
-
Location: location,
|
|
175
|
-
"Set-Cookie": "authToken=; Max-Age=0"
|
|
176
|
-
}
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
async function authenticate(c, next) {
|
|
180
|
-
const token = (0, import_cookie.getCookie)(c, "authToken");
|
|
181
|
-
if (!token) {
|
|
182
|
-
return redirect("/login");
|
|
183
|
-
}
|
|
184
|
-
const parsedToken = (0, import_jwt.decode)(token);
|
|
185
|
-
const payload = parsedToken.payload;
|
|
186
|
-
if (payload.exp < (new Date().getTime() + 1) / 1e3) {
|
|
187
|
-
return redirect("/login");
|
|
188
|
-
}
|
|
189
|
-
if (!payload.info.active) {
|
|
190
|
-
return redirect("/login?reason=inactive");
|
|
191
|
-
}
|
|
192
|
-
const {
|
|
193
|
-
RAKETA_GATEWAY_PRIMARY_USER_POOL,
|
|
194
|
-
RAKETA_GATEWAY_SECONDARY_USER_POOL
|
|
195
|
-
} = (0, import_adapter.env)(c);
|
|
196
|
-
if (![RAKETA_GATEWAY_PRIMARY_USER_POOL, RAKETA_GATEWAY_SECONDARY_USER_POOL].filter(Boolean).includes(payload.info.user_pool_id)) {
|
|
197
|
-
return redirect("/login");
|
|
198
|
-
}
|
|
199
|
-
await next();
|
|
200
|
-
}
|
|
201
|
-
var authentication_default = async (c, next) => {
|
|
202
|
-
if (shouldAuthenticate(c)) {
|
|
203
|
-
return authenticate(c, next);
|
|
204
|
-
}
|
|
205
|
-
await next();
|
|
206
|
-
};
|
|
207
|
-
|
|
208
|
-
// src/crud/tags.tsx
|
|
209
|
-
var import_hono = require("hono");
|
|
210
|
-
|
|
211
|
-
// src/lib/dxp/protocol.ts
|
|
212
|
-
var import_cookie2 = require("hono/cookie");
|
|
213
|
-
var import_adapter2 = require("hono/adapter");
|
|
214
|
-
|
|
215
|
-
// src/lib/gqlEngine.ts
|
|
216
|
-
var import_graphql_request = require("graphql-request");
|
|
217
|
-
function gqlRequest(url, query, variables = {}, headers = {}) {
|
|
218
|
-
return (0, import_graphql_request.request)({
|
|
219
|
-
url,
|
|
220
|
-
document: query,
|
|
221
|
-
variables,
|
|
222
|
-
requestHeaders: headers
|
|
223
|
-
});
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
// src/lib/dxp/protocol.ts
|
|
227
|
-
function dxpPrivateRequest(query, variables, honoCtx) {
|
|
228
|
-
const token = (0, import_cookie2.getCookie)(honoCtx, "authToken");
|
|
229
|
-
const {
|
|
230
|
-
RAKETA_GATEWAY_DISPATCH_URL,
|
|
231
|
-
RAKETA_GATEWAY_PROJECT,
|
|
232
|
-
RAKETA_DXP_PRIVATE_SERVICE
|
|
233
|
-
} = (0, import_adapter2.env)(honoCtx);
|
|
234
|
-
return gqlRequest(RAKETA_GATEWAY_DISPATCH_URL, query, variables, {
|
|
235
|
-
"x-raketa-project": RAKETA_GATEWAY_PROJECT,
|
|
236
|
-
"x-raketa-service": RAKETA_DXP_PRIVATE_SERVICE,
|
|
237
|
-
"x-raketa-identity": token
|
|
238
|
-
});
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
// src/lib/dxp/private/tags.ts
|
|
242
|
-
var TagsDocument = import_graphql_request.gql`
|
|
243
|
-
query Tags($input: TagsInput!) {
|
|
244
|
-
tags(input: $input) {
|
|
245
|
-
list {
|
|
246
|
-
id
|
|
247
|
-
name
|
|
248
|
-
slug
|
|
249
|
-
}
|
|
250
|
-
pagination {
|
|
251
|
-
currentPage
|
|
252
|
-
pagesCount
|
|
253
|
-
entriesCount
|
|
254
|
-
pageSize
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
`;
|
|
259
|
-
var CreateTagDocument = import_graphql_request.gql`
|
|
260
|
-
mutation CreateTag($input: CreateTagInput!) {
|
|
261
|
-
createTag(input: $input) {
|
|
262
|
-
tag {
|
|
263
|
-
id
|
|
264
|
-
slug
|
|
265
|
-
name
|
|
266
|
-
}
|
|
267
|
-
errors {
|
|
268
|
-
key
|
|
269
|
-
message
|
|
270
|
-
codes {
|
|
271
|
-
key
|
|
272
|
-
placeholders
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
`;
|
|
278
|
-
var UpdateTagDocument = import_graphql_request.gql`
|
|
279
|
-
mutation UpdateTag($input: UpdateTagInput!) {
|
|
280
|
-
updateTag(input: $input) {
|
|
281
|
-
tag {
|
|
282
|
-
id
|
|
283
|
-
slug
|
|
284
|
-
name
|
|
285
|
-
}
|
|
286
|
-
errors {
|
|
287
|
-
key
|
|
288
|
-
message
|
|
289
|
-
codes {
|
|
290
|
-
key
|
|
291
|
-
placeholders
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
`;
|
|
297
|
-
var DeleteTagDocument = import_graphql_request.gql`
|
|
298
|
-
mutation DeleteTag($input: IdInput!) {
|
|
299
|
-
deleteTag(input: $input) {
|
|
300
|
-
tag {
|
|
301
|
-
id
|
|
302
|
-
slug
|
|
303
|
-
name
|
|
304
|
-
}
|
|
305
|
-
errors {
|
|
306
|
-
key
|
|
307
|
-
message
|
|
308
|
-
codes {
|
|
309
|
-
key
|
|
310
|
-
placeholders
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
`;
|
|
316
|
-
var TagByIdDocument = import_graphql_request.gql`
|
|
317
|
-
query TagByID($input: IdInput!) {
|
|
318
|
-
tag(input: $input) {
|
|
319
|
-
id
|
|
320
|
-
slug
|
|
321
|
-
name
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
`;
|
|
325
|
-
var tags = {
|
|
326
|
-
list: async (variables, honoCtx) => dxpPrivateRequest(TagsDocument, variables, honoCtx),
|
|
327
|
-
find: async (id, locale, honoCtx) => dxpPrivateRequest(TagByIdDocument, { input: { id, locale } }, honoCtx),
|
|
328
|
-
create: async (variables, honoCtx) => dxpPrivateRequest(CreateTagDocument, variables, honoCtx),
|
|
329
|
-
update: async (variables, honoCtx) => dxpPrivateRequest(UpdateTagDocument, variables, honoCtx),
|
|
330
|
-
delete: async (id, locale, honoCtx) => dxpPrivateRequest(DeleteTagDocument, { input: { id, locale } }, honoCtx)
|
|
331
|
-
};
|
|
332
|
-
var tags_default = tags;
|
|
333
|
-
|
|
334
|
-
// src/shared/Layout.tsx
|
|
335
|
-
var import_cookie3 = require("hono/cookie");
|
|
336
|
-
var import_jwt2 = require("hono/jwt");
|
|
337
|
-
var import_jsx_runtime = require("hono/jsx/jsx-runtime");
|
|
338
|
-
function fetchUser(c) {
|
|
339
|
-
const token = (0, import_cookie3.getCookie)(c, "authToken");
|
|
340
|
-
if (!token) {
|
|
341
|
-
return null;
|
|
342
|
-
}
|
|
343
|
-
return (0, import_jwt2.decode)(token).payload.info || null;
|
|
344
|
-
}
|
|
345
|
-
var Layout = ({ context, children }) => {
|
|
346
|
-
const user = fetchUser(context);
|
|
347
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("html", { lang: "en", children: [
|
|
348
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("head", { children: [
|
|
349
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("meta", { charset: "UTF-8" }),
|
|
350
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("meta", { name: "viewport", content: "width=device-width, initial-scale=1.0" }),
|
|
351
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("script", { src: "https://cdn.tailwindcss.com" }),
|
|
352
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("script", { src: "https://unpkg.com/htmx.org@1.9.6" }),
|
|
353
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("title", { children: "Administration" })
|
|
354
|
-
] }),
|
|
355
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("body", { children: [
|
|
356
|
-
user && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { class: "flex items-center justify-end gap-4 w-full h-[50px] p-4", children: [
|
|
357
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
358
|
-
"img",
|
|
359
|
-
{
|
|
360
|
-
src: user.avatar,
|
|
361
|
-
class: "rounded-full h-[40px] w-[40px]",
|
|
362
|
-
alt: "Admin avatar"
|
|
363
|
-
}
|
|
364
|
-
),
|
|
365
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("button", { type: "button", "hx-delete": "/logout", children: "Logout" })
|
|
366
|
-
] }),
|
|
367
|
-
children
|
|
368
|
-
] })
|
|
369
|
-
] });
|
|
370
|
-
};
|
|
371
|
-
var Layout_default = Layout;
|
|
372
|
-
|
|
373
|
-
// src/crud/tags.tsx
|
|
374
|
-
var import_jsx_runtime2 = require("hono/jsx/jsx-runtime");
|
|
375
|
-
var TagsList = ({ data }) => {
|
|
376
|
-
const list = data?.tags?.list || [];
|
|
377
|
-
const results = list.map((tag) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("tr", { class: "bg-transparent hover:bg-yellow-50 transition", children: [
|
|
378
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("td", { class: "p-4 border-b", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
379
|
-
"a",
|
|
380
|
-
{
|
|
381
|
-
href: `/tags/${tag.id}/edit`,
|
|
382
|
-
class: "underline font-semibold hover:no-underline",
|
|
383
|
-
children: tag.name
|
|
384
|
-
}
|
|
385
|
-
) }),
|
|
386
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("td", { class: "p-4 border-b", children: tag.slug })
|
|
387
|
-
] }));
|
|
388
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
389
|
-
results.length > 0 && results,
|
|
390
|
-
results.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("tr", { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("td", { colspan: 2, class: "p-4", children: "Not found." }) })
|
|
391
|
-
] });
|
|
392
|
-
};
|
|
393
|
-
var Tags = ({ data }) => {
|
|
394
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "container mx-auto py-16", children: [
|
|
395
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h1", { class: "mb-8 text-2xl font-bold", children: "Tags" }),
|
|
396
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("a", { href: "/tags/new", children: "New" }),
|
|
397
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("table", { class: "w-full", children: [
|
|
398
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("tr", { children: [
|
|
399
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("th", { class: "p-4 border-b text-left", children: "Name" }),
|
|
400
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("th", { class: "p-4 border-b text-left", children: "URL" })
|
|
401
|
-
] }) }),
|
|
402
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(TagsList, { data })
|
|
403
|
-
] })
|
|
404
|
-
] });
|
|
405
|
-
};
|
|
406
|
-
var Form = ({ action, tag, errors = {} }) => {
|
|
407
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("form", { method: "POST", action, children: [
|
|
408
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "flex gap-2", children: [
|
|
409
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { children: "Name" }),
|
|
410
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("input", { type: "text", value: tag.name, name: "name", class: "border" }),
|
|
411
|
-
errors.name && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: errors.name })
|
|
412
|
-
] }),
|
|
413
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "flex gap-2", children: [
|
|
414
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("label", { children: "URL" }),
|
|
415
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("input", { type: "text", value: tag.slug, name: "slug", class: "border" }),
|
|
416
|
-
errors.slug && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: errors.slug })
|
|
417
|
-
] }),
|
|
418
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "flex gap-4", children: [
|
|
419
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "submit", children: "Save" }),
|
|
420
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("a", { href: "/tags", children: "Back" }),
|
|
421
|
-
tag.id && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
422
|
-
"button",
|
|
423
|
-
{
|
|
424
|
-
type: "button",
|
|
425
|
-
"hx-delete": `/tags/${tag.id}`,
|
|
426
|
-
"hx-confirm": "Are you sure you wish to delete this tag?",
|
|
427
|
-
children: "DELETE"
|
|
428
|
-
}
|
|
429
|
-
)
|
|
430
|
-
] })
|
|
431
|
-
] });
|
|
432
|
-
};
|
|
433
|
-
var EditForm = ({ tag, errors = {} }) => {
|
|
434
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "container mx-auto py-16", children: [
|
|
435
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h1", { class: "mb-8 text-2xl font-bold", children: "Tags" }),
|
|
436
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Form, { action: `/tags/${tag.id}`, tag, errors })
|
|
437
|
-
] });
|
|
438
|
-
};
|
|
439
|
-
var NewForm = ({ tag = {}, errors = {} }) => {
|
|
440
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { class: "container mx-auto py-16", children: [
|
|
441
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h1", { class: "mb-8 text-2xl font-bold", children: "Tags" }),
|
|
442
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Form, { action: "/tags", tag, errors })
|
|
443
|
-
] });
|
|
444
|
-
};
|
|
445
|
-
var app = new import_hono.Hono();
|
|
446
|
-
app.get("/tags", async (c) => {
|
|
447
|
-
const data = await tags_default.list({ input: { locale: "en" } }, c);
|
|
448
|
-
return c.html(
|
|
449
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Layout_default, { context: c, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Tags, { data }) })
|
|
450
|
-
);
|
|
451
|
-
});
|
|
452
|
-
app.get("/tags/new", (c) => c.html(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(NewForm, {})));
|
|
453
|
-
app.get("/tags/:id/edit", async (c) => {
|
|
454
|
-
const { tag } = await tags_default.find(parseInt(c.req.param().id, 10), "en", c);
|
|
455
|
-
return c.html(
|
|
456
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Layout_default, { context: c, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(EditForm, { tag }) })
|
|
457
|
-
);
|
|
458
|
-
});
|
|
459
|
-
app.delete("/tags/:id", async (c) => {
|
|
460
|
-
const { tag } = await tags_default.find(parseInt(c.req.param().id, 10), "en", c);
|
|
461
|
-
const resp = await tags_default.delete(tag.id, "en", c);
|
|
462
|
-
const deleteTag = resp.deleteTag;
|
|
463
|
-
if (deleteTag.errors) {
|
|
464
|
-
throw `ERROR: ${deleteTag.errors}`;
|
|
465
|
-
}
|
|
466
|
-
c.header("HX-Redirect", "/tags");
|
|
467
|
-
c.status(201);
|
|
468
|
-
return c.json(deleteTag.tag);
|
|
469
|
-
});
|
|
470
|
-
app.post("/tags/:id", async (c) => {
|
|
471
|
-
const body = await c.req.parseBody();
|
|
472
|
-
const { tag } = await tags_default.find(parseInt(c.req.param().id, 10), "en", c);
|
|
473
|
-
const resp = await tags_default.update(
|
|
474
|
-
{
|
|
475
|
-
input: {
|
|
476
|
-
locale: "en",
|
|
477
|
-
id: tag.id,
|
|
478
|
-
tag: {
|
|
479
|
-
name: body.name,
|
|
480
|
-
slug: body.slug
|
|
481
|
-
}
|
|
482
|
-
}
|
|
483
|
-
},
|
|
484
|
-
c
|
|
485
|
-
);
|
|
486
|
-
if (resp.updateTag.errors) {
|
|
487
|
-
const errors = {};
|
|
488
|
-
resp.updateTag.errors.forEach((error) => {
|
|
489
|
-
const key = error.key;
|
|
490
|
-
errors[key] = [errors[key] || "", error.message].filter(Boolean).join("; ");
|
|
491
|
-
});
|
|
492
|
-
return c.html(
|
|
493
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Layout_default, { context: c, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
494
|
-
EditForm,
|
|
495
|
-
{
|
|
496
|
-
tag: {
|
|
497
|
-
id: tag.id,
|
|
498
|
-
name: body.name,
|
|
499
|
-
slug: body.slug
|
|
500
|
-
},
|
|
501
|
-
errors
|
|
502
|
-
}
|
|
503
|
-
) })
|
|
504
|
-
);
|
|
505
|
-
}
|
|
506
|
-
return c.redirect("/tags", 301);
|
|
507
|
-
});
|
|
508
|
-
app.post("/tags", async (c) => {
|
|
509
|
-
const body = await c.req.parseBody();
|
|
510
|
-
const tag = {
|
|
511
|
-
name: body.name,
|
|
512
|
-
slug: body.slug
|
|
513
|
-
};
|
|
514
|
-
const resp = await tags_default.create(
|
|
515
|
-
{
|
|
516
|
-
input: {
|
|
517
|
-
locale: "en",
|
|
518
|
-
tag
|
|
519
|
-
}
|
|
520
|
-
},
|
|
521
|
-
c
|
|
522
|
-
);
|
|
523
|
-
if (resp.createTag.errors) {
|
|
524
|
-
const errors = {};
|
|
525
|
-
resp.createTag.errors.forEach((error) => {
|
|
526
|
-
const key = error.key;
|
|
527
|
-
errors[key] = [errors[key] || "", error.message].filter(Boolean).join("; ");
|
|
528
|
-
});
|
|
529
|
-
return c.html(
|
|
530
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Layout_default, { context: c, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(NewForm, { tag, errors }) })
|
|
531
|
-
);
|
|
532
|
-
}
|
|
533
|
-
return c.redirect("/tags", 301);
|
|
534
|
-
});
|
|
535
|
-
var tags_default2 = app;
|
|
536
|
-
|
|
537
|
-
// src/crud/login.tsx
|
|
538
|
-
var import_hono2 = require("hono");
|
|
539
|
-
|
|
540
|
-
// src/lib/gateway/login.ts
|
|
541
|
-
var import_adapter4 = require("hono/adapter");
|
|
542
|
-
|
|
543
|
-
// src/lib/gateway/protocol.ts
|
|
544
|
-
var import_adapter3 = require("hono/adapter");
|
|
545
|
-
function gatewayRequest(query, variables, honoCtx) {
|
|
546
|
-
const { RAKETA_GATEWAY_AUTH_URL } = (0, import_adapter3.env)(honoCtx);
|
|
547
|
-
return gqlRequest(RAKETA_GATEWAY_AUTH_URL, query, variables);
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
// src/lib/gateway/login.ts
|
|
551
|
-
var LoginDocument = import_graphql_request.gql`
|
|
552
|
-
mutation Login($input: LoginInput!) {
|
|
553
|
-
login(input: $input) {
|
|
554
|
-
accessToken
|
|
555
|
-
errors {
|
|
556
|
-
key
|
|
557
|
-
message
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
`;
|
|
562
|
-
var login = {
|
|
563
|
-
create: async (email, password, honoCtx) => {
|
|
564
|
-
const {
|
|
565
|
-
RAKETA_GATEWAY_PRIMARY_USER_POOL,
|
|
566
|
-
RAKETA_GATEWAY_SECONDARY_USER_POOL,
|
|
567
|
-
RAKETA_GATEWAY_PROJECT
|
|
568
|
-
} = (0, import_adapter4.env)(honoCtx);
|
|
569
|
-
return gatewayRequest(
|
|
570
|
-
LoginDocument,
|
|
571
|
-
{
|
|
572
|
-
input: {
|
|
573
|
-
email,
|
|
574
|
-
password,
|
|
575
|
-
userPools: [
|
|
576
|
-
RAKETA_GATEWAY_PRIMARY_USER_POOL,
|
|
577
|
-
RAKETA_GATEWAY_SECONDARY_USER_POOL
|
|
578
|
-
].filter(Boolean),
|
|
579
|
-
project: RAKETA_GATEWAY_PROJECT
|
|
580
|
-
}
|
|
581
|
-
},
|
|
582
|
-
honoCtx
|
|
583
|
-
);
|
|
584
|
-
}
|
|
585
|
-
};
|
|
586
|
-
var login_default = login;
|
|
587
|
-
|
|
588
|
-
// src/crud/login.tsx
|
|
589
|
-
var import_cookie4 = require("hono/cookie");
|
|
590
|
-
var import_jwt3 = require("hono/jwt");
|
|
591
|
-
var import_jsx_runtime3 = require("hono/jsx/jsx-runtime");
|
|
592
|
-
var app2 = new import_hono2.Hono();
|
|
593
|
-
var LoginForm = ({ login: login2 = {}, errors = {} }) => {
|
|
594
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { class: "container mx-auto py-16", children: [
|
|
595
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("h1", { class: "mb-8 text-2xl font-bold", children: "Login" }),
|
|
596
|
-
errors.general && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: errors.general }) }),
|
|
597
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("form", { method: "POST", action: "/login", children: [
|
|
598
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { class: "flex gap-2", children: [
|
|
599
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("label", { children: "Email" }),
|
|
600
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("input", { type: "email", value: login2.email, name: "email", class: "border" }),
|
|
601
|
-
errors.email && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: errors.email })
|
|
602
|
-
] }),
|
|
603
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { class: "flex gap-2", children: [
|
|
604
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("label", { children: "Password" }),
|
|
605
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("input", { type: "password", value: "", name: "password", class: "border" })
|
|
606
|
-
] }),
|
|
607
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { class: "flex gap-4", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("button", { type: "submit", children: "Login" }) })
|
|
608
|
-
] })
|
|
609
|
-
] });
|
|
610
|
-
};
|
|
611
|
-
app2.get("/login", async (c) => {
|
|
612
|
-
const errors = {};
|
|
613
|
-
if (c.req.query().reason === "inactive") {
|
|
614
|
-
errors.general = "Your user is not activated. Please contact your administrator for more information";
|
|
615
|
-
}
|
|
616
|
-
return c.html(
|
|
617
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Layout_default, { context: c, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(LoginForm, { errors }) })
|
|
618
|
-
);
|
|
619
|
-
});
|
|
620
|
-
app2.post("/login", async (c) => {
|
|
621
|
-
const body = await c.req.parseBody();
|
|
622
|
-
const email = body.email;
|
|
623
|
-
const password = body.password;
|
|
624
|
-
const resp = await login_default.create(email, password, c);
|
|
625
|
-
if (resp.login.errors) {
|
|
626
|
-
const errors = {};
|
|
627
|
-
resp.login.errors.forEach((error) => {
|
|
628
|
-
const key = error.key;
|
|
629
|
-
errors[key] = [errors[key] || "", error.message].filter(Boolean).join("; ");
|
|
630
|
-
});
|
|
631
|
-
(0, import_cookie4.deleteCookie)(c, "authToken");
|
|
632
|
-
return c.html(
|
|
633
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Layout_default, { context: c, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(LoginForm, { login: { email }, errors }) })
|
|
634
|
-
);
|
|
635
|
-
}
|
|
636
|
-
const token = resp.login.accessToken;
|
|
637
|
-
const expiration = (0, import_jwt3.decode)(token).payload.exp || (new Date().getTime() / 1e3).toFixed(0);
|
|
638
|
-
const opts = {
|
|
639
|
-
expires: new Date(expiration * 1e3)
|
|
640
|
-
};
|
|
641
|
-
(0, import_cookie4.setCookie)(c, "authToken", token, opts);
|
|
642
|
-
return c.redirect("/tags", 301);
|
|
643
|
-
});
|
|
644
|
-
var login_default2 = app2;
|
|
645
|
-
|
|
646
|
-
// src/crud/logout.tsx
|
|
647
|
-
var import_hono3 = require("hono");
|
|
648
|
-
var import_cookie5 = require("hono/cookie");
|
|
649
|
-
var app3 = new import_hono3.Hono();
|
|
650
|
-
app3.delete("/logout", async (c) => {
|
|
651
|
-
(0, import_cookie5.deleteCookie)(c, "authToken");
|
|
652
|
-
c.header("HX-Redirect", "/login");
|
|
653
|
-
c.status(201);
|
|
654
|
-
return c.json({ message: "Bye" });
|
|
655
|
-
});
|
|
656
|
-
var logout_default = app3;
|
|
657
|
-
|
|
658
|
-
// src/app.tsx
|
|
659
|
-
var app4 = new import_hono4.Hono();
|
|
660
|
-
app4.use("*", logger_default);
|
|
661
|
-
app4.use("*", http_logger_default);
|
|
662
|
-
app4.use("*", authentication_default);
|
|
663
|
-
app4.route("/", tags_default2);
|
|
664
|
-
app4.route("/", login_default2);
|
|
665
|
-
app4.route("/", logout_default);
|
|
666
|
-
var app_default = app4;
|
|
667
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
668
|
-
0 && (module.exports = {
|
|
669
|
-
adminApp
|
|
670
|
-
});
|