Skip to content

Commit cad9f69

Browse files
committed
feat: #1243 add api routes
1 parent 278107a commit cad9f69

File tree

13 files changed

+362
-279
lines changed

13 files changed

+362
-279
lines changed

packages/api/src/router/app.ts

+29-46
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,14 @@ import { apps } from "@homarr/db/schema/sqlite";
55
import { validation, z } from "@homarr/validation";
66

77
import { createTRPCRouter, protectedProcedure, publicProcedure } from "../trpc";
8+
import { selectAppSchema } from "@homarr/db/validationSchemas/app";
89

910
export const appRouter = createTRPCRouter({
1011
all: publicProcedure
1112
.input(z.void())
1213
.output(
1314
z.array(
14-
z.object({
15-
name: z.string(),
16-
id: z.string(),
17-
description: z.string().nullable(),
18-
iconUrl: z.string(),
19-
href: z.string().nullable(),
20-
}),
15+
selectAppSchema
2116
),
2217
)
2318
.meta({ openapi: { method: "GET", path: "/api/apps", tags: ["apps"], protect: true } })
@@ -30,13 +25,7 @@ export const appRouter = createTRPCRouter({
3025
.input(z.object({ query: z.string(), limit: z.number().min(1).max(100).default(10) }))
3126
.output(
3227
z.array(
33-
z.object({
34-
name: z.string(),
35-
id: z.string(),
36-
description: z.string().nullable(),
37-
iconUrl: z.string(),
38-
href: z.string().nullable(),
39-
}),
28+
selectAppSchema,
4029
),
4130
)
4231
.meta({ openapi: { method: "GET", path: "/api/apps/search", tags: ["apps"], protect: true } })
@@ -51,11 +40,7 @@ export const appRouter = createTRPCRouter({
5140
.input(z.void())
5241
.output(
5342
z.array(
54-
z.object({
55-
name: z.string(),
56-
id: z.string(),
57-
iconUrl: z.string(),
58-
}),
43+
selectAppSchema.pick({ id: true, name: true, iconUrl: true }),
5944
),
6045
)
6146
.meta({
@@ -79,13 +64,7 @@ export const appRouter = createTRPCRouter({
7964
byId: publicProcedure
8065
.input(validation.common.byId)
8166
.output(
82-
z.object({
83-
name: z.string(),
84-
id: z.string(),
85-
description: z.string().nullable(),
86-
iconUrl: z.string(),
87-
href: z.string().nullable(),
88-
}),
67+
selectAppSchema,
8968
)
9069
.meta({ openapi: { method: "GET", path: "/api/apps/{id}", tags: ["apps"], protect: true } })
9170
.query(async ({ ctx, input }) => {
@@ -115,28 +94,32 @@ export const appRouter = createTRPCRouter({
11594
href: input.href,
11695
});
11796
}),
118-
update: protectedProcedure.input(validation.app.edit).mutation(async ({ ctx, input }) => {
119-
const app = await ctx.db.query.apps.findFirst({
120-
where: eq(apps.id, input.id),
121-
});
122-
123-
if (!app) {
124-
throw new TRPCError({
125-
code: "NOT_FOUND",
126-
message: "App not found",
97+
update: protectedProcedure
98+
.input(validation.app.edit)
99+
.output(z.void())
100+
.meta({ openapi: { method: "PATCH", path: "/api/apps/{id}", tags: ["apps"], protect: true } })
101+
.mutation(async ({ ctx, input }) => {
102+
const app = await ctx.db.query.apps.findFirst({
103+
where: eq(apps.id, input.id),
127104
});
128-
}
129105

130-
await ctx.db
131-
.update(apps)
132-
.set({
133-
name: input.name,
134-
description: input.description,
135-
iconUrl: input.iconUrl,
136-
href: input.href,
137-
})
138-
.where(eq(apps.id, input.id));
139-
}),
106+
if (!app) {
107+
throw new TRPCError({
108+
code: "NOT_FOUND",
109+
message: "App not found",
110+
});
111+
}
112+
113+
await ctx.db
114+
.update(apps)
115+
.set({
116+
name: input.name,
117+
description: input.description,
118+
iconUrl: input.iconUrl,
119+
href: input.href,
120+
})
121+
.where(eq(apps.id, input.id));
122+
}),
140123
delete: protectedProcedure
141124
.output(z.void())
142125
.meta({ openapi: { method: "DELETE", path: "/api/apps/{id}", tags: ["apps"], protect: true } })

packages/api/src/router/invite.ts

+27-16
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,41 @@ import { z } from "@homarr/validation";
77

88
import { createTRPCRouter, protectedProcedure } from "../trpc";
99
import { throwIfCredentialsDisabled } from "./invite/checks";
10+
import { selectInviteSchema } from "@homarr/db/validationSchemas/invite";
1011

1112
export const inviteRouter = createTRPCRouter({
12-
getAll: protectedProcedure.query(async ({ ctx }) => {
13-
throwIfCredentialsDisabled();
14-
const dbInvites = await ctx.db.query.invites.findMany({
15-
orderBy: asc(invites.expirationDate),
16-
columns: {
17-
token: false,
18-
},
19-
with: {
20-
creator: {
21-
columns: {
22-
id: true,
23-
name: true,
13+
getAll: protectedProcedure
14+
.output(z.array(selectInviteSchema.pick({
15+
id: true,
16+
expirationDate: true
17+
}).extend({ creator: z.object({ name: z.string().nullable(), id: z.string() }) })))
18+
.input(z.undefined())
19+
.meta({ openapi: { method: "GET", path: "/api/invites", tags: ["invites"], protect: true } })
20+
.query(async ({ ctx }) => {
21+
throwIfCredentialsDisabled();
22+
return await ctx.db.query.invites.findMany({
23+
orderBy: asc(invites.expirationDate),
24+
columns: {
25+
token: false,
26+
},
27+
with: {
28+
creator: {
29+
columns: {
30+
id: true,
31+
name: true,
32+
},
2433
},
2534
},
26-
},
27-
});
28-
return dbInvites;
29-
}),
35+
});
36+
}),
3037
createInvite: protectedProcedure
3138
.input(
3239
z.object({
3340
expirationDate: z.date(),
3441
}),
3542
)
43+
.output(z.object({ id: z.string(), token: z.string() }))
44+
.meta({ openapi: { method: "GET", path: "/api/invites", tags: ["invites"], protect: true } })
3645
.mutation(async ({ ctx, input }) => {
3746
throwIfCredentialsDisabled();
3847
const id = createId();
@@ -56,6 +65,8 @@ export const inviteRouter = createTRPCRouter({
5665
id: z.string(),
5766
}),
5867
)
68+
.output(z.undefined())
69+
.meta({ openapi: { method: "DELETE", path: "/api/invites/{id}", tags: ["invites"], protect: true } })
5970
.mutation(async ({ ctx, input }) => {
6071
throwIfCredentialsDisabled();
6172
const dbInvite = await ctx.db.query.invites.findFirst({

packages/api/src/router/serverSettings.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ import { createTRPCRouter, protectedProcedure, publicProcedure } from "../trpc";
1111

1212
export const serverSettingsRouter = createTRPCRouter({
1313
// this must be public so anonymous users also get analytics
14-
getAnalytics: publicProcedure.query(async ({ ctx }) => {
14+
getAnalytics: publicProcedure
15+
.input(z.undefined())
16+
.query(async ({ ctx }) => {
1517
const setting = await ctx.db.query.serverSettings.findFirst({
1618
where: eq(serverSettings.settingKey, "analytics"),
1719
});
@@ -30,7 +32,8 @@ export const serverSettingsRouter = createTRPCRouter({
3032

3133
return SuperJSON.parse<(typeof defaultServerSettings)["analytics"]>(setting.value);
3234
}),
33-
getAll: protectedProcedure.query(async ({ ctx }) => {
35+
getAll: protectedProcedure
36+
.query(async ({ ctx }) => {
3437
const settings = await ctx.db.query.serverSettings.findMany();
3538

3639
const data = {} as ServerSettings;

0 commit comments

Comments
 (0)