@raketa-cloud/admin 0.0.1 → 0.0.3

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/jest.config.js DELETED
@@ -1,15 +0,0 @@
1
- const { pathsToModuleNameMapper } = require("ts-jest");
2
- const { compilerOptions } = require("./tsconfig.json");
3
-
4
- module.exports = {
5
- clearMocks: true,
6
- preset: "ts-jest",
7
- testEnvironment: "node",
8
- globalSetup: "./tests/support/setup.js",
9
- transform: {
10
- "^.+\\.ts?$": "ts-jest",
11
- },
12
- roots: ["."],
13
- modulePaths: [compilerOptions.baseUrl],
14
- moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths),
15
- };
package/src/app.tsx DELETED
@@ -1,19 +0,0 @@
1
- import { Hono } from "hono";
2
- import logger from "src/middleware/logger";
3
- import httpLogger from "src/middleware/http_logger";
4
- import auth from "src/middleware/authentication";
5
-
6
- import tagsApp from "src/crud/tags";
7
- import loginApp from "src/crud/login";
8
- import logoutApp from "src/crud/logout";
9
-
10
- const app = new Hono();
11
- app.use("*", logger);
12
- app.use("*", httpLogger);
13
- app.use("*", auth);
14
-
15
- app.route("/", tagsApp);
16
- app.route("/", loginApp);
17
- app.route("/", logoutApp);
18
-
19
- export default app;
@@ -1,99 +0,0 @@
1
- import { Hono } from "hono";
2
- import type { FC } from "hono/jsx";
3
- import Layout from "src/shared/Layout";
4
- import login from "src/lib/gateway/login";
5
- import { setCookie, deleteCookie } from "hono/cookie";
6
- import { decode } from "hono/jwt";
7
- import { CookieOptions } from "hono/utils/cookie";
8
-
9
- const app = new Hono();
10
-
11
- // Login part
12
- const LoginForm: FC = ({ login = {}, errors = {} }) => {
13
- return (
14
- <div class="container mx-auto py-16">
15
- <h1 class="mb-8 text-2xl font-bold">Login</h1>
16
-
17
- {errors.general && (
18
- <p>
19
- <span>{errors.general}</span>
20
- </p>
21
- )}
22
-
23
- <form method="POST" action="/login">
24
- <div class="flex gap-2">
25
- <label>Email</label>
26
- <input type="email" value={login.email} name="email" class="border" />
27
- {errors.email && <span>{errors.email}</span>}
28
- </div>
29
-
30
- <div class="flex gap-2">
31
- <label>Password</label>
32
- <input type="password" value="" name="password" class="border" />
33
- </div>
34
-
35
- <div class="flex gap-4">
36
- <button type="submit">Login</button>
37
- </div>
38
- </form>
39
- </div>
40
- );
41
- };
42
-
43
- app.get("/login", async (c) => {
44
- const errors = {};
45
-
46
- if (c.req.query().reason === "inactive") {
47
- (errors as any).general =
48
- "Your user is not activated. Please contact your administrator for more information";
49
- }
50
-
51
- return c.html(
52
- <Layout context={c}>
53
- <LoginForm errors={errors} />
54
- </Layout>,
55
- );
56
- });
57
-
58
- app.post("/login", async (c) => {
59
- const body = await c.req.parseBody();
60
-
61
- const email = body.email as string;
62
- const password = body.password as string;
63
-
64
- const resp = await login.create(email, password, c);
65
-
66
- if ((resp as any).login.errors) {
67
- const errors = {};
68
-
69
- (resp as any).login.errors.forEach((error: any) => {
70
- const key = error.key;
71
-
72
- (errors as any)[key] = [(errors as any)[key] || "", error.message]
73
- .filter(Boolean)
74
- .join("; ");
75
- });
76
-
77
- deleteCookie(c, "authToken");
78
- return c.html(
79
- <Layout context={c}>
80
- <LoginForm login={{ email }} errors={errors} />
81
- </Layout>,
82
- );
83
- }
84
-
85
- const token = (resp as any).login.accessToken;
86
- const expiration =
87
- (decode(token) as any).payload.exp ||
88
- (new Date().getTime() / 1000).toFixed(0);
89
-
90
- const opts = {
91
- expires: new Date(expiration * 1000),
92
- } as CookieOptions;
93
-
94
- setCookie(c, "authToken", token, opts);
95
-
96
- return c.redirect("/tags", 301);
97
- });
98
-
99
- export default app;
@@ -1,14 +0,0 @@
1
- import { Hono } from "hono";
2
- import { deleteCookie } from "hono/cookie";
3
-
4
- const app = new Hono();
5
-
6
- app.delete("/logout", async (c) => {
7
- deleteCookie(c, "authToken");
8
-
9
- c.header("HX-Redirect", "/login");
10
- c.status(201);
11
- return c.json({ message: "Bye" });
12
- });
13
-
14
- export default app;
package/src/crud/tags.tsx DELETED
@@ -1,235 +0,0 @@
1
- import type { FC } from "hono/jsx";
2
- import { Hono } from "hono";
3
- import tags from "src/lib/dxp/private/tags";
4
- import Layout from "src/shared/Layout";
5
-
6
- const TagsList: FC = ({ data }) => {
7
- // TODO: Pagination!
8
- const list = data?.tags?.list || [];
9
-
10
- const results = list.map((tag: any) => (
11
- <tr class="bg-transparent hover:bg-yellow-50 transition">
12
- <td class="p-4 border-b">
13
- <a
14
- href={`/tags/${tag.id}/edit`}
15
- class="underline font-semibold hover:no-underline"
16
- >
17
- {tag.name}
18
- </a>
19
- </td>
20
- <td class="p-4 border-b">{tag.slug}</td>
21
- </tr>
22
- ));
23
-
24
- return (
25
- <>
26
- {results.length > 0 && results}
27
- {results.length === 0 && (
28
- <tr>
29
- <td colspan={2} class="p-4">
30
- Not found.
31
- </td>
32
- </tr>
33
- )}
34
- </>
35
- );
36
- };
37
-
38
- const Tags: FC = ({ data }) => {
39
- return (
40
- <div class="container mx-auto py-16">
41
- <h1 class="mb-8 text-2xl font-bold">Tags</h1>
42
-
43
- <a href="/tags/new">New</a>
44
-
45
- <table class="w-full">
46
- <thead>
47
- <tr>
48
- <th class="p-4 border-b text-left">Name</th>
49
- <th class="p-4 border-b text-left">URL</th>
50
- </tr>
51
- </thead>
52
- <TagsList data={data} />
53
- </table>
54
- </div>
55
- );
56
- };
57
-
58
- const Form: FC = ({ action, tag, errors = {} }) => {
59
- return (
60
- <form method="POST" action={action}>
61
- <div class="flex gap-2">
62
- <label>Name</label>
63
- <input type="text" value={tag.name} name="name" class="border" />
64
- {errors.name && <span>{errors.name}</span>}
65
- </div>
66
-
67
- <div class="flex gap-2">
68
- <label>URL</label>
69
- <input type="text" value={tag.slug} name="slug" class="border" />
70
- {errors.slug && <span>{errors.slug}</span>}
71
- </div>
72
-
73
- <div class="flex gap-4">
74
- <button type="submit">Save</button>
75
- <a href="/tags">Back</a>
76
- {tag.id && (
77
- <button
78
- type="button"
79
- hx-delete={`/tags/${tag.id}`}
80
- hx-confirm="Are you sure you wish to delete this tag?"
81
- >
82
- DELETE
83
- </button>
84
- )}
85
- </div>
86
- </form>
87
- );
88
- };
89
-
90
- const EditForm: FC = ({ tag, errors = {} }) => {
91
- return (
92
- <div class="container mx-auto py-16">
93
- <h1 class="mb-8 text-2xl font-bold">Tags</h1>
94
-
95
- <Form action={`/tags/${tag.id}`} tag={tag} errors={errors} />
96
- </div>
97
- );
98
- };
99
-
100
- const NewForm: FC = ({ tag = {}, errors = {} }) => {
101
- return (
102
- <div class="container mx-auto py-16">
103
- <h1 class="mb-8 text-2xl font-bold">Tags</h1>
104
-
105
- <Form action="/tags" tag={tag} errors={errors} />
106
- </div>
107
- );
108
- };
109
-
110
- const app = new Hono();
111
-
112
- app.get("/tags", async (c) => {
113
- const data = await tags.list({ input: { locale: "en" } }, c);
114
-
115
- return c.html(
116
- <Layout context={c}>
117
- <Tags data={data} />
118
- </Layout>,
119
- );
120
- });
121
-
122
- app.get("/tags/new", (c) => c.html(<NewForm />));
123
-
124
- app.get("/tags/:id/edit", async (c) => {
125
- const { tag }: any = await tags.find(parseInt(c.req.param().id, 10), "en", c);
126
-
127
- return c.html(
128
- <Layout context={c}>
129
- <EditForm tag={tag} />
130
- </Layout>,
131
- );
132
- });
133
-
134
- app.delete("/tags/:id", async (c) => {
135
- const { tag }: any = await tags.find(parseInt(c.req.param().id, 10), "en", c);
136
- const resp = await tags.delete(tag.id, "en", c);
137
- const deleteTag = (resp as any).deleteTag;
138
-
139
- if (deleteTag.errors) {
140
- throw `ERROR: ${deleteTag.errors}`;
141
- }
142
-
143
- c.header("HX-Redirect", "/tags");
144
- c.status(201);
145
-
146
- return c.json(deleteTag.tag);
147
- });
148
-
149
- app.post("/tags/:id", async (c) => {
150
- const body = await c.req.parseBody();
151
-
152
- const { tag }: any = await tags.find(parseInt(c.req.param().id, 10), "en", c);
153
-
154
- const resp = await tags.update(
155
- {
156
- input: {
157
- locale: "en",
158
- id: tag.id,
159
- tag: {
160
- name: body.name as string,
161
- slug: body.slug as string,
162
- },
163
- },
164
- },
165
- c,
166
- );
167
-
168
- if ((resp as any).updateTag.errors) {
169
- const errors = {};
170
-
171
- (resp as any).updateTag.errors.forEach((error: any) => {
172
- const key = error.key;
173
-
174
- (errors as any)[key] = [(errors as any)[key] || "", error.message]
175
- .filter(Boolean)
176
- .join("; ");
177
- });
178
-
179
- return c.html(
180
- <Layout context={c}>
181
- <EditForm
182
- tag={{
183
- id: tag.id,
184
- name: body.name as string,
185
- slug: body.slug as string,
186
- }}
187
- errors={errors}
188
- />
189
- </Layout>,
190
- );
191
- }
192
-
193
- return c.redirect("/tags", 301);
194
- });
195
-
196
- app.post("/tags", async (c) => {
197
- const body = await c.req.parseBody();
198
-
199
- const tag = {
200
- name: body.name as string,
201
- slug: body.slug as string,
202
- };
203
-
204
- const resp = await tags.create(
205
- {
206
- input: {
207
- locale: "en",
208
- tag,
209
- },
210
- },
211
- c,
212
- );
213
-
214
- if ((resp as any).createTag.errors) {
215
- const errors = {};
216
-
217
- (resp as any).createTag.errors.forEach((error: any) => {
218
- const key = error.key;
219
-
220
- (errors as any)[key] = [(errors as any)[key] || "", error.message]
221
- .filter(Boolean)
222
- .join("; ");
223
- });
224
-
225
- return c.html(
226
- <Layout context={c}>
227
- <NewForm tag={tag} errors={errors} />
228
- </Layout>,
229
- );
230
- }
231
-
232
- return c.redirect("/tags", 301);
233
- });
234
-
235
- export default app;
package/src/index.ts DELETED
@@ -1 +0,0 @@
1
- export { default as adminApp } from "./app";
@@ -1,106 +0,0 @@
1
- import { Context } from "hono";
2
- import { dxpPrivateRequest } from "../protocol";
3
- import { gql } from "../../gqlEngine";
4
-
5
- const TagsDocument = gql`
6
- query Tags($input: TagsInput!) {
7
- tags(input: $input) {
8
- list {
9
- id
10
- name
11
- slug
12
- }
13
- pagination {
14
- currentPage
15
- pagesCount
16
- entriesCount
17
- pageSize
18
- }
19
- }
20
- }
21
- `;
22
-
23
- const CreateTagDocument = gql`
24
- mutation CreateTag($input: CreateTagInput!) {
25
- createTag(input: $input) {
26
- tag {
27
- id
28
- slug
29
- name
30
- }
31
- errors {
32
- key
33
- message
34
- codes {
35
- key
36
- placeholders
37
- }
38
- }
39
- }
40
- }
41
- `;
42
-
43
- const UpdateTagDocument = gql`
44
- mutation UpdateTag($input: UpdateTagInput!) {
45
- updateTag(input: $input) {
46
- tag {
47
- id
48
- slug
49
- name
50
- }
51
- errors {
52
- key
53
- message
54
- codes {
55
- key
56
- placeholders
57
- }
58
- }
59
- }
60
- }
61
- `;
62
-
63
- const DeleteTagDocument = gql`
64
- mutation DeleteTag($input: IdInput!) {
65
- deleteTag(input: $input) {
66
- tag {
67
- id
68
- slug
69
- name
70
- }
71
- errors {
72
- key
73
- message
74
- codes {
75
- key
76
- placeholders
77
- }
78
- }
79
- }
80
- }
81
- `;
82
-
83
- const TagByIdDocument = gql`
84
- query TagByID($input: IdInput!) {
85
- tag(input: $input) {
86
- id
87
- slug
88
- name
89
- }
90
- }
91
- `;
92
-
93
- const tags = {
94
- list: async (variables: any, honoCtx: Context) =>
95
- dxpPrivateRequest(TagsDocument, variables, honoCtx),
96
- find: async (id: number, locale: string, honoCtx: Context) =>
97
- dxpPrivateRequest(TagByIdDocument, { input: { id, locale } }, honoCtx),
98
- create: async (variables: any, honoCtx: Context) =>
99
- dxpPrivateRequest(CreateTagDocument, variables, honoCtx),
100
- update: async (variables: any, honoCtx: Context) =>
101
- dxpPrivateRequest(UpdateTagDocument, variables, honoCtx),
102
- delete: async (id: number, locale: string, honoCtx: Context) =>
103
- dxpPrivateRequest(DeleteTagDocument, { input: { id, locale } }, honoCtx),
104
- };
105
-
106
- export default tags;
@@ -1,32 +0,0 @@
1
- import { getCookie } from "hono/cookie";
2
- import { env } from "hono/adapter";
3
- import { gqlRequest } from "../gqlEngine";
4
-
5
- export function dxpPublicRequest(query: string, variables: any, honoCtx: any) {
6
- const {
7
- RAKETA_GATEWAY_DISPATCH_URL,
8
- RAKETA_GATEWAY_PROJECT,
9
- RAKETA_DXP_PRIVATE_SERVICE,
10
- } = env(honoCtx);
11
-
12
- return gqlRequest(RAKETA_GATEWAY_DISPATCH_URL, query, variables, {
13
- "x-raketa-project": RAKETA_GATEWAY_PROJECT,
14
- "x-raketa-service": RAKETA_DXP_PRIVATE_SERVICE,
15
- });
16
- }
17
-
18
- export function dxpPrivateRequest(query: string, variables: any, honoCtx: any) {
19
- const token = getCookie(honoCtx, "authToken");
20
-
21
- const {
22
- RAKETA_GATEWAY_DISPATCH_URL,
23
- RAKETA_GATEWAY_PROJECT,
24
- RAKETA_DXP_PRIVATE_SERVICE,
25
- } = env(honoCtx);
26
-
27
- return gqlRequest(RAKETA_GATEWAY_DISPATCH_URL, query, variables, {
28
- "x-raketa-project": RAKETA_GATEWAY_PROJECT,
29
- "x-raketa-service": RAKETA_DXP_PRIVATE_SERVICE,
30
- "x-raketa-identity": token,
31
- });
32
- }
@@ -1,44 +0,0 @@
1
- import { Context } from "hono";
2
- import { env } from "hono/adapter";
3
- import { gql } from "../gqlEngine";
4
- import { gatewayRequest } from "./protocol";
5
-
6
- const LoginDocument = gql`
7
- mutation Login($input: LoginInput!) {
8
- login(input: $input) {
9
- accessToken
10
- errors {
11
- key
12
- message
13
- }
14
- }
15
- }
16
- `;
17
-
18
- const login = {
19
- create: async (email: string, password: string, honoCtx: Context) => {
20
- const {
21
- RAKETA_GATEWAY_PRIMARY_USER_POOL,
22
- RAKETA_GATEWAY_SECONDARY_USER_POOL,
23
- RAKETA_GATEWAY_PROJECT,
24
- } = env(honoCtx);
25
-
26
- return gatewayRequest(
27
- LoginDocument,
28
- {
29
- input: {
30
- email,
31
- password,
32
- userPools: [
33
- RAKETA_GATEWAY_PRIMARY_USER_POOL,
34
- RAKETA_GATEWAY_SECONDARY_USER_POOL,
35
- ].filter(Boolean),
36
- project: RAKETA_GATEWAY_PROJECT,
37
- },
38
- },
39
- honoCtx,
40
- );
41
- },
42
- };
43
-
44
- export default login;
@@ -1,8 +0,0 @@
1
- import { env } from "hono/adapter";
2
- import { gqlRequest } from "../gqlEngine";
3
-
4
- export function gatewayRequest(query: string, variables: any, honoCtx: any) {
5
- const { RAKETA_GATEWAY_AUTH_URL } = env(honoCtx);
6
-
7
- return gqlRequest(RAKETA_GATEWAY_AUTH_URL, query, variables);
8
- }
@@ -1,17 +0,0 @@
1
- import { request, gql } from "graphql-request";
2
-
3
- export function gqlRequest(
4
- url: string,
5
- query: string,
6
- variables = {},
7
- headers = {},
8
- ) {
9
- return request({
10
- url,
11
- document: query,
12
- variables: variables,
13
- requestHeaders: headers,
14
- });
15
- }
16
-
17
- export { gql };