Compare commits
8
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
510c9b945d | ||
|
|
2405e1b931 | ||
|
|
41fe5928f1 | ||
|
|
6eb59d6f53 | ||
|
|
2c6b7a818e | ||
|
|
fd10788838 | ||
|
|
fe4598f722 | ||
|
|
a755692d81 |
No files matched your search
@@ -0,0 +1,2 @@
|
||||
-P ubuntu-latest=catthehacker/ubuntu:act-latest
|
||||
--container-architecture linux/amd64
|
||||
@@ -19,7 +19,10 @@ body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional information
|
||||
description: Add any other information related to the integration.
|
||||
description: |
|
||||
Add any other information related to the integration.
|
||||
|
||||
After your integration is merged to `dev`, a bot PR updates [CODEOWNERS](https://github.com/homarr-labs/homarr/blob/dev/CODEOWNERS) so you are requested on future PRs touching your folders. Run `pnpm scripts:generate-codeowners` locally for faster updates. Add email mappings in `scripts/codeowners-overrides.json` if the generator cannot resolve your GitHub user.
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Public API available?
|
||||
|
||||
@@ -19,7 +19,10 @@ body:
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional information
|
||||
description: Add any other information related to the widget.
|
||||
description: |
|
||||
Add any other information related to the widget.
|
||||
|
||||
After your widget is merged to `dev`, a bot PR updates [CODEOWNERS](https://github.com/homarr-labs/homarr/blob/dev/CODEOWNERS) so you are requested on future PRs touching your folders. Run `pnpm scripts:generate-codeowners` locally for faster updates. Add email mappings in `scripts/codeowners-overrides.json` if the generator cannot resolve your GitHub user.
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Are you willing to contribute this yourself?
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
name: Update CODEOWNERS
|
||||
|
||||
on:
|
||||
workflow_dispatch: {}
|
||||
pull_request:
|
||||
paths:
|
||||
- CODEOWNERS
|
||||
- packages/widgets/src/**
|
||||
- packages/integrations/src/**
|
||||
- packages/api/src/router/widgets/**
|
||||
- packages/cron-jobs/src/jobs/**
|
||||
- scripts/generate-codeowners.mts
|
||||
- scripts/validate-codeowners.mts
|
||||
- scripts/codeowners-overrides.json
|
||||
push:
|
||||
paths:
|
||||
- packages/widgets/src/**
|
||||
- packages/integrations/src/**
|
||||
- packages/api/src/router/widgets/**
|
||||
- packages/cron-jobs/src/jobs/**
|
||||
- scripts/generate-codeowners.mts
|
||||
- scripts/validate-codeowners.mts
|
||||
- scripts/codeowners-overrides.json
|
||||
branches:
|
||||
- dev
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
validate:
|
||||
name: Validate CODEOWNERS
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version-file: .nvmrc
|
||||
|
||||
- uses: pnpm/action-setup@v6
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Check CODEOWNERS is up to date
|
||||
run: pnpm exec tsx ./scripts/generate-codeowners.mts --check
|
||||
|
||||
- name: Validate CODEOWNERS
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
GITHUB_REPOSITORY: ${{ github.repository }}
|
||||
run: pnpm exec tsx ./scripts/validate-codeowners.mts
|
||||
|
||||
update:
|
||||
name: Open CODEOWNERS update PR
|
||||
needs: validate
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/dev'
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
concurrency:
|
||||
group: update-codeowners
|
||||
cancel-in-progress: false
|
||||
steps:
|
||||
- name: Obtain token
|
||||
id: obtainToken
|
||||
uses: actions/create-github-app-token@v3
|
||||
with:
|
||||
private-key: ${{ secrets.HOMARR_UPDATE_CONTRIBUTORS_PRIVATE_KEY }}
|
||||
client-id: ${{ vars.HOMARR_UPDATE_CONTRIBUTORS_APP_ID }}
|
||||
permission-contents: write
|
||||
permission-pull-requests: write
|
||||
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
fetch-depth: 0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ steps.obtainToken.outputs.token }}
|
||||
|
||||
- name: Use Node.js
|
||||
uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version-file: .nvmrc
|
||||
|
||||
- uses: pnpm/action-setup@v6
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install --frozen-lockfile
|
||||
|
||||
- name: Generate CODEOWNERS
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ steps.obtainToken.outputs.token }}
|
||||
run: pnpm scripts:generate-codeowners
|
||||
|
||||
- name: Validate CODEOWNERS
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ steps.obtainToken.outputs.token }}
|
||||
GITHUB_REPOSITORY: ${{ github.repository }}
|
||||
run: pnpm exec tsx ./scripts/validate-codeowners.mts
|
||||
|
||||
- name: Create Pull Request
|
||||
id: create-pull-request
|
||||
uses: peter-evans/create-pull-request@v8
|
||||
with:
|
||||
token: ${{ steps.obtainToken.outputs.token }}
|
||||
branch: update-codeowners
|
||||
base: dev
|
||||
title: "chore: update widget/integration CODEOWNERS"
|
||||
delete-branch: true
|
||||
commit-message: "chore: update widget/integration CODEOWNERS"
|
||||
body: |
|
||||
This PR updates per-widget and per-integration CODEOWNERS entries from git history.
|
||||
|
||||
Unmapped authors can be added in `scripts/codeowners-overrides.json`.
|
||||
|
||||
- name: Install GitHub CLI
|
||||
run: sudo apt-get install -y gh
|
||||
|
||||
- name: Enable auto-merge
|
||||
if: steps.create-pull-request.outputs.pull-request-number != ''
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ steps.obtainToken.outputs.token }}
|
||||
run: |
|
||||
gh pr merge ${{ steps.create-pull-request.outputs.pull-request-number }} --auto --squash
|
||||
+83
@@ -11,3 +11,86 @@ pnpm-lock.yaml
|
||||
pnpm-workspace.yaml
|
||||
Dockerfile
|
||||
docker-compose.yml
|
||||
|
||||
# BEGIN GENERATED widget/integration owners
|
||||
/packages/api/src/router/widgets/anchor-notes.ts /packages/integrations/src/anchor/ /packages/widgets/src/anchor-note/ @omariqbal
|
||||
/packages/api/src/router/widgets/app.ts /packages/widgets/src/app/ @manuel-rw
|
||||
/packages/api/src/router/widgets/calendar.ts /packages/widgets/src/calendar/ @manuel-rw
|
||||
/packages/api/src/router/widgets/coolify.ts /packages/integrations/src/coolify/ /packages/widgets/src/coolify/ @Rhiz3K
|
||||
/packages/api/src/router/widgets/dns-hole.ts /packages/cron-jobs/src/jobs/integrations/dns-hole.ts /packages/widgets/src/dns-hole/controls/ @manuel-rw
|
||||
/packages/api/src/router/widgets/dns-hole.ts /packages/cron-jobs/src/jobs/integrations/dns-hole.ts /packages/widgets/src/dns-hole/summary/ @manuel-rw
|
||||
/packages/api/src/router/widgets/downloads.ts /packages/cron-jobs/src/jobs/integrations/downloads.ts /packages/widgets/src/downloads/ @manuel-rw
|
||||
/packages/api/src/router/widgets/firewall.ts /packages/cron-jobs/src/jobs/integrations/firewall.ts /packages/widgets/src/firewall/ @Oupsman
|
||||
/packages/api/src/router/widgets/health-monitoring.ts /packages/cron-jobs/src/jobs/integrations/health-monitoring.ts /packages/widgets/src/health-monitoring/ @dgshue
|
||||
/packages/api/src/router/widgets/immich.ts /packages/integrations/src/immich/ /packages/widgets/src/immich/album-carousel/ @manuel-rw
|
||||
/packages/api/src/router/widgets/immich.ts /packages/integrations/src/immich/ /packages/widgets/src/immich/server-stats/ @manuel-rw
|
||||
/packages/api/src/router/widgets/indexer-manager.ts /packages/cron-jobs/src/jobs/integrations/indexer-manager.ts /packages/widgets/src/indexer-manager/ @manuel-rw
|
||||
/packages/api/src/router/widgets/media-release.ts /packages/widgets/src/media-releases/ @manuel-rw
|
||||
/packages/api/src/router/widgets/media-requests.ts /packages/cron-jobs/src/jobs/integrations/media-requests.ts /packages/widgets/src/media-requests/list/ @manuel-rw
|
||||
/packages/api/src/router/widgets/media-requests.ts /packages/cron-jobs/src/jobs/integrations/media-requests.ts /packages/widgets/src/media-requests/stats/ @manuel-rw
|
||||
/packages/api/src/router/widgets/media-server.ts /packages/cron-jobs/src/jobs/integrations/media-server.ts /packages/widgets/src/media-server/ @manuel-rw
|
||||
/packages/api/src/router/widgets/media-transcoding.ts /packages/cron-jobs/src/jobs/integrations/media-transcoding.ts /packages/integrations/src/media-transcoding/ /packages/widgets/src/media-transcoding/ @manuel-rw
|
||||
/packages/api/src/router/widgets/minecraft.ts /packages/widgets/src/minecraft/server-status/ @manuel-rw
|
||||
/packages/api/src/router/widgets/network-controller.ts /packages/cron-jobs/src/jobs/integrations/network-controller.ts /packages/widgets/src/network-controller/network-status/ @pitschi
|
||||
/packages/api/src/router/widgets/network-controller.ts /packages/cron-jobs/src/jobs/integrations/network-controller.ts /packages/widgets/src/network-controller/summary/ @pitschi
|
||||
/packages/api/src/router/widgets/notebook.ts /packages/widgets/src/notebook/ @manuel-rw
|
||||
/packages/api/src/router/widgets/notifications.ts /packages/cron-jobs/src/jobs/integrations/notifications.ts /packages/widgets/src/notifications/ @itzTheMeow
|
||||
/packages/api/src/router/widgets/releases.ts /packages/widgets/src/releases/ @Aandree5
|
||||
/packages/api/src/router/widgets/rssFeed.ts /packages/widgets/src/rssFeed/ @manuel-rw
|
||||
/packages/api/src/router/widgets/smart-home.ts /packages/cron-jobs/src/jobs/integrations/home-assistant.ts /packages/widgets/src/smart-home/entity-state/ @manuel-rw
|
||||
/packages/api/src/router/widgets/smart-home.ts /packages/cron-jobs/src/jobs/integrations/home-assistant.ts /packages/widgets/src/smart-home/execute-automation/ @manuel-rw
|
||||
/packages/api/src/router/widgets/speedtest-tracker.ts /packages/integrations/src/speedtest-tracker/ /packages/widgets/src/speedtest-tracker/ @kylegrieder
|
||||
/packages/api/src/router/widgets/stocks.ts /packages/widgets/src/stocks/ @jackwellerreal
|
||||
/packages/api/src/router/widgets/timetable.ts /packages/cron-jobs/src/jobs/integrations/timetable.ts /packages/widgets/src/timetable/ @manuel-rw
|
||||
/packages/api/src/router/widgets/tracearr.ts /packages/cron-jobs/src/jobs/integrations/tracearr.ts /packages/integrations/src/tracearr/ /packages/widgets/src/tracearr/ @StrandedTurtle
|
||||
/packages/api/src/router/widgets/umami.ts /packages/cron-jobs/src/jobs/integrations/umami.ts /packages/integrations/src/umami/ /packages/widgets/src/umami/ @febrile42
|
||||
/packages/api/src/router/widgets/weather.ts /packages/cron-jobs/src/jobs/weather.ts /packages/widgets/src/weather/ @manuel-rw
|
||||
/packages/cron-jobs/src/jobs/docker.ts /packages/widgets/src/docker/ @ashtonbatty
|
||||
/packages/cron-jobs/src/jobs/integrations/dns-hole.ts /packages/integrations/src/pi-hole/ @manuel-rw
|
||||
/packages/cron-jobs/src/jobs/integrations/downloads.ts /packages/integrations/src/download-client/aria2/ @manuel-rw
|
||||
/packages/cron-jobs/src/jobs/integrations/downloads.ts /packages/integrations/src/download-client/deluge/ @manuel-rw
|
||||
/packages/cron-jobs/src/jobs/integrations/downloads.ts /packages/integrations/src/download-client/nzbget/ @manuel-rw
|
||||
/packages/cron-jobs/src/jobs/integrations/downloads.ts /packages/integrations/src/download-client/qbittorrent/ @manuel-rw
|
||||
/packages/cron-jobs/src/jobs/integrations/downloads.ts /packages/integrations/src/download-client/sabnzbd/ @manuel-rw
|
||||
/packages/cron-jobs/src/jobs/integrations/downloads.ts /packages/integrations/src/download-client/slskd/ @manuel-rw
|
||||
/packages/cron-jobs/src/jobs/integrations/downloads.ts /packages/integrations/src/download-client/transmission/ @manuel-rw
|
||||
/packages/cron-jobs/src/jobs/integrations/home-assistant.ts /packages/integrations/src/homeassistant/ @manuel-rw
|
||||
/packages/cron-jobs/src/jobs/integrations/media-organizer.ts /packages/integrations/src/media-organizer/lidarr/ @NicolasNewman
|
||||
/packages/cron-jobs/src/jobs/integrations/media-organizer.ts /packages/integrations/src/media-organizer/radarr/ @manuel-rw
|
||||
/packages/cron-jobs/src/jobs/integrations/media-organizer.ts /packages/integrations/src/media-organizer/readarr/ @manuel-rw
|
||||
/packages/cron-jobs/src/jobs/integrations/media-organizer.ts /packages/integrations/src/media-organizer/sonarr/ @manuel-rw
|
||||
/packages/integrations/src/adguard-home/ @manuel-rw
|
||||
/packages/integrations/src/codeberg/ @Aandree5
|
||||
/packages/integrations/src/dashdot/ @dgshue
|
||||
/packages/integrations/src/docker-hub/ @Aandree5
|
||||
/packages/integrations/src/emby/ @manuel-rw
|
||||
/packages/integrations/src/github-container-registry/ @manuel-rw
|
||||
/packages/integrations/src/github/ @manuel-rw
|
||||
/packages/integrations/src/gitlab/ @Aandree5
|
||||
/packages/integrations/src/glances/ @dgshue
|
||||
/packages/integrations/src/ical/ @NicolasNewman
|
||||
/packages/integrations/src/jellyfin/ @manuel-rw
|
||||
/packages/integrations/src/jellyseerr/ @manuel-rw
|
||||
/packages/integrations/src/linuxserverio/ @Aandree5
|
||||
/packages/integrations/src/nextcloud/ @manuel-rw
|
||||
/packages/integrations/src/npm/ @Aandree5
|
||||
/packages/integrations/src/ntfy/ @manuel-rw
|
||||
/packages/integrations/src/openmediavault/ @dgshue
|
||||
/packages/integrations/src/opnsense/ @manuel-rw
|
||||
/packages/integrations/src/overseerr/ @manuel-rw
|
||||
/packages/integrations/src/plex/ @manuel-rw
|
||||
/packages/integrations/src/prowlarr/ @manuel-rw
|
||||
/packages/integrations/src/proxmox/ @manuel-rw
|
||||
/packages/integrations/src/quay/ @Aandree5
|
||||
/packages/integrations/src/search-ch/ @manuel-rw
|
||||
/packages/integrations/src/seerr/ @manuel-rw
|
||||
/packages/integrations/src/truenas/ @dgshue
|
||||
/packages/integrations/src/unifi-controller/ @manuel-rw
|
||||
/packages/integrations/src/unraid/ @dgshue
|
||||
/packages/widgets/src/bookmarks/ @manuel-rw
|
||||
/packages/widgets/src/clock/ @manuel-rw
|
||||
/packages/widgets/src/iframe/ @manuel-rw
|
||||
/packages/widgets/src/system-disks/ @manuel-rw
|
||||
/packages/widgets/src/system-resources/ @kylegrieder
|
||||
/packages/widgets/src/video/ @manuel-rw
|
||||
# END GENERATED widget/integration owners
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import type { PropsWithChildren } from "react";
|
||||
import type { MantineColorScheme, MantineColorSchemeManager } from "@mantine/core";
|
||||
import { DirectionProvider, MantineProvider } from "@mantine/core";
|
||||
import { DirectionProvider, MantineProvider, v8CssVariablesResolver } from "@mantine/core";
|
||||
import dayjs from "dayjs";
|
||||
|
||||
import { clientApi } from "@homarr/api/client";
|
||||
@@ -18,7 +18,12 @@ export const CustomMantineProvider = ({
|
||||
const manager = useColorSchemeManager();
|
||||
return (
|
||||
<DirectionProvider>
|
||||
<MantineProvider defaultColorScheme={defaultColorScheme} colorSchemeManager={manager} theme={theme}>
|
||||
<MantineProvider
|
||||
defaultColorScheme={defaultColorScheme}
|
||||
colorSchemeManager={manager}
|
||||
theme={theme}
|
||||
cssVariablesResolver={v8CssVariablesResolver}
|
||||
>
|
||||
{children}
|
||||
</MantineProvider>
|
||||
</DirectionProvider>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
import type { PropsWithChildren } from "react";
|
||||
import type { MantineColorsTuple } from "@mantine/core";
|
||||
import { colorsTuple, createTheme, darken, lighten, MantineProvider, rem } from "@mantine/core";
|
||||
import { colorsTuple, createTheme, darken, lighten, MantineProvider, rem, v8CssVariablesResolver } from "@mantine/core";
|
||||
|
||||
import { useRequiredBoard } from "@homarr/boards/context";
|
||||
import type { ColorScheme } from "@homarr/definitions";
|
||||
@@ -33,7 +33,12 @@ export const BoardMantineProvider = ({
|
||||
});
|
||||
|
||||
return (
|
||||
<MantineProvider defaultColorScheme={defaultColorScheme} theme={theme} colorSchemeManager={colorSchemeManager}>
|
||||
<MantineProvider
|
||||
defaultColorScheme={defaultColorScheme}
|
||||
theme={theme}
|
||||
colorSchemeManager={colorSchemeManager}
|
||||
cssVariablesResolver={v8CssVariablesResolver}
|
||||
>
|
||||
{children}
|
||||
</MantineProvider>
|
||||
);
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
"use client";
|
||||
|
||||
import { Button, PasswordInput, Stack, TextInput } from "@mantine/core";
|
||||
import { Button, Stack, TextInput } from "@mantine/core";
|
||||
import type { z } from "zod/v4";
|
||||
|
||||
import { clientApi } from "@homarr/api/client";
|
||||
import { signIn } from "@homarr/auth/client";
|
||||
import { revalidatePathActionAsync } from "@homarr/common/client";
|
||||
import { useZodForm } from "@homarr/form";
|
||||
import { UserCreatePasswordFields } from "@homarr/forms-collection";
|
||||
import { showErrorNotification, showSuccessNotification } from "@homarr/notifications";
|
||||
import { useScopedI18n } from "@homarr/translation/client";
|
||||
import { CustomPasswordInput } from "@homarr/ui";
|
||||
import { userInitSchema } from "@homarr/validation/user";
|
||||
|
||||
export const InitUserForm = () => {
|
||||
@@ -59,12 +59,10 @@ export const InitUserForm = () => {
|
||||
>
|
||||
<Stack gap="lg">
|
||||
<TextInput label={t("field.username.label")} {...form.getInputProps("username")} />
|
||||
<CustomPasswordInput
|
||||
withPasswordRequirements
|
||||
label={t("field.password.label")}
|
||||
{...form.getInputProps("password")}
|
||||
<UserCreatePasswordFields
|
||||
passwordInputProps={form.getInputProps("password")}
|
||||
confirmPasswordInputProps={form.getInputProps("confirmPassword")}
|
||||
/>
|
||||
<PasswordInput label={t("field.passwordConfirm.label")} {...form.getInputProps("confirmPassword")} />
|
||||
<Button type="submit" fullWidth loading={isPending}>
|
||||
{t("action.create")}
|
||||
</Button>
|
||||
|
||||
@@ -107,6 +107,23 @@ export function DockerTable(initialData: RouterOutputs["docker"]["getContainers"
|
||||
refetchOnReconnect: false,
|
||||
});
|
||||
const relativeTime = useTimeAgo(data.timestamp);
|
||||
const utils = clientApi.useUtils();
|
||||
const { mutate, isPending } = clientApi.docker.invalidate.useMutation({
|
||||
async onSuccess() {
|
||||
await utils.docker.getContainers.invalidate();
|
||||
showSuccessNotification({
|
||||
title: tDocker("action.refresh.notification.success.title"),
|
||||
message: tDocker("action.refresh.notification.success.message"),
|
||||
});
|
||||
},
|
||||
onError() {
|
||||
showErrorNotification({
|
||||
title: tDocker("action.refresh.notification.error.title"),
|
||||
message: tDocker("action.refresh.notification.error.message"),
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
const table = useTranslatedMantineReactTable({
|
||||
data: data.containers,
|
||||
enableDensityToggle: false,
|
||||
@@ -125,35 +142,11 @@ export function DockerTable(initialData: RouterOutputs["docker"]["getContainers"
|
||||
},
|
||||
|
||||
initialState: { density: "xs", showGlobalFilter: true },
|
||||
renderTopToolbarCustomActions: () => {
|
||||
const utils = clientApi.useUtils();
|
||||
const { mutate, isPending } = clientApi.docker.invalidate.useMutation({
|
||||
async onSuccess() {
|
||||
await utils.docker.getContainers.invalidate();
|
||||
showSuccessNotification({
|
||||
title: tDocker("action.refresh.notification.success.title"),
|
||||
message: tDocker("action.refresh.notification.success.message"),
|
||||
});
|
||||
},
|
||||
onError() {
|
||||
showErrorNotification({
|
||||
title: tDocker("action.refresh.notification.error.title"),
|
||||
message: tDocker("action.refresh.notification.error.message"),
|
||||
});
|
||||
},
|
||||
});
|
||||
|
||||
return (
|
||||
<Button
|
||||
variant="default"
|
||||
rightSection={<IconRefresh size="1rem" />}
|
||||
onClick={() => mutate()}
|
||||
loading={isPending}
|
||||
>
|
||||
{tDocker("action.refresh.label")}
|
||||
</Button>
|
||||
);
|
||||
},
|
||||
renderTopToolbarCustomActions: () => (
|
||||
<Button variant="default" rightSection={<IconRefresh size="1rem" />} onClick={() => mutate()} loading={isPending}>
|
||||
{tDocker("action.refresh.label")}
|
||||
</Button>
|
||||
),
|
||||
renderToolbarAlertBannerContent: ({ groupedAlert, table }) => {
|
||||
const dockerContainers = table.getSelectedRowModel().rows.map((row) => row.original);
|
||||
return (
|
||||
|
||||
+6
-26
@@ -1,20 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { startTransition, useCallback, useState } from "react";
|
||||
import {
|
||||
Badge,
|
||||
Button,
|
||||
Card,
|
||||
Group,
|
||||
PasswordInput,
|
||||
Stack,
|
||||
Stepper,
|
||||
Table,
|
||||
Text,
|
||||
TextInput,
|
||||
Title,
|
||||
Tooltip,
|
||||
} from "@mantine/core";
|
||||
import { Badge, Button, Card, Group, Stack, Stepper, Table, Text, TextInput, Title, Tooltip } from "@mantine/core";
|
||||
import { useListState } from "@mantine/hooks";
|
||||
import { IconPlus, IconUserCheck } from "@tabler/icons-react";
|
||||
import { z } from "zod/v4";
|
||||
@@ -24,10 +11,11 @@ import type { GroupPermissionKey } from "@homarr/definitions";
|
||||
import { everyoneGroup, groupPermissions } from "@homarr/definitions";
|
||||
import type { IsValid } from "@homarr/form";
|
||||
import { useZodForm } from "@homarr/form";
|
||||
import { UserCreatePasswordFields } from "@homarr/forms-collection";
|
||||
import { useModalAction } from "@homarr/modals";
|
||||
import { showErrorNotification } from "@homarr/notifications";
|
||||
import { useI18n, useScopedI18n } from "@homarr/translation/client";
|
||||
import { CustomPasswordInput, UserAvatar } from "@homarr/ui";
|
||||
import { UserAvatar } from "@homarr/ui";
|
||||
import { createCustomErrorParams } from "@homarr/validation/form/i18n";
|
||||
import { userPasswordSchema } from "@homarr/validation/user";
|
||||
|
||||
@@ -167,18 +155,10 @@ export const UserCreateStepperComponent = ({ initialGroups }: UserCreateStepperC
|
||||
<form>
|
||||
<Card p="xl">
|
||||
<Stack gap="md">
|
||||
<CustomPasswordInput
|
||||
withPasswordRequirements
|
||||
label={tUserField("password.label")}
|
||||
<UserCreatePasswordFields
|
||||
variant="filled"
|
||||
withAsterisk
|
||||
{...securityForm.getInputProps("password")}
|
||||
/>
|
||||
<PasswordInput
|
||||
label={tUserField("passwordConfirm.label")}
|
||||
variant="filled"
|
||||
withAsterisk
|
||||
{...securityForm.getInputProps("confirmPassword")}
|
||||
passwordInputProps={securityForm.getInputProps("password")}
|
||||
confirmPasswordInputProps={securityForm.getInputProps("confirmPassword")}
|
||||
/>
|
||||
</Stack>
|
||||
</Card>
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
"release": "semantic-release",
|
||||
"scripts:update-bug-report-template": "tsx ./scripts/update-bug-report-template.mts",
|
||||
"scripts:update-readme-integrations": "tsx ./scripts/update-integration-list.mts",
|
||||
"scripts:generate-codeowners": "tsx ./scripts/generate-codeowners.mts",
|
||||
"scripts:validate-codeowners": "tsx ./scripts/validate-codeowners.mts",
|
||||
"start": "concurrently \"pnpm with-env node apps/tasks/tasks.cjs\" \"pnpm with-env node apps/websocket/wssServer.cjs\" \"pnpm -F nextjs start\"",
|
||||
"test": "cross-env NODE_ENV=development CI=true vitest run --exclude e2e --coverage.enabled ",
|
||||
"test:e2e": "cross-env NODE_ENV=development CI=true vitest e2e",
|
||||
|
||||
@@ -81,13 +81,7 @@ describe("initUser should initialize the first user", () => {
|
||||
await expect(actAsync()).rejects.toThrow("passwordsDoNotMatch");
|
||||
});
|
||||
|
||||
it.each([
|
||||
["aB2%"], // too short
|
||||
["abc123DEF"], // does not contain special characters
|
||||
["abcDEFghi+"], // does not contain numbers
|
||||
["ABC123+/-"], // does not contain lowercase
|
||||
["abc123+/-"], // does not contain uppercase
|
||||
])("should throw error that password requirements do not match for '%s' as password", async (password) => {
|
||||
it.each([["aB2%"], ["short"]])("should reject passwords shorter than 8 characters for '%s'", async (password) => {
|
||||
const db = createDb();
|
||||
await createOnboardingStepAsync(db, "user");
|
||||
const caller = userRouter.createCaller({
|
||||
@@ -103,7 +97,55 @@ describe("initUser should initialize the first user", () => {
|
||||
confirmPassword: password,
|
||||
});
|
||||
|
||||
await expect(actAsync()).rejects.toThrow("passwordRequirements");
|
||||
await expect(actAsync()).rejects.toThrow();
|
||||
});
|
||||
|
||||
it("should accept passwords without complexity requirements", async () => {
|
||||
const db = createDb();
|
||||
await createOnboardingStepAsync(db, "user");
|
||||
const caller = userRouter.createCaller({
|
||||
db,
|
||||
deviceType: undefined,
|
||||
session: null,
|
||||
});
|
||||
|
||||
await caller.initUser({
|
||||
username: "test",
|
||||
password: "abc123DEF",
|
||||
confirmPassword: "abc123DEF",
|
||||
});
|
||||
|
||||
const user = await db.query.users.findFirst({
|
||||
columns: {
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
|
||||
expect(user).toBeDefined();
|
||||
});
|
||||
|
||||
it("should accept passwords with special characters like LoveHomarr<3", async () => {
|
||||
const db = createDb();
|
||||
await createOnboardingStepAsync(db, "user");
|
||||
const caller = userRouter.createCaller({
|
||||
db,
|
||||
deviceType: undefined,
|
||||
session: null,
|
||||
});
|
||||
|
||||
await caller.initUser({
|
||||
username: "test",
|
||||
password: "LoveHomarr<3",
|
||||
confirmPassword: "LoveHomarr<3",
|
||||
});
|
||||
|
||||
const user = await db.query.users.findFirst({
|
||||
columns: {
|
||||
id: true,
|
||||
},
|
||||
});
|
||||
|
||||
expect(user).toBeDefined();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -5,3 +5,5 @@ export * from "./icon-picker/icon-picker";
|
||||
export * from "./new-app/icon-matcher";
|
||||
|
||||
export * from "./upload-media/upload-media";
|
||||
|
||||
export * from "./user-create/user-create-password-fields";
|
||||
@@ -0,0 +1,33 @@
|
||||
"use client";
|
||||
|
||||
import { PasswordInput, Stack } from "@mantine/core";
|
||||
import type { PasswordInputProps } from "@mantine/core";
|
||||
|
||||
import { useScopedI18n } from "@homarr/translation/client";
|
||||
import { CustomPasswordInput } from "@homarr/ui";
|
||||
|
||||
interface UserCreatePasswordFieldsProps {
|
||||
passwordInputProps: PasswordInputProps;
|
||||
confirmPasswordInputProps: PasswordInputProps;
|
||||
variant?: PasswordInputProps["variant"];
|
||||
}
|
||||
|
||||
export const UserCreatePasswordFields = ({
|
||||
passwordInputProps,
|
||||
confirmPasswordInputProps,
|
||||
variant,
|
||||
}: UserCreatePasswordFieldsProps) => {
|
||||
const t = useScopedI18n("user.field");
|
||||
|
||||
return (
|
||||
<Stack gap="md">
|
||||
<CustomPasswordInput
|
||||
withPasswordRequirements
|
||||
label={t("password.label")}
|
||||
variant={variant}
|
||||
{...passwordInputProps}
|
||||
/>
|
||||
<PasswordInput label={t("passwordConfirm.label")} variant={variant} {...confirmPasswordInputProps} />
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
@@ -132,7 +132,7 @@
|
||||
},
|
||||
"password": {
|
||||
"label": "Contrasenya",
|
||||
"requirement": {
|
||||
"suggestion": {
|
||||
"length": "Inclou com a mínim 8 caràcters",
|
||||
"lowercase": "Inclou minúscules",
|
||||
"uppercase": "Inclou majúscules",
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
},
|
||||
"password": {
|
||||
"label": "密码",
|
||||
"requirement": {
|
||||
"suggestion": {
|
||||
"length": "至少包含 8 个字符",
|
||||
"lowercase": "包含小写字母",
|
||||
"uppercase": "包含大写字母",
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
},
|
||||
"password": {
|
||||
"label": "crwdns26:0crwdne26:0",
|
||||
"requirement": {
|
||||
"suggestion": {
|
||||
"length": "crwdns28:0crwdne28:0",
|
||||
"lowercase": "crwdns30:0crwdne30:0",
|
||||
"uppercase": "crwdns32:0crwdne32:0",
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
},
|
||||
"password": {
|
||||
"label": "Heslo",
|
||||
"requirement": {
|
||||
"suggestion": {
|
||||
"length": "Obsahuje alespoň 8 znaků",
|
||||
"lowercase": "Obsahuje malé písmeno",
|
||||
"uppercase": "Obsahuje velké písmeno",
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
},
|
||||
"password": {
|
||||
"label": "Adgangskode",
|
||||
"requirement": {
|
||||
"suggestion": {
|
||||
"length": "Inkluderer mindst 8 tegn",
|
||||
"lowercase": "Inkluderer små bogstaver",
|
||||
"uppercase": "Inkluderer store bogstaver",
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
},
|
||||
"password": {
|
||||
"label": "Passwort",
|
||||
"requirement": {
|
||||
"suggestion": {
|
||||
"length": "Enthält mindestens 8 Zeichen",
|
||||
"lowercase": "Enthält Kleinbuchstaben",
|
||||
"uppercase": "Enthält Großbuchstaben",
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
},
|
||||
"password": {
|
||||
"label": "Passwort",
|
||||
"requirement": {
|
||||
"suggestion": {
|
||||
"length": "Enthält mindestens 8 Zeichen",
|
||||
"lowercase": "Enthält Kleinbuchstaben",
|
||||
"uppercase": "Enthält Großbuchstaben",
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
},
|
||||
"password": {
|
||||
"label": "Κωδικός",
|
||||
"requirement": {
|
||||
"suggestion": {
|
||||
"length": "",
|
||||
"lowercase": "Περιλαμβάνει πεζό γράμμα",
|
||||
"uppercase": "Περιλαμβάνει κεφαλαίο γράμμα",
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
},
|
||||
"password": {
|
||||
"label": "Password",
|
||||
"requirement": {
|
||||
"suggestion": {
|
||||
"length": "Includes a minimum of 8 characters",
|
||||
"lowercase": "Includes a lower-case letter",
|
||||
"uppercase": "Includes an upper-case letter",
|
||||
|
||||
@@ -132,8 +132,9 @@
|
||||
},
|
||||
"password": {
|
||||
"label": "Password",
|
||||
"requirement": {
|
||||
"length": "Includes at least 8 characters",
|
||||
"suggestionsTitle": "Password suggestions",
|
||||
"suggestion": {
|
||||
"length": "At least 8 characters",
|
||||
"lowercase": "Includes lowercase letter",
|
||||
"uppercase": "Includes uppercase letter",
|
||||
"number": "Includes number",
|
||||
@@ -1405,6 +1406,9 @@
|
||||
"openNewTab": {
|
||||
"label": "Open in new tab"
|
||||
},
|
||||
"withBorder": {
|
||||
"label": "Show border"
|
||||
},
|
||||
"items": {
|
||||
"label": "Bookmarks",
|
||||
"add": "Add bookmark"
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
},
|
||||
"password": {
|
||||
"label": "Contraseña",
|
||||
"requirement": {
|
||||
"suggestion": {
|
||||
"length": "Incluye al menos 8 caracteres",
|
||||
"lowercase": "Incluye al menos una letra minúscula",
|
||||
"uppercase": "Incluye al menos una letra mayúscula",
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
},
|
||||
"password": {
|
||||
"label": "",
|
||||
"requirement": {
|
||||
"suggestion": {
|
||||
"length": "",
|
||||
"lowercase": "",
|
||||
"uppercase": "",
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
},
|
||||
"password": {
|
||||
"label": "Mot de passe",
|
||||
"requirement": {
|
||||
"suggestion": {
|
||||
"length": "Contient au moins 8 caractères",
|
||||
"lowercase": "Inclut une lettre minuscule",
|
||||
"uppercase": "Inclut une lettre majuscule",
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
},
|
||||
"password": {
|
||||
"label": "סיסמה",
|
||||
"requirement": {
|
||||
"suggestion": {
|
||||
"length": "כולל לפחות 8 תווים",
|
||||
"lowercase": "אפשר אותיות קטנות",
|
||||
"uppercase": "אפשר אותיות גדולות",
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
},
|
||||
"password": {
|
||||
"label": "Lozinka",
|
||||
"requirement": {
|
||||
"suggestion": {
|
||||
"length": "",
|
||||
"lowercase": "Uključuje mala slova",
|
||||
"uppercase": "Uključuje veliko slovo",
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
},
|
||||
"password": {
|
||||
"label": "Jelszó",
|
||||
"requirement": {
|
||||
"suggestion": {
|
||||
"length": "Tartalmazzon legalább 8 karaktert",
|
||||
"lowercase": "Tartalmazzon kisbetűt",
|
||||
"uppercase": "Tartalmazzon nagybetűt",
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
},
|
||||
"password": {
|
||||
"label": "Password",
|
||||
"requirement": {
|
||||
"suggestion": {
|
||||
"length": "Include almeno 8 caratteri",
|
||||
"lowercase": "Include lettera minuscola",
|
||||
"uppercase": "Include lettera maiuscola",
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
},
|
||||
"password": {
|
||||
"label": "パスワード",
|
||||
"requirement": {
|
||||
"suggestion": {
|
||||
"length": "少なくとも 8 文字以上を含む",
|
||||
"lowercase": "小文字を含む",
|
||||
"uppercase": "大文字を含む",
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
},
|
||||
"password": {
|
||||
"label": "비밀번호",
|
||||
"requirement": {
|
||||
"suggestion": {
|
||||
"length": "",
|
||||
"lowercase": "소문자 포함",
|
||||
"uppercase": "대문자 포함",
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
},
|
||||
"password": {
|
||||
"label": "Slaptažodis",
|
||||
"requirement": {
|
||||
"suggestion": {
|
||||
"length": "",
|
||||
"lowercase": "",
|
||||
"uppercase": "",
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
},
|
||||
"password": {
|
||||
"label": "Parole",
|
||||
"requirement": {
|
||||
"suggestion": {
|
||||
"length": "",
|
||||
"lowercase": "Ietver mazo burtu",
|
||||
"uppercase": "Ietver lielo burtu",
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
},
|
||||
"password": {
|
||||
"label": "Wachtwoord",
|
||||
"requirement": {
|
||||
"suggestion": {
|
||||
"length": "Bevat ten minste 8 tekens",
|
||||
"lowercase": "Inclusief kleine letter",
|
||||
"uppercase": "Inclusief hoofdletter",
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
},
|
||||
"password": {
|
||||
"label": "Passord",
|
||||
"requirement": {
|
||||
"suggestion": {
|
||||
"length": "Inkluderer minst 8 tegn",
|
||||
"lowercase": "Inkluderer liten bokstav",
|
||||
"uppercase": "Inkluderer stor bokstav",
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
},
|
||||
"password": {
|
||||
"label": "Hasło",
|
||||
"requirement": {
|
||||
"suggestion": {
|
||||
"length": "Zawiera co najmniej 8 znaków",
|
||||
"lowercase": "Zawiera małą literę",
|
||||
"uppercase": "Zawiera wielką literę",
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
},
|
||||
"password": {
|
||||
"label": "Senha",
|
||||
"requirement": {
|
||||
"suggestion": {
|
||||
"length": "Inclua pelo menos 8 caracteres",
|
||||
"lowercase": "Inclui letras minúsculas",
|
||||
"uppercase": "Inclui letras maiúsculas",
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
},
|
||||
"password": {
|
||||
"label": "",
|
||||
"requirement": {
|
||||
"suggestion": {
|
||||
"length": "",
|
||||
"lowercase": "",
|
||||
"uppercase": "",
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
},
|
||||
"password": {
|
||||
"label": "Parola",
|
||||
"requirement": {
|
||||
"suggestion": {
|
||||
"length": "",
|
||||
"lowercase": "Să includă litere mici",
|
||||
"uppercase": "Să includă litere mari",
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
},
|
||||
"password": {
|
||||
"label": "Пароль",
|
||||
"requirement": {
|
||||
"suggestion": {
|
||||
"length": "Содержит не менее 8 символов",
|
||||
"lowercase": "Содержит строчную букву",
|
||||
"uppercase": "Содержит заглавную букву",
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
},
|
||||
"password": {
|
||||
"label": "Heslo",
|
||||
"requirement": {
|
||||
"suggestion": {
|
||||
"length": "Obsahuje aspoň 8 znakov",
|
||||
"lowercase": "Zahŕňa malé písmeno",
|
||||
"uppercase": "Zahŕňa veľké písmená",
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
},
|
||||
"password": {
|
||||
"label": "Geslo",
|
||||
"requirement": {
|
||||
"suggestion": {
|
||||
"length": "",
|
||||
"lowercase": "Vključuje male črke",
|
||||
"uppercase": "Vključuje velike tiskane črke",
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
},
|
||||
"password": {
|
||||
"label": "Lösenord",
|
||||
"requirement": {
|
||||
"suggestion": {
|
||||
"length": "Använd minst 8 tecken",
|
||||
"lowercase": "Använd liten bokstav",
|
||||
"uppercase": "Använd stor bokstav",
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
},
|
||||
"password": {
|
||||
"label": "Şifre",
|
||||
"requirement": {
|
||||
"suggestion": {
|
||||
"length": "En az 8 karakter içermeli",
|
||||
"lowercase": "Küçük harf içermeli",
|
||||
"uppercase": "Büyük harf içermeli",
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
},
|
||||
"password": {
|
||||
"label": "Пароль",
|
||||
"requirement": {
|
||||
"suggestion": {
|
||||
"length": "Включає принаймні 8 символів",
|
||||
"lowercase": "Включає малу літеру",
|
||||
"uppercase": "Включає велику літеру",
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
},
|
||||
"password": {
|
||||
"label": "Mật khẩu",
|
||||
"requirement": {
|
||||
"suggestion": {
|
||||
"length": "Bao gồm ít nhất 8 kí tự",
|
||||
"lowercase": "Bao gồm chữ thường",
|
||||
"uppercase": "Bao gồm chữ in hoa",
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
},
|
||||
"password": {
|
||||
"label": "密碼",
|
||||
"requirement": {
|
||||
"suggestion": {
|
||||
"length": "至少包含 8 個字符",
|
||||
"lowercase": "包含小寫字母",
|
||||
"uppercase": "包含大寫字母",
|
||||
|
||||
@@ -20,15 +20,15 @@ export const CustomPasswordInput = ({ withPasswordRequirements, ...props }: Cust
|
||||
};
|
||||
|
||||
const WithPasswordRequirements = (props: PasswordInputProps) => {
|
||||
const [value, setValue] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
|
||||
const onChange = (event: ChangeEvent<HTMLInputElement>) => {
|
||||
setValue(event.currentTarget.value);
|
||||
setPassword(event.currentTarget.value);
|
||||
props.onChange?.(event);
|
||||
};
|
||||
|
||||
return (
|
||||
<PasswordRequirementsPopover password={value}>
|
||||
<PasswordRequirementsPopover password={password}>
|
||||
<PasswordInput {...props} onChange={onChange} />
|
||||
</PasswordRequirementsPopover>
|
||||
);
|
||||
|
||||
@@ -1,14 +1,19 @@
|
||||
import { rem, Text } from "@mantine/core";
|
||||
import { IconCheck, IconX } from "@tabler/icons-react";
|
||||
import { IconCheck, IconPoint } from "@tabler/icons-react";
|
||||
|
||||
const getRequirementDisplay = (meets: boolean) =>
|
||||
({
|
||||
true: { color: "teal", Icon: IconCheck },
|
||||
false: { color: "dimmed", Icon: IconPoint },
|
||||
})[String(meets) as "true" | "false"];
|
||||
|
||||
export function PasswordRequirement({ meets, label }: { meets: boolean; label: string }) {
|
||||
const display = getRequirementDisplay(meets);
|
||||
const Icon = display.Icon;
|
||||
|
||||
return (
|
||||
<Text c={meets ? "teal" : "red"} display="flex" style={{ alignItems: "center" }} size="sm">
|
||||
{meets ? (
|
||||
<IconCheck style={{ width: rem(14), height: rem(14) }} />
|
||||
) : (
|
||||
<IconX style={{ width: rem(14), height: rem(14) }} />
|
||||
)}
|
||||
<Text c={display.color} display="flex" style={{ alignItems: "center" }} size="sm">
|
||||
<Icon style={{ width: rem(14), height: rem(14) }} />
|
||||
<Text span ml={10}>
|
||||
{label}
|
||||
</Text>
|
||||
|
||||
@@ -1,16 +1,24 @@
|
||||
import type { PropsWithChildren } from "react";
|
||||
import { useState } from "react";
|
||||
import { Popover, Progress } from "@mantine/core";
|
||||
import { Popover, Progress, Text } from "@mantine/core";
|
||||
|
||||
import { useScopedI18n } from "@homarr/translation/client";
|
||||
import { passwordRequirements } from "@homarr/validation/user";
|
||||
|
||||
import { PasswordRequirement } from "./password-requirement";
|
||||
|
||||
const strengthColorMap = [
|
||||
{ min: 100, color: "teal" },
|
||||
{ min: 51, color: "yellow" },
|
||||
{ min: 0, color: "dimmed" },
|
||||
] as const;
|
||||
|
||||
export const PasswordRequirementsPopover = ({ password, children }: PropsWithChildren<{ password: string }>) => {
|
||||
const tPassword = useScopedI18n("user.field.password");
|
||||
const requirements = useRequirements();
|
||||
const strength = useStrength(password);
|
||||
const [popoverOpened, setPopoverOpened] = useState(false);
|
||||
const strengthColor = strengthColorMap.find(({ min }) => strength >= min)?.color ?? "dimmed";
|
||||
const checks = (
|
||||
<>
|
||||
{requirements.map((requirement) => (
|
||||
@@ -19,8 +27,6 @@ export const PasswordRequirementsPopover = ({ password, children }: PropsWithChi
|
||||
</>
|
||||
);
|
||||
|
||||
const color = strength === 100 ? "teal" : strength > 50 ? "yellow" : "red";
|
||||
|
||||
return (
|
||||
<Popover opened={popoverOpened} position="bottom" width="target" transitionProps={{ transition: "pop" }}>
|
||||
<Popover.Target>
|
||||
@@ -29,7 +35,10 @@ export const PasswordRequirementsPopover = ({ password, children }: PropsWithChi
|
||||
</div>
|
||||
</Popover.Target>
|
||||
<Popover.Dropdown>
|
||||
<Progress color={color} value={strength} size={5} mb="xs" />
|
||||
<Progress color={strengthColor} value={strength} size={5} mb="xs" />
|
||||
<Text size="sm" c="dimmed" mb="xs">
|
||||
{tPassword("suggestionsTitle")}
|
||||
</Text>
|
||||
{checks}
|
||||
</Popover.Dropdown>
|
||||
</Popover>
|
||||
@@ -37,7 +46,7 @@ export const PasswordRequirementsPopover = ({ password, children }: PropsWithChi
|
||||
};
|
||||
|
||||
const useRequirements = () => {
|
||||
const t = useScopedI18n("user.field.password.requirement");
|
||||
const t = useScopedI18n("user.field.password.suggestion");
|
||||
|
||||
return passwordRequirements.map(({ check, value }) => ({ check, label: t(value) }));
|
||||
};
|
||||
|
||||
@@ -19,24 +19,10 @@ export const passwordRequirements = [
|
||||
{ check: regexCheck(/[$&+,:;=?@#|'<>.^*()%!\-~`"_/\\[\]{}]/), value: "special" },
|
||||
] satisfies {
|
||||
check: (value: string) => boolean;
|
||||
value: keyof TranslationObject["user"]["field"]["password"]["requirement"];
|
||||
value: keyof TranslationObject["user"]["field"]["password"]["suggestion"];
|
||||
}[];
|
||||
|
||||
export const userPasswordSchema = z
|
||||
.string()
|
||||
.min(8)
|
||||
.max(255)
|
||||
.refine(
|
||||
(value) => {
|
||||
return passwordRequirements.every((requirement) => requirement.check(value));
|
||||
},
|
||||
{
|
||||
params: createCustomErrorParams({
|
||||
key: "passwordRequirements",
|
||||
params: {},
|
||||
}),
|
||||
},
|
||||
);
|
||||
export const userPasswordSchema = z.string().min(8).max(255);
|
||||
|
||||
const addConfirmPasswordRefinement = <
|
||||
TSchema extends z.ZodObject<{ password: z.core.$ZodString; confirmPassword: z.core.$ZodString }, z.core.$strip>,
|
||||
|
||||
@@ -16,7 +16,7 @@ export default function BookmarksWidget({ options, itemId }: WidgetComponentProp
|
||||
const board = useRequiredBoard();
|
||||
const [data] = clientApi.app.byIds.useSuspenseQuery(options.items, {
|
||||
select(data) {
|
||||
return data.sort((appA, appB) => options.items.indexOf(appA.id) - options.items.indexOf(appB.id));
|
||||
return data.toSorted((appA, appB) => options.items.indexOf(appA.id) - options.items.indexOf(appB.id));
|
||||
},
|
||||
});
|
||||
|
||||
@@ -56,6 +56,7 @@ export default function BookmarksWidget({ options, itemId }: WidgetComponentProp
|
||||
hideIcon={options.hideIcon}
|
||||
hideHostname={options.hideHostname}
|
||||
openNewTab={options.openNewTab}
|
||||
withBorder={options.withBorder}
|
||||
hasIconColor={board.iconColor !== null}
|
||||
/>
|
||||
)}
|
||||
@@ -67,6 +68,7 @@ export default function BookmarksWidget({ options, itemId }: WidgetComponentProp
|
||||
hideIcon={options.hideIcon}
|
||||
hideHostname={options.hideHostname}
|
||||
openNewTab={options.openNewTab}
|
||||
withBorder={options.withBorder}
|
||||
hasIconColor={board.iconColor !== null}
|
||||
/>
|
||||
)}
|
||||
@@ -81,6 +83,7 @@ interface FlexLayoutProps {
|
||||
hideIcon: boolean;
|
||||
hideHostname: boolean;
|
||||
openNewTab: boolean;
|
||||
withBorder: boolean;
|
||||
hasIconColor: boolean;
|
||||
}
|
||||
|
||||
@@ -91,6 +94,7 @@ const FlexLayout = ({
|
||||
hideIcon,
|
||||
hideHostname,
|
||||
openNewTab,
|
||||
withBorder,
|
||||
hasIconColor,
|
||||
}: FlexLayoutProps) => {
|
||||
const board = useRequiredBoard();
|
||||
@@ -106,7 +110,15 @@ const FlexLayout = ({
|
||||
key={app.id}
|
||||
w="100%"
|
||||
>
|
||||
<Card radius={board.itemRadius} className={classes.card} w="100%" display="flex" p={4} h="100%">
|
||||
<Card
|
||||
radius={board.itemRadius}
|
||||
className={classes.card}
|
||||
w="100%"
|
||||
display="flex"
|
||||
p={4}
|
||||
h="100%"
|
||||
withBorder={withBorder}
|
||||
>
|
||||
{direction === "row" ? (
|
||||
<VerticalItem
|
||||
app={app}
|
||||
@@ -138,6 +150,7 @@ interface GridLayoutProps {
|
||||
hideIcon: boolean;
|
||||
hideHostname: boolean;
|
||||
openNewTab: boolean;
|
||||
withBorder: boolean;
|
||||
itemDirection: "horizontal" | "vertical";
|
||||
hasIconColor: boolean;
|
||||
}
|
||||
@@ -148,6 +161,7 @@ const GridLayout = ({
|
||||
hideIcon,
|
||||
hideHostname,
|
||||
openNewTab,
|
||||
withBorder,
|
||||
itemDirection,
|
||||
hasIconColor,
|
||||
}: GridLayoutProps) => {
|
||||
@@ -168,6 +182,7 @@ const GridLayout = ({
|
||||
h="100%"
|
||||
className={combineClasses(classes.card, classes["card-grid"])}
|
||||
radius={board.itemRadius}
|
||||
withBorder={withBorder}
|
||||
p="xs"
|
||||
>
|
||||
{itemDirection === "horizontal" ? (
|
||||
|
||||
@@ -24,6 +24,7 @@ export const { definition, componentLoader } = createWidgetDefinition("bookmarks
|
||||
hideIcon: factory.switch({ defaultValue: false }),
|
||||
hideHostname: factory.switch({ defaultValue: false }),
|
||||
openNewTab: factory.switch({ defaultValue: true }),
|
||||
withBorder: factory.switch({ defaultValue: false }),
|
||||
items: factory.sortableItemList<RouterOutputs["app"]["all"][number], string>({
|
||||
ItemComponent: ({ item, handle: Handle, removeItem, rootAttributes }) => {
|
||||
return (
|
||||
|
||||
@@ -1,20 +1,10 @@
|
||||
.statItem {
|
||||
padding: 12px;
|
||||
border-radius: var(--mantine-radius-md);
|
||||
background-color: var(--mantine-color-gray-0);
|
||||
background-color: light-dark(var(--mantine-color-gray-0), var(--mantine-color-dark-6));
|
||||
transition: all 0.2s ease;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--mantine-color-gray-1);
|
||||
}
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
.statItem {
|
||||
background-color: var(--mantine-color-dark-6);
|
||||
|
||||
&:hover {
|
||||
background-color: var(--mantine-color-dark-5);
|
||||
}
|
||||
background-color: light-dark(var(--mantine-color-gray-1), var(--mantine-color-dark-5));
|
||||
}
|
||||
}
|
||||
Generated
+331
-339
@@ -142,53 +142,53 @@ catalogs:
|
||||
specifier: ^12.0.1
|
||||
version: 12.0.1
|
||||
'@tiptap/extension-color':
|
||||
specifier: 3.23.6
|
||||
version: 3.23.6
|
||||
specifier: 3.24.0
|
||||
version: 3.24.0
|
||||
'@tiptap/extension-highlight':
|
||||
specifier: 3.23.6
|
||||
version: 3.23.6
|
||||
specifier: 3.24.0
|
||||
version: 3.24.0
|
||||
'@tiptap/extension-image':
|
||||
specifier: 3.23.6
|
||||
version: 3.23.6
|
||||
specifier: 3.24.0
|
||||
version: 3.24.0
|
||||
'@tiptap/extension-link':
|
||||
specifier: ^3.23.6
|
||||
version: 3.23.6
|
||||
specifier: ^3.24.0
|
||||
version: 3.24.0
|
||||
'@tiptap/extension-placeholder':
|
||||
specifier: ^3.23.6
|
||||
version: 3.23.6
|
||||
specifier: ^3.24.0
|
||||
version: 3.24.0
|
||||
'@tiptap/extension-table':
|
||||
specifier: 3.23.6
|
||||
version: 3.23.6
|
||||
specifier: 3.24.0
|
||||
version: 3.24.0
|
||||
'@tiptap/extension-table-cell':
|
||||
specifier: 3.23.6
|
||||
version: 3.23.6
|
||||
specifier: 3.24.0
|
||||
version: 3.24.0
|
||||
'@tiptap/extension-table-header':
|
||||
specifier: 3.23.6
|
||||
version: 3.23.6
|
||||
specifier: 3.24.0
|
||||
version: 3.24.0
|
||||
'@tiptap/extension-table-row':
|
||||
specifier: 3.23.6
|
||||
version: 3.23.6
|
||||
specifier: 3.24.0
|
||||
version: 3.24.0
|
||||
'@tiptap/extension-task-item':
|
||||
specifier: 3.23.6
|
||||
version: 3.23.6
|
||||
specifier: 3.24.0
|
||||
version: 3.24.0
|
||||
'@tiptap/extension-task-list':
|
||||
specifier: 3.23.6
|
||||
version: 3.23.6
|
||||
specifier: 3.24.0
|
||||
version: 3.24.0
|
||||
'@tiptap/extension-text-align':
|
||||
specifier: 3.23.6
|
||||
version: 3.23.6
|
||||
specifier: 3.24.0
|
||||
version: 3.24.0
|
||||
'@tiptap/extension-text-style':
|
||||
specifier: 3.23.6
|
||||
version: 3.23.6
|
||||
specifier: 3.24.0
|
||||
version: 3.24.0
|
||||
'@tiptap/extension-underline':
|
||||
specifier: 3.23.6
|
||||
version: 3.23.6
|
||||
specifier: 3.24.0
|
||||
version: 3.24.0
|
||||
'@tiptap/react':
|
||||
specifier: ^3.23.6
|
||||
version: 3.23.6
|
||||
specifier: ^3.24.0
|
||||
version: 3.24.0
|
||||
'@tiptap/starter-kit':
|
||||
specifier: ^3.23.6
|
||||
version: 3.23.6
|
||||
specifier: ^3.24.0
|
||||
version: 3.24.0
|
||||
'@trpc/client':
|
||||
specifier: ^11.17.0
|
||||
version: 11.17.0
|
||||
@@ -388,8 +388,8 @@ catalogs:
|
||||
specifier: ^4.5.0
|
||||
version: 4.5.0
|
||||
mantine-react-table:
|
||||
specifier: 2.0.0-beta.9
|
||||
version: 2.0.0-beta.9
|
||||
specifier: npm:mantine-react-table-open@9.0.3
|
||||
version: 9.0.3
|
||||
maria2:
|
||||
specifier: ^0.4.1
|
||||
version: 0.4.1
|
||||
@@ -756,7 +756,7 @@ importers:
|
||||
version: 9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
'@mantine/tiptap':
|
||||
specifier: 'catalog:'
|
||||
version: 9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(@tiptap/extension-link@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6))(@tiptap/react@3.23.6(@floating-ui/dom@1.7.6)(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6)(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
version: 9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(@tiptap/extension-link@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))(@tiptap/react@3.24.0(@floating-ui/dom@1.7.6)(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
'@tabler/icons-react':
|
||||
specifier: 'catalog:'
|
||||
version: 3.44.0(react@19.2.6)
|
||||
@@ -819,7 +819,7 @@ importers:
|
||||
version: 2.20.0(@babel/core@7.29.0)(@babel/template@7.28.6)(@types/react@19.2.15)(react@19.2.6)
|
||||
mantine-react-table:
|
||||
specifier: 'catalog:'
|
||||
version: 2.0.0-beta.9(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/dates@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(@tabler/icons-react@3.44.0(react@19.2.6))(clsx@2.1.1)(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
version: mantine-react-table-open@9.0.3(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/dates@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(@tabler/icons-react@3.44.0(react@19.2.6))(clsx@2.1.1)(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
next:
|
||||
specifier: 'catalog:'
|
||||
version: 16.2.6(@babel/core@7.29.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0)
|
||||
@@ -2204,7 +2204,7 @@ importers:
|
||||
version: 4.3.1
|
||||
mantine-react-table:
|
||||
specifier: 'catalog:'
|
||||
version: 2.0.0-beta.9(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/dates@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(@tabler/icons-react@3.44.0(react@19.2.6))(clsx@2.1.1)(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
version: mantine-react-table-open@9.0.3(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/dates@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(@tabler/icons-react@3.44.0(react@19.2.6))(clsx@2.1.1)(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
next:
|
||||
specifier: 'catalog:'
|
||||
version: 16.2.6(@babel/core@7.29.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0)
|
||||
@@ -2259,7 +2259,7 @@ importers:
|
||||
version: 4.2.0
|
||||
mantine-react-table:
|
||||
specifier: 'catalog:'
|
||||
version: 2.0.0-beta.9(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/dates@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(@tabler/icons-react@3.44.0(react@19.2.6))(clsx@2.1.1)(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
version: mantine-react-table-open@9.0.3(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/dates@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(@tabler/icons-react@3.44.0(react@19.2.6))(clsx@2.1.1)(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
next:
|
||||
specifier: 'catalog:'
|
||||
version: 16.2.6(@babel/core@7.29.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0)
|
||||
@@ -2396,52 +2396,52 @@ importers:
|
||||
version: 3.44.0(react@19.2.6)
|
||||
'@tiptap/extension-color':
|
||||
specifier: 'catalog:'
|
||||
version: 3.23.6(@tiptap/extension-text-style@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6)))
|
||||
version: 3.24.0(@tiptap/extension-text-style@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0)))
|
||||
'@tiptap/extension-highlight':
|
||||
specifier: 'catalog:'
|
||||
version: 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))
|
||||
version: 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))
|
||||
'@tiptap/extension-image':
|
||||
specifier: 'catalog:'
|
||||
version: 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))
|
||||
version: 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))
|
||||
'@tiptap/extension-link':
|
||||
specifier: 'catalog:'
|
||||
version: 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6)
|
||||
version: 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)
|
||||
'@tiptap/extension-placeholder':
|
||||
specifier: 'catalog:'
|
||||
version: 3.23.6(@tiptap/extensions@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6))
|
||||
version: 3.24.0(@tiptap/extensions@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))
|
||||
'@tiptap/extension-table':
|
||||
specifier: 'catalog:'
|
||||
version: 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6)
|
||||
version: 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)
|
||||
'@tiptap/extension-table-cell':
|
||||
specifier: 'catalog:'
|
||||
version: 3.23.6(@tiptap/extension-table@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6))
|
||||
version: 3.24.0(@tiptap/extension-table@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))
|
||||
'@tiptap/extension-table-header':
|
||||
specifier: 'catalog:'
|
||||
version: 3.23.6(@tiptap/extension-table@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6))
|
||||
version: 3.24.0(@tiptap/extension-table@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))
|
||||
'@tiptap/extension-table-row':
|
||||
specifier: 'catalog:'
|
||||
version: 3.23.6(@tiptap/extension-table@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6))
|
||||
version: 3.24.0(@tiptap/extension-table@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))
|
||||
'@tiptap/extension-task-item':
|
||||
specifier: 'catalog:'
|
||||
version: 3.23.6(@tiptap/extension-list@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6))
|
||||
version: 3.24.0(@tiptap/extension-list@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))
|
||||
'@tiptap/extension-task-list':
|
||||
specifier: 'catalog:'
|
||||
version: 3.23.6(@tiptap/extension-list@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6))
|
||||
version: 3.24.0(@tiptap/extension-list@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))
|
||||
'@tiptap/extension-text-align':
|
||||
specifier: 'catalog:'
|
||||
version: 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))
|
||||
version: 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))
|
||||
'@tiptap/extension-text-style':
|
||||
specifier: 'catalog:'
|
||||
version: 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))
|
||||
version: 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))
|
||||
'@tiptap/extension-underline':
|
||||
specifier: 'catalog:'
|
||||
version: 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))
|
||||
version: 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))
|
||||
'@tiptap/react':
|
||||
specifier: 'catalog:'
|
||||
version: 3.23.6(@floating-ui/dom@1.7.6)(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6)(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
version: 3.24.0(@floating-ui/dom@1.7.6)(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
'@tiptap/starter-kit':
|
||||
specifier: 'catalog:'
|
||||
version: 3.23.6
|
||||
version: 3.24.0
|
||||
clsx:
|
||||
specifier: 'catalog:'
|
||||
version: 2.1.1
|
||||
@@ -2450,7 +2450,7 @@ importers:
|
||||
version: 1.11.21
|
||||
mantine-react-table:
|
||||
specifier: 'catalog:'
|
||||
version: 2.0.0-beta.9(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/dates@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(@tabler/icons-react@3.44.0(react@19.2.6))(clsx@2.1.1)(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
version: mantine-react-table-open@9.0.3(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/dates@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(@tabler/icons-react@3.44.0(react@19.2.6))(clsx@2.1.1)(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
next:
|
||||
specifier: 'catalog:'
|
||||
version: 16.2.6(@babel/core@7.29.0)(@playwright/test@1.60.0)(babel-plugin-react-compiler@1.0.0)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)(sass@1.100.0)
|
||||
@@ -3268,15 +3268,9 @@ packages:
|
||||
'@fastify/proxy-addr@5.1.0':
|
||||
resolution: {integrity: sha512-INS+6gh91cLUjB+PVHfu1UqcB76Sqtpyp7bnL+FYojhjygvOPA9ctiD/JDKsyD9Xgu4hUhCSJBPig/w7duNajw==}
|
||||
|
||||
'@floating-ui/core@1.7.3':
|
||||
resolution: {integrity: sha512-sGnvb5dmrJaKEZ+LDIpguvdX3bDlEllmv4/ClQ9awcmCZrlx5jQyyMWFM5kBI+EyNOCDDiKk8il0zeuX3Zlg/w==}
|
||||
|
||||
'@floating-ui/core@1.7.5':
|
||||
resolution: {integrity: sha512-1Ih4WTWyw0+lKyFMcBHGbb5U5FtuHJuujoyyr5zTaWS5EYMeT6Jb2AuDeftsCsEuchO+mM2ij5+q9crhydzLhQ==}
|
||||
|
||||
'@floating-ui/dom@1.7.4':
|
||||
resolution: {integrity: sha512-OOchDgh4F2CchOX94cRVqhvy7b3AFb+/rQXyswmzmGakRfkMgoWVjfnLWkRirfLEfuD4ysVW16eXzwt3jHIzKA==}
|
||||
|
||||
'@floating-ui/dom@1.7.6':
|
||||
resolution: {integrity: sha512-9gZSAI5XM36880PPMm//9dfiEngYoC6Am2izES1FF406YFsjvyBMmeJ2g4SAju3xWwtuynNRFL2s9hgxpLI5SQ==}
|
||||
|
||||
@@ -4932,215 +4926,215 @@ packages:
|
||||
'@testcontainers/redis@12.0.1':
|
||||
resolution: {integrity: sha512-x5iDR6Y2Mc+2rTJYSQlRTtBMCPt77pKxDogpqRwXgJVmWoDrWFpiFcA/dw6IEoNuyxYUg03tbS8/VzCJI5JX6A==}
|
||||
|
||||
'@tiptap/core@3.23.6':
|
||||
resolution: {integrity: sha512-MRB3pHz4Oxqmcawh0cQ5iOGdY5xtNYp/1CoK7hdTLzw5K0C6/gTC2VvanB1R4INaB6EpBkxG/GiWkVirDRnuXw==}
|
||||
'@tiptap/core@3.24.0':
|
||||
resolution: {integrity: sha512-GTAsXAI32p4hEZgPzvUv2RPrObxamy9AFhmhG10fXSvN/cDUs8naEYVIqDV3Sh99jMwQEbTFKW1E1mcspsY6ow==}
|
||||
peerDependencies:
|
||||
'@tiptap/pm': 3.23.6
|
||||
'@tiptap/pm': 3.24.0
|
||||
|
||||
'@tiptap/extension-blockquote@3.23.6':
|
||||
resolution: {integrity: sha512-2RmnqNqTltZ2k1F7IfjoDNs935Uq4rRDR7d98mqkg3OlDktcQIyBpv0t9dTay6H5bkQeZUuS8ogK2S1E8Edjug==}
|
||||
'@tiptap/extension-blockquote@3.24.0':
|
||||
resolution: {integrity: sha512-DgwEEJ1GbDQcT054ynxoaZGmB9apGeUklPrinq9o6xdLHpdg+bO9HCQzggdB8n21VLLglb8jfAEWsVNwh3eASQ==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': 3.23.6
|
||||
'@tiptap/core': 3.24.0
|
||||
|
||||
'@tiptap/extension-bold@3.23.6':
|
||||
resolution: {integrity: sha512-1LMhjnytdbbhWHSoOwnLxZAOQZWPkKyXVCNmaIk0Mhi4tLPUXptG4qKS5sVYTCveE5H6IBPFrbgBFi5dMI6krA==}
|
||||
'@tiptap/extension-bold@3.24.0':
|
||||
resolution: {integrity: sha512-CujogYaynasklFKHADUseuvj8X2FnWktTCCo3Hl+nlyRvBTmm5TK2aqiamg3v2P4dBh3O6a70mo8BfRJPuiR1g==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': 3.23.6
|
||||
'@tiptap/core': 3.24.0
|
||||
|
||||
'@tiptap/extension-bubble-menu@3.23.6':
|
||||
resolution: {integrity: sha512-Mwkyp9LkDHFbqmWRIkp63FinRxFu3ajC4qSb9t4mnHsb4kAdbNLLsGtbFg+le0SWk4CxGwAOwM7SzeJ+6UGqCA==}
|
||||
'@tiptap/extension-bubble-menu@3.24.0':
|
||||
resolution: {integrity: sha512-jRXD+JPu9ayvq78g8hsCxx4q/qUFtrdfIYirRSf5YUseuuUbtfrq83AsGabcygpUTefjJkMQoXNITkh6294Ggw==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': 3.23.6
|
||||
'@tiptap/pm': 3.23.6
|
||||
'@tiptap/core': 3.24.0
|
||||
'@tiptap/pm': 3.24.0
|
||||
|
||||
'@tiptap/extension-bullet-list@3.23.6':
|
||||
resolution: {integrity: sha512-RMRgfXZykr/13X8UBOwvpgysVOo9KchwqMoEbvqQSj4YFfU56iIn59C8sbxiQ1sKfeltUf0wH4fPc0I4iwKqAA==}
|
||||
'@tiptap/extension-bullet-list@3.24.0':
|
||||
resolution: {integrity: sha512-IOpAm5c4XVVVvkOef+V9XYMVpea+3MgBpCQgn83UQRlwO9eIMwmcyxOznu7gQPQVShTEpkt4T6uK+ZN9o8meIA==}
|
||||
peerDependencies:
|
||||
'@tiptap/extension-list': 3.23.6
|
||||
'@tiptap/extension-list': 3.24.0
|
||||
|
||||
'@tiptap/extension-code-block@3.23.6':
|
||||
resolution: {integrity: sha512-4kccgcn5yHThxrzsIhJny3EwfEZYIk+BjUCL4uIuzOyWvExtGhZ6JMHVCZeMhI8D1/bX1LNkkAKN5DXPzH4lXQ==}
|
||||
'@tiptap/extension-code-block@3.24.0':
|
||||
resolution: {integrity: sha512-NZglw4oHoH6oJ5+HvxxQCYk+wODJmsxzUpRQdsOmje08sekQH+Zt9i4UKimBhg4urpd5r+dKXTslab9a5eQ86w==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': 3.23.6
|
||||
'@tiptap/pm': 3.23.6
|
||||
'@tiptap/core': 3.24.0
|
||||
'@tiptap/pm': 3.24.0
|
||||
|
||||
'@tiptap/extension-code@3.23.6':
|
||||
resolution: {integrity: sha512-KG8KXFYyLrtYvT7AZ1WGV61ofx8pDe5g9pH658MERxqQGii+Pyfc6xkz04l7XeBts/7+571UQp/0O7i/z560TA==}
|
||||
'@tiptap/extension-code@3.24.0':
|
||||
resolution: {integrity: sha512-MAQtrPRQ+HRmcGotWbksdIGeH1gqayFAdvi4lNGeFT7taHXP1o1XD7CQp7iYIKmg8IU4/MQ+RdetSfuC1A9edQ==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': 3.23.6
|
||||
'@tiptap/core': 3.24.0
|
||||
|
||||
'@tiptap/extension-color@3.23.6':
|
||||
resolution: {integrity: sha512-2WxYc+X+OGFXbq/Ak0VXODEzfK1l5wz33oTWSuhdSw44HAQM7+SSyiDnMCXDQdqi063ANqMmQmlw5WngjQ6wCA==}
|
||||
'@tiptap/extension-color@3.24.0':
|
||||
resolution: {integrity: sha512-gVv9zfQ9diq/sk+SVJzqadShsOtDK1XPojBZR1zXg1QxedzdwLKuRDxvnlfIc3kFIyaDP4mNrek+anednTbWBA==}
|
||||
peerDependencies:
|
||||
'@tiptap/extension-text-style': 3.23.6
|
||||
'@tiptap/extension-text-style': 3.24.0
|
||||
|
||||
'@tiptap/extension-document@3.23.6':
|
||||
resolution: {integrity: sha512-XDAIgG9KcKumFM9KJWUEUhXPbFIhhl47bfy5GknareWTRKke85rcoj/oxKKO9ihLZr8JfpbXjqnS4SCm5yhYPw==}
|
||||
'@tiptap/extension-document@3.24.0':
|
||||
resolution: {integrity: sha512-yxgM3+yXy2XZzEwH43y2Kp8D1BkblxEWLXqo0YCoAKtxyKCcEaT8kdlf70kS7D0+VSzYU4D0iN7VdQIYHcL2mA==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': 3.23.6
|
||||
'@tiptap/core': 3.24.0
|
||||
|
||||
'@tiptap/extension-dropcursor@3.23.6':
|
||||
resolution: {integrity: sha512-+XWEoRKf3lXxi7Le1aOM2xU1XHwxICGpXjT3m4QaYqUgIpsq8gQEuso6kVg8DnTD7biKQs6+oIQ0o2b/gTW9WA==}
|
||||
'@tiptap/extension-dropcursor@3.24.0':
|
||||
resolution: {integrity: sha512-Dbv1c5LnvG3PT+yEbCNroyOeeUkHq9wcir2pbC7wri7g7d2sCi0+HvKH0MAxLwY3j5NJJSiSyG2ypMaXOAs4sg==}
|
||||
peerDependencies:
|
||||
'@tiptap/extensions': 3.23.6
|
||||
'@tiptap/extensions': 3.24.0
|
||||
|
||||
'@tiptap/extension-floating-menu@3.23.6':
|
||||
resolution: {integrity: sha512-2kjuDcEq69lEcECl75xqY5MyzUSh2zcC5aLrpwP1WwhJz5bxsIFHiaps5AP6h9R4A+ZBj5b2haay2Y1wDUU3VA==}
|
||||
'@tiptap/extension-floating-menu@3.24.0':
|
||||
resolution: {integrity: sha512-7QEbf3mUzFAkejjQGX9f0L507oMtnOBRwHt2skUTR+9yXgudsN8zaDBSSRHLeMWGk9b7L293ZMA6zCRrZaHrfA==}
|
||||
peerDependencies:
|
||||
'@floating-ui/dom': ^1.0.0
|
||||
'@tiptap/core': 3.23.6
|
||||
'@tiptap/pm': 3.23.6
|
||||
'@tiptap/core': 3.24.0
|
||||
'@tiptap/pm': 3.24.0
|
||||
|
||||
'@tiptap/extension-gapcursor@3.23.6':
|
||||
resolution: {integrity: sha512-wbKmxXsszxWacEkrHucRpSQbiKjz4fmOebD6OVyL9AcrmlbxNk8vcM3iyh/8cVeRy09XY+morM165t/u7/z4IQ==}
|
||||
'@tiptap/extension-gapcursor@3.24.0':
|
||||
resolution: {integrity: sha512-CzCP5/jni5RFwW9jCfBO6auh83GbaioMTpSk6tyR3sd+CbwlBcUdsJFGJkbaRdiSS9dgIyi+6hRbhjpYdHcp+w==}
|
||||
peerDependencies:
|
||||
'@tiptap/extensions': 3.23.6
|
||||
'@tiptap/extensions': 3.24.0
|
||||
|
||||
'@tiptap/extension-hard-break@3.23.6':
|
||||
resolution: {integrity: sha512-KeUm+tkUfIVSX9QM9XOIhaay0Fn36sLKUo5NVYjN3uJaxFvaZXZmTlxdO85OTdgF2P5sqh9LomrIgliaFRGk4w==}
|
||||
'@tiptap/extension-hard-break@3.24.0':
|
||||
resolution: {integrity: sha512-T/ZEBiHQPMyTqDvXG0tiqBToNeuSemIPmNtdoGSgBN/degVl7VJZqQIrLIvOUHfjf3QkRs7TE/mcqTJsIboO/g==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': 3.23.6
|
||||
'@tiptap/core': 3.24.0
|
||||
|
||||
'@tiptap/extension-heading@3.23.6':
|
||||
resolution: {integrity: sha512-A/0jPhxnUh9THSZymlu0OGPZe1wdFdwHAXnRCmqvYUCwJjrG7LCC/ahzmcj1tcNzI9hgHyuYPSfev8RXYrNu/w==}
|
||||
'@tiptap/extension-heading@3.24.0':
|
||||
resolution: {integrity: sha512-GCSgapIzQPqEGNcVGE0/Pcjg5wITMLYJlrS3GGVw7BPmECJwgexcoOsEwkxtzJnXT/HpFXbvOFW43sM0KeHSjg==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': 3.23.6
|
||||
'@tiptap/core': 3.24.0
|
||||
|
||||
'@tiptap/extension-highlight@3.23.6':
|
||||
resolution: {integrity: sha512-GWv6R4iZzVrNeB33qtJDBt/BfVjuc5S/sUF/VDFAtK8h86bg4cEm1tGLEsui4T3+vij/t+P+eoGhkzF6NGogdg==}
|
||||
'@tiptap/extension-highlight@3.24.0':
|
||||
resolution: {integrity: sha512-+Vx6YKSP+lzCBiTbgQOpR2rIOzL8Ns6UnOBtW4O6tYc7TMTexycaG66RWxXMpAD6QkamwLwX3H5TTYviWtU9RQ==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': 3.23.6
|
||||
'@tiptap/core': 3.24.0
|
||||
|
||||
'@tiptap/extension-horizontal-rule@3.23.6':
|
||||
resolution: {integrity: sha512-hEUlz4H+I64r+TH6LCuNCRgO7JTHncXGmx9+WbU69EOfY8O0ZurcgeJc8HeiAKL+r9YuC1e5YHfFxgCaaC0jlg==}
|
||||
'@tiptap/extension-horizontal-rule@3.24.0':
|
||||
resolution: {integrity: sha512-DFzWJTrb23x+qssLLs85vEyho8ItUGp3RY9XUsVTIAGZn5IsoUw8wMsvIBlH1ux4Ch7gLchtcD6kpTdMdrL9kw==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': 3.23.6
|
||||
'@tiptap/pm': 3.23.6
|
||||
'@tiptap/core': 3.24.0
|
||||
'@tiptap/pm': 3.24.0
|
||||
|
||||
'@tiptap/extension-image@3.23.6':
|
||||
resolution: {integrity: sha512-vvNGxArvD2dW+XvV0KdYovRVUzCy8QVNulc2r5pV7umnG1E6cCmMkiHiif8J2ePJu2KtysAvJQe0iF+UqueGMw==}
|
||||
'@tiptap/extension-image@3.24.0':
|
||||
resolution: {integrity: sha512-mH+bvsX2cPKuZzV7YMQi4FV2YbDP+Kmq36bY+Bwi/x4mYUc8u0cjQxcu8RzLO7GtsgUJPxGMwfkQxmDqXFLZvw==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': 3.23.6
|
||||
'@tiptap/core': 3.24.0
|
||||
|
||||
'@tiptap/extension-italic@3.23.6':
|
||||
resolution: {integrity: sha512-wol5KdwCPAvpiYhH9PLlvO8ZnJHwZtIboVevrfOGgBcKlXRA3dedR4OAMXHnUtkkzu9KtliLg1+TYzEx4JZG9Q==}
|
||||
'@tiptap/extension-italic@3.24.0':
|
||||
resolution: {integrity: sha512-mf3cbNlbMPUNj3IyUkIke+o3ZpOUrtVeY5Yqs5IM/VhkUUh/PdIzqw74VuqEAJ0Z4oZ6nNDHeYLrl3Be1j99lQ==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': 3.23.6
|
||||
'@tiptap/core': 3.24.0
|
||||
|
||||
'@tiptap/extension-link@3.23.6':
|
||||
resolution: {integrity: sha512-KNZz7z7P2/qbQsx5bPAbSPjrKDg1VHsedGlLHJCr8U2VRD5VgmDLkMpkouP1CsDg15qgyUKv/nDib5KgPpLNWA==}
|
||||
'@tiptap/extension-link@3.24.0':
|
||||
resolution: {integrity: sha512-MwMoNGG2mL5XGFV1tEGunBRglwsIbW+ZOB2QnKiv+Mcbi2JCWMrorndJZBqpVPR5nM+Bef2KnpchEJmYlQLvKQ==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': 3.23.6
|
||||
'@tiptap/pm': 3.23.6
|
||||
'@tiptap/core': 3.24.0
|
||||
'@tiptap/pm': 3.24.0
|
||||
|
||||
'@tiptap/extension-list-item@3.23.6':
|
||||
resolution: {integrity: sha512-3zzyhdkUWcHVpXuvy6KiIwjh29rbH6gEDEqPQqHLrl1XGnO9pnShC7pSHctlCDjmcx3O4n9cd4QMtVBlUerbiA==}
|
||||
'@tiptap/extension-list-item@3.24.0':
|
||||
resolution: {integrity: sha512-zl/U3viJiV9OzkKM37AHIUN1af1TSLrcbHUUoNLkfJ33Nq+NlpaXpCVK0rKRqiLFJf7zk/a5KWG5CrOy9TxjKA==}
|
||||
peerDependencies:
|
||||
'@tiptap/extension-list': 3.23.6
|
||||
'@tiptap/extension-list': 3.24.0
|
||||
|
||||
'@tiptap/extension-list-keymap@3.23.6':
|
||||
resolution: {integrity: sha512-x8bPcLViGzg/RAmQM/XtmfqIwQ/Pv9Q8mkd+OgfUiTqjeJqKwVQmiqbLFNa7zw81+H61M+HDU+qGAaQ3vRIMjw==}
|
||||
'@tiptap/extension-list-keymap@3.24.0':
|
||||
resolution: {integrity: sha512-69fKcrngYGEKWNn4R5oLwl0YuV3FY4kufEValVcjnihUmqJTE1vx+fwctYoTsOGnIuNGpUIQ7f9YDD/0w34qBw==}
|
||||
peerDependencies:
|
||||
'@tiptap/extension-list': 3.23.6
|
||||
'@tiptap/extension-list': 3.24.0
|
||||
|
||||
'@tiptap/extension-list@3.23.6':
|
||||
resolution: {integrity: sha512-z6vj9+Qht2sjdQkyyHcUpsC/yCIZqTrQiyHDhs/HGKrfvoANyAZGpqdNeKf1wSyjIso+27tQuIH5NDfk8ygyNw==}
|
||||
'@tiptap/extension-list@3.24.0':
|
||||
resolution: {integrity: sha512-GcxDVMMmDGj7OFTBrV7JpVgr5wxlr2vmjwH7U8QxZX7OJI5vrsMYl/U6KRTvUpG8wP+Zmo5jRlLM+BbL+a/W3g==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': 3.23.6
|
||||
'@tiptap/pm': 3.23.6
|
||||
'@tiptap/core': 3.24.0
|
||||
'@tiptap/pm': 3.24.0
|
||||
|
||||
'@tiptap/extension-ordered-list@3.23.6':
|
||||
resolution: {integrity: sha512-1m/wWB/ZtXcmG2vNdiUkCqsOgqv5vBjCv/mVaHhF9OvV+zQS8YDjoWE7zEuT/GgELdT77Xq8lHrn4nCDudB3/A==}
|
||||
'@tiptap/extension-ordered-list@3.24.0':
|
||||
resolution: {integrity: sha512-buRa6bmBDw0TztH+rAcusIye14DiLDS+yGheo6GiNCTD7kKJnksXagBdxvip3jhW5sx7gyAKvoBmvGSg1BbsGA==}
|
||||
peerDependencies:
|
||||
'@tiptap/extension-list': 3.23.6
|
||||
'@tiptap/extension-list': 3.24.0
|
||||
|
||||
'@tiptap/extension-paragraph@3.23.6':
|
||||
resolution: {integrity: sha512-+7m58LUSncodjrIyXks4RZ3tLNYrvgT77wRR4l3HnM5OABY3GDsDTqi7c1t1yI29NVOSk/DUacqy6UwYAj1DGg==}
|
||||
'@tiptap/extension-paragraph@3.24.0':
|
||||
resolution: {integrity: sha512-wD06aB6hO7LgcrlhGiw7I64k2tus9kNoICX5R+UecBSB1DVJdzKvXoXL2kPNv4DqYvljHdkIeK/OpuOTQd6MJA==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': 3.23.6
|
||||
'@tiptap/core': 3.24.0
|
||||
|
||||
'@tiptap/extension-placeholder@3.23.6':
|
||||
resolution: {integrity: sha512-8I6b2aevF74aLgymKMxbDxSLxWA2y+2dh0zZDeI8sRZ2m6WHHes+Kyuuwkq1HIPcR+ZLpbec74cmf6lcL/yvqQ==}
|
||||
'@tiptap/extension-placeholder@3.24.0':
|
||||
resolution: {integrity: sha512-3jfYYCIuwMADhvZ92vB6c80YiTmgTSFR23JqyLps8qkQtV59Va5CBYpwJtSs1+VrbCVnNxhZBHhVXusZO3uRkA==}
|
||||
peerDependencies:
|
||||
'@tiptap/extensions': 3.23.6
|
||||
'@tiptap/extensions': 3.24.0
|
||||
|
||||
'@tiptap/extension-strike@3.23.6':
|
||||
resolution: {integrity: sha512-oF7FEZ37f15aCe5kPgzGDYf/m+hr7VdQ/Ko/Hds/UM9pX7AG1fdtmRrl6wqkRqDM/incZaC/AQR2/Dpo2VCNGQ==}
|
||||
'@tiptap/extension-strike@3.24.0':
|
||||
resolution: {integrity: sha512-sfN1iQs6Fdlorrfe8wipDkTPwu/Egx3s2fkY7TAWusTGFHwlovuRUGFKqCL9dI4N3u6uqUMpEuWmQNgv+aQGjQ==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': 3.23.6
|
||||
'@tiptap/core': 3.24.0
|
||||
|
||||
'@tiptap/extension-table-cell@3.23.6':
|
||||
resolution: {integrity: sha512-hS9TmmvRlT9/ikT+0ukACS+hmJuii4zQaH47cg3oJkz/Fv7O7tL7GZniKtK6l2OUZGPhY+4SV2RkDB6bD7DXfw==}
|
||||
'@tiptap/extension-table-cell@3.24.0':
|
||||
resolution: {integrity: sha512-jg62iVc1L8tOycSuwZ5i82EGKGuvelCIkpFX7wvHMl9EiPX9fv70enmb4ua9DyLgRtYg/MNrGOdUATRpxWsFRA==}
|
||||
peerDependencies:
|
||||
'@tiptap/extension-table': 3.23.6
|
||||
'@tiptap/extension-table': 3.24.0
|
||||
|
||||
'@tiptap/extension-table-header@3.23.6':
|
||||
resolution: {integrity: sha512-D6o0a1cJXUU0xWakainBFGPnGHinQkPcdu1YqGd/PoFANY38lnuZt/NW2O/OLfLXu5LXDRfpqF1+dsKww27dUA==}
|
||||
'@tiptap/extension-table-header@3.24.0':
|
||||
resolution: {integrity: sha512-z1TGVoBD5lVX48hpKcrQY5vETB8aCR61Enk5wGl45zNO/sMEMNxYfDKTkMydyOFUWfGqvOPnjDHJqJuT36/19w==}
|
||||
peerDependencies:
|
||||
'@tiptap/extension-table': 3.23.6
|
||||
'@tiptap/extension-table': 3.24.0
|
||||
|
||||
'@tiptap/extension-table-row@3.23.6':
|
||||
resolution: {integrity: sha512-OauWVzkyRQg0rKOqM/a3PuKPc1S7YXMb1LRN7Nh8Ytvglvd7GFRTbl1lVqdZRaz4Jzopag4PQnriIZfMPUpxWw==}
|
||||
'@tiptap/extension-table-row@3.24.0':
|
||||
resolution: {integrity: sha512-kASEYMWZF9ZqO6DRGz0LiD11c3LPfzOlFiJQVDrOyLP7xkJpHzIAKH0K+8u4aohOziDLn8nz+8I+3xjRS46oGg==}
|
||||
peerDependencies:
|
||||
'@tiptap/extension-table': 3.23.6
|
||||
'@tiptap/extension-table': 3.24.0
|
||||
|
||||
'@tiptap/extension-table@3.23.6':
|
||||
resolution: {integrity: sha512-XbhZXjhsS6AP7ThoZxjAnNs+NiR81YRori25l6E+ORqB7quiPkIXOAi5h4AIpkn/CYIqze6ere11lWsYpDjtaQ==}
|
||||
'@tiptap/extension-table@3.24.0':
|
||||
resolution: {integrity: sha512-lr5elob3uJnB+ltgqPDEeVQmIPRx6JoS0I6z93tOgKsI2mIsaw5ErghteeiCTpExdyax7aWR0fn5pZzLVDQL8A==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': 3.23.6
|
||||
'@tiptap/pm': 3.23.6
|
||||
'@tiptap/core': 3.24.0
|
||||
'@tiptap/pm': 3.24.0
|
||||
|
||||
'@tiptap/extension-task-item@3.23.6':
|
||||
resolution: {integrity: sha512-PIHW+3KZCtEmtC7z34rfkusbC42HYr7uw1h5xNvrazQwJGWhKo1UmI0Yea5vyJNKPrTLPCMEm/mgMrj8nNAZfA==}
|
||||
'@tiptap/extension-task-item@3.24.0':
|
||||
resolution: {integrity: sha512-2VtX6VOp4SJk5E/VHeSC2Acfbge6h69TUBhF7hFebbiCDyB73xCaPKcuClIyzOlWJgpWz2ZPXwVB+Y3meXw+yw==}
|
||||
peerDependencies:
|
||||
'@tiptap/extension-list': 3.23.6
|
||||
'@tiptap/extension-list': 3.24.0
|
||||
|
||||
'@tiptap/extension-task-list@3.23.6':
|
||||
resolution: {integrity: sha512-XNuYbVV7F0TBpxHqqEFvrxwGbmTq01qJrZA6qwbQopOsw5wOsCy4XQsCkeZ8BGkakORCEWGSMjPyVOtIKq2jGA==}
|
||||
'@tiptap/extension-task-list@3.24.0':
|
||||
resolution: {integrity: sha512-EIbB/WQ7L92WfaY5AF9upH93nIgBHjGt5zwPYoX+ZTpBncebr1AEDF7rc+LHNuSa1g1ToOKbFB88ep02IIXOjA==}
|
||||
peerDependencies:
|
||||
'@tiptap/extension-list': 3.23.6
|
||||
'@tiptap/extension-list': 3.24.0
|
||||
|
||||
'@tiptap/extension-text-align@3.23.6':
|
||||
resolution: {integrity: sha512-pE+gDmvnrSMWHADDnDSzaO7YUi9kOywQkyrqZ9bEPLddZred7ICoJ4NtD2DqLjDSur+HijaJuByResWb78c6FA==}
|
||||
'@tiptap/extension-text-align@3.24.0':
|
||||
resolution: {integrity: sha512-WKFtYXGthtkUc+Cwy2fItSr+9FKwLZjkJVAY1GhkRdcq35qTuVhkb4Q4wR2Rhkb6QRqtlxF1NDuTf2vxiQmfBQ==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': 3.23.6
|
||||
'@tiptap/core': 3.24.0
|
||||
|
||||
'@tiptap/extension-text-style@3.23.6':
|
||||
resolution: {integrity: sha512-Auasgj469wkQ5ip+Zi2gaRzvqxx9qKG58+1mkT8yPE3QAGnOIg/AaKyQ7pTV77UyL3FHvLnU+KsWCad+qcobww==}
|
||||
'@tiptap/extension-text-style@3.24.0':
|
||||
resolution: {integrity: sha512-1Hy+5tFEAsnoLhZ/eqmza4USvFHwMA8haeAdCGlwTeshBrt+nUKTrEsRHidF60cGsRwlTcuqxSkjT94dULgp5Q==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': 3.23.6
|
||||
'@tiptap/core': 3.24.0
|
||||
|
||||
'@tiptap/extension-text@3.23.6':
|
||||
resolution: {integrity: sha512-ipoC2TkIAIOTiF5ByiGgvQB1DqDyfP90wrUB3mohBcgvp7lQnwHszCDGv8dNnmcUek8uXV/uoLu2VXeVQlxjPA==}
|
||||
'@tiptap/extension-text@3.24.0':
|
||||
resolution: {integrity: sha512-Im7keLPEihxm3+LyF+drYCoaOY5hlq35lvHAp/el6M8pJ/scts88HrYpdR1Yc4BtpZBIhfHSyWgPaupI4qwdeg==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': 3.23.6
|
||||
'@tiptap/core': 3.24.0
|
||||
|
||||
'@tiptap/extension-underline@3.23.6':
|
||||
resolution: {integrity: sha512-P55wGIZGYTVH92Fq0cgI4/O9AhLCaJC3hhxg15RSERP5/YegM9eJHDK/GQ1EE/DvYA+xpYGOV6agKwAUqfA/Iw==}
|
||||
'@tiptap/extension-underline@3.24.0':
|
||||
resolution: {integrity: sha512-D4W4X3UMq9dLVIOfPB9+UodQ4eAJ8yDcm8qFWAwq0a15YWH6bnwulCuIdV+U5dEG+yaRxN8haB9GrrID9jmrSA==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': 3.23.6
|
||||
'@tiptap/core': 3.24.0
|
||||
|
||||
'@tiptap/extensions@3.23.6':
|
||||
resolution: {integrity: sha512-X09/Db1teB+ifXzDGVVFmOeQRx7wTAayE9/280spxpsHkHZvJ5bHRvWIzUzviMIjbBz+NPDIKYPK7gMfh9iaig==}
|
||||
'@tiptap/extensions@3.24.0':
|
||||
resolution: {integrity: sha512-z6gRYzy2ucJp07OQ0F2W07NxyhMTxPYH1ia2eGiQkWax1i56oExpjMsDHP8THWlg8Tb7NnbfKpkfh881EsmofA==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': 3.23.6
|
||||
'@tiptap/pm': 3.23.6
|
||||
'@tiptap/core': 3.24.0
|
||||
'@tiptap/pm': 3.24.0
|
||||
|
||||
'@tiptap/pm@3.23.6':
|
||||
resolution: {integrity: sha512-in5CaMaWlJcH2A1q6GJKFtrodE8WLS3M9tIi/f89jPmIVHJShpodC0KZDNyJkrVBQomYk0DEh86Utm6ASXzQww==}
|
||||
'@tiptap/pm@3.24.0':
|
||||
resolution: {integrity: sha512-QQP/78ryOZDN99gNBV7dgh69/8AYaOYQYFklq/iR+ZRFaaL3+qqHFvPVJapGkzPdymBgNJ34xjFM8n5pJ4QmMg==}
|
||||
|
||||
'@tiptap/react@3.23.6':
|
||||
resolution: {integrity: sha512-Tw9KZkYqFMk3vaJAEQKqEYIO/iq3cSJe7OUEGBul4k4GaMQeLItLf5EYhUd0GIPXci1WVVPNntKJsHfX25M37w==}
|
||||
'@tiptap/react@3.24.0':
|
||||
resolution: {integrity: sha512-KxnrlQbzOgA02EMsfuGGHtNhfkJQGqVlQttmQctI9DOl/F3gcaRqg+wNTBY1Fof8yDaZ8Z1LL1F0C05W0o3vUw==}
|
||||
peerDependencies:
|
||||
'@tiptap/core': 3.23.6
|
||||
'@tiptap/pm': 3.23.6
|
||||
'@tiptap/core': 3.24.0
|
||||
'@tiptap/pm': 3.24.0
|
||||
'@types/react': ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
'@types/react-dom': ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
react: ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
react-dom: ^17.0.0 || ^18.0.0 || ^19.0.0
|
||||
|
||||
'@tiptap/starter-kit@3.23.6':
|
||||
resolution: {integrity: sha512-gykwtGWrnWCmtql1hid3opac/KV8zQvOAnu3bTqIqcHrn1FusbUwKmNzavSbfGvcktHM3hFjb35W48JyVLyu/A==}
|
||||
'@tiptap/starter-kit@3.24.0':
|
||||
resolution: {integrity: sha512-Ef4PCP96vcY2GonXN9J0M8iC6zvxPTmQlL/QZiCwuYqqnH/hNpYIjNSQdTndiDpxRKofa32Sr2HWktgEnL32Bg==}
|
||||
|
||||
'@tree-sitter-grammars/tree-sitter-yaml@0.7.1':
|
||||
resolution: {integrity: sha512-AynBwkIoQCTgjDR33bDUp9Mqq+YTco0is3n5hRApMqG9of/6A4eQsfC1/uSEeHSUyMQSYawcAWamsexnVpIP4Q==}
|
||||
@@ -7442,18 +7436,18 @@ packages:
|
||||
resolution: {integrity: sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
mantine-react-table@2.0.0-beta.9:
|
||||
resolution: {integrity: sha512-ZdfcwebWaPERoDvAuk43VYcBCzamohARVclnbuepT0PHZ0wRcDPMBR+zgaocL+pFy8EXUGwvWTOKNh25ITpjNQ==}
|
||||
mantine-react-table-open@9.0.3:
|
||||
resolution: {integrity: sha512-HsrBU4KZluj96FPvvH0wcLzog0m5LIMdwB/59oj6BpftLGEibiLxX00G+tDM06PL2jXuiRxiGKPJ4oQOV+VK8w==}
|
||||
engines: {node: '>=16'}
|
||||
peerDependencies:
|
||||
'@mantine/core': ^7.9
|
||||
'@mantine/dates': ^7.9
|
||||
'@mantine/hooks': ^7.9
|
||||
'@mantine/core': ^9.0.0
|
||||
'@mantine/dates': ^9.0.0
|
||||
'@mantine/hooks': ^9.0.0
|
||||
'@tabler/icons-react': '>=2.23.0'
|
||||
clsx: '>=2'
|
||||
dayjs: '>=1.11'
|
||||
react: '>=18.0'
|
||||
react-dom: '>=18.0'
|
||||
react: '>=19.2'
|
||||
react-dom: '>=19.2'
|
||||
|
||||
maria2@0.4.1:
|
||||
resolution: {integrity: sha512-3lr8UeB+R+BN9c7eOBkeH1GlHf7+0Kzt0pcEgsT9xoXIA5gfXAzjd1niYiYDsvb62v5rLPqCqDiyYxtmmhGJ3g==}
|
||||
@@ -8313,6 +8307,9 @@ packages:
|
||||
prosemirror-history@1.4.1:
|
||||
resolution: {integrity: sha512-2JZD8z2JviJrboD9cPuX/Sv/1ChFng+xh2tChQ2X4bB2HeK+rra/bmJ3xGntCcjhOqIzSDG6Id7e8RJ9QPXLEQ==}
|
||||
|
||||
prosemirror-inputrules@1.5.1:
|
||||
resolution: {integrity: sha512-7wj4uMjKaXWAQ1CDgxNzNtR9AlsuwzHfdFH1ygEHA2KHF2DOEaXl1CJfNPAKCg9qNEh4rum975QLaCiQPyY6Fw==}
|
||||
|
||||
prosemirror-keymap@1.2.2:
|
||||
resolution: {integrity: sha512-EAlXoksqC6Vbocqc0GtzCruZEzYgrn+iiGnNjsJsH4mrnIGex4qbLdWWNza3AW5W36ZRrlBID0eM6bdKH4OStQ==}
|
||||
|
||||
@@ -10463,21 +10460,10 @@ snapshots:
|
||||
'@fastify/forwarded': 3.0.1
|
||||
ipaddr.js: 2.3.0
|
||||
|
||||
'@floating-ui/core@1.7.3':
|
||||
dependencies:
|
||||
'@floating-ui/utils': 0.2.11
|
||||
optional: true
|
||||
|
||||
'@floating-ui/core@1.7.5':
|
||||
dependencies:
|
||||
'@floating-ui/utils': 0.2.11
|
||||
|
||||
'@floating-ui/dom@1.7.4':
|
||||
dependencies:
|
||||
'@floating-ui/core': 1.7.3
|
||||
'@floating-ui/utils': 0.2.11
|
||||
optional: true
|
||||
|
||||
'@floating-ui/dom@1.7.6':
|
||||
dependencies:
|
||||
'@floating-ui/core': 1.7.5
|
||||
@@ -11010,12 +10996,12 @@ snapshots:
|
||||
dependencies:
|
||||
react: 19.2.6
|
||||
|
||||
'@mantine/tiptap@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(@tiptap/extension-link@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6))(@tiptap/react@3.23.6(@floating-ui/dom@1.7.6)(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6)(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)':
|
||||
'@mantine/tiptap@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(@tiptap/extension-link@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))(@tiptap/react@3.24.0(@floating-ui/dom@1.7.6)(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(react-dom@19.2.6(react@19.2.6))(react@19.2.6)':
|
||||
dependencies:
|
||||
'@mantine/core': 9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
'@mantine/hooks': 9.2.2(react@19.2.6)
|
||||
'@tiptap/extension-link': 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6)
|
||||
'@tiptap/react': 3.23.6(@floating-ui/dom@1.7.6)(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6)(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
'@tiptap/extension-link': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)
|
||||
'@tiptap/react': 3.24.0(@floating-ui/dom@1.7.6)(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
react: 19.2.6
|
||||
react-dom: 19.2.6(react@19.2.6)
|
||||
|
||||
@@ -12232,174 +12218,175 @@ snapshots:
|
||||
- bare-buffer
|
||||
- supports-color
|
||||
|
||||
'@tiptap/core@3.23.6(@tiptap/pm@3.23.6)':
|
||||
'@tiptap/core@3.24.0(@tiptap/pm@3.24.0)':
|
||||
dependencies:
|
||||
'@tiptap/pm': 3.23.6
|
||||
'@tiptap/pm': 3.24.0
|
||||
|
||||
'@tiptap/extension-blockquote@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))':
|
||||
'@tiptap/extension-blockquote@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))':
|
||||
dependencies:
|
||||
'@tiptap/core': 3.23.6(@tiptap/pm@3.23.6)
|
||||
'@tiptap/core': 3.24.0(@tiptap/pm@3.24.0)
|
||||
|
||||
'@tiptap/extension-bold@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))':
|
||||
'@tiptap/extension-bold@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))':
|
||||
dependencies:
|
||||
'@tiptap/core': 3.23.6(@tiptap/pm@3.23.6)
|
||||
'@tiptap/core': 3.24.0(@tiptap/pm@3.24.0)
|
||||
|
||||
'@tiptap/extension-bubble-menu@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6)':
|
||||
dependencies:
|
||||
'@floating-ui/dom': 1.7.4
|
||||
'@tiptap/core': 3.23.6(@tiptap/pm@3.23.6)
|
||||
'@tiptap/pm': 3.23.6
|
||||
optional: true
|
||||
|
||||
'@tiptap/extension-bullet-list@3.23.6(@tiptap/extension-list@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6))':
|
||||
dependencies:
|
||||
'@tiptap/extension-list': 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6)
|
||||
|
||||
'@tiptap/extension-code-block@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6)':
|
||||
dependencies:
|
||||
'@tiptap/core': 3.23.6(@tiptap/pm@3.23.6)
|
||||
'@tiptap/pm': 3.23.6
|
||||
|
||||
'@tiptap/extension-code@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))':
|
||||
dependencies:
|
||||
'@tiptap/core': 3.23.6(@tiptap/pm@3.23.6)
|
||||
|
||||
'@tiptap/extension-color@3.23.6(@tiptap/extension-text-style@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6)))':
|
||||
dependencies:
|
||||
'@tiptap/extension-text-style': 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))
|
||||
|
||||
'@tiptap/extension-document@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))':
|
||||
dependencies:
|
||||
'@tiptap/core': 3.23.6(@tiptap/pm@3.23.6)
|
||||
|
||||
'@tiptap/extension-dropcursor@3.23.6(@tiptap/extensions@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6))':
|
||||
dependencies:
|
||||
'@tiptap/extensions': 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6)
|
||||
|
||||
'@tiptap/extension-floating-menu@3.23.6(@floating-ui/dom@1.7.6)(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6)':
|
||||
'@tiptap/extension-bubble-menu@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)':
|
||||
dependencies:
|
||||
'@floating-ui/dom': 1.7.6
|
||||
'@tiptap/core': 3.23.6(@tiptap/pm@3.23.6)
|
||||
'@tiptap/pm': 3.23.6
|
||||
'@tiptap/core': 3.24.0(@tiptap/pm@3.24.0)
|
||||
'@tiptap/pm': 3.24.0
|
||||
optional: true
|
||||
|
||||
'@tiptap/extension-gapcursor@3.23.6(@tiptap/extensions@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6))':
|
||||
'@tiptap/extension-bullet-list@3.24.0(@tiptap/extension-list@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))':
|
||||
dependencies:
|
||||
'@tiptap/extensions': 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6)
|
||||
'@tiptap/extension-list': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)
|
||||
|
||||
'@tiptap/extension-hard-break@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))':
|
||||
'@tiptap/extension-code-block@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)':
|
||||
dependencies:
|
||||
'@tiptap/core': 3.23.6(@tiptap/pm@3.23.6)
|
||||
'@tiptap/core': 3.24.0(@tiptap/pm@3.24.0)
|
||||
'@tiptap/pm': 3.24.0
|
||||
|
||||
'@tiptap/extension-heading@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))':
|
||||
'@tiptap/extension-code@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))':
|
||||
dependencies:
|
||||
'@tiptap/core': 3.23.6(@tiptap/pm@3.23.6)
|
||||
'@tiptap/core': 3.24.0(@tiptap/pm@3.24.0)
|
||||
|
||||
'@tiptap/extension-highlight@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))':
|
||||
'@tiptap/extension-color@3.24.0(@tiptap/extension-text-style@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0)))':
|
||||
dependencies:
|
||||
'@tiptap/core': 3.23.6(@tiptap/pm@3.23.6)
|
||||
'@tiptap/extension-text-style': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))
|
||||
|
||||
'@tiptap/extension-horizontal-rule@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6)':
|
||||
'@tiptap/extension-document@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))':
|
||||
dependencies:
|
||||
'@tiptap/core': 3.23.6(@tiptap/pm@3.23.6)
|
||||
'@tiptap/pm': 3.23.6
|
||||
'@tiptap/core': 3.24.0(@tiptap/pm@3.24.0)
|
||||
|
||||
'@tiptap/extension-image@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))':
|
||||
'@tiptap/extension-dropcursor@3.24.0(@tiptap/extensions@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))':
|
||||
dependencies:
|
||||
'@tiptap/core': 3.23.6(@tiptap/pm@3.23.6)
|
||||
'@tiptap/extensions': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)
|
||||
|
||||
'@tiptap/extension-italic@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))':
|
||||
'@tiptap/extension-floating-menu@3.24.0(@floating-ui/dom@1.7.6)(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)':
|
||||
dependencies:
|
||||
'@tiptap/core': 3.23.6(@tiptap/pm@3.23.6)
|
||||
'@floating-ui/dom': 1.7.6
|
||||
'@tiptap/core': 3.24.0(@tiptap/pm@3.24.0)
|
||||
'@tiptap/pm': 3.24.0
|
||||
optional: true
|
||||
|
||||
'@tiptap/extension-link@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6)':
|
||||
'@tiptap/extension-gapcursor@3.24.0(@tiptap/extensions@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))':
|
||||
dependencies:
|
||||
'@tiptap/core': 3.23.6(@tiptap/pm@3.23.6)
|
||||
'@tiptap/pm': 3.23.6
|
||||
'@tiptap/extensions': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)
|
||||
|
||||
'@tiptap/extension-hard-break@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))':
|
||||
dependencies:
|
||||
'@tiptap/core': 3.24.0(@tiptap/pm@3.24.0)
|
||||
|
||||
'@tiptap/extension-heading@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))':
|
||||
dependencies:
|
||||
'@tiptap/core': 3.24.0(@tiptap/pm@3.24.0)
|
||||
|
||||
'@tiptap/extension-highlight@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))':
|
||||
dependencies:
|
||||
'@tiptap/core': 3.24.0(@tiptap/pm@3.24.0)
|
||||
|
||||
'@tiptap/extension-horizontal-rule@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)':
|
||||
dependencies:
|
||||
'@tiptap/core': 3.24.0(@tiptap/pm@3.24.0)
|
||||
'@tiptap/pm': 3.24.0
|
||||
|
||||
'@tiptap/extension-image@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))':
|
||||
dependencies:
|
||||
'@tiptap/core': 3.24.0(@tiptap/pm@3.24.0)
|
||||
|
||||
'@tiptap/extension-italic@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))':
|
||||
dependencies:
|
||||
'@tiptap/core': 3.24.0(@tiptap/pm@3.24.0)
|
||||
|
||||
'@tiptap/extension-link@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)':
|
||||
dependencies:
|
||||
'@tiptap/core': 3.24.0(@tiptap/pm@3.24.0)
|
||||
'@tiptap/pm': 3.24.0
|
||||
linkifyjs: 4.3.3
|
||||
|
||||
'@tiptap/extension-list-item@3.23.6(@tiptap/extension-list@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6))':
|
||||
'@tiptap/extension-list-item@3.24.0(@tiptap/extension-list@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))':
|
||||
dependencies:
|
||||
'@tiptap/extension-list': 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6)
|
||||
'@tiptap/extension-list': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)
|
||||
|
||||
'@tiptap/extension-list-keymap@3.23.6(@tiptap/extension-list@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6))':
|
||||
'@tiptap/extension-list-keymap@3.24.0(@tiptap/extension-list@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))':
|
||||
dependencies:
|
||||
'@tiptap/extension-list': 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6)
|
||||
'@tiptap/extension-list': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)
|
||||
|
||||
'@tiptap/extension-list@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6)':
|
||||
'@tiptap/extension-list@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)':
|
||||
dependencies:
|
||||
'@tiptap/core': 3.23.6(@tiptap/pm@3.23.6)
|
||||
'@tiptap/pm': 3.23.6
|
||||
'@tiptap/core': 3.24.0(@tiptap/pm@3.24.0)
|
||||
'@tiptap/pm': 3.24.0
|
||||
|
||||
'@tiptap/extension-ordered-list@3.23.6(@tiptap/extension-list@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6))':
|
||||
'@tiptap/extension-ordered-list@3.24.0(@tiptap/extension-list@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))':
|
||||
dependencies:
|
||||
'@tiptap/extension-list': 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6)
|
||||
'@tiptap/extension-list': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)
|
||||
|
||||
'@tiptap/extension-paragraph@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))':
|
||||
'@tiptap/extension-paragraph@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))':
|
||||
dependencies:
|
||||
'@tiptap/core': 3.23.6(@tiptap/pm@3.23.6)
|
||||
'@tiptap/core': 3.24.0(@tiptap/pm@3.24.0)
|
||||
|
||||
'@tiptap/extension-placeholder@3.23.6(@tiptap/extensions@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6))':
|
||||
'@tiptap/extension-placeholder@3.24.0(@tiptap/extensions@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))':
|
||||
dependencies:
|
||||
'@tiptap/extensions': 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6)
|
||||
'@tiptap/extensions': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)
|
||||
|
||||
'@tiptap/extension-strike@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))':
|
||||
'@tiptap/extension-strike@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))':
|
||||
dependencies:
|
||||
'@tiptap/core': 3.23.6(@tiptap/pm@3.23.6)
|
||||
'@tiptap/core': 3.24.0(@tiptap/pm@3.24.0)
|
||||
|
||||
'@tiptap/extension-table-cell@3.23.6(@tiptap/extension-table@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6))':
|
||||
'@tiptap/extension-table-cell@3.24.0(@tiptap/extension-table@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))':
|
||||
dependencies:
|
||||
'@tiptap/extension-table': 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6)
|
||||
'@tiptap/extension-table': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)
|
||||
|
||||
'@tiptap/extension-table-header@3.23.6(@tiptap/extension-table@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6))':
|
||||
'@tiptap/extension-table-header@3.24.0(@tiptap/extension-table@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))':
|
||||
dependencies:
|
||||
'@tiptap/extension-table': 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6)
|
||||
'@tiptap/extension-table': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)
|
||||
|
||||
'@tiptap/extension-table-row@3.23.6(@tiptap/extension-table@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6))':
|
||||
'@tiptap/extension-table-row@3.24.0(@tiptap/extension-table@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))':
|
||||
dependencies:
|
||||
'@tiptap/extension-table': 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6)
|
||||
'@tiptap/extension-table': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)
|
||||
|
||||
'@tiptap/extension-table@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6)':
|
||||
'@tiptap/extension-table@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)':
|
||||
dependencies:
|
||||
'@tiptap/core': 3.23.6(@tiptap/pm@3.23.6)
|
||||
'@tiptap/pm': 3.23.6
|
||||
'@tiptap/core': 3.24.0(@tiptap/pm@3.24.0)
|
||||
'@tiptap/pm': 3.24.0
|
||||
|
||||
'@tiptap/extension-task-item@3.23.6(@tiptap/extension-list@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6))':
|
||||
'@tiptap/extension-task-item@3.24.0(@tiptap/extension-list@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))':
|
||||
dependencies:
|
||||
'@tiptap/extension-list': 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6)
|
||||
'@tiptap/extension-list': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)
|
||||
|
||||
'@tiptap/extension-task-list@3.23.6(@tiptap/extension-list@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6))':
|
||||
'@tiptap/extension-task-list@3.24.0(@tiptap/extension-list@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))':
|
||||
dependencies:
|
||||
'@tiptap/extension-list': 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6)
|
||||
'@tiptap/extension-list': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)
|
||||
|
||||
'@tiptap/extension-text-align@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))':
|
||||
'@tiptap/extension-text-align@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))':
|
||||
dependencies:
|
||||
'@tiptap/core': 3.23.6(@tiptap/pm@3.23.6)
|
||||
'@tiptap/core': 3.24.0(@tiptap/pm@3.24.0)
|
||||
|
||||
'@tiptap/extension-text-style@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))':
|
||||
'@tiptap/extension-text-style@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))':
|
||||
dependencies:
|
||||
'@tiptap/core': 3.23.6(@tiptap/pm@3.23.6)
|
||||
'@tiptap/core': 3.24.0(@tiptap/pm@3.24.0)
|
||||
|
||||
'@tiptap/extension-text@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))':
|
||||
'@tiptap/extension-text@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))':
|
||||
dependencies:
|
||||
'@tiptap/core': 3.23.6(@tiptap/pm@3.23.6)
|
||||
'@tiptap/core': 3.24.0(@tiptap/pm@3.24.0)
|
||||
|
||||
'@tiptap/extension-underline@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))':
|
||||
'@tiptap/extension-underline@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))':
|
||||
dependencies:
|
||||
'@tiptap/core': 3.23.6(@tiptap/pm@3.23.6)
|
||||
'@tiptap/core': 3.24.0(@tiptap/pm@3.24.0)
|
||||
|
||||
'@tiptap/extensions@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6)':
|
||||
'@tiptap/extensions@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)':
|
||||
dependencies:
|
||||
'@tiptap/core': 3.23.6(@tiptap/pm@3.23.6)
|
||||
'@tiptap/pm': 3.23.6
|
||||
'@tiptap/core': 3.24.0(@tiptap/pm@3.24.0)
|
||||
'@tiptap/pm': 3.24.0
|
||||
|
||||
'@tiptap/pm@3.23.6':
|
||||
'@tiptap/pm@3.24.0':
|
||||
dependencies:
|
||||
prosemirror-changeset: 2.3.0
|
||||
prosemirror-commands: 1.6.2
|
||||
prosemirror-dropcursor: 1.8.1
|
||||
prosemirror-gapcursor: 1.3.2
|
||||
prosemirror-history: 1.4.1
|
||||
prosemirror-inputrules: 1.5.1
|
||||
prosemirror-keymap: 1.2.2
|
||||
prosemirror-model: 1.24.1
|
||||
prosemirror-schema-list: 1.5.1
|
||||
@@ -12408,10 +12395,10 @@ snapshots:
|
||||
prosemirror-transform: 1.10.2
|
||||
prosemirror-view: 1.41.4
|
||||
|
||||
'@tiptap/react@3.23.6(@floating-ui/dom@1.7.6)(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6)(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)':
|
||||
'@tiptap/react@3.24.0(@floating-ui/dom@1.7.6)(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)(@types/react-dom@19.2.3(@types/react@19.2.15))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)':
|
||||
dependencies:
|
||||
'@tiptap/core': 3.23.6(@tiptap/pm@3.23.6)
|
||||
'@tiptap/pm': 3.23.6
|
||||
'@tiptap/core': 3.24.0(@tiptap/pm@3.24.0)
|
||||
'@tiptap/pm': 3.24.0
|
||||
'@types/react': 19.2.15
|
||||
'@types/react-dom': 19.2.3(@types/react@19.2.15)
|
||||
'@types/use-sync-external-store': 0.0.6
|
||||
@@ -12420,37 +12407,37 @@ snapshots:
|
||||
react-dom: 19.2.6(react@19.2.6)
|
||||
use-sync-external-store: 1.6.0(react@19.2.6)
|
||||
optionalDependencies:
|
||||
'@tiptap/extension-bubble-menu': 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6)
|
||||
'@tiptap/extension-floating-menu': 3.23.6(@floating-ui/dom@1.7.6)(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6)
|
||||
'@tiptap/extension-bubble-menu': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)
|
||||
'@tiptap/extension-floating-menu': 3.24.0(@floating-ui/dom@1.7.6)(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)
|
||||
transitivePeerDependencies:
|
||||
- '@floating-ui/dom'
|
||||
|
||||
'@tiptap/starter-kit@3.23.6':
|
||||
'@tiptap/starter-kit@3.24.0':
|
||||
dependencies:
|
||||
'@tiptap/core': 3.23.6(@tiptap/pm@3.23.6)
|
||||
'@tiptap/extension-blockquote': 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))
|
||||
'@tiptap/extension-bold': 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))
|
||||
'@tiptap/extension-bullet-list': 3.23.6(@tiptap/extension-list@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6))
|
||||
'@tiptap/extension-code': 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))
|
||||
'@tiptap/extension-code-block': 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6)
|
||||
'@tiptap/extension-document': 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))
|
||||
'@tiptap/extension-dropcursor': 3.23.6(@tiptap/extensions@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6))
|
||||
'@tiptap/extension-gapcursor': 3.23.6(@tiptap/extensions@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6))
|
||||
'@tiptap/extension-hard-break': 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))
|
||||
'@tiptap/extension-heading': 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))
|
||||
'@tiptap/extension-horizontal-rule': 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6)
|
||||
'@tiptap/extension-italic': 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))
|
||||
'@tiptap/extension-link': 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6)
|
||||
'@tiptap/extension-list': 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6)
|
||||
'@tiptap/extension-list-item': 3.23.6(@tiptap/extension-list@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6))
|
||||
'@tiptap/extension-list-keymap': 3.23.6(@tiptap/extension-list@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6))
|
||||
'@tiptap/extension-ordered-list': 3.23.6(@tiptap/extension-list@3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6))
|
||||
'@tiptap/extension-paragraph': 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))
|
||||
'@tiptap/extension-strike': 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))
|
||||
'@tiptap/extension-text': 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))
|
||||
'@tiptap/extension-underline': 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))
|
||||
'@tiptap/extensions': 3.23.6(@tiptap/core@3.23.6(@tiptap/pm@3.23.6))(@tiptap/pm@3.23.6)
|
||||
'@tiptap/pm': 3.23.6
|
||||
'@tiptap/core': 3.24.0(@tiptap/pm@3.24.0)
|
||||
'@tiptap/extension-blockquote': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))
|
||||
'@tiptap/extension-bold': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))
|
||||
'@tiptap/extension-bullet-list': 3.24.0(@tiptap/extension-list@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))
|
||||
'@tiptap/extension-code': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))
|
||||
'@tiptap/extension-code-block': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)
|
||||
'@tiptap/extension-document': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))
|
||||
'@tiptap/extension-dropcursor': 3.24.0(@tiptap/extensions@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))
|
||||
'@tiptap/extension-gapcursor': 3.24.0(@tiptap/extensions@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))
|
||||
'@tiptap/extension-hard-break': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))
|
||||
'@tiptap/extension-heading': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))
|
||||
'@tiptap/extension-horizontal-rule': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)
|
||||
'@tiptap/extension-italic': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))
|
||||
'@tiptap/extension-link': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)
|
||||
'@tiptap/extension-list': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)
|
||||
'@tiptap/extension-list-item': 3.24.0(@tiptap/extension-list@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))
|
||||
'@tiptap/extension-list-keymap': 3.24.0(@tiptap/extension-list@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))
|
||||
'@tiptap/extension-ordered-list': 3.24.0(@tiptap/extension-list@3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0))
|
||||
'@tiptap/extension-paragraph': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))
|
||||
'@tiptap/extension-strike': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))
|
||||
'@tiptap/extension-text': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))
|
||||
'@tiptap/extension-underline': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))
|
||||
'@tiptap/extensions': 3.24.0(@tiptap/core@3.24.0(@tiptap/pm@3.24.0))(@tiptap/pm@3.24.0)
|
||||
'@tiptap/pm': 3.24.0
|
||||
|
||||
'@tree-sitter-grammars/tree-sitter-yaml@0.7.1(tree-sitter@0.22.4)':
|
||||
dependencies:
|
||||
@@ -14795,7 +14782,7 @@ snapshots:
|
||||
dependencies:
|
||||
semver: 7.7.4
|
||||
|
||||
mantine-react-table@2.0.0-beta.9(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/dates@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(@tabler/icons-react@3.44.0(react@19.2.6))(clsx@2.1.1)(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6):
|
||||
mantine-react-table-open@9.0.3(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/dates@9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(@tabler/icons-react@3.44.0(react@19.2.6))(clsx@2.1.1)(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6):
|
||||
dependencies:
|
||||
'@mantine/core': 9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
'@mantine/dates': 9.2.2(@mantine/core@9.2.2(@mantine/hooks@9.2.2(react@19.2.6))(@types/react@19.2.15)(react-dom@19.2.6(react@19.2.6))(react@19.2.6))(@mantine/hooks@9.2.2(react@19.2.6))(dayjs@1.11.21)(react-dom@19.2.6(react@19.2.6))(react@19.2.6)
|
||||
@@ -15748,6 +15735,11 @@ snapshots:
|
||||
prosemirror-view: 1.41.4
|
||||
rope-sequence: 1.3.4
|
||||
|
||||
prosemirror-inputrules@1.5.1:
|
||||
dependencies:
|
||||
prosemirror-state: 1.4.3
|
||||
prosemirror-transform: 1.10.2
|
||||
|
||||
prosemirror-keymap@1.2.2:
|
||||
dependencies:
|
||||
prosemirror-state: 1.4.3
|
||||
|
||||
+17
-17
@@ -49,22 +49,22 @@ catalog:
|
||||
"@testcontainers/mysql": ^12.0.1
|
||||
"@testcontainers/postgresql": ^12.0.1
|
||||
"@testcontainers/redis": ^12.0.1
|
||||
"@tiptap/extension-color": 3.23.6
|
||||
"@tiptap/extension-highlight": 3.23.6
|
||||
"@tiptap/extension-image": 3.23.6
|
||||
"@tiptap/extension-link": ^3.23.6
|
||||
"@tiptap/extension-placeholder": ^3.23.6
|
||||
"@tiptap/extension-table": 3.23.6
|
||||
"@tiptap/extension-table-cell": 3.23.6
|
||||
"@tiptap/extension-table-header": 3.23.6
|
||||
"@tiptap/extension-table-row": 3.23.6
|
||||
"@tiptap/extension-task-item": 3.23.6
|
||||
"@tiptap/extension-task-list": 3.23.6
|
||||
"@tiptap/extension-text-align": 3.23.6
|
||||
"@tiptap/extension-text-style": 3.23.6
|
||||
"@tiptap/extension-underline": 3.23.6
|
||||
"@tiptap/react": ^3.23.6
|
||||
"@tiptap/starter-kit": ^3.23.6
|
||||
"@tiptap/extension-color": 3.24.0
|
||||
"@tiptap/extension-highlight": 3.24.0
|
||||
"@tiptap/extension-image": 3.24.0
|
||||
"@tiptap/extension-link": ^3.24.0
|
||||
"@tiptap/extension-placeholder": ^3.24.0
|
||||
"@tiptap/extension-table": 3.24.0
|
||||
"@tiptap/extension-table-cell": 3.24.0
|
||||
"@tiptap/extension-table-header": 3.24.0
|
||||
"@tiptap/extension-table-row": 3.24.0
|
||||
"@tiptap/extension-task-item": 3.24.0
|
||||
"@tiptap/extension-task-list": 3.24.0
|
||||
"@tiptap/extension-text-align": 3.24.0
|
||||
"@tiptap/extension-text-style": 3.24.0
|
||||
"@tiptap/extension-underline": 3.24.0
|
||||
"@tiptap/react": ^3.24.0
|
||||
"@tiptap/starter-kit": ^3.24.0
|
||||
"@trpc/client": ^11.17.0
|
||||
"@trpc/next": ^11.17.0
|
||||
"@trpc/react-query": ^11.17.0
|
||||
@@ -131,7 +131,7 @@ catalog:
|
||||
json5: ^2.2.3
|
||||
ldapts: 8.1.8
|
||||
lodash.clonedeep: ^4.5.0
|
||||
mantine-react-table: 2.0.0-beta.9
|
||||
mantine-react-table: npm:mantine-react-table-open@9.0.3
|
||||
maria2: ^0.4.1
|
||||
mysql2: 3.22.4
|
||||
next: 16.2.6
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"meierschlumpf@gmail.com": "manuel-rw",
|
||||
"thomas@ajnart.fr": "ajnart",
|
||||
"omariqbal97@gmail.com": "omariqbal",
|
||||
"kyle.grieder@gmail.com": "kylegrieder",
|
||||
"oupsman@oupsman.fr": "Oupsman",
|
||||
"pitschi@posteo.de": "pitschi",
|
||||
"github@xela.codes": "itzTheMeow",
|
||||
"febrile42@gmail.com": "febrile42",
|
||||
"nanewman01@gmail.com": "NicolasNewman"
|
||||
}
|
||||
@@ -0,0 +1,309 @@
|
||||
import { spawnSync } from "node:child_process";
|
||||
import { existsSync, readdirSync, statSync } from "node:fs";
|
||||
import { readFile, writeFile } from "node:fs/promises";
|
||||
import { join, relative } from "node:path";
|
||||
|
||||
const REPO_ROOT = join(import.meta.dirname, "..");
|
||||
const CODEOWNERS_PATH = join(REPO_ROOT, "CODEOWNERS");
|
||||
const OVERRIDES_PATH = join(REPO_ROOT, "scripts/codeowners-overrides.json");
|
||||
|
||||
const BEGIN_MARKER = "# BEGIN GENERATED widget/integration owners";
|
||||
const END_MARKER = "# END GENERATED widget/integration owners";
|
||||
|
||||
const WIDGET_SKIP = new Set(["_inputs", "errors", "modals", "test"]);
|
||||
const INTEGRATION_SKIP = new Set(["base", "interfaces", "mock"]);
|
||||
|
||||
const BOT_SUBSTRINGS = ["[bot]", "renovate", "homarr-update", "dependabot", "github-actions"];
|
||||
|
||||
const WIDGET_ROUTER_ALIASES: Record<string, string> = {
|
||||
"anchor-note": "anchor-notes",
|
||||
"media-releases": "media-release",
|
||||
rssFeed: "rssFeed",
|
||||
stocks: "stocks",
|
||||
};
|
||||
|
||||
const INTEGRATION_CRON_ALIASES: Record<string, string> = {
|
||||
homeassistant: "home-assistant",
|
||||
"download-client": "downloads",
|
||||
"media-organizer": "media-organizer",
|
||||
"pi-hole": "dns-hole",
|
||||
"smart-home": "home-assistant",
|
||||
};
|
||||
|
||||
const WIDGET_TO_INTEGRATION_DIR: Record<string, string> = {
|
||||
"anchor-note": "anchor",
|
||||
};
|
||||
|
||||
const NESTED_WIDGET_ROUTER_PARENT: Record<string, string> = {
|
||||
"dns-hole": "dns-hole",
|
||||
immich: "immich",
|
||||
"media-requests": "media-requests",
|
||||
"network-controller": "network-controller",
|
||||
minecraft: "minecraft",
|
||||
"smart-home": "smart-home",
|
||||
};
|
||||
|
||||
type Overrides = Record<string, string>;
|
||||
|
||||
const isBotEmail = (email: string) => BOT_SUBSTRINGS.some((fragment) => email.toLowerCase().includes(fragment));
|
||||
|
||||
const gitEmailForPath = (repoPath: string) => {
|
||||
const strategies = [
|
||||
["log", "--grep=feat", "-i", "--format=%ae", "--reverse", "-1", "--", repoPath],
|
||||
["log", "--diff-filter=A", "--format=%ae", "--reverse", "-1", "--", repoPath],
|
||||
["log", "--format=%ae", "--reverse", "-1", "--", repoPath],
|
||||
] as const;
|
||||
|
||||
for (const args of strategies) {
|
||||
const result = spawnSync("git", args, { cwd: REPO_ROOT, encoding: "utf8" });
|
||||
const email = (result.stdout ?? "").trim();
|
||||
if (email && !isBotEmail(email)) return email;
|
||||
}
|
||||
return "";
|
||||
};
|
||||
|
||||
const noreplyHandle = (email: string) => {
|
||||
const match = email.match(/^\d+\+([^@]+)@users\.noreply\.github\.com$/i);
|
||||
return match?.[1] ?? null;
|
||||
};
|
||||
|
||||
const resolveHandle = (email: string, overrides: Overrides) => {
|
||||
const fromNoreply = noreplyHandle(email);
|
||||
if (fromNoreply) return fromNoreply;
|
||||
return overrides[email] ?? null;
|
||||
};
|
||||
|
||||
const hasLeafMarker = (dirPath: string) => {
|
||||
const names = readdirSync(dirPath);
|
||||
const leafPatterns = ["-integration.ts", "component.tsx", "index.ts", "index.tsx"];
|
||||
return names.some((name) => leafPatterns.some((suffix) => name.endsWith(suffix) || name === suffix));
|
||||
};
|
||||
|
||||
const discoverLeafDirs = (base: string, skip: Set<string>) => {
|
||||
const absoluteBase = join(REPO_ROOT, base);
|
||||
const leaves: string[] = [];
|
||||
|
||||
for (const name of readdirSync(absoluteBase).sort()) {
|
||||
const dirPath = join(absoluteBase, name);
|
||||
if (!statSync(dirPath).isDirectory() || skip.has(name)) continue;
|
||||
|
||||
if (hasLeafMarker(dirPath)) {
|
||||
leaves.push(join(base, name));
|
||||
continue;
|
||||
}
|
||||
|
||||
const nestedLeaves = readdirSync(dirPath)
|
||||
.filter((sub) => statSync(join(dirPath, sub)).isDirectory())
|
||||
.filter((sub) => hasLeafMarker(join(dirPath, sub)))
|
||||
.map((sub) => join(base, name, sub));
|
||||
|
||||
leaves.push(...(nestedLeaves.length > 0 ? nestedLeaves : [join(base, name)]));
|
||||
}
|
||||
|
||||
return leaves;
|
||||
};
|
||||
|
||||
const relFromBase = (fullPath: string, base: string) => relative(join(REPO_ROOT, base), join(REPO_ROOT, fullPath));
|
||||
|
||||
const widgetRouterKey = (widgetRel: string) => {
|
||||
const direct = WIDGET_ROUTER_ALIASES[widgetRel];
|
||||
if (direct) return direct;
|
||||
|
||||
const segment = widgetRel.includes("/") ? (widgetRel.split("/")[0] ?? widgetRel) : widgetRel;
|
||||
const parentAlias = NESTED_WIDGET_ROUTER_PARENT[segment];
|
||||
const segmentAlias = WIDGET_ROUTER_ALIASES[segment];
|
||||
return parentAlias ?? segmentAlias ?? segment;
|
||||
};
|
||||
|
||||
const integrationCronKey = (integrationRel: string) => {
|
||||
const segment = integrationRel.includes("/") ? (integrationRel.split("/")[0] ?? integrationRel) : integrationRel;
|
||||
return INTEGRATION_CRON_ALIASES[segment] ?? INTEGRATION_CRON_ALIASES[integrationRel] ?? segment;
|
||||
};
|
||||
|
||||
const existingFile = (repoPath: string) => {
|
||||
const full = join(REPO_ROOT, repoPath);
|
||||
return existsSync(full) ? `/${repoPath}` : null;
|
||||
};
|
||||
|
||||
const widgetSatellites = (widgetRel: string) => {
|
||||
const routerKey = widgetRouterKey(widgetRel);
|
||||
const cronKey = integrationCronKey(widgetRel);
|
||||
return [
|
||||
existingFile(`packages/api/src/router/widgets/${routerKey}.ts`),
|
||||
existingFile(`packages/cron-jobs/src/jobs/integrations/${cronKey}.ts`),
|
||||
existingFile(`packages/cron-jobs/src/jobs/${cronKey}.ts`),
|
||||
].filter((path): path is string => path !== null);
|
||||
};
|
||||
|
||||
const integrationSatellites = (integrationRel: string) => {
|
||||
const cronKey = integrationCronKey(integrationRel);
|
||||
return [
|
||||
existingFile(`packages/cron-jobs/src/jobs/integrations/${cronKey}.ts`),
|
||||
existingFile(`packages/cron-jobs/src/jobs/${cronKey}.ts`),
|
||||
].filter((path): path is string => path !== null);
|
||||
};
|
||||
|
||||
const dirCodeownersPath = (repoDir: string) => `/${repoDir}/`;
|
||||
|
||||
const integrationRelForWidget = (widgetRel: string) => {
|
||||
const mapped = WIDGET_TO_INTEGRATION_DIR[widgetRel] ?? WIDGET_TO_INTEGRATION_DIR[widgetRel.split("/")[0] ?? ""];
|
||||
if (mapped) return mapped;
|
||||
|
||||
const direct = join("packages/integrations/src", widgetRel);
|
||||
if (existsSync(join(REPO_ROOT, direct))) return widgetRel;
|
||||
|
||||
const segment = widgetRel.split("/")[0] ?? widgetRel;
|
||||
const segmentPath = join("packages/integrations/src", segment);
|
||||
if (existsSync(join(REPO_ROOT, segmentPath))) return segment;
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
const collectPathsForWidget = (widgetRel: string) => {
|
||||
const paths = new Set<string>([dirCodeownersPath(`packages/widgets/src/${widgetRel}`), ...widgetSatellites(widgetRel)]);
|
||||
|
||||
const integrationRel = integrationRelForWidget(widgetRel);
|
||||
if (integrationRel) {
|
||||
paths.add(dirCodeownersPath(`packages/integrations/src/${integrationRel}`));
|
||||
for (const satellite of integrationSatellites(integrationRel)) paths.add(satellite);
|
||||
}
|
||||
|
||||
return [...paths];
|
||||
};
|
||||
|
||||
const collectPathsForIntegration = (integrationRel: string) => {
|
||||
const paths = new Set<string>([
|
||||
dirCodeownersPath(`packages/integrations/src/${integrationRel}`),
|
||||
...integrationSatellites(integrationRel),
|
||||
]);
|
||||
|
||||
const widgetPath = join(REPO_ROOT, "packages/widgets/src", integrationRel);
|
||||
if (existsSync(widgetPath)) {
|
||||
paths.add(dirCodeownersPath(`packages/widgets/src/${integrationRel}`));
|
||||
for (const satellite of widgetSatellites(integrationRel)) paths.add(satellite);
|
||||
}
|
||||
|
||||
return [...paths];
|
||||
};
|
||||
|
||||
const loadOverrides = async () => JSON.parse(await readFile(OVERRIDES_PATH, "utf8")) as Overrides;
|
||||
|
||||
const resolveGithubUser = async (email: string, overrides: Overrides) => {
|
||||
const fromOverrides = resolveHandle(email, overrides);
|
||||
if (fromOverrides) return fromOverrides;
|
||||
|
||||
const token = process.env.GITHUB_TOKEN;
|
||||
if (!token) return null;
|
||||
|
||||
const response = await fetch(`https://api.github.com/search/users?q=${encodeURIComponent(email)}`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
Accept: "application/vnd.github+json",
|
||||
"X-GitHub-Api-Version": "2022-11-28",
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) return null;
|
||||
|
||||
const data = (await response.json()) as { items: { login: string }[] };
|
||||
return data.items[0]?.login ?? null;
|
||||
};
|
||||
|
||||
type OwnerEntry = { primary: string; line: string };
|
||||
|
||||
const buildOwnerEntries = async (overrides: Overrides) => {
|
||||
const entries: OwnerEntry[] = [];
|
||||
const unresolved: { path: string; email: string }[] = [];
|
||||
const claimedDirs = new Set<string>();
|
||||
|
||||
const addUnit = async (repoDir: string, collectPaths: (rel: string) => string[]) => {
|
||||
if (claimedDirs.has(repoDir)) return;
|
||||
|
||||
const rel =
|
||||
repoDir.startsWith("packages/widgets/") ?
|
||||
relFromBase(repoDir, "packages/widgets/src")
|
||||
: relFromBase(repoDir, "packages/integrations/src");
|
||||
|
||||
const email = gitEmailForPath(`${repoDir}/`);
|
||||
if (!email) {
|
||||
unresolved.push({ path: repoDir, email: "" });
|
||||
return;
|
||||
}
|
||||
|
||||
const handle = await resolveGithubUser(email, overrides);
|
||||
if (!handle) {
|
||||
unresolved.push({ path: repoDir, email });
|
||||
return;
|
||||
}
|
||||
|
||||
const paths = collectPaths(rel).sort();
|
||||
const primary = paths[0] ?? `/${repoDir}/`;
|
||||
entries.push({ primary, line: `${paths.join(" ")} @${handle}` });
|
||||
|
||||
claimedDirs.add(repoDir);
|
||||
for (const path of paths) {
|
||||
if (!path.endsWith("/")) continue;
|
||||
claimedDirs.add(path.slice(1, -1));
|
||||
}
|
||||
};
|
||||
|
||||
for (const widgetDir of discoverLeafDirs("packages/widgets/src", WIDGET_SKIP)) {
|
||||
await addUnit(widgetDir, collectPathsForWidget);
|
||||
}
|
||||
|
||||
for (const integrationDir of discoverLeafDirs("packages/integrations/src", INTEGRATION_SKIP)) {
|
||||
await addUnit(integrationDir, collectPathsForIntegration);
|
||||
}
|
||||
|
||||
entries.sort((a, b) => a.primary.localeCompare(b.primary));
|
||||
return { entries, unresolved };
|
||||
};
|
||||
|
||||
const formatGeneratedBlock = (entries: OwnerEntry[]) => {
|
||||
const lines = entries.map((entry) => entry.line);
|
||||
return [BEGIN_MARKER, ...lines, END_MARKER].join("\n");
|
||||
};
|
||||
|
||||
const replaceGeneratedSection = (content: string, generatedBlock: string) => {
|
||||
const startIndex = content.indexOf(BEGIN_MARKER);
|
||||
const endIndex = content.indexOf(END_MARKER);
|
||||
|
||||
if (startIndex === -1 || endIndex === -1) {
|
||||
return `${content.trimEnd()}\n\n${generatedBlock}\n`;
|
||||
}
|
||||
|
||||
const before = content.slice(0, startIndex).trimEnd();
|
||||
const after = content.slice(endIndex + END_MARKER.length).trimStart();
|
||||
const middle = generatedBlock;
|
||||
const chunks = [before, middle, after].filter((chunk) => chunk.length > 0);
|
||||
return `${chunks.join("\n\n")}\n`;
|
||||
};
|
||||
|
||||
const main = async () => {
|
||||
const overrides = await loadOverrides();
|
||||
const { entries, unresolved } = await buildOwnerEntries(overrides);
|
||||
const generatedBlock = formatGeneratedBlock(entries);
|
||||
|
||||
const current = await readFile(CODEOWNERS_PATH, "utf8");
|
||||
const next = replaceGeneratedSection(current, generatedBlock);
|
||||
|
||||
const checkOnly = process.argv.includes("--check");
|
||||
|
||||
if (unresolved.length > 0) {
|
||||
console.warn("Unresolved ownership units (add to scripts/codeowners-overrides.json):");
|
||||
for (const entry of unresolved) console.warn(` ${entry.path} (${entry.email || "no email"})`);
|
||||
}
|
||||
|
||||
if (checkOnly) {
|
||||
if (next !== current) {
|
||||
console.error("CODEOWNERS is out of date. Run: pnpm scripts:generate-codeowners");
|
||||
process.exit(1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
await writeFile(CODEOWNERS_PATH, next, "utf8");
|
||||
console.log(`Updated CODEOWNERS with ${entries.length} feature units.`);
|
||||
};
|
||||
|
||||
await main();
|
||||
Executable
+17
@@ -0,0 +1,17 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
echo "==> Local CODEOWNERS checks"
|
||||
pnpm exec tsx ./scripts/generate-codeowners.mts --check
|
||||
export GITHUB_REPOSITORY="${GITHUB_REPOSITORY:-homarr-labs/homarr}"
|
||||
if [ -z "${GITHUB_TOKEN:-}" ] && [ -z "${GH_TOKEN:-}" ]; then
|
||||
GITHUB_TOKEN="$(gh auth token 2>/dev/null || true)"
|
||||
export GITHUB_TOKEN
|
||||
fi
|
||||
pnpm exec tsx ./scripts/validate-codeowners.mts
|
||||
|
||||
echo "==> act: validate job (requires Docker)"
|
||||
act workflow_dispatch -W .github/workflows/update-codeowners.yml -j validate \
|
||||
-s GITHUB_TOKEN="${GITHUB_TOKEN:-}"
|
||||
@@ -0,0 +1,145 @@
|
||||
import { readFile } from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
|
||||
const REPO_ROOT = join(import.meta.dirname, "..");
|
||||
const CODEOWNERS_PATH = join(REPO_ROOT, "CODEOWNERS");
|
||||
|
||||
const BEGIN_MARKER = "# BEGIN GENERATED widget/integration owners";
|
||||
const END_MARKER = "# END GENERATED widget/integration owners";
|
||||
|
||||
const UNSUPPORTED_PATTERN_CHECKS: { label: string; pattern: RegExp }[] = [
|
||||
{ label: "negation (!)", pattern: /^\s*!/ },
|
||||
{ label: "character range ([ ])", pattern: /^\s*[^#]*\[[^\]]+\]/ },
|
||||
];
|
||||
|
||||
const parseOwners = (line: string) => [...line.matchAll(/@[\w-]+(?:\/[\w-]+)?/g)].map((match) => match[0]);
|
||||
|
||||
const parsePatterns = (line: string) => {
|
||||
const withoutOwners = line.replace(/@[\w-]+(?:\/[\w-]+)?/g, "").trim();
|
||||
return withoutOwners.split(/\s+/).filter((token) => token.length > 0 && !token.startsWith("#"));
|
||||
};
|
||||
|
||||
const validateLine = (line: string, lineNumber: number) => {
|
||||
const trimmed = line.trim();
|
||||
if (trimmed.length === 0 || trimmed.startsWith("#")) return [];
|
||||
|
||||
const errors: string[] = [];
|
||||
|
||||
for (const check of UNSUPPORTED_PATTERN_CHECKS) {
|
||||
if (check.pattern.test(line)) {
|
||||
errors.push(`line ${lineNumber}: unsupported CODEOWNERS syntax (${check.label})`);
|
||||
}
|
||||
}
|
||||
|
||||
const owners = parseOwners(line);
|
||||
const patterns = parsePatterns(line);
|
||||
|
||||
if (patterns.length === 0 && owners.length === 0) return errors;
|
||||
|
||||
if (patterns.length > 0 && owners.length === 0) return errors;
|
||||
|
||||
if (owners.length > 0 && patterns.length === 0) {
|
||||
errors.push(`line ${lineNumber}: owners without file patterns`);
|
||||
}
|
||||
|
||||
for (const pattern of patterns) {
|
||||
const allowedGlobal = pattern === "*";
|
||||
const hasValidShape =
|
||||
allowedGlobal || pattern.startsWith("/") || pattern.includes("*") || pattern.includes(".");
|
||||
if (!hasValidShape) {
|
||||
errors.push(`line ${lineNumber}: pattern "${pattern}" should start with / or contain a wildcard`);
|
||||
}
|
||||
}
|
||||
|
||||
for (const owner of owners) {
|
||||
if (!owner.startsWith("@")) {
|
||||
errors.push(`line ${lineNumber}: invalid owner "${owner}"`);
|
||||
}
|
||||
}
|
||||
|
||||
return errors;
|
||||
};
|
||||
|
||||
const validateStructure = (content: string) => {
|
||||
const errors: string[] = [];
|
||||
const lines = content.split("\n");
|
||||
|
||||
if (!content.includes("* @")) {
|
||||
errors.push("missing default owner rule (* @team or * @user) — last matching pattern wins per GitHub docs");
|
||||
}
|
||||
|
||||
const starIndex = lines.findIndex((line) => /^\*(\s+|$)/.test(line.trim()));
|
||||
const beginIndex = lines.findIndex((line) => line.includes(BEGIN_MARKER));
|
||||
const endIndex = lines.findIndex((line) => line.includes(END_MARKER));
|
||||
|
||||
if (beginIndex === -1 || endIndex === -1) {
|
||||
errors.push("missing generated CODEOWNERS markers");
|
||||
return errors;
|
||||
}
|
||||
|
||||
if (starIndex !== -1 && beginIndex !== -1 && starIndex > beginIndex) {
|
||||
errors.push("global * rule must appear before generated feature rules so per-folder owners override maintainers");
|
||||
}
|
||||
|
||||
if (endIndex <= beginIndex) {
|
||||
errors.push("END GENERATED marker must follow BEGIN GENERATED marker");
|
||||
}
|
||||
|
||||
for (let index = 0; index < lines.length; index += 1) {
|
||||
const lineErrors = validateLine(lines[index] ?? "", index + 1);
|
||||
errors.push(...lineErrors);
|
||||
}
|
||||
|
||||
return errors;
|
||||
};
|
||||
|
||||
const validateGithubApi = async () => {
|
||||
const token = process.env.GITHUB_TOKEN ?? process.env.GH_TOKEN;
|
||||
const repository = process.env.GITHUB_REPOSITORY ?? "homarr-labs/homarr";
|
||||
|
||||
if (!token) {
|
||||
console.warn("Skipping GitHub API CODEOWNERS check (GITHUB_TOKEN not set).");
|
||||
return;
|
||||
}
|
||||
|
||||
const response = await fetch(`https://api.github.com/repos/${repository}/codeowners/errors`, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
Accept: "application/vnd.github+json",
|
||||
"X-GitHub-Api-Version": "2022-11-28",
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`GitHub API codeowners/errors failed: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
|
||||
const payload = (await response.json()) as { errors: unknown[] };
|
||||
const apiErrors = payload.errors ?? [];
|
||||
|
||||
if (apiErrors.length > 0) {
|
||||
console.error("GitHub reported CODEOWNERS syntax errors:");
|
||||
console.error(JSON.stringify(apiErrors, null, 2));
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log("GitHub API: no CODEOWNERS syntax errors.");
|
||||
};
|
||||
|
||||
const main = async () => {
|
||||
const content = await readFile(CODEOWNERS_PATH, "utf8");
|
||||
const errors = validateStructure(content);
|
||||
|
||||
if (errors.length > 0) {
|
||||
console.error("CODEOWNERS validation failed:");
|
||||
for (const error of errors) {
|
||||
console.error(` ${error}`);
|
||||
}
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
console.log("CODEOWNERS structure validation passed.");
|
||||
await validateGithubApi();
|
||||
};
|
||||
|
||||
await main();
|
||||
Reference in new issue
Block a user