Update dependencies and version number, remove link tickets endpoint

This commit is contained in:
Darren Clarke 2025-10-07 11:24:00 +02:00
parent 6f0f97ab7b
commit 11563a794e
36 changed files with 2953 additions and 4655 deletions

View file

@ -1,6 +1,6 @@
{
"name": "@link-stack/bridge-frontend",
"version": "3.1.0",
"version": "3.2.0b3",
"type": "module",
"scripts": {
"dev": "next dev",
@ -13,26 +13,26 @@
"migrate:down:one": "tsx database/migrate.ts down:one"
},
"dependencies": {
"@auth/kysely-adapter": "^1.8.0",
"@auth/kysely-adapter": "^1.10.0",
"@mui/icons-material": "^6",
"@mui/material": "^6",
"@mui/material-nextjs": "^6",
"@mui/x-license": "^7.28.0",
"@mui/x-license": "^7",
"@link-stack/bridge-common": "*",
"@link-stack/bridge-ui": "*",
"next": "15.2.3",
"next": "15.5.4",
"next-auth": "^4.24.11",
"react": "19.0.0",
"react-dom": "19.0.0",
"sharp": "^0.33.5",
"tsx": "^4.19.3",
"react": "19.2.0",
"react-dom": "19.2.0",
"sharp": "^0.34.4",
"tsx": "^4.20.6",
"@link-stack/ui": "*"
},
"devDependencies": {
"@link-stack/eslint-config": "*",
"@link-stack/typescript-config": "*",
"@types/node": "^22",
"@types/pg": "^8.11.11",
"@types/node": "^24",
"@types/pg": "^8.15.5",
"@types/react": "^19",
"@types/react-dom": "^19",
"@link-stack/eslint-config": "*",

View file

@ -1,6 +1,6 @@
{
"name": "@link-stack/bridge-migrations",
"version": "3.1.0",
"version": "3.2.0b3",
"type": "module",
"scripts": {
"migrate:up:all": "tsx migrate.ts up:all",
@ -10,14 +10,14 @@
},
"dependencies": {
"@link-stack/logger": "*",
"dotenv": "^16.4.7",
"kysely": "0.27.6",
"pg": "^8.14.1",
"tsx": "^4.19.3"
"dotenv": "^17.2.3",
"kysely": "0.27.5",
"pg": "^8.16.3",
"tsx": "^4.20.6"
},
"devDependencies": {
"@types/node": "^22",
"@types/pg": "^8.11.11",
"@types/node": "^24",
"@types/pg": "^8.15.5",
"@link-stack/eslint-config": "*",
"@link-stack/typescript-config": "*",
"typescript": "^5"

View file

@ -1,27 +1,27 @@
{
"name": "@link-stack/bridge-whatsapp",
"version": "3.1.0",
"version": "3.2.0b3",
"main": "build/main/index.js",
"author": "Darren Clarke <darren@redaranj.com>",
"license": "AGPL-3.0-or-later",
"dependencies": {
"@adiwajshing/keyed-db": "0.2.4",
"@hapi/hapi": "^21.4.0",
"@hapi/hapi": "^21.4.3",
"@hapipal/schmervice": "^3.0.0",
"@hapipal/toys": "^4.0.0",
"@link-stack/logger": "*",
"@whiskeysockets/baileys": "^6.7.16",
"hapi-pino": "^12.1.0",
"link-preview-js": "^3.0.14"
"@whiskeysockets/baileys": "^6.7.20",
"hapi-pino": "^13.0.0",
"link-preview-js": "^3.1.0"
},
"devDependencies": {
"@link-stack/eslint-config": "*",
"@link-stack/jest-config": "*",
"@link-stack/typescript-config": "*",
"@types/node": "*",
"dotenv-cli": "^8.0.0",
"tsx": "^4.19.3",
"typescript": "^5.8.2"
"dotenv-cli": "^10.0.0",
"tsx": "^4.20.6",
"typescript": "^5.9.3"
},
"scripts": {
"build": "tsc -p tsconfig.json",

View file

@ -42,7 +42,7 @@ export const SendMessageRoute = withDefaults({
attachmentCount: attachments?.length || 0,
},
"Sent a message at %s",
new Date(),
new Date().toISOString(),
);
return _h
@ -69,7 +69,7 @@ export const ReceiveMessageRoute = withDefaults({
const date = new Date();
const twoDaysAgo = new Date(date.getTime());
twoDaysAgo.setDate(date.getDate() - 2);
request.logger.info({ id }, "Received messages at %s", new Date());
request.logger.info({ id }, "Received messages at %s", new Date().toISOString());
return whatsappService.receive(id, twoDaysAgo);
},

View file

@ -1,6 +1,6 @@
{
"name": "@link-stack/bridge-worker",
"version": "3.1.0",
"version": "3.2.0b3",
"type": "module",
"main": "build/main/index.js",
"author": "Darren Clarke <darren@redaranj.com>",
@ -17,14 +17,14 @@
"@link-stack/signal-api": "*",
"fluent-ffmpeg": "^2.1.3",
"graphile-worker": "^0.16.6",
"remeda": "^2.21.2",
"twilio": "^5.5.1"
"remeda": "^2.32.0",
"twilio": "^5.10.2"
},
"devDependencies": {
"@types/fluent-ffmpeg": "^2.1.27",
"dotenv-cli": "^8.0.0",
"dotenv-cli": "^10.0.0",
"@link-stack/eslint-config": "*",
"@link-stack/typescript-config": "*",
"typescript": "^5.8.2"
"typescript": "^5.9.3"
}
}

View file

@ -1,6 +1,7 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
/// <reference types="next/navigation-types/compat/navigation" />
/// <reference path="./.next/types/routes.d.ts" />
// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.

View file

@ -1,6 +1,6 @@
{
"name": "@link-stack/leafcutter",
"version": "3.1.0",
"version": "3.2.0b3",
"scripts": {
"dev": "next dev -p 3001",
"login": "aws sso login --sso-session cdr",
@ -16,35 +16,35 @@
"@emotion/cache": "^11.14.0",
"@emotion/react": "^11.14.0",
"@emotion/server": "^11.11.0",
"@emotion/styled": "^11.14.0",
"@emotion/styled": "^11.14.1",
"@link-stack/leafcutter-ui": "*",
"@link-stack/logger": "*",
"@link-stack/opensearch-common": "*",
"@mui/icons-material": "^6",
"@mui/material": "^6",
"@mui/material-nextjs": "^6",
"@mui/x-date-pickers-pro": "^7.28.0",
"@opensearch-project/opensearch": "^3.4.0",
"@mui/x-date-pickers-pro": "^7",
"@opensearch-project/opensearch": "^3.5.1",
"date-fns": "^4.1.0",
"http-proxy-middleware": "^3.0.3",
"material-ui-popup-state": "^5.3.3",
"next": "15.2.3",
"http-proxy-middleware": "^3.0.5",
"material-ui-popup-state": "^5.3.6",
"next": "15.5.4",
"next-auth": "^4.24.11",
"react": "19.0.0",
"react": "19.2.0",
"react-cookie": "^8.0.1",
"react-cookie-consent": "^9.0.0",
"react-dom": "19.0.0",
"react-dom": "19.2.0",
"react-iframe": "^1.8.5",
"react-polyglot": "^0.7.2",
"sharp": "^0.33.5",
"uuid": "^11.1.0"
"sharp": "^0.34.4",
"uuid": "^13.0.0"
},
"devDependencies": {
"@types/node": "^22.13.12",
"@types/react": "19.0.12",
"@types/uuid": "^10.0.0",
"@types/node": "^24.7.0",
"@types/react": "19.2.2",
"@types/uuid": "^11.0.0",
"@link-stack/eslint-config": "*",
"@link-stack/typescript-config": "*",
"typescript": "5.8.2"
"typescript": "5.9.3"
}
}

View file

@ -1,10 +0,0 @@
import { Metadata } from "next";
import { ZammadWrapper } from "../../(main)/_components/ZammadWrapper";
export const metadata: Metadata = {
title: "Knowledge Base",
};
export default function Page() {
return <ZammadWrapper path="/#knowledge_base/1/locale/en-us" />;
}

View file

@ -1,100 +0,0 @@
"use client";
import { FC, useState } from "react";
import {
Grid,
Button,
Dialog,
DialogActions,
DialogContent,
TextField,
} from "@mui/material";
import { createTicketArticleAction } from "app/_actions/tickets";
interface ArticleCreateDialogProps {
ticketID: string;
open: boolean;
closeDialog: () => void;
kind: string;
recipient?: string;
}
export const ArticleCreateDialog: FC<ArticleCreateDialogProps> = ({
ticketID,
open,
closeDialog,
kind,
recipient,
}) => {
const [body, setBody] = useState("");
const backgroundColor = kind === "note" ? "#FFB620" : "#1982FC";
const color = kind === "note" ? "black" : "white";
const article = {
body,
type: kind,
internal: kind === "note",
};
if (kind === "email") {
article["to"] = recipient;
}
const createArticle = async () => {
await createTicketArticleAction(ticketID, article);
closeDialog();
setBody("");
};
return (
<Dialog open={open} maxWidth="sm" fullWidth>
<DialogContent>
<TextField
label={kind === "note" ? "Write internal note" : "Write reply"}
multiline
rows={10}
fullWidth
value={body}
onChange={(e: any) => setBody(e.target.value)}
/>
</DialogContent>
<DialogActions sx={{ px: 3, pt: 0, pb: 3 }}>
<Grid container justifyContent="space-between">
<Grid item>
<Button
sx={{
backgroundColor: "white",
color: "#666",
fontFamily: "Poppins, sans-serif",
fontWeight: 700,
borderRadius: 2,
textTransform: "none",
}}
onClick={() => {
setBody("");
closeDialog();
}}
>
Cancel
</Button>
</Grid>
<Grid item>
<Button
sx={{
backgroundColor,
color,
fontFamily: "Poppins, sans-serif",
fontWeight: 700,
borderRadius: 2,
textTransform: "none",
px: 3,
}}
onClick={createArticle}
>
{kind === "note" ? "Save Note" : "Send Reply"}
</Button>
</Grid>
</Grid>
</DialogActions>
</Dialog>
);
};

View file

@ -1,177 +0,0 @@
"use client";
import { FC, useState, useEffect } from "react";
import { getTicketAction, getTicketArticlesAction } from "app/_actions/tickets";
import { Grid, Box, Typography } from "@mui/material";
import { Button, fonts, colors } from "@link-stack/ui";
import "@chatscope/chat-ui-kit-styles/dist/default/styles.min.css";
import {
MainContainer,
ChatContainer,
MessageList,
Message,
ConversationHeader,
} from "@chatscope/chat-ui-kit-react";
import { ArticleCreateDialog } from "./ArticleCreateDialog";
interface TicketDetailProps {
id: string;
}
export const TicketDetail: FC<TicketDetailProps> = ({ id }) => {
const [ticket, setTicket] = useState<any>(null);
const [ticketArticles, setTicketArticles] = useState<any>(null);
const { poppins, roboto } = fonts;
const { veryLightGray, lightGray } = colors;
const [dialogOpen, setDialogOpen] = useState(false);
const [articleKind, setArticleKind] = useState("note");
useEffect(() => {
const fetchTicket = async () => {
const result = await getTicketAction(id);
setTicket(result);
};
fetchTicket();
const interval = setInterval(fetchTicket, 20000);
return () => clearInterval(interval);
}, [id]);
useEffect(() => {
const fetchTicketArticles = async () => {
const result = await getTicketArticlesAction(id);
setTicketArticles(result);
};
fetchTicketArticles();
const interval = setInterval(fetchTicketArticles, 5000);
return () => clearInterval(interval);
}, [id]);
const closeDialog = () => setDialogOpen(false);
const firstArticle = ticketArticles?.edges[0]?.node;
const firstArticleKind = firstArticle?.type?.name ?? "phone";
const firstEmailSender = firstArticle?.from?.parsed?.[0]?.emailAddress ?? "";
const recipient = firstEmailSender;
const shouldRender = !!ticket && !!ticketArticles;
return (
<Box sx={{ height: "100%", width: "100%", background: veryLightGray }}>
{shouldRender && (
<>
<MainContainer>
<ChatContainer>
<ConversationHeader>
<ConversationHeader.Content>
<Box
sx={{
width: "100%",
textAlign: "center",
fontWeight: "bold",
}}
>
<Typography
variant="h5"
sx={{
fontFamily: poppins.style.fontFamily,
fontWeight: 700,
}}
>
{ticket.title}
</Typography>
<Typography
variant="h6"
sx={{
fontFamily: roboto.style.fontFamily,
fontWeight: 400,
}}
>{`Ticket #${ticket.number} (created ${new Date(
ticket.createdAt,
).toLocaleDateString()})`}</Typography>
</Box>
</ConversationHeader.Content>
</ConversationHeader>
<MessageList style={{ marginBottom: 80 }}>
{ticketArticles.edges.map(({ node: article }: any) => (
<Message
key={article.id}
className={
article.internal
? "internal-note"
: article?.sender?.name === "Agent"
? "outgoing-message"
: "incoming-message"
}
model={{
message: article.bodyWithUrls,
type:
article.contentType === "text/html" ? "html" : "text",
sentTime: article.updated_at,
sender: article.from,
direction:
article.sender === "Agent" ? "outgoing" : "incoming",
position: "single",
}}
/>
))}
</MessageList>
</ChatContainer>
<Box
sx={{
height: 80,
background: veryLightGray,
borderTop: `1px solid ${lightGray}`,
position: "absolute",
bottom: 0,
width: "100%",
zIndex: 1000,
}}
>
<Grid
container
spacing={6}
justifyContent="center"
alignItems="center"
alignContent="center"
sx={{ height: "100%", pt: 6 }}
>
<Grid item>
<Button
text="Write note to agent"
color="#FFB620"
onClick={() => {
setArticleKind("note");
setDialogOpen(true);
}}
/>
</Grid>
<Grid item>
<Button
text="Reply to ticket"
kind="primary"
onClick={() => {
setArticleKind(firstArticleKind);
setDialogOpen(true);
}}
/>
</Grid>
</Grid>
</Box>
</MainContainer>
<ArticleCreateDialog
ticketID={ticket.internalId}
open={dialogOpen}
closeDialog={closeDialog}
kind={articleKind}
recipient={recipient}
/>
</>
)}
</Box>
);
};

View file

@ -1,13 +0,0 @@
import { TicketDetail } from "./_components/TicketDetail";
type PageProps = {
params: Promise<{
id: string;
}>;
};
export default async function Page({ params }: PageProps) {
const { id } = await params;
return <TicketDetail id={id} />;
}

View file

@ -1,201 +0,0 @@
"use client";
import { FC, useEffect, useState } from "react";
import { Grid, Box } from "@mui/material";
import { Select, Button } from "@link-stack/ui";
import { MuiChipsInput } from "mui-chips-input";
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
import {
updateTicketAction,
getTicketAction,
getTicketStatesAction,
getTicketPrioritiesAction,
} from "app/_actions/tickets";
import { getAgentsAction } from "app/_actions/users";
import { getGroupsAction } from "app/_actions/groups";
interface TicketEditProps {
id: string;
}
export const TicketEdit: FC<TicketEditProps> = ({ id }) => {
const [ticket, setTicket] = useState<any>();
const [hasChanges, setHasChanges] = useState(false);
const [formState, setFormState] = useState({
values: {
group: null,
owner: null,
priority: null,
pendingTime: null,
state: null,
tags: [],
},
});
const [ticketStates, setTicketStates] = useState<any>();
const [ticketPriorities, setTicketPriorities] = useState<any>();
const [groups, setGroups] = useState<any>();
const [agents, setAgents] = useState<any>();
const [pendingVisible, setPendingVisible] = useState(false);
useEffect(() => {
const fetchAgents = async () => {
const groupID = formState?.values?.group?.split("/")?.pop();
const result = await getAgentsAction(groupID);
setAgents(result);
};
const fetchGroups = async () => {
const result = await getGroupsAction();
setGroups(result);
};
const fetchTicketStates = async () => {
const result = await getTicketStatesAction();
setTicketStates(result);
};
const fetchTicketPriorities = async () => {
const result = await getTicketPrioritiesAction();
setTicketPriorities(result);
};
fetchTicketStates();
fetchTicketPriorities();
fetchAgents();
fetchGroups();
}, [formState.values.group]);
useEffect(() => {
const fetchTicket = async () => {
const result = await getTicketAction(id);
setTicket(result);
setFormState({
values: {
...formState.values,
group: result?.group?.id,
owner: result?.owner?.id,
priority: result?.priority?.id,
state: result?.state?.id,
tags: result?.tags,
},
});
};
fetchTicket();
}, []);
const updateFormState = (name: string, value: any) => {
setFormState({
values: {
...formState.values,
[name]: value,
},
});
const stateName = ticketStates?.find(
(state: any) => state.id === formState.values.state,
)?.name;
setPendingVisible(stateName?.includes("pending") ?? false);
setHasChanges(true);
};
const updateTicket = async () => {
await updateTicketAction(id, formState.values);
setHasChanges(false);
};
const shouldRender = !!ticket;
return (
<Box sx={{ height: "100vh", background: "#ddd", p: 2 }}>
{shouldRender && (
<Grid container direction="column" spacing={3}>
<Grid item>
<Box sx={{ m: 1 }}>Group</Box>
<Select
name="group"
label="Group"
formState={formState}
updateFormState={updateFormState}
getOptions={() => groups}
/>
</Grid>
<Grid item>
<Box sx={{ m: 1, mt: 0 }}>Owner</Box>
<Select
name="owner"
label="Owner"
formState={formState}
updateFormState={updateFormState}
getOptions={() => agents}
/>
</Grid>
<Grid item xs={12}>
<Box sx={{ m: 1, mt: 0 }}>State</Box>
<Select
name="state"
label="State"
formState={formState}
updateFormState={updateFormState}
getOptions={() => ticketStates}
/>
</Grid>
<Grid
item
xs={12}
sx={{ display: pendingVisible ? "inherit" : "none" }}
>
<DatePicker
label="Pending Date"
value={new Date(formState.values.pendingTime)}
onChange={(newValue: any) => {
updateFormState("pendingDate", newValue.toISOString());
}}
slotProps={{ textField: { size: "small" } }}
sx={{
width: "100%",
backgroundColor: "white",
}}
/>
</Grid>
<Grid item>
<Box sx={{ m: 1, mt: 0 }}>Priority</Box>
<Select
name="priority"
label="Priority"
formState={formState}
updateFormState={updateFormState}
getOptions={() => ticketPriorities}
/>
</Grid>
<Grid item>
<Box sx={{ mb: 1 }}>Tags</Box>
<MuiChipsInput
sx={{ backgroundColor: "white", width: "100%" }}
value={formState.values.tags}
hideClearAll
onChange={(tags: any) => {
updateFormState("tags", tags);
}}
onDeleteChip={(tag: any) => {
const tags = formState.values.tags.filter(
(t: any) => t !== tag,
);
updateFormState("tags", tags);
}}
/>
</Grid>
<Grid item container direction="row-reverse">
<Grid item>
<Button
text="Save"
kind="primary"
onClick={updateTicket}
disabled={!hasChanges}
/>
</Grid>
</Grid>
</Grid>
)}
</Box>
);
};

View file

@ -1,13 +0,0 @@
import { TicketEdit } from "./_components/TicketEdit";
type PageProps = {
params: Promise<{
id: string;
}>;
};
export default async function Page({ params }: PageProps) {
const { id } = await params;
return <TicketEdit id={id} />;
}

View file

@ -1,11 +0,0 @@
"use client";
import { DisplayError } from "app/_components/DisplayError";
type PageProps = {
error: Error;
};
export default function Page({ error }: PageProps) {
return <DisplayError error={error} />;
}

View file

@ -1,19 +0,0 @@
import { Grid } from "@mui/material";
type LayoutProps = {
detail: any;
edit: any;
};
export default async function Layout({ detail, edit }: LayoutProps) {
return (
<Grid container spacing={0} sx={{ height: "100vh" }} direction="row">
<Grid item sx={{ height: "100vh" }} xs={9}>
{detail}
</Grid>
<Grid item xs={3} sx={{ height: "100vh" }}>
{edit}
</Grid>
</Grid>
);
}

View file

@ -1,15 +0,0 @@
"use client";
import Link from "next/link";
export default function Page() {
return (
<div>
<h2>Not Found</h2>
<p>Could not find requested resource</p>
<p>
View <Link href="/blog">all posts</Link>
</p>
</div>
);
}

View file

@ -58,7 +58,8 @@ const checkRewrites = async (request: NextRequestWithAuth) => {
opensearchBaseURL,
headers,
);
} else {
}
const isDev = process.env.NODE_ENV === "development";
const nonce = Buffer.from(crypto.randomUUID()).toString("base64");
const cspHeader = `
@ -98,7 +99,6 @@ const checkRewrites = async (request: NextRequestWithAuth) => {
);
return response;
};
}
export default withAuth(checkRewrites, {

View file

@ -1,5 +1,6 @@
/// <reference types="next" />
/// <reference types="next/image-types/global" />
/// <reference path="./.next/types/routes.d.ts" />
// NOTE: This file should not be edited
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.

View file

@ -1,6 +1,6 @@
{
"name": "@link-stack/link",
"version": "3.1.0",
"version": "3.2.0b3",
"type": "module",
"scripts": {
"dev": "next dev -H 0.0.0.0",
@ -10,12 +10,12 @@
"lint": "next lint"
},
"dependencies": {
"@chatscope/chat-ui-kit-react": "^2.0.3",
"@chatscope/chat-ui-kit-react": "^2.1.1",
"@chatscope/chat-ui-kit-styles": "^1.4.0",
"@emotion/cache": "^11.14.0",
"@emotion/react": "^11.14.0",
"@emotion/server": "^11.11.0",
"@emotion/styled": "^11.14.0",
"@emotion/styled": "^11.14.1",
"@link-stack/bridge-common": "*",
"@link-stack/bridge-ui": "*",
"@link-stack/leafcutter-ui": "*",
@ -25,27 +25,27 @@
"@mui/icons-material": "^6",
"@mui/material": "^6",
"@mui/material-nextjs": "^6",
"@mui/x-data-grid-pro": "^7.28.1",
"@mui/x-date-pickers": "^7.28.0",
"@mui/x-date-pickers-pro": "^7.28.0",
"@mui/x-license": "^7.28.0",
"@mui/x-data-grid-pro": "^7",
"@mui/x-date-pickers": "^7",
"@mui/x-date-pickers-pro": "^7",
"@mui/x-license": "^7",
"date-fns": "^4.1.0",
"graphql-request": "^7.1.2",
"ioredis": "^5.6.0",
"graphql-request": "^7.2.0",
"ioredis": "^5.8.1",
"mui-chips-input": "^6.0.0",
"next": "15.2.3",
"next": "15.5.4",
"next-auth": "^4.24.11",
"react": "19.0.0",
"react": "19.2.0",
"react-cookie": "^8.0.1",
"react-dom": "19.0.0",
"react-dom": "19.2.0",
"react-iframe": "^1.8.5",
"react-polyglot": "^0.7.2",
"sharp": "^0.33.5"
"sharp": "^0.34.4"
},
"devDependencies": {
"@link-stack/eslint-config": "*",
"@types/node": "^22.13.12",
"@types/react": "19.0.12",
"@types/uuid": "^10.0.0"
"@types/node": "^24.7.0",
"@types/react": "19.2.2",
"@types/uuid": "^11.0.0"
}
}

View file

@ -1,4 +1,4 @@
ARG ZAMMAD_VERSION=6.5.0
ARG ZAMMAD_VERSION=6.5.2
FROM node:22-slim AS node
@ -31,7 +31,7 @@ RUN if [ "$EMBEDDED" = "true" ] ; then sed -i "/location \/ {/i\
proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;\n\
proxy_set_header X-Forwarded-Proto https;\n\
}\n\
" ${ZAMMAD_DIR}/contrib/nginx/zammad.conf; fi
" ${ZAMMAD_DIR}/contrib/nginx/zammad.conf; fi
RUN sed -i '/^[[:space:]]*# es config/a\
echo "about to reinstall..."\n\
bundle exec rails runner /opt/zammad/contrib/link/setup.rb\n\

6671
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,13 +1,13 @@
{
"name": "@link-stack",
"version": "3.1.0",
"version": "3.2.0b3",
"description": "Link from the Center for Digital Resilience",
"scripts": {
"dev": "dotenv -- turbo dev",
"build": "dotenv -- turbo build",
"migrate": "dotenv -- npm run migrate --workspace=database",
"lint": "dotenv turbo lint",
"update-version": "find . -name 'package.json' -exec sed -i -E 's/\"version\": \"[^\"]+\"/\"version\": \"3.1.0\"/' {} +",
"update-version": "find . -name 'package.json' -exec sed -i -E 's/\"version\": \"[^\"]+\"/\"version\": \"3.2.0b3\"/' {} +",
"upgrade:setup": "npm i -g npm-check-updates",
"upgrade:check": "ncu && ncu -ws",
"upgrade": "ncu -u && ncu -ws -u && npm i",
@ -48,25 +48,25 @@
"type": "git",
"url": "git+https://gitlab.com/digiresilience/link/link-stack.git"
},
"packageManager": "npm@11.2.0",
"packageManager": "npm@11.6.1",
"author": "Darren Clarke",
"license": "AGPL-3.0-or-later",
"devDependencies": {
"@types/react": "19.0.12",
"@types/react-dom": "19.0.4",
"@types/react": "19.2.2",
"@types/react-dom": "19.2.1",
"dotenv-cli": "latest",
"eslint": "^9",
"react": "19.0.0",
"react-dom": "19.0.0",
"react": "19.2.0",
"react-dom": "19.2.0",
"ts-node": "^10.9.2",
"turbo": "^2.4.4",
"turbo": "^2.5.8",
"typescript": "latest"
},
"overrides": {
"react": "19.0.0",
"react-dom": "19.0.0",
"@types/react": "19.0.12",
"@types/react-dom": "19.0.4",
"react": "19.2.0",
"react-dom": "19.2.0",
"@types/react": "19.2.2",
"@types/react-dom": "19.2.1",
"@mui/material": "^6.5.0"
},
"engines": {

View file

@ -1,6 +1,6 @@
{
"name": "@link-stack/bridge-common",
"version": "3.1.0",
"version": "3.2.0b3",
"main": "build/main/index.js",
"type": "module",
"author": "Darren Clarke <darren@redaranj.com>",
@ -9,14 +9,14 @@
"build": "tsc -p tsconfig.json"
},
"dependencies": {
"@auth/kysely-adapter": "^1.8.0",
"@auth/kysely-adapter": "^1.10.0",
"graphile-worker": "^0.16.6",
"kysely": "0.27.6",
"pg": "^8.14.1"
"kysely": "0.27.5",
"pg": "^8.16.3"
},
"devDependencies": {
"@link-stack/eslint-config": "*",
"@link-stack/typescript-config": "*",
"typescript": "^5.8.2"
"typescript": "^5.9.3"
}
}

View file

@ -1,6 +1,6 @@
{
"name": "@link-stack/bridge-ui",
"version": "3.1.0",
"version": "3.2.0b3",
"scripts": {
"build": "tsc -p tsconfig.json"
},
@ -9,17 +9,17 @@
"@link-stack/signal-api": "*",
"@link-stack/ui": "*",
"@mui/material": "^6",
"@mui/x-data-grid-pro": "^7.28.1",
"kysely": "0.27.6",
"next": "15.2.3",
"react": "19.0.0",
"react-dom": "19.0.0",
"react-qr-code": "^2.0.15"
"@mui/x-data-grid-pro": "^7",
"kysely": "0.27.5",
"next": "15.5.4",
"react": "19.2.0",
"react-dom": "19.2.0",
"react-qr-code": "^2.0.18"
},
"devDependencies": {
"@types/node": "^22.13.12",
"@types/react": "19.0.12",
"@types/react-dom": "^19.0.4",
"typescript": "5.8.2"
"@types/node": "^24.7.0",
"@types/react": "19.2.2",
"@types/react-dom": "^19.2.1",
"typescript": "5.9.3"
}
}

View file

@ -1,6 +1,6 @@
{
"name": "@link-stack/eslint-config",
"version": "3.1.0",
"version": "3.2.0b3",
"description": "amigo's eslint config",
"author": "Abel Luck <abel@guardianproject.info>",
"license": "AGPL-3.0-or-later",
@ -9,24 +9,24 @@
"fmt": "prettier \"profile/**/*.js\" --write"
},
"dependencies": {
"@rushstack/eslint-patch": "^1.11.0",
"@typescript-eslint/eslint-plugin": "^8.27.0",
"@typescript-eslint/parser": "^8.27.0",
"eslint-config-prettier": "^10.1.1",
"@rushstack/eslint-patch": "^1.13.0",
"@typescript-eslint/eslint-plugin": "^8.46.0",
"@typescript-eslint/parser": "^8.46.0",
"eslint-config-prettier": "^10.1.8",
"eslint-config-xo-space": "^0.35.0",
"eslint-plugin-eslint-comments": "^3.2.0",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-jest": "^28.11.0",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-jest": "^29.0.1",
"eslint-plugin-promise": "^7.2.1",
"eslint-plugin-unicorn": "58.0.0",
"@babel/eslint-parser": "7.26.10"
"eslint-plugin-unicorn": "61.0.2",
"@babel/eslint-parser": "7.28.4"
},
"peerDependencies": {
"typescript": "^4.9.5"
},
"devDependencies": {
"eslint": "^9",
"jest": "^29.7.0",
"typescript": "^5.8.2"
"jest": "^30.2.0",
"typescript": "^5.9.3"
}
}

View file

@ -1,6 +1,6 @@
{
"name": "@link-stack/jest-config",
"version": "3.1.0",
"version": "3.2.0b3",
"description": "",
"author": "Abel Luck <abel@guardianproject.info>",
"license": "AGPL-3.0-or-later",
@ -9,8 +9,8 @@
"node": ">=14"
},
"dependencies": {
"@types/jest": "^29.5.14",
"jest": "^29.7.0",
"@types/jest": "^30.0.0",
"jest": "^30.2.0",
"jest-junit": "^16.0.0"
},
"peerDependencies": {}

View file

@ -1,23 +1,23 @@
{
"name": "@link-stack/leafcutter-ui",
"version": "3.1.0",
"version": "3.2.0b3",
"scripts": {
"build": "tsc -p tsconfig.json"
},
"dependencies": {
"@emotion/react": "^11.14.0",
"@emotion/styled": "^11.14.0",
"@emotion/styled": "^11.14.1",
"@link-stack/opensearch-common": "*",
"@mui/icons-material": "^6",
"@mui/material": "^6",
"@mui/x-data-grid-pro": "^7.28.1",
"@mui/x-date-pickers-pro": "^7.28.0",
"@mui/x-data-grid-pro": "^7",
"@mui/x-date-pickers-pro": "^7",
"date-fns": "^4.1.0",
"next": "15.2.3",
"next": "15.5.4",
"next-auth": "^4.24.11",
"react": "19.0.0",
"react": "19.2.0",
"react-cookie": "^8.0.1",
"react-dom": "19.0.0",
"react-dom": "19.2.0",
"react-iframe": "^1.8.5",
"react-markdown": "^10.1.0",
"react-polyglot": "^0.7.2"
@ -25,8 +25,8 @@
"devDependencies": {
"@link-stack/eslint-config": "*",
"@link-stack/typescript-config": "*",
"@types/node": "^22.13.12",
"@types/react": "19.0.12",
"typescript": "5.8.2"
"@types/node": "^24.7.0",
"@types/react": "19.2.2",
"typescript": "5.9.3"
}
}

View file

@ -1,6 +1,6 @@
{
"name": "@link-stack/logger",
"version": "1.0.0",
"version": "3.2.0b3",
"description": "Shared logging utility for Link Stack monorepo",
"main": "./dist/index.js",
"module": "./dist/index.mjs",
@ -19,16 +19,16 @@
"type-check": "tsc --noEmit"
},
"dependencies": {
"pino": "^9.5.0",
"pino-pretty": "^13.0.0"
"pino": "^10.0.0",
"pino-pretty": "^13.1.1"
},
"devDependencies": {
"@link-stack/eslint-config": "*",
"@link-stack/typescript-config": "*",
"@types/node": "^22.10.5",
"eslint": "^9.17.0",
"tsup": "^8.3.5",
"typescript": "^5.7.3"
"@types/node": "^24.7.0",
"eslint": "^9.37.0",
"tsup": "^8.5.0",
"typescript": "^5.9.3"
},
"publishConfig": {
"access": "public"

View file

@ -1,19 +1,19 @@
{
"name": "@link-stack/opensearch-common",
"version": "3.1.0",
"version": "3.2.0b3",
"scripts": {
"build": "tsc -p tsconfig.json"
},
"dependencies": {
"@link-stack/logger": "*",
"@opensearch-project/opensearch": "^3.4.0",
"uuid": "^11.1.0"
"@opensearch-project/opensearch": "^3.5.1",
"uuid": "^13.0.0"
},
"devDependencies": {
"@types/node": "^22.13.12",
"@types/uuid": "^10.0.0",
"@types/node": "^24.7.0",
"@types/uuid": "^11.0.0",
"@link-stack/typescript-config": "*",
"@link-stack/eslint-config": "*",
"typescript": "5.8.2"
"typescript": "5.9.3"
}
}

View file

@ -1,6 +1,6 @@
{
"name": "@link-stack/signal-api",
"version": "3.1.0",
"version": "3.2.0b3",
"type": "module",
"main": "build/index.js",
"exports": {
@ -12,10 +12,10 @@
"update-api": "openapi-generator-cli generate -i 'https://bbernhard.github.io/signal-cli-rest-api/src/docs/swagger.json' -g typescript-fetch -o . --skip-validate-spec"
},
"devDependencies": {
"@openapitools/openapi-generator-cli": "^2.18.4",
"@openapitools/openapi-generator-cli": "^2.24.0",
"@link-stack/typescript-config": "*",
"@link-stack/eslint-config": "*",
"@types/node": "^22",
"@types/node": "^24",
"typescript": "^5"
}
}

View file

@ -1,6 +1,6 @@
{
"name": "@link-stack/typescript-config",
"version": "3.1.0",
"version": "3.2.0b3",
"description": "Shared TypeScript config",
"license": "AGPL-3.0-or-later",
"author": "Abel Luck <abel@guardianproject.info>",

View file

@ -1,6 +1,6 @@
{
"name": "@link-stack/ui",
"version": "3.1.0",
"version": "3.2.0b3",
"description": "",
"scripts": {
"build": "tsc -p tsconfig.json"
@ -9,16 +9,16 @@
"dependencies": {
"@mui/icons-material": "^6",
"@mui/material": "^6",
"@mui/x-data-grid-pro": "^7.28.1",
"@mui/x-license": "^7.28.0",
"next": "15.2.3",
"react": "19.0.0",
"react-dom": "19.0.0"
"@mui/x-data-grid-pro": "^7",
"@mui/x-license": "^7",
"next": "15.5.4",
"react": "19.2.0",
"react-dom": "19.2.0"
},
"devDependencies": {
"@types/node": "^22.13.12",
"@types/react": "19.0.12",
"@types/react-dom": "^19.0.4",
"typescript": "^5.8.2"
"@types/node": "^24.7.0",
"@types/react": "19.2.2",
"@types/react-dom": "^19.2.1",
"typescript": "^5.9.3"
}
}

View file

@ -1,7 +1,7 @@
{
"name": "@link-stack/zammad-addon-bridge",
"displayName": "Bridge",
"version": "3.1.0",
"version": "3.2.0b3",
"description": "An addon that adds CDR Bridge channels to Zammad.",
"scripts": {
"build": "node '../../node_modules/@link-stack/zammad-addon-common/dist/build.js'",

View file

@ -1,6 +1,6 @@
{
"name": "@link-stack/zammad-addon-common",
"version": "3.1.0",
"version": "3.2.0b3",
"description": "",
"bin": {
"zpm-build": "./dist/build.js",
@ -10,13 +10,13 @@
"build": "tsc"
},
"devDependencies": {
"@types/node": "^22.13.12",
"@types/node": "^24.7.0",
"typescript": "^5"
},
"author": "",
"license": "AGPL-3.0-or-later",
"dependencies": {
"@link-stack/logger": "*",
"glob": "^11.0.1"
"glob": "^11.0.3"
}
}

View file

@ -1,7 +1,7 @@
{
"name": "@link-stack/zammad-addon-hardening",
"displayName": "Hardening",
"version": "3.1.0",
"version": "3.2.0b3",
"description": "A Zammad addon that hardens a Zammad instance according to CDR's needs.",
"scripts": {
"build": "node '../../node_modules/@link-stack/zammad-addon-common/dist/build.js'",

View file

@ -1,7 +1,7 @@
{
"name": "@link-stack/zammad-addon-leafcutter",
"displayName": "Leafcutter",
"version": "3.1.0",
"version": "3.2.0b3",
"description": "Adds a common set of tags for Leafcutter uses.",
"scripts": {
"build": "node '../../node_modules/@link-stack/zammad-addon-common/dist/build.js'",