chore(release): automatic release v1.0.0

This commit is contained in:
homarr-releases[bot]
2024-12-18 13:15:07 +00:00
committed by GitHub
21 changed files with 187 additions and 169 deletions

View File

@@ -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

View File

@@ -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"]

View File

@@ -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>

View File

@@ -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> => {

View File

@@ -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));
}),
});

View File

@@ -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",

View File

@@ -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";

View File

@@ -1,2 +1,2 @@
export const everyoneGroup = "everyone";
export const credentialsAdminGroup = "admin";
export const credentialsAdminGroup = "credentials-admin";

View File

@@ -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";

View File

@@ -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}`);

View File

@@ -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;
}
}

View File

@@ -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;
}

View File

@@ -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;
}

View File

@@ -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(),
});

View File

@@ -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");

View File

@@ -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 };

View File

@@ -69,7 +69,7 @@ export const oldmarrAppSchema = z
behaviour: appBehaviourSchema,
network: appNetworkSchema,
appearance: appAppearanceSchema,
integration: appIntegrationSchema.optional(),
integration: appIntegrationSchema.optional().nullable(),
})
.and(tileBaseSchema);

View File

@@ -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
View File

@@ -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
View 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 "$@"

View File

@@ -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"