mirror of
https://github.com/ajnart/homarr.git
synced 2026-02-27 08:50:56 +01:00
chore(release): automatic release v1.0.0
This commit is contained in:
@@ -104,7 +104,7 @@ jobs:
|
||||
NEXT_VERSION: ${{ needs.release.outputs.version }}
|
||||
DEPLOY_LATEST: ${{ github.ref_name == 'main' }}
|
||||
DEPLOY_BETA: ${{ github.ref_name == 'beta' }}
|
||||
PUSH_IMAGE: ${{ github.event_name != 'workflow_dispatch' || github.events.inputs.push-image == 'true' }}
|
||||
PUSH_IMAGE: ${{ github.event_name != 'workflow_dispatch' || github.events.inputs.push-image == true }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Discord notification
|
||||
|
||||
@@ -26,7 +26,7 @@ FROM base AS runner
|
||||
WORKDIR /app
|
||||
|
||||
# gettext is required for envsubst
|
||||
RUN apk add --no-cache redis nginx bash gettext
|
||||
RUN apk add --no-cache redis nginx bash gettext su-exec
|
||||
RUN mkdir /appdata
|
||||
VOLUME /appdata
|
||||
RUN mkdir /secrets
|
||||
@@ -43,14 +43,12 @@ RUN echo $'#!/bin/bash\ncd /app/apps/cli && node ./cli.cjs "$@"' > /usr/bin/homa
|
||||
RUN chmod +x /usr/bin/homarr
|
||||
|
||||
# Don't run production as root
|
||||
RUN chown -R nextjs:nodejs /appdata
|
||||
RUN chown -R nextjs:nodejs /secrets
|
||||
RUN mkdir -p /var/cache/nginx && chown -R nextjs:nodejs /var/cache/nginx && \
|
||||
mkdir -p /var/log/nginx && chown -R nextjs:nodejs /var/log/nginx && \
|
||||
mkdir -p /var/lib/nginx && chown -R nextjs:nodejs /var/lib/nginx && \
|
||||
touch /run/nginx/nginx.pid && chown -R nextjs:nodejs /run/nginx/nginx.pid && \
|
||||
mkdir -p /etc/nginx/templates /etc/nginx/ssl/certs && chown -R nextjs:nodejs /etc/nginx
|
||||
USER nextjs
|
||||
|
||||
COPY --from=builder /app/apps/nextjs/next.config.mjs .
|
||||
COPY --from=builder /app/apps/nextjs/package.json .
|
||||
@@ -67,6 +65,8 @@ COPY --from=builder --chown=nextjs:nodejs /app/apps/nextjs/.next/standalone ./
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/apps/nextjs/.next/static ./apps/nextjs/.next/static
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/apps/nextjs/public ./apps/nextjs/public
|
||||
COPY --chown=nextjs:nodejs scripts/run.sh ./run.sh
|
||||
COPY scripts/entrypoint.sh ./entrypoint.sh
|
||||
RUN chmod +x ./entrypoint.sh
|
||||
COPY --chown=nextjs:nodejs scripts/generateRandomSecureKey.js ./generateRandomSecureKey.js
|
||||
COPY --chown=nextjs:nodejs packages/redis/redis.conf /app/redis.conf
|
||||
COPY --chown=nextjs:nodejs nginx.conf /etc/nginx/templates/nginx.conf
|
||||
@@ -77,4 +77,5 @@ ENV DB_DIALECT='sqlite'
|
||||
ENV DB_DRIVER='better-sqlite3'
|
||||
ENV AUTH_PROVIDERS='credentials'
|
||||
|
||||
ENTRYPOINT [ "/app/entrypoint.sh" ]
|
||||
CMD ["sh", "run.sh"]
|
||||
|
||||
@@ -7,13 +7,13 @@ import { CurrentUserAvatar } from "~/components/user-avatar";
|
||||
import { UserAvatarMenu } from "~/components/user-avatar-menu";
|
||||
|
||||
export const UserButton = async () => {
|
||||
const data = await api.updateChecker.getAvailableUpdates();
|
||||
const session = await auth();
|
||||
const isAdmin = session?.user.permissions.includes("admin");
|
||||
const data = isAdmin ? await api.updateChecker.getAvailableUpdates() : undefined;
|
||||
return (
|
||||
<UserAvatarMenu availableUpdates={isAdmin ? data : undefined}>
|
||||
<UserAvatarMenu availableUpdates={data}>
|
||||
<UnstyledButton>
|
||||
<Indicator disabled={data.length === 0 || !isAdmin} size={15} processing withBorder>
|
||||
<Indicator disabled={data?.length === 0 || !isAdmin} size={15} processing withBorder>
|
||||
<CurrentUserAvatar size="md" />
|
||||
</Indicator>
|
||||
</UnstyledButton>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import fsPromises from "fs/promises";
|
||||
import { glob } from "glob";
|
||||
|
||||
import packageJson from "~/../package.json";
|
||||
import packageJson from "../../../../package.json";
|
||||
|
||||
const getPackageVersion = () => packageJson.version;
|
||||
const getDependenciesAsync = async (): Promise<PackageJsonDependencies> => {
|
||||
|
||||
@@ -14,15 +14,16 @@ import {
|
||||
} from "@homarr/db/schema/sqlite";
|
||||
import type { IntegrationSecretKind } from "@homarr/definitions";
|
||||
import {
|
||||
getIntegrationKindsByCategory,
|
||||
getPermissionsWithParents,
|
||||
integrationDefs,
|
||||
integrationKinds,
|
||||
integrationSecretKindObject,
|
||||
isIntegrationWithSearchSupport,
|
||||
} from "@homarr/definitions";
|
||||
import { integrationCreatorFromSecrets } from "@homarr/integrations";
|
||||
import { integrationCreator } from "@homarr/integrations";
|
||||
import { validation, z } from "@homarr/validation";
|
||||
|
||||
import { createOneIntegrationMiddleware } from "../../middlewares/integration";
|
||||
import { createTRPCRouter, permissionRequiredProcedure, protectedProcedure, publicProcedure } from "../../trpc";
|
||||
import { throwIfActionForbiddenAsync } from "./integration-access";
|
||||
import { testConnectionAsync } from "./integration-test-connection";
|
||||
@@ -90,7 +91,7 @@ export const integrationRouter = createTRPCRouter({
|
||||
where: inArray(
|
||||
integrations.kind,
|
||||
objectEntries(integrationDefs)
|
||||
.filter(([_, integration]) => integration.supportsSearch)
|
||||
.filter(([_, integration]) => [...integration.category].includes("search"))
|
||||
.map(([kind, _]) => kind),
|
||||
),
|
||||
});
|
||||
@@ -383,31 +384,11 @@ export const integrationRouter = createTRPCRouter({
|
||||
});
|
||||
}),
|
||||
searchInIntegration: protectedProcedure
|
||||
.unstable_concat(createOneIntegrationMiddleware("query", ...getIntegrationKindsByCategory("search")))
|
||||
.input(z.object({ integrationId: z.string(), query: z.string() }))
|
||||
.query(async ({ ctx, input }) => {
|
||||
const integration = await ctx.db.query.integrations.findFirst({
|
||||
where: eq(integrations.id, input.integrationId),
|
||||
with: {
|
||||
secrets: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!integration) {
|
||||
throw new TRPCError({
|
||||
code: "NOT_FOUND",
|
||||
message: "The requested integration does not exist",
|
||||
});
|
||||
}
|
||||
|
||||
if (!isIntegrationWithSearchSupport(integration)) {
|
||||
throw new TRPCError({
|
||||
code: "BAD_REQUEST",
|
||||
message: "The requested integration does not support searching",
|
||||
});
|
||||
}
|
||||
|
||||
const integrationInstance = integrationCreatorFromSecrets(integration);
|
||||
return await integrationInstance.searchAsync(input.query);
|
||||
const integrationInstance = integrationCreator(ctx.integration);
|
||||
return await integrationInstance.searchAsync(encodeURI(input.query));
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
"@t3-oss/env-nextjs": "^0.11.1",
|
||||
"bcrypt": "^5.1.1",
|
||||
"cookies": "^0.9.1",
|
||||
"ldapts": "7.2.2",
|
||||
"ldapts": "7.3.0",
|
||||
"next": "^14.2.20",
|
||||
"next-auth": "5.0.0-beta.25",
|
||||
"react": "^19.0.0",
|
||||
|
||||
@@ -8,6 +8,7 @@ export type HomarrDocumentationPath =
|
||||
| "/blog/2023/11/10/authentication"
|
||||
| "/blog/2023/12/22/updated-documentation"
|
||||
| "/blog/2024/09/23/version-1.0"
|
||||
| "/blog/2024/12/17/open-beta-1.0"
|
||||
| "/blog/archive"
|
||||
| "/blog/authors"
|
||||
| "/blog/authors/ajnart"
|
||||
@@ -33,6 +34,7 @@ export type HomarrDocumentationPath =
|
||||
| "/blog/tags/update"
|
||||
| "/blog/tags/version"
|
||||
| "/blog/translations"
|
||||
| "/search"
|
||||
| "/docs/tags"
|
||||
| "/docs/tags/active-directory"
|
||||
| "/docs/tags/ad-guard"
|
||||
@@ -44,7 +46,6 @@ export type HomarrDocumentationPath =
|
||||
| "/docs/tags/apps"
|
||||
| "/docs/tags/banner"
|
||||
| "/docs/tags/blocking"
|
||||
| "/docs/tags/board"
|
||||
| "/docs/tags/boards"
|
||||
| "/docs/tags/bookmark"
|
||||
| "/docs/tags/bookmarks"
|
||||
@@ -56,10 +57,12 @@ export type HomarrDocumentationPath =
|
||||
| "/docs/tags/connections"
|
||||
| "/docs/tags/customization"
|
||||
| "/docs/tags/data-sources"
|
||||
| "/docs/tags/database"
|
||||
| "/docs/tags/developer"
|
||||
| "/docs/tags/development"
|
||||
| "/docs/tags/dns"
|
||||
| "/docs/tags/docker"
|
||||
| "/docs/tags/donation"
|
||||
| "/docs/tags/edit-mode"
|
||||
| "/docs/tags/env"
|
||||
| "/docs/tags/environment-variables"
|
||||
@@ -71,6 +74,8 @@ export type HomarrDocumentationPath =
|
||||
| "/docs/tags/hardware"
|
||||
| "/docs/tags/health"
|
||||
| "/docs/tags/help"
|
||||
| "/docs/tags/icon-picker"
|
||||
| "/docs/tags/icon-repositories"
|
||||
| "/docs/tags/icons"
|
||||
| "/docs/tags/iframe"
|
||||
| "/docs/tags/images"
|
||||
@@ -84,17 +89,18 @@ export type HomarrDocumentationPath =
|
||||
| "/docs/tags/links"
|
||||
| "/docs/tags/lists"
|
||||
| "/docs/tags/management"
|
||||
| "/docs/tags/media"
|
||||
| "/docs/tags/monitoring"
|
||||
| "/docs/tags/news"
|
||||
| "/docs/tags/notebook"
|
||||
| "/docs/tags/notes"
|
||||
| "/docs/tags/oidc"
|
||||
| "/docs/tags/open-collective"
|
||||
| "/docs/tags/open-media-vault"
|
||||
| "/docs/tags/overseerr"
|
||||
| "/docs/tags/permissions"
|
||||
| "/docs/tags/pi-hole"
|
||||
| "/docs/tags/ping"
|
||||
| "/docs/tags/preferences"
|
||||
| "/docs/tags/programming"
|
||||
| "/docs/tags/proxmox"
|
||||
| "/docs/tags/proxy"
|
||||
@@ -112,39 +118,37 @@ export type HomarrDocumentationPath =
|
||||
| "/docs/tags/table"
|
||||
| "/docs/tags/technical-documentation"
|
||||
| "/docs/tags/text"
|
||||
| "/docs/tags/theming"
|
||||
| "/docs/tags/torrent"
|
||||
| "/docs/tags/traefik"
|
||||
| "/docs/tags/translations"
|
||||
| "/docs/tags/unraid"
|
||||
| "/docs/tags/user"
|
||||
| "/docs/tags/uploads"
|
||||
| "/docs/tags/usenet"
|
||||
| "/docs/tags/users"
|
||||
| "/docs/tags/variables"
|
||||
| "/docs/tags/widgets"
|
||||
| "/docs/advanced/command-line"
|
||||
| "/docs/advanced/command-line/password-recovery"
|
||||
| "/docs/advanced/configuration/environment-variables"
|
||||
| "/docs/advanced/configuration/keyboard-shortcuts"
|
||||
| "/docs/advanced/configuration/proxies-and-certificates"
|
||||
| "/docs/advanced/customizations/board-customization"
|
||||
| "/docs/advanced/customizations/dark-mode"
|
||||
| "/docs/advanced/customizations/icons"
|
||||
| "/docs/advanced/customizations/user-preferences"
|
||||
| "/docs/advanced/sso"
|
||||
| "/docs/advanced/development/getting-started"
|
||||
| "/docs/advanced/environment-variables"
|
||||
| "/docs/advanced/icons"
|
||||
| "/docs/advanced/keyboard-shortcuts"
|
||||
| "/docs/advanced/proxy"
|
||||
| "/docs/advanced/single-sign-on"
|
||||
| "/docs/category/advanced"
|
||||
| "/docs/category/developer-guide"
|
||||
| "/docs/category/community"
|
||||
| "/docs/category/developer-guides"
|
||||
| "/docs/category/getting-started"
|
||||
| "/docs/category/installation"
|
||||
| "/docs/category/installation-1"
|
||||
| "/docs/category/integrations"
|
||||
| "/docs/category/management"
|
||||
| "/docs/category/more"
|
||||
| "/docs/category/widgets"
|
||||
| "/docs/community/donate"
|
||||
| "/docs/community/faq"
|
||||
| "/docs/community/get-in-touch"
|
||||
| "/docs/community/license"
|
||||
| "/docs/community/translations"
|
||||
| "/docs/development/getting-started"
|
||||
| "/docs/getting-started"
|
||||
| "/docs/getting-started/after-the-installation"
|
||||
| "/docs/getting-started/glossary"
|
||||
@@ -152,7 +156,6 @@ export type HomarrDocumentationPath =
|
||||
| "/docs/getting-started/installation/easy-panel"
|
||||
| "/docs/getting-started/installation/helm"
|
||||
| "/docs/getting-started/installation/home-assistant"
|
||||
| "/docs/getting-started/installation/kubernetes"
|
||||
| "/docs/getting-started/installation/portainer"
|
||||
| "/docs/getting-started/installation/qnap"
|
||||
| "/docs/getting-started/installation/saltbox"
|
||||
@@ -172,15 +175,15 @@ export type HomarrDocumentationPath =
|
||||
| "/docs/management/apps"
|
||||
| "/docs/management/boards"
|
||||
| "/docs/management/integrations"
|
||||
| "/docs/management/media"
|
||||
| "/docs/management/search-engines"
|
||||
| "/docs/management/settings"
|
||||
| "/docs/management/users"
|
||||
| "/docs/widgets/bookmarks"
|
||||
| "/docs/widgets/calendar-widget"
|
||||
| "/docs/widgets/clock-widget"
|
||||
| "/docs/widgets/dashdot-widget"
|
||||
| "/docs/widgets/calendar"
|
||||
| "/docs/widgets/clock"
|
||||
| "/docs/widgets/dns-hole"
|
||||
| "/docs/widgets/download-speed-widget"
|
||||
| "/docs/widgets/downloads"
|
||||
| "/docs/widgets/health-monitoring"
|
||||
| "/docs/widgets/home-assistant"
|
||||
| "/docs/widgets/iframe"
|
||||
@@ -188,10 +191,8 @@ export type HomarrDocumentationPath =
|
||||
| "/docs/widgets/media-requests"
|
||||
| "/docs/widgets/media-server"
|
||||
| "/docs/widgets/notebook"
|
||||
| "/docs/widgets/rss-widget"
|
||||
| "/docs/widgets/torrent-widget"
|
||||
| "/docs/widgets/usenet-widget"
|
||||
| "/docs/widgets/rss"
|
||||
| "/docs/widgets/video"
|
||||
| "/docs/widgets/weather-widget"
|
||||
| "/docs/widgets/weather"
|
||||
| ""
|
||||
| "/sitemap.xml";
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
export const everyoneGroup = "everyone";
|
||||
export const credentialsAdminGroup = "admin";
|
||||
export const credentialsAdminGroup = "credentials-admin";
|
||||
|
||||
@@ -14,7 +14,6 @@ interface integrationDefinition {
|
||||
iconUrl: string;
|
||||
secretKinds: AtLeastOneOf<IntegrationSecretKind[]>; // at least one secret kind set is required
|
||||
category: AtLeastOneOf<IntegrationCategory>;
|
||||
supportsSearch: boolean;
|
||||
}
|
||||
|
||||
export const integrationDefs = {
|
||||
@@ -23,140 +22,120 @@ export const integrationDefs = {
|
||||
secretKinds: [["apiKey"]],
|
||||
iconUrl: "https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons@master/png/sabnzbd.png",
|
||||
category: ["downloadClient", "usenet"],
|
||||
supportsSearch: false,
|
||||
},
|
||||
nzbGet: {
|
||||
name: "NZBGet",
|
||||
secretKinds: [["username", "password"]],
|
||||
iconUrl: "https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons@master/png/nzbget.png",
|
||||
category: ["downloadClient", "usenet"],
|
||||
supportsSearch: false,
|
||||
},
|
||||
deluge: {
|
||||
name: "Deluge",
|
||||
secretKinds: [["password"]],
|
||||
iconUrl: "https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons@master/png/deluge.png",
|
||||
category: ["downloadClient", "torrent"],
|
||||
supportsSearch: false,
|
||||
},
|
||||
transmission: {
|
||||
name: "Transmission",
|
||||
secretKinds: [["username", "password"]],
|
||||
iconUrl: "https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons@master/png/transmission.png",
|
||||
category: ["downloadClient", "torrent"],
|
||||
supportsSearch: false,
|
||||
},
|
||||
qBittorrent: {
|
||||
name: "qBittorrent",
|
||||
secretKinds: [["username", "password"]],
|
||||
iconUrl: "https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons@master/png/qbittorrent.png",
|
||||
category: ["downloadClient", "torrent"],
|
||||
supportsSearch: false,
|
||||
},
|
||||
sonarr: {
|
||||
name: "Sonarr",
|
||||
secretKinds: [["apiKey"]],
|
||||
iconUrl: "https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons@master/png/sonarr.png",
|
||||
category: ["calendar"],
|
||||
supportsSearch: false,
|
||||
},
|
||||
radarr: {
|
||||
name: "Radarr",
|
||||
secretKinds: [["apiKey"]],
|
||||
iconUrl: "https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons@master/png/radarr.png",
|
||||
category: ["calendar"],
|
||||
supportsSearch: false,
|
||||
},
|
||||
lidarr: {
|
||||
name: "Lidarr",
|
||||
secretKinds: [["apiKey"]],
|
||||
iconUrl: "https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons@master/png/lidarr.png",
|
||||
category: ["calendar"],
|
||||
supportsSearch: false,
|
||||
},
|
||||
readarr: {
|
||||
name: "Readarr",
|
||||
secretKinds: [["apiKey"]],
|
||||
iconUrl: "https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons@master/png/readarr.png",
|
||||
category: ["calendar"],
|
||||
supportsSearch: false,
|
||||
},
|
||||
prowlarr: {
|
||||
name: "Prowlarr",
|
||||
secretKinds: [["apiKey"]],
|
||||
iconUrl: "https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons@master/png/prowlarr.png",
|
||||
category: ["indexerManager"],
|
||||
supportsSearch: false,
|
||||
},
|
||||
jellyfin: {
|
||||
name: "Jellyfin",
|
||||
secretKinds: [["username", "password"], ["apiKey"]],
|
||||
iconUrl: "https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons@master/png/jellyfin.png",
|
||||
category: ["mediaService"],
|
||||
supportsSearch: false,
|
||||
},
|
||||
plex: {
|
||||
name: "Plex",
|
||||
secretKinds: [["apiKey"]],
|
||||
iconUrl: "https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons@master/png/plex.png",
|
||||
category: ["mediaService"],
|
||||
supportsSearch: false,
|
||||
},
|
||||
jellyseerr: {
|
||||
name: "Jellyseerr",
|
||||
secretKinds: [["apiKey"]],
|
||||
iconUrl: "https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons@master/png/jellyseerr.png",
|
||||
category: ["mediaSearch", "mediaRequest"],
|
||||
supportsSearch: true,
|
||||
category: ["mediaSearch", "mediaRequest", "search"],
|
||||
},
|
||||
overseerr: {
|
||||
name: "Overseerr",
|
||||
secretKinds: [["apiKey"]],
|
||||
iconUrl: "https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons@master/png/overseerr.png",
|
||||
category: ["mediaSearch", "mediaRequest"],
|
||||
supportsSearch: true,
|
||||
category: ["mediaSearch", "mediaRequest", "search"],
|
||||
},
|
||||
piHole: {
|
||||
name: "Pi-hole",
|
||||
secretKinds: [["apiKey"]],
|
||||
iconUrl: "https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons@master/png/pi-hole.png",
|
||||
category: ["dnsHole"],
|
||||
supportsSearch: false,
|
||||
},
|
||||
adGuardHome: {
|
||||
name: "AdGuard Home",
|
||||
secretKinds: [["username", "password"]],
|
||||
iconUrl: "https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons@master/png/adguard-home.png",
|
||||
category: ["dnsHole"],
|
||||
supportsSearch: false,
|
||||
},
|
||||
homeAssistant: {
|
||||
name: "Home Assistant",
|
||||
secretKinds: [["apiKey"]],
|
||||
iconUrl: "https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons@master/png/home-assistant.png",
|
||||
category: ["smartHomeServer"],
|
||||
supportsSearch: false,
|
||||
},
|
||||
openmediavault: {
|
||||
name: "OpenMediaVault",
|
||||
secretKinds: [["username", "password"]],
|
||||
iconUrl: "https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons@master/png/openmediavault.png",
|
||||
category: ["healthMonitoring"],
|
||||
supportsSearch: false,
|
||||
},
|
||||
dashDot: {
|
||||
name: "Dash.",
|
||||
secretKinds: [[]],
|
||||
category: ["healthMonitoring"],
|
||||
iconUrl: "https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons@master/png/dashdot.png",
|
||||
supportsSearch: false,
|
||||
},
|
||||
tdarr: {
|
||||
name: "Tdarr",
|
||||
secretKinds: [[]],
|
||||
category: ["mediaTranscoding"],
|
||||
iconUrl: "https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons@master/png/tdarr.png",
|
||||
supportsSearch: false,
|
||||
},
|
||||
} as const satisfies Record<string, integrationDefinition>;
|
||||
|
||||
@@ -195,22 +174,6 @@ export type IntegrationKindByCategory<TCategory extends IntegrationCategory> = {
|
||||
U
|
||||
: never;
|
||||
|
||||
/**
|
||||
* Checks if search is supported by the integration
|
||||
* Uses a typescript guard with is to allow only integrations with search support within if statement
|
||||
* @param integration integration with kind
|
||||
* @returns true if the integration supports search
|
||||
*/
|
||||
export const isIntegrationWithSearchSupport = (integration: {
|
||||
kind: IntegrationKind;
|
||||
}): integration is { kind: IntegrationWithSearchSupport } => {
|
||||
return integrationDefs[integration.kind].supportsSearch;
|
||||
};
|
||||
|
||||
type IntegrationWithSearchSupport = {
|
||||
[Key in keyof typeof integrationDefs]: true extends (typeof integrationDefs)[Key]["supportsSearch"] ? Key : never;
|
||||
}[keyof typeof integrationDefs];
|
||||
|
||||
export type IntegrationSecretKind = keyof typeof integrationSecretKindObject;
|
||||
export type IntegrationKind = keyof typeof integrationDefs;
|
||||
export type IntegrationCategory =
|
||||
@@ -225,4 +188,5 @@ export type IntegrationCategory =
|
||||
| "smartHomeServer"
|
||||
| "indexerManager"
|
||||
| "healthMonitoring"
|
||||
| "search"
|
||||
| "mediaTranscoding";
|
||||
|
||||
@@ -29,6 +29,10 @@ export abstract class Integration {
|
||||
return secret.value;
|
||||
}
|
||||
|
||||
protected hasSecretValue(kind: IntegrationSecretKind) {
|
||||
return this.integration.decryptedSecrets.some((secret) => secret.kind === kind);
|
||||
}
|
||||
|
||||
protected url(path: `/${string}`, queryParams?: Record<string, string | Date | number | boolean>) {
|
||||
const baseUrl = removeTrailingSlash(this.integration.url);
|
||||
const url = new URL(`${baseUrl}${path}`);
|
||||
|
||||
@@ -18,13 +18,13 @@ export class JellyfinIntegration extends Integration {
|
||||
});
|
||||
|
||||
public async testConnectionAsync(): Promise<void> {
|
||||
const api = this.getApi();
|
||||
const api = await this.getApiAsync();
|
||||
const systemApi = getSystemApi(api);
|
||||
await systemApi.getPingSystem();
|
||||
}
|
||||
|
||||
public async getCurrentSessionsAsync(): Promise<StreamSession[]> {
|
||||
const api = this.getApi();
|
||||
const api = await this.getApiAsync();
|
||||
const sessionApi = getSessionApi(api);
|
||||
const sessions = await sessionApi.getSessions();
|
||||
|
||||
@@ -59,8 +59,22 @@ export class JellyfinIntegration extends Integration {
|
||||
});
|
||||
}
|
||||
|
||||
private getApi() {
|
||||
const apiKey = this.getSecretValue("apiKey");
|
||||
return this.jellyfin.createApi(this.url("/").toString(), apiKey);
|
||||
/**
|
||||
* Constructs an ApiClient synchronously with an ApiKey or asynchronously
|
||||
* with a username and password.
|
||||
* @returns An instance of Api that has been authenticated
|
||||
*/
|
||||
private async getApiAsync() {
|
||||
if (this.hasSecretValue("apiKey")) {
|
||||
const apiKey = this.getSecretValue("apiKey");
|
||||
return this.jellyfin.createApi(this.url("/").toString(), apiKey);
|
||||
}
|
||||
|
||||
const apiClient = this.jellyfin.createApi(this.url("/").toString());
|
||||
// Authentication state is stored internally in the Api class, so now
|
||||
// requests that require authentication can be made normally.
|
||||
// see https://typescript-sdk.jellyfin.org/#usage
|
||||
await apiClient.authenticateUserByName(this.getSecretValue("username"), this.getSecretValue("password"));
|
||||
return apiClient;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,12 +7,17 @@ import { createDbInsertCollection } from "./common";
|
||||
|
||||
export const createIntegrationInsertCollection = (
|
||||
preparedIntegrations: PreparedIntegration[],
|
||||
encryptionToken: string | null,
|
||||
encryptionToken: string | null | undefined,
|
||||
) => {
|
||||
const insertCollection = createDbInsertCollection(["integrations", "integrationSecrets"]);
|
||||
|
||||
if (preparedIntegrations.length === 0) {
|
||||
return insertCollection;
|
||||
}
|
||||
|
||||
logger.info(`Preparing integrations for insert collection count=${preparedIntegrations.length}`);
|
||||
|
||||
if (encryptionToken === null) {
|
||||
if (encryptionToken === null || encryptionToken === undefined) {
|
||||
logger.debug("Skipping integration decryption due to missing token");
|
||||
return insertCollection;
|
||||
}
|
||||
|
||||
@@ -6,12 +6,19 @@ import { mapAndDecryptUsers } from "../../mappers/map-user";
|
||||
import type { OldmarrImportUser } from "../../user-schema";
|
||||
import { createDbInsertCollection } from "./common";
|
||||
|
||||
export const createUserInsertCollection = (importUsers: OldmarrImportUser[], encryptionToken: string | null) => {
|
||||
export const createUserInsertCollection = (
|
||||
importUsers: OldmarrImportUser[],
|
||||
encryptionToken: string | null | undefined,
|
||||
) => {
|
||||
const insertCollection = createDbInsertCollection(["users", "groups", "groupMembers", "groupPermissions"]);
|
||||
|
||||
if (importUsers.length === 0) {
|
||||
return insertCollection;
|
||||
}
|
||||
|
||||
logger.info(`Preparing users for insert collection count=${importUsers.length}`);
|
||||
|
||||
if (encryptionToken === null) {
|
||||
if (encryptionToken === null || encryptionToken === undefined) {
|
||||
logger.debug("Skipping user decryption due to missing token");
|
||||
return insertCollection;
|
||||
}
|
||||
|
||||
@@ -20,5 +20,5 @@ export const importInitialOldmarrInputSchema = zfd.formData({
|
||||
const map = boardSelectionMapSchema.parse(SuperJSON.parse(value));
|
||||
return map;
|
||||
}),
|
||||
token: zfd.text().nullable(),
|
||||
token: zfd.text().nullable().optional(),
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { decryptSecretWithKey } from "@homarr/common/server";
|
||||
|
||||
export const ensureValidTokenOrThrow = (checksum: string | undefined, encryptionToken: string | null) => {
|
||||
export const ensureValidTokenOrThrow = (checksum: string | undefined, encryptionToken: string | null | undefined) => {
|
||||
if (!encryptionToken || !checksum) return;
|
||||
|
||||
const [first, second] = checksum.split("\n");
|
||||
|
||||
@@ -81,13 +81,26 @@ export const moveWidgetsAndAppsIfMerge = (
|
||||
}
|
||||
|
||||
if (configuration.sidebarBehaviour === "last-section") {
|
||||
if (old.settings.customization.layout.enabledLeftSidebar) {
|
||||
const areas = [...old.apps.map((app) => app.area), ...old.widgets.map((widget) => widget.area)];
|
||||
if (
|
||||
old.settings.customization.layout.enabledLeftSidebar ||
|
||||
areas.some((area) => area.type === "sidebar" && area.properties.location === "left")
|
||||
) {
|
||||
offset = moveWidgetsAndAppsInLeftSidebar(old, firstId, offset, configuration.screenSize);
|
||||
}
|
||||
|
||||
if (old.settings.customization.layout.enabledRightSidebar) {
|
||||
if (
|
||||
old.settings.customization.layout.enabledRightSidebar ||
|
||||
areas.some((area) => area.type === "sidebar" && area.properties.location === "right")
|
||||
) {
|
||||
moveWidgetsAndAppsInRightSidebar(old, firstId, offset, configuration.screenSize);
|
||||
}
|
||||
} else {
|
||||
// Remove all widgets and apps in the sidebar
|
||||
return {
|
||||
apps: old.apps.filter((app) => app.area.type !== "sidebar"),
|
||||
widgets: old.widgets.filter((app) => app.area.type !== "sidebar"),
|
||||
};
|
||||
}
|
||||
|
||||
return { apps: old.apps, widgets: old.widgets };
|
||||
|
||||
@@ -69,7 +69,7 @@ export const oldmarrAppSchema = z
|
||||
behaviour: appBehaviourSchema,
|
||||
network: appNetworkSchema,
|
||||
appearance: appAppearanceSchema,
|
||||
integration: appIntegrationSchema.optional(),
|
||||
integration: appIntegrationSchema.optional().nullable(),
|
||||
})
|
||||
.and(tileBaseSchema);
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
"deepmerge": "4.3.1",
|
||||
"mantine-react-table": "2.0.0-beta.7",
|
||||
"next": "^14.2.20",
|
||||
"next-intl": "3.26.1",
|
||||
"next-intl": "3.26.2",
|
||||
"react": "^19.0.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
124
pnpm-lock.yaml
generated
124
pnpm-lock.yaml
generated
@@ -186,16 +186,16 @@ importers:
|
||||
version: 5.62.8(@tanstack/react-query@5.62.8(react@19.0.0))(next@14.2.20(@babel/core@7.26.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.83.0))(react@19.0.0)
|
||||
'@trpc/client':
|
||||
specifier: next
|
||||
version: 11.0.0-rc.660(@trpc/server@11.0.0-rc.660(typescript@5.7.2))(typescript@5.7.2)
|
||||
version: 11.0.0-rc.666(@trpc/server@11.0.0-rc.666(typescript@5.7.2))(typescript@5.7.2)
|
||||
'@trpc/next':
|
||||
specifier: next
|
||||
version: 11.0.0-rc.660(@tanstack/react-query@5.62.8(react@19.0.0))(@trpc/client@11.0.0-rc.660(@trpc/server@11.0.0-rc.660(typescript@5.7.2))(typescript@5.7.2))(@trpc/react-query@11.0.0-rc.660(@tanstack/react-query@5.62.8(react@19.0.0))(@trpc/client@11.0.0-rc.660(@trpc/server@11.0.0-rc.660(typescript@5.7.2))(typescript@5.7.2))(@trpc/server@11.0.0-rc.660(typescript@5.7.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.7.2))(@trpc/server@11.0.0-rc.660(typescript@5.7.2))(next@14.2.20(@babel/core@7.26.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.83.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.7.2)
|
||||
version: 11.0.0-rc.666(@tanstack/react-query@5.62.8(react@19.0.0))(@trpc/client@11.0.0-rc.666(@trpc/server@11.0.0-rc.666(typescript@5.7.2))(typescript@5.7.2))(@trpc/react-query@11.0.0-rc.666(@tanstack/react-query@5.62.8(react@19.0.0))(@trpc/client@11.0.0-rc.666(@trpc/server@11.0.0-rc.666(typescript@5.7.2))(typescript@5.7.2))(@trpc/server@11.0.0-rc.666(typescript@5.7.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.7.2))(@trpc/server@11.0.0-rc.666(typescript@5.7.2))(next@14.2.20(@babel/core@7.26.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.83.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.7.2)
|
||||
'@trpc/react-query':
|
||||
specifier: next
|
||||
version: 11.0.0-rc.660(@tanstack/react-query@5.62.8(react@19.0.0))(@trpc/client@11.0.0-rc.660(@trpc/server@11.0.0-rc.660(typescript@5.7.2))(typescript@5.7.2))(@trpc/server@11.0.0-rc.660(typescript@5.7.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.7.2)
|
||||
version: 11.0.0-rc.666(@tanstack/react-query@5.62.8(react@19.0.0))(@trpc/client@11.0.0-rc.666(@trpc/server@11.0.0-rc.666(typescript@5.7.2))(typescript@5.7.2))(@trpc/server@11.0.0-rc.666(typescript@5.7.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.7.2)
|
||||
'@trpc/server':
|
||||
specifier: next
|
||||
version: 11.0.0-rc.660(typescript@5.7.2)
|
||||
version: 11.0.0-rc.666(typescript@5.7.2)
|
||||
'@xterm/addon-canvas':
|
||||
specifier: ^0.7.0
|
||||
version: 0.7.0(@xterm/xterm@5.5.0)
|
||||
@@ -538,13 +538,13 @@ importers:
|
||||
version: link:../validation
|
||||
'@trpc/client':
|
||||
specifier: next
|
||||
version: 11.0.0-rc.660(@trpc/server@11.0.0-rc.660(typescript@5.7.2))(typescript@5.7.2)
|
||||
version: 11.0.0-rc.666(@trpc/server@11.0.0-rc.666(typescript@5.7.2))(typescript@5.7.2)
|
||||
'@trpc/react-query':
|
||||
specifier: next
|
||||
version: 11.0.0-rc.660(@tanstack/react-query@5.62.8(react@19.0.0))(@trpc/client@11.0.0-rc.660(@trpc/server@11.0.0-rc.660(typescript@5.7.2))(typescript@5.7.2))(@trpc/server@11.0.0-rc.660(typescript@5.7.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.7.2)
|
||||
version: 11.0.0-rc.666(@tanstack/react-query@5.62.8(react@19.0.0))(@trpc/client@11.0.0-rc.666(@trpc/server@11.0.0-rc.666(typescript@5.7.2))(typescript@5.7.2))(@trpc/server@11.0.0-rc.666(typescript@5.7.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.7.2)
|
||||
'@trpc/server':
|
||||
specifier: next
|
||||
version: 11.0.0-rc.660(typescript@5.7.2)
|
||||
version: 11.0.0-rc.666(typescript@5.7.2)
|
||||
dockerode:
|
||||
specifier: ^4.0.2
|
||||
version: 4.0.2
|
||||
@@ -559,7 +559,7 @@ importers:
|
||||
version: 2.2.2
|
||||
trpc-to-openapi:
|
||||
specifier: ^2.1.0
|
||||
version: 2.1.0(@trpc/server@11.0.0-rc.660(typescript@5.7.2))(zod-openapi@2.19.0(zod@3.24.1))(zod@3.24.1)
|
||||
version: 2.1.0(@trpc/server@11.0.0-rc.666(typescript@5.7.2))(zod-openapi@2.19.0(zod@3.24.1))(zod@3.24.1)
|
||||
devDependencies:
|
||||
'@homarr/eslint-config':
|
||||
specifier: workspace:^0.2.0
|
||||
@@ -616,8 +616,8 @@ importers:
|
||||
specifier: ^0.9.1
|
||||
version: 0.9.1
|
||||
ldapts:
|
||||
specifier: 7.2.2
|
||||
version: 7.2.2
|
||||
specifier: 7.3.0
|
||||
version: 7.3.0
|
||||
next:
|
||||
specifier: ^14.2.20
|
||||
version: 14.2.20(@babel/core@7.26.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.83.0)
|
||||
@@ -1569,8 +1569,8 @@ importers:
|
||||
specifier: ^14.2.20
|
||||
version: 14.2.20(@babel/core@7.26.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.83.0)
|
||||
next-intl:
|
||||
specifier: 3.26.1
|
||||
version: 3.26.1(next@14.2.20(@babel/core@7.26.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.83.0))(react@19.0.0)
|
||||
specifier: 3.26.2
|
||||
version: 3.26.2(next@14.2.20(@babel/core@7.26.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.83.0))(react@19.0.0)
|
||||
react:
|
||||
specifier: ^19.0.0
|
||||
version: 19.0.0
|
||||
@@ -3886,19 +3886,19 @@ packages:
|
||||
'@tootallnate/quickjs-emscripten@0.23.0':
|
||||
resolution: {integrity: sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==}
|
||||
|
||||
'@trpc/client@11.0.0-rc.660':
|
||||
resolution: {integrity: sha512-bNpkZEfyMGKHynYFxdLpY8nJ1n7E3JHKcd4Pe2cagmpkzOEF9tFT3kzNf+eLI8XMG8196lTRR0J0W2/1Q8/cug==}
|
||||
'@trpc/client@11.0.0-rc.666':
|
||||
resolution: {integrity: sha512-BP3H0bktY03m7haVT5QoPR4sn30DNJcvFHsA3Msj3uPRY8JLVE03MR4rVG6T7VbcglORKpyMlRxjpUgdRmJErA==}
|
||||
peerDependencies:
|
||||
'@trpc/server': 11.0.0-rc.660+74625d5e4
|
||||
'@trpc/server': 11.0.0-rc.666+99556c074
|
||||
typescript: '>=5.6.2'
|
||||
|
||||
'@trpc/next@11.0.0-rc.660':
|
||||
resolution: {integrity: sha512-LQHdiVED8h+CJEAy/X9PDmY3fM8VPdZ+3bVkbmEiP4xoNnSKRTbSbknFyRzG9M2AogfIafF4zAZVwOvCxexyGw==}
|
||||
'@trpc/next@11.0.0-rc.666':
|
||||
resolution: {integrity: sha512-EiNMEY0nValoxMSvC+j68evlQqU/NoLrZXskvHnheoyaDLP8TxhTA2xUr+P4tkWPkjsRzh/Y5lxlyAb2PTA7aw==}
|
||||
peerDependencies:
|
||||
'@tanstack/react-query': ^5.59.15
|
||||
'@trpc/client': 11.0.0-rc.660+74625d5e4
|
||||
'@trpc/react-query': 11.0.0-rc.660+74625d5e4
|
||||
'@trpc/server': 11.0.0-rc.660+74625d5e4
|
||||
'@trpc/client': 11.0.0-rc.666+99556c074
|
||||
'@trpc/react-query': 11.0.0-rc.666+99556c074
|
||||
'@trpc/server': 11.0.0-rc.666+99556c074
|
||||
next: '*'
|
||||
react: '>=16.8.0'
|
||||
react-dom: '>=16.8.0'
|
||||
@@ -3909,18 +3909,18 @@ packages:
|
||||
'@trpc/react-query':
|
||||
optional: true
|
||||
|
||||
'@trpc/react-query@11.0.0-rc.660':
|
||||
resolution: {integrity: sha512-U2BHtYVt+8jt0a8Nrrk5cep8O1UZRxtTCBHtXie9kmJyQWWml43KfHxL5ssnFywaFrDZQz6Ec7kIoOxR/CQNfg==}
|
||||
'@trpc/react-query@11.0.0-rc.666':
|
||||
resolution: {integrity: sha512-BH0vU7g5w4IrN7xmWSKvLucZ9ZnpRwsDWCSJ0R09xdYwR7geHkna3PBbd8vQVFBSw7MpWEy6LGXVSCHSbUicLg==}
|
||||
peerDependencies:
|
||||
'@tanstack/react-query': ^5.59.15
|
||||
'@trpc/client': 11.0.0-rc.660+74625d5e4
|
||||
'@trpc/server': 11.0.0-rc.660+74625d5e4
|
||||
'@tanstack/react-query': ^5.62.8
|
||||
'@trpc/client': 11.0.0-rc.666+99556c074
|
||||
'@trpc/server': 11.0.0-rc.666+99556c074
|
||||
react: '>=18.2.0'
|
||||
react-dom: '>=18.2.0'
|
||||
typescript: '>=5.6.2'
|
||||
|
||||
'@trpc/server@11.0.0-rc.660':
|
||||
resolution: {integrity: sha512-QUapcZCNOpHT7ng9LceGc9ImkboWd0Go9ryrduZpL+p4jdfaC6409AQ3x4XEW6Wu3yBmZAn4CywCsDrDhjDy/w==}
|
||||
'@trpc/server@11.0.0-rc.666':
|
||||
resolution: {integrity: sha512-k+jKrdH/owDRRXPR7oPKCQRTu0dOEnqdGh56863ym95sFY8qXE7BhOR8S4WqyZw1CiPZGjRkdFN0q/GsJhKsIA==}
|
||||
peerDependencies:
|
||||
typescript: '>=5.6.2'
|
||||
|
||||
@@ -5076,6 +5076,15 @@ packages:
|
||||
supports-color:
|
||||
optional: true
|
||||
|
||||
debug@4.4.0:
|
||||
resolution: {integrity: sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==}
|
||||
engines: {node: '>=6.0'}
|
||||
peerDependencies:
|
||||
supports-color: '*'
|
||||
peerDependenciesMeta:
|
||||
supports-color:
|
||||
optional: true
|
||||
|
||||
decimal.js@10.4.3:
|
||||
resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==}
|
||||
|
||||
@@ -6554,8 +6563,8 @@ packages:
|
||||
resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==}
|
||||
engines: {node: '>= 0.6.3'}
|
||||
|
||||
ldapts@7.2.2:
|
||||
resolution: {integrity: sha512-UotAq24/vJEz0m3w/jgwZm7JGNw8M6vexL/5KU5pe3aIZWBkT/HRhjsPw/buRqKSK5Y0vTu5Zv8iyPgQF7ozzg==}
|
||||
ldapts@7.3.0:
|
||||
resolution: {integrity: sha512-hj+cOy50uwu496x66IrqeY0WY35pMnkKrOgdYtZFu0uii4Xzw39Wng1hgzmGYWmzK9On4jYiiYyz1ZdVc857XA==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
levn@0.4.1:
|
||||
@@ -6930,8 +6939,8 @@ packages:
|
||||
nodemailer:
|
||||
optional: true
|
||||
|
||||
next-intl@3.26.1:
|
||||
resolution: {integrity: sha512-TE4cQgXNw4jzEtVPdiYQOCmhAu+Z2qoUppCMxPkJoz8XXe8TdqiNEPhD/GtXEsI80nV6NnVAq3hyTHH5+ex6Hw==}
|
||||
next-intl@3.26.2:
|
||||
resolution: {integrity: sha512-fPsL5/9Y/aYNHoOf904b+PhYkm1RfZKrNMAxUvURMqFuQTA0TQAIGnY0s03yPH7oRv9qCFcutaxr6DsHq0aCzQ==}
|
||||
peerDependencies:
|
||||
next: ^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0 || ^14.0.0 || ^15.0.0
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0
|
||||
@@ -8889,8 +8898,8 @@ packages:
|
||||
peerDependencies:
|
||||
react: '>=16.13'
|
||||
|
||||
use-intl@3.26.1:
|
||||
resolution: {integrity: sha512-MZhtSBcMrDna3xs1T6O7CAXx4wRfm1eGyUYrDCCnW9qTOGZurCH5k/X6ChDl6EI4f+qYEtXQCRMkQUVOIhJWTQ==}
|
||||
use-intl@3.26.2:
|
||||
resolution: {integrity: sha512-H0BpBXLNFTkw6RvntLXSXr2+la4T/xilKSG5l8ND9Br9+i1hqHensWouNS288QZdiDTrfYUVswDtUIR6L39JHQ==}
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || >=19.0.0-rc <19.0.0 || ^19.0.0
|
||||
|
||||
@@ -9096,6 +9105,10 @@ packages:
|
||||
resolution: {integrity: sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
whatwg-url@14.1.0:
|
||||
resolution: {integrity: sha512-jlf/foYIKywAt3x/XWKZ/3rz8OSJPiWktjmk891alJUEjiVxKX9LEO92qH3hv4aJ0mN3MWPvGMCy8jQi95xK4w==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
whatwg-url@5.0.0:
|
||||
resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
|
||||
|
||||
@@ -11335,33 +11348,33 @@ snapshots:
|
||||
|
||||
'@tootallnate/quickjs-emscripten@0.23.0': {}
|
||||
|
||||
'@trpc/client@11.0.0-rc.660(@trpc/server@11.0.0-rc.660(typescript@5.7.2))(typescript@5.7.2)':
|
||||
'@trpc/client@11.0.0-rc.666(@trpc/server@11.0.0-rc.666(typescript@5.7.2))(typescript@5.7.2)':
|
||||
dependencies:
|
||||
'@trpc/server': 11.0.0-rc.660(typescript@5.7.2)
|
||||
'@trpc/server': 11.0.0-rc.666(typescript@5.7.2)
|
||||
typescript: 5.7.2
|
||||
|
||||
'@trpc/next@11.0.0-rc.660(@tanstack/react-query@5.62.8(react@19.0.0))(@trpc/client@11.0.0-rc.660(@trpc/server@11.0.0-rc.660(typescript@5.7.2))(typescript@5.7.2))(@trpc/react-query@11.0.0-rc.660(@tanstack/react-query@5.62.8(react@19.0.0))(@trpc/client@11.0.0-rc.660(@trpc/server@11.0.0-rc.660(typescript@5.7.2))(typescript@5.7.2))(@trpc/server@11.0.0-rc.660(typescript@5.7.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.7.2))(@trpc/server@11.0.0-rc.660(typescript@5.7.2))(next@14.2.20(@babel/core@7.26.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.83.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.7.2)':
|
||||
'@trpc/next@11.0.0-rc.666(@tanstack/react-query@5.62.8(react@19.0.0))(@trpc/client@11.0.0-rc.666(@trpc/server@11.0.0-rc.666(typescript@5.7.2))(typescript@5.7.2))(@trpc/react-query@11.0.0-rc.666(@tanstack/react-query@5.62.8(react@19.0.0))(@trpc/client@11.0.0-rc.666(@trpc/server@11.0.0-rc.666(typescript@5.7.2))(typescript@5.7.2))(@trpc/server@11.0.0-rc.666(typescript@5.7.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.7.2))(@trpc/server@11.0.0-rc.666(typescript@5.7.2))(next@14.2.20(@babel/core@7.26.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.83.0))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.7.2)':
|
||||
dependencies:
|
||||
'@trpc/client': 11.0.0-rc.660(@trpc/server@11.0.0-rc.660(typescript@5.7.2))(typescript@5.7.2)
|
||||
'@trpc/server': 11.0.0-rc.660(typescript@5.7.2)
|
||||
'@trpc/client': 11.0.0-rc.666(@trpc/server@11.0.0-rc.666(typescript@5.7.2))(typescript@5.7.2)
|
||||
'@trpc/server': 11.0.0-rc.666(typescript@5.7.2)
|
||||
next: 14.2.20(@babel/core@7.26.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.83.0)
|
||||
react: 19.0.0
|
||||
react-dom: 19.0.0(react@19.0.0)
|
||||
typescript: 5.7.2
|
||||
optionalDependencies:
|
||||
'@tanstack/react-query': 5.62.8(react@19.0.0)
|
||||
'@trpc/react-query': 11.0.0-rc.660(@tanstack/react-query@5.62.8(react@19.0.0))(@trpc/client@11.0.0-rc.660(@trpc/server@11.0.0-rc.660(typescript@5.7.2))(typescript@5.7.2))(@trpc/server@11.0.0-rc.660(typescript@5.7.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.7.2)
|
||||
'@trpc/react-query': 11.0.0-rc.666(@tanstack/react-query@5.62.8(react@19.0.0))(@trpc/client@11.0.0-rc.666(@trpc/server@11.0.0-rc.666(typescript@5.7.2))(typescript@5.7.2))(@trpc/server@11.0.0-rc.666(typescript@5.7.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.7.2)
|
||||
|
||||
'@trpc/react-query@11.0.0-rc.660(@tanstack/react-query@5.62.8(react@19.0.0))(@trpc/client@11.0.0-rc.660(@trpc/server@11.0.0-rc.660(typescript@5.7.2))(typescript@5.7.2))(@trpc/server@11.0.0-rc.660(typescript@5.7.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.7.2)':
|
||||
'@trpc/react-query@11.0.0-rc.666(@tanstack/react-query@5.62.8(react@19.0.0))(@trpc/client@11.0.0-rc.666(@trpc/server@11.0.0-rc.666(typescript@5.7.2))(typescript@5.7.2))(@trpc/server@11.0.0-rc.666(typescript@5.7.2))(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(typescript@5.7.2)':
|
||||
dependencies:
|
||||
'@tanstack/react-query': 5.62.8(react@19.0.0)
|
||||
'@trpc/client': 11.0.0-rc.660(@trpc/server@11.0.0-rc.660(typescript@5.7.2))(typescript@5.7.2)
|
||||
'@trpc/server': 11.0.0-rc.660(typescript@5.7.2)
|
||||
'@trpc/client': 11.0.0-rc.666(@trpc/server@11.0.0-rc.666(typescript@5.7.2))(typescript@5.7.2)
|
||||
'@trpc/server': 11.0.0-rc.666(typescript@5.7.2)
|
||||
react: 19.0.0
|
||||
react-dom: 19.0.0(react@19.0.0)
|
||||
typescript: 5.7.2
|
||||
|
||||
'@trpc/server@11.0.0-rc.660(typescript@5.7.2)':
|
||||
'@trpc/server@11.0.0-rc.666(typescript@5.7.2)':
|
||||
dependencies:
|
||||
typescript: 5.7.2
|
||||
|
||||
@@ -12714,6 +12727,10 @@ snapshots:
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
|
||||
debug@4.4.0:
|
||||
dependencies:
|
||||
ms: 2.1.3
|
||||
|
||||
decimal.js@10.4.3: {}
|
||||
|
||||
decompress-response@6.0.0:
|
||||
@@ -14392,14 +14409,14 @@ snapshots:
|
||||
dependencies:
|
||||
readable-stream: 2.3.8
|
||||
|
||||
ldapts@7.2.2:
|
||||
ldapts@7.3.0:
|
||||
dependencies:
|
||||
'@types/asn1': 0.2.4
|
||||
asn1: 0.2.6
|
||||
debug: 4.3.7
|
||||
debug: 4.4.0
|
||||
strict-event-emitter-types: 2.0.0
|
||||
uuid: 11.0.3
|
||||
whatwg-url: 14.0.0
|
||||
whatwg-url: 14.1.0
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
@@ -14746,13 +14763,13 @@ snapshots:
|
||||
next: 14.2.20(@babel/core@7.26.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.83.0)
|
||||
react: 19.0.0
|
||||
|
||||
next-intl@3.26.1(next@14.2.20(@babel/core@7.26.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.83.0))(react@19.0.0):
|
||||
next-intl@3.26.2(next@14.2.20(@babel/core@7.26.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.83.0))(react@19.0.0):
|
||||
dependencies:
|
||||
'@formatjs/intl-localematcher': 0.5.5
|
||||
negotiator: 1.0.0
|
||||
next: 14.2.20(@babel/core@7.26.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.83.0)
|
||||
react: 19.0.0
|
||||
use-intl: 3.26.1(react@19.0.0)
|
||||
use-intl: 3.26.2(react@19.0.0)
|
||||
|
||||
next@14.2.20(@babel/core@7.26.0)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(sass@1.83.0):
|
||||
dependencies:
|
||||
@@ -16651,9 +16668,9 @@ snapshots:
|
||||
|
||||
triple-beam@1.4.1: {}
|
||||
|
||||
trpc-to-openapi@2.1.0(@trpc/server@11.0.0-rc.660(typescript@5.7.2))(zod-openapi@2.19.0(zod@3.24.1))(zod@3.24.1):
|
||||
trpc-to-openapi@2.1.0(@trpc/server@11.0.0-rc.666(typescript@5.7.2))(zod-openapi@2.19.0(zod@3.24.1))(zod@3.24.1):
|
||||
dependencies:
|
||||
'@trpc/server': 11.0.0-rc.660(typescript@5.7.2)
|
||||
'@trpc/server': 11.0.0-rc.666(typescript@5.7.2)
|
||||
co-body: 6.2.0
|
||||
h3: 1.13.0
|
||||
lodash.clonedeep: 4.5.0
|
||||
@@ -16959,7 +16976,7 @@ snapshots:
|
||||
dequal: 2.0.3
|
||||
react: 19.0.0
|
||||
|
||||
use-intl@3.26.1(react@19.0.0):
|
||||
use-intl@3.26.2(react@19.0.0):
|
||||
dependencies:
|
||||
'@formatjs/fast-memoize': 2.2.1
|
||||
intl-messageformat: 10.7.1
|
||||
@@ -17203,6 +17220,11 @@ snapshots:
|
||||
tr46: 5.0.0
|
||||
webidl-conversions: 7.0.0
|
||||
|
||||
whatwg-url@14.1.0:
|
||||
dependencies:
|
||||
tr46: 5.0.0
|
||||
webidl-conversions: 7.0.0
|
||||
|
||||
whatwg-url@5.0.0:
|
||||
dependencies:
|
||||
tr46: 0.0.3
|
||||
|
||||
10
scripts/entrypoint.sh
Normal file
10
scripts/entrypoint.sh
Normal file
@@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
set -e
|
||||
|
||||
# Creating folders in volume
|
||||
mkdir -p /appdata/db
|
||||
mkdir -p /appdata/redis
|
||||
|
||||
chown -R nextjs:nodejs /appdata
|
||||
|
||||
su-exec 1001:1001 "$@"
|
||||
@@ -1,7 +1,3 @@
|
||||
# Creating folders in volume
|
||||
mkdir -p /appdata/db
|
||||
mkdir -p /appdata/redis
|
||||
|
||||
# Run migrations
|
||||
if [ $DB_MIGRATIONS_DISABLED = "true" ]; then
|
||||
echo "DB migrations are disabled, skipping"
|
||||
|
||||
Reference in New Issue
Block a user