Add reusable db queries

This commit is contained in:
Meier Lukas
2023-11-17 18:13:33 +01:00
parent 0142276bed
commit 5e75ccc660
5 changed files with 188 additions and 1 deletions

View File

@@ -13,6 +13,11 @@ export const getWidgetsForSectionsAsync = async (sectionIds: string[]) => {
return await db.query.widgets.findMany({
with: {
options: true,
integrations: {
with: {
integration: true,
},
},
item: {
with: {
layouts: {

View File

@@ -1,7 +1,8 @@
import { IconKey, IconPassword, IconUser, TablerIconsProps } from '@tabler/icons-react';
import { objectEntries, objectKeys } from '~/tools/object';
import widgets from '~/widgets';
import { objectEntries, objectKeys } from '../../tools/object';
type IntegrationTypeDefinition = {
secrets: IntegrationSecretKey[];
iconUrl: string;
@@ -48,6 +49,14 @@ export const widgetOptionTypes = [
'array',
'null',
] as const;
export const boardBackgroundImageAttachmentTypes = ['fixed', 'scroll'] as const;
export const boardBackgroundImageRepeatTypes = [
'repeat',
'repeat-x',
'repeat-y',
'no-repeat',
] as const;
export const boardBackgroundImageSizeTypes = ['cover', 'contain'] as const;
export const appNamePositions = ['right', 'left', 'top', 'bottom'] as const;
export const appNameStyles = ['normal', 'hide', 'hover'] as const;
export const statusCodeTypes = [
@@ -159,6 +168,10 @@ export type IntegrationSecretVisibility = (typeof integrationSecretVisibility)[n
export type IntegrationSecretKey = keyof typeof integrationSecrets;
export type WidgetSort = (typeof widgetSorts)[number];
export type WidgetOptionType = (typeof widgetOptionTypes)[number];
export type BoardBackgroundImageAttachmentType =
(typeof boardBackgroundImageAttachmentTypes)[number];
export type BoardBackgroundImageRepeatType = (typeof boardBackgroundImageRepeatTypes)[number];
export type BoardBackgroundImageSizeType = (typeof boardBackgroundImageSizeTypes)[number];
export type AppNamePosition = (typeof appNamePositions)[number];
export type AppNameStyle = (typeof appNameStyles)[number];
export type StatusCodeType = (typeof statusCodeTypes)[number];

View File

@@ -0,0 +1,31 @@
import { and, eq } from 'drizzle-orm';
import { User } from 'next-auth';
import { db } from '..';
import { boards, items } from '../schema';
export const getAppAsync = async (boardId: string, id: string, user: User | null | undefined) => {
return await db.query.items.findFirst({
where: and(
eq(items.boardId, boardId),
eq(items.id, id),
user ? undefined : eq(boards.allowGuests, true)
),
with: {
app: {
with: {
statusCodes: {
columns: {
code: true,
},
},
},
},
board: {
columns: {
allowGuests: true,
},
},
},
});
};

View File

@@ -0,0 +1,67 @@
import { and, eq, inArray } from 'drizzle-orm';
import { User } from 'next-auth';
import { db } from '..';
import { IntegrationSecretKey, IntegrationType } from '../items';
import { boards, integrations, items } from '../schema';
export async function getIntegrations<TIntegrations extends IntegrationType>(
boardId: string,
sorts: TIntegrations[],
user: User | null | undefined
) {
return await getIntegrationsForWidget(boardId, sorts, user, 'ignore');
}
export const getIntegrationsForWidget = async <TIntegrations extends IntegrationType>(
boardId: string,
sorts: TIntegrations[],
user: User | null | undefined,
widgetId: 'ignore' | (string & {})
) => {
const widgetItems = await db.query.items.findMany({
where: and(
eq(items.boardId, boardId),
user ? undefined : eq(boards.allowGuests, true),
sorts.length >= 1 ? inArray(integrations.sort, sorts) : undefined,
widgetId !== 'ignore' ? eq(items.id, widgetId) : undefined
),
with: {
widget: {
with: {
integrations: {
with: {
integration: {
with: {
secrets: true,
},
},
},
},
options: true,
},
},
},
});
return widgetItems
.flatMap((x) => x.widget?.integrations ?? [])
.map((x) => ({ ...x.integration, sort: x.integration.sort as TIntegrations }));
};
export async function getIntegrationAsync(integrationId: string) {
return await db.query.integrations.findFirst({
where: eq(integrations.id, integrationId),
with: {
secrets: true,
widgets: true,
},
});
}
export function getSecret(
integration: Awaited<ReturnType<typeof getIntegrations>>[number],
key: IntegrationSecretKey
) {
return integration.secrets.find((s) => s.key === key)?.value ?? '';
}

View File

@@ -0,0 +1,71 @@
import { and, eq } from 'drizzle-orm';
import { User } from 'next-auth';
import { mapWidgetOptions } from '~/server/api/routers/board/mapping/options';
import { objectEntries } from '~/tools/object';
import widgetDefinitions from '~/widgets';
import { InferWidgetOptions } from '~/widgets/widgets';
import { db } from '..';
import { boards, items, widgets } from '../schema';
export const getWidgetAsync = async <TSort extends keyof typeof widgetDefinitions>(
boardId: string,
id: string,
user: User | null | undefined,
sort: TSort
) => {
const widgetItem = await db.query.items.findFirst({
where: and(
eq(items.boardId, boardId),
eq(items.id, id),
user ? undefined : eq(boards.allowGuests, true),
eq(widgets.sort, sort)
),
with: {
widget: {
with: {
integrations: {
with: {
integration: {
with: {
secrets: true,
},
},
},
},
options: true,
},
},
board: {
columns: {
allowGuests: true,
},
},
},
});
if (!widgetItem) {
return null;
}
const mappedOptions = mapWidgetOptions(
widgetItem.widget!.options.sort((a, b) => a.path.localeCompare(b.path))
);
objectEntries(widgetDefinitions[sort].options).forEach(([key, definition]) => {
mappedOptions[key] = mappedOptions[key] ?? definition.defaultValue;
});
return {
id: widgetItem.id,
sort: widgetItem.widget!.sort,
options: mappedOptions as InferWidgetOptions<(typeof widgetDefinitions)[TSort]>,
integrations: widgetItem.widget!.integrations.map((i) => ({
...i.integration,
})),
};
};
export type WidgetIntegration = Exclude<
Awaited<ReturnType<typeof getWidgetAsync>>,
null
>['integrations'][number];